aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgthreadedrenderloop.cpp
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-03-03 21:02:30 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-05 19:10:43 +0100
commit6f15b9102afb8694679f4c7648d0effdac4dd051 (patch)
tree9437ad20faed07e4cb21334eec1994b781d7a1fe /src/quick/scenegraph/qsgthreadedrenderloop.cpp
parent808f17756887d2fc95d526ee4aec741cb5730fad (diff)
Reset the expose cycle when polishAndSync aborts.
On platforms with misbehaving expose behavior, we will get and exposure, even though the window is not renderable. This results in the renderthread being in the "wait for polish" state while the GUI thread goes back to "no state". Check for this and reset render thread's expose cycle when it is hit. Task-number: QTBUG-37201 Change-Id: I6a6c89d9016301ff19443f88a2c182012b4eb65f Reviewed-by: Ulf Hermann <ulf.hermann@digia.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/quick/scenegraph/qsgthreadedrenderloop.cpp')
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp41
1 files changed, 26 insertions, 15 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)