From ddac7122d3dbddd40a7ca06da39db1ae060b37a7 Mon Sep 17 00:00:00 2001 From: rogerman Date: Tue, 18 Jul 2017 01:26:42 -0700 Subject: [PATCH] Cocoa Port: Ensure that display windows avoid drawing with uninitialized display info and possibly non-existent buffers on startup. --- .../src/frontend/cocoa/OGLDisplayOutput.cpp | 190 +++++++++--------- .../userinterface/MacMetalDisplayView.mm | 132 ++++++------ 2 files changed, 167 insertions(+), 155 deletions(-) diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp index b2388d527..926693b00 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp @@ -6929,31 +6929,34 @@ void OGLDisplayLayer::ProcessOGL() GLsizei width[2] = { emuDisplayInfo.renderedWidth[NDSDisplayID_Main], emuDisplayInfo.renderedWidth[NDSDisplayID_Touch] }; GLsizei height[2] = { emuDisplayInfo.renderedHeight[NDSDisplayID_Main], emuDisplayInfo.renderedHeight[NDSDisplayID_Touch] }; - // Run the video source filters and the pixel scalers - const bool willFilterOnGPU = this->_output->WillFilterOnGPU(); - const bool useDeposterize = this->_output->GetSourceDeposterize(); - const bool needProcessDisplay[2] = { (didRenderNative[NDSDisplayID_Main] || !emuDisplayInfo.isCustomSizeRequested) && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), - (didRenderNative[NDSDisplayID_Touch] || !emuDisplayInfo.isCustomSizeRequested) && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual) }; - const bool needsLock = (willFilterOnGPU || useDeposterize) && (needProcessDisplay[NDSDisplayID_Main] || needProcessDisplay[NDSDisplayID_Touch]); - - if (needsLock) + if (emuDisplayInfo.pixelBytes != 0) { - this->_output->LockDisplayTextures(); - } - - if (needProcessDisplay[NDSDisplayID_Main]) - { - this->_ProcessDisplayByID(NDSDisplayID_Main, width[NDSDisplayID_Main], height[NDSDisplayID_Main], texVideoSourceID[NDSDisplayID_Main]); - } - - if (needProcessDisplay[NDSDisplayID_Touch]) - { - this->_ProcessDisplayByID(NDSDisplayID_Touch, width[NDSDisplayID_Touch], height[NDSDisplayID_Touch], texVideoSourceID[NDSDisplayID_Touch]); - } - - if (needsLock) - { - this->_output->UnlockDisplayTextures(); + // Run the video source filters and the pixel scalers + const bool willFilterOnGPU = this->_output->WillFilterOnGPU(); + const bool useDeposterize = this->_output->GetSourceDeposterize(); + const bool needProcessDisplay[2] = { (didRenderNative[NDSDisplayID_Main] || !emuDisplayInfo.isCustomSizeRequested) && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), + (didRenderNative[NDSDisplayID_Touch] || !emuDisplayInfo.isCustomSizeRequested) && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual) }; + const bool needsLock = (willFilterOnGPU || useDeposterize) && (needProcessDisplay[NDSDisplayID_Main] || needProcessDisplay[NDSDisplayID_Touch]); + + if (needsLock) + { + this->_output->LockDisplayTextures(); + } + + if (needProcessDisplay[NDSDisplayID_Main]) + { + this->_ProcessDisplayByID(NDSDisplayID_Main, width[NDSDisplayID_Main], height[NDSDisplayID_Main], texVideoSourceID[NDSDisplayID_Main]); + } + + if (needProcessDisplay[NDSDisplayID_Touch]) + { + this->_ProcessDisplayByID(NDSDisplayID_Touch, width[NDSDisplayID_Touch], height[NDSDisplayID_Touch], texVideoSourceID[NDSDisplayID_Touch]); + } + + if (needsLock) + { + this->_output->UnlockDisplayTextures(); + } } // Set the final output texture IDs @@ -7007,88 +7010,91 @@ void OGLDisplayLayer::RenderOGL() this->_UpdateRotationScaleOGL(); } - if (this->_needUpdateVertices) + if (emuDisplayInfo.pixelBytes != 0) { - this->_UpdateVerticesOGL(); - } - - this->_output->LockDisplayTextures(); - glBindVertexArrayDESMUME(this->_vaoMainStatesID); - - switch (this->_output->GetViewProperties().mode) - { - case ClientDisplayMode_Main: + if (this->_needUpdateVertices) { - if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) - { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - } - break; + this->_UpdateVerticesOGL(); } - - case ClientDisplayMode_Touch: + + this->_output->LockDisplayTextures(); + glBindVertexArrayDESMUME(this->_vaoMainStatesID); + + switch (this->_output->GetViewProperties().mode) { - if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + case ClientDisplayMode_Main: { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); - glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); - } - break; - } - - case ClientDisplayMode_Dual: - { - const NDSDisplayID majorDisplayID = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; - const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; - - switch (this->_output->GetViewProperties().layout) - { - case ClientDisplayLayout_Hybrid_2_1: - case ClientDisplayLayout_Hybrid_16_9: - case ClientDisplayLayout_Hybrid_16_10: + if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) { - if (emuDisplayInfo.isDisplayEnabled[majorDisplayID]) - { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]); - glDrawArrays(GL_TRIANGLE_STRIP, majorDisplayVtx, 4); - } - break; + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - - default: - break; + break; } - - if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) + + case ClientDisplayMode_Touch: { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + { + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); + glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); + } + break; } - - if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + + case ClientDisplayMode_Dual: { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); - glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); + const NDSDisplayID majorDisplayID = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; + const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; + + switch (this->_output->GetViewProperties().layout) + { + case ClientDisplayLayout_Hybrid_2_1: + case ClientDisplayLayout_Hybrid_16_9: + case ClientDisplayLayout_Hybrid_16_10: + { + if (emuDisplayInfo.isDisplayEnabled[majorDisplayID]) + { + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]); + glDrawArrays(GL_TRIANGLE_STRIP, majorDisplayVtx, 4); + } + break; + } + + default: + break; + } + + if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) + { + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + { + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); + glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); + } } + + default: + break; } - - default: - break; + + glBindVertexArrayDESMUME(0); + this->_output->UnlockDisplayTextures(); } - - glBindVertexArrayDESMUME(0); - this->_output->UnlockDisplayTextures(); } void OGLDisplayLayer::FinishOGL(const u8 bufferIndex) diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm index 1d7b0dcca..992a36405 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm @@ -619,9 +619,10 @@ } [cce endEncoding]; - [cb commit]; } + [cb commit]; + [self setTexDisplaySrcTargetMain:texDisplaySrcTarget[NDSDisplayID_Main]]; [self setTexDisplaySrcTargetTouch:texDisplaySrcTarget[NDSDisplayID_Touch]]; } @@ -823,6 +824,8 @@ [self setSharedData:nil]; delete _cdv; + dispatch_release(availableResources); + [super dealloc]; } @@ -1244,7 +1247,7 @@ _texDisplayOutput[NDSDisplayID_Main] = [sharedData texDisplaySrcTargetMain]; _texDisplayOutput[NDSDisplayID_Touch] = [sharedData texDisplaySrcTargetTouch]; - if (useDeposterize || (_cdv->GetPixelScaler() != VideoFilterTypeID_None)) + if ( (fetchDisplayInfo.pixelBytes != 0) && (useDeposterize || (_cdv->GetPixelScaler() != VideoFilterTypeID_None)) ) { const bool willFilterOnGPU = _cdv->WillFilterOnGPU(); const bool shouldProcessDisplay[2] = { (!fetchDisplayInfo.didPerformCustomRender[NDSDisplayID_Main] || !fetchDisplayInfo.isCustomSizeRequested) && fetchDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), @@ -1480,79 +1483,82 @@ } // Draw the NDS displays. - if ([self needsScreenVerticesUpdate]) + if (displayInfo.pixelBytes != 0) { - _cdv->SetScreenVertices((float *)[_displayVtxPositionBuffer contents]); - [_displayVtxPositionBuffer didModifyRange:NSMakeRange(0, sizeof(float) * (4 * 8))]; + if ([self needsScreenVerticesUpdate]) + { + _cdv->SetScreenVertices((float *)[_displayVtxPositionBuffer contents]); + [_displayVtxPositionBuffer didModifyRange:NSMakeRange(0, sizeof(float) * (4 * 8))]; + + [self setNeedsScreenVerticesUpdate:NO]; + } - [self setNeedsScreenVerticesUpdate:NO]; - } - - [ce setRenderPipelineState:[self displayOutputPipeline]]; - [ce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0]; - [ce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1]; - [ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:2]; - - switch (_cdv->GetViewProperties().mode) - { - case ClientDisplayMode_Main: + [ce setRenderPipelineState:[self displayOutputPipeline]]; + [ce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0]; + [ce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1]; + [ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:2]; + + switch (_cdv->GetViewProperties().mode) { - if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) + case ClientDisplayMode_Main: { - [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; - [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; - } - break; - } - - case ClientDisplayMode_Touch: - { - if (displayInfo.isDisplayEnabled[NDSDisplayID_Touch]) - { - [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; - [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; - } - break; - } - - case ClientDisplayMode_Dual: - { - const NDSDisplayID majorDisplayID = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; - const size_t majorDisplayVtx = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; - - switch (_cdv->GetViewProperties().layout) - { - case ClientDisplayLayout_Hybrid_2_1: - case ClientDisplayLayout_Hybrid_16_9: - case ClientDisplayLayout_Hybrid_16_10: + if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) { - if (displayInfo.isDisplayEnabled[majorDisplayID]) - { - [ce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0]; - [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4]; - } - break; + [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; + [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; } - - default: - break; + break; } - - if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) + + case ClientDisplayMode_Touch: { - [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; - [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + if (displayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + { + [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; + [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; + } + break; } - - if (displayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + + case ClientDisplayMode_Dual: { - [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; - [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; + const NDSDisplayID majorDisplayID = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; + const size_t majorDisplayVtx = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; + + switch (_cdv->GetViewProperties().layout) + { + case ClientDisplayLayout_Hybrid_2_1: + case ClientDisplayLayout_Hybrid_16_9: + case ClientDisplayLayout_Hybrid_16_10: + { + if (displayInfo.isDisplayEnabled[majorDisplayID]) + { + [ce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0]; + [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4]; + } + break; + } + + default: + break; + } + + if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) + { + [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; + [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + } + + if (displayInfo.isDisplayEnabled[NDSDisplayID_Touch]) + { + [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; + [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; + } } + + default: + break; } - - default: - break; } // Draw the HUD.