Core: Improve ordering of boot
- Smplification of graphics backend startup/shutdown. - Don't send complete message until CPU is ready to execute. - Remove redundant stop message. - Remove OSD message with backend name.
This commit is contained in:
parent
f9053527a9
commit
04027a7da7
|
@ -241,7 +241,6 @@ bool Init(std::unique_ptr<BootParameters> boot)
|
||||||
|
|
||||||
// Start the emu thread
|
// Start the emu thread
|
||||||
s_emu_thread = std::thread(EmuThread, std::move(boot));
|
s_emu_thread = std::thread(EmuThread, std::move(boot));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,9 +310,13 @@ void UndeclareAsCPUThread()
|
||||||
// For the CPU Thread only.
|
// For the CPU Thread only.
|
||||||
static void CPUSetInitialExecutionState()
|
static void CPUSetInitialExecutionState()
|
||||||
{
|
{
|
||||||
QueueHostJob([] {
|
// The CPU starts in stepping state, and will wait until a new state is set before executing.
|
||||||
|
// SetState must be called on the host thread, so we defer it for later.
|
||||||
|
QueueHostJob([]() {
|
||||||
SetState(SConfig::GetInstance().bBootToPause ? State::Paused : State::Running);
|
SetState(SConfig::GetInstance().bBootToPause ? State::Paused : State::Running);
|
||||||
|
Host_UpdateDisasmDialog();
|
||||||
Host_UpdateMainFrame();
|
Host_UpdateMainFrame();
|
||||||
|
Host_Message(WM_USER_CREATE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,17 +326,10 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
|
||||||
DeclareAsCPUThread();
|
DeclareAsCPUThread();
|
||||||
|
|
||||||
const SConfig& _CoreParameter = SConfig::GetInstance();
|
const SConfig& _CoreParameter = SConfig::GetInstance();
|
||||||
|
|
||||||
if (_CoreParameter.bCPUThread)
|
if (_CoreParameter.bCPUThread)
|
||||||
{
|
|
||||||
Common::SetCurrentThreadName("CPU thread");
|
Common::SetCurrentThreadName("CPU thread");
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
Common::SetCurrentThreadName("CPU-GPU thread");
|
Common::SetCurrentThreadName("CPU-GPU thread");
|
||||||
g_video_backend->Video_Prepare();
|
|
||||||
Host_Message(WM_USER_CREATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This needs to be delayed until after the video backend is ready.
|
// This needs to be delayed until after the video backend is ready.
|
||||||
DolphinAnalytics::Instance()->ReportGameStart();
|
DolphinAnalytics::Instance()->ReportGameStart();
|
||||||
|
@ -341,6 +337,17 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
|
||||||
if (_CoreParameter.bFastmem)
|
if (_CoreParameter.bFastmem)
|
||||||
EMM::InstallExceptionHandler(); // Let's run under memory watch
|
EMM::InstallExceptionHandler(); // Let's run under memory watch
|
||||||
|
|
||||||
|
#ifdef USE_MEMORYWATCHER
|
||||||
|
MemoryWatcher::Init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (savestate_path)
|
||||||
|
{
|
||||||
|
::State::LoadAs(*savestate_path);
|
||||||
|
if (delete_savestate)
|
||||||
|
File::Delete(*savestate_path);
|
||||||
|
}
|
||||||
|
|
||||||
s_is_started = true;
|
s_is_started = true;
|
||||||
CPUSetInitialExecutionState();
|
CPUSetInitialExecutionState();
|
||||||
|
|
||||||
|
@ -361,25 +368,11 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MEMORYWATCHER
|
|
||||||
MemoryWatcher::Init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (savestate_path)
|
|
||||||
{
|
|
||||||
::State::LoadAs(*savestate_path);
|
|
||||||
if (delete_savestate)
|
|
||||||
File::Delete(*savestate_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter CPU run loop. When we leave it - we are done.
|
// Enter CPU run loop. When we leave it - we are done.
|
||||||
CPU::Run();
|
CPU::Run();
|
||||||
|
|
||||||
s_is_started = false;
|
s_is_started = false;
|
||||||
|
|
||||||
if (!_CoreParameter.bCPUThread)
|
|
||||||
g_video_backend->Video_CleanupShared();
|
|
||||||
|
|
||||||
if (_CoreParameter.bFastmem)
|
if (_CoreParameter.bFastmem)
|
||||||
EMM::UninstallExceptionHandler();
|
EMM::UninstallExceptionHandler();
|
||||||
}
|
}
|
||||||
|
@ -388,18 +381,12 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
|
||||||
bool delete_savestate)
|
bool delete_savestate)
|
||||||
{
|
{
|
||||||
DeclareAsCPUThread();
|
DeclareAsCPUThread();
|
||||||
const SConfig& _CoreParameter = SConfig::GetInstance();
|
|
||||||
|
|
||||||
|
const SConfig& _CoreParameter = SConfig::GetInstance();
|
||||||
if (_CoreParameter.bCPUThread)
|
if (_CoreParameter.bCPUThread)
|
||||||
{
|
|
||||||
Common::SetCurrentThreadName("FIFO player thread");
|
Common::SetCurrentThreadName("FIFO player thread");
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
g_video_backend->Video_Prepare();
|
|
||||||
Host_Message(WM_USER_CREATE);
|
|
||||||
Common::SetCurrentThreadName("FIFO-GPU thread");
|
Common::SetCurrentThreadName("FIFO-GPU thread");
|
||||||
}
|
|
||||||
|
|
||||||
// Enter CPU run loop. When we leave it - we are done.
|
// Enter CPU run loop. When we leave it - we are done.
|
||||||
if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
|
if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
|
||||||
|
@ -412,20 +399,15 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
|
||||||
|
|
||||||
s_is_started = false;
|
s_is_started = false;
|
||||||
PowerPC::InjectExternalCPUCore(nullptr);
|
PowerPC::InjectExternalCPUCore(nullptr);
|
||||||
|
FifoPlayer::GetInstance().Close();
|
||||||
}
|
}
|
||||||
FifoPlayer::GetInstance().Close();
|
else
|
||||||
|
|
||||||
// If we did not enter the CPU Run Loop above then run a fake one instead.
|
|
||||||
// We need to be IsRunningAndStarted() for DolphinWX to stop us.
|
|
||||||
if (CPU::GetState() != CPU::State::PowerDown)
|
|
||||||
{
|
{
|
||||||
s_is_started = true;
|
// FIFO log does not contain any frames, cannot continue.
|
||||||
Host_Message(WM_USER_STOP);
|
PanicAlert("FIFO file is invalid, cannot playback.");
|
||||||
s_is_started = false;
|
FifoPlayer::GetInstance().Close();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_CoreParameter.bCPUThread)
|
|
||||||
g_video_backend->Video_CleanupShared();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize and create emulation thread
|
// Initialize and create emulation thread
|
||||||
|
@ -449,9 +431,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
||||||
INFO_LOG(CONSOLE, "Stop\t\t---- Shutdown complete ----");
|
INFO_LOG(CONSOLE, "Stop\t\t---- Shutdown complete ----");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Prevent the UI from getting stuck whenever an error occurs.
|
|
||||||
Common::ScopeGuard stop_message_guard{[] { Host_Message(WM_USER_STOP); }};
|
|
||||||
|
|
||||||
Common::SetCurrentThreadName("Emuthread - Starting");
|
Common::SetCurrentThreadName("Emuthread - Starting");
|
||||||
|
|
||||||
// For a time this acts as the CPU thread...
|
// For a time this acts as the CPU thread...
|
||||||
|
@ -485,9 +464,11 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
||||||
PanicAlert("Failed to initialize video backend!");
|
PanicAlert("Failed to initialize video backend!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }};
|
g_video_backend->Video_Prepare();
|
||||||
|
Common::ScopeGuard video_guard{[] {
|
||||||
OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000);
|
g_video_backend->Video_Cleanup();
|
||||||
|
g_video_backend->Shutdown();
|
||||||
|
}};
|
||||||
|
|
||||||
if (cpu_info.HTT)
|
if (cpu_info.HTT)
|
||||||
SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4;
|
SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4;
|
||||||
|
@ -568,9 +549,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
||||||
// This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
|
// This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
|
||||||
Fifo::Prepare();
|
Fifo::Prepare();
|
||||||
|
|
||||||
// Thread is no longer acting as CPU Thread
|
|
||||||
UndeclareAsCPUThread();
|
|
||||||
|
|
||||||
// Setup our core, but can't use dynarec if we are compare server
|
// Setup our core, but can't use dynarec if we are compare server
|
||||||
if (core_parameter.iCPUCore != PowerPC::CORE_INTERPRETER &&
|
if (core_parameter.iCPUCore != PowerPC::CORE_INTERPRETER &&
|
||||||
(!core_parameter.bRunCompareServer || core_parameter.bRunCompareClient))
|
(!core_parameter.bRunCompareServer || core_parameter.bRunCompareClient))
|
||||||
|
@ -582,21 +560,15 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
||||||
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
|
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the window again because all stuff is initialized
|
|
||||||
Host_UpdateDisasmDialog();
|
|
||||||
Host_UpdateMainFrame();
|
|
||||||
|
|
||||||
// ENTER THE VIDEO THREAD LOOP
|
// ENTER THE VIDEO THREAD LOOP
|
||||||
if (core_parameter.bCPUThread)
|
if (core_parameter.bCPUThread)
|
||||||
{
|
{
|
||||||
// This thread, after creating the EmuWindow, spawns a CPU
|
// This thread, after creating the EmuWindow, spawns a CPU
|
||||||
// thread, and then takes over and becomes the video thread
|
// thread, and then takes over and becomes the video thread
|
||||||
Common::SetCurrentThreadName("Video thread");
|
Common::SetCurrentThreadName("Video thread");
|
||||||
|
UndeclareAsCPUThread();
|
||||||
|
|
||||||
g_video_backend->Video_Prepare();
|
// Spawn the CPU thread. The CPU thread will signal the event that boot is complete.
|
||||||
Host_Message(WM_USER_CREATE);
|
|
||||||
|
|
||||||
// Spawn the CPU thread
|
|
||||||
s_cpu_thread = std::thread(cpuThreadFunc, savestate_path, delete_savestate);
|
s_cpu_thread = std::thread(cpuThreadFunc, savestate_path, delete_savestate);
|
||||||
|
|
||||||
// become the GPU thread
|
// become the GPU thread
|
||||||
|
@ -620,12 +592,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
||||||
gdb_deinit();
|
gdb_deinit();
|
||||||
INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str());
|
INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (core_parameter.bCPUThread)
|
|
||||||
g_video_backend->Video_CleanupShared();
|
|
||||||
|
|
||||||
// If we shut down normally, the stop message does not need to be triggered.
|
|
||||||
stop_message_guard.Dismiss();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set or get the running state
|
// Set or get the running state
|
||||||
|
|
|
@ -83,10 +83,9 @@ static Common::Event updateMainFrameEvent;
|
||||||
void Host_Message(int Id)
|
void Host_Message(int Id)
|
||||||
{
|
{
|
||||||
if (Id == WM_USER_STOP)
|
if (Id == WM_USER_STOP)
|
||||||
{
|
|
||||||
s_running.Clear();
|
s_running.Clear();
|
||||||
|
if (Id == WM_USER_JOB_DISPATCH || Id == WM_USER_STOP)
|
||||||
updateMainFrameEvent.Set();
|
updateMainFrameEvent.Set();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* s_window_handle = nullptr;
|
static void* s_window_handle = nullptr;
|
||||||
|
|
Loading…
Reference in New Issue