diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 1e06d2ac83..80dfe6d565 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -377,7 +377,7 @@ void GLRenderManager::Finish() { frameData_[curFrame].deleter.Take(deleter_); VLOG("PUSH: Finish, pushing task. curFrame = %d", curFrame); - GLRRenderThreadTask *task = new GLRRenderThreadTask(GLRRunType::PRESENT); + GLRRenderThreadTask *task = new GLRRenderThreadTask(GLRRunType::SUBMIT); task->frame = curFrame; { @@ -414,10 +414,56 @@ void GLRenderManager::Finish() { insideFrame_ = false; } +void GLRenderManager::Present() { + int curFrame = GetCurFrame(); + GLRRenderThreadTask *task = new GLRRenderThreadTask(GLRRunType::PRESENT); + task->frame = curFrame; + std::unique_lock lock(pushMutex_); + renderThreadQueue_.push(task); +} + // Render thread. Returns true if the caller should handle a swap. bool GLRenderManager::Run(GLRRenderThreadTask &task) { GLFrameData &frameData = frameData_[task.frame]; + if (task.runType == GLRRunType::PRESENT) { + bool swapRequest = false; + if (!frameData.skipSwap) { + if (swapIntervalChanged_) { + swapIntervalChanged_ = false; + if (swapIntervalFunction_) { + swapIntervalFunction_(swapInterval_); + } + } + // This is the swapchain framebuffer flip. + if (swapFunction_) { + VLOG(" PULL: SwapFunction()"); + swapFunction_(); + if (!retainControl_) { + // get out of here. + swapRequest = true; + } + } else { + VLOG(" PULL: SwapRequested"); + swapRequest = true; + } + } else { + frameData.skipSwap = false; + } + frameData.hasBegun = false; + + VLOG(" PULL: Frame %d.readyForFence = true", task.frame); + + { + std::lock_guard lock(frameData.fenceMutex); + frameData.readyForFence = true; + frameData.fenceCondVar.notify_one(); + // At this point, we're done with this framedata (for now). + } + + return swapRequest; + } + if (!frameData.hasBegun) { frameData.hasBegun = true; @@ -461,43 +507,8 @@ bool GLRenderManager::Run(GLRRenderThreadTask &task) { } } - bool swapRequest = false; - switch (task.runType) { - case GLRRunType::PRESENT: - if (!frameData.skipSwap) { - if (swapIntervalChanged_) { - swapIntervalChanged_ = false; - if (swapIntervalFunction_) { - swapIntervalFunction_(swapInterval_); - } - } - // This is the swapchain framebuffer flip. - if (swapFunction_) { - VLOG(" PULL: SwapFunction()"); - swapFunction_(); - if (!retainControl_) { - // get out of here. - swapRequest = true; - } - } else { - VLOG(" PULL: SwapRequested"); - swapRequest = true; - } - } else { - frameData.skipSwap = false; - } - frameData.hasBegun = false; - - VLOG(" PULL: Frame %d.readyForFence = true", task.frame); - - { - std::lock_guard lock(frameData.fenceMutex); - frameData.readyForFence = true; - frameData.fenceCondVar.notify_one(); - // At this point, we're done with this framedata (for now). - } - + case GLRRunType::SUBMIT: break; case GLRRunType::SYNC: @@ -516,7 +527,7 @@ bool GLRenderManager::Run(GLRRenderThreadTask &task) { _assert_(false); } VLOG(" PULL: ::Run(): Done running tasks"); - return swapRequest; + return false; } void GLRenderManager::FlushSync() { diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 5cfc5711ed..c714fb2d61 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -198,6 +198,7 @@ public: }; enum class GLRRunType { + SUBMIT, PRESENT, SYNC, EXIT, @@ -253,7 +254,8 @@ public: // Makes sure that the GPU has caught up enough that we can start writing buffers of this frame again. void BeginFrame(bool enableProfiling); // Can run on a different thread! - void Finish(); + void Finish(); + void Present(); // Creation commands. These were not needed in Vulkan since there we can do that on the main thread. // We pass in width/height here even though it's not strictly needed until we support glTextureStorage diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 8da8345109..124a5c0583 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -803,6 +803,7 @@ void OpenGLContext::EndFrame() { } void OpenGLContext::Present() { + renderManager_.Present(); frameCount_++; } diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 9274e4cc15..fb29d8c77d 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1172,8 +1172,10 @@ namespace Libretro gpu->EndHostFrame(); - if (ctx->GetDrawContext()) + if (ctx->GetDrawContext()) { ctx->GetDrawContext()->EndFrame(); + ctx->GetDrawContext()->Present(); + } } static void EmuThreadFunc()