aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-12-03 14:55:38 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-12-03 21:45:17 +0100
commit8c0fb7679c34281b7ed48e466a7eb72885c088e7 (patch)
treecaf7f688887840fb7a40c35dafc8c3c7f83e5962 /src/quick/scenegraph
parenta2f7de70d60a9ac212a575cae2387adfb0e5426b (diff)
Clear RequestRepaint bit set in sync() if we are going to render
...because if we are going to go on doing a frame then the repaint request is fulfilled. Leaving the bit set would cause the render thread's main loop to start another frame right after the current one is queued, which is kind of bad in certain scheduling and blocking cases because the main thread may end up starving due to the unnecessary extra (and sync-less) frame. Task-number: QTBUG-80498 Change-Id: I6c9a8f60e5f49d771d7d284bb7399eadbde33b8c Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 36ef0cc218..a213c6efd4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -699,8 +699,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
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;
+ if (!grabRequested)
+ pendingUpdate = 0;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
// Begin the frame before syncing -> sync is where we may invoke
@@ -776,20 +777,30 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
- if (!syncResultedInChanges && !repaintRequested && sgrc->isValid() && !grabImage) {
- if (gl || (rhi && !rhi->isRecordingFrame())) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
+ if (!syncResultedInChanges
+ && !repaintRequested
+ && !(pendingUpdate & RepaintRequest) // may have been set in sync()
+ && sgrc->isValid()
+ && !grabRequested
+ && (gl || (rhi && !rhi->isRecordingFrame())))
+ {
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
+ int waitTime = vsyncDelta - (int) waitTimer.elapsed();
+ if (waitTime > 0)
+ msleep(waitTime);
+ return;
}
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
+ // RepaintRequest may have been set in pendingUpdate in an
+ // updatePaintNode() invoked from sync(). We are about to do a repaint
+ // right now, so reset the flag. (bits other than RepaintRequest cannot
+ // be set in pendingUpdate at this point)
+ if (!grabRequested)
+ pendingUpdate = 0;
- if (animatorDriver->isRunning() && !grabImage) {
+ if (animatorDriver->isRunning() && !grabRequested) {
d->animationController->lock();
animatorDriver->advance();
d->animationController->unlock();
@@ -824,14 +835,14 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
// blocking in a real frame. The legacy GL path never gets here with
// grabs as it rather invokes sync/render directly without going
// through syncAndRender().
- if (grabImage) {
+ if (grabRequested) {
Q_ASSERT(rhi && !gl && cd->swapchain);
*grabImage = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain);
}
if (cd->swapchain) {
QRhi::EndFrameFlags flags;
- if (grabImage)
+ if (grabRequested)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
if (frameResult != QRhi::FrameOpSuccess) {
@@ -847,7 +858,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
gl->swapBuffers(window);
}
- if (!grabImage)
+ if (!grabRequested)
d->fireFrameSwapped();
} else {