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:
Stenzek 2018-01-26 14:41:57 +10:00
parent f9053527a9
commit 04027a7da7
2 changed files with 31 additions and 66 deletions

View File

@ -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

View File

@ -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;