From 33f16af30764d82af3f6c196618165b7b5f5afee Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 18 Jun 2019 16:18:05 +0200 Subject: [PATCH] rhi: metal: Reuse drawable after a frame without a present The source of this is likely a "window" grab from Qt Quick. Requesting a new drawable is an error in this case since we do not enqueue a present for the current one. Change-Id: I64bab03ff46743ce1f270b251229be126f9ad9fb Reviewed-by: Lars Knoll --- src/gui/rhi/qrhimetal.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 22d4e4e6d2..214374e0c6 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1206,8 +1206,10 @@ QRhi::FrameOpResult QRhiMetal::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame Q_ASSERT(currentSwapChain == swapChainD); const bool needsPresent = !flags.testFlag(QRhi::SkipPresent); - if (needsPresent) + if (needsPresent) { [swapChainD->cbWrapper.d->cb presentDrawable: swapChainD->d->curDrawable]; + swapChainD->d->curDrawable = nil; + } __block int thisFrameSlot = currentFrameSlot; [swapChainD->cbWrapper.d->cb addCompletedHandler: ^(id) { @@ -1689,7 +1691,8 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb, if (color0.needsDrawableForTex || color0.needsDrawableForResolveTex) { Q_ASSERT(currentSwapChain); QMetalSwapChain *swapChainD = QRHI_RES(QMetalSwapChain, currentSwapChain); - swapChainD->d->curDrawable = [swapChainD->d->layer nextDrawable]; + if (!swapChainD->d->curDrawable) + swapChainD->d->curDrawable = [swapChainD->d->layer nextDrawable]; if (!swapChainD->d->curDrawable) { qWarning("No drawable"); return; @@ -3497,6 +3500,8 @@ bool QMetalSwapChain::buildOrResize() [d->layer setDevice: rhiD->d->dev]; + d->curDrawable = nil; + for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) { if (!d->sem[i]) d->sem[i] = dispatch_semaphore_create(QMTL_FRAMES_IN_FLIGHT - 1);