diff options
author | Gunnar Sletta <gunnar@sletta.org> | 2014-10-07 12:22:26 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar@sletta.org> | 2014-10-10 21:10:52 +0200 |
commit | 099ae0597df6f6bbd0b9e05d063a4a58c9cae2ff (patch) | |
tree | ccfaf743aa3a572d362927131311787dd98c599b | |
parent | 7f5a59c2025022f99dff9fa030c892adb4473d6a (diff) |
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 3 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller.cpp | 44 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller_p.h | 21 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob.cpp | 11 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob_p.h | 2 |
5 files changed, 63 insertions, 18 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 7b300c9ab6..4ec901ceb4 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -458,8 +458,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface); q->setFormat(sg->defaultSurfaceFormat()); - animationController = new QQuickAnimatorController(); - animationController->m_window = q; + animationController = new QQuickAnimatorController(q); delayedTouch = 0; diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index e009de205c..cfaa439072 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -44,10 +44,19 @@ QT_BEGIN_NAMESPACE -QQuickAnimatorController::QQuickAnimatorController() - : m_window(0) +QQuickAnimatorController::QQuickAnimatorController(QQuickWindow *window) + : m_window(window) , m_nodesAreInvalid(false) { + m_guiEntity = new QQuickAnimatorControllerGuiThreadEntity(); + m_guiEntity->controller = this; + connect(window, SIGNAL(frameSwapped()), m_guiEntity, SLOT(frameSwapped())); +} + +void QQuickAnimatorControllerGuiThreadEntity::frameSwapped() +{ + if (!controller.isNull()) + controller->stopProxyJobs(); } QQuickAnimatorController::~QQuickAnimatorController() @@ -71,6 +80,8 @@ QQuickAnimatorController::~QQuickAnimatorController() if (!m_animatorRoots.contains(job)) delete job; } + + delete m_guiEntity; } static void qquickanimator_invalidate_node(QAbstractAnimationJob *job) @@ -211,6 +222,27 @@ void QQuickAnimatorController::afterNodeSync() } } +void QQuickAnimatorController::proxyWasDestroyed(QQuickAnimatorProxyJob *proxy) +{ + lock(); + m_proxiesToStop.remove(proxy); + unlock(); +} + +void QQuickAnimatorController::stopProxyJobs() +{ + // Need to make a copy under lock and then stop while unlocked. + // Stopping triggers writeBack which in turn may lock, so it needs + // to be outside the lock. It is also safe because deletion of + // proxies happens on the GUI thread, where this code is also executing. + lock(); + QSet<QQuickAnimatorProxyJob *> jobs = m_proxiesToStop; + m_proxiesToStop.clear(); + unlock(); + foreach (QQuickAnimatorProxyJob *p, jobs) + p->stop(); +} + void QQuickAnimatorController::animationFinished(QAbstractAnimationJob *job) { /* We are currently on the render thread and m_deleting is primarily @@ -221,8 +253,10 @@ void QQuickAnimatorController::animationFinished(QAbstractAnimationJob *job) */ if (!m_deleting.contains(job)) { QQuickAnimatorProxyJob *proxy = m_animatorRoots[job]; - if (proxy) - QCoreApplication::postEvent(proxy, new QEvent(QEvent::User)); + if (proxy) { + m_window->update(); + m_proxiesToStop << proxy; + } // else already gone... } } @@ -254,12 +288,14 @@ void QQuickAnimatorController::startJob(QQuickAnimatorProxyJob *proxy, QAbstract { proxy->markJobManagedByController(); m_starting[job] = proxy; + m_stopping.remove(job); requestSync(); } void QQuickAnimatorController::stopJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) { m_stopping[job] = proxy; + m_starting.remove(job); requestSync(); } diff --git a/src/quick/util/qquickanimatorcontroller_p.h b/src/quick/util/qquickanimatorcontroller_p.h index bd44adf928..b13c174606 100644 --- a/src/quick/util/qquickanimatorcontroller_p.h +++ b/src/quick/util/qquickanimatorcontroller_p.h @@ -43,12 +43,14 @@ QT_BEGIN_NAMESPACE +class QQuickAnimatorControllerGuiThreadEntity; + class QQuickAnimatorController : public QObject, public QAnimationJobChangeListener { Q_OBJECT public: - QQuickAnimatorController(); + QQuickAnimatorController(QQuickWindow *window); ~QQuickAnimatorController(); void advance(); @@ -68,6 +70,9 @@ public: void lock() { m_mutex.lock(); } void unlock() { m_mutex.unlock(); } + + void proxyWasDestroyed(QQuickAnimatorProxyJob *proxy); + void stopProxyJobs(); void windowNodesDestroyed(); public Q_SLOTS: @@ -85,11 +90,25 @@ public: QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> m_transforms; QSet<QQuickItem *> m_deletedSinceLastFrame; QQuickWindow *m_window; + QQuickAnimatorControllerGuiThreadEntity *m_guiEntity; + QSet<QQuickAnimatorProxyJob *> m_proxiesToStop; QMutex m_mutex; bool m_nodesAreInvalid; }; +class QQuickAnimatorControllerGuiThreadEntity : public QObject +{ + Q_OBJECT +public: + QPointer<QQuickAnimatorController> controller; + +public Q_SLOTS: + void frameSwapped(); +}; + + + QT_END_NAMESPACE #endif // QQUICKANIMATORCONTROLLER_P_H diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index fdbffd4709..f29ec49b9f 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -85,6 +85,8 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje QQuickAnimatorProxyJob::~QQuickAnimatorProxyJob() { deleteJob(); + if (m_controller) + m_controller->proxyWasDestroyed(this); } void QQuickAnimatorProxyJob::deleteJob() @@ -179,15 +181,6 @@ void QQuickAnimatorProxyJob::startedByController() m_internalState = State_Running; } -bool QQuickAnimatorProxyJob::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - stop(); - return true; - } - return QObject::event(e); -} - static void qquick_syncback_helper(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 4bdcd6917d..d87c9072a2 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -72,8 +72,6 @@ public: void markJobManagedByController() { m_jobManagedByController = true; } protected: - bool event(QEvent *); - void updateCurrentTime(int); void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); |