diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-09-06 19:46:34 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-09-07 11:48:28 +0200 |
commit | f500e45cc5b237b5ed549947cdf129e9cafa689c (patch) | |
tree | 16bcfd3f3ca72a4798b51a72f05c8cbf122bb3ef | |
parent | 23ad0953abd4acee9f866966b6ff1d26b1eb777d (diff) |
Render loops: ignore update reqs during the main polish step
The classic example is Shape, which needs to dirty the QQuickItem in
updatePolish() in order to get it picked up in the synchronize step.
That part is fine, but we do not want maybeUpdate() to issue a
requestUpdate() then since we are effectively in progress of doing an
update, so having another full round of polish/sync/render is a waste.
Task-number: QTBUG-86089
Change-Id: Ie41563b34da17e7134631791ed024b31e87e21e3
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 10 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 9 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop_p.h | 1 |
3 files changed, 20 insertions, 0 deletions
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 6f83085745..f5234bbf5e 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -191,6 +191,7 @@ public: QSGRenderContext *rc; QImage grabContent; + bool m_inPolish = false; }; #endif @@ -591,7 +592,9 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) Q_TRACE(QSG_polishItems_entry); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); + m_inPolish = true; cd->polishItems(); + m_inPolish = false; if (profileFrames) polishTime = renderTimer.nsecsElapsed(); @@ -782,6 +785,13 @@ void QSGGuiThreadRenderLoop::maybeUpdate(QQuickWindow *window) if (!cd->isRenderable()) return; + // An updatePolish() implementation may call update() to get the QQuickItem + // dirtied. That's fine but it also leads to calling this function. + // Requesting another update is a waste then since the updatePolish() call + // will be followed up with a round of sync and render. + if (m_inPolish) + return; + window->requestUpdate(); } diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index a4524b5b33..a47aa4f359 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -1401,6 +1401,13 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w) return; } + // An updatePolish() implementation may call update() to get the QQuickItem + // dirtied. That's fine but it also leads to calling this function. + // Requesting another update is a waste then since the updatePolish() call + // will be followed up with a round of sync and render. + if (m_inPolish) + return; + postUpdateRequest(w); } @@ -1507,7 +1514,9 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) Q_TRACE(QSG_polishItems_entry); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + m_inPolish = true; d->polishItems(); + m_inPolish = false; if (profileFrames) polishTime = timer.nsecsElapsed(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 60d3e7781d..1a99cc7ddf 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -134,6 +134,7 @@ private: int m_animation_timer; bool m_lockedForSync; + bool m_inPolish = false; }; QT_END_NAMESPACE |