From d6ecadfd3a620e1f6a161f0feb2a1f47b052045e Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 29 Mar 2026 14:13:02 +0200 Subject: [PATCH] fix: vsync off no anava en Wayland --- source/core/rendering/screen.cpp | 21 +++++++++++++++---- .../core/rendering/sdl3gpu/sdl3gpu_shader.cpp | 21 +++++++++++++++++-- .../core/rendering/sdl3gpu/sdl3gpu_shader.hpp | 2 ++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index a70e2a0..f93ac8e 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -297,11 +297,24 @@ void Screen::adjustWindowSize() { int old_x, old_y; SDL_GetWindowPosition(window_, &old_x, &old_y); - const int NEW_X = old_x + ((old_w - (window_width_ * Options::window.zoom)) / 2); - const int NEW_Y = old_y + ((old_h - (window_height_ * Options::window.zoom)) / 2); + const int new_w = window_width_ * Options::window.zoom; + const int new_h = window_height_ * Options::window.zoom; + const int NEW_X = old_x + ((old_w - new_w) / 2); + const int NEW_Y = old_y + ((old_h - new_h) / 2); - SDL_SetWindowSize(window_, window_width_ * Options::window.zoom, window_height_ * Options::window.zoom); - SDL_SetWindowPosition(window_, std::max(NEW_X, WINDOWS_DECORATIONS), std::max(NEW_Y, 0)); + SDL_SetWindowSize(window_, new_w, new_h); + + // En Wayland, SDL_SetWindowPosition es ignorado por el compositor (limitación de + // protocolo: el compositor controla la posición de ventanas toplevel). Solo se + // aplica en X11/Windows/macOS donde el posicionado funciona correctamente. + // SDL_SyncWindow garantiza que el resize esté completado antes de reposicionar + // (evita el race condition en X11). + SDL_SyncWindow(window_); + const char* driver = SDL_GetCurrentVideoDriver(); + const bool is_wayland = (driver != nullptr && SDL_strcmp(driver, "wayland") == 0); + if (!is_wayland) { + SDL_SetWindowPosition(window_, std::max(NEW_X, WINDOWS_DECORATIONS), std::max(NEW_Y, 0)); + } } } diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp index b60d508..b02ac18 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp @@ -433,7 +433,7 @@ namespace Rendering { device_ = nullptr; return false; } - SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, vsync_ ? SDL_GPU_PRESENTMODE_VSYNC : SDL_GPU_PRESENTMODE_IMMEDIATE); + SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, bestPresentMode(vsync_)); } // ---------------------------------------------------------------- @@ -1144,10 +1144,27 @@ namespace Rendering { active_shader_ = type; } + auto SDL3GPUShader::bestPresentMode(bool vsync) const -> SDL_GPUPresentMode { + if (vsync) { + return SDL_GPU_PRESENTMODE_VSYNC; + } + // IMMEDIATE: sin sincronización — el driver puede no soportarlo en Wayland/compositing + if (SDL_WindowSupportsGPUPresentMode(device_, window_, SDL_GPU_PRESENTMODE_IMMEDIATE)) { + return SDL_GPU_PRESENTMODE_IMMEDIATE; + } + // MAILBOX: presenta en el siguiente VBlank pero sin bloquear el hilo (triple buffer) + if (SDL_WindowSupportsGPUPresentMode(device_, window_, SDL_GPU_PRESENTMODE_MAILBOX)) { + SDL_Log("SDL3GPUShader: IMMEDIATE no soportado, usando MAILBOX para VSync desactivado"); + return SDL_GPU_PRESENTMODE_MAILBOX; + } + SDL_Log("SDL3GPUShader: IMMEDIATE y MAILBOX no soportados, forzando VSYNC"); + return SDL_GPU_PRESENTMODE_VSYNC; + } + void SDL3GPUShader::setVSync(bool vsync) { vsync_ = vsync; if (device_ != nullptr && window_ != nullptr) { - SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, vsync_ ? SDL_GPU_PRESENTMODE_VSYNC : SDL_GPU_PRESENTMODE_IMMEDIATE); + SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, bestPresentMode(vsync_)); } } diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp index 8e9d518..6298898 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp @@ -141,6 +141,8 @@ namespace Rendering { auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_ auto recreateScaledTexture(int factor) -> bool; // Recrea scaled_texture_ para factor dado static auto calcSsFactor(float zoom) -> int; // Primer múltiplo de 3 >= zoom (mín 3) + // Devuelve el mejor present mode disponible: IMMEDIATE > MAILBOX > VSYNC + [[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode; SDL_Window* window_ = nullptr; SDL_GPUDevice* device_ = nullptr;