From 04027a7da774bfcafeff0b8565417e43e5e3c198 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 26 Jan 2018 14:41:57 +1000 Subject: [PATCH] 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. --- Source/Core/Core/Core.cpp | 94 ++++++++------------------ Source/Core/DolphinNoGUI/MainNoGUI.cpp | 3 +- 2 files changed, 31 insertions(+), 66 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index b1fdd8261a..61ab1f9062 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -241,7 +241,6 @@ bool Init(std::unique_ptr boot) // Start the emu thread s_emu_thread = std::thread(EmuThread, std::move(boot)); - return true; } @@ -311,9 +310,13 @@ void UndeclareAsCPUThread() // For the CPU Thread only. 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); + Host_UpdateDisasmDialog(); Host_UpdateMainFrame(); + Host_Message(WM_USER_CREATE); }); } @@ -323,17 +326,10 @@ static void CpuThread(const std::optional& savestate_path, bool del DeclareAsCPUThread(); const SConfig& _CoreParameter = SConfig::GetInstance(); - if (_CoreParameter.bCPUThread) - { Common::SetCurrentThreadName("CPU thread"); - } else - { 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. DolphinAnalytics::Instance()->ReportGameStart(); @@ -341,6 +337,17 @@ static void CpuThread(const std::optional& savestate_path, bool del if (_CoreParameter.bFastmem) 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; CPUSetInitialExecutionState(); @@ -361,25 +368,11 @@ static void CpuThread(const std::optional& savestate_path, bool del } #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. CPU::Run(); s_is_started = false; - if (!_CoreParameter.bCPUThread) - g_video_backend->Video_CleanupShared(); - if (_CoreParameter.bFastmem) EMM::UninstallExceptionHandler(); } @@ -388,18 +381,12 @@ static void FifoPlayerThread(const std::optional& savestate_path, bool delete_savestate) { DeclareAsCPUThread(); - const SConfig& _CoreParameter = SConfig::GetInstance(); + const SConfig& _CoreParameter = SConfig::GetInstance(); if (_CoreParameter.bCPUThread) - { Common::SetCurrentThreadName("FIFO player thread"); - } else - { - g_video_backend->Video_Prepare(); - Host_Message(WM_USER_CREATE); Common::SetCurrentThreadName("FIFO-GPU thread"); - } // Enter CPU run loop. When we leave it - we are done. if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore()) @@ -412,20 +399,15 @@ static void FifoPlayerThread(const std::optional& savestate_path, s_is_started = false; PowerPC::InjectExternalCPUCore(nullptr); + FifoPlayer::GetInstance().Close(); } - FifoPlayer::GetInstance().Close(); - - // 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) + else { - s_is_started = true; - Host_Message(WM_USER_STOP); - s_is_started = false; + // FIFO log does not contain any frames, cannot continue. + PanicAlert("FIFO file is invalid, cannot playback."); + FifoPlayer::GetInstance().Close(); + return; } - - if (!_CoreParameter.bCPUThread) - g_video_backend->Video_CleanupShared(); } // Initialize and create emulation thread @@ -449,9 +431,6 @@ static void EmuThread(std::unique_ptr boot) 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"); // For a time this acts as the CPU thread... @@ -485,9 +464,11 @@ static void EmuThread(std::unique_ptr boot) PanicAlert("Failed to initialize video backend!"); return; } - Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }}; - - OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); + g_video_backend->Video_Prepare(); + Common::ScopeGuard video_guard{[] { + g_video_backend->Video_Cleanup(); + g_video_backend->Shutdown(); + }}; if (cpu_info.HTT) SConfig::GetInstance().bDSPThread = cpu_info.num_cores > 4; @@ -568,9 +549,6 @@ static void EmuThread(std::unique_ptr boot) // This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block. Fifo::Prepare(); - // Thread is no longer acting as CPU Thread - UndeclareAsCPUThread(); - // Setup our core, but can't use dynarec if we are compare server if (core_parameter.iCPUCore != PowerPC::CORE_INTERPRETER && (!core_parameter.bRunCompareServer || core_parameter.bRunCompareClient)) @@ -582,21 +560,15 @@ static void EmuThread(std::unique_ptr boot) PowerPC::SetMode(PowerPC::CoreMode::Interpreter); } - // Update the window again because all stuff is initialized - Host_UpdateDisasmDialog(); - Host_UpdateMainFrame(); - // ENTER THE VIDEO THREAD LOOP if (core_parameter.bCPUThread) { // This thread, after creating the EmuWindow, spawns a CPU // thread, and then takes over and becomes the video thread Common::SetCurrentThreadName("Video thread"); + UndeclareAsCPUThread(); - g_video_backend->Video_Prepare(); - Host_Message(WM_USER_CREATE); - - // Spawn the CPU thread + // Spawn the CPU thread. The CPU thread will signal the event that boot is complete. s_cpu_thread = std::thread(cpuThreadFunc, savestate_path, delete_savestate); // become the GPU thread @@ -620,12 +592,6 @@ static void EmuThread(std::unique_ptr boot) gdb_deinit(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str()); #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 diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 9582facf2d..574ebc07ba 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -83,10 +83,9 @@ static Common::Event updateMainFrameEvent; void Host_Message(int Id) { if (Id == WM_USER_STOP) - { s_running.Clear(); + if (Id == WM_USER_JOB_DISPATCH || Id == WM_USER_STOP) updateMainFrameEvent.Set(); - } } static void* s_window_handle = nullptr;