Implement the new shutdown path for libretro too

This commit is contained in:
Henrik Rydgård
2026-08-04 17:45:03 +02:00
parent be922eca62
commit c42a3f070a
8 changed files with 30 additions and 18 deletions
+4
View File
@@ -42,3 +42,7 @@ void LibretroGLContext::DestroyDrawContext() {
LibretroHWRenderContext::DestroyDrawContext();
renderManager_ = nullptr;
}
void LibretroGLContext::NotifyEmuThreadExit() {
renderManager_->NotifyEmuThreadExit();
}
+4 -1
View File
@@ -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;
+4
View File
@@ -44,3 +44,7 @@ void LibretroGLCoreContext::DestroyDrawContext() {
LibretroHWRenderContext::DestroyDrawContext();
renderManager_ = nullptr;
}
void LibretroGLCoreContext::NotifyEmuThreadExit() {
renderManager_->NotifyEmuThreadExit();
}
+4 -1
View File
@@ -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"; }
-2
View File
@@ -96,9 +96,7 @@ extern retro_hw_context_type backend;
enum class EmuThreadState {
DISABLED,
START_REQUESTED,
RUNNING,
PAUSE_REQUESTED,
PAUSED,
QUIT_REQUESTED,
STOPPED,
+12 -12
View File
@@ -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;