diff --git a/ext/aemu_postoffice b/ext/aemu_postoffice index d4dd0e90f4..9e533637b9 160000 --- a/ext/aemu_postoffice +++ b/ext/aemu_postoffice @@ -1 +1 @@ -Subproject commit d4dd0e90f411b7cd1a1a38610a3712f2b46a6bc7 +Subproject commit 9e533637b9a13bb0194c75cf43b0bf6d25d8101a diff --git a/libretro/LibretroGLContext.cpp b/libretro/LibretroGLContext.cpp index 1f4bb6e5fc..3ac3765a97 100644 --- a/libretro/LibretroGLContext.cpp +++ b/libretro/LibretroGLContext.cpp @@ -42,3 +42,7 @@ void LibretroGLContext::DestroyDrawContext() { LibretroHWRenderContext::DestroyDrawContext(); renderManager_ = nullptr; } + +void LibretroGLContext::NotifyEmuThreadExit() { + renderManager_->NotifyEmuThreadExit(); +} diff --git a/libretro/LibretroGLContext.h b/libretro/LibretroGLContext.h index 296e6efd1c..0ae24937d0 100644 --- a/libretro/LibretroGLContext.h +++ b/libretro/LibretroGLContext.h @@ -27,12 +27,15 @@ public: } void ThreadStart() override { renderManager_->ThreadStart(draw_); } - bool ThreadFrame(bool waitIfEmpty) override { return renderManager_->ThreadFrame(waitIfEmpty); } + bool ThreadFrame() override { return renderManager_->ThreadFrame(); } void ThreadEnd() override { renderManager_->ThreadEnd(); } GPUCore GetGPUCore() override { return GPUCORE_GLES; } const char *Ident() override { return "OpenGL"; } + // Call from emu thread + void NotifyEmuThreadExit() override; + private: GLRenderManager *renderManager_ = nullptr; bool glewInitDone = false; diff --git a/libretro/LibretroGLCoreContext.cpp b/libretro/LibretroGLCoreContext.cpp index 968fcf2059..de549e0380 100644 --- a/libretro/LibretroGLCoreContext.cpp +++ b/libretro/LibretroGLCoreContext.cpp @@ -44,3 +44,7 @@ void LibretroGLCoreContext::DestroyDrawContext() { LibretroHWRenderContext::DestroyDrawContext(); renderManager_ = nullptr; } + +void LibretroGLCoreContext::NotifyEmuThreadExit() { + renderManager_->NotifyEmuThreadExit(); +} diff --git a/libretro/LibretroGLCoreContext.h b/libretro/LibretroGLCoreContext.h index e97bb128e0..d91c20164d 100644 --- a/libretro/LibretroGLCoreContext.h +++ b/libretro/LibretroGLCoreContext.h @@ -21,9 +21,12 @@ public: } void ThreadStart() override { renderManager_->ThreadStart(draw_); } - bool ThreadFrame(bool waitIfEmpty) override { return renderManager_->ThreadFrame(waitIfEmpty); } + bool ThreadFrame() override { return renderManager_->ThreadFrame(); } void ThreadEnd() override { renderManager_->ThreadEnd(); } + // Call from emu thread + void NotifyEmuThreadExit() override; + GPUCore GetGPUCore() override { return GPUCORE_GLES; } const char *Ident() override { return "OpenGL Core"; } diff --git a/libretro/LibretroGraphicsContext.h b/libretro/LibretroGraphicsContext.h index e644ae8f96..5e0bc2ac4c 100644 --- a/libretro/LibretroGraphicsContext.h +++ b/libretro/LibretroGraphicsContext.h @@ -96,9 +96,7 @@ extern retro_hw_context_type backend; enum class EmuThreadState { DISABLED, - START_REQUESTED, RUNNING, - PAUSE_REQUESTED, PAUSED, QUIT_REQUESTED, STOPPED, diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 7b38fd175d..bcde70a12c 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1384,34 +1384,32 @@ namespace Libretro { for (;;) { switch ((EmuThreadState)emuThreadState) { - case EmuThreadState::START_REQUESTED: - emuThreadState = EmuThreadState::RUNNING; - [[fallthrough]]; case EmuThreadState::RUNNING: EmuFrame(); break; - case EmuThreadState::PAUSE_REQUESTED: - emuThreadState = EmuThreadState::PAUSED; - [[fallthrough]]; case EmuThreadState::PAUSED: sleep_ms(1, "libretro-paused"); break; - default: case EmuThreadState::QUIT_REQUESTED: + ctx->NotifyEmuThreadExit(); emuThreadState = EmuThreadState::STOPPED; return; + default: + _dbg_assert_(false); + return; } } + // Unreachable } void EmuThreadStart() { EmuThreadState state = emuThreadState; bool wasPaused = state == EmuThreadState::PAUSED; - if (state == EmuThreadState::RUNNING || state == EmuThreadState::START_REQUESTED || (emuThread.joinable() && !wasPaused)) + if (state == EmuThreadState::RUNNING || (emuThread.joinable() && !wasPaused)) return; - emuThreadState = EmuThreadState::START_REQUESTED; + emuThreadState = EmuThreadState::RUNNING; if (!wasPaused) { @@ -1426,6 +1424,9 @@ namespace Libretro { emuThreadState = EmuThreadState::QUIT_REQUESTED; + // Eat remaining frames. + while (ctx->ThreadFrame()) {} + emuThread.join(); emuThread = std::thread(); ctx->ThreadEnd(); @@ -1435,7 +1436,7 @@ namespace Libretro { if (emuThreadState != EmuThreadState::RUNNING) return; - emuThreadState = EmuThreadState::PAUSE_REQUESTED; + emuThreadState = EmuThreadState::PAUSED; // Is this safe? ctx->ThreadFrame(); // Eat 1 frame @@ -1709,8 +1710,7 @@ void retro_run(void) { // Handle thread pumping. if (useEmuThread) { - if (emuThreadState == EmuThreadState::PAUSED || - emuThreadState == EmuThreadState::PAUSE_REQUESTED) { + if (emuThreadState == EmuThreadState::PAUSED) { VsyncSwapIntervalDetect(); ctx->SwapBuffers(); return; diff --git a/pspautotests b/pspautotests index 4374348477..6ba9cf9e1e 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 4374348477b425f48f99c8fd58a853c439f78acd +Subproject commit 6ba9cf9e1eca2fd911dfa728f5509bb321d36b20