From c95542694527d66361b9882ad39db5eb06cca3fe Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 26 Jul 2019 13:16:57 +0200 Subject: rhi: metal: Do not hold on to the drawable when not presenting The Quick render loops do SkipPresent occasionally, and it all seemed to work with the threaded one because we lack an autorelease pool on the SG render thread. (to be corrected separately) The basic one ended up crashing sometimes, however. Holding on to the drawable is incorrect. Fixes: QTBUG-76953 Change-Id: I0d0ec6d09aa209d2c848d7a9dbd9b15916fe23ab Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 6 ++++++ src/gui/rhi/qrhimetal.mm | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src/gui') diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index d7c1607e57..a29c7e263e 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -260,6 +260,12 @@ QT_BEGIN_NAMESPACE tied to those concepts, however, and is thus a topic that is currently out of scope, but may be introduced in the future. + \note The Metal backend requires that an autorelease pool is available on + the rendering thread, ideally wrapping each iteration of the render loop. + This needs no action from the users of QRhi when rendering on the main + (gui) thread, but becomes important when a separate, dedicated render + thread is used. + \section3 Resource synchronization QRhi does not expose APIs for resource barriers or image layout diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index fa537a504b..98b2a9bcac 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -57,7 +57,8 @@ QT_BEGIN_NAMESPACE Textures are Private (device local) and a host visible staging buffer is used to upload data to them. Does not rely on strong objects refs from command buffers but does rely on the automatic resource tracking of the - command encoders. + command encoders. Assumes that an autorelease pool (ideally per frame) is + available on the thread on which QRhi is used. */ #if __has_feature(objc_arc) @@ -1214,10 +1215,12 @@ 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; - } + + // Must not hold on to the drawable, regardless of needsPresent. + // (internally it is autoreleased or something, it seems) + swapChainD->d->curDrawable = nil; __block int thisFrameSlot = currentFrameSlot; [swapChainD->cbWrapper.d->cb addCompletedHandler: ^(id) { -- cgit v1.2.3