4646
4747#define HAS_MEMORY_PRESSURE_SETTINGS_API WEBKIT_CHECK_VERSION (2 , 38 , 0 )
4848
49+ #define HAS_SCREEN_HDR_API WEBKIT_CHECK_VERSION (2 , 46 , 0 )
50+ #if HAS_SCREEN_HDR_API
51+ #include < interfaces/IDisplayInfo.h>
52+ #endif
53+
4954#ifdef ENABLE_TESTING
5055#include < testrunner.h>
5156#endif // ENABLE_TESTING
@@ -78,7 +83,11 @@ namespace Plugin {
7883 #if defined(ENABLE_CLOUD_COOKIE_JAR)
7984 public Exchange::IBrowserCookieJar,
8085 #endif
81- public PluginHost::IStateControl {
86+ public PluginHost::IStateControl
87+ #if HAS_SCREEN_HDR_API
88+ , public Exchange::IConnectionProperties::INotification
89+ #endif
90+ {
8291 public:
8392 class BundleConfig : public Core ::JSON::Container {
8493 private:
@@ -333,6 +342,7 @@ namespace Plugin {
333342 , ICECandidateFilteringEnabled()
334343 , GstQuirks()
335344 , GstHolePunchQuirk()
345+ , HDRRefreshDelay(1000 ) // Default to 1 second for HDR refresh delay
336346 {
337347 Add (_T (" useragent" ), &UserAgent);
338348 Add (_T (" url" ), &URL);
@@ -404,6 +414,7 @@ namespace Plugin {
404414 Add (_T (" icecandidatefiltering" ), &ICECandidateFilteringEnabled);
405415 Add (_T (" gstquirks" ), &GstQuirks);
406416 Add (_T (" gstholepunchquirk" ), &GstHolePunchQuirk);
417+ Add (_T (" hdrrefreshDelay" ), &HDRRefreshDelay);
407418 }
408419 ~Config ()
409420 {
@@ -480,6 +491,7 @@ namespace Plugin {
480491 Core::JSON::Boolean ICECandidateFilteringEnabled;
481492 Core::JSON::String GstQuirks;
482493 Core::JSON::String GstHolePunchQuirk;
494+ Core::JSON::DecUInt16 HDRRefreshDelay; // Delay in miliseconds to refresh HDR support
483495 };
484496
485497 class HangDetector
@@ -619,6 +631,11 @@ namespace Plugin {
619631 , _unresponsiveReplyNum(0 )
620632 , _frameCount(0 )
621633 , _lastDumpTime(g_get_monotonic_time())
634+ #if HAS_SCREEN_HDR_API
635+ ,_displayInfoPlugin(nullptr )
636+ ,_displayConnectionProps(nullptr )
637+ ,_hdrSupported(false )
638+ #endif // HAS_SCREEN_HDR_API
622639 {
623640 // Register an @Exit, in case we are killed, with an incorrect ref count !!
624641 if (atexit (CloseDown) != 0 ) {
@@ -649,6 +666,10 @@ namespace Plugin {
649666 TRACE (Trace::Information, (_T (" Bailed out before the end of the WPE main app was reached. %d" ), 6000 ));
650667 }
651668
669+ #if HAS_SCREEN_HDR_API
670+ UnsubscribeHDRCapabilities ();
671+ #endif
672+
652673 implementation = nullptr ;
653674 }
654675
@@ -1927,6 +1948,7 @@ namespace Plugin {
19271948 _config.Bundle .Config (key,value);
19281949 return (value);
19291950 }
1951+
19301952 BEGIN_INTERFACE_MAP (WebKitImplementation)
19311953 INTERFACE_ENTRY (Exchange::IWebBrowser)
19321954 INTERFACE_ENTRY (Exchange::IBrowser)
@@ -1936,6 +1958,9 @@ namespace Plugin {
19361958 INTERFACE_ENTRY (Exchange::IBrowserCookieJar)
19371959#endif
19381960 INTERFACE_ENTRY (PluginHost::IStateControl)
1961+ #if HAS_SCREEN_HDR_API
1962+ INTERFACE_ENTRY (Exchange::IConnectionProperties::INotification)
1963+ #endif
19391964 END_INTERFACE_MAP
19401965
19411966 private:
@@ -2490,6 +2515,13 @@ namespace Plugin {
24902515 // webaudio support
24912516 webkit_settings_set_enable_webaudio (preferences, _config.WebAudioEnabled .Value ());
24922517
2518+ #if HAS_SCREEN_HDR_API
2519+ SubscribeHDRCapabilities ();
2520+ // Query the current HDR capabilities before we start the browser
2521+ RefreshHDRSupport ();
2522+ UpdateHDRSettings (preferences);
2523+ #endif
2524+
24932525 // Allow mixed content.
24942526 bool enableWebSecurity = _config.Secure .Value ();
24952527#if WEBKIT_CHECK_VERSION(2, 38, 0)
@@ -2655,6 +2687,181 @@ namespace Plugin {
26552687 }
26562688 }
26572689
2690+ #if HAS_SCREEN_HDR_API
2691+ WPEFramework::PluginHost::IPlugin* QueryDisplayInfoPlugin ()
2692+ {
2693+ if (_displayInfoPlugin) {
2694+ return _displayInfoPlugin;
2695+ }
2696+ if (!_service) {
2697+ return nullptr ;
2698+ }
2699+ _displayInfoPlugin = _service->QueryInterfaceByCallsign <WPEFramework::PluginHost::IPlugin>(_T (" DisplayInfo" ));
2700+ if (!_displayInfoPlugin) {
2701+ SYSLOG (Logging::Error, (_T (" Failed to query DisplayInfo plugin." )));
2702+ return nullptr ;
2703+ }
2704+ return _displayInfoPlugin;
2705+ }
2706+
2707+ bool SubscribeHDRCapabilities ()
2708+ {
2709+ auto * displayInfoPlugin = QueryDisplayInfoPlugin ();
2710+ if (!displayInfoPlugin || _displayConnectionProps) {
2711+ return false ;
2712+ }
2713+ _displayConnectionProps = displayInfoPlugin->QueryInterface <Exchange::IConnectionProperties>();
2714+ if (!_displayConnectionProps) {
2715+ SYSLOG (Logging::Error, (_T (" Failed to query IConnectionProperties interface from DisplayInfo plugin." )));
2716+ return false ;
2717+ }
2718+ _displayConnectionProps->Register (this );
2719+ SYSLOG (Logging::Notification, (_T (" Subscribed to HDR capabilities updates from DisplayInfo plugin." )));
2720+ return true ;
2721+ }
2722+
2723+ void UnsubscribeHDRCapabilities ()
2724+ {
2725+ if (_displayConnectionProps) {
2726+ _displayConnectionProps->Unregister (this );
2727+ _displayConnectionProps->Release ();
2728+ _displayConnectionProps = nullptr ;
2729+ }
2730+ _adminLock.Lock ();
2731+ if (_hdrRefreshJob.IsValid ()) {
2732+ Core::WorkerPool::Instance ().Revoke (_hdrRefreshJob);
2733+ _hdrRefreshJob.Release ();
2734+ }
2735+ _adminLock.Unlock ();
2736+ if (_displayInfoPlugin) {
2737+ _displayInfoPlugin->Release ();
2738+ _displayInfoPlugin = nullptr ;
2739+ }
2740+ SYSLOG (Logging::Notification, (_T (" Unsubscribed from HDR capabilities updates from DisplayInfo plugin." )));
2741+ }
2742+
2743+ void RefreshHDRSupport ()
2744+ {
2745+ // HDR support will be set to false in case of any failure
2746+ bool isHDRSupported = false ;
2747+ struct ScopeExit {
2748+ bool & isHDRSupported;
2749+ WebKitImplementation& browser;
2750+ ~ScopeExit () {
2751+ browser._adminLock .Lock ();
2752+ bool wasSupported = browser._hdrSupported ;
2753+ browser._hdrSupported = isHDRSupported;
2754+ browser._adminLock .Unlock ();
2755+ if (wasSupported != isHDRSupported) {
2756+ SYSLOG (Logging::Notification, (_T (" HDR support changed to %s" ), isHDRSupported ? " true" : " false" ));
2757+ }
2758+ }
2759+ } scope_exit{isHDRSupported, *this };
2760+
2761+ auto displayInfoPlugin = QueryDisplayInfoPlugin ();
2762+ if (!displayInfoPlugin) {
2763+ return ;
2764+ }
2765+ Exchange::IHDRProperties* hdrPropIface = displayInfoPlugin->QueryInterface <Exchange::IHDRProperties>();
2766+ if (!hdrPropIface) {
2767+ SYSLOG (Logging::Error, (_T (" Failed to query IHDRProperties interface from DisplayInfo plugin." )));
2768+ return ;
2769+ }
2770+ uint32_t rc = Core::ERROR_NONE;
2771+ Exchange::IHDRProperties::IHDRIterator* iter = nullptr ;
2772+ if ((rc = hdrPropIface->STBCapabilities (iter)) != Core::ERROR_NONE) {
2773+ SYSLOG (Logging::Error, (_T (" Failed to get STB HDR capabilities, error code: %u" ), rc));
2774+ hdrPropIface->Release ();
2775+ return ;
2776+ }
2777+
2778+ std::vector<Exchange::IHDRProperties::HDRType> stbCaps;
2779+ Exchange::IHDRProperties::HDRType value;
2780+ while (iter->Next (value)) {
2781+ stbCaps.push_back (value);
2782+ }
2783+ iter->Release ();
2784+ iter = nullptr ;
2785+
2786+ if ((rc = hdrPropIface->TVCapabilities (iter)) != Core::ERROR_NONE) {
2787+ SYSLOG (Logging::Error, (_T (" Failed to get TV HDR capabilities, error code: %u" ), rc));
2788+ hdrPropIface->Release ();
2789+ return ;
2790+ }
2791+
2792+ std::vector<Exchange::IHDRProperties::HDRType> commonCaps;
2793+ while (iter->Next (value)) {
2794+ if (std::find (stbCaps.begin (), stbCaps.end (), value) != stbCaps.end ()) {
2795+ commonCaps.push_back (value);
2796+ }
2797+ }
2798+ iter->Release ();
2799+ hdrPropIface->Release ();
2800+
2801+ for (const auto & cap : commonCaps) {
2802+ if (cap > Exchange::IHDRProperties::HDRType::HDR_OFF) {
2803+ isHDRSupported = true ;
2804+ break ;
2805+ }
2806+ }
2807+ // _hdrSupported will be update in the scope exit handler
2808+ }
2809+
2810+ void UpdateHDRSettings (WebKitSettings* settings)
2811+ {
2812+ ASSERT (settings != nullptr );
2813+ _adminLock.Lock ();
2814+ bool isHDRSupported = _hdrSupported;
2815+ _adminLock.Unlock ();
2816+ if (webkit_settings_get_screen_supports_hdr (settings) != isHDRSupported) {
2817+ SYSLOG (Logging::Notification, (_T (" Updating HDR support setting to %s" ), isHDRSupported ? " true" : " false" ));
2818+ webkit_settings_set_screen_supports_hdr (settings, isHDRSupported);
2819+ }
2820+ }
2821+
2822+ class HDRRefreshJob : public Core ::IDispatch {
2823+ public:
2824+ HDRRefreshJob (WebKitImplementation& browser)
2825+ : _browser(browser)
2826+ {
2827+ }
2828+ ~HDRRefreshJob () override = default ;
2829+ void Dispatch () override
2830+ {
2831+ _browser.RefreshHDRSupport ();
2832+ g_main_context_invoke (
2833+ _browser._context ,
2834+ [](gpointer user_data) -> gboolean {
2835+ WebKitImplementation* browser = static_cast <WebKitImplementation*>(user_data);
2836+ WebKitSettings* settings = webkit_web_view_get_settings (browser->_view );
2837+ browser->UpdateHDRSettings (settings);
2838+ return G_SOURCE_REMOVE;
2839+ },
2840+ &_browser);
2841+ }
2842+ private:
2843+ WebKitImplementation& _browser;
2844+ };
2845+
2846+ // Exchange::IConnectionProperties::INotification implementation
2847+ // This method is called on the main thread of the plugin
2848+ // when the display connection properties are updated.
2849+ void Updated (const Exchange::IConnectionProperties::INotification::Source event) override
2850+ {
2851+ SYSLOG (Logging::Notification, (_T (" Display connection properties updated, event: %s" ),
2852+ Core::EnumerateType<Exchange::IConnectionProperties::INotification::Source>(event).Data ()));
2853+ _adminLock.Lock ();
2854+ if (!_hdrRefreshJob.IsValid ()) {
2855+ _hdrRefreshJob = Core::ProxyType<HDRRefreshJob>::Create (*this );
2856+ // If a refresh is already scheduled, do nothing
2857+ }
2858+ // Delay the refresh to avoid too frequent updates
2859+ // and to allow the display connection properties to stabilize.
2860+ Core::WorkerPool::Instance ().Reschedule (Core::Time::Now ().Add (_config.HDRRefreshDelay .Value ()), _hdrRefreshJob);
2861+ _adminLock.Unlock ();
2862+ }
2863+ #endif // HAS_SCREEN_HDR_API
2864+
26582865 void CheckWebProcess ()
26592866 {
26602867 if ( _webProcessCheckInProgress )
@@ -2790,6 +2997,13 @@ namespace Plugin {
27902997 uint32_t _unresponsiveReplyNum;
27912998 unsigned _frameCount;
27922999 gint64 _lastDumpTime;
3000+
3001+ #if HAS_SCREEN_HDR_API
3002+ PluginHost::IPlugin* _displayInfoPlugin;
3003+ Exchange::IConnectionProperties* _displayConnectionProps;
3004+ Core::ProxyType<Core::IDispatch> _hdrRefreshJob;
3005+ bool _hdrSupported;
3006+ #endif // HAS_SCREEN_HDR_API
27933007 };
27943008
27953009 SERVICE_REGISTRATION (WebKitImplementation, 1 , 0 );
0 commit comments