diff options
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 41 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop_p.h | 2 |
2 files changed, 27 insertions, 16 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 0d98fc6464..a420ce074a 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -176,15 +176,13 @@ const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 5); // if no windows are rendering. const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 7); -// Passed by the RL to the RL when maybeUpdate is called on the RT to -// just replay the maybeUpdate later. This typically happens when -// updatePaintNode() results in a call to QQuickItem::update(). -//const QEvent::Type WM_UpdateLater = QEvent::Type(QEvent::User + 8); // not used for now - // Passed by the RL to the RT when a QQuickWindow::grabWindow() is // called. const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 9); +// Passed by RL to RT when polish fails and we need to reset the expose sycle. +const QEvent::Type WM_ResetExposeCycle = QEvent::Type(QEvent::User + 10); + template <typename T> T *windowFor(const QList<T> list, QQuickWindow *window) { for (int i=0; i<list.size(); ++i) { @@ -380,6 +378,11 @@ bool QSGRenderThread::event(QEvent *e) exposeCycle = ExposePendingSync; return true; } + case WM_ResetExposeCycle: + QSG_RT_DEBUG("WM_ResetExposeCycle"); + exposeCycle = NoExpose; + return true; + case WM_Obscure: { QSG_RT_DEBUG("WM_Obscure"); @@ -977,15 +980,19 @@ void QSGThreadedRenderLoop::handleExposure(Window *w) } w->thread->postEvent(new WMExposeEvent(w->window)); - polishAndSync(w); + bool synced = polishAndSync(w); - w->thread->mutex.lock(); - if (w->thread->exposeCycle != QSGRenderThread::NoExpose) { - QSG_GUI_DEBUG(w->window, " - waiting for swap to complete..."); - w->thread->waitCondition.wait(&w->thread->mutex); + if (synced) { + w->thread->mutex.lock(); + if (w->thread->exposeCycle != QSGRenderThread::NoExpose) { + QSG_GUI_DEBUG(w->window, " - waiting for swap to complete..."); + w->thread->waitCondition.wait(&w->thread->mutex); + } + Q_ASSERT(w->thread->exposeCycle == QSGRenderThread::NoExpose); + w->thread->mutex.unlock(); + } else { + w->thread->postEvent(new QEvent(WM_ResetExposeCycle)); } - Q_ASSERT(w->thread->exposeCycle == QSGRenderThread::NoExpose); - w->thread->mutex.unlock(); QSG_GUI_DEBUG(w->window, " - handleExposure completed..."); startOrStopAnimationTimer(); @@ -1111,8 +1118,10 @@ void QSGThreadedRenderLoop::releaseResources(QQuickWindow *window, bool inDestru } - -void QSGThreadedRenderLoop::polishAndSync(Window *w) +/* Calls polish on all items, then requests synchronization with the render thread + * and blocks until that is complete. Returns false if it aborted; otherwise true. + */ +bool QSGThreadedRenderLoop::polishAndSync(Window *w) { QSG_GUI_DEBUG(w->window, "polishAndSync()"); @@ -1120,7 +1129,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w) QSG_GUI_DEBUG(w->window, " - not exposed, aborting..."); killTimer(w->timerId); w->timerId = 0; - return; + return false; } @@ -1196,6 +1205,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w) syncTime - waitTime, timer.nsecsElapsed() - syncTime)); #endif + + return true; } bool QSGThreadedRenderLoop::event(QEvent *e) diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 5943d0bd08..e142f7f2c8 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -102,7 +102,7 @@ private: void startOrStopAnimationTimer(); void maybePostPolishRequest(Window *w); void waitForReleaseComplete(); - void polishAndSync(Window *w); + bool polishAndSync(Window *w); void maybeUpdate(Window *window); void handleExposure(Window *w); |