aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Chuan <ouchuanm@outlook.com>2020-04-02 22:24:22 +0800
committerWang Chuan <ouchuanm@outlook.com>2020-04-07 21:53:12 +0800
commit2cefb096768b1d8d30b4d0705a622f1c7d041344 (patch)
tree70de419292e2591729f98fc7e52ab912bd80d248
parent5050ebd7a5c9d181af8bc037aaed05ff3f9b0ca6 (diff)
OpacityAnimator: apply opacity animation to the first frame in SG
When using OpacityAnimator, an opacity node will be created and inserted into nodes tree to perform opacity animation. However, since the default value of opacity node is 1, the opacity animation will start from 1 even if we set it from 0 to 1. Fixes this issue by updating the value of opacity just after creating a new opacity node. Fixes: QTBUG-79199 Change-Id: I2e462f0c56892fda040836ffde6685145769e60c Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/quick/util/qquickanimatorjob.cpp1
-rw-r--r--tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml20
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp37
3 files changed, 58 insertions, 0 deletions
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index a9caedec4f..84480ddd18 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -582,6 +582,7 @@ void QQuickOpacityAnimatorJob::postSync()
}
d->extra.value().opacityNode = m_opacityNode;
+ updateCurrentTime(0);
}
Q_ASSERT(m_opacityNode);
}
diff --git a/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml b/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml
new file mode 100644
index 0000000000..bfb8211706
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/opacityAnimationFromZero.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.14
+import QtQuick.Window 2.14
+
+Window {
+ width: 640
+ height: 480
+ Rectangle {
+ id: rect
+ width: 200
+ height: 200
+ color: "black"
+ OpacityAnimator {
+ target: rect
+ from: 0
+ to: 1
+ duration: 1000
+ running: true
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 48f779a490..9bd0cd777f 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -112,6 +112,7 @@ private slots:
void replacingTransitions();
void animationJobSelfDestruction();
void fastFlickingBug();
+ void opacityAnimationFromZero();
};
#define QTIMED_COMPARE(lhs, rhs) do { \
@@ -1774,6 +1775,42 @@ void tst_qquickanimations::fastFlickingBug()
}
}
+void tst_qquickanimations::opacityAnimationFromZero()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
+ // not easy to verify this in threaded render loop
+ // since it's difficult to capture the first frame when scene graph
+ // is renderred in another thread
+ qputenv("QSG_RENDER_LOOP", "basic");
+ auto cleanup = qScopeGuard([]() { qputenv("QSG_RENDER_LOOP", ""); });
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("opacityAnimationFromZero.qml"));
+ QScopedPointer<QQuickWindow> win(qobject_cast<QQuickWindow*>(c.create()));
+ if (!c.errors().isEmpty())
+ qDebug() << c.errorString();
+ QVERIFY(win);
+ win->setTitle(QTest::currentTestFunction());
+ win->show();
+ QVERIFY(QTest::qWaitForWindowExposed(win.data()));
+
+ QImage img;
+ bool firstFrameSwapped = false;
+ QObject::connect(win.get(), &QQuickWindow::frameSwapped, win.get(), [&win, &img, &firstFrameSwapped]() {
+ if (firstFrameSwapped)
+ return;
+ else
+ firstFrameSwapped = true;
+ img = win->grabWindow();
+ if (img.width() < win->width())
+ QSKIP("Skipping due to grabWindow not functional");
+ });
+ QTRY_VERIFY(!img.isNull() && img.pixel(100, 100) > qRgb(10, 10, 10));
+}
+
QTEST_MAIN(tst_qquickanimations)
#include "tst_qquickanimations.moc"