aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-09-24 12:51:36 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-26 20:08:19 +0200
commit0150202cc710e580695656fee049bf25091c0ded (patch)
tree217f5fbf792b5d40baeea0916064bb0ac2050b84
parentc40d9f64a6bd9671edc807bc74cf5b73c7465250 (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.cpp15
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp40
-rw-r--r--src/quick/util/qquickanimatorcontroller_p.h6
-rw-r--r--src/quick/util/qquickanimatorjob.cpp67
-rw-r--r--src/quick/util/qquickanimatorjob_p.h6
-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.qml68
-rw-r--r--tests/auto/quick/qquickanimators/qquickanimators.pro14
-rw-r--r--tests/auto/quick/qquickanimators/tst_qquickanimators.cpp73
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)