aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-11-01 15:49:33 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-06 19:19:34 +0100
commit63e0ffb32a4a432ed57f31388fabff89b05cb8cc (patch)
tree8c4927b577bb47789b85368d55ebee2544938352 /src/quick
parente0458defdfadeb3a1fb92eb12b14fce9191fe1ee (diff)
Refactored Animator internals
Change the design from posting events for starting and stopping to use the scene graph's existing 'sync' point. This gives much higher predictability and makes both ownership and cleanup cleaner and also reduces intermediate states while events are waiting to be delivered. Task-number: QTBUG-34137 Change-Id: I069ac22acbddaa47925b8172ba98ac340fe9bf8d Reviewed-by: Michael Brasser <michael.brasser@live.com>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickwindow.cpp2
-rw-r--r--src/quick/items/qquickwindow.h2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp13
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp185
-rw-r--r--src/quick/util/qquickanimatorcontroller_p.h63
-rw-r--r--src/quick/util/qquickanimatorjob.cpp103
-rw-r--r--src/quick/util/qquickanimatorjob_p.h12
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();