diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-12-03 14:55:38 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-12-03 21:45:17 +0100 |
commit | 8c0fb7679c34281b7ed48e466a7eb72885c088e7 (patch) | |
tree | caf7f688887840fb7a40c35dafc8c3c7f83e5962 /src/quick/scenegraph | |
parent | a2f7de70d60a9ac212a575cae2387adfb0e5426b (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.cpp | 37 |
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 { |