diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-07-29 11:25:48 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-07-30 15:37:02 +0200 |
commit | 25c61c5de86d8ca4debd9a2956702fdb58f42981 (patch) | |
tree | 55d2525c943ee4ba40d2e4644e03ae71a5cec2e0 | |
parent | 65d9d4b930387ff67ebaba8e81c08cb8a417d035 (diff) |
Avoid locking up on resize with threaded loop and the rhi
This was visible on X11 only because there beginFrame() happened
to fail once or twice with out-of-date swapchain when there were
a lot of resizes in a row. Handle this case correctly by waking up
the main thread as appropriate.
Change-Id: I67dc18522e1c05070267fd355095324f48259276
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index db8e17a8e6..98a493f6ae 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -686,10 +686,11 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) syncResultedInChanges = false; QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage; - bool syncRequested = (pendingUpdate & SyncRequest) || grabImage; - bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; + const bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage; + const bool syncRequested = (pendingUpdate & SyncRequest) || grabImage; + const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; pendingUpdate = 0; + const bool grabRequested = grabImage != nullptr; QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); // Begin the frame before syncing -> sync is where we may invoke @@ -732,13 +733,26 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) // try again later if (frameResult == QRhi::FrameOpDeviceLost || frameResult == QRhi::FrameOpSwapChainOutOfDate) QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); + + // Before returning we need to ensure the same wake up logic that + // would have happened if beginFrame() had suceeded. + if (exposeRequested) { + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui"); + waitCondition.wakeOne(); + mutex.unlock(); + } else if (syncRequested && !grabRequested) { + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui like sync would do"); + mutex.lock(); + waitCondition.wakeOne(); + mutex.unlock(); + } return; } } if (syncRequested) { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- updatePending, doing sync"); - sync(exposeRequested, grabImage != nullptr); + sync(exposeRequested, grabRequested); } #ifndef QSG_NO_RENDER_TIMING if (profileFrames) |