diff options
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 13 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller.cpp | 185 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller_p.h | 63 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob.cpp | 103 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob_p.h | 12 |
7 files changed, 193 insertions, 187 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 9798974788..28a5df789f 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -420,7 +420,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c) q->setFormat(sg->defaultSurfaceFormat()); animationController = new QQuickAnimatorController(); - animationController->window = q; + animationController->m_window = q; QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection); QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection); diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 6fd01a3119..9f31ee708a 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -177,7 +177,7 @@ private Q_SLOTS: private: friend class QQuickItem; - friend class QQuickWindowRenderLoop; + friend class QQuickAnimatorController; Q_DISABLE_COPY(QQuickWindow) }; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 42c7c9c0ba..1d69034f5e 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -387,19 +387,16 @@ bool QSGRenderThread::event(QEvent *e) } window = se->window; - connect(animatorDriver, SIGNAL(started()), QQuickWindowPrivate::get(se->window)->animationController, SLOT(animationsStarted())); return true; } case WM_Obscure: { RLDEBUG1(" Render: WM_Obscure"); - WMWindowEvent *ce = static_cast<WMWindowEvent *>(e); - Q_ASSERT(!window || window == ce->window); + Q_ASSERT(!window || window == static_cast<WMWindowEvent *>(e)->window); if (window) { RLDEBUG1(" Render: - removed one..."); window = 0; - disconnect(animatorDriver, SIGNAL(started()), QQuickWindowPrivate::get(ce->window)->animationController, SLOT(animationsStarted())); } return true; } @@ -583,10 +580,14 @@ void QSGRenderThread::syncAndRender() #endif RLDEBUG(" Render: - rendering starting"); - if (animatorDriver->isRunning()) + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + + if (animatorDriver->isRunning()) { + d->animationController->lock(); animatorDriver->advance(); + d->animationController->unlock(); + } - QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) { gl->makeCurrent(window); d->renderSceneGraph(windowSize); diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 82c66b431d..a2364f4586 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -48,54 +48,80 @@ #include <QtGui/qscreen.h> +#include <QtCore/qcoreapplication.h> + QT_BEGIN_NAMESPACE QQuickAnimatorController::QQuickAnimatorController() - : window(0) + : m_window(0) { } QQuickAnimatorController::~QQuickAnimatorController() { - qDeleteAll(activeRootAnimations); + // The proxy job might already have been deleted, in which case we + // need to avoid calling functions on them. Then delete the job. + foreach (QAbstractAnimationJob *job, m_deleting) { + m_animatorRoots.take(job); + delete job; + } + + foreach (QQuickAnimatorProxyJob *proxy, m_animatorRoots) + proxy->controllerWasDeleted(); + qDeleteAll(m_animatorRoots.keys()); + + // Delete those who have been started, stopped and are now still + // pending for restart. + foreach (QAbstractAnimationJob *job, m_starting.keys()) { + if (!m_animatorRoots.contains(job)) + delete job; + } } void QQuickAnimatorController::itemDestroyed(QObject *o) { - deletedSinceLastFrame << (QQuickItem *) o; + m_deletedSinceLastFrame << (QQuickItem *) o; } void QQuickAnimatorController::advance() { bool running = false; - for (QSet<QAbstractAnimationJob *>::const_iterator it = activeRootAnimations.constBegin(); - !running && it != activeRootAnimations.constEnd(); ++it) { - if ((*it)->isRunning()) + for (QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *>::const_iterator it = m_animatorRoots.constBegin(); + !running && it != m_animatorRoots.constEnd(); ++it) { + if (it.key()->isRunning()) running = true; } // It was tempting to only run over the active animations, but we need to push // the values for the transforms that finished in the last frame and those will // have been removed already... - for (QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *>::const_iterator it = transforms.constBegin(); - it != transforms.constEnd(); ++it) { + lock(); + for (QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *>::const_iterator it = m_transforms.constBegin(); + it != m_transforms.constEnd(); ++it) { + QQuickTransformAnimatorJob::Helper *xform = *it; + // Set to zero when the item was deleted in beforeNodeSync(). + if (!xform->item) + continue; (*it)->apply(); } + unlock(); if (running) - window->update(); + m_window->update(); } static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorController *c) { if (job->isRenderThreadJob()) { QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); - if (!j->target()) + if (!j->target()) { return; - else if (c->deletedSinceLastFrame.contains(j->target())) + } else if (c->m_deletedSinceLastFrame.contains(j->target())) { j->targetWasDeleted(); - else + } else { + j->addAnimationChangeListener(c, QAbstractAnimationJob::StateChange); j->initialize(c); + } } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) @@ -105,90 +131,117 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC void QQuickAnimatorController::beforeNodeSync() { - // Force a render pass if we are adding new animations - // so that advance will be called.. - if (starting.size()) - window->update(); - - for (int i=0; i<starting.size(); ++i) { - QAbstractAnimationJob *job = starting.at(i); - job->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + foreach (QAbstractAnimationJob *job, m_deleting) { + m_starting.take(job); + m_stopping.take(job); + m_animatorRoots.take(job); + job->stop(); + delete job; + } + m_deleting.clear(); + + if (m_starting.size()) + m_window->update(); + foreach (QQuickAnimatorProxyJob *proxy, m_starting) { + QAbstractAnimationJob *job = proxy->job(); + job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); qquick_initialize_helper(job, this); + m_animatorRoots[job] = proxy; job->start(); + proxy->startedByController(); } - starting.clear(); + m_starting.clear(); - for (QSet<QQuickAnimatorJob *>::const_iterator it = activeLeafAnimations.constBegin(); - it != activeLeafAnimations.constEnd(); ++it) { - QQuickAnimatorJob *job = *it; + foreach (QQuickAnimatorProxyJob *proxy, m_stopping) { + QAbstractAnimationJob *job = proxy->job(); + job->stop(); + } + m_stopping.clear(); + + foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { if (!job->target()) continue; - else if (deletedSinceLastFrame.contains(job->target())) + else if (m_deletedSinceLastFrame.contains(job->target())) job->targetWasDeleted(); else if (job->isTransform()) { - QQuickTransformAnimatorJob *xform = static_cast<QQuickTransformAnimatorJob *>(*it); + QQuickTransformAnimatorJob *xform = static_cast<QQuickTransformAnimatorJob *>(job); xform->transformHelper()->sync(); } } - deletedSinceLastFrame.clear(); + foreach (QQuickItem *wiped, m_deletedSinceLastFrame) { + QQuickTransformAnimatorJob::Helper *helper = m_transforms.value(wiped); + if (helper) + helper->item = 0; + } + + m_deletedSinceLastFrame.clear(); } void QQuickAnimatorController::afterNodeSync() { - for (QSet<QQuickAnimatorJob *>::const_iterator it = activeLeafAnimations.constBegin(); - it != activeLeafAnimations.constEnd(); ++it) { - QQuickAnimatorJob *job = *it; - if (job->isUniform() && job->target()) { - QQuickUniformAnimatorJob *job = static_cast<QQuickUniformAnimatorJob *>(*it); - job->afterNodeSync(); - } + foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { + if (job->isUniform() && job->target()) + static_cast<QQuickUniformAnimatorJob *>(job)->afterNodeSync(); } } - -void QQuickAnimatorController::startAnimation(QAbstractAnimationJob *job) +void QQuickAnimatorController::animationFinished(QAbstractAnimationJob *job) { - mutex.lock(); - starting << job; - mutex.unlock(); + /* We are currently on the render thread and m_deleting is primarily + * being written on the GUI Thread and read during sync. However, we don't + * need to lock here as this is a direct result of animationDriver->advance() + * which is already locked. For non-threaded render loops no locking is + * needed in any case. + */ + if (!m_deleting.contains(job)) { + QQuickAnimatorProxyJob *proxy = m_animatorRoots[job]; + if (proxy) + QCoreApplication::postEvent(proxy, new QEvent(QEvent::User)); + // else already gone... + } } -void QQuickAnimatorController::animationsStarted() +void QQuickAnimatorController::animationStateChanged(QAbstractAnimationJob *job, + QAbstractAnimationJob::State newState, + QAbstractAnimationJob::State oldState) { - window->update(); + Q_ASSERT(job->isRenderThreadJob()); + QQuickAnimatorJob *animator = static_cast<QQuickAnimatorJob *>(job); + if (newState == QAbstractAnimationJob::Running) { + m_activeLeafAnimations << animator; + animator->setHasBeenRunning(true); + } else if (oldState == QAbstractAnimationJob::Running) { + m_activeLeafAnimations.remove(animator); + } } -void QQuickAnimatorController::animationStateChanged(QAbstractAnimationJob *job, - QAbstractAnimationJob::State newState, - QAbstractAnimationJob::State) + + +void QQuickAnimatorController::requestSync() { - if (newState == QAbstractAnimationJob::Running) - activeRootAnimations << job; - else - activeRootAnimations.remove(job); + // Force a "sync" pass as the newly started animation needs to sync properties from GUI. + m_window->maybeUpdate(); } -bool QQuickAnimatorController::event(QEvent *e) +// These functions are called on the GUI thread. +void QQuickAnimatorController::startJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) { - if ((int) e->type() == StopAnimation) { - QAbstractAnimationJob *job = static_cast<Event *>(e)->job; - mutex.lock(); - starting.removeOne(job); - mutex.unlock(); - job->stop(); - return true; + m_starting[job] = proxy; + requestSync(); +} - } else if ((uint) e->type() == DeleteAnimation) { - QAbstractAnimationJob *job = static_cast<Event *>(e)->job; - mutex.lock(); - starting.removeOne(job); - mutex.unlock(); - job->stop(); - delete job; - return true; - } +void QQuickAnimatorController::stopJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) +{ + m_stopping[job] = proxy; + requestSync(); +} - return QObject::event(e); +void QQuickAnimatorController::deleteJob(QAbstractAnimationJob *job) +{ + lock(); + m_deleting << job; + requestSync(); + unlock(); } QT_END_NAMESPACE diff --git a/src/quick/util/qquickanimatorcontroller_p.h b/src/quick/util/qquickanimatorcontroller_p.h index ab08bf05db..6223a9938f 100644 --- a/src/quick/util/qquickanimatorcontroller_p.h +++ b/src/quick/util/qquickanimatorcontroller_p.h @@ -47,6 +47,7 @@ #include <QtQuick/qquickitem.h> #include <QtCore/qmutex.h> +#include <QtCore/qthread.h> QT_BEGIN_NAMESPACE @@ -55,27 +56,6 @@ class QQuickAnimatorController : public QObject, public QAnimationJobChangeListe Q_OBJECT public: - - enum EventType { - // GUI to RT events - StartAnimation = QEvent::User + 1, - StopAnimation, - DeleteAnimation, - - // RT back to GUI events - AnimationFinished - }; - - class Event : public QEvent { - public: - Event(QAbstractAnimationJob *j, EventType type) - : QEvent(QEvent::Type(type)) - , job(j) - { - } - QAbstractAnimationJob *job; - }; - QQuickAnimatorController(); ~QQuickAnimatorController(); @@ -83,32 +63,35 @@ public: void beforeNodeSync(); void afterNodeSync(); - bool event(QEvent *); + void animationFinished(QAbstractAnimationJob *job); + void animationStateChanged(QAbstractAnimationJob *job, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); - void startAnimation(QAbstractAnimationJob *job); + void requestSync(); - void animationStateChanged(QAbstractAnimationJob *job, - QAbstractAnimationJob::State newState, - QAbstractAnimationJob::State oldState); + // These are called from the GUI thread (the proxy) + void startJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job); + void stopJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job); + void deleteJob(QAbstractAnimationJob *job); + + void lock() { m_mutex.lock(); } + void unlock() { m_mutex.unlock(); } public Q_SLOTS: - void animationsStarted(); void itemDestroyed(QObject *); public: - QList<QAbstractAnimationJob *> starting; - QList<QAbstractAnimationJob *> stopped; - - QSet<QAbstractAnimationJob *> activeRootAnimations; - QSet<QQuickAnimatorJob *> activeLeafAnimations; - - QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> transforms; - - QSet<QQuickItem *> deletedSinceLastFrame; - - QQuickWindow *window; - - QMutex mutex; + // These are manipulated from the GUI thread and should only + // be updated during the sync() phase. + QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_starting; + QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_stopping; + QSet<QAbstractAnimationJob *> m_deleting; + + QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_animatorRoots; + QSet<QQuickAnimatorJob *> m_activeLeafAnimations; + QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> m_transforms; + QSet<QQuickItem *> m_deletedSinceLastFrame; + QQuickWindow *m_window; + QMutex m_mutex; }; QT_END_NAMESPACE diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index fffb9fc65f..fa6f615649 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -72,8 +72,6 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje // be negligiblie compared to animating and re-rendering the scene on the render thread. m_duration = -1; - job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); - QObject *ctx = findAnimationContext(m_animation); if (!ctx) { qWarning("QtQuick: unable to find animation context for RT animation..."); @@ -100,7 +98,7 @@ void QQuickAnimatorProxyJob::deleteJob() { if (m_job) { if (m_controller && m_internalState != State_Starting) - QCoreApplication::postEvent(m_controller, new QQuickAnimatorController::Event(m_job, QQuickAnimatorController::DeleteAnimation)); + m_controller->deleteJob(m_job); else if (m_internalState == State_Starting) delete m_job; m_job = 0; @@ -122,18 +120,15 @@ void QQuickAnimatorProxyJob::updateCurrentTime(int) void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) { if (m_state == Running) { - if (m_controller) { - m_internalState = State_Running; - startOnRenderThread(); - } else { - m_internalState = State_Starting; - } + m_internalState = State_Starting; + if (m_controller) + m_controller->startJob(this, m_job); } else if (newState == Stopped) { syncBackCurrentValues(); if (m_internalState == State_Starting) m_internalState = State_Stopped; else if (m_controller) { - QCoreApplication::postEvent(m_controller, new QQuickAnimatorController::Event(m_job, QQuickAnimatorController::StopAnimation)); + m_controller->stopJob(this, m_job); } } } @@ -143,23 +138,28 @@ void QQuickAnimatorProxyJob::windowChanged(QQuickWindow *window) setWindow(window); } +void QQuickAnimatorProxyJob::controllerWasDeleted() +{ + m_controller = 0; + m_job = 0; +} + void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) { if (!window) { - m_controller = 0; // Stop will trigger syncBackCurrentValues so best to do it before // we delete m_job. stop(); deleteJob(); return; - } - m_controller = QQuickWindowPrivate::get(window)->animationController; - - if (window->openglContext()) - readyToAnimate(); - else - connect(window, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitialized())); + } else if (!m_controller && m_job) { + m_controller = QQuickWindowPrivate::get(window)->animationController; + if (window->openglContext()) + readyToAnimate(); + else + connect(window, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitialized())); + } } void QQuickAnimatorProxyJob::sceneGraphInitialized() @@ -170,36 +170,24 @@ void QQuickAnimatorProxyJob::sceneGraphInitialized() void QQuickAnimatorProxyJob::readyToAnimate() { - if (m_internalState == State_Starting) { - startOnRenderThread(); - } + if (m_internalState == State_Starting) + m_controller->startJob(this, m_job); } -void QQuickAnimatorProxyJob::animationFinished(QAbstractAnimationJob *job) +void QQuickAnimatorProxyJob::startedByController() { - QCoreApplication::postEvent(this, new QQuickAnimatorController::Event(job, QQuickAnimatorController::AnimationFinished)); + m_internalState = State_Running; } bool QQuickAnimatorProxyJob::event(QEvent *e) { - if ((uint) e->type() == QQuickAnimatorController::AnimationFinished) { - // Update the duration of this proxy to the current time and stop it so - // that parent animations can progress gracefully + if (e->type() == QEvent::User) { stop(); return true; } - return QObject::event(e); } -void QQuickAnimatorProxyJob::startOnRenderThread() -{ - m_internalState = State_Running; - // Force a "sync" pass as the newly started animation needs to sync properties from GUI. - m_controller->startAnimation(m_job); - QQuickWindowPrivate::get(m_controller->window)->dirtyItem(0); -} - static void qquick_syncback_helper(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { @@ -216,7 +204,8 @@ static void qquick_syncback_helper(QAbstractAnimationJob *job) void QQuickAnimatorProxyJob::syncBackCurrentValues() { - qquick_syncback_helper(m_job); + if (m_job) + qquick_syncback_helper(m_job); } QQuickAnimatorJob::QQuickAnimatorJob() @@ -236,9 +225,9 @@ QQuickAnimatorJob::QQuickAnimatorJob() qreal QQuickAnimatorJob::value() const { qreal v; - m_controller->mutex.lock(); + m_controller->lock(); v = m_value; - m_controller->mutex.unlock(); + m_controller->unlock(); return v; } @@ -258,21 +247,6 @@ void QQuickAnimatorJob::targetWasDeleted() m_controller = 0; } -void QQuickAnimatorJob::updateState(State newState, State oldState) -{ - if (!m_controller) { - stop(); - return; - } - - if (newState == Running) { - m_controller->activeLeafAnimations << this; - m_hasBeenRunning = true; - } else if (oldState == Running) { - m_controller->activeLeafAnimations.remove(this); - } -} - QQuickTransformAnimatorJob::QQuickTransformAnimatorJob() : m_helper(0) { @@ -282,7 +256,7 @@ QQuickTransformAnimatorJob::QQuickTransformAnimatorJob() QQuickTransformAnimatorJob::~QQuickTransformAnimatorJob() { if (m_helper && --m_helper->ref == 0) { - m_controller->transforms.remove(m_helper->item); + m_controller->m_transforms.remove(m_helper->item); delete m_helper; } } @@ -292,11 +266,11 @@ void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller QQuickAnimatorJob::initialize(controller); if (m_controller) { - m_helper = m_controller->transforms.value(m_target); + m_helper = m_controller->m_transforms.value(m_target); if (!m_helper) { m_helper = new Helper(); m_helper->item = m_target; - m_controller->transforms.insert(m_target, m_helper); + m_controller->m_transforms.insert(m_target, m_helper); QObject::connect(m_target, SIGNAL(destroyed(QObject *)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection); } else { ++m_helper->ref; @@ -307,11 +281,6 @@ void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller } } -QQuickTransformAnimatorJob::Helper::~Helper() -{ -} - - void QQuickTransformAnimatorJob::Helper::sync() { const quint32 mask = QQuickItemPrivate::Position @@ -383,7 +352,7 @@ void QQuickXAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); m_helper->dx = m_value; @@ -400,7 +369,7 @@ void QQuickYAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); m_helper->dy = m_value; @@ -453,7 +422,7 @@ void QQuickOpacityAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); m_opacityNode->setOpacity(m_value); @@ -469,7 +438,7 @@ void QQuickScaleAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); m_helper->scale = m_value; @@ -489,7 +458,7 @@ void QQuickRotationAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); float t = m_easing.valueForProgress(time / (qreal) m_duration); switch (m_direction) { @@ -564,7 +533,7 @@ void QQuickUniformAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); + Q_ASSERT(m_controller->m_window->openglContext()->thread() == QThread::currentThread()); if (!m_node || m_uniformIndex == -1 || m_uniformType == -1) return; diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index bc9c65c347..8aae121106 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -63,7 +63,7 @@ class QQuickShaderEffectNode; class QSGOpacityNode; -class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorProxyJob : public QObject, public QAbstractAnimationJob, public QAnimationJobChangeListener +class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorProxyJob : public QObject, public QAbstractAnimationJob { Q_OBJECT @@ -73,7 +73,10 @@ public: int duration() const { return m_duration; } - virtual void animationFinished(QAbstractAnimationJob *); + QAbstractAnimationJob *job() const { return m_job; } + + void startedByController(); + void controllerWasDeleted(); protected: bool event(QEvent *); @@ -91,7 +94,6 @@ private: void readyToAnimate(); void setWindow(QQuickWindow *window); static QObject *findAnimationContext(QQuickAbstractAnimation *); - void startOnRenderThread(); QQuickAnimatorController *m_controller; QQuickAbstractAnimation *m_animation; @@ -134,6 +136,7 @@ public: bool isUniform() const { return m_isUniform; } bool hasBeenRunning() const { return m_hasBeenRunning; } + void setHasBeenRunning(bool has) { m_hasBeenRunning = has; } qreal value() const; @@ -141,7 +144,6 @@ public: protected: QQuickAnimatorJob(); - void updateState(State newState, State oldState); QQuickItem *m_target; QQuickAnimatorController *m_controller; @@ -180,8 +182,6 @@ public: { } - ~Helper(); - void sync(); void apply(); |