@@ -3407,48 +3407,61 @@ HWND DisplayServerWindows::_find_window_from_process_id(ProcessID p_pid, HWND p_
34073407}
34083408
34093409// Get screen HDR capabilities for internal use only.
3410- DisplayServerWindows::ScreenHdrData DisplayServerWindows::_get_screen_hdr_data (int p_screen , bool p_include_sdr_white_level) const {
3410+ DisplayServerWindows::ScreenHdrData DisplayServerWindows::_get_screen_hdr_data (DisplayServerEnums::WindowID p_window , bool p_include_sdr_white_level) const {
34113411 ScreenHdrData data;
3412- HMONITOR monitor = _get_hmonitor_of_screen (p_screen);
3413- if (!monitor) {
3414- return data;
3415- }
3412+ const WindowData &wd = windows[p_window];
3413+ if (WinRTUtils::window_has_display_info (wd.wrt_wd )) {
3414+ WinRTUtils::window_get_advanced_color_info (wd.wrt_wd , data.hdr_supported , data.min_luminance , data.max_luminance , data.max_average_luminance , data.sdr_white_level );
3415+ } else {
3416+ int screen = window_get_current_screen (p_window);
3417+ HMONITOR monitor = _get_hmonitor_of_screen (screen);
3418+ if (!monitor) {
3419+ return data;
3420+ }
34163421
34173422#ifdef D3D12_ENABLED
3418- // A dynamic cast is used here because the rendering context is not an Object and Object:cast is not supported.
3419- RenderingContextDriverD3D12 *rendering_context_d3d12 = dynamic_cast <RenderingContextDriverD3D12 *>(rendering_context);
3420- if (rendering_context_d3d12) {
3421- IDXGIFactory2 *dxgi_factory = rendering_context_d3d12->dxgi_factory_get ();
3423+ // A dynamic cast is used here because the rendering context is not an Object and Object:cast is not supported.
3424+ RenderingContextDriverD3D12 *rendering_context_d3d12 = dynamic_cast <RenderingContextDriverD3D12 *>(rendering_context);
3425+ if (rendering_context_d3d12) {
3426+ IDXGIFactory2 *dxgi_factory = rendering_context_d3d12->dxgi_factory_get ();
34223427
3423- DXGI_OUTPUT_DESC1 desc;
3424- if (_get_monitor_desc (monitor, dxgi_factory, desc)) {
3425- data.hdr_supported = desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 ;
3426- data.min_luminance = desc.MinLuminance ;
3427- data.max_luminance = desc.MaxLuminance ;
3428- data.max_average_luminance = desc.MaxFullFrameLuminance ;
3428+ DXGI_OUTPUT_DESC1 desc;
3429+ if (_get_monitor_desc (monitor, dxgi_factory, desc)) {
3430+ data.hdr_supported = desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 ;
3431+ data.min_luminance = desc.MinLuminance ;
3432+ data.max_luminance = desc.MaxLuminance ;
3433+ data.max_average_luminance = desc.MaxFullFrameLuminance ;
3434+ }
34293435 }
3430- }
34313436#endif // D3D12_ENABLED
34323437
3433- if (p_include_sdr_white_level) {
3434- uint32_t path_count = 0 ;
3435- uint32_t mode_count = 0 ;
3438+ if (p_include_sdr_white_level) {
3439+ uint32_t path_count = 0 ;
3440+ uint32_t mode_count = 0 ;
34363441
3437- if (GetDisplayConfigBufferSizes (QDC_ONLY_ACTIVE_PATHS , &path_count, &mode_count) == ERROR_SUCCESS ) {
3438- LocalVector<DISPLAYCONFIG_PATH_INFO > paths;
3439- LocalVector<DISPLAYCONFIG_MODE_INFO > modes;
3440- paths.resize (path_count);
3441- modes.resize (mode_count);
3442+ if (GetDisplayConfigBufferSizes (QDC_ONLY_ACTIVE_PATHS , &path_count, &mode_count) == ERROR_SUCCESS ) {
3443+ LocalVector<DISPLAYCONFIG_PATH_INFO > paths;
3444+ LocalVector<DISPLAYCONFIG_MODE_INFO > modes;
3445+ paths.resize (path_count);
3446+ modes.resize (mode_count);
34423447
3443- if (QueryDisplayConfig (QDC_ONLY_ACTIVE_PATHS , &path_count, paths.ptr (), &mode_count, modes.ptr (), nullptr ) == ERROR_SUCCESS ) {
3444- data.sdr_white_level = _get_sdr_white_level_for_hmonitor (monitor, paths);
3448+ if (QueryDisplayConfig (QDC_ONLY_ACTIVE_PATHS , &path_count, paths.ptr (), &mode_count, modes.ptr (), nullptr ) == ERROR_SUCCESS ) {
3449+ data.sdr_white_level = _get_sdr_white_level_for_hmonitor (monitor, paths);
3450+ }
34453451 }
34463452 }
34473453 }
34483454
34493455 return data;
34503456}
34513457
3458+ void DisplayServerWindows::_winrt_adv_color_info_cb (DisplayServerEnums::WindowID p_id) {
3459+ WindowData &wd = windows[p_id];
3460+
3461+ DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (p_id, true );
3462+ _update_hdr_output_for_window (p_id, wd, data);
3463+ }
3464+
34523465void DisplayServerWindows::_update_hdr_output_for_window (DisplayServerEnums::WindowID p_window, const WindowData &p_window_data, ScreenHdrData p_screen_data) {
34533466#ifdef RD_ENABLED
34543467 if (rendering_context) {
@@ -3494,15 +3507,18 @@ void DisplayServerWindows::_update_hdr_output_for_window(DisplayServerEnums::Win
34943507#endif // RD_ENABLED
34953508}
34963509
3497- void DisplayServerWindows::_update_hdr_output_for_tracked_windows (bool p_include_sdr_white_level) {
3510+ void DisplayServerWindows::_legacy_update_hdr_output_for_tracked_windows (bool p_include_sdr_white_level) {
34983511 hdr_output_cache.clear ();
34993512 for (const KeyValue<DisplayServerEnums::WindowID, WindowData> &E : windows) {
3513+ if (WinRTUtils::window_has_display_info (E.value .wrt_wd )) {
3514+ continue ; // Updated by "_winrt_adv_color_info_cb" callback.
3515+ }
35003516 if (E.value .hdr_output_requested ) {
35013517 int screen = window_get_current_screen (E.key );
35023518
35033519 ScreenHdrData data;
35043520 if (!hdr_output_cache.has (screen)) {
3505- data = _get_screen_hdr_data (screen , p_include_sdr_white_level);
3521+ data = _get_screen_hdr_data (E. key , p_include_sdr_white_level);
35063522 hdr_output_cache.insert (screen, data);
35073523 } else {
35083524 data = hdr_output_cache[screen];
@@ -4211,7 +4227,7 @@ void DisplayServerWindows::process_events() {
42114227 // because the only way to adjust this is to leave the Godot Window and adjust the SDR/HDR
42124228 // Content Brightness Windows display setting. This means the user must return to the Godot
42134229 // window, which triggers a WM_WINDOWPOSCHANGED event.
4214- _update_hdr_output_for_tracked_windows (false );
4230+ _legacy_update_hdr_output_for_tracked_windows (false );
42154231
42164232 LocalVector<List<FileDialogData *>::Element *> to_remove;
42174233 for (List<FileDialogData *>::Element *E = file_dialogs.front (); E; E = E->next ()) {
@@ -4737,8 +4753,7 @@ bool DisplayServerWindows::window_is_hdr_output_supported(DisplayServerEnums::Wi
47374753#endif
47384754
47394755 // The window supports HDR if the screen it is on supports HDR.
4740- int screen = window_get_current_screen (p_window);
4741- DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (screen, false );
4756+ DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (p_window, false );
47424757 return data.hdr_supported ;
47434758}
47444759
@@ -4752,8 +4767,7 @@ void DisplayServerWindows::window_request_hdr_output(const bool p_enable, Displa
47524767 WindowData &wd = windows[p_window];
47534768 wd.hdr_output_requested = p_enable;
47544769
4755- int screen = window_get_current_screen (p_window);
4756- DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (screen, true );
4770+ DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (p_window, true );
47574771 _update_hdr_output_for_window (p_window, wd, data);
47584772}
47594773
@@ -4789,8 +4803,7 @@ void DisplayServerWindows::window_set_hdr_output_reference_luminance(const float
47894803
47904804 // Negative luminance means auto-adjust
47914805 if (wd.hdr_output_reference_luminance < 0 .0f ) {
4792- int screen = window_get_current_screen (p_window);
4793- DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (screen, true );
4806+ DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (p_window, true );
47944807 _update_hdr_output_for_window (p_window, wd, data);
47954808 } else {
47964809 // Otherwise, apply the requested luminance
@@ -4835,8 +4848,7 @@ void DisplayServerWindows::window_set_hdr_output_max_luminance(const float p_max
48354848
48364849 // Negative luminance means auto-adjust
48374850 if (wd.hdr_output_max_luminance < 0 .0f ) {
4838- int screen = window_get_current_screen (p_window);
4839- DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (screen, true );
4851+ DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data (p_window, true );
48404852 _update_hdr_output_for_window (p_window, wd, data);
48414853 } else {
48424854 // Otherwise, apply the requested luminance
@@ -6356,7 +6368,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
63566368
63576369 case WM_DISPLAYCHANGE : {
63586370 // Update HDR capabilities and reference luminance when display changes.
6359- _update_hdr_output_for_tracked_windows (true );
6371+ _legacy_update_hdr_output_for_tracked_windows (true );
63606372 } break ;
63616373
63626374 case WM_WINDOWPOSCHANGED : {
@@ -6497,7 +6509,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
64976509 // Update HDR capabilities and reference luminance when window moves to different screen.
64986510 // Also update when Godot has regained focus because the user may have adjusted their SDR white
64996511 // level while Godot was not in focus.
6500- _update_hdr_output_for_tracked_windows (true );
6512+ _legacy_update_hdr_output_for_tracked_windows (true );
65016513
65026514 // Return here to prevent WM_MOVE and WM_SIZE from being sent
65036515 // See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-windowposchanged#remarks
@@ -7036,6 +7048,10 @@ Error DisplayServerWindows::_create_window(DisplayServerEnums::WindowID p_window
70367048
70377049 wd.parent_hwnd = p_parent_hwnd;
70387050
7051+ if (has_winrt_queue) {
7052+ wd.wrt_wd = WinRTUtils::create_wd (wd.hWnd , callable_mp (this , &DisplayServerWindows::_winrt_adv_color_info_cb), wd.id );
7053+ }
7054+
70397055 // Detach the input queue from the parent window.
70407056 // This prevents the embedded window from waiting on the main window's input queue,
70417057 // causing lags input lags when resizing or moving the main window.
@@ -7228,6 +7244,9 @@ void DisplayServerWindows::_destroy_window(DisplayServerEnums::WindowID p_window
72287244 wd.icon_small = nullptr ;
72297245 }
72307246
7247+ if (has_winrt_queue) {
7248+ WinRTUtils::destroy_wd (wd.wrt_wd );
7249+ }
72317250 DestroyWindow (wd.hWnd );
72327251 windows.erase (p_window_id);
72337252}
@@ -7565,6 +7584,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Dis
75657584 }
75667585 native_menu = memnew (NativeMenuWindows);
75677586
7587+ has_winrt_queue = WinRTUtils::create_queue ();
7588+
75687589 // Enforce default keep screen on value.
75697590 screen_set_keep_on (GLOBAL_GET (" display/window/energy_saving/keep_screen_on" ));
75707591
@@ -8238,6 +8259,10 @@ DisplayServerWindows::~DisplayServerWindows() {
82388259
82398260 cursors_cache.clear ();
82408261
8262+ if (has_winrt_queue) {
8263+ WinRTUtils::destroy_queue ();
8264+ }
8265+
82418266 // Destroy all status indicators.
82428267 for (HashMap<DisplayServerEnums::IndicatorID, IndicatorData>::Iterator E = indicators.begin (); E; ++E) {
82438268 NOTIFYICONDATAW ndat;
0 commit comments