Permalink
Browse files

Cocoa Port: Stability improvements for Metal display views.

  • Loading branch information...
rogerman committed Nov 30, 2017
1 parent 02a3b58 commit 66e8a95657f92c7e28dd68f66fcb0cd47d171fc0
Showing with 169 additions and 51 deletions.
  1. +22 −9 desmume/src/GPU.cpp
  2. +147 −42 desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm
View
@@ -7404,38 +7404,51 @@ GPUSubsystem::GPUSubsystem()
//osd = new OSDCLASS(-1);
//delete previousOSD;
_customVRAM = NULL;
_customVRAMBlank = NULL;
_displayInfo.colorFormat = NDSColorFormat_BGR555_Rev;
_displayInfo.pixelBytes = sizeof(u16);
_displayInfo.isCustomSizeRequested = false;
_displayInfo.customWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.customHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_customVRAM = NULL;
_customVRAMBlank = NULL;
_displayInfo.framebufferSize = ((GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT) + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT)) * 2 * _displayInfo.pixelBytes;
_masterFramebuffer = malloc_alignedPage(_displayInfo.framebufferSize * 2);
_displayInfo.masterFramebufferHead = _masterFramebuffer;
_displayInfo.isDisplayEnabled[NDSDisplayID_Main] = true;
_displayInfo.isDisplayEnabled[NDSDisplayID_Touch] = true;
_displayInfo.bufferIndex = 0;
_displayInfo.masterFramebufferHead = _masterFramebuffer;
_displayInfo.masterNativeBuffer = _masterFramebuffer;
_displayInfo.masterCustomBuffer = (u8 *)_masterFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * _displayInfo.pixelBytes);
_displayInfo.nativeBuffer[NDSDisplayID_Main] = _displayInfo.masterNativeBuffer;
_displayInfo.nativeBuffer[NDSDisplayID_Touch] = (u8 *)_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * _displayInfo.pixelBytes);
_displayInfo.masterCustomBuffer = (u8 *)_masterFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * _displayInfo.pixelBytes);
_displayInfo.customBuffer[NDSDisplayID_Main] = _displayInfo.masterCustomBuffer;
_displayInfo.customBuffer[NDSDisplayID_Touch] = (u8 *)_displayInfo.masterCustomBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * _displayInfo.pixelBytes);
_displayInfo.didPerformCustomRender[NDSDisplayID_Main] = false;
_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false;
_displayInfo.renderedWidth[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.renderedWidth[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.renderedWidth[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.renderedWidth[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.renderedHeight[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_displayInfo.renderedHeight[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_displayInfo.renderedBuffer[NDSDisplayID_Main] = _displayInfo.nativeBuffer[NDSDisplayID_Main];
_displayInfo.renderedBuffer[NDSDisplayID_Touch] = _displayInfo.nativeBuffer[NDSDisplayID_Touch];
_displayInfo.engineID[NDSDisplayID_Main] = GPUEngineID_Main;
_displayInfo.engineID[NDSDisplayID_Touch] = GPUEngineID_Sub;
_displayInfo.didPerformCustomRender[NDSDisplayID_Main] = false;
_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false;
_displayInfo.masterBrightnessDiffersPerLine[NDSDisplayID_Main] = false;
_displayInfo.masterBrightnessDiffersPerLine[NDSDisplayID_Touch] = false;
memset(_displayInfo.masterBrightnessMode[NDSDisplayID_Main], GPUMasterBrightMode_Disable, sizeof(_displayInfo.masterBrightnessMode[NDSDisplayID_Main]));
memset(_displayInfo.masterBrightnessMode[NDSDisplayID_Touch], GPUMasterBrightMode_Disable, sizeof(_displayInfo.masterBrightnessMode[NDSDisplayID_Touch]));
memset(_displayInfo.masterBrightnessIntensity[NDSDisplayID_Main], 0, sizeof(_displayInfo.masterBrightnessIntensity[NDSDisplayID_Main]));
memset(_displayInfo.masterBrightnessIntensity[NDSDisplayID_Touch], 0, sizeof(_displayInfo.masterBrightnessIntensity[NDSDisplayID_Touch]));
_displayInfo.backlightIntensity[NDSDisplayID_Main] = 1.0f;
_displayInfo.backlightIntensity[NDSDisplayID_Touch] = 1.0f;
_displayInfo.needConvertColorFormat[NDSDisplayID_Main] = false;
@@ -677,9 +677,19 @@ - (void) fetchFromBufferIndex:(const u8)index
[self setFetchTextureBindingsAtIndex:index commandBuffer:cb];
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([self rwlockFramebufferAtIndex:index]);
}];
if (index == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([self rwlockFramebufferAtIndex:0]);
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([self rwlockFramebufferAtIndex:1]);
}];
}
[cb commit];
[cb waitUntilScheduled];
}
@@ -1338,7 +1348,7 @@ - (void) processDisplays
{
[cce setComputePipelineState:[sharedData deposterizePipeline]];
if (shouldProcessDisplay[NDSDisplayID_Main])
if ((texMain != nil) && shouldProcessDisplay[NDSDisplayID_Main])
{
[cce setTexture:texMain atIndex:0];
[cce setTexture:_texDisplaySrcDeposterize[NDSDisplayID_Main][0] atIndex:1];
@@ -1360,7 +1370,7 @@ - (void) processDisplays
}
}
if (shouldProcessDisplay[NDSDisplayID_Touch])
if ((texTouch != nil) && shouldProcessDisplay[NDSDisplayID_Touch])
{
[cce setTexture:texTouch atIndex:0];
[cce setTexture:_texDisplaySrcDeposterize[NDSDisplayID_Touch][0] atIndex:1];
@@ -1381,12 +1391,23 @@ - (void) processDisplays
needsFetchBuffersLock = !isDisplayProcessedMain || !isDisplayProcessedTouch;
[cce endEncoding];
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
if (!needsFetchBuffersLock)
if (!needsFetchBuffersLock)
{
if (bufferIndex == 0)
{
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:bufferIndex]);
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:0]);
}];
}
}];
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:1]);
}];
}
}
[cb commit];
cb = [self newCommandBuffer];
@@ -1399,7 +1420,7 @@ - (void) processDisplays
{
[cce setComputePipelineState:[self pixelScalePipeline]];
if (shouldProcessDisplay[NDSDisplayID_Main])
if ((texMain != nil) && shouldProcessDisplay[NDSDisplayID_Main])
{
[cce setTexture:texMain atIndex:0];
[cce setTexture:[self texDisplayPixelScaleMain] atIndex:1];
@@ -1420,7 +1441,7 @@ - (void) processDisplays
}
}
if (shouldProcessDisplay[NDSDisplayID_Touch])
if ((texTouch != nil) && shouldProcessDisplay[NDSDisplayID_Touch])
{
[cce setTexture:texTouch atIndex:0];
[cce setTexture:[self texDisplayPixelScaleTouch] atIndex:1];
@@ -1438,9 +1459,20 @@ - (void) processDisplays
needsFetchBuffersLock = false;
[cce endEncoding];
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:bufferIndex]);
}];
if (bufferIndex == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:0]);
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:1]);
}];
}
[cb commit];
cb = [self newCommandBuffer];
@@ -1574,17 +1606,57 @@ - (void) processDisplays
[bce endEncoding];
}
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
if (needsCPUFilterUnlockMain)
if (needsCPUFilterUnlockMain)
{
if (needsCPUFilterUnlockTouch)
{
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Main, bufferIndex));
if (bufferIndex == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Main, 0));
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Touch, 0));
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Main, 1));
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Touch, 1));
}];
}
}
if (needsCPUFilterUnlockTouch)
else
{
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Touch, bufferIndex));
if (bufferIndex == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Main, 0));
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Main, 1));
}];
}
}
}];
}
else if (needsCPUFilterUnlockTouch)
{
if (bufferIndex == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Touch, 0));
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_rwlock_unlock(((MacMetalDisplayPresenter *)cdp)->GetCPUFilterRWLock(NDSDisplayID_Touch, 1));
}];
}
}
[cb commit];
}
@@ -1756,7 +1828,7 @@ - (void) renderForCommandBuffer:(id<MTLCommandBuffer>)cb
{
case ClientDisplayMode_Main:
{
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
if ( (texDisplayMain != nil) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main) )
{
[rce setFragmentBytes:&backlightIntensity[NDSDisplayID_Main] length:sizeof(backlightIntensity[NDSDisplayID_Main]) atIndex:0];
[rce setFragmentTexture:texDisplayMain atIndex:0];
@@ -1767,7 +1839,7 @@ - (void) renderForCommandBuffer:(id<MTLCommandBuffer>)cb
case ClientDisplayMode_Touch:
{
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
if ( (texDisplayTouch != nil) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch) )
{
[rce setFragmentBytes:&backlightIntensity[NDSDisplayID_Touch] length:sizeof(backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
[rce setFragmentTexture:texDisplayTouch atIndex:0];
@@ -1787,7 +1859,7 @@ - (void) renderForCommandBuffer:(id<MTLCommandBuffer>)cb
case ClientDisplayLayout_Hybrid_16_9:
case ClientDisplayLayout_Hybrid_16_10:
{
if (cdp->IsSelectedDisplayEnabled(majorDisplayID))
if ( (((majorDisplayID == NDSDisplayID_Main) && (texDisplayMain != nil)) || ((majorDisplayID == NDSDisplayID_Touch) && (texDisplayTouch != nil))) && cdp->IsSelectedDisplayEnabled(majorDisplayID) )
{
[rce setFragmentBytes:&backlightIntensity[majorDisplayID] length:sizeof(backlightIntensity[majorDisplayID]) atIndex:0];
[rce setFragmentTexture:((majorDisplayID == NDSDisplayID_Main) ? texDisplayMain : texDisplayTouch) atIndex:0];
@@ -1800,14 +1872,14 @@ - (void) renderForCommandBuffer:(id<MTLCommandBuffer>)cb
break;
}
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
if ( (texDisplayMain != nil) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main) )
{
[rce setFragmentBytes:&backlightIntensity[NDSDisplayID_Main] length:sizeof(backlightIntensity[NDSDisplayID_Main]) atIndex:0];
[rce setFragmentTexture:texDisplayMain atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
}
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
if ( (texDisplayTouch != nil) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch) )
{
[rce setFragmentBytes:&backlightIntensity[NDSDisplayID_Touch] length:sizeof(backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
[rce setFragmentTexture:texDisplayTouch atIndex:0];
@@ -1912,16 +1984,32 @@ - (void) renderToBuffer:(uint32_t *)dstBuffer
texDisplayMain:_processedFrameInfo.tex[NDSDisplayID_Main]
texDisplayTouch:_processedFrameInfo.tex[NDSDisplayID_Touch]];
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock(&_mutexBufferUpdate);
if (needsFetchBuffersLock)
if (needsFetchBuffersLock)
{
if (_processedFrameInfo.bufferIndex == 0)
{
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:_processedFrameInfo.bufferIndex]);
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock(&_mutexBufferUpdate);
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:0]);
pthread_mutex_unlock(&_mutexTexProcessUpdate);
}];
}
pthread_mutex_unlock(&_mutexTexProcessUpdate);
}];
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock(&_mutexBufferUpdate);
pthread_rwlock_unlock([sharedData rwlockFramebufferAtIndex:1]);
pthread_mutex_unlock(&_mutexTexProcessUpdate);
}];
}
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock(&_mutexBufferUpdate);
pthread_mutex_unlock(&_mutexTexProcessUpdate);
}];
}
[cb commit];
@@ -2015,16 +2103,33 @@ - (void) renderToDrawable
texDisplayTouch:processedInfo.tex[NDSDisplayID_Touch]];
[cb presentDrawable:layerDrawable];
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock([presenterObject mutexBufferUpdate]);
if (needsFetchBuffersLock)
if (needsFetchBuffersLock)
{
if (processedInfo.bufferIndex == 0)
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock([presenterObject mutexBufferUpdate]);
pthread_rwlock_unlock([[presenterObject sharedData] rwlockFramebufferAtIndex:0]);
pthread_mutex_unlock([presenterObject mutexTexProcessUpdate]);
}];
}
else
{
pthread_rwlock_unlock([[presenterObject sharedData] rwlockFramebufferAtIndex:processedInfo.bufferIndex]);
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock([presenterObject mutexBufferUpdate]);
pthread_rwlock_unlock([[presenterObject sharedData] rwlockFramebufferAtIndex:1]);
pthread_mutex_unlock([presenterObject mutexTexProcessUpdate]);
}];
}
pthread_mutex_unlock([presenterObject mutexTexProcessUpdate]);
}];
}
else
{
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
pthread_mutex_unlock([presenterObject mutexBufferUpdate]);
pthread_mutex_unlock([presenterObject mutexTexProcessUpdate]);
}];
}
[cb commit];
}

0 comments on commit 66e8a95

Please sign in to comment.