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:
@@ -334,6 +343,7 @@ namespace Plugin {
334343 , ICECandidateFilteringEnabled()
335344 , GstQuirks()
336345 , GstHolePunchQuirk()
346+ , HDRRefreshDelay(1000 ) // Default to 1 second for HDR refresh delay
337347 {
338348 Add (_T (" useragent" ), &UserAgent);
339349 Add (_T (" url" ), &URL);
@@ -406,6 +416,7 @@ namespace Plugin {
406416 Add (_T (" icecandidatefiltering" ), &ICECandidateFilteringEnabled);
407417 Add (_T (" gstquirks" ), &GstQuirks);
408418 Add (_T (" gstholepunchquirk" ), &GstHolePunchQuirk);
419+ Add (_T (" hdrrefreshDelay" ), &HDRRefreshDelay);
409420 }
410421 ~Config ()
411422 {
@@ -483,6 +494,7 @@ namespace Plugin {
483494 Core::JSON::Boolean ICECandidateFilteringEnabled;
484495 Core::JSON::String GstQuirks;
485496 Core::JSON::String GstHolePunchQuirk;
497+ Core::JSON::DecUInt16 HDRRefreshDelay; // Delay in miliseconds to refresh HDR support
486498 };
487499
488500 class HangDetector
@@ -622,6 +634,11 @@ namespace Plugin {
622634 , _unresponsiveReplyNum(0 )
623635 , _frameCount(0 )
624636 , _lastDumpTime(g_get_monotonic_time())
637+ #if HAS_SCREEN_HDR_API
638+ ,_displayInfoPlugin(nullptr )
639+ ,_displayConnectionProps(nullptr )
640+ ,_hdrSupported(false )
641+ #endif // HAS_SCREEN_HDR_API
625642 {
626643 // Register an @Exit, in case we are killed, with an incorrect ref count !!
627644 if (atexit (CloseDown) != 0 ) {
@@ -652,6 +669,10 @@ namespace Plugin {
652669 TRACE (Trace::Information, (_T (" Bailed out before the end of the WPE main app was reached. %d" ), 6000 ));
653670 }
654671
672+ #if HAS_SCREEN_HDR_API
673+ UnsubscribeHDRCapabilities ();
674+ #endif
675+
655676 implementation = nullptr ;
656677 }
657678
@@ -1935,6 +1956,7 @@ namespace Plugin {
19351956 _config.Bundle .Config (key,value);
19361957 return (value);
19371958 }
1959+
19381960 BEGIN_INTERFACE_MAP (WebKitImplementation)
19391961 INTERFACE_ENTRY (Exchange::IWebBrowser)
19401962 INTERFACE_ENTRY (Exchange::IBrowser)
@@ -1944,6 +1966,9 @@ namespace Plugin {
19441966 INTERFACE_ENTRY (Exchange::IBrowserCookieJar)
19451967#endif
19461968 INTERFACE_ENTRY (PluginHost::IStateControl)
1969+ #if HAS_SCREEN_HDR_API
1970+ INTERFACE_ENTRY (Exchange::IConnectionProperties::INotification)
1971+ #endif
19471972 END_INTERFACE_MAP
19481973
19491974 private:
@@ -2523,6 +2548,13 @@ namespace Plugin {
25232548 // webaudio support
25242549 webkit_settings_set_enable_webaudio (preferences, _config.WebAudioEnabled .Value ());
25252550
2551+ #if HAS_SCREEN_HDR_API
2552+ SubscribeHDRCapabilities ();
2553+ // Query the current HDR capabilities before we start the browser
2554+ RefreshHDRSupport ();
2555+ UpdateHDRSettings (preferences);
2556+ #endif
2557+
25262558 // Allow mixed content.
25272559 bool enableWebSecurity = _config.Secure .Value ();
25282560#if WEBKIT_CHECK_VERSION(2, 38, 0)
@@ -2688,6 +2720,181 @@ namespace Plugin {
26882720 }
26892721 }
26902722
2723+ #if HAS_SCREEN_HDR_API
2724+ WPEFramework::PluginHost::IPlugin* QueryDisplayInfoPlugin ()
2725+ {
2726+ if (_displayInfoPlugin) {
2727+ return _displayInfoPlugin;
2728+ }
2729+ if (!_service) {
2730+ return nullptr ;
2731+ }
2732+ _displayInfoPlugin = _service->QueryInterfaceByCallsign <WPEFramework::PluginHost::IPlugin>(_T (" DisplayInfo" ));
2733+ if (!_displayInfoPlugin) {
2734+ SYSLOG (Logging::Error, (_T (" Failed to query DisplayInfo plugin." )));
2735+ return nullptr ;
2736+ }
2737+ return _displayInfoPlugin;
2738+ }
2739+
2740+ bool SubscribeHDRCapabilities ()
2741+ {
2742+ auto * displayInfoPlugin = QueryDisplayInfoPlugin ();
2743+ if (!displayInfoPlugin || _displayConnectionProps) {
2744+ return false ;
2745+ }
2746+ _displayConnectionProps = displayInfoPlugin->QueryInterface <Exchange::IConnectionProperties>();
2747+ if (!_displayConnectionProps) {
2748+ SYSLOG (Logging::Error, (_T (" Failed to query IConnectionProperties interface from DisplayInfo plugin." )));
2749+ return false ;
2750+ }
2751+ _displayConnectionProps->Register (this );
2752+ SYSLOG (Logging::Notification, (_T (" Subscribed to HDR capabilities updates from DisplayInfo plugin." )));
2753+ return true ;
2754+ }
2755+
2756+ void UnsubscribeHDRCapabilities ()
2757+ {
2758+ if (_displayConnectionProps) {
2759+ _displayConnectionProps->Unregister (this );
2760+ _displayConnectionProps->Release ();
2761+ _displayConnectionProps = nullptr ;
2762+ }
2763+ _adminLock.Lock ();
2764+ if (_hdrRefreshJob.IsValid ()) {
2765+ Core::WorkerPool::Instance ().Revoke (_hdrRefreshJob);
2766+ _hdrRefreshJob.Release ();
2767+ }
2768+ _adminLock.Unlock ();
2769+ if (_displayInfoPlugin) {
2770+ _displayInfoPlugin->Release ();
2771+ _displayInfoPlugin = nullptr ;
2772+ }
2773+ SYSLOG (Logging::Notification, (_T (" Unsubscribed from HDR capabilities updates from DisplayInfo plugin." )));
2774+ }
2775+
2776+ void RefreshHDRSupport ()
2777+ {
2778+ // HDR support will be set to false in case of any failure
2779+ bool isHDRSupported = false ;
2780+ struct ScopeExit {
2781+ bool & isHDRSupported;
2782+ WebKitImplementation& browser;
2783+ ~ScopeExit () {
2784+ browser._adminLock .Lock ();
2785+ bool wasSupported = browser._hdrSupported ;
2786+ browser._hdrSupported = isHDRSupported;
2787+ browser._adminLock .Unlock ();
2788+ if (wasSupported != isHDRSupported) {
2789+ SYSLOG (Logging::Notification, (_T (" HDR support changed to %s" ), isHDRSupported ? " true" : " false" ));
2790+ }
2791+ }
2792+ } scope_exit{isHDRSupported, *this };
2793+
2794+ auto displayInfoPlugin = QueryDisplayInfoPlugin ();
2795+ if (!displayInfoPlugin) {
2796+ return ;
2797+ }
2798+ Exchange::IHDRProperties* hdrPropIface = displayInfoPlugin->QueryInterface <Exchange::IHDRProperties>();
2799+ if (!hdrPropIface) {
2800+ SYSLOG (Logging::Error, (_T (" Failed to query IHDRProperties interface from DisplayInfo plugin." )));
2801+ return ;
2802+ }
2803+ uint32_t rc = Core::ERROR_NONE;
2804+ Exchange::IHDRProperties::IHDRIterator* iter = nullptr ;
2805+ if ((rc = hdrPropIface->STBCapabilities (iter)) != Core::ERROR_NONE) {
2806+ SYSLOG (Logging::Error, (_T (" Failed to get STB HDR capabilities, error code: %u" ), rc));
2807+ hdrPropIface->Release ();
2808+ return ;
2809+ }
2810+
2811+ std::vector<Exchange::IHDRProperties::HDRType> stbCaps;
2812+ Exchange::IHDRProperties::HDRType value;
2813+ while (iter->Next (value)) {
2814+ stbCaps.push_back (value);
2815+ }
2816+ iter->Release ();
2817+ iter = nullptr ;
2818+
2819+ if ((rc = hdrPropIface->TVCapabilities (iter)) != Core::ERROR_NONE) {
2820+ SYSLOG (Logging::Error, (_T (" Failed to get TV HDR capabilities, error code: %u" ), rc));
2821+ hdrPropIface->Release ();
2822+ return ;
2823+ }
2824+
2825+ std::vector<Exchange::IHDRProperties::HDRType> commonCaps;
2826+ while (iter->Next (value)) {
2827+ if (std::find (stbCaps.begin (), stbCaps.end (), value) != stbCaps.end ()) {
2828+ commonCaps.push_back (value);
2829+ }
2830+ }
2831+ iter->Release ();
2832+ hdrPropIface->Release ();
2833+
2834+ for (const auto & cap : commonCaps) {
2835+ if (cap > Exchange::IHDRProperties::HDRType::HDR_OFF) {
2836+ isHDRSupported = true ;
2837+ break ;
2838+ }
2839+ }
2840+ // _hdrSupported will be update in the scope exit handler
2841+ }
2842+
2843+ void UpdateHDRSettings (WebKitSettings* settings)
2844+ {
2845+ ASSERT (settings != nullptr );
2846+ _adminLock.Lock ();
2847+ bool isHDRSupported = _hdrSupported;
2848+ _adminLock.Unlock ();
2849+ if (webkit_settings_get_screen_supports_hdr (settings) != isHDRSupported) {
2850+ SYSLOG (Logging::Notification, (_T (" Updating HDR support setting to %s" ), isHDRSupported ? " true" : " false" ));
2851+ webkit_settings_set_screen_supports_hdr (settings, isHDRSupported);
2852+ }
2853+ }
2854+
2855+ class HDRRefreshJob : public Core ::IDispatch {
2856+ public:
2857+ HDRRefreshJob (WebKitImplementation& browser)
2858+ : _browser(browser)
2859+ {
2860+ }
2861+ ~HDRRefreshJob () override = default ;
2862+ void Dispatch () override
2863+ {
2864+ _browser.RefreshHDRSupport ();
2865+ g_main_context_invoke (
2866+ _browser._context ,
2867+ [](gpointer user_data) -> gboolean {
2868+ WebKitImplementation* browser = static_cast <WebKitImplementation*>(user_data);
2869+ WebKitSettings* settings = webkit_web_view_get_settings (browser->_view );
2870+ browser->UpdateHDRSettings (settings);
2871+ return G_SOURCE_REMOVE;
2872+ },
2873+ &_browser);
2874+ }
2875+ private:
2876+ WebKitImplementation& _browser;
2877+ };
2878+
2879+ // Exchange::IConnectionProperties::INotification implementation
2880+ // This method is called on the main thread of the plugin
2881+ // when the display connection properties are updated.
2882+ void Updated (const Exchange::IConnectionProperties::INotification::Source event) override
2883+ {
2884+ SYSLOG (Logging::Notification, (_T (" Display connection properties updated, event: %s" ),
2885+ Core::EnumerateType<Exchange::IConnectionProperties::INotification::Source>(event).Data ()));
2886+ _adminLock.Lock ();
2887+ if (!_hdrRefreshJob.IsValid ()) {
2888+ _hdrRefreshJob = Core::ProxyType<HDRRefreshJob>::Create (*this );
2889+ // If a refresh is already scheduled, do nothing
2890+ }
2891+ // Delay the refresh to avoid too frequent updates
2892+ // and to allow the display connection properties to stabilize.
2893+ Core::WorkerPool::Instance ().Reschedule (Core::Time::Now ().Add (_config.HDRRefreshDelay .Value ()), _hdrRefreshJob);
2894+ _adminLock.Unlock ();
2895+ }
2896+ #endif // HAS_SCREEN_HDR_API
2897+
26912898 void CheckWebProcess ()
26922899 {
26932900 if ( _webProcessCheckInProgress )
@@ -2823,6 +3030,13 @@ namespace Plugin {
28233030 uint32_t _unresponsiveReplyNum;
28243031 unsigned _frameCount;
28253032 gint64 _lastDumpTime;
3033+
3034+ #if HAS_SCREEN_HDR_API
3035+ PluginHost::IPlugin* _displayInfoPlugin;
3036+ Exchange::IConnectionProperties* _displayConnectionProps;
3037+ Core::ProxyType<Core::IDispatch> _hdrRefreshJob;
3038+ bool _hdrSupported;
3039+ #endif // HAS_SCREEN_HDR_API
28263040 };
28273041
28283042 SERVICE_REGISTRATION (WebKitImplementation, 1 , 0 );
0 commit comments