aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-15 01:02:20 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-15 01:02:20 +0100
commit0ee087f5a5edd7d1aa39fd15e0dc85985320c09a (patch)
treea998054898e2013407f38b4b6ea267d7f912bd21
parentcd78e8cd862a819ae2683ed98a131f2582e18609 (diff)
parentb6b1d5899415fef3231120c08c56a1dc2e246940 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
-rw-r--r--examples/qml/xmlhttprequest/Get.qml2
-rw-r--r--examples/quick/scenegraph/fboitem/fboitem.qrc2
-rw-r--r--examples/quick/scenegraph/fboitem/main.qml15
-rw-r--r--examples/quick/scenegraph/fboitem/shaders/+qsb/checker.fragbin0 -> 1615 bytes
-rw-r--r--examples/quick/scenegraph/fboitem/shaders/checker.frag14
-rw-r--r--examples/quick/scenegraph/fboitem/shaders/checker_rhi.frag22
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.pro12
-rw-r--r--src/qmltyperegistrar/qmltypes.prf13
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp35
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h11
-rw-r--r--src/quick/items/qquickanimatedsprite_p_p.h5
-rw-r--r--src/quick/items/qquickframebufferobject.cpp30
-rw-r--r--src/quick/items/qquickframebufferobject.h3
-rw-r--r--src/quick/items/qquickwindow.cpp13
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml18
-rw-r--r--tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp26
16 files changed, 185 insertions, 36 deletions
diff --git a/examples/qml/xmlhttprequest/Get.qml b/examples/qml/xmlhttprequest/Get.qml
index 1a35d32666..96cec2a99d 100644
--- a/examples/qml/xmlhttprequest/Get.qml
+++ b/examples/qml/xmlhttprequest/Get.qml
@@ -58,7 +58,7 @@ GetForm
mouseArea.onClicked: Utils.makeRequest()
- button.border.width: button.pressed ? 2 : 1
+ button.border.width: mouseArea.pressed ? 2 : 1
text.text: "Request data.xml"
}
diff --git a/examples/quick/scenegraph/fboitem/fboitem.qrc b/examples/quick/scenegraph/fboitem/fboitem.qrc
index 9d9db70654..eeb5c36afd 100644
--- a/examples/quick/scenegraph/fboitem/fboitem.qrc
+++ b/examples/quick/scenegraph/fboitem/fboitem.qrc
@@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/scenegraph/fboitem">
<file>main.qml</file>
+ <file>shaders/checker.frag</file>
+ <file>shaders/+qsb/checker.frag</file>
</qresource>
</RCC>
diff --git a/examples/quick/scenegraph/fboitem/main.qml b/examples/quick/scenegraph/fboitem/main.qml
index 92fa99e847..1f1829deda 100644
--- a/examples/quick/scenegraph/fboitem/main.qml
+++ b/examples/quick/scenegraph/fboitem/main.qml
@@ -67,20 +67,7 @@ Item {
property size pixelSize: Qt.size(width / tileSize, height / tileSize);
- fragmentShader:
- "
- uniform lowp vec4 color1;
- uniform lowp vec4 color2;
- uniform highp vec2 pixelSize;
- varying highp vec2 qt_TexCoord0;
- void main() {
- highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
- if (tc.x != tc.y)
- gl_FragColor = color1;
- else
- gl_FragColor = color2;
- }
- "
+ fragmentShader: "qrc:/scenegraph/fboitem/shaders/checker.frag"
}
Renderer {
diff --git a/examples/quick/scenegraph/fboitem/shaders/+qsb/checker.frag b/examples/quick/scenegraph/fboitem/shaders/+qsb/checker.frag
new file mode 100644
index 0000000000..5037899d19
--- /dev/null
+++ b/examples/quick/scenegraph/fboitem/shaders/+qsb/checker.frag
Binary files differ
diff --git a/examples/quick/scenegraph/fboitem/shaders/checker.frag b/examples/quick/scenegraph/fboitem/shaders/checker.frag
new file mode 100644
index 0000000000..044b3bad58
--- /dev/null
+++ b/examples/quick/scenegraph/fboitem/shaders/checker.frag
@@ -0,0 +1,14 @@
+uniform lowp vec4 color1;
+uniform lowp vec4 color2;
+uniform highp vec2 pixelSize;
+
+varying highp vec2 qt_TexCoord0;
+
+void main()
+{
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
+ if (tc.x != tc.y)
+ gl_FragColor = color1;
+ else
+ gl_FragColor = color2;
+}
diff --git a/examples/quick/scenegraph/fboitem/shaders/checker_rhi.frag b/examples/quick/scenegraph/fboitem/shaders/checker_rhi.frag
new file mode 100644
index 0000000000..1e4131d026
--- /dev/null
+++ b/examples/quick/scenegraph/fboitem/shaders/checker_rhi.frag
@@ -0,0 +1,22 @@
+#version 440
+
+layout(std140, binding = 0) uniform buf {
+ mat4 qt_Matrix;
+ float qt_Opacity;
+
+ vec4 color1;
+ vec4 color2;
+ vec2 pixelSize;
+} ubuf;
+
+layout(location = 0) in vec2 qt_TexCoord0;
+layout(location = 0) out vec4 fragColor;
+
+void main()
+{
+ vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * ubuf.pixelSize));
+ if (tc.x != tc.y)
+ fragColor = ubuf.color1;
+ else
+ fragColor = ubuf.color2;
+}
diff --git a/src/qmltyperegistrar/qmltyperegistrar.pro b/src/qmltyperegistrar/qmltyperegistrar.pro
index 8f4235c015..dff8f00ca3 100644
--- a/src/qmltyperegistrar/qmltyperegistrar.pro
+++ b/src/qmltyperegistrar/qmltyperegistrar.pro
@@ -18,7 +18,15 @@ HEADERS += \
build_integration.files = qmltypes.prf
build_integration.path = $$[QT_HOST_DATA]/mkspecs/features
-prefix_build: INSTALLS += build_integration
-else: COPIES += build_integration
+
+prefix_build {
+ load(qt_build_paths)
+ qmltypes_to_builddir.files = qmltypes.prf
+ qmltypes_to_builddir.path = $$MODULE_BASE_OUTDIR/mkspecs/features
+ COPIES += qmltypes_to_builddir
+ INSTALLS += build_integration
+} else {
+ COPIES += build_integration
+}
load(qt_tool)
diff --git a/src/qmltyperegistrar/qmltypes.prf b/src/qmltyperegistrar/qmltypes.prf
index 4fed3c69c7..ed11ef44cf 100644
--- a/src/qmltyperegistrar/qmltypes.prf
+++ b/src/qmltyperegistrar/qmltypes.prf
@@ -39,8 +39,17 @@ qt_module_deps += $$replace(QT_PRIVATE, -private$, '')
qt_module_deps = $$replace(qt_module_deps, _private$, '')
all_qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends")
foreign_types =
-for(dep, all_qt_module_deps): \
- foreign_types += $$[QT_INSTALL_LIBS]/metatypes/$$lower($$eval(QT.$${dep}.module))_metatypes.json
+for(dep, all_qt_module_deps) {
+ METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))_metatypes.json
+ INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME
+ isEmpty(MODULE_BASE_OUTDIR) {
+ foreign_types += $$INSTALLED_METATYPES
+ } else {
+ MODULE_BASE_METATYPES = $$MODULE_BASE_OUTDIR/lib/metatypes/$$METATYPES_FILENAME
+ exists($$MODULE_BASE_METATYPES): foreign_types += $$MODULE_BASE_METATYPES
+ else: foreign_types += $$INSTALLED_METATYPES
+ }
+}
QML_TYPEREGISTRAR_FLAGS = \
--generate-plugintypes=$$QMLTYPES_FILENAME \
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index 21c09f898d..b285fe56ed 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -263,6 +263,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \qmlproperty enumeration QtQuick::AnimatedSprite::finishBehavior
+
+ The behavior when the animation finishes on its own.
+
+ \value FinishAtInitialFrame
+ When the animation finishes it returns to the initial frame.
+ This is the default behavior.
+
+ \value FinishAtFinalFrame
+ When the animation finishes it stays on the final frame.
+*/
+
+/*!
\qmlmethod int QtQuick::AnimatedSprite::restart()
Stops, then starts the sprite animation.
@@ -381,6 +394,12 @@ int QQuickAnimatedSprite::currentFrame() const
return d->m_curFrame;
}
+QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior() const
+{
+ Q_D(const QQuickAnimatedSprite);
+ return d->m_finishBehavior;
+}
+
bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
{
IS_SIGNAL_CONNECTED(this, QQuickAnimatedSprite, currentFrameChanged, (int));
@@ -704,6 +723,16 @@ void QQuickAnimatedSprite::setCurrentFrame(int arg) //TODO-C: Probably only work
}
}
+void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
+{
+ Q_D(QQuickAnimatedSprite);
+
+ if (d->m_finishBehavior != arg) {
+ d->m_finishBehavior = arg;
+ Q_EMIT finishBehaviorChanged(arg);
+ }
+}
+
void QQuickAnimatedSprite::createEngine()
{
Q_D(QQuickAnimatedSprite);
@@ -838,7 +867,11 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
progress = 0;
}
if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
- frameAt = 0;
+ if (d->m_finishBehavior == FinishAtInitialFrame)
+ frameAt = 0;
+ else
+ frameAt = frameCount() - 1;
+ d->m_curFrame = frameAt;
d->m_running = false;
emit runningChanged(false);
emit finished();
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index 30f64e9def..c28b6ce3af 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -92,6 +92,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
+ Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION 15)
QML_NAMED_ELEMENT(AnimatedSprite)
public:
@@ -101,6 +102,12 @@ public:
};
Q_ENUM(LoopParameters)
+ enum FinishBehavior {
+ FinishAtInitialFrame,
+ FinishAtFinalFrame
+ };
+ Q_ENUM(FinishBehavior)
+
bool running() const;
bool interpolate() const;
QUrl source() const;
@@ -116,6 +123,7 @@ public:
int loops() const;
bool paused() const;
int currentFrame() const;
+ FinishBehavior finishBehavior() const;
Q_SIGNALS:
@@ -135,6 +143,7 @@ Q_SIGNALS:
void frameDurationChanged(int arg);
void loopsChanged(int arg);
void currentFrameChanged(int arg);
+ Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg);
Q_REVISION(12) void finished();
@@ -163,7 +172,7 @@ public Q_SLOTS:
void resetFrameDuration();
void setLoops(int arg);
void setCurrentFrame(int arg);
-
+ void setFinishBehavior(FinishBehavior arg);
private Q_SLOTS:
void createEngine();
diff --git a/src/quick/items/qquickanimatedsprite_p_p.h b/src/quick/items/qquickanimatedsprite_p_p.h
index 3610e58861..fb8faefbee 100644
--- a/src/quick/items/qquickanimatedsprite_p_p.h
+++ b/src/quick/items/qquickanimatedsprite_p_p.h
@@ -57,11 +57,10 @@ QT_REQUIRE_CONFIG(quick_sprite);
#include "qquickitem_p.h"
#include "qquicksprite_p.h"
+#include "qquickanimatedsprite_p.h"
QT_BEGIN_NAMESPACE
-class QQuickAnimatedSprite;
-
class QQuickAnimatedSpritePrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickAnimatedSprite)
@@ -78,6 +77,7 @@ public:
, m_loops(-1)
, m_curLoop(0)
, m_pauseOffset(0)
+ , m_finishBehavior(QQuickAnimatedSprite::FinishAtInitialFrame)
{
}
@@ -93,6 +93,7 @@ public:
int m_loops;
int m_curLoop;
int m_pauseOffset;
+ QQuickAnimatedSprite::FinishBehavior m_finishBehavior;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 190bc6853c..d5550e78b6 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -83,6 +83,11 @@ public:
* Everything that relates to rendering must be located in the
* QQuickFramebufferObject::Renderer class.
*
+ * \warning This class is only functional when Qt Quick is rendering
+ * via OpenGL, either directly or through the \l{Scene Graph
+ * Adaptations}{RHI-based rendering path}. It is not compatible with
+ * other RHI backends, such as, Vulkan or Metal.
+ *
* To avoid race conditions and read/write issues from two threads
* it is important that the renderer and the item never read or
* write shared variables. Communication between the item and the renderer
@@ -109,10 +114,6 @@ public:
* and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
* classes that consume texture providers.
*
- * \warning This class is only suitable when working directly with OpenGL. It
- * is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
- * path}.
- *
* \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
@@ -233,6 +234,13 @@ public Q_SLOTS:
{
if (renderPending) {
renderPending = false;
+
+ const bool needsWrap = QSGRendererInterface::isApiRhiBased(window->rendererInterface()->graphicsApi());
+ if (needsWrap) {
+ window->beginExternalCommands();
+ window->resetOpenGLState();
+ }
+
fbo->bind();
QOpenGLContext::currentContext()->functions()->glViewport(0, 0, fbo->width(), fbo->height());
renderer->render();
@@ -241,6 +249,9 @@ public Q_SLOTS:
if (msDisplayFbo)
QOpenGLFramebufferObject::blitFramebuffer(msDisplayFbo, fbo);
+ if (needsWrap)
+ window->endExternalCommands();
+
markDirty(QSGNode::DirtyMaterial);
emit textureChanged();
}
@@ -270,7 +281,8 @@ public:
static inline bool isOpenGL(QSGRenderContext *rc)
{
QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
- return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
+ return rif && (rif->graphicsApi() == QSGRendererInterface::OpenGL
+ || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
}
/*!
@@ -335,9 +347,11 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode
displayTexture = n->msDisplayFbo->texture();
}
- n->setTexture(window()->createTextureFromId(displayTexture,
- n->fbo->size(),
- QQuickWindow::TextureHasAlphaChannel));
+ QSGTexture *wrapper = window()->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
+ &displayTexture, 0,
+ n->fbo->size(),
+ QQuickWindow::TextureHasAlphaChannel);
+ n->setTexture(wrapper);
}
n->setTextureCoordinatesTransform(d->mirrorVertically ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index db143e48cf..e26c8293a6 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -48,7 +48,8 @@ class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
-// ### Qt 6: To be removed. To be seen if an alternative will need to be introduced.
+// ### Qt 6: Consider what to do here. QQuickFbo supports both direct OpenGL and
+// OpenGL via QRhi, but it cannot function when running with another rhi backend.
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index cb4656874d..9b45750a3b 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -4735,8 +4735,7 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha)
adaptation.
\note This function has no effect when running on the RHI graphics
- abstraction. With the RHI, the functions to call when enqueuing native
- graphics commands are beginExternalCommands() and endExternalCommands().
+ abstraction and the underlying RHI backend is not OpenGL.
\sa QQuickWindow::beforeRendering(), beginExternalCommands(), endExternalCommands()
*/
@@ -4744,7 +4743,7 @@ void QQuickWindow::resetOpenGLState()
{
Q_D(QQuickWindow);
- if (d->rhi || !openglContext())
+ if (!openglContext())
return;
QOpenGLContext *ctx = openglContext();
@@ -4859,7 +4858,13 @@ const QQuickWindow::GraphicsStateInfo &QQuickWindow::graphicsStateInfo()
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
- \sa endExternalCommands()
+ \note When the scenegraph is using the RHI graphics abstraction layer with
+ the OpenGL backend underneath, pay attention to the fact that the OpenGL
+ state in the context can have arbitrary settings, and this function does not
+ perform any resetting of the state back to defaults. Call
+ resetOpenGLState() if that is seen necessary.
+
+ \sa endExternalCommands(), resetOpenGLState()
\since 5.14
*/
diff --git a/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml b/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml
new file mode 100644
index 0000000000..13a0ef4622
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.15
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ AnimatedSprite {
+ objectName: "sprite"
+ loops: 1
+ source: "squarefacesprite.png"
+ frameCount: 6
+ frameDuration: 64
+ width: 160
+ height: 160
+ finishBehavior: AnimatedSprite.FinishAtFinalFrame
+ }
+}
diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
index b5366e2bb9..9f616c56e2 100644
--- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
+++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
@@ -57,6 +57,7 @@ private slots:
void test_changeSourceToSmallerImgKeepingBigFrameSize();
void test_infiniteLoops();
void test_implicitSize();
+ void test_finishBehavior();
};
void tst_qquickanimatedsprite::initTestCase()
@@ -428,6 +429,31 @@ void tst_qquickanimatedsprite::test_infiniteLoops()
QCOMPARE(finishedSpy.count(), 0);
}
+void tst_qquickanimatedsprite::test_finishBehavior()
+{
+ QQuickView window;
+ window.setSource(testFileUrl("finishBehavior.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject());
+
+ QQuickAnimatedSprite* sprite = window.rootObject()->findChild<QQuickAnimatedSprite*>("sprite");
+ QVERIFY(sprite);
+
+ QTRY_VERIFY(sprite->running());
+
+ // correctly stops at last frame
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.wait(2000));
+ QCOMPARE(sprite->running(), false);
+ QCOMPARE(sprite->currentFrame(), 5);
+
+ // correctly starts a second time
+ sprite->start();
+ QTRY_VERIFY(sprite->running());
+ QTRY_COMPARE(sprite->currentFrame(), 5);
+}
+
QTEST_MAIN(tst_qquickanimatedsprite)
#include "tst_qquickanimatedsprite.moc"