From e6f0c23d259df391e8db2f30e6a39049d4aa5fb1 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Wed, 24 Jul 2024 21:35:25 +0800 Subject: [PATCH] EGLManager: Track per-window v-sync state --- drivers/egl/egl_manager.cpp | 23 +++++++++++++------ drivers/egl/egl_manager.h | 9 ++++---- .../wayland/display_server_wayland.cpp | 8 +++---- platform/linuxbsd/x11/display_server_x11.cpp | 4 ++-- platform/macos/display_server_macos.mm | 4 ++-- platform/windows/display_server_windows.cpp | 4 ++-- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 9c1d08331d2..92ebccf6d21 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -318,13 +318,20 @@ void EGLManager::window_make_current(DisplayServer::WindowID p_window_id) { eglMakeCurrent(current_display.egl_display, current_window->egl_surface, current_window->egl_surface, current_display.egl_context); } -void EGLManager::set_use_vsync(bool p_use) { - // We need an active window to get a display to set the vsync. - if (!current_window) { +void EGLManager::set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use) { + ERR_FAIL_INDEX(p_window_id, (int)windows.size()); + + GLWindow &glwindow = windows[p_window_id]; + + if (!glwindow.initialized) { return; } - GLDisplay &disp = displays[current_window->gldisplay_id]; + if (&glwindow != current_window) { + window_make_current(p_window_id); + } + + GLDisplay &disp = displays[glwindow.gldisplay_id]; int swap_interval = p_use ? 1 : 0; @@ -332,11 +339,13 @@ void EGLManager::set_use_vsync(bool p_use) { WARN_PRINT("Could not set V-Sync mode."); } - use_vsync = p_use; + glwindow.use_vsync = p_use; } -bool EGLManager::is_using_vsync() const { - return use_vsync; +bool EGLManager::is_using_vsync(DisplayServer::WindowID p_window_id) const { + ERR_FAIL_INDEX_V(p_window_id, (int)windows.size(), false); + + return windows[p_window_id].use_vsync; } EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) { diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h index a4502c06871..b8b50629108 100644 --- a/drivers/egl/egl_manager.h +++ b/drivers/egl/egl_manager.h @@ -58,6 +58,8 @@ private: // EGL specific window data. struct GLWindow { bool initialized = false; + // On EGL the default swap interval is 1 and thus vsync is on by default. + bool use_vsync = true; // An handle to the GLDisplay associated with this window. int gldisplay_id = -1; @@ -70,9 +72,6 @@ private: GLWindow *current_window = nullptr; - // On EGL the default swap interval is 1 and thus vsync is on by default. - bool use_vsync = true; - virtual const char *_get_platform_extension_name() const = 0; virtual EGLenum _get_platform_extension_enum() const = 0; virtual EGLenum _get_platform_api_enum() const = 0; @@ -102,8 +101,8 @@ public: void window_make_current(DisplayServer::WindowID p_window_id); - void set_use_vsync(bool p_use); - bool is_using_vsync() const; + void set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use); + bool is_using_vsync(DisplayServer::WindowID p_window_id) const; EGLContext get_context(DisplayServer::WindowID p_window_id); diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 93096fcdcc6..0c5a9107d41 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -945,13 +945,13 @@ void DisplayServerWayland::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn #ifdef GLES3_ENABLED if (egl_manager) { - egl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); + egl_manager->set_use_vsync(p_window_id, p_vsync_mode != DisplayServer::VSYNC_DISABLED); - emulate_vsync = egl_manager->is_using_vsync(); + emulate_vsync = egl_manager->is_using_vsync(p_window_id); if (emulate_vsync) { print_verbose("VSYNC: manually throttling frames with swap delay 0."); - egl_manager->set_use_vsync(false); + egl_manager->set_use_vsync(p_window_id, false); } } #endif // GLES3_ENABLED @@ -970,7 +970,7 @@ DisplayServer::VSyncMode DisplayServerWayland::window_get_vsync_mode(DisplayServ #ifdef GLES3_ENABLED if (egl_manager) { - return egl_manager->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + return egl_manager->is_using_vsync(p_window_id) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } #endif // GLES3_ENABLED diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index d6eb101a686..633edbd05cf 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -5367,7 +5367,7 @@ void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo gl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); } if (gl_manager_egl) { - gl_manager_egl->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); + gl_manager_egl->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); } #endif } @@ -5384,7 +5384,7 @@ DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_wind return gl_manager->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } if (gl_manager_egl) { - return gl_manager_egl->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + return gl_manager_egl->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } #endif return DisplayServer::VSYNC_ENABLED; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index da453919951..c6752e521ae 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -2688,7 +2688,7 @@ void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_ _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) if (gl_manager_angle) { - gl_manager_angle->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); + gl_manager_angle->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); } if (gl_manager_legacy) { gl_manager_legacy->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); @@ -2705,7 +2705,7 @@ DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_wi _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) if (gl_manager_angle) { - return (gl_manager_angle->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); + return (gl_manager_angle->is_using_vsync(p_window) ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); } if (gl_manager_legacy) { return (gl_manager_legacy->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index f29048b16d7..40fff7ef249 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3419,7 +3419,7 @@ void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn gl_manager_native->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); } if (gl_manager_angle) { - gl_manager_angle->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); + gl_manager_angle->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); } #endif } @@ -3437,7 +3437,7 @@ DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_ return gl_manager_native->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } if (gl_manager_angle) { - return gl_manager_angle->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + return gl_manager_angle->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } #endif return DisplayServer::VSYNC_ENABLED;