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:
parent
241f50ee7a
commit
ff2e6cb220
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -199,7 +199,7 @@ void MacOGLClientFetchObject::SetFetchBuffers(const NDSDisplayInfo ¤tDispl
|
|||
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]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue