Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions platform/windows/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ from pathlib import Path

import platform_windows_builders

from methods import redirect_emitter
from methods import get_compiler_version, redirect_emitter

sources = []

Expand Down Expand Up @@ -92,8 +92,13 @@ if env["winrt"]:
env_winrt["CXXFLAGS"].remove("-fno-exceptions")
env_winrt.Append(CXXFLAGS=["-fexceptions"])
else:
cc_version = get_compiler_version(env)
cc_version_major = cc_version["major"]
if not env["use_llvm"]:
env_winrt.Append(CXXFLAGS=["/await"])
if cc_version_major >= 18:
env_winrt.Append(CXXFLAGS=["/await:strict"]) # /await is deprecated in MSVC 2026+
else:
env_winrt.Append(CXXFLAGS=["/await"])
if "/std:c++17" in env_winrt["CXXFLAGS"]:
env_winrt["CXXFLAGS"].remove("/std:c++17")
env_winrt.Append(CXXFLAGS=["/std:c++20"])
Expand Down
2 changes: 2 additions & 0 deletions platform/windows/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ def spawn_capture(sh, escape, cmd, args, env):
"ntdll",
"hid",
"mincore",
"coremessaging",
]

if env.debug_features:
Expand Down Expand Up @@ -823,6 +824,7 @@ def configure_mingw(env: "SConsEnvironment"):
"ntdll",
"hid",
"mincore",
"coremessaging",
]
)

Expand Down
103 changes: 64 additions & 39 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3407,48 +3407,61 @@ HWND DisplayServerWindows::_find_window_from_process_id(ProcessID p_pid, HWND p_
}

// Get screen HDR capabilities for internal use only.
DisplayServerWindows::ScreenHdrData DisplayServerWindows::_get_screen_hdr_data(int p_screen, bool p_include_sdr_white_level) const {
DisplayServerWindows::ScreenHdrData DisplayServerWindows::_get_screen_hdr_data(DisplayServerEnums::WindowID p_window, bool p_include_sdr_white_level) const {
ScreenHdrData data;
HMONITOR monitor = _get_hmonitor_of_screen(p_screen);
if (!monitor) {
return data;
}
const WindowData &wd = windows[p_window];
if (WinRTUtils::window_has_display_info(wd.wrt_wd)) {
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);
} else {
int screen = window_get_current_screen(p_window);
HMONITOR monitor = _get_hmonitor_of_screen(screen);
if (!monitor) {
return data;
}

#ifdef D3D12_ENABLED
// A dynamic cast is used here because the rendering context is not an Object and Object:cast is not supported.
RenderingContextDriverD3D12 *rendering_context_d3d12 = dynamic_cast<RenderingContextDriverD3D12 *>(rendering_context);
if (rendering_context_d3d12) {
IDXGIFactory2 *dxgi_factory = rendering_context_d3d12->dxgi_factory_get();
// A dynamic cast is used here because the rendering context is not an Object and Object:cast is not supported.
RenderingContextDriverD3D12 *rendering_context_d3d12 = dynamic_cast<RenderingContextDriverD3D12 *>(rendering_context);
if (rendering_context_d3d12) {
IDXGIFactory2 *dxgi_factory = rendering_context_d3d12->dxgi_factory_get();

DXGI_OUTPUT_DESC1 desc;
if (_get_monitor_desc(monitor, dxgi_factory, desc)) {
data.hdr_supported = desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
data.min_luminance = desc.MinLuminance;
data.max_luminance = desc.MaxLuminance;
data.max_average_luminance = desc.MaxFullFrameLuminance;
DXGI_OUTPUT_DESC1 desc;
if (_get_monitor_desc(monitor, dxgi_factory, desc)) {
data.hdr_supported = desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
data.min_luminance = desc.MinLuminance;
data.max_luminance = desc.MaxLuminance;
data.max_average_luminance = desc.MaxFullFrameLuminance;
}
}
}
#endif // D3D12_ENABLED

if (p_include_sdr_white_level) {
uint32_t path_count = 0;
uint32_t mode_count = 0;
if (p_include_sdr_white_level) {
uint32_t path_count = 0;
uint32_t mode_count = 0;

if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &path_count, &mode_count) == ERROR_SUCCESS) {
LocalVector<DISPLAYCONFIG_PATH_INFO> paths;
LocalVector<DISPLAYCONFIG_MODE_INFO> modes;
paths.resize(path_count);
modes.resize(mode_count);
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &path_count, &mode_count) == ERROR_SUCCESS) {
LocalVector<DISPLAYCONFIG_PATH_INFO> paths;
LocalVector<DISPLAYCONFIG_MODE_INFO> modes;
paths.resize(path_count);
modes.resize(mode_count);

if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &path_count, paths.ptr(), &mode_count, modes.ptr(), nullptr) == ERROR_SUCCESS) {
data.sdr_white_level = _get_sdr_white_level_for_hmonitor(monitor, paths);
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &path_count, paths.ptr(), &mode_count, modes.ptr(), nullptr) == ERROR_SUCCESS) {
data.sdr_white_level = _get_sdr_white_level_for_hmonitor(monitor, paths);
}
}
}
}

