diff options
Diffstat (limited to 'src/gui/rhi/qrhimetal.mm')
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index fd9b86148a..6f1acede9b 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1481,10 +1481,25 @@ QRhi::FrameOpResult QRhiMetal::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame const bool needsPresent = !flags.testFlag(QRhi::SkipPresent); if (needsPresent) { - auto drawable = swapChainD->d->curDrawable; - [swapChainD->cbWrapper.d->cb addScheduledHandler:^(id<MTLCommandBuffer>) { - [drawable present]; - }]; + // beginFrame-endFrame without a render pass inbetween means there is no + // drawable, handle this gracefully because presentDrawable does not like + // null arguments. + if (id<CAMetalDrawable> drawable = swapChainD->d->curDrawable) { + // QTBUG-103415: while the docs suggest the following two approaches are + // equivalent, there is a difference in case a frame is recorded earlier than + // (i.e. not in response to) the next CVDisplayLink callback. Therefore, stick + // with presentDrawable, which gives results identical to OpenGL, and all other + // platforms, i.e. throttles to vsync as expected, meaning constant 15-17 ms with + // a 60 Hz screen, no jumps with smaller intervals, regardless of when the frame + // is submitted by the app) +#if 1 + [swapChainD->cbWrapper.d->cb presentDrawable: drawable]; +#else + [swapChainD->cbWrapper.d->cb addScheduledHandler:^(id<MTLCommandBuffer>) { + [drawable present]; + }]; +#endif + } } // Must not hold on to the drawable, regardless of needsPresent |