From 7d04612d064946ad8ffe016604baa84fc2c9d980 Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Sat, 9 May 2026 16:38:11 +0300 Subject: [PATCH] UI: use atomics for window handle display/surface --- .../Latte/Renderer/Metal/MetalLayerHandle.cpp | 2 +- .../HW/Latte/Renderer/Vulkan/VsyncDriver.cpp | 4 +-- .../Latte/Renderer/Vulkan/VulkanRenderer.cpp | 16 +++++------ src/audio/DirectSoundAPI.cpp | 2 +- src/gui/interface/WindowSystem.h | 28 +++++++++++++++++-- src/gui/wxgui/helpers/wxHelpers.cpp | 2 +- src/imgui/imgui_extension.cpp | 2 +- .../api/DirectInput/DirectInputController.cpp | 2 +- 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp index ddc94177..408350e7 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp @@ -7,7 +7,7 @@ MetalLayerHandle::MetalLayerHandle(MTL::Device* device, const Vector2i& size, bo { const auto& windowInfo = (mainWindow ? WindowSystem::GetWindowInfo().window_main : WindowSystem::GetWindowInfo().window_pad); - m_layer = (CA::MetalLayer*)CreateMetalLayer(windowInfo.surface, m_layerScaleX, m_layerScaleY); + m_layer = (CA::MetalLayer*)CreateMetalLayer(windowInfo.surface.load(), m_layerScaleX, m_layerScaleY); m_layer->setDevice(device); m_layer->setDrawableSize(CGSize{(float)size.x * m_layerScaleX, (float)size.y * m_layerScaleY}); m_layer->setFramebufferOnly(true); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp index 64cbbb6b..4f26cff3 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.cpp @@ -53,7 +53,7 @@ public: private: bool HasMonitorChanged() { - HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface; + HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface.load(std::memory_order::relaxed); if (hWnd == 0) return true; HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); @@ -71,7 +71,7 @@ private: HRESULT GetAdapterHandleFromHwnd(D3DKMT_HANDLE* phAdapter, UINT* pOutput) { - HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface; + HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface.load(std::memory_order::relaxed); if (hWnd == 0) return E_FAIL; diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index eeba119e..99ba79f1 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -1633,17 +1633,17 @@ VkSurfaceKHR VulkanRenderer::CreateWaylandSurface(VkInstance instance, wl_displa VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, WindowSystem::WindowHandleInfo& windowInfo) { #if BOOST_OS_WINDOWS - return CreateWinSurface(instance, static_cast(windowInfo.surface)); + return CreateWinSurface(instance, static_cast(windowInfo.surface.load())); #elif BOOST_OS_LINUX || BOOST_OS_BSD - if(windowInfo.backend == WindowSystem::WindowHandleInfo::Backend::X11) - return CreateXlibSurface(instance, static_cast(windowInfo.display), reinterpret_cast(windowInfo.surface)); - #ifdef HAS_WAYLAND - if(windowInfo.backend == WindowSystem::WindowHandleInfo::Backend::Wayland) - return CreateWaylandSurface(instance, static_cast(windowInfo.display), static_cast(windowInfo.surface)); - #endif + if (windowInfo.backend == WindowSystem::WindowHandleInfo::Backend::X11) + return CreateXlibSurface(instance, static_cast(windowInfo.display.load()), reinterpret_cast(windowInfo.surface.load())); +#ifdef HAS_WAYLAND + if (windowInfo.backend == WindowSystem::WindowHandleInfo::Backend::Wayland) + return CreateWaylandSurface(instance, static_cast(windowInfo.display.load()), static_cast(windowInfo.surface.load())); +#endif return {}; #elif BOOST_OS_MACOS - return CreateCocoaSurface(instance, windowInfo.surface); + return CreateCocoaSurface(instance, windowInfo.surface.load()); #endif } diff --git a/src/audio/DirectSoundAPI.cpp b/src/audio/DirectSoundAPI.cpp index d14531eb..77939dfb 100644 --- a/src/audio/DirectSoundAPI.cpp +++ b/src/audio/DirectSoundAPI.cpp @@ -17,7 +17,7 @@ DirectSoundAPI::DirectSoundAPI(GUID* guid, sint32 samplerate, sint32 channels, s if (DirectSoundCreate8(guid, &m_direct_sound, nullptr) != DS_OK) throw std::runtime_error("can't create directsound device"); - if (FAILED(m_direct_sound->SetCooperativeLevel(static_cast(WindowSystem::GetWindowInfo().window_main.surface), DSSCL_PRIORITY))) + if (FAILED(m_direct_sound->SetCooperativeLevel(static_cast(WindowSystem::GetWindowInfo().window_main.surface.load()), DSSCL_PRIORITY))) throw std::runtime_error("can't set directsound priority"); DSBUFFERDESC bd{}; diff --git a/src/gui/interface/WindowSystem.h b/src/gui/interface/WindowSystem.h index b2346c17..08790bc2 100644 --- a/src/gui/interface/WindowSystem.h +++ b/src/gui/interface/WindowSystem.h @@ -13,8 +13,32 @@ namespace WindowSystem Cocoa, Windows, } backend; - void* display = nullptr; - void* surface = nullptr; + std::atomic display = nullptr; + std::atomic surface = nullptr; + + WindowHandleInfo() = default; + + WindowHandleInfo(WindowHandleInfo&& other) noexcept + : backend(other.backend), + display(other.display.exchange(nullptr)), + surface(other.surface.exchange(nullptr)) + { + } + + WindowHandleInfo(const WindowHandleInfo&) = delete; + WindowHandleInfo& operator=(const WindowHandleInfo&) = delete; + + WindowHandleInfo& operator=(WindowHandleInfo&& other) noexcept + { + if (this != &other) + { + backend = other.backend; + display.store(other.display.exchange(nullptr)); + surface.store(other.surface.exchange(nullptr)); + } + + return *this; + } }; enum struct PlatformKeyCodes : uint32 diff --git a/src/gui/wxgui/helpers/wxHelpers.cpp b/src/gui/wxgui/helpers/wxHelpers.cpp index 0d734372..46663d32 100644 --- a/src/gui/wxgui/helpers/wxHelpers.cpp +++ b/src/gui/wxgui/helpers/wxHelpers.cpp @@ -112,5 +112,5 @@ WindowSystem::WindowHandleInfo initHandleContextFromWxWidgetsWindow(wxWindow* wx handleInfo.backend = WindowSystem::WindowHandleInfo::Backend::Cocoa; handleInfo.surface = reinterpret_cast(wxw->GetHandle()); #endif - return handleInfo; + return std::move(handleInfo); } diff --git a/src/imgui/imgui_extension.cpp b/src/imgui/imgui_extension.cpp index eb0e31ef..802431f0 100644 --- a/src/imgui/imgui_extension.cpp +++ b/src/imgui/imgui_extension.cpp @@ -132,7 +132,7 @@ void ImGui_UpdateWindowInformation(bool mainWindow) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; #if BOOST_OS_WINDOWS - io.ImeWindowHandle = mainWindow ? windowInfo.window_main.surface : windowInfo.window_pad.surface; + io.ImeWindowHandle = mainWindow ? windowInfo.window_main.surface.load(std::memory_order::relaxed) : windowInfo.window_pad.surface.load(std::memory_order::relaxed); #else io.ImeWindowHandle = nullptr; #endif diff --git a/src/input/api/DirectInput/DirectInputController.cpp b/src/input/api/DirectInput/DirectInputController.cpp index f0f33701..c6b3fde0 100644 --- a/src/input/api/DirectInput/DirectInputController.cpp +++ b/src/input/api/DirectInput/DirectInputController.cpp @@ -105,7 +105,7 @@ bool DirectInputController::connect() return false; } - HWND hwndMainWindow = static_cast(WindowSystem::GetWindowInfo().window_main.surface); + HWND hwndMainWindow = static_cast(WindowSystem::GetWindowInfo().window_main.surface.load(std::memory_order::relaxed)); // set access if (FAILED(m_device->SetCooperativeLevel(hwndMainWindow, DISCL_BACKGROUND | DISCL_EXCLUSIVE)))