return data;
}

void DisplayServerWindows::_winrt_adv_color_info_cb(DisplayServerEnums::WindowID p_id) {
WindowData &wd = windows[p_id];

DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(p_id, true);
_update_hdr_output_for_window(p_id, wd, data);
}

void DisplayServerWindows::_update_hdr_output_for_window(DisplayServerEnums::WindowID p_window, const WindowData &p_window_data, ScreenHdrData p_screen_data) {
#ifdef RD_ENABLED
if (rendering_context) {
Expand Down Expand Up @@ -3494,15 +3507,18 @@ void DisplayServerWindows::_update_hdr_output_for_window(DisplayServerEnums::Win
#endif // RD_ENABLED
}

void DisplayServerWindows::_update_hdr_output_for_tracked_windows(bool p_include_sdr_white_level) {
void DisplayServerWindows::_legacy_update_hdr_output_for_tracked_windows(bool p_include_sdr_white_level) {
hdr_output_cache.clear();
for (const KeyValue<DisplayServerEnums::WindowID, WindowData> &E : windows) {
if (WinRTUtils::window_has_display_info(E.value.wrt_wd)) {
continue; // Updated by "_winrt_adv_color_info_cb" callback.
}
if (E.value.hdr_output_requested) {
int screen = window_get_current_screen(E.key);

ScreenHdrData data;
if (!hdr_output_cache.has(screen)) {
data = _get_screen_hdr_data(screen, p_include_sdr_white_level);
data = _get_screen_hdr_data(E.key, p_include_sdr_white_level);
hdr_output_cache.insert(screen, data);
} else {
data = hdr_output_cache[screen];
Expand Down Expand Up @@ -4211,7 +4227,7 @@ void DisplayServerWindows::process_events() {
// because the only way to adjust this is to leave the Godot Window and adjust the SDR/HDR
// Content Brightness Windows display setting. This means the user must return to the Godot
// window, which triggers a WM_WINDOWPOSCHANGED event.
_update_hdr_output_for_tracked_windows(false);
_legacy_update_hdr_output_for_tracked_windows(false);

LocalVector<List<FileDialogData *>::Element *> to_remove;
for (List<FileDialogData *>::Element *E = file_dialogs.front(); E; E = E->next()) {
Expand Down Expand Up @@ -4737,8 +4753,7 @@ bool DisplayServerWindows::window_is_hdr_output_supported(DisplayServerEnums::Wi
#endif

// The window supports HDR if the screen it is on supports HDR.
int screen = window_get_current_screen(p_window);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen, false);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(p_window, false);
return data.hdr_supported;
}

Expand All @@ -4752,8 +4767,7 @@ void DisplayServerWindows::window_request_hdr_output(const bool p_enable, Displa
WindowData &wd = windows[p_window];
wd.hdr_output_requested = p_enable;

int screen = window_get_current_screen(p_window);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen, true);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(p_window, true);
_update_hdr_output_for_window(p_window, wd, data);
}

Expand Down Expand Up @@ -4789,8 +4803,7 @@ void DisplayServerWindows::window_set_hdr_output_reference_luminance(const float

// Negative luminance means auto-adjust
if (wd.hdr_output_reference_luminance < 0.0f) {
int screen = window_get_current_screen(p_window);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen, true);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(p_window, true);
_update_hdr_output_for_window(p_window, wd, data);
} else {
// Otherwise, apply the requested luminance
Expand Down Expand Up @@ -4835,8 +4848,7 @@ void DisplayServerWindows::window_set_hdr_output_max_luminance(const float p_max

// Negative luminance means auto-adjust
if (wd.hdr_output_max_luminance < 0.0f) {
int screen = window_get_current_screen(p_window);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen, true);
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(p_window, true);
_update_hdr_output_for_window(p_window, wd, data);
} else {
// Otherwise, apply the requested luminance
Expand Down Expand Up @@ -6356,7 +6368,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA

case WM_DISPLAYCHANGE: {
// Update HDR capabilities and reference luminance when display changes.
_update_hdr_output_for_tracked_windows(true);
_legacy_update_hdr_output_for_tracked_windows(true);
} break;

case WM_WINDOWPOSCHANGED: {
Expand Down Expand Up @@ -6497,7 +6509,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Update HDR capabilities and reference luminance when window moves to different screen.
// Also update when Godot has regained focus because the user may have adjusted their SDR white
// level while Godot was not in focus.
_update_hdr_output_for_tracked_windows(true);
_legacy_update_hdr_output_for_tracked_windows(true);

// Return here to prevent WM_MOVE and WM_SIZE from being sent
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-windowposchanged#remarks
Expand Down Expand Up @@ -7036,6 +7048,10 @@ Error DisplayServerWindows::_create_window(DisplayServerEnums::WindowID p_window

wd.parent_hwnd = p_parent_hwnd;

if (has_winrt_queue) {
wd.wrt_wd = WinRTUtils::create_wd(wd.hWnd, callable_mp(this, &DisplayServerWindows::_winrt_adv_color_info_cb), wd.id);
}

// Detach the input queue from the parent window.
// This prevents the embedded window from waiting on the main window's input queue,
// causing lags input lags when resizing or moving the main window.
Expand Down Expand Up @@ -7228,6 +7244,9 @@ void DisplayServerWindows::_destroy_window(DisplayServerEnums::WindowID p_window
wd.icon_small = nullptr;
}

if (has_winrt_queue) {
WinRTUtils::destroy_wd(wd.wrt_wd);
}
DestroyWindow(wd.hWnd);
windows.erase(p_window_id);
}
Expand Down Expand Up @@ -7565,6 +7584,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Dis
}
native_menu = memnew(NativeMenuWindows);

has_winrt_queue = WinRTUtils::create_queue();

// Enforce default keep screen on value.
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));

Expand Down Expand Up @@ -8238,6 +8259,10 @@ DisplayServerWindows::~DisplayServerWindows() {

cursors_cache.clear();

if (has_winrt_queue) {
WinRTUtils::destroy_queue();
}

// Destroy all status indicators.
for (HashMap<DisplayServerEnums::IndicatorID, IndicatorData>::Iterator E = indicators.begin(); E; ++E) {
NOTIFYICONDATAW ndat;
Expand Down
9 changes: 7 additions & 2 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ typedef struct {
class DropTargetWindows;
class NativeMenuWindows;
class TTS_Windows;
class WinRTWindowData;

#ifndef WDA_EXCLUDEFROMCAPTURE
#define WDA_EXCLUDEFROMCAPTURE 0x00000011
Expand Down Expand Up @@ -282,9 +283,13 @@ class DisplayServerWindows : public DisplayServer {
NativeMenuWindows *native_menu = nullptr;
ITaskbarList3 *taskbar = nullptr;

bool has_winrt_queue = false;
void _winrt_adv_color_info_cb(DisplayServerEnums::WindowID p_id);

struct WindowData {
HWND hWnd;
DisplayServerEnums::WindowID id;
WinRTWindowData *wrt_wd = nullptr;

Vector<Vector2> mpath;
DisplayServerEnums::ProgressState progress_state = DisplayServerEnums::PROGRESS_STATE_NOPROGRESS;
Expand Down Expand Up @@ -556,9 +561,9 @@ class DisplayServerWindows : public DisplayServer {
};
AHashMap<int, ScreenHdrData> hdr_output_cache;

ScreenHdrData _get_screen_hdr_data(int p_screen, bool p_include_sdr_white_level) const;
ScreenHdrData _get_screen_hdr_data(DisplayServerEnums::WindowID p_window, bool p_include_sdr_white_level) const;
void _update_hdr_output_for_window(DisplayServerEnums::WindowID p_window, const WindowData &p_window_data, ScreenHdrData p_screen_data);
void _update_hdr_output_for_tracked_windows(bool p_include_sdr_white_level);
void _legacy_update_hdr_output_for_tracked_windows(bool p_include_sdr_white_level);

public:
LRESULT WndProcFileDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Expand Down
Loading