Cocoa Port:

- Fix freezing bug that can occur when switching the 3D rendering engine while the emulation is paused. (Regression from r5288.)
This commit is contained in:
rogerman 2016-03-05 03:33:16 +00:00
parent 4f8a16d980
commit 4c9a50ae91
3 changed files with 44 additions and 7 deletions

View File

@ -27,6 +27,7 @@ class GPUEventHandlerOSX;
UInt32 gpuStateFlags; UInt32 gpuStateFlags;
uint8_t _gpuScale; uint8_t _gpuScale;
BOOL isCPUCoreCountAuto; BOOL isCPUCoreCountAuto;
BOOL _needRestoreRender3DLock;
OSSpinLock spinlockGpuState; OSSpinLock spinlockGpuState;
GPUEventHandlerOSX *gpuEvent; GPUEventHandlerOSX *gpuEvent;
@ -65,6 +66,7 @@ class GPUEventHandlerOSX;
- (BOOL) gpuStateByBit:(const UInt32)stateBit; - (BOOL) gpuStateByBit:(const UInt32)stateBit;
- (NSString *) render3DRenderingEngineString; - (NSString *) render3DRenderingEngineString;
- (void) clearWithColor:(const uint16_t)colorBGRA5551; - (void) clearWithColor:(const uint16_t)colorBGRA5551;
- (void) respondToPauseState:(BOOL)isPaused;
@end @end

View File

@ -66,6 +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();
virtual void DidFrameBegin(); virtual void DidFrameBegin();
virtual void DidFrameEnd(bool isFrameSkipped); virtual void DidFrameEnd(bool isFrameSkipped);
@ -130,6 +131,7 @@ public:
GPUSTATE_SUB_OBJ_MASK; GPUSTATE_SUB_OBJ_MASK;
isCPUCoreCountAuto = NO; isCPUCoreCountAuto = NO;
_needRestoreRender3DLock = NO;
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
&OSXOpenGLRendererBegin, &OSXOpenGLRendererBegin,
@ -696,6 +698,26 @@ public:
gpuEvent->FramebufferUnlock(); gpuEvent->FramebufferUnlock();
} }
- (void) respondToPauseState:(BOOL)isPaused
{
if (isPaused)
{
if (gpuEvent->IsRender3DLockHeld())
{
gpuEvent->Render3DUnlock();
_needRestoreRender3DLock = YES;
}
}
else
{
if (_needRestoreRender3DLock)
{
gpuEvent->Render3DLock();
_needRestoreRender3DLock = NO;
}
}
}
@end @end
GPUEventHandlerOSX::GPUEventHandlerOSX() GPUEventHandlerOSX::GPUEventHandlerOSX()
@ -708,6 +730,13 @@ GPUEventHandlerOSX::GPUEventHandlerOSX()
GPUEventHandlerOSX::~GPUEventHandlerOSX() GPUEventHandlerOSX::~GPUEventHandlerOSX()
{ {
if (this->_isRender3DLockHeld)
{
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);
} }
@ -749,17 +778,12 @@ void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped)
void GPUEventHandlerOSX::DidRender3DBegin() void GPUEventHandlerOSX::DidRender3DBegin()
{ {
this->_isRender3DLockHeld = true;
this->Render3DLock(); this->Render3DLock();
} }
void GPUEventHandlerOSX::DidRender3DEnd() void GPUEventHandlerOSX::DidRender3DEnd()
{ {
if (this->_isRender3DLockHeld) this->Render3DUnlock();
{
this->Render3DUnlock();
this->_isRender3DLockHeld = false;
}
} }
void GPUEventHandlerOSX::FramebufferLockWrite() void GPUEventHandlerOSX::FramebufferLockWrite()
@ -780,11 +804,16 @@ 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()
{ {
pthread_mutex_unlock(&this->_mutex3DRender); if (this->_isRender3DLockHeld)
{
pthread_mutex_unlock(&this->_mutex3DRender);
this->_isRender3DLockHeld = false;
}
} }
void GPUEventHandlerOSX::FrameFinish() void GPUEventHandlerOSX::FrameFinish()
@ -837,6 +866,11 @@ void GPUEventHandlerOSX::SetVideoBuffers()
#endif #endif
} }
bool GPUEventHandlerOSX::IsRender3DLockHeld()
{
return this->_isRender3DLockHeld;
}
pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock() pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock()
{ {
return &this->_rwlockFrame; return &this->_rwlockFrame;

View File

@ -719,6 +719,7 @@ volatile bool execute = true;
pthread_cond_signal(&threadParam.condThreadExecute); pthread_cond_signal(&threadParam.condThreadExecute);
pthread_mutex_unlock(&threadParam.mutexThreadExecute); pthread_mutex_unlock(&threadParam.mutexThreadExecute);
[[self cdsGPU] respondToPauseState:(coreState == CORESTATE_PAUSE)];
[[self cdsController] setHardwareMicPause:!(coreState == CORESTATE_EXECUTE)]; [[self cdsController] setHardwareMicPause:!(coreState == CORESTATE_EXECUTE)];
} }