From 6df89c3b9d4e88d600c80aa3f39718fcab14fc6f Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@digia.com>
Date: Wed, 19 Feb 2014 12:20:20 +0100
Subject: [PATCH] Add a signal for syncing external animation systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[ChangeLog] QQuickWindow will now emit the afterAnimating() signal
from the gui thread before each scenegraph sync request.

Change-Id: I4897c82f75066238e781455d4fce4fb6bbe2558e
Reviewed-by: Pasi Keränen <pasi.keranen@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
---
 src/quick/items/qquickwindow.cpp                  | 10 ++++++++++
 src/quick/items/qquickwindow.h                    |  1 +
 src/quick/scenegraph/qsgrenderloop.cpp            |  2 ++
 src/quick/scenegraph/qsgthreadedrenderloop.cpp    |  2 ++
 src/quick/scenegraph/qsgwindowsrenderloop.cpp     |  2 ++
 .../auto/quick/qquickwindow/tst_qquickwindow.cpp  | 15 +++++++++++++++
 6 files changed, 32 insertions(+)

diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index f035e87d99..bc8558e1d8 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -3044,6 +3044,16 @@ QQmlIncubationController *QQuickWindow::incubationController() const
     do so can result in the scene not rendering properly.
  */
 
+/*!
+    \fn void QQuickWindow::afterAnimating()
+
+    This signal is emitted on the gui thread before requesting the render thread to
+    perform the synchronization of the scene graph.
+
+    Unlike the other similar signals, this one is emitted on the gui thread instead
+    of the render thread. It can be used to synchronize external animation systems
+    with the QML content.
+ */
 
 
 /*!
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 233340d6fa..ced232467b 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -138,6 +138,7 @@ Q_SIGNALS:
     void beforeSynchronizing();
     void beforeRendering();
     void afterRendering();
+    void afterAnimating();
     Q_REVISION(1) void closing(QQuickCloseEvent *close);
     void colorChanged(const QColor &);
     Q_REVISION(1) void activeFocusItemChanged();
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 4e8fa67869..50c5b141c3 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -302,6 +302,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
     QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
     cd->polishItems();
 
+    emit window->afterAnimating();
+
     qint64 renderTime = 0, syncTime = 0;
     QElapsedTimer renderTimer;
     bool profileFrames = qsg_render_timing()  || QQuickProfiler::enabled;
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index ffc6d31aa7..ddf724b89f 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -1096,6 +1096,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w)
 
     w->updateDuringSync = false;
 
+    emit w->window->afterAnimating();
+
     QSG_GUI_DEBUG(w->window, " - lock for sync...");
     w->thread->mutex.lock();
     m_locked = true;
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 995d80bb82..204a303d2c 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -442,6 +442,8 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
     d->polishItems();
     QSG_RENDER_TIMING_SAMPLE(time_polished);
 
+    emit window->afterAnimating();
+
     RLDEBUG(" - syncing");
     d->syncSceneGraph();
     QSG_RENDER_TIMING_SAMPLE(time_synced);
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index bdd70f6a6e..edde8d2134 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -351,6 +351,8 @@ private slots:
     void cursor();
 #endif
 
+    void animatingSignal();
+
 private:
     QTouchDevice *touchDevice;
     QTouchDevice *touchDeviceWithVelocity;
@@ -1657,6 +1659,19 @@ void tst_qquickwindow::qobjectEventFilter_mouse()
     QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, point);
 }
 
+void tst_qquickwindow::animatingSignal()
+{
+    QQuickWindow window;
+    window.setGeometry(100, 100, 300, 200);
+
+    QSignalSpy spy(&window, SIGNAL(afterAnimating()));
+
+    window.show();
+    QTRY_VERIFY(window.isExposed());
+
+    QTRY_VERIFY(spy.count() > 1);
+}
+
 QTEST_MAIN(tst_qquickwindow)
 
 #include "tst_qquickwindow.moc"
-- 
GitLab