Cocoa Port: Ensure that display windows avoid drawing with uninitialized display info and possibly non-existent buffers on startup.

This commit is contained in:
rogerman 2017-07-18 01:26:42 -07:00
parent 7791f60495
commit ddac7122d3
2 changed files with 167 additions and 155 deletions

View File

@ -6929,31 +6929,34 @@ void OGLDisplayLayer::ProcessOGL()
GLsizei width[2] = { emuDisplayInfo.renderedWidth[NDSDisplayID_Main], emuDisplayInfo.renderedWidth[NDSDisplayID_Touch] }; GLsizei width[2] = { emuDisplayInfo.renderedWidth[NDSDisplayID_Main], emuDisplayInfo.renderedWidth[NDSDisplayID_Touch] };
GLsizei height[2] = { emuDisplayInfo.renderedHeight[NDSDisplayID_Main], emuDisplayInfo.renderedHeight[NDSDisplayID_Touch] }; GLsizei height[2] = { emuDisplayInfo.renderedHeight[NDSDisplayID_Main], emuDisplayInfo.renderedHeight[NDSDisplayID_Touch] };
// Run the video source filters and the pixel scalers if (emuDisplayInfo.pixelBytes != 0)
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(); // Run the video source filters and the pixel scalers
} const bool willFilterOnGPU = this->_output->WillFilterOnGPU();
const bool useDeposterize = this->_output->GetSourceDeposterize();
if (needProcessDisplay[NDSDisplayID_Main]) 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) };
this->_ProcessDisplayByID(NDSDisplayID_Main, width[NDSDisplayID_Main], height[NDSDisplayID_Main], texVideoSourceID[NDSDisplayID_Main]); const bool needsLock = (willFilterOnGPU || useDeposterize) && (needProcessDisplay[NDSDisplayID_Main] || needProcessDisplay[NDSDisplayID_Touch]);
}
if (needsLock)
if (needProcessDisplay[NDSDisplayID_Touch]) {
{ this->_output->LockDisplayTextures();
this->_ProcessDisplayByID(NDSDisplayID_Touch, width[NDSDisplayID_Touch], height[NDSDisplayID_Touch], texVideoSourceID[NDSDisplayID_Touch]); }
}
if (needProcessDisplay[NDSDisplayID_Main])
if (needsLock) {
{ this->_ProcessDisplayByID(NDSDisplayID_Main, width[NDSDisplayID_Main], height[NDSDisplayID_Main], texVideoSourceID[NDSDisplayID_Main]);
this->_output->UnlockDisplayTextures(); }
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 // Set the final output texture IDs
@ -7007,88 +7010,91 @@ void OGLDisplayLayer::RenderOGL()
this->_UpdateRotationScaleOGL(); this->_UpdateRotationScaleOGL();
} }
if (this->_needUpdateVertices) if (emuDisplayInfo.pixelBytes != 0)
{ {
this->_UpdateVerticesOGL(); if (this->_needUpdateVertices)
}
this->_output->LockDisplayTextures();
glBindVertexArrayDESMUME(this->_vaoMainStatesID);
switch (this->_output->GetViewProperties().mode)
{
case ClientDisplayMode_Main:
{ {
if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) this->_UpdateVerticesOGL();
{
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;
} }
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]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main])
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[majorDisplayID]) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
{ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]);
glDrawArrays(GL_TRIANGLE_STRIP, majorDisplayVtx, 4);
}
break;
} }
break;
default:
break;
} }
if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]) case ClientDisplayMode_Touch:
{ {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch])
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]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 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]); const NDSDisplayID majorDisplayID = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch;
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]); const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12;
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); 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: glBindVertexArrayDESMUME(0);
break; this->_output->UnlockDisplayTextures();
} }
glBindVertexArrayDESMUME(0);
this->_output->UnlockDisplayTextures();
} }
void OGLDisplayLayer::FinishOGL(const u8 bufferIndex) void OGLDisplayLayer::FinishOGL(const u8 bufferIndex)

View File

@ -619,9 +619,10 @@
} }
[cce endEncoding]; [cce endEncoding];
[cb commit];
} }
[cb commit];
[self setTexDisplaySrcTargetMain:texDisplaySrcTarget[NDSDisplayID_Main]]; [self setTexDisplaySrcTargetMain:texDisplaySrcTarget[NDSDisplayID_Main]];
[self setTexDisplaySrcTargetTouch:texDisplaySrcTarget[NDSDisplayID_Touch]]; [self setTexDisplaySrcTargetTouch:texDisplaySrcTarget[NDSDisplayID_Touch]];
} }
@ -823,6 +824,8 @@
[self setSharedData:nil]; [self setSharedData:nil];
delete _cdv; delete _cdv;
dispatch_release(availableResources);
[super dealloc]; [super dealloc];
} }
@ -1244,7 +1247,7 @@
_texDisplayOutput[NDSDisplayID_Main] = [sharedData texDisplaySrcTargetMain]; _texDisplayOutput[NDSDisplayID_Main] = [sharedData texDisplaySrcTargetMain];
_texDisplayOutput[NDSDisplayID_Touch] = [sharedData texDisplaySrcTargetTouch]; _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 willFilterOnGPU = _cdv->WillFilterOnGPU();
const bool shouldProcessDisplay[2] = { (!fetchDisplayInfo.didPerformCustomRender[NDSDisplayID_Main] || !fetchDisplayInfo.isCustomSizeRequested) && fetchDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), 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. // Draw the NDS displays.
if ([self needsScreenVerticesUpdate]) if (displayInfo.pixelBytes != 0)
{ {
_cdv->SetScreenVertices((float *)[_displayVtxPositionBuffer contents]); if ([self needsScreenVerticesUpdate])
[_displayVtxPositionBuffer didModifyRange:NSMakeRange(0, sizeof(float) * (4 * 8))]; {
_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 setRenderPipelineState:[self displayOutputPipeline]]; [ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:2];
[ce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0];
[ce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1]; switch (_cdv->GetViewProperties().mode)
[ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:2];
switch (_cdv->GetViewProperties().mode)
{
case ClientDisplayMode_Main:
{ {
if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) case ClientDisplayMode_Main:
{ {
[ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; if (displayInfo.isDisplayEnabled[NDSDisplayID_Main])
[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[majorDisplayID]) [ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0];
{ [ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
[ce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0];
[ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4];
}
break;
} }
break;
default:
break;
} }
if (displayInfo.isDisplayEnabled[NDSDisplayID_Main]) case ClientDisplayMode_Touch:
{ {
[ce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; if (displayInfo.isDisplayEnabled[NDSDisplayID_Touch])
[ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; {
[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]; const NDSDisplayID majorDisplayID = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch;
[ce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; 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. // Draw the HUD.