- 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)
{
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));

View File

@ -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;
}

View File

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

View File

@ -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()

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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