From df8c0d2b39319057a9f611b4490f5749387052d1 Mon Sep 17 00:00:00 2001 From: TryTwo Date: Thu, 16 Nov 2023 10:41:53 -0700 Subject: [PATCH 1/2] Core::GetState() bugfix: remove forced incorrect state on frame advance. This was implemented to prevent UI flickering due to the state rapidly switching between pause/play. Recently, it has been causing issues with debugger windows, which update during frame advance. --- Source/Core/Core/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 870d4729f7..5599573e62 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -750,7 +750,7 @@ State GetState() if (s_hardware_initialized) { auto& system = Core::System::GetInstance(); - if (system.GetCPU().IsStepping() || s_frame_step) + if (system.GetCPU().IsStepping()) return State::Paused; return State::Running; From b57ba42a55099f82a71c3acede18f9de0c67bf74 Mon Sep 17 00:00:00 2001 From: TryTwo Date: Thu, 16 Nov 2023 11:07:37 -0700 Subject: [PATCH 2/2] Core::SetState() allow state to change without sending a callback. Some state changes are meant to be near instantanoues, before switching to something else. By reporting ithe instant switch, the UI will flicker between states (pause/play button) and the debugger will unnecessarily update. Skipping the callback avoids these issues. --- Source/Core/Core/Core.cpp | 9 ++++++--- Source/Core/Core/Core.h | 2 +- Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 5599573e62..536244869a 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -712,7 +712,7 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi // Set or get the running state -void SetState(State state) +void SetState(State state, bool report_state_change) { // State cannot be controlled until the CPU Thread is operational if (!IsRunningAndStarted()) @@ -739,7 +739,10 @@ void SetState(State state) break; } - CallOnStateChangedCallbacks(GetState()); + // Certain callers only change the state momentarily. Sending a callback for them causes + // unwanted updates, such as the Pause/Play button flickering between states on frame advance. + if (report_state_change) + CallOnStateChangedCallbacks(GetState()); } State GetState() @@ -1083,7 +1086,7 @@ void DoFrameStep() // if already paused, frame advance for 1 frame s_stop_frame_step = false; s_frame_step = true; - SetState(State::Running); + SetState(State::Running, false); } else if (!s_frame_step) { diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 0ff8c32b5c..d8c5c9a0da 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -147,7 +147,7 @@ bool IsHostThread(); bool WantsDeterminism(); // [NOT THREADSAFE] For use by Host only -void SetState(State state); +void SetState(State state, bool report_state_change = true); State GetState(); void SaveScreenShot(); diff --git a/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp b/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp index 6698a8289e..f8610e3b85 100644 --- a/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp @@ -160,7 +160,7 @@ void CodeDiffDialog::ClearBlockCache() Core::State old_state = Core::GetState(); if (old_state == Core::State::Running) - Core::SetState(Core::State::Paused); + Core::SetState(Core::State::Paused, false); Core::System::GetInstance().GetJitInterface().ClearCache(); @@ -349,7 +349,7 @@ void CodeDiffDialog::Update(bool include) // Wrap everything in a pause Core::State old_state = Core::GetState(); if (old_state == Core::State::Running) - Core::SetState(Core::State::Paused); + Core::SetState(Core::State::Paused, false); // Main process if (include)