I think I've solved it. Consider this code from OgreMetalWindow.mm:
Code: Select all
void MetalWindow::swapBuffers()
{
if( !mDevice->mFrameAborted )
{
// Schedule a present once rendering to the framebuffer is complete
const CFTimeInterval presentationTime = mMetalView.presentationTime;
if( mMetalLayer.presentsWithTransaction )
{
id<MTLCommandBuffer> commandBuffer = mDevice->mCurrentCommandBuffer;
mDevice->commitAndNextCommandBuffer();
[commandBuffer waitUntilScheduled];
[mCurrentDrawable present];
}
else if( presentationTime < 0 )
{
[mDevice->mCurrentCommandBuffer presentDrawable:mCurrentDrawable];
}
else
{
[mDevice->mCurrentCommandBuffer presentDrawable:mCurrentDrawable
atTime:presentationTime];
}
}
if( !mManualRelease )
mCurrentDrawable = 0;
}
Normally, presentsWithTransaction is false, and the view's presentationTime has not been set, so it has its initial value of 0. Therefore the last else
clause runs. I'm guessing that what changed in Ventura is the behavior of -[MtlCommandBuffer presentDrawable:atTime:]
when it is passed a time that is 0, or maybe anything less than the current time. If we change the last else if
to
Code: Select all
else if( presentationTime <= 0.0 )
then the flicker goes away.