From f97bba59eed34a4155d2a678635878d9446c0255 Mon Sep 17 00:00:00 2001 From: cuesta4 Date: Sun, 7 Jun 2026 09:32:47 -0300 Subject: [PATCH] [Frontend]: improve fullscreen startup presentation --- src/sdl_window.cpp | 29 +++++++++++++++++++ src/sdl_window.h | 4 +++ .../renderer_vulkan/vk_presenter.cpp | 7 ++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 2dc2e9ffa..04ce55c0f 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -14,6 +14,7 @@ #include "core/emulator_settings.h" #include "core/libraries/kernel/time.h" #include "core/libraries/pad/pad.h" +#include "core/libraries/system/systemservice.h" #include "core/libraries/system/userservice.h" #include "core/user_settings.h" #include "imgui/renderer/imgui_core.h" @@ -109,6 +110,8 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameControllers* controller SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); SDL_SetNumberProperty(props, "flags", SDL_WINDOW_VULKAN); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true); + const bool start_hidden = EmulatorSettings.IsFullScreen(); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, start_hidden); window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); if (window == nullptr) { @@ -134,6 +137,15 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameControllers* controller } SDL_SetWindowFullscreen(window, EmulatorSettings.IsFullScreen()); SDL_SyncWindow(window); + if (start_hidden) { + const bool defer_reveal = Libraries::SystemService::IsSplashVisible() && + !Common::ElfInfo::Instance().GetSplashPath().empty() && + SDL_SetWindowOpacity(window, 0.0f); + startup_splash_reveal_pending.store(defer_reveal, std::memory_order_release); + SDL_ShowWindow(window); + SDL_SyncWindow(window); + } + SDL_GetWindowSizeInPixels(window, &width, &height); SDL_InitSubSystem(SDL_INIT_GAMEPAD); @@ -308,6 +320,23 @@ void WindowSDL::InitTimers() { SDL_AddTimer(33, Input::MousePolling, (void*)controllers[0]); } +void WindowSDL::RequestStartupSplashReveal() { + if (!startup_splash_reveal_pending.exchange(false, std::memory_order_acq_rel)) { + return; + } + if (!SDL_RunOnMainThread( + [](void* userdata) { + static_cast(userdata)->RevealStartupSplash(); + }, + this, false)) { + startup_splash_reveal_pending.store(true, std::memory_order_release); + } +} + +void WindowSDL::RevealStartupSplash() { + SDL_SetWindowOpacity(window, 1.0f); +} + void WindowSDL::RequestKeyboard() { if (keyboard_grab == 0) { SDL_RunOnMainThread( diff --git a/src/sdl_window.h b/src/sdl_window.h index 4fc750bbc..bedfddb40 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include "common/types.h" @@ -76,9 +77,11 @@ public: void RequestKeyboard(); void ReleaseKeyboard(); + void RequestStartupSplashReveal(); private: void OnResize(); + void RevealStartupSplash(); void OnKeyboardMouseInput(const SDL_Event* event); void OnGamepadEvent(const SDL_Event* event); @@ -90,6 +93,7 @@ private: SDL_Window* window{}; bool is_shown{}; bool is_open{true}; + std::atomic_bool startup_splash_reveal_pending{false}; }; } // namespace Frontend diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index a98a5ce23..ea7823e5c 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -1086,12 +1086,17 @@ void Presenter::Present(Frame* frame, bool is_reusing_frame) { scheduler.Flush(info); // Present to swapchain. + bool presented = false; { std::scoped_lock submit_lock{Scheduler::submit_mutex}; - if (!swapchain.Present()) { + presented = swapchain.Present(); + if (!presented) { swapchain.Recreate(window.GetWidth(), window.GetHeight()); } } + if (presented) { + window.RequestStartupSplashReveal(); + } free_frame(); if (!is_reusing_frame) {