From d167a11b1cddd541bd14c8b0f47e66fa0f19d4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 29 Dec 2022 16:14:54 +0100 Subject: [PATCH] SDL: Add a way to reset OpenGL graphics by pressing F7. --- Common/GPU/OpenGL/GLFeatures.cpp | 10 +++---- SDL/SDLGLGraphicsContext.cpp | 3 +++ SDL/SDLMain.cpp | 45 +++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Common/GPU/OpenGL/GLFeatures.cpp b/Common/GPU/OpenGL/GLFeatures.cpp index 9b1e313372..8dee1e98c2 100644 --- a/Common/GPU/OpenGL/GLFeatures.cpp +++ b/Common/GPU/OpenGL/GLFeatures.cpp @@ -626,11 +626,11 @@ bool CheckGLExtensions() { } void SetGLCoreContext(bool flag) { - _assert_msg_(!extensionsDone, "SetGLCoreContext() after CheckGLExtensions()"); - - useCoreContext = flag; - // For convenience, it'll get reset later. - gl_extensions.IsCoreContext = useCoreContext; + if (!extensionsDone) { + useCoreContext = flag; + // For convenience, it'll get reset later. + gl_extensions.IsCoreContext = useCoreContext; + } } void ResetGLExtensions() { diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index b3c580d3b4..91b89a4966 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -449,9 +449,12 @@ void SDLGLGraphicsContext::Shutdown() { void SDLGLGraphicsContext::ShutdownFromRenderThread() { delete draw_; draw_ = nullptr; + renderManager_ = nullptr; #ifdef USING_EGL EGL_Close(); #endif SDL_GL_DeleteContext(glContext); + glContext = nullptr; + window_ = nullptr; } diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index c49df319a7..ac47c7b478 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -589,7 +589,7 @@ static void EmuThreadStart(GraphicsContext *context) { emuThread = std::thread(&EmuThreadFunc, context); } -static void EmuThreadStop() { +static void EmuThreadStop(const char *reason) { emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; } @@ -931,9 +931,11 @@ int main(int argc, char *argv[]) { #if PPSSPP_PLATFORM(MAC) // setup menu items for macOS - initializeOSXExtras(); + initializeOSXExtras(); #endif + bool rebootEmuThread = false; + while (true) { double startTime = time_now_d(); @@ -1046,6 +1048,13 @@ int main(int argc, char *argv[]) { key.keyCode = mapped->second; key.deviceId = DEVICE_ID_KEYBOARD; NativeKey(key); + +#ifdef _DEBUG + if (k == SDLK_F7 && useEmuThread) { + printf("f7 pressed - rebooting emuthread\n"); + rebootEmuThread = true; + } +#endif break; } case SDL_KEYUP: @@ -1349,6 +1358,36 @@ int main(int argc, char *argv[]) { } } + if (rebootEmuThread) { + printf("rebooting emu thread"); + rebootEmuThread = false; + EmuThreadStop("shutdown"); + // Skipping GL calls, the old context is gone. + while (graphicsContext->ThreadFrame()) { + INFO_LOG(SYSTEM, "graphicsContext->ThreadFrame executed to clear buffers"); + } + EmuThreadJoin(); + graphicsContext->ThreadEnd(); + graphicsContext->ShutdownFromRenderThread(); + + printf("OK, shutdown complete. starting up graphics again.\n"); + + if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) { + SDLGLGraphicsContext *ctx = (SDLGLGraphicsContext *)graphicsContext; + if (!ctx->Init(window, x, y, w, h, mode, &error_message)) { + printf("Failed to reinit graphics.\n"); + } + } + + if (!graphicsContext->InitFromRenderThread(&error_message)) { + System_Toast("Graphics initialization failed. Quitting."); + return 1; + } + + EmuThreadStart(graphicsContext); + graphicsContext->ThreadStart(); + } + // Simple throttling to not burn the GPU in the menu. if (GetUIState() != UISTATE_INGAME || !PSP_IsInited() || renderThreadPaused) { double diffTime = time_now_d() - startTime; @@ -1361,7 +1400,7 @@ int main(int argc, char *argv[]) { } if (useEmuThread) { - EmuThreadStop(); + EmuThreadStop("shutdown"); while (graphicsContext->ThreadFrame()) { // Need to keep eating frames to allow the EmuThread to exit correctly. continue;