diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index 91bbc230..ce856981 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -235,6 +235,8 @@ set(PP_PANOPAINTER_UI_SOURCES set(PP_WINDOWS_PLATFORM_SOURCES src/main.cpp src/platform_windows/windows_bootstrap_helpers.cpp + src/platform_windows/windows_async_render_context.cpp + src/platform_windows/windows_async_render_context.h src/platform_windows/windows_lifecycle_shell.cpp src/platform_windows/windows_lifecycle_shell.h src/platform_windows/windows_main_window_session.cpp diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 0e36c5e6..c258abf3 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -70,6 +70,11 @@ What is already real: - `pp_app_core` Latest slice: +- `src/platform_windows/windows_async_render_context.*` now owns the retained + Win32 async OpenGL context lock/swap state instead of leaving it inside + `windows_platform_services.cpp`. +- `src/platform_windows/windows_platform_services.cpp` now keeps the VR/runtime + adapter surface without also owning the async GL context pocket. - `src/platform_windows/windows_main_window_session.*` now owns the retained Win32 main-window session fields (`HWND`, title buffer, sandbox flag) instead of leaving them inside `windows_runtime_shell.cpp`. diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index aa6c1251..68832d50 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -78,6 +78,10 @@ Completed, blocked, and superseded task history moved to the queue is now ordered by code movement instead. Current slice: +- `src/platform_windows/windows_async_render_context.*` now owns the retained + Win32 async GL context lock/swap state. +- `src/platform_windows/windows_platform_services.cpp` no longer carries the + retained async render-context pocket. - `src/platform_windows/windows_main_window_session.*` now owns the retained Win32 main-window session fields. - `src/platform_windows/windows_runtime_shell.cpp` no longer carries the diff --git a/src/platform_windows/windows_async_render_context.cpp b/src/platform_windows/windows_async_render_context.cpp new file mode 100644 index 00000000..126b0378 --- /dev/null +++ b/src/platform_windows/windows_async_render_context.cpp @@ -0,0 +1,82 @@ +#include "pch.h" + +#include "platform_windows/windows_async_render_context.h" + +#include "log.h" +#include "platform_windows/windows_bootstrap_helpers.h" + +namespace pp::platform::windows { +namespace { + +struct RetainedWin32AsyncRenderContextState final { + HDC hdc{}; + HGLRC hrc{}; + std::mutex gl_mutex; + std::thread::id gl_thread{}; + int gl_count = 0; +}; + +[[nodiscard]] RetainedWin32AsyncRenderContextState& retained_win32_async_render_context_state() +{ + static RetainedWin32AsyncRenderContextState state; + return state; +} + +} + +void set_async_render_context(HDC hdc, HGLRC hrc) +{ + auto& state = retained_win32_async_render_context_state(); + state.hdc = hdc; + state.hrc = hrc; + state.gl_thread = {}; + state.gl_count = 0; +} + +void lock_async_render_context() +{ + auto& state = retained_win32_async_render_context_state(); + if (state.gl_count == 0 || state.gl_thread != std::this_thread::get_id()) + { + state.gl_mutex.lock(); + const bool ret = wglMakeCurrent(state.hdc, state.hrc); + if (!ret) + LOG("FAILED wglMakeCurrent: %s", pp::platform::windows::GetLastErrorAsString().c_str()); + state.gl_thread = std::this_thread::get_id(); + } + state.gl_count++; +} + +bool try_lock_async_render_context() +{ + auto& state = retained_win32_async_render_context_state(); + if (state.gl_count == 0 || state.gl_thread != std::this_thread::get_id()) + { + if (!state.gl_mutex.try_lock()) + return false; + const bool ret = wglMakeCurrent(state.hdc, state.hrc); + if (!ret) + LOG("FAILED wglMakeCurrent: %s", pp::platform::windows::GetLastErrorAsString().c_str()); + state.gl_thread = std::this_thread::get_id(); + } + state.gl_count++; + return true; +} + +void unlock_async_render_context() +{ + auto& state = retained_win32_async_render_context_state(); + state.gl_count--; + if (state.gl_count == 0) + { + wglMakeCurrent(0, 0); + state.gl_mutex.unlock(); + } +} + +void swap_async_render_context() +{ + SwapBuffers(retained_win32_async_render_context_state().hdc); +} + +} diff --git a/src/platform_windows/windows_async_render_context.h b/src/platform_windows/windows_async_render_context.h new file mode 100644 index 00000000..e2151b1e --- /dev/null +++ b/src/platform_windows/windows_async_render_context.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace pp::platform::windows { + +void set_async_render_context(HDC hdc, HGLRC hrc); +void lock_async_render_context(); +[[nodiscard]] bool try_lock_async_render_context(); +void unlock_async_render_context(); +void swap_async_render_context(); + +} diff --git a/src/platform_windows/windows_bootstrap_helpers.cpp b/src/platform_windows/windows_bootstrap_helpers.cpp index bf5854e8..ca324a10 100644 --- a/src/platform_windows/windows_bootstrap_helpers.cpp +++ b/src/platform_windows/windows_bootstrap_helpers.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "platform_windows/windows_bootstrap_helpers.h" +#include "platform_windows/windows_async_render_context.h" #include "platform_windows/windows_main_window_session.h" #include "platform_windows/windows_runtime_shell.h" #include "platform_windows/windows_window_shell.h" @@ -25,7 +26,6 @@ #endif namespace pp::platform::windows { -void set_async_render_context(HDC hdc, HGLRC hrc); App* bound_app() noexcept; } diff --git a/src/platform_windows/windows_platform_services.cpp b/src/platform_windows/windows_platform_services.cpp index 36a15651..a2497454 100644 --- a/src/platform_windows/windows_platform_services.cpp +++ b/src/platform_windows/windows_platform_services.cpp @@ -1,4 +1,5 @@ #include "pch.h" +#include "platform_windows/windows_async_render_context.h" #include "platform_windows/windows_bootstrap_helpers.h" #include "platform_windows/windows_lifecycle_shell.h" #include "platform_windows/windows_main_window_session.h" @@ -20,11 +21,6 @@ #include namespace pp::platform::windows { -void set_async_render_context(HDC hdc, HGLRC hrc); -void lock_async_render_context(); -bool try_lock_async_render_context(); -void unlock_async_render_context(); -void swap_async_render_context(); [[nodiscard]] VrShellState& platform_vr_state() noexcept; } @@ -145,77 +141,8 @@ VrShellState& platform_vr_state() noexcept namespace pp::platform::windows { namespace { - -struct RetainedWin32AsyncRenderContextState final { - HDC hdc{}; - HGLRC hrc{}; - std::mutex gl_mutex; - std::thread::id gl_thread{}; - int gl_count = 0; -}; - -[[nodiscard]] RetainedWin32AsyncRenderContextState& retained_win32_async_render_context_state() -{ - static RetainedWin32AsyncRenderContextState state; - return state; -} } // namespace -void set_async_render_context(HDC hdc, HGLRC hrc) -{ - auto& state = retained_win32_async_render_context_state(); - state.hdc = hdc; - state.hrc = hrc; - state.gl_thread = {}; - state.gl_count = 0; -} - -void lock_async_render_context() -{ - auto& state = retained_win32_async_render_context_state(); - if (state.gl_count == 0 || state.gl_thread != std::this_thread::get_id()) - { - state.gl_mutex.lock(); - const bool ret = wglMakeCurrent(state.hdc, state.hrc); - if (!ret) - LOG("FAILED wglMakeCurrent: %s", pp::platform::windows::GetLastErrorAsString().c_str()); - state.gl_thread = std::this_thread::get_id(); - } - state.gl_count++; -} - -bool try_lock_async_render_context() -{ - auto& state = retained_win32_async_render_context_state(); - if (state.gl_count == 0 || state.gl_thread != std::this_thread::get_id()) - { - if (!state.gl_mutex.try_lock()) - return false; - const bool ret = wglMakeCurrent(state.hdc, state.hrc); - if (!ret) - LOG("FAILED wglMakeCurrent: %s", pp::platform::windows::GetLastErrorAsString().c_str()); - state.gl_thread = std::this_thread::get_id(); - } - state.gl_count++; - return true; -} - -void unlock_async_render_context() -{ - auto& state = retained_win32_async_render_context_state(); - state.gl_count--; - if (state.gl_count == 0) - { - wglMakeCurrent(0, 0); - state.gl_mutex.unlock(); - } -} - -void swap_async_render_context() -{ - SwapBuffers(retained_win32_async_render_context_state().hdc); -} - void enqueue_main_thread_task(std::packaged_task task) { if (auto* app = bound_app())