Cocoa Port: Increment/decrement the number of display views in need of CPU filtering, instead of looping through all outputs to determine it. Prevents a possible deadlock when changing CPU-based pixel scalers.

- Also do some additional code cleanup.
This commit is contained in:
rogerman 2017-02-10 11:28:35 -08:00
parent 241f50ee7a
commit ff2e6cb220
7 changed files with 74 additions and 35 deletions

View File

@ -354,17 +354,20 @@ void ClientDisplayView::SetPixelScaler(const VideoFilterTypeID filterID)
const size_t newDstBufferWidth = (this->_vf[NDSDisplayID_Main]->GetSrcWidth() + this->_vf[NDSDisplayID_Touch]->GetSrcWidth()) * newFilterAttr.scaleMultiply / newFilterAttr.scaleDivide;
const size_t newDstBufferHeight = (this->_vf[NDSDisplayID_Main]->GetSrcHeight() + this->_vf[NDSDisplayID_Touch]->GetSrcHeight()) * newFilterAttr.scaleMultiply / newFilterAttr.scaleDivide;
uint32_t *oldMasterBuffer = NULL;
if ( (oldDstBufferWidth != newDstBufferWidth) || (oldDstBufferHeight != newDstBufferHeight) )
{
uint32_t *oldMasterBuffer = this->_vfMasterDstBuffer;
oldMasterBuffer = this->_vfMasterDstBuffer;
this->_ResizeCPUPixelScaler(newFilterID);
free_aligned(oldMasterBuffer);
}
this->_vf[NDSDisplayID_Main]->ChangeFilterByID(newFilterID);
this->_vf[NDSDisplayID_Touch]->ChangeFilterByID(newFilterID);
this->_pixelScaler = newFilterID;
free_aligned(oldMasterBuffer);
}
VideoFilter* ClientDisplayView::GetPixelScalerObject(const NDSDisplayID displayID)

View File

@ -38,14 +38,17 @@ class GPUEventHandlerOSX;
pthread_rwlock_t *_rwlockFramebuffer[2];
pthread_mutex_t *_mutexOutputList;
NSMutableArray *_cdsOutputList;
volatile int32_t numberViewsUsingCPUFiltering;
}
@property (assign, nonatomic) GPUClientFetchObject *GPUFetchObject;
@property (readonly, nonatomic) int32_t numberViewsUsingCPUFiltering;
- (const NDSDisplayInfo &) fetchDisplayInfoForIndex:(const u8)bufferIndex;
- (pthread_rwlock_t *) rwlockFramebufferAtIndex:(const u8)bufferIndex;
- (void) setOutputList:(NSMutableArray *)theOutputList mutex:(pthread_mutex_t *)theMutex;
- (BOOL) isCPUFilteringNeeded;
- (void) incrementViewsUsingCPUFiltering;
- (void) decrementViewsUsingCPUFiltering;
- (void) handleFetchFromBufferIndexAndPushVideo:(NSData *)indexData;
- (void) pushVideoDataToAllDisplayViews;
- (void) finishAllDisplayViewsAtIndex:(const u8)bufferIndex;

View File

@ -153,13 +153,21 @@ public:
GPU->SetEventHandler(gpuEvent);
GPU->SetWillAutoResolveToCustomBuffer(false);
fetchObject = NULL;
#ifdef ENABLE_APPLE_METAL
if (IsOSXVersionSupported(10, 11, 0))
{
fetchObject = new MacMetalFetchObject;
if (fetchObject->GetClientData() == nil)
{
delete fetchObject;
fetchObject = NULL;
}
}
else
#endif
if (fetchObject == NULL)
{
fetchObject = new MacOGLClientFetchObject;
}
@ -852,6 +860,7 @@ public:
@implementation MacClientSharedObject
@synthesize GPUFetchObject;
@synthesize numberViewsUsingCPUFiltering;
- (id)init
{
@ -870,6 +879,7 @@ public:
GPUFetchObject = nil;
_mutexOutputList = NULL;
_cdsOutputList = nil;
numberViewsUsingCPUFiltering = 0;
return self;
}
@ -952,36 +962,14 @@ public:
_mutexOutputList = theMutex;
}
- (BOOL) isCPUFilteringNeeded
- (void) incrementViewsUsingCPUFiltering
{
bool useCPUFilterPipeline = NO;
pthread_mutex_t *currentMutex = _mutexOutputList;
OSAtomicIncrement32(&numberViewsUsingCPUFiltering);
}
if (currentMutex != NULL)
{
pthread_mutex_lock(currentMutex);
}
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
{
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
{
ClientDisplay3DView *cdv = [(CocoaDSDisplay *)cdsOutput clientDisplayView];
if (!cdv->WillFilterOnGPU() && (cdv->GetPixelScaler() != VideoFilterTypeID_None))
{
useCPUFilterPipeline = YES;
break;
}
}
}
if (currentMutex != NULL)
{
pthread_mutex_unlock(currentMutex);
}
return useCPUFilterPipeline;
- (void) decrementViewsUsingCPUFiltering
{
OSAtomicDecrement32(&numberViewsUsingCPUFiltering);
}
- (void) pushVideoDataToAllDisplayViews

