diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 305edfcfd..3c8ed4a63 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -6187,16 +6187,22 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested) if (l == 0) { - CurrentRenderer->SetFramebufferFlushStates(this->_engineMain->WillRender3DLayer(), this->_engineMain->WillCapture3DLayerDirect()); - CurrentRenderer->RenderFinish(); - CurrentRenderer->SetFramebufferFlushStates(true, true); - this->_event->DidFrameBegin(); - this->UpdateRenderProperties(); // Clear displays to black if they are turned off by the user. if (!isFrameSkipRequested) { + if (CurrentRenderer->GetRenderNeedsFinish()) + { + CurrentRenderer->SetFramebufferFlushStates(this->_engineMain->WillRender3DLayer(), this->_engineMain->WillCapture3DLayerDirect()); + CurrentRenderer->RenderFinish(); + CurrentRenderer->SetFramebufferFlushStates(true, true); + CurrentRenderer->SetRenderNeedsFinish(false); + this->_event->DidRender3DEnd(); + } + + this->UpdateRenderProperties(); + if (!CommonSettings.showGpu.main) { memset(this->_engineMain->renderedBuffer, 0, this->_engineMain->renderedWidth * this->_engineMain->renderedHeight * sizeof(u16)); diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 6bfb21e89..8ed4840a8 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -2996,9 +2996,8 @@ Render3DError OpenGLRenderer_1_2::Reset() Render3DError OpenGLRenderer_1_2::RenderFinish() { - if (!this->_pixelReadNeedsFinish) + if (!this->_renderNeedsFinish || !this->_pixelReadNeedsFinish) { - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_NOERR; } @@ -3009,7 +3008,6 @@ Render3DError OpenGLRenderer_1_2::RenderFinish() { if(!BEGINGL()) { - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_BEGINGL_FAILED; } @@ -3029,7 +3027,6 @@ Render3DError OpenGLRenderer_1_2::RenderFinish() this->_pixelReadNeedsFinish = false; - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_NOERR; } @@ -4495,9 +4492,8 @@ Render3DError OpenGLRenderer_2_1::ReadBackPixels() Render3DError OpenGLRenderer_2_1::RenderFinish() { - if (!this->_pixelReadNeedsFinish) + if (!this->_renderNeedsFinish || !this->_pixelReadNeedsFinish) { - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_NOERR; } @@ -4508,7 +4504,6 @@ Render3DError OpenGLRenderer_2_1::RenderFinish() { if(!BEGINGL()) { - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_BEGINGL_FAILED; } @@ -4520,6 +4515,5 @@ Render3DError OpenGLRenderer_2_1::RenderFinish() this->_pixelReadNeedsFinish = false; - GPU->GetEventHandler()->DidRender3DEnd(); return OGLERROR_NOERR; } diff --git a/desmume/src/cocoa/cocoa_GPU.h b/desmume/src/cocoa/cocoa_GPU.h index d15e0d5f3..c95dfb352 100644 --- a/desmume/src/cocoa/cocoa_GPU.h +++ b/desmume/src/cocoa/cocoa_GPU.h @@ -27,6 +27,7 @@ class GPUEventHandlerOSX; UInt32 gpuStateFlags; uint8_t _gpuScale; BOOL isCPUCoreCountAuto; + BOOL _needRestoreFrameLock; BOOL _needRestoreRender3DLock; OSSpinLock spinlockGpuState; diff --git a/desmume/src/cocoa/cocoa_GPU.mm b/desmume/src/cocoa/cocoa_GPU.mm index cec8a5d35..25d9abc6c 100644 --- a/desmume/src/cocoa/cocoa_GPU.mm +++ b/desmume/src/cocoa/cocoa_GPU.mm @@ -48,8 +48,7 @@ private: pthread_mutex_t _mutex3DRender; pthread_mutex_t *_mutexOutputList; NSMutableArray *_cdsOutputList; - bool _isRender3DLockHeld; - bool _isIn3DRender; + bool _render3DNeedsFinish; public: GPUEventHandlerOSX(); @@ -67,7 +66,7 @@ public: pthread_rwlock_t* GetFrameRWLock(); NSMutableArray* GetOutputList(); void SetOutputList(NSMutableArray *outputList, pthread_mutex_t *theMutex); - bool IsRender3DLockHeld(); + bool GetRender3DNeedsFinish(); virtual void DidFrameBegin(); virtual void DidFrameEnd(bool isFrameSkipped); @@ -132,6 +131,7 @@ public: GPUSTATE_SUB_OBJ_MASK; isCPUCoreCountAuto = NO; + _needRestoreFrameLock = NO; _needRestoreRender3DLock = NO; SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, @@ -188,23 +188,23 @@ public: - (void) setGpuDimensions:(NSSize)theDimensions { gpuEvent->FrameFinish(); - gpuEvent->FramebufferLockWrite(); gpuEvent->Render3DLock(); + gpuEvent->FramebufferLockWrite(); GPU->SetCustomFramebufferSize(theDimensions.width, theDimensions.height); gpuEvent->SetVideoBuffers(); - gpuEvent->Render3DUnlock(); gpuEvent->FramebufferUnlock(); + gpuEvent->Render3DUnlock(); } - (NSSize) gpuDimensions { - gpuEvent->FramebufferLockRead(); gpuEvent->Render3DLock(); + gpuEvent->FramebufferLockRead(); const NSSize dimensions = NSMakeSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight()); - gpuEvent->Render3DUnlock(); gpuEvent->FramebufferUnlock(); + gpuEvent->Render3DUnlock(); return dimensions; } @@ -362,7 +362,7 @@ public: CommonSettings.num_cores = numberCores; - if (renderingEngineID == CORE3DLIST_SWRASTERIZE || renderingEngineID == CORE3DLIST_OPENGL) + if (renderingEngineID == CORE3DLIST_SWRASTERIZE) { NDS_3D_ChangeCore(renderingEngineID); } @@ -703,7 +703,7 @@ public: { if (isPaused) { - if (gpuEvent->IsRender3DLockHeld()) + if (!_needRestoreRender3DLock && gpuEvent->GetRender3DNeedsFinish()) { gpuEvent->Render3DUnlock(); _needRestoreRender3DLock = YES; @@ -723,8 +723,7 @@ public: GPUEventHandlerOSX::GPUEventHandlerOSX() { - _isRender3DLockHeld = false; - _isIn3DRender = false; + _render3DNeedsFinish = false; _mutexOutputList = NULL; pthread_rwlock_init(&_rwlockFrame, NULL); pthread_mutex_init(&_mutex3DRender, NULL); @@ -732,13 +731,11 @@ GPUEventHandlerOSX::GPUEventHandlerOSX() GPUEventHandlerOSX::~GPUEventHandlerOSX() { - if (this->_isRender3DLockHeld) + if (this->_render3DNeedsFinish) { pthread_mutex_unlock(&this->_mutex3DRender); } - this->Render3DUnlock(); - pthread_rwlock_destroy(&this->_rwlockFrame); pthread_mutex_destroy(&this->_mutex3DRender); } @@ -780,17 +777,14 @@ void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped) void GPUEventHandlerOSX::DidRender3DBegin() { - this->_isIn3DRender = true; this->Render3DLock(); + this->_render3DNeedsFinish = true; } void GPUEventHandlerOSX::DidRender3DEnd() { - if (this->_isIn3DRender) - { - this->Render3DUnlock(); - this->_isIn3DRender = false; - } + this->_render3DNeedsFinish = false; + this->Render3DUnlock(); } void GPUEventHandlerOSX::FramebufferLockWrite() @@ -811,16 +805,11 @@ void GPUEventHandlerOSX::FramebufferUnlock() void GPUEventHandlerOSX::Render3DLock() { pthread_mutex_lock(&this->_mutex3DRender); - this->_isRender3DLockHeld = true; } void GPUEventHandlerOSX::Render3DUnlock() { - if (this->_isRender3DLockHeld) - { - this->_isRender3DLockHeld = false; - pthread_mutex_unlock(&this->_mutex3DRender); - } + pthread_mutex_unlock(&this->_mutex3DRender); } void GPUEventHandlerOSX::FrameFinish() @@ -873,9 +862,9 @@ void GPUEventHandlerOSX::SetVideoBuffers() #endif } -bool GPUEventHandlerOSX::IsRender3DLockHeld() +bool GPUEventHandlerOSX::GetRender3DNeedsFinish() { - return this->_isRender3DLockHeld; + return this->_render3DNeedsFinish; } pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock() diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 2d834c3bb..4b9980d98 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -2318,6 +2318,17 @@ void gfx3d_VBlankEndSignal(bool skipFrame) return; } + if (CurrentRenderer->GetRenderNeedsFinish()) + { + CurrentRenderer->SetFramebufferFlushStates(false, false); + CurrentRenderer->RenderFinish(); + CurrentRenderer->SetFramebufferFlushStates(true, true); + CurrentRenderer->SetRenderNeedsFinish(false); + GPU->GetEventHandler()->DidRender3DEnd(); + } + + GPU->GetEventHandler()->DidRender3DBegin(); + CurrentRenderer->SetRenderNeedsFinish(true); CurrentRenderer->Render(gfx3d); } diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index ba75b62cb..fbc5e4724 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -1929,7 +1929,6 @@ Render3DError SoftRasterizerRenderer::Render(const GFX3D &engine) { Render3DError error = RENDER3DERROR_NOERR; - GPU->GetEventHandler()->DidRender3DBegin(); error = this->BeginRender(engine); if (error != RENDER3DERROR_NOERR) { @@ -1966,9 +1965,8 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount) Render3DError SoftRasterizerRenderer::RenderFinish() { - if (!this->_renderGeometryNeedsFinish) + if (!this->_renderNeedsFinish || !this->_renderGeometryNeedsFinish) { - GPU->GetEventHandler()->DidRender3DEnd(); return RENDER3DERROR_NOERR; } @@ -2005,7 +2003,6 @@ Render3DError SoftRasterizerRenderer::RenderFinish() u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL; this->FlushFramebuffer(this->_framebufferColor, NULL, framebufferRGBA5551); - GPU->GetEventHandler()->DidRender3DEnd(); return RENDER3DERROR_NOERR; } diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index 1cf6353b3..b1cad7f89 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -83,10 +83,12 @@ bool NDS_3D_ChangeCore(int newCore) // Some resources are shared between renderers, such as the texture cache, // so we need to shut down the current renderer now to ensure that any // shared resources aren't in use. + const bool didRenderBegin = CurrentRenderer->GetRenderNeedsFinish(); CurrentRenderer->RenderFinish(); gpu3D->NDS_3D_Close(); gpu3D = &gpu3DNull; cur3DCore = GPU3D_NULL; + BaseRenderer->SetRenderNeedsFinish(didRenderBegin); CurrentRenderer = BaseRenderer; Render3D *newRenderer = newRenderInterface->NDS_3D_Init(); @@ -103,6 +105,7 @@ bool NDS_3D_ChangeCore(int newCore) gpu3D = newRenderInterface; cur3DCore = newCore; + newRenderer->SetRenderNeedsFinish( BaseRenderer->GetRenderNeedsFinish() ); CurrentRenderer = newRenderer; result = true; @@ -229,6 +232,7 @@ Render3D::Render3D() _framebufferColorSizeBytes = 0; _framebufferColor = NULL; + _renderNeedsFinish = false; _willFlushFramebufferRGBA6665 = true; _willFlushFramebufferRGBA5551 = true; @@ -297,6 +301,16 @@ void Render3D::SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushR this->_willFlushFramebufferRGBA5551 = willFlushRGBA5551; } +bool Render3D::GetRenderNeedsFinish() const +{ + return this->_renderNeedsFinish; +} + +void Render3D::SetRenderNeedsFinish(const bool renderNeedsFinish) +{ + this->_renderNeedsFinish = renderNeedsFinish; +} + Render3DError Render3D::BeginRender(const GFX3D &engine) { return RENDER3DERROR_NOERR; @@ -484,7 +498,6 @@ Render3DError Render3D::Render(const GFX3D &engine) { Render3DError error = RENDER3DERROR_NOERR; - GPU->GetEventHandler()->DidRender3DBegin(); error = this->BeginRender(engine); if (error != RENDER3DERROR_NOERR) { @@ -513,7 +526,6 @@ Render3DError Render3D::Render(const GFX3D &engine) Render3DError Render3D::RenderFinish() { - GPU->GetEventHandler()->DidRender3DEnd(); return RENDER3DERROR_NOERR; } diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index eab322cef..dc63c279b 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -109,6 +109,7 @@ protected: size_t _framebufferColorSizeBytes; FragmentColor *_framebufferColor; + bool _renderNeedsFinish; bool _willFlushFramebufferRGBA6665; bool _willFlushFramebufferRGBA5551; @@ -162,6 +163,9 @@ public: virtual FragmentColor* GetFramebuffer(); virtual void GetFramebufferFlushStates(bool &willFlushRGBA6665, bool &willFlushRGBA5551); virtual void SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushRGBA5551); + + bool GetRenderNeedsFinish() const; + void SetRenderNeedsFinish(const bool renderNeedsFinish); }; #ifdef ENABLE_SSE2