diff options
author | Gunnar Sletta <gunnar.sletta@digia.com> | 2013-09-24 12:51:36 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-26 20:08:19 +0200 |
commit | 0150202cc710e580695656fee049bf25091c0ded (patch) | |
tree | 217f5fbf792b5d40baeea0916064bb0ac2050b84 | |
parent | c40d9f64a6bd9671edc807bc74cf5b73c7465250 (diff) |
Allow animators to work properly with multiple windows
Change-Id: I5ba663ba0fa089ea786cf43cb4dfa40cbc955342
Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com>
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 15 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller.cpp | 40 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorcontroller_p.h | 6 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob.cpp | 67 | ||||
-rw-r--r-- | src/quick/util/qquickanimatorjob_p.h | 6 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/Box.qml (renamed from tests/auto/quick/qquickanimators/data/Box.qml) | 0 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_behavior.qml (renamed from tests/auto/quick/qquickanimators/data/tst_behavior.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_mixedparallel.qml (renamed from tests/auto/quick/qquickanimators/data/tst_mixedparallel.qml) | 6 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_mixedsequential.qml (renamed from tests/auto/quick/qquickanimators/data/tst_mixedsequential.qml) | 6 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_nested.qml (renamed from tests/auto/quick/qquickanimators/data/tst_nested.qml) | 16 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_on.qml (renamed from tests/auto/quick/qquickanimators/data/tst_on.qml) | 12 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_opacity.qml (renamed from tests/auto/quick/qquickanimators/data/tst_opacity.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_parallel.qml (renamed from tests/auto/quick/qquickanimators/data/tst_parallel.qml) | 6 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_restart.qml (renamed from tests/auto/quick/qquickanimators/data/tst_restart.qml) | 2 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_rotation.qml (renamed from tests/auto/quick/qquickanimators/data/tst_rotation.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_scale.qml (renamed from tests/auto/quick/qquickanimators/data/tst_scale.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_sequential.qml (renamed from tests/auto/quick/qquickanimators/data/tst_sequential.qml) | 6 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_transformorigin.qml (renamed from tests/auto/quick/qquickanimators/data/tst_transformorigin.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_transition.qml (renamed from tests/auto/quick/qquickanimators/data/tst_transition.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_x.qml (renamed from tests/auto/quick/qquickanimators/data/tst_x.qml) | 4 | ||||
-rw-r--r-- | tests/auto/qmltest/animators/tst_y.qml (renamed from tests/auto/quick/qquickanimators/data/tst_y.qml) | 4 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimators/data/windowWithAnimator.qml | 68 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimators/qquickanimators.pro | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimators/tst_qquickanimators.cpp | 73 |
24 files changed, 268 insertions, 107 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 88bc013306..a2c16fa4dd 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -281,6 +281,7 @@ public: : wm(w) , gl(0) , sg(QSGContext::createDefaultContext()) + , animatorDriver(0) , pendingUpdate(0) , sleeping(false) , syncResultedInChanges(false) @@ -330,6 +331,8 @@ public: QOpenGLContext *gl; QSGContext *sg; + QAnimationDriver *animatorDriver; + uint pendingUpdate; uint sleeping; uint syncResultedInChanges; @@ -375,6 +378,7 @@ bool QSGRenderThread::event(QEvent *e) window.window = se->window; window.size = se->size; m_windows << window; + connect(animatorDriver, SIGNAL(started()), QQuickWindowPrivate::get(se->window)->animationController, SLOT(animationsStarted())); return true; } case WM_Obscure: { @@ -384,6 +388,7 @@ bool QSGRenderThread::event(QEvent *e) if (m_windows.at(i).window == ce->window) { RLDEBUG1(" Render: - removed one..."); m_windows.removeAt(i); + disconnect(animatorDriver, SIGNAL(started()), QQuickWindowPrivate::get(ce->window)->animationController, SLOT(animationsStarted())); break; } } @@ -584,6 +589,9 @@ void QSGRenderThread::syncAndRender() #endif RLDEBUG(" Render: - rendering starting"); + if (animatorDriver->isRunning()) + animatorDriver->advance(); + for (int i=0; i<m_windows.size(); ++i) { Window &w = const_cast<Window &>(m_windows.at(i)); QQuickWindowPrivate *d = QQuickWindowPrivate::get(w.window); @@ -656,6 +664,10 @@ void QSGRenderThread::processEventsAndWaitForMore() void QSGRenderThread::run() { RLDEBUG1(" Render: run()"); + animatorDriver = sg->createAnimationDriver(0); + animatorDriver->install(); + QUnifiedTimer::instance(true)->setConsistentTiming(QSGRenderLoop::useConsistentTiming()); + while (!shouldExit) { if (m_windows.size() > 0) { @@ -682,6 +694,9 @@ void QSGRenderThread::run() Q_ASSERT_X(!gl, "QSGRenderThread::run()", "The OpenGL context should be cleaned up before exiting the render thread..."); RLDEBUG1(" Render: run() completed..."); + + delete animatorDriver; + animatorDriver = 0; } QSGThreadedRenderLoop::QSGThreadedRenderLoop() diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 73d2882c05..344c64d091 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE QQuickAnimatorController::QQuickAnimatorController() : window(0) - , driver(0) { } @@ -61,20 +60,14 @@ QQuickAnimatorController::~QQuickAnimatorController() qDeleteAll(activeRootAnimations); } -void QQuickAnimatorController::advance() +void QQuickAnimatorController::itemDestroyed(QObject *o) { - if (driver && driver->isRunning()) { - // This lock is to prevent conflicts with syncBackCurrentValues - mutex.lock(); - driver->advance(); - mutex.unlock(); - } + deletedSinceLastFrame << (QQuickItem *) o; +} - // The animation system uses a chain of queued connections to - // start the animation driver and these won't get delievered until, - // at best, after this frame. We need to track if animations - // are running here so we can keep on rendering in that case. - bool running = driver && driver->isRunning(); +void QQuickAnimatorController::advance() +{ + bool running = false; for (QSet<QAbstractAnimationJob *>::const_iterator it = activeRootAnimations.constBegin(); !running && it != activeRootAnimations.constEnd(); ++it) { if ((*it)->isRunning()) @@ -97,7 +90,10 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC { if (job->isRenderThreadJob()) { QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); - j->initialize(c); + if (j->target() && c->deletedSinceLastFrame.contains(j->target())) + j->targetWasDeleted(); + else + j->initialize(c); } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) @@ -107,15 +103,6 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC void QQuickAnimatorController::beforeNodeSync() { - if (!driver && window->thread() != window->openglContext()->thread()) { - driver = QQuickWindowPrivate::get(window)->context->createAnimationDriver(this); - connect(driver, SIGNAL(started()), this, SLOT(animationsStarted()), Qt::DirectConnection); - connect(driver, SIGNAL(stopped()), this, SLOT(animationsStopped()), Qt::DirectConnection); - driver->install(); - - QUnifiedTimer::instance(true)->setConsistentTiming(QSGRenderLoop::useConsistentTiming()); - } - // Force a render pass if we are adding new animations // so that advance will be called.. if (starting.size()) @@ -123,11 +110,12 @@ void QQuickAnimatorController::beforeNodeSync() for (int i=0; i<starting.size(); ++i) { QAbstractAnimationJob *job = starting.at(i); - qquick_initialize_helper(job, this); job->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + qquick_initialize_helper(job, this); job->start(); } starting.clear(); + deletedSinceLastFrame.clear(); for (QSet<QQuickAnimatorJob *>::const_iterator it = activeLeafAnimations.constBegin(); it != activeLeafAnimations.constEnd(); ++it) { @@ -157,10 +145,6 @@ void QQuickAnimatorController::startAnimation(QAbstractAnimationJob *job) mutex.unlock(); } -void QQuickAnimatorController::animationsStopped() -{ -} - void QQuickAnimatorController::animationsStarted() { window->update(); diff --git a/src/quick/util/qquickanimatorcontroller_p.h b/src/quick/util/qquickanimatorcontroller_p.h index 1c79e3c493..ab08bf05db 100644 --- a/src/quick/util/qquickanimatorcontroller_p.h +++ b/src/quick/util/qquickanimatorcontroller_p.h @@ -93,7 +93,7 @@ public: public Q_SLOTS: void animationsStarted(); - void animationsStopped(); + void itemDestroyed(QObject *); public: QList<QAbstractAnimationJob *> starting; @@ -104,9 +104,9 @@ public: QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> transforms; - QQuickWindow *window; + QSet<QQuickItem *> deletedSinceLastFrame; - QAnimationDriver *driver; + QQuickWindow *window; QMutex mutex; }; diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index ea8da018b0..5ab54ab733 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -87,8 +87,7 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje QQuickItem *item = qobject_cast<QQuickItem *>(ctx); if (item->window()) setWindow(item->window()); - else - connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(windowChanged(QQuickWindow*))); + connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(windowChanged(QQuickWindow*))); } } @@ -102,7 +101,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)); - else + else if (m_internalState == State_Starting) delete m_job; m_job = 0; } @@ -133,7 +132,7 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, syncBackCurrentValues(); if (m_internalState == State_Starting) m_internalState = State_Stopped; - else { + else if (m_controller) { QCoreApplication::postEvent(m_controller, new QQuickAnimatorController::Event(m_job, QQuickAnimatorController::StopAnimation)); } } @@ -146,13 +145,14 @@ void QQuickAnimatorProxyJob::windowChanged(QQuickWindow *window) void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) { - if (m_controller) { + if (!window) { + m_controller = 0; + // Stop will trigger syncBackCurrentValues so best to do it before + // we delete m_job. stop(); deleteJob(); - m_controller = 0; - } - if (!window) return; + } m_controller = QQuickWindowPrivate::get(window)->animationController; @@ -250,8 +250,19 @@ void QQuickAnimatorJob::initialize(QQuickAnimatorController *controller) m_controller = controller; } +void QQuickAnimatorJob::targetWasDeleted() +{ + m_target = 0; + m_controller = 0; +} + void QQuickAnimatorJob::updateState(State newState, State oldState) { + if (!m_controller) { + stop(); + return; + } + if (newState == Running) { m_controller->activeLeafAnimations << this; } else if (oldState == Running) { @@ -277,15 +288,22 @@ void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller { QQuickAnimatorJob::initialize(controller); - m_helper = m_controller->transforms.value(m_target); - if (!m_helper) { - m_helper = new Helper(); - m_helper->item = m_target; - m_controller->transforms.insert(m_target, m_helper); - } else { - ++m_helper->ref; + if (m_controller) { + m_helper = m_controller->transforms.value(m_target); + if (!m_helper) { + m_helper = new Helper(); + m_helper->item = m_target; + m_controller->transforms.insert(m_target, m_helper); + QObject::connect(m_target, SIGNAL(destroyed(QObject *)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection); + } else { + ++m_helper->ref; + } + m_helper->sync(); } - m_helper->sync(); +} + +QQuickTransformAnimatorJob::Helper::~Helper() +{ } @@ -295,7 +313,8 @@ void QQuickTransformAnimatorJob::Helper::sync() | QQuickItemPrivate::BasicTransform | QQuickItemPrivate::TransformOrigin; - quint32 dirty = mask & QQuickItemPrivate::get(item)->dirtyAttributes; + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + quint32 dirty = mask & d->dirtyAttributes; if (!wasSynced) { dirty = 0xffffffffu; @@ -305,7 +324,7 @@ void QQuickTransformAnimatorJob::Helper::sync() if (dirty == 0) return; - node = QQuickItemPrivate::get(item)->itemNode(); + node = d->itemNode(); if (dirty & QQuickItemPrivate::Position) { dx = item->x(); @@ -350,6 +369,8 @@ void QQuickXAnimatorJob::writeBack() void QQuickXAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); @@ -365,6 +386,8 @@ void QQuickYAnimatorJob::writeBack() void QQuickYAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); @@ -410,6 +433,8 @@ void QQuickOpacityAnimatorJob::writeBack() void QQuickOpacityAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); @@ -424,6 +449,8 @@ void QQuickScaleAnimatorJob::writeBack() void QQuickScaleAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * m_easing.valueForProgress(time / (qreal) m_duration); @@ -442,6 +469,8 @@ extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal void QQuickRotationAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); float t = m_easing.valueForProgress(time / (qreal) m_duration); @@ -510,6 +539,8 @@ void QQuickUniformAnimatorJob::afterNodeSync() void QQuickUniformAnimatorJob::updateCurrentTime(int time) { + if (!m_controller) + return; Q_ASSERT(m_controller->window->openglContext()->thread() == QThread::currentThread()); if (!m_node || m_uniformIndex == -1 || m_uniformType == -1) diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index c6814523c6..44155c1f93 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -126,6 +126,7 @@ public: QEasingCurve easingCurve() const { return m_easing; } void setEasingCurve(const QEasingCurve &curve) { m_easing = curve; } + void targetWasDeleted(); virtual void initialize(QQuickAnimatorController *controller); virtual void writeBack() = 0; @@ -140,7 +141,7 @@ protected: QQuickAnimatorJob(); void updateState(State newState, State oldState); - QPointer<QQuickItem> m_target; + QQuickItem *m_target; QQuickAnimatorController *m_controller; qreal m_from; @@ -164,7 +165,6 @@ public: { Helper() : ref(1) - , item(0) , node(0) , ox(0) , oy(0) @@ -177,6 +177,8 @@ public: { } + ~Helper(); + void sync(); void apply(); diff --git a/tests/auto/quick/qquickanimators/data/Box.qml b/tests/auto/qmltest/animators/Box.qml index cff3e7f929..cff3e7f929 100644 --- a/tests/auto/quick/qquickanimators/data/Box.qml +++ b/tests/auto/qmltest/animators/Box.qml diff --git a/tests/auto/quick/qquickanimators/data/tst_behavior.qml b/tests/auto/qmltest/animators/tst_behavior.qml index b22cc93b09..dfcbcd0620 100644 --- a/tests/auto/quick/qquickanimators/data/tst_behavior.qml +++ b/tests/auto/qmltest/animators/tst_behavior.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "behavior" + name: "animators-behavior" when: box.scale == 2 function test_endresult() { compare(box.scaleChangeCounter, 1); @@ -62,7 +62,7 @@ Item { Box { id: box - Behavior on scale { ScaleAnimator { id: animation; duration: 300; } } + Behavior on scale { ScaleAnimator { id: animation; duration: 100; } } } Timer { diff --git a/tests/auto/quick/qquickanimators/data/tst_mixedparallel.qml b/tests/auto/qmltest/animators/tst_mixedparallel.qml index 9cd28f2493..863affec7b 100644 --- a/tests/auto/quick/qquickanimators/data/tst_mixedparallel.qml +++ b/tests/auto/qmltest/animators/tst_mixedparallel.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "mixedparallel" + name: "animators-mixedparallel" when: !animation.running function test_endresult() { compare(box.rotationChangeCounter, 1); @@ -65,8 +65,8 @@ Item { id: box ParallelAnimation { id: animation - NumberAnimation { target: box; property: "scale"; from: 1; to: 2.0; duration: 1000; } - RotationAnimator { target: box; from: 0; to: 180; duration: 1000; } + NumberAnimation { target: box; property: "scale"; from: 1; to: 2.0; duration: 100; } + RotationAnimator { target: box; from: 0; to: 180; duration: 100; } running: true loops: 1; } diff --git a/tests/auto/quick/qquickanimators/data/tst_mixedsequential.qml b/tests/auto/qmltest/animators/tst_mixedsequential.qml index 4c62bc8018..e514f2c4ab 100644 --- a/tests/auto/quick/qquickanimators/data/tst_mixedsequential.qml +++ b/tests/auto/qmltest/animators/tst_mixedsequential.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "mixedsequential" + name: "animators-mixedsequential" when: !animation.running function test_endresult() { compare(box.rotationChangeCounter, 1); @@ -65,8 +65,8 @@ Item { id: box ParallelAnimation { id: animation - NumberAnimation { target: box; property: "scale"; from: 1; to: 2.0; duration: 500; } - RotationAnimator { target: box; from: 0; to: 180; duration: 500; } + NumberAnimation { target: box; property: "scale"; from: 1; to: 2.0; duration: 100; } + RotationAnimator { target: box; from: 0; to: 180; duration: 100; } running: true loops: 1; } diff --git a/tests/auto/quick/qquickanimators/data/tst_nested.qml b/tests/auto/qmltest/animators/tst_nested.qml index 95cb70cb48..b936a88124 100644 --- a/tests/auto/quick/qquickanimators/data/tst_nested.qml +++ b/tests/auto/qmltest/animators/tst_nested.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "nested" + name: "animators-nested" when: !animation.running function test_endresult() { compare(box.before, 2); @@ -69,18 +69,18 @@ Item { id: animation; ScriptAction { script: box.before++; } ParallelAnimation { - ScaleAnimator { target: box; from: 2.0; to: 1; duration: 500; } - OpacityAnimator { target: box; from: 0; to: 1; duration: 500; } + ScaleAnimator { target: box; from: 2.0; to: 1; duration: 100; } + OpacityAnimator { target: box; from: 0; to: 1; duration: 100; } } - PauseAnimation { duration: 500 } + PauseAnimation { duration: 100 } SequentialAnimation { ParallelAnimation { - XAnimator { target: box; from: 0; to: 100; duration: 500} - RotationAnimator { target: box; from: 0; to: 90; duration: 500 } + XAnimator { target: box; from: 0; to: 100; duration: 100 } + RotationAnimator { target: box; from: 0; to: 90; duration: 100 } } ParallelAnimation { - XAnimator { target: box; from: 100; to: 0; duration: 500 } - RotationAnimator { target: box; from: 90; to: 0; duration: 500 } + XAnimator { target: box; from: 100; to: 0; duration: 100 } + RotationAnimator { target: box; from: 90; to: 0; duration: 100 } } } ScriptAction { script: box.after++; } diff --git a/tests/auto/quick/qquickanimators/data/tst_on.qml b/tests/auto/qmltest/animators/tst_on.qml index e48d7107f9..7930dc5be3 100644 --- a/tests/auto/quick/qquickanimators/data/tst_on.qml +++ b/tests/auto/qmltest/animators/tst_on.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "on" + name: "animators-on" when: !animx.running && !animy.running && !anims.running && !animr.running && !animo.running; @@ -70,10 +70,10 @@ Item { Box { id: box anchors.centerIn: undefined - XAnimator on x { id: animx; from: 0; to: 100; duration: 1000 } - YAnimator on y { id: animy; from: 0; to: 100; duration: 1000 } - ScaleAnimator on scale { id: anims; from: 1; to: 2; duration: 1000 } - RotationAnimator on rotation { id: animr ; from: 0; to: 180; duration: 1000 } - OpacityAnimator on opacity { id: animo; from: 1; to: 0.5; duration: 1000 } + XAnimator on x { id: animx; from: 0; to: 100; duration: 100 } + YAnimator on y { id: animy; from: 0; to: 100; duration: 100 } + ScaleAnimator on scale { id: anims; from: 1; to: 2; duration: 100 } + RotationAnimator on rotation { id: animr ; from: 0; to: 180; duration: 100 } + OpacityAnimator on opacity { id: animo; from: 1; to: 0.5; duration: 100 } } } diff --git a/tests/auto/quick/qquickanimators/data/tst_opacity.qml b/tests/auto/qmltest/animators/tst_opacity.qml index a785b2b3f3..eba1659cc4 100644 --- a/tests/auto/quick/qquickanimators/data/tst_opacity.qml +++ b/tests/auto/qmltest/animators/tst_opacity.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "opacity" + name: "animators-opacity" when: !animation.running function test_endresult() { compare(box.opacityChangeCounter, 1); @@ -69,7 +69,7 @@ Item { target: box from: 1; to: 0.5 - duration: 1000 + duration: 100 running: true } } diff --git a/tests/auto/quick/qquickanimators/data/tst_parallel.qml b/tests/auto/qmltest/animators/tst_parallel.qml index 3105d3c2dd..8fde73804f 100644 --- a/tests/auto/quick/qquickanimators/data/tst_parallel.qml +++ b/tests/auto/qmltest/animators/tst_parallel.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "parallel" + name: "animators-parallel" when: !animation.running function test_endresult() { compare(box.rotationChangeCounter, 1); @@ -66,8 +66,8 @@ Item { id: box ParallelAnimation { id: animation - ScaleAnimator { target: box; from: 1; to: 2.0; duration: 1000; } - RotationAnimator { target: box; from: 0; to: 180; duration: 1000; } + ScaleAnimator { target: box; from: 1; to: 2.0; duration: 100; } + RotationAnimator { target: box; from: 0; to: 180; duration: 100; } running: true } } diff --git a/tests/auto/quick/qquickanimators/data/tst_restart.qml b/tests/auto/qmltest/animators/tst_restart.qml index 42c7a33a8b..588c81ade5 100644 --- a/tests/auto/quick/qquickanimators/data/tst_restart.qml +++ b/tests/auto/qmltest/animators/tst_restart.qml @@ -51,7 +51,7 @@ Item { TestCase { id: testcase - name: "restart" + name: "animators-restart" when: root.restartCount == 0 && animation.running == false; function test_endresult() { compare(box.scale, 2); diff --git a/tests/auto/quick/qquickanimators/data/tst_rotation.qml b/tests/auto/qmltest/animators/tst_rotation.qml index 517cf59456..384a3738bb 100644 --- a/tests/auto/quick/qquickanimators/data/tst_rotation.qml +++ b/tests/auto/qmltest/animators/tst_rotation.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "rotation" + name: "animators-rotation" when: !animation.running function test_endresult() { compare(box.rotationChangeCounter, 1); @@ -66,7 +66,7 @@ Item { target: box from: 0; to: 180 - duration: 1000 + duration: 100 easing.type: Easing.InOutBack running: true } diff --git a/tests/auto/quick/qquickanimators/data/tst_scale.qml b/tests/auto/qmltest/animators/tst_scale.qml index 6fd4668684..5df0cb5cea 100644 --- a/tests/auto/quick/qquickanimators/data/tst_scale.qml +++ b/tests/auto/qmltest/animators/tst_scale.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "scale" + name: "animators-scale" when: !animation.running function test_endresult() { compare(box.scaleChangeCounter, 1); @@ -67,7 +67,7 @@ Item { target: box from: 1; to: 2.0 - duration: 1000 + duration: 100 easing.type: Easing.InOutCubic running: true } diff --git a/tests/auto/quick/qquickanimators/data/tst_sequential.qml b/tests/auto/qmltest/animators/tst_sequential.qml index 2bb14f8acf..397133ea7d 100644 --- a/tests/auto/quick/qquickanimators/data/tst_sequential.qml +++ b/tests/auto/qmltest/animators/tst_sequential.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "parallel" + name: "animators-parallel" when: !animation.running function test_endresult() { compare(box.rotationChangeCounter, 1); @@ -66,8 +66,8 @@ Item { id: box SequentialAnimation { id: animation - ScaleAnimator { target: box; from: 1; to: 2.0; duration: 1000; } - RotationAnimator { target: box; from: 0; to: 180; duration: 1000; } + ScaleAnimator { target: box; from: 1; to: 2.0; duration: 100; } + RotationAnimator { target: box; from: 0; to: 180; duration: 100; } running: true } } diff --git a/tests/auto/quick/qquickanimators/data/tst_transformorigin.qml b/tests/auto/qmltest/animators/tst_transformorigin.qml index 0211d0305d..2cc57f81a2 100644 --- a/tests/auto/quick/qquickanimators/data/tst_transformorigin.qml +++ b/tests/auto/qmltest/animators/tst_transformorigin.qml @@ -58,7 +58,7 @@ Item { TestCase { id: testCase - name: "transformorigin" + name: "animators-transformorigin" when: timer.triggered function test_endresult() { @@ -151,7 +151,7 @@ Item { transformOrigin: root.origins[index]; - ScaleAnimator { target: box; from: 1; to: 5.5; duration: 1000; running: true; } + ScaleAnimator { target: box; from: 1; to: 5.5; duration: 100; running: true; } } } } diff --git a/tests/auto/quick/qquickanimators/data/tst_transition.qml b/tests/auto/qmltest/animators/tst_transition.qml index 8e21a6537e..d2ccf600ff 100644 --- a/tests/auto/quick/qquickanimators/data/tst_transition.qml +++ b/tests/auto/qmltest/animators/tst_transition.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testcase - name: "transition" + name: "animators-transition" when: box.scale == 2 function test_endresult() { compare(box.scaleChangeCounter, 1); @@ -74,7 +74,7 @@ Item { transitions: [ Transition { - ScaleAnimator { duration: 200; } + ScaleAnimator { duration: 100; } } ] diff --git a/tests/auto/quick/qquickanimators/data/tst_x.qml b/tests/auto/qmltest/animators/tst_x.qml index 70ecf96346..d789b5c434 100644 --- a/tests/auto/quick/qquickanimators/data/tst_x.qml +++ b/tests/auto/qmltest/animators/tst_x.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "x" + name: "animators-x" when: !animation.running function test_endresult() { compare(box.xChangeCounter, 1); @@ -70,7 +70,7 @@ Item { target: box from: 0; to: 100 - duration: 1000 + duration: 100 running: true } } diff --git a/tests/auto/quick/qquickanimators/data/tst_y.qml b/tests/auto/qmltest/animators/tst_y.qml index 428d42a6c3..a595023919 100644 --- a/tests/auto/quick/qquickanimators/data/tst_y.qml +++ b/tests/auto/qmltest/animators/tst_y.qml @@ -49,7 +49,7 @@ Item { TestCase { id: testCase - name: "y" + name: "animators-y" when: !animation.running function test_endresult() { compare(box.yChangeCounter, 1); @@ -70,7 +70,7 @@ Item { target: box from: 0; to: 100 - duration: 1000 + duration: 100 running: true } } diff --git a/tests/auto/quick/qquickanimators/data/windowWithAnimator.qml b/tests/auto/quick/qquickanimators/data/windowWithAnimator.qml new file mode 100644 index 0000000000..d49b91da83 --- /dev/null +++ b/tests/auto/quick/qquickanimators/data/windowWithAnimator.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Window 2.0 + +Window { + width: 200 + height: 200 + + visible: true + property bool animationDone: rect.scale == 1; + + Rectangle { + id: rect + anchors.centerIn: parent + + width: 100 + height: 100 + color: "red" + scale: 0 + + ScaleAnimator on scale { + id: animation; + from: 0 + to: 1 + duration: 1000 + } + } +} diff --git a/tests/auto/quick/qquickanimators/qquickanimators.pro b/tests/auto/quick/qquickanimators/qquickanimators.pro index 4fa0438e41..4ff2471fde 100644 --- a/tests/auto/quick/qquickanimators/qquickanimators.pro +++ b/tests/auto/quick/qquickanimators/qquickanimators.pro @@ -1,14 +1,6 @@ -QT += core-private gui-private qml-private -TEMPLATE=app +QT += core-private gui-private qml-private quick-private testlib TARGET=tst_qquickanimators - -CONFIG += qmltestcase +CONFIG += testcase +macx: CONFIG -= app_bundle SOURCES += tst_qquickanimators.cpp -TESTDATA = data/* - -OTHER_FILES += \ - data/tst_scale.qml \ - data/Scale.qml \ - tst_on.qml \ - data/tst_nested.qml diff --git a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp index f3f982091f..3311fa6bf2 100644 --- a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp +++ b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp @@ -39,6 +39,75 @@ ** ****************************************************************************/ -#include <QtQuickTest/quicktest.h> +#include <qtest.h> + +#include <QtQuick> +#include <private/qquickanimator_p.h> + +#include <QtQml> + +class tst_Animators: public QObject +{ + Q_OBJECT + +private slots: + void testMultiWinAnimator_data(); + void testMultiWinAnimator(); +}; + +void tst_Animators::testMultiWinAnimator_data() +{ + QTest::addColumn<int>("count"); + + QTest::newRow("1") << 1; + QTest::newRow("10") << 10; +} + +void tst_Animators::testMultiWinAnimator() +{ + QFETCH(int, count); + + QQmlEngine engine; + QQmlComponent component(&engine, "data/windowWithAnimator.qml"); + + QList<QQuickWindow *> windows; + for (int i=0; i<count; ++i) { + QQuickWindow *win = qobject_cast<QQuickWindow *>(component.create()); + windows << win; + + // As the windows are all the same size, if they are positioned at the + // same place only the top-most one will strictly be "exposed" and rendering + // for all the others will be disabled. Move the windows a little bit + // to ensure they are exposed and actually rendering. + if (i > 0) { + QPoint pos = win->position(); + if (pos == windows.first()->position()) + pos += QPoint(10 * i, 10 * i); + win->setPosition(pos); + } + } + + // let all animations run their course... + while (true) { + QTest::qWait(200); + bool allDone = true; + for (int i=0; i<count; ++i) { + QQuickWindow *win = windows.at(i); + allDone = win->isExposed() && win->property("animationDone").toBool(); + } + + if (allDone) { + for (int i=0; i<count; ++i) { + QQuickWindow *win = windows.at(i); + delete win; + } + break; + } + } + QVERIFY(true); +} + +#include "tst_qquickanimators.moc" + +QTEST_MAIN(tst_Animators) -QUICK_TEST_MAIN(qquickanimators) |