aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickanimatorjob.cpp
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/util/qquickanimatorjob.cpp
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/util/qquickanimatorjob.cpp')
-rw-r--r--src/quick/util/qquickanimatorjob.cpp103
1 files changed, 36 insertions, 67 deletions
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;