- Only flush the 3D rendering buffers and update the rendering properties if the frame is not skipped.
- Be more accurate when using callbacks for DidRender3DBegin and DidRender3DEnd.
- Make the 3D rendering stage more multithreading friendly.
This commit is contained in:
rogerman 2016-03-08 01:57:08 +00:00
parent 7b84225fa4
commit e0a139aeda
8 changed files with 61 additions and 47 deletions

View File

@ -6187,16 +6187,22 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested)
if (l == 0) if (l == 0)
{ {
CurrentRenderer->SetFramebufferFlushStates(this->_engineMain->WillRender3DLayer(), this->_engineMain->WillCapture3DLayerDirect());
CurrentRenderer->RenderFinish();
CurrentRenderer->SetFramebufferFlushStates(true, true);
this->_event->DidFrameBegin(); this->_event->DidFrameBegin();
this->UpdateRenderProperties();
// Clear displays to black if they are turned off by the user. // Clear displays to black if they are turned off by the user.
if (!isFrameSkipRequested) 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) if (!CommonSettings.showGpu.main)
{ {
memset(this->_engineMain->renderedBuffer, 0, this->_engineMain->renderedWidth * this->_engineMain->renderedHeight * sizeof(u16)); memset(this->_engineMain->renderedBuffer, 0, this->_engineMain->renderedWidth * this->_engineMain->renderedHeight * sizeof(u16));

View File

@ -2996,9 +2996,8 @@ Render3DError OpenGLRenderer_1_2::Reset()
Render3DError OpenGLRenderer_1_2::RenderFinish() Render3DError OpenGLRenderer_1_2::RenderFinish()
{ {
if (!this->_pixelReadNeedsFinish) if (!this->_renderNeedsFinish || !this->_pixelReadNeedsFinish)
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -3009,7 +3008,6 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
{ {
if(!BEGINGL()) if(!BEGINGL())
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_BEGINGL_FAILED; return OGLERROR_BEGINGL_FAILED;
} }
@ -3029,7 +3027,6 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
this->_pixelReadNeedsFinish = false; this->_pixelReadNeedsFinish = false;
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -4495,9 +4492,8 @@ Render3DError OpenGLRenderer_2_1::ReadBackPixels()
Render3DError OpenGLRenderer_2_1::RenderFinish() Render3DError OpenGLRenderer_2_1::RenderFinish()
{ {
if (!this->_pixelReadNeedsFinish) if (!this->_renderNeedsFinish || !this->_pixelReadNeedsFinish)
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -4508,7 +4504,6 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
{ {
if(!BEGINGL()) if(!BEGINGL())
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_BEGINGL_FAILED; return OGLERROR_BEGINGL_FAILED;
} }
@ -4520,6 +4515,5 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
this->_pixelReadNeedsFinish = false; this->_pixelReadNeedsFinish = false;
GPU->GetEventHandler()->DidRender3DEnd();
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }

View File

@ -27,6 +27,7 @@ class GPUEventHandlerOSX;
UInt32 gpuStateFlags; UInt32 gpuStateFlags;
uint8_t _gpuScale; uint8_t _gpuScale;
BOOL isCPUCoreCountAuto; BOOL isCPUCoreCountAuto;
BOOL _needRestoreFrameLock;
BOOL _needRestoreRender3DLock; BOOL _needRestoreRender3DLock;
OSSpinLock spinlockGpuState; OSSpinLock spinlockGpuState;

View File

@ -48,8 +48,7 @@ private:
pthread_mutex_t _mutex3DRender; pthread_mutex_t _mutex3DRender;
pthread_mutex_t *_mutexOutputList; pthread_mutex_t *_mutexOutputList;
NSMutableArray *_cdsOutputList; NSMutableArray *_cdsOutputList;
bool _isRender3DLockHeld; bool _render3DNeedsFinish;
bool _isIn3DRender;
public: public:
GPUEventHandlerOSX(); GPUEventHandlerOSX();
@ -67,7 +66,7 @@ public:
pthread_rwlock_t* GetFrameRWLock(); pthread_rwlock_t* GetFrameRWLock();
NSMutableArray* GetOutputList(); NSMutableArray* GetOutputList();
void SetOutputList(NSMutableArray *outputList, pthread_mutex_t *theMutex); void SetOutputList(NSMutableArray *outputList, pthread_mutex_t *theMutex);
bool IsRender3DLockHeld(); bool GetRender3DNeedsFinish();
virtual void DidFrameBegin(); virtual void DidFrameBegin();
virtual void DidFrameEnd(bool isFrameSkipped); virtual void DidFrameEnd(bool isFrameSkipped);
@ -132,6 +131,7 @@ public:
GPUSTATE_SUB_OBJ_MASK; GPUSTATE_SUB_OBJ_MASK;
isCPUCoreCountAuto = NO; isCPUCoreCountAuto = NO;
_needRestoreFrameLock = NO;
_needRestoreRender3DLock = NO; _needRestoreRender3DLock = NO;
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
@ -188,23 +188,23 @@ public:
- (void) setGpuDimensions:(NSSize)theDimensions - (void) setGpuDimensions:(NSSize)theDimensions
{ {
gpuEvent->FrameFinish(); gpuEvent->FrameFinish();
gpuEvent->FramebufferLockWrite();
gpuEvent->Render3DLock(); gpuEvent->Render3DLock();
gpuEvent->FramebufferLockWrite();
GPU->SetCustomFramebufferSize(theDimensions.width, theDimensions.height); GPU->SetCustomFramebufferSize(theDimensions.width, theDimensions.height);
gpuEvent->SetVideoBuffers(); gpuEvent->SetVideoBuffers();
gpuEvent->Render3DUnlock();
gpuEvent->FramebufferUnlock(); gpuEvent->FramebufferUnlock();
gpuEvent->Render3DUnlock();
} }
- (NSSize) gpuDimensions - (NSSize) gpuDimensions
{ {
gpuEvent->FramebufferLockRead();
gpuEvent->Render3DLock(); gpuEvent->Render3DLock();
gpuEvent->FramebufferLockRead();
const NSSize dimensions = NSMakeSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight()); const NSSize dimensions = NSMakeSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight());
gpuEvent->Render3DUnlock();
gpuEvent->FramebufferUnlock(); gpuEvent->FramebufferUnlock();
gpuEvent->Render3DUnlock();
return dimensions; return dimensions;
} }
@ -362,7 +362,7 @@ public:
CommonSettings.num_cores = numberCores; CommonSettings.num_cores = numberCores;
if (renderingEngineID == CORE3DLIST_SWRASTERIZE || renderingEngineID == CORE3DLIST_OPENGL) if (renderingEngineID == CORE3DLIST_SWRASTERIZE)
{ {
NDS_3D_ChangeCore(renderingEngineID); NDS_3D_ChangeCore(renderingEngineID);
} }
@ -703,7 +703,7 @@ public:
{ {
if (isPaused) if (isPaused)
{ {
if (gpuEvent->IsRender3DLockHeld()) if (!_needRestoreRender3DLock && gpuEvent->GetRender3DNeedsFinish())
{ {
gpuEvent->Render3DUnlock(); gpuEvent->Render3DUnlock();
_needRestoreRender3DLock = YES; _needRestoreRender3DLock = YES;
@ -723,8 +723,7 @@ public:
GPUEventHandlerOSX::GPUEventHandlerOSX() GPUEventHandlerOSX::GPUEventHandlerOSX()
{ {
_isRender3DLockHeld = false; _render3DNeedsFinish = false;
_isIn3DRender = false;
_mutexOutputList = NULL; _mutexOutputList = NULL;
pthread_rwlock_init(&_rwlockFrame, NULL); pthread_rwlock_init(&_rwlockFrame, NULL);
pthread_mutex_init(&_mutex3DRender, NULL); pthread_mutex_init(&_mutex3DRender, NULL);
@ -732,13 +731,11 @@ GPUEventHandlerOSX::GPUEventHandlerOSX()
GPUEventHandlerOSX::~GPUEventHandlerOSX() GPUEventHandlerOSX::~GPUEventHandlerOSX()
{ {
if (this->_isRender3DLockHeld) if (this->_render3DNeedsFinish)
{ {
pthread_mutex_unlock(&this->_mutex3DRender); pthread_mutex_unlock(&this->_mutex3DRender);
} }
this->Render3DUnlock();
pthread_rwlock_destroy(&this->_rwlockFrame); pthread_rwlock_destroy(&this->_rwlockFrame);
pthread_mutex_destroy(&this->_mutex3DRender); pthread_mutex_destroy(&this->_mutex3DRender);
} }
@ -780,17 +777,14 @@ void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped)
void GPUEventHandlerOSX::DidRender3DBegin() void GPUEventHandlerOSX::DidRender3DBegin()
{ {
this->_isIn3DRender = true;
this->Render3DLock(); this->Render3DLock();
this->_render3DNeedsFinish = true;
} }
void GPUEventHandlerOSX::DidRender3DEnd() void GPUEventHandlerOSX::DidRender3DEnd()
{ {
if (this->_isIn3DRender) this->_render3DNeedsFinish = false;
{ this->Render3DUnlock();
this->Render3DUnlock();
this->_isIn3DRender = false;
}
} }
void GPUEventHandlerOSX::FramebufferLockWrite() void GPUEventHandlerOSX::FramebufferLockWrite()
@ -811,16 +805,11 @@ void GPUEventHandlerOSX::FramebufferUnlock()
void GPUEventHandlerOSX::Render3DLock() void GPUEventHandlerOSX::Render3DLock()
{ {
pthread_mutex_lock(&this->_mutex3DRender); pthread_mutex_lock(&this->_mutex3DRender);
this->_isRender3DLockHeld = true;
} }
void GPUEventHandlerOSX::Render3DUnlock() void GPUEventHandlerOSX::Render3DUnlock()
{ {
if (this->_isRender3DLockHeld) pthread_mutex_unlock(&this->_mutex3DRender);
{
this->_isRender3DLockHeld = false;
pthread_mutex_unlock(&this->_mutex3DRender);
}
} }
void GPUEventHandlerOSX::FrameFinish() void GPUEventHandlerOSX::FrameFinish()
@ -873,9 +862,9 @@ void GPUEventHandlerOSX::SetVideoBuffers()
#endif #endif
} }
bool GPUEventHandlerOSX::IsRender3DLockHeld() bool GPUEventHandlerOSX::GetRender3DNeedsFinish()
{ {
return this->_isRender3DLockHeld; return this->_render3DNeedsFinish;
} }
pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock() pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock()

View File

@ -2318,6 +2318,17 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
return; 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); CurrentRenderer->Render(gfx3d);
} }

View File

@ -1929,7 +1929,6 @@ Render3DError SoftRasterizerRenderer::Render(const GFX3D &engine)
{ {
Render3DError error = RENDER3DERROR_NOERR; Render3DError error = RENDER3DERROR_NOERR;
GPU->GetEventHandler()->DidRender3DBegin();
error = this->BeginRender(engine); error = this->BeginRender(engine);
if (error != RENDER3DERROR_NOERR) if (error != RENDER3DERROR_NOERR)
{ {
@ -1966,9 +1965,8 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount)
Render3DError SoftRasterizerRenderer::RenderFinish() Render3DError SoftRasterizerRenderer::RenderFinish()
{ {
if (!this->_renderGeometryNeedsFinish) if (!this->_renderNeedsFinish || !this->_renderGeometryNeedsFinish)
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return RENDER3DERROR_NOERR; return RENDER3DERROR_NOERR;
} }
@ -2005,7 +2003,6 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL; u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL;
this->FlushFramebuffer(this->_framebufferColor, NULL, framebufferRGBA5551); this->FlushFramebuffer(this->_framebufferColor, NULL, framebufferRGBA5551);
GPU->GetEventHandler()->DidRender3DEnd();
return RENDER3DERROR_NOERR; return RENDER3DERROR_NOERR;
} }

View File

@ -83,10 +83,12 @@ bool NDS_3D_ChangeCore(int newCore)
// Some resources are shared between renderers, such as the texture cache, // 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 // so we need to shut down the current renderer now to ensure that any
// shared resources aren't in use. // shared resources aren't in use.
const bool didRenderBegin = CurrentRenderer->GetRenderNeedsFinish();
CurrentRenderer->RenderFinish(); CurrentRenderer->RenderFinish();
gpu3D->NDS_3D_Close(); gpu3D->NDS_3D_Close();
gpu3D = &gpu3DNull; gpu3D = &gpu3DNull;
cur3DCore = GPU3D_NULL; cur3DCore = GPU3D_NULL;
BaseRenderer->SetRenderNeedsFinish(didRenderBegin);
CurrentRenderer = BaseRenderer; CurrentRenderer = BaseRenderer;
Render3D *newRenderer = newRenderInterface->NDS_3D_Init(); Render3D *newRenderer = newRenderInterface->NDS_3D_Init();
@ -103,6 +105,7 @@ bool NDS_3D_ChangeCore(int newCore)
gpu3D = newRenderInterface; gpu3D = newRenderInterface;
cur3DCore = newCore; cur3DCore = newCore;
newRenderer->SetRenderNeedsFinish( BaseRenderer->GetRenderNeedsFinish() );
CurrentRenderer = newRenderer; CurrentRenderer = newRenderer;
result = true; result = true;
@ -229,6 +232,7 @@ Render3D::Render3D()
_framebufferColorSizeBytes = 0; _framebufferColorSizeBytes = 0;
_framebufferColor = NULL; _framebufferColor = NULL;
_renderNeedsFinish = false;
_willFlushFramebufferRGBA6665 = true; _willFlushFramebufferRGBA6665 = true;
_willFlushFramebufferRGBA5551 = true; _willFlushFramebufferRGBA5551 = true;
@ -297,6 +301,16 @@ void Render3D::SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushR
this->_willFlushFramebufferRGBA5551 = willFlushRGBA5551; 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) Render3DError Render3D::BeginRender(const GFX3D &engine)
{ {
return RENDER3DERROR_NOERR; return RENDER3DERROR_NOERR;
@ -484,7 +498,6 @@ Render3DError Render3D::Render(const GFX3D &engine)
{ {
Render3DError error = RENDER3DERROR_NOERR; Render3DError error = RENDER3DERROR_NOERR;
GPU->GetEventHandler()->DidRender3DBegin();
error = this->BeginRender(engine); error = this->BeginRender(engine);
if (error != RENDER3DERROR_NOERR) if (error != RENDER3DERROR_NOERR)
{ {
@ -513,7 +526,6 @@ Render3DError Render3D::Render(const GFX3D &engine)
Render3DError Render3D::RenderFinish() Render3DError Render3D::RenderFinish()
{ {
GPU->GetEventHandler()->DidRender3DEnd();
return RENDER3DERROR_NOERR; return RENDER3DERROR_NOERR;
} }

View File

@ -109,6 +109,7 @@ protected:
size_t _framebufferColorSizeBytes; size_t _framebufferColorSizeBytes;
FragmentColor *_framebufferColor; FragmentColor *_framebufferColor;
bool _renderNeedsFinish;
bool _willFlushFramebufferRGBA6665; bool _willFlushFramebufferRGBA6665;
bool _willFlushFramebufferRGBA5551; bool _willFlushFramebufferRGBA5551;
@ -162,6 +163,9 @@ public:
virtual FragmentColor* GetFramebuffer(); virtual FragmentColor* GetFramebuffer();
virtual void GetFramebufferFlushStates(bool &willFlushRGBA6665, bool &willFlushRGBA5551); virtual void GetFramebufferFlushStates(bool &willFlushRGBA6665, bool &willFlushRGBA5551);
virtual void SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushRGBA5551); virtual void SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushRGBA5551);
bool GetRenderNeedsFinish() const;
void SetRenderNeedsFinish(const bool renderNeedsFinish);
}; };
#ifdef ENABLE_SSE2 #ifdef ENABLE_SSE2