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:
@@ -334,6 +343,7 @@ namespace Plugin {
334
343
, ICECandidateFilteringEnabled()
335
344
, GstQuirks()
336
345
, GstHolePunchQuirk()
346
+ , HDRRefreshDelay(1000 ) // Default to 1 second for HDR refresh delay
337
347
{
338
348
Add (_T (" useragent" ), &UserAgent);
339
349
Add (_T (" url" ), &URL);
@@ -406,6 +416,7 @@ namespace Plugin {
406
416
Add (_T (" icecandidatefiltering" ), &ICECandidateFilteringEnabled);
407
417
Add (_T (" gstquirks" ), &GstQuirks);
408
418
Add (_T (" gstholepunchquirk" ), &GstHolePunchQuirk);
419
+ Add (_T (" hdrrefreshDelay" ), &HDRRefreshDelay);
409
420
}
410
421
~Config ()
411
422
{
@@ -483,6 +494,7 @@ namespace Plugin {
483
494
Core::JSON::Boolean ICECandidateFilteringEnabled;
484
495
Core::JSON::String GstQuirks;
485
496
Core::JSON::String GstHolePunchQuirk;
497
+ Core::JSON::DecUInt16 HDRRefreshDelay; // Delay in miliseconds to refresh HDR support
486
498
};
487
499
488
500
class HangDetector
@@ -622,6 +634,11 @@ namespace Plugin {
622
634
, _unresponsiveReplyNum(0 )
623
635
, _frameCount(0 )
624
636
, _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
625
642
{
626
643
// Register an @Exit, in case we are killed, with an incorrect ref count !!
627
644
if (atexit (CloseDown) != 0 ) {
@@ -652,6 +669,10 @@ namespace Plugin {
652
669
TRACE (Trace::Information, (_T (" Bailed out before the end of the WPE main app was reached. %d" ), 6000 ));
653
670
}
654
671
672
+ #if HAS_SCREEN_HDR_API
673
+ UnsubscribeHDRCapabilities ();
674
+ #endif
675
+
655
676
implementation = nullptr ;
656
677
}
657
678
@@ -1935,6 +1956,7 @@ namespace Plugin {
1935
1956
_config.Bundle .Config (key,value);
1936
1957
return (value);
1937
1958
}
1959
+
1938
1960
BEGIN_INTERFACE_MAP (WebKitImplementation)
1939
1961
INTERFACE_ENTRY (Exchange::IWebBrowser)
1940
1962
INTERFACE_ENTRY (Exchange::IBrowser)
@@ -1944,6 +1966,9 @@ namespace Plugin {
1944
1966
INTERFACE_ENTRY (Exchange::IBrowserCookieJar)
1945
1967
#endif
1946
1968
INTERFACE_ENTRY (PluginHost::IStateControl)
1969
+ #if HAS_SCREEN_HDR_API
1970
+ INTERFACE_ENTRY (Exchange::IConnectionProperties::INotification)
1971
+ #endif
1947
1972
END_INTERFACE_MAP
1948
1973
1949
1974
private:
@@ -2523,6 +2548,13 @@ namespace Plugin {
2523
2548
// webaudio support
2524
2549
webkit_settings_set_enable_webaudio (preferences, _config.WebAudioEnabled .Value ());
2525
2550
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
+
2526
2558
// Allow mixed content.
2527
2559
bool enableWebSecurity = _config.Secure .Value ();
2528
2560
#if WEBKIT_CHECK_VERSION(2, 38, 0)
@@ -2688,6 +2720,181 @@ namespace Plugin {
2688
2720
}
2689
2721
}
2690
2722
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
+
2691
2898
void CheckWebProcess ()
2692
2899
{
2693
2900
if ( _webProcessCheckInProgress )
@@ -2823,6 +3030,13 @@ namespace Plugin {
2823
3030
uint32_t _unresponsiveReplyNum;
2824
3031
unsigned _frameCount;
2825
3032
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
2826
3040
};
2827
3041
2828
3042
SERVICE_REGISTRATION (WebKitImplementation, 1 , 0 );
0 commit comments