aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-07-29 11:25:48 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-07-30 15:37:02 +0200
commit25c61c5de86d8ca4debd9a2956702fdb58f42981 (patch)
tree55d2525c943ee4ba40d2e4644e03ae71a5cec2e0
parent65d9d4b930387ff67ebaba8e81c08cb8a417d035 (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.cpp22
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)