diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index 220feff21..222efb6c9 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -592,23 +592,21 @@ bool FullscreenUI::Initialize() !LoadResources()) { DestroyResources(); - ImGuiFullscreen::Shutdown(); + Shutdown(true); s_state.tried_to_initialize = true; return false; } s_state.initialized = true; - s_state.current_main_window = MainWindowType::None; - s_state.current_pause_submenu = PauseSubMenu::None; - s_state.pause_menu_was_open = false; - s_state.was_paused_on_quick_menu_open = false; - s_state.about_window_open = false; s_state.hotkey_list_cache = InputManager::GetHotkeyList(); Host::RunOnCPUThread([]() { Host::OnFullscreenUIStartedOrStopped(true); }); - if (!GPUThread::HasGPUBackend() && !GPUThread::IsGPUBackendRequested()) + if (s_state.current_main_window == MainWindowType::None && !GPUThread::HasGPUBackend() && + !GPUThread::IsGPUBackendRequested()) + { SwitchToLanding(); + } UpdateRunIdleState(); ForceKeyNavEnabled(); @@ -799,27 +797,37 @@ void FullscreenUI::OpenPauseSubMenu(PauseSubMenu submenu) QueueResetFocus(FocusResetType::ViewChanged); } -void FullscreenUI::Shutdown() +void FullscreenUI::Shutdown(bool clear_state) { - Achievements::ClearUIState(); - ClearInputBindingVariables(); - CloseSaveStateSelector(); - s_state.cover_image_map.clear(); - std::memset(s_state.controller_macro_expanded, 0, sizeof(s_state.controller_macro_expanded)); - s_state.game_list_sorted_entries = {}; - s_state.game_list_directories_cache = {}; - s_state.game_patch_list = {}; - s_state.enabled_game_patch_cache = {}; - s_state.game_cheats_list = {}; - s_state.enabled_game_cheat_cache = {}; - s_state.game_cheat_groups = {}; - s_state.postprocessing_stages = {}; - s_state.fullscreen_mode_list_cache = {}; - s_state.graphics_adapter_list_cache = {}; - s_state.hotkey_list_cache = {}; - s_state.current_game_subtitle = {}; + if (clear_state) + { + s_state.current_main_window = MainWindowType::None; + s_state.current_pause_submenu = PauseSubMenu::None; + s_state.pause_menu_was_open = false; + s_state.was_paused_on_quick_menu_open = false; + s_state.about_window_open = false; + + Achievements::ClearUIState(); + ClearInputBindingVariables(); + CloseSaveStateSelector(); + s_state.cover_image_map.clear(); + std::memset(s_state.controller_macro_expanded, 0, sizeof(s_state.controller_macro_expanded)); + s_state.game_list_sorted_entries = {}; + s_state.game_list_directories_cache = {}; + s_state.game_patch_list = {}; + s_state.enabled_game_patch_cache = {}; + s_state.game_cheats_list = {}; + s_state.enabled_game_cheat_cache = {}; + s_state.game_cheat_groups = {}; + s_state.postprocessing_stages = {}; + s_state.fullscreen_mode_list_cache = {}; + s_state.graphics_adapter_list_cache = {}; + s_state.hotkey_list_cache = {}; + s_state.current_game_subtitle = {}; + } + DestroyResources(); - ImGuiFullscreen::Shutdown(); + ImGuiFullscreen::Shutdown(clear_state); if (s_state.initialized) Host::RunOnCPUThread([]() { Host::OnFullscreenUIStartedOrStopped(false); }); @@ -4318,7 +4326,6 @@ void FullscreenUI::DrawGraphicsSettingsPage() else bsi->SetStringValue("GPU", "Adapter", value); SetSettingsChanged(bsi); - ShowToast(std::string(), FSUI_STR("GPU adapter will be applied after restarting."), 10.0f); CloseChoiceDialog(); }; OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_MICROCHIP, "GPU Adapter"), false, std::move(options), std::move(callback)); diff --git a/src/core/fullscreen_ui.h b/src/core/fullscreen_ui.h index b08d3d7dc..304023b61 100644 --- a/src/core/fullscreen_ui.h +++ b/src/core/fullscreen_ui.h @@ -35,7 +35,7 @@ void ReturnToPreviousWindow(); void SetStandardSelectionFooterText(bool back_instead_of_cancel); #endif -void Shutdown(); +void Shutdown(bool clear_state); void Render(); void InvalidateCoverCache(); void TimeToPrintableString(SmallStringBase* str, time_t t); diff --git a/src/core/gpu_thread.cpp b/src/core/gpu_thread.cpp index 668714768..fa2fe9cda 100644 --- a/src/core/gpu_thread.cpp +++ b/src/core/gpu_thread.cpp @@ -68,8 +68,8 @@ static bool IsCommandFIFOEmpty(); static void WakeGPUThread(); static bool SleepGPUThread(bool allow_sleep); -static bool CreateDeviceOnThread(RenderAPI api, bool fullscreen, Error* error); -static void DestroyDeviceOnThread(); +static bool CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_fsui_state_on_failure, Error* error); +static void DestroyDeviceOnThread(bool clear_fsui_state); static void ResizeDisplayWindowOnThread(u32 width, u32 height, float scale); static void UpdateDisplayWindowOnThread(bool fullscreen); static void DisplayWindowResizedOnThread(); @@ -610,7 +610,7 @@ bool GPUThread::IsGPUBackendRequested() return s_state.requested_renderer.has_value(); } -bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, Error* error) +bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_fsui_state_on_failure, Error* error) { DebugAssert(!g_gpu_device); @@ -686,7 +686,7 @@ bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, Error* erro { ERROR_LOG("Failed to initialize ImGuiManager: {}", create_error.GetDescription()); Error::SetStringFmt(error, "Failed to initialize ImGuiManager: {}", create_error.GetDescription()); - FullscreenUI::Shutdown(); + FullscreenUI::Shutdown(clear_fsui_state_on_failure); ImGuiManager::Shutdown(); g_gpu_device->Destroy(); g_gpu_device.reset(); @@ -707,14 +707,14 @@ bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, Error* erro return true; } -void GPUThread::DestroyDeviceOnThread() +void GPUThread::DestroyDeviceOnThread(bool clear_fsui_state) { if (!g_gpu_device) return; const bool has_window = g_gpu_device->HasMainSwapChain(); - FullscreenUI::Shutdown(); + FullscreenUI::Shutdown(clear_fsui_state); ImGuiManager::Shutdown(); INFO_LOG("Destroying {} GPU device...", GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI())); @@ -749,12 +749,12 @@ void GPUThread::HandleGPUDeviceLost() // Device lost, something went really bad. // Let's just toss out everything, and try to hobble on. DestroyGPUBackendOnThread(); - DestroyDeviceOnThread(); + DestroyDeviceOnThread(false); Error error; if (!CreateDeviceOnThread( Settings::GetRenderAPIForRenderer(s_state.requested_renderer.value_or(g_gpu_settings.gpu_renderer)), - is_fullscreen, &error) || + is_fullscreen, true, &error) || (s_state.requested_renderer.has_value() && !CreateGPUBackendOnThread(s_state.requested_renderer.value(), true, &error))) { @@ -832,7 +832,7 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd) if (!cmd->renderer.has_value() && !s_state.requested_fullscreen_ui) { DestroyGPUBackendOnThread(); - DestroyDeviceOnThread(); + DestroyDeviceOnThread(true); return; } @@ -864,10 +864,10 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd) if (cmd->force_recreate_device || !GPUDevice::IsSameRenderAPI(current_api, expected_api)) { const bool fullscreen = cmd->fullscreen.value_or(Host::IsFullscreen()); - DestroyDeviceOnThread(); + DestroyDeviceOnThread(false); Error local_error; - if (!CreateDeviceOnThread(expected_api, fullscreen, &local_error)) + if (!CreateDeviceOnThread(expected_api, fullscreen, false, &local_error)) { Host::AddIconOSDMessage( "DeviceSwitchFailed", ICON_FA_PAINT_ROLLER, @@ -877,7 +877,7 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd) Host::OSD_CRITICAL_ERROR_DURATION); Host::ReleaseRenderWindow(); - if (current_api == RenderAPI::None || !CreateDeviceOnThread(current_api, fullscreen, &local_error)) + if (current_api == RenderAPI::None || !CreateDeviceOnThread(current_api, fullscreen, true, &local_error)) { if (cmd->error_ptr) *cmd->error_ptr = local_error; @@ -895,7 +895,8 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd) } else if (s_state.requested_fullscreen_ui) { - if (!g_gpu_device && !CreateDeviceOnThread(expected_api, cmd->fullscreen.value_or(false), cmd->error_ptr)) + const bool had_gpu_device = static_cast(g_gpu_device); + if (!g_gpu_device && !CreateDeviceOnThread(expected_api, cmd->fullscreen.value_or(false), true, cmd->error_ptr)) { *cmd->out_result = false; return; @@ -905,12 +906,16 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd) g_gpu_device->SetGPUTimingEnabled(false); if (!(*cmd->out_result = FullscreenUI::IsInitialized() || FullscreenUI::Initialize())) + { Error::SetStringView(cmd->error_ptr, "Failed to initialize FullscreenUI."); + if (!had_gpu_device) + DestroyDeviceOnThread(true); + } } else { // Device is no longer needed. - DestroyDeviceOnThread(); + DestroyDeviceOnThread(true); } } diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 14fb34a82..63e4ab472 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -1093,7 +1093,7 @@ void Settings::FixIncompatibleSettings(const SettingsInterface& si, bool display bool Settings::AreGPUDeviceSettingsChanged(const Settings& old_settings) const { - return (gpu_use_debug_device != old_settings.gpu_use_debug_device || + return (gpu_adapter != old_settings.gpu_adapter || gpu_use_debug_device != old_settings.gpu_use_debug_device || gpu_disable_shader_cache != old_settings.gpu_disable_shader_cache || gpu_disable_dual_source_blend != old_settings.gpu_disable_dual_source_blend || gpu_disable_framebuffer_fetch != old_settings.gpu_disable_framebuffer_fetch || diff --git a/src/core/system.cpp b/src/core/system.cpp index cbadab190..03e5dec07 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -4577,7 +4577,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings) if (GPUThread::IsFullscreenUIRequested()) { // handle device setting updates as well - if (g_settings.AreGPUDeviceSettingsChanged(old_settings)) + if (g_settings.gpu_renderer != old_settings.gpu_renderer || g_settings.AreGPUDeviceSettingsChanged(old_settings)) GPUThread::UpdateSettings(false, true); if (g_settings.display_vsync != old_settings.display_vsync || diff --git a/src/util/imgui_fullscreen.cpp b/src/util/imgui_fullscreen.cpp index fc64e8126..43bd1c230 100644 --- a/src/util/imgui_fullscreen.cpp +++ b/src/util/imgui_fullscreen.cpp @@ -216,7 +216,7 @@ bool ImGuiFullscreen::Initialize(const char* placeholder_image_path) return true; } -void ImGuiFullscreen::Shutdown() +void ImGuiFullscreen::Shutdown(bool clear_state) { if (s_state.texture_load_thread.joinable()) { @@ -235,33 +235,36 @@ void ImGuiFullscreen::Shutdown() s_state.texture_cache.Clear(); - s_state.notifications.clear(); - s_state.background_progress_dialogs.clear(); - s_state.fullscreen_footer_text.clear(); - s_state.last_fullscreen_footer_text.clear(); - s_state.fullscreen_text_change_time = 0.0f; - CloseInputDialog(); - CloseMessageDialog(); - s_state.choice_dialog_open = false; - s_state.choice_dialog_checkable = false; - s_state.choice_dialog_title = {}; - s_state.choice_dialog_options.clear(); - s_state.choice_dialog_callback = {}; - s_state.enum_choice_button_id = 0; - s_state.enum_choice_button_value = 0; - s_state.enum_choice_button_set = false; - s_state.file_selector_open = false; - s_state.file_selector_directory = false; - s_state.file_selector_title = {}; - s_state.file_selector_callback = {}; - s_state.file_selector_current_directory = {}; - s_state.file_selector_filters.clear(); - s_state.file_selector_items.clear(); - s_state.message_dialog_open = false; - s_state.message_dialog_title = {}; - s_state.message_dialog_message = {}; - s_state.message_dialog_buttons = {}; - s_state.message_dialog_callback = {}; + if (clear_state) + { + s_state.notifications.clear(); + s_state.background_progress_dialogs.clear(); + s_state.fullscreen_footer_text.clear(); + s_state.last_fullscreen_footer_text.clear(); + s_state.fullscreen_text_change_time = 0.0f; + CloseInputDialog(); + CloseMessageDialog(); + s_state.choice_dialog_open = false; + s_state.choice_dialog_checkable = false; + s_state.choice_dialog_title = {}; + s_state.choice_dialog_options.clear(); + s_state.choice_dialog_callback = {}; + s_state.enum_choice_button_id = 0; + s_state.enum_choice_button_value = 0; + s_state.enum_choice_button_set = false; + s_state.file_selector_open = false; + s_state.file_selector_directory = false; + s_state.file_selector_title = {}; + s_state.file_selector_callback = {}; + s_state.file_selector_current_directory = {}; + s_state.file_selector_filters.clear(); + s_state.file_selector_items.clear(); + s_state.message_dialog_open = false; + s_state.message_dialog_title = {}; + s_state.message_dialog_message = {}; + s_state.message_dialog_buttons = {}; + s_state.message_dialog_callback = {}; + } } void ImGuiFullscreen::SetSmoothScrolling(bool enabled) diff --git a/src/util/imgui_fullscreen.h b/src/util/imgui_fullscreen.h index 044cf6543..8ae55a53a 100644 --- a/src/util/imgui_fullscreen.h +++ b/src/util/imgui_fullscreen.h @@ -130,7 +130,7 @@ void SetFonts(ImFont* medium_font, ImFont* large_font); bool UpdateLayoutScale(); /// Shuts down, clearing all state. -void Shutdown(); +void Shutdown(bool clear_state); /// Texture cache. const std::shared_ptr& GetPlaceholderTexture();