View File

@ -140,7 +140,8 @@ struct NDSFrameInfo;
OSSpinLock spinlockPixelScaler;
}
@property (readonly) BOOL canFilterOnGPU;
@property (readonly, nonatomic) BOOL canFilterOnGPU;
@property (readonly, nonatomic) BOOL willFilterOnGPU;
@property (assign) BOOL isHUDVisible;
@property (assign) BOOL isHUDVideoFPSVisible;
@property (assign) BOOL isHUDRender3DFPSVisible;

View File

@ -733,6 +733,7 @@
@implementation CocoaDSDisplayVideo
@dynamic canFilterOnGPU;
@dynamic willFilterOnGPU;
@dynamic isHUDVisible;
@dynamic isHUDVideoFPSVisible;
@dynamic isHUDRender3DFPSVisible;
@ -774,6 +775,11 @@
return (_cdv->CanFilterOnGPU()) ? YES : NO;
}
- (BOOL) willFilterOnGPU
{
return (_cdv->WillFilterOnGPU()) ? YES : NO;
}
- (void) setIsHUDVisible:(BOOL)theState
{
OSSpinLockLock(&spinlockIsHUDVisible);

View File

@ -1751,7 +1751,26 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void) setVideoFiltersPreferGPU:(BOOL)theState
{
const BOOL oldState = (![[self cdsVideoOutput] willFilterOnGPU] && ([[self cdsVideoOutput] pixelScaler] != VideoFilterTypeID_None));
[[self cdsVideoOutput] setVideoFiltersPreferGPU:theState];
const BOOL newState = (![[self cdsVideoOutput] willFilterOnGPU] && ([[self cdsVideoOutput] pixelScaler] != VideoFilterTypeID_None));
if (oldState != newState)
{
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
CocoaDSCore *cdsCore = (CocoaDSCore *)[[[windowController emuControl] cdsCoreController] content];
CocoaDSGPU *cdsGPU = [cdsCore cdsGPU];
MacClientSharedObject *macSharedData = [cdsGPU sharedData];
if (newState)
{
[macSharedData incrementViewsUsingCPUFiltering];
}
else
{
[macSharedData decrementViewsUsingCPUFiltering];
}
}
}
- (BOOL) videoFiltersPreferGPU
@ -1781,7 +1800,26 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
- (void) setPixelScaler:(NSInteger)filterID
{
const BOOL oldState = (![[self cdsVideoOutput] willFilterOnGPU] && ([[self cdsVideoOutput] pixelScaler] != VideoFilterTypeID_None));
[[self cdsVideoOutput] setPixelScaler:filterID];
const BOOL newState = (![[self cdsVideoOutput] willFilterOnGPU] && ([[self cdsVideoOutput] pixelScaler] != VideoFilterTypeID_None));
if (oldState != newState)
{
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
CocoaDSCore *cdsCore = (CocoaDSCore *)[[[windowController emuControl] cdsCoreController] content];
CocoaDSGPU *cdsGPU = [cdsCore cdsGPU];
MacClientSharedObject *macSharedData = [cdsGPU sharedData];
if (newState)
{
[macSharedData incrementViewsUsingCPUFiltering];
}
else
{
[macSharedData decrementViewsUsingCPUFiltering];
}
}
}
- (NSInteger) pixelScaler

View File

@ -199,7 +199,7 @@ void MacOGLClientFetchObject::SetFetchBuffers(const NDSDisplayInfo &currentDispl
void MacOGLClientFetchObject::FetchFromBufferIndex(const u8 index)
{
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)this->_clientData;
this->_useCPUFilterPipeline = ([sharedViewObject isCPUFilteringNeeded]) ? true : false;
this->_useCPUFilterPipeline = ([sharedViewObject numberViewsUsingCPUFiltering] > 0);
pthread_rwlock_rdlock([sharedViewObject rwlockFramebufferAtIndex:index]);