46
46
47
47
#define HAS_MEMORY_PRESSURE_SETTINGS_API WEBKIT_CHECK_VERSION (2 , 38 , 0 )
48
48
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
+
49
54
#ifdef ENABLE_TESTING
50
55
#include < testrunner.h>
51
56
#endif // ENABLE_TESTING
@@ -78,7 +83,11 @@ namespace Plugin {
78
83
#if defined(ENABLE_CLOUD_COOKIE_JAR)
79
84
public Exchange::IBrowserCookieJar,
80
85
#endif
81
- public PluginHost::IStateControl {
86
+ public PluginHost::IStateControl
87
+ #if HAS_SCREEN_HDR_API
88
+ , public Exchange::IConnectionProperties::INotification
89
+ #endif
90
+ {
82
91
public:
83
92
class BundleConfig : public Core ::JSON::Container {
84
93
private:
@@ -333,6 +342,7 @@ namespace Plugin {
333
342
, ICECandidateFilteringEnabled()
334
343
, GstQuirks()
335
344
, GstHolePunchQuirk()
345
+ , HDRRefreshDelay(1000 ) // Default to 1 second for HDR refresh delay
336
346
{
337
347
Add (_T (" useragent" ), &UserAgent);
338
348
Add (_T (" url" ), &URL);
@@ -404,6 +414,7 @@ namespace Plugin {
404
414
Add (_T (" icecandidatefiltering" ), &ICECandidateFilteringEnabled);
405
415
Add (_T (" gstquirks" ), &GstQuirks);
406
416
Add (_T (" gstholepunchquirk" ), &GstHolePunchQuirk);
417
+ Add (_T (" hdrrefreshDelay" ), &HDRRefreshDelay);
407
418
}
408
419
~Config ()
409
420
{
@@ -480,6 +491,7 @@ namespace Plugin {
480
491
Core::JSON::Boolean ICECandidateFilteringEnabled;
481
492
Core::JSON::String GstQuirks;
482
493
Core::JSON::String GstHolePunchQuirk;
494
+ Core::JSON::DecUInt16 HDRRefreshDelay; // Delay in miliseconds to refresh HDR support
483
495
};
484
496
485
497
class HangDetector
@@ -619,6 +631,11 @@ namespace Plugin {
619
631
, _unresponsiveReplyNum(0 )
620
632
, _frameCount(0 )
621
633
, _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
622
639
{
623
640
// Register an @Exit, in case we are killed, with an incorrect ref count !!
624
641
if (atexit (CloseDown) != 0 ) {
@@ -649,6 +666,10 @@ namespace Plugin {
649
666
TRACE (Trace::Information, (_T (" Bailed out before the end of the WPE main app was reached. %d" ), 6000 ));
650
667
}
651
668
669
+ #if HAS_SCREEN_HDR_API
670
+ UnsubscribeHDRCapabilities ();
671
+ #endif
672
+
652
673
implementation = nullptr ;
653
674
}
654
675
@@ -1927,6 +1948,7 @@ namespace Plugin {
1927
1948
_config.Bundle .Config (key,value);
1928
1949
return (value);
1929
1950
}
1951
+
1930
1952
BEGIN_INTERFACE_MAP (WebKitImplementation)
1931
1953
INTERFACE_ENTRY (Exchange::IWebBrowser)
1932
1954
INTERFACE_ENTRY (Exchange::IBrowser)
@@ -1936,6 +1958,9 @@ namespace Plugin {
1936
1958
INTERFACE_ENTRY (Exchange::IBrowserCookieJar)
1937
1959
#endif
1938
1960
INTERFACE_ENTRY (PluginHost::IStateControl)
1961
+ #if HAS_SCREEN_HDR_API
1962
+ INTERFACE_ENTRY (Exchange::IConnectionProperties::INotification)
1963
+ #endif
1939
1964
END_INTERFACE_MAP
1940
1965
1941
1966
private:
@@ -2490,6 +2515,13 @@ namespace Plugin {
2490
2515
// webaudio support
2491
2516
webkit_settings_set_enable_webaudio (preferences, _config.WebAudioEnabled .Value ());
2492
2517
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
+
2493
2525
// Allow mixed content.
2494
2526
bool enableWebSecurity = _config.Secure .Value ();
2495
2527
#if WEBKIT_CHECK_VERSION(2, 38, 0)
@@ -2655,6 +2687,181 @@ namespace Plugin {
2655
2687
}
2656
2688
}
2657
2689
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
+
2658
2865
void CheckWebProcess ()
2659
2866
{
2660
2867
if ( _webProcessCheckInProgress )
@@ -2790,6 +2997,13 @@ namespace Plugin {
2790
2997
uint32_t _unresponsiveReplyNum;
2791
2998
unsigned _frameCount;
2792
2999
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
2793
3007
};
2794
3008
2795
3009
SERVICE_REGISTRATION (WebKitImplementation, 1 , 0 );
0 commit comments