aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
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();