mirror of
https://github.com/stenzek/duckstation.git
synced 2026-04-22 14:02:13 +00:00
FullscreenUI: Fix incorrect state with per-game renderer setting
This commit is contained in:
@@ -170,7 +170,7 @@ ALIGN_TO_CACHE_LINE static Locals s_locals;
|
||||
// Main
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FullscreenUI::Initialize()
|
||||
void FullscreenUI::Initialize(bool preserve_state /*= false */)
|
||||
{
|
||||
// some achievement callbacks fire early while e.g. there is a load state popup blocking system init
|
||||
if (s_locals.initialized || !ImGuiManager::IsInitialized())
|
||||
@@ -179,7 +179,7 @@ void FullscreenUI::Initialize()
|
||||
s_locals.initialized = true;
|
||||
|
||||
// in case we open the pause menu while the game is running
|
||||
if (s_locals.current_main_window == MainWindowType::None && !GPUThread::HasGPUBackend() &&
|
||||
if (!preserve_state && s_locals.current_main_window == MainWindowType::None && !GPUThread::HasGPUBackend() &&
|
||||
!GPUThread::IsGPUBackendRequested())
|
||||
{
|
||||
ReturnToMainWindow();
|
||||
@@ -456,9 +456,9 @@ void FullscreenUI::ReturnToMainWindow(float transition_time)
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::Shutdown(bool clear_state)
|
||||
void FullscreenUI::Shutdown(bool preserve_fsui_state)
|
||||
{
|
||||
if (clear_state)
|
||||
if (!preserve_fsui_state)
|
||||
{
|
||||
SoundEffectManager::Shutdown();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class SmallStringBase;
|
||||
struct GPUSettings;
|
||||
|
||||
namespace FullscreenUI {
|
||||
void Initialize();
|
||||
void Initialize(bool preserve_state = false);
|
||||
bool IsInitialized();
|
||||
bool HasActiveWindow();
|
||||
void CheckForConfigChanges(const GPUSettings& old_settings);
|
||||
@@ -28,7 +28,7 @@ void OnSystemPaused();
|
||||
void OnSystemResumed();
|
||||
void OnSystemDestroyed();
|
||||
|
||||
void Shutdown(bool clear_state);
|
||||
void Shutdown(bool preserve_state);
|
||||
void Render();
|
||||
void InvalidateCoverCache(std::string path = {});
|
||||
|
||||
|
||||
@@ -396,28 +396,38 @@ void FullscreenUI::SetFont(ImFont* ui_font)
|
||||
UIStyle.Font = ui_font;
|
||||
}
|
||||
|
||||
bool FullscreenUI::InitializeWidgets(Error* error)
|
||||
bool FullscreenUI::InitializeWidgets(bool preserve_fsui_state, Error* error)
|
||||
{
|
||||
std::unique_lock lock(s_state.shared_state_mutex);
|
||||
|
||||
s_state.has_initialized = true;
|
||||
s_state.focus_reset_queued = FocusResetType::ViewChanged;
|
||||
s_state.close_button_state = CloseButtonState::None;
|
||||
|
||||
if (!(s_state.placeholder_texture = LoadTexture("images/placeholder.png")))
|
||||
Error::SetStringView(error, "Failed to load placeholder.png");
|
||||
if (!s_state.placeholder_texture || !CompileTransitionPipelines(error))
|
||||
{
|
||||
ShutdownWidgets(true);
|
||||
std::unique_lock lock(s_state.shared_state_mutex);
|
||||
|
||||
if (!(s_state.placeholder_texture = LoadTexture("images/placeholder.png")))
|
||||
{
|
||||
Error::SetStringView(error, "Failed to load placeholder.png");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CompileTransitionPipelines(error))
|
||||
{
|
||||
ShutdownWidgets(preserve_fsui_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preserve_fsui_state)
|
||||
{
|
||||
s_state.focus_reset_queued = FocusResetType::ViewChanged;
|
||||
s_state.close_button_state = CloseButtonState::None;
|
||||
ResetMenuButtonFrame();
|
||||
}
|
||||
|
||||
UpdateWidgetsSettings();
|
||||
ResetMenuButtonFrame();
|
||||
|
||||
s_state.has_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FullscreenUI::ShutdownWidgets(bool clear_state)
|
||||
void FullscreenUI::ShutdownWidgets(bool preserve_fsui_state)
|
||||
{
|
||||
std::unique_lock lock(s_state.shared_state_mutex);
|
||||
|
||||
@@ -435,7 +445,7 @@ void FullscreenUI::ShutdownWidgets(bool clear_state)
|
||||
|
||||
s_state.has_initialized = false;
|
||||
|
||||
if (clear_state)
|
||||
if (!preserve_fsui_state)
|
||||
{
|
||||
s_state.fullscreen_footer_icon_mapping = {};
|
||||
s_state.notifications.clear();
|
||||
|
||||
@@ -213,10 +213,10 @@ ImRect CenterImage(const ImRect& fit_rect, const GPUTexture* texture);
|
||||
ImRect FitImage(const ImVec2& fit_size, const ImVec2& image_size);
|
||||
|
||||
/// Initializes, setting up any state.
|
||||
bool InitializeWidgets(Error* error);
|
||||
bool InitializeWidgets(bool preserve_fsui_state, Error* error);
|
||||
|
||||
/// Shuts down, clearing all state.
|
||||
void ShutdownWidgets(bool clear_state);
|
||||
void ShutdownWidgets(bool preserve_fsui_state);
|
||||
|
||||
/// Loads settings from the settings interface.
|
||||
void UpdateWidgetsSettings();
|
||||
|
||||
@@ -72,8 +72,8 @@ static void WakeGPUThread();
|
||||
static void WakeGPUThreadIfSleeping();
|
||||
static bool SleepGPUThread(bool allow_sleep);
|
||||
|
||||
static bool CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_fsui_state_on_failure, Error* error);
|
||||
static void DestroyDeviceOnThread(bool clear_fsui_state);
|
||||
static bool CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool preserve_fsui_state, Error* error);
|
||||
static void DestroyDeviceOnThread(bool preserve_fsui_state);
|
||||
static void ResizeDisplayWindowOnThread(u32 width, u32 height, float scale);
|
||||
static void UpdateDisplayWindowOnThread(bool fullscreen, bool allow_exclusive_fullscreen);
|
||||
static void DisplayWindowResizedOnThread();
|
||||
@@ -626,7 +626,7 @@ bool GPUThread::IsFullscreen()
|
||||
return s_state.requested_fullscreen;
|
||||
}
|
||||
|
||||
bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_fsui_state_on_failure, Error* error)
|
||||
bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool preserve_fsui_state, Error* error)
|
||||
{
|
||||
DebugAssert(!g_gpu_device);
|
||||
|
||||
@@ -704,11 +704,11 @@ bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImGuiManager::Initialize(&create_error))
|
||||
if (!ImGuiManager::Initialize(preserve_fsui_state, &create_error))
|
||||
{
|
||||
ERROR_LOG("Failed to initialize ImGuiManager: {}", create_error.GetDescription());
|
||||
Error::SetStringFmt(error, "Failed to initialize ImGuiManager: {}", create_error.GetDescription());
|
||||
ImGuiManager::Shutdown(clear_fsui_state_on_failure);
|
||||
ImGuiManager::Shutdown(preserve_fsui_state);
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
if (wi.has_value())
|
||||
@@ -717,7 +717,7 @@ bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_
|
||||
}
|
||||
|
||||
if (s_state.requested_fullscreen_ui)
|
||||
FullscreenUI::Initialize();
|
||||
FullscreenUI::Initialize(preserve_fsui_state);
|
||||
|
||||
InputManager::SetDisplayWindowSize(ImGuiManager::GetWindowWidth(), ImGuiManager::GetWindowHeight());
|
||||
|
||||
@@ -739,7 +739,7 @@ bool GPUThread::CreateDeviceOnThread(RenderAPI api, bool fullscreen, bool clear_
|
||||
return true;
|
||||
}
|
||||
|
||||
void GPUThread::DestroyDeviceOnThread(bool clear_fsui_state)
|
||||
void GPUThread::DestroyDeviceOnThread(bool preserve_fsui_state)
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
@@ -747,8 +747,8 @@ void GPUThread::DestroyDeviceOnThread(bool clear_fsui_state)
|
||||
// Presenter should be gone by this point
|
||||
Assert(!s_state.gpu_presenter);
|
||||
|
||||
FullscreenUI::Shutdown(clear_fsui_state);
|
||||
ImGuiManager::Shutdown(clear_fsui_state);
|
||||
FullscreenUI::Shutdown(preserve_fsui_state);
|
||||
ImGuiManager::Shutdown(preserve_fsui_state);
|
||||
|
||||
INFO_LOG("Destroying {} GPU device...", GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
|
||||
g_gpu_device->Destroy();
|
||||
@@ -832,7 +832,7 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd)
|
||||
// Serial clear must be after backend destroy, otherwise textures won't dump.
|
||||
DestroyGPUBackendOnThread();
|
||||
DestroyGPUPresenterOnThread();
|
||||
DestroyDeviceOnThread(true);
|
||||
DestroyDeviceOnThread(false);
|
||||
ClearGameInfoOnThread();
|
||||
return;
|
||||
}
|
||||
@@ -864,12 +864,14 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd)
|
||||
Settings::GetRenderAPIForRenderer(s_state.requested_renderer.value_or(g_gpu_settings.gpu_renderer));
|
||||
if (cmd->force_recreate_device || !GPUDevice::IsSameRenderAPI(current_api, expected_api))
|
||||
{
|
||||
const bool preserve_fsui_state = FullscreenUI::IsInitialized();
|
||||
|
||||
Timer timer;
|
||||
DestroyGPUPresenterOnThread();
|
||||
DestroyDeviceOnThread(false);
|
||||
DestroyDeviceOnThread(preserve_fsui_state);
|
||||
|
||||
Error local_error;
|
||||
if (!CreateDeviceOnThread(expected_api, cmd->fullscreen, false, &local_error))
|
||||
if (!CreateDeviceOnThread(expected_api, cmd->fullscreen, preserve_fsui_state, &local_error))
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
OSDMessageType::Error, "DeviceSwitchFailed", ICON_FA_PAINT_ROLLER,
|
||||
@@ -878,7 +880,8 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd)
|
||||
local_error.GetDescription()));
|
||||
|
||||
Host::ReleaseRenderWindow();
|
||||
if (current_api == RenderAPI::None || !CreateDeviceOnThread(current_api, cmd->fullscreen, true, &local_error))
|
||||
if (current_api == RenderAPI::None ||
|
||||
!CreateDeviceOnThread(current_api, cmd->fullscreen, preserve_fsui_state, &local_error))
|
||||
{
|
||||
if (cmd->error_ptr)
|
||||
*cmd->error_ptr = local_error;
|
||||
@@ -919,18 +922,16 @@ void GPUThread::ReconfigureOnThread(GPUThreadReconfigureCommand* cmd)
|
||||
}
|
||||
else if (s_state.requested_fullscreen_ui)
|
||||
{
|
||||
if (!(*cmd->out_result = g_gpu_device || CreateDeviceOnThread(expected_api, cmd->fullscreen, true, cmd->error_ptr)))
|
||||
// s_state.requested_fullscreen_ui starts FullscreenUI in CreateDeviceOnThread().
|
||||
if (!(*cmd->out_result =
|
||||
g_gpu_device || CreateDeviceOnThread(expected_api, cmd->fullscreen, false, cmd->error_ptr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't need to present game frames anymore.
|
||||
DestroyGPUPresenterOnThread();
|
||||
ClearGameInfoOnThread();
|
||||
|
||||
// Don't need timing to run FSUI.
|
||||
g_gpu_device->SetGPUTimingEnabled(false);
|
||||
|
||||
// Ensure FSUI is initialized.
|
||||
FullscreenUI::Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,6 +961,9 @@ void GPUThread::DestroyGPUPresenterOnThread()
|
||||
Assert(!s_state.gpu_backend);
|
||||
Assert(GPUBackend::GetQueuedFrameCount() == 0);
|
||||
|
||||
// Don't need timing anymore.
|
||||
g_gpu_device->SetGPUTimingEnabled(false);
|
||||
|
||||
s_state.gpu_presenter.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ void ImGuiManager::SetTextFontOrder(const TextFontOrder& order)
|
||||
ReloadFontDataIfActive();
|
||||
}
|
||||
|
||||
bool ImGuiManager::Initialize(Error* error)
|
||||
bool ImGuiManager::Initialize(bool preserve_fsui_state, Error* error)
|
||||
{
|
||||
if (!LoadFontData(error))
|
||||
{
|
||||
@@ -230,8 +230,11 @@ bool ImGuiManager::Initialize(Error* error)
|
||||
FullscreenUI::UpdateTheme();
|
||||
FullscreenUI::UpdateLayoutScale();
|
||||
|
||||
if (!CreateFontAtlas(error) || !CompilePipelines(error) || !FullscreenUI::InitializeWidgets(error))
|
||||
if (!CreateFontAtlas(error) || !CompilePipelines(error) ||
|
||||
!FullscreenUI::InitializeWidgets(preserve_fsui_state, error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NewFrame();
|
||||
|
||||
@@ -239,11 +242,11 @@ bool ImGuiManager::Initialize(Error* error)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGuiManager::Shutdown(bool clear_fsui_state)
|
||||
void ImGuiManager::Shutdown(bool preserve_fsui_state)
|
||||
{
|
||||
DestroySoftwareCursorTextures();
|
||||
|
||||
FullscreenUI::ShutdownWidgets(clear_fsui_state);
|
||||
FullscreenUI::ShutdownWidgets(preserve_fsui_state);
|
||||
|
||||
s_state.text_font = nullptr;
|
||||
s_state.fixed_font = nullptr;
|
||||
|
||||
@@ -91,10 +91,10 @@ TextFontOrder GetDefaultTextFontOrder();
|
||||
void SetTextFontOrder(const TextFontOrder& order);
|
||||
|
||||
/// Initializes ImGui, creates fonts, etc.
|
||||
bool Initialize(Error* error);
|
||||
bool Initialize(bool preserve_fsui_state, Error* error);
|
||||
|
||||
/// Frees all ImGui resources.
|
||||
void Shutdown(bool clear_fsui_state);
|
||||
void Shutdown(bool preserve_fsui_state);
|
||||
|
||||
/// Returns main ImGui context.
|
||||
ImGuiContext* GetMainContext();
|
||||
|
||||
Reference in New Issue
Block a user