diff --git a/.gitignore b/.gitignore index 4631907118..dac6b5062a 100644 --- a/.gitignore +++ b/.gitignore @@ -90,6 +90,7 @@ __testerror.txt __testfinish.txt __testfailure.bmp __testcompare.png +vt_ref.bmp GameLogNotes.txt screenshots android/assets/lang diff --git a/Core/EmuThread.cpp b/Core/EmuThread.cpp index 4f1b9de872..95c861613f 100644 --- a/Core/EmuThread.cpp +++ b/Core/EmuThread.cpp @@ -43,7 +43,6 @@ enum class EmuThreadState { static std::thread emuThread; static std::atomic g_emuThreadState(EmuThreadState::DISABLED); -static std::thread mainThread; static std::string g_error_message; static bool g_inLoop; @@ -52,23 +51,7 @@ static GraphicsContext *g_graphicsContext; void MainThreadFunc(); -void MainThread_Start() { - mainThread = std::thread([]() { - MainThreadFunc(); - }); -} - -void MainThread_Stop() { - // Already stopped? - UpdateUIState(UISTATE_EXIT); - _dbg_assert_(mainThread.joinable()); - mainThread.join(); -} - bool MainThread_Ready() { - if (g_inLoop) { - _dbg_assert_(mainThread.joinable()); - } return g_inLoop; } @@ -152,8 +135,6 @@ void MainThreadFunc() { SetCurrentThreadName(useEmuThread ? "RenderThread" : "EmuThread"); - System_SetWindowTitle(""); - const bool performingRestart = NativeIsRestarting(); if (g_Config.sFailedGPUBackends.find("ALL") != std::string::npos) { diff --git a/Core/EmuThread.h b/Core/EmuThread.h index 80b99ca297..71ccf03690 100644 --- a/Core/EmuThread.h +++ b/Core/EmuThread.h @@ -20,6 +20,6 @@ // Utilities to manage Emu and Render threads. // TODO: Use across platforms, currently Windows-only. -void MainThread_Start(); -void MainThread_Stop(); bool MainThread_Ready(); + +void MainThreadFunc(); diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index a687957acf..013494d1c9 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -1070,7 +1070,7 @@ namespace MainWindow { g_InputManager.Shutdown(); WindowsRawInput::Shutdown(); - MainThread_Stop(); + UpdateUIState(UISTATE_EXIT); KillTimer(hWnd, TIMER_CURSORUPDATE); KillTimer(hWnd, TIMER_CURSORMOVEUPDATE); // Main window is gone, this tells the message loop to exit. diff --git a/Windows/main.cpp b/Windows/main.cpp index e65ad214ec..0941a1f8d4 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -1146,11 +1146,18 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin MainWindow::Minimize(); } - // Emu thread (and render thread, if any) is always running! + // Emu thread is always running! // OpenGL uses an externally managed render thread (due to GL's single-threaded context design). // Vulkan manages its own render thread. Our D3D backend doesn't have a render thread. // The Emu thread calls NativeInit() and NativeMain() etc. - MainThread_Start(); + + System_SetWindowTitle(""); + + std::thread mainThread = std::thread([]() { + MainThreadFunc(); + }); + + // This thread can become the render thread or the emu thread depending on the backend. g_InputManager.BeginPolling(); @@ -1190,15 +1197,18 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin if (!wnd || !accel || !TranslateAccelerator(wnd, accel, &msg)) { if (!DialogManager::IsDialogMessage(&msg)) { - //and finally translate and dispatch + // and finally translate and dispatch TranslateMessage(&msg); DispatchMessage(&msg); } } } - // When we've exited the loop, MainThread_Stop has already been called. - // So it's safe to call NativeShutdown. + // Already stopped? + _dbg_assert_(mainThread.joinable()); + mainThread.join(); + + // It's safe to call NativeShutdown, we've joined the main thread. NativeShutdown(); g_VFS.Clear();