From 21109eb56758a85832ee5f81d4dd84738c0eed58 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 11 Nov 2019 11:37:42 +0100 Subject: [PATCH 1/5] In case of prefix build, copy qmltypes.prf to build dir Otherwise we cannot use it when compiling QML itself. Change-Id: I79dd77f56ffcb61a89109829824958b1d6bd6583 Reviewed-by: Simon Hausmann --- src/qmltyperegistrar/qmltyperegistrar.pro | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) 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) From c18d261971639fd78868b9a1a63b957b9dc89245 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 11 Nov 2019 13:39:12 +0100 Subject: [PATCH 2/5] qmltyperegistrar: Search for foreign types also in MODULE_BASE_OUTDIR That's where we put the metatypes from the same module in order to be able to access them before installing. Those are generally more recent than the installed ones, therefore prefer them. Change-Id: I823ef53d9b1a39d00d6c75dde14e1942722514a7 Reviewed-by: Simon Hausmann --- src/qmltyperegistrar/qmltypes.prf | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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 \ From 2c6966c775fec86e3c4265cd3a5b204e7e5e183a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 29 Oct 2019 09:45:54 -0500 Subject: [PATCH 3/5] Allow AnimatedSprite to finish on the last frame [ChangeLog][AnimatedSprite] Add finishBehavior to allow a sprite to finish on the last frame. Task-number: QTBUG-59090 Change-Id: Id45e879cdc4905f43e2ac3cb2529181390d47aab Reviewed-by: Mitch Curtis --- src/quick/items/qquickanimatedsprite.cpp | 35 ++++++++++++++++++- src/quick/items/qquickanimatedsprite_p.h | 11 +++++- src/quick/items/qquickanimatedsprite_p_p.h | 5 +-- .../data/finishBehavior.qml | 18 ++++++++++ .../tst_qquickanimatedsprite.cpp | 26 ++++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml 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 @@ -262,6 +262,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() @@ -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/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("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" From 0a649f25813b8c2ecf679db106cb8ec175b9145a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 8 Nov 2019 17:42:28 +0100 Subject: [PATCH 4/5] Fix xmlhttprequest example The "pressed" property belongs to mouseArea, not button. Change-Id: Ib35c520b75e30c2cb9a3a7dee0b482a2209040c8 Reviewed-by: Fabian Kosmale Reviewed-by: Simon Hausmann --- examples/qml/xmlhttprequest/Get.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" } From b6b1d5899415fef3231120c08c56a1dc2e246940 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 Nov 2019 10:57:15 +0100 Subject: [PATCH 5/5] Make QQuickFbo work with the OpenGL backend of QRhi So no matter if Quick goes directly to OpenGL, or via QRhi, QQuickFramebufferObject will still work. Also fix up the fboitem example to use a ShaderEffect that works with both rendering paths. With graphics APIs other than OpenGL the item will be empty, as QQuickFbo is not something we can support there. Task-number: QTBUG-79222 Change-Id: I52177d3a75f619f7075a2fc829573c17031eded1 Reviewed-by: Andy Nichols --- examples/quick/scenegraph/fboitem/fboitem.qrc | 2 ++ examples/quick/scenegraph/fboitem/main.qml | 15 +-------- .../fboitem/shaders/+qsb/checker.frag | Bin 0 -> 1615 bytes .../scenegraph/fboitem/shaders/checker.frag | 14 ++++++++ .../fboitem/shaders/checker_rhi.frag | 22 +++++++++++++ src/quick/items/qquickframebufferobject.cpp | 30 +++++++++++++----- src/quick/items/qquickframebufferobject.h | 3 +- src/quick/items/qquickwindow.cpp | 13 +++++--- 8 files changed, 72 insertions(+), 27 deletions(-) create mode 100644 examples/quick/scenegraph/fboitem/shaders/+qsb/checker.frag create mode 100644 examples/quick/scenegraph/fboitem/shaders/checker.frag create mode 100644 examples/quick/scenegraph/fboitem/shaders/checker_rhi.frag 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 @@ main.qml + shaders/checker.frag + shaders/+qsb/checker.frag 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 0000000000000000000000000000000000000000..5037899d1973e76cd8fdcc506076fafaab6e8759 GIT binary patch literal 1615 zcmV-V2C(@602GCIob6a!Zxcrp-o$YN=8}Y4(^6nVTJQoj_Tmsq8U%zkMWPKN2vv%r zWxYG=Ot9Bxcbz(=c|aBF8;_OxT-u*d^}Ro%Kcp9_QqP$=yE|(e2uM}?fWuzqo9~=C zbLN|!88l7HX__{oX+uw+dE9SzqVVw#>y4IUN4({0u5UM4<6&goW!=SAD{#whwAE(r zCUZ=Vti}reihTnv>a9*R(3*RJU0-Z9z&JLoHakA|T0!$VP#=Vkf2!BG?{dGc@fsqZ zgPBw7c=aZ0)>sfe`LWToqkwl;;O4Rk=@+8LA|`N96w|SR|^u)xrAnr;t=%i71 zH^M0BI1zT;?LgllrK56Ww7pvL8~%QV`%a_dGX0|_i|mFKMs9=Gt`t%{PjjfCRbA$*A2Jol)RRoi z7q-);n>P2$7RV+OfS$-jUtJZxie+PMZGa{BRYOx(RSLG9kOf6hlb@QS>n8J+rsZ2P zcBsR@)zvVv>kLY3Yv-UhJ`{bCs8c!)3=rV%F&URZF{B>xTF@VDXEG2ufQ7v77hyPx zMedg}(Vo#Slq%KA?1$!DwNkE_vvU{Bs#&=-H)}v0wpvPZXc*En_w-`ql)C!#0=O@2 z83L8j;1A*`rMX;?Uexj07I)SN*^Vtu)iPjFC-9LC*)0@6oq3T3lqpL^VyB~kCxV(JlMmaNWR3FRYYyG^LcUfP#XWg}fI*Z7~W{bOmVBr`SjcoHh^4_7g zy;$7VD~r2Vp4N_pJ=iJ{HHf%BMPg~#%aw&lUO-m1Q zVU;8m$;?qjGRoY{I@rcJI)ZJ&a|o{Ql!fK~%qFa~uxjg-*)psqp36La>6Ufv&UGtX zw{dm08n$2WpvS6NMu`_@ST|z6uzCqq%=(8N9xyP1wchJ(g0=0yj+k)30;^TqU``Yc zYGE+5zk&WG4)+8*Ti$RP&n#{!U?xD{!bZCq@s&e;0R#(*U}gn?YlQHq&U7)wGP6rq zzTVt={dME@){K{|7jk`2wdc|kAHSyBE0+uHfH_>0)_HxsEk|g+59WR}XdCk%jPa%& zY~dzrz(D_B2DRR>K7kRsVMq3AdF_=(_64Rd7~Zb(X<1E&*L?G7c_X`jNp>22Rp^)h zIyXEshH4zsb|t&fN!XjBKKH=s3ZF~2R&JHx3{|Sm;>K0mFV4eK!{cB%LT9kJ4Lpk( za7_RY@iE-q!XNHE7%BOZ4p;4v0b8moTN76^0ZPmls+5;t6@=}6Yb#p z5qQHhw+`1^z#r4(8GKk^BcLML7rf3w8S7Ahzm4C#iuHS_Z&*K1<-LTVzi}-+(@(*D zLTF5ukAu}DiZo8+6c?5a!s0m2C^?hy`(%gs@6gU^%FSQE$GTH+l_*cA z$T#Nr9QFAO`Nn*IKsd&0Q29@=J5BZ_#lB4T=N0=3;jw+C#~z=5LuM|?jh(t3==pD~ Nc;_d7{{R32;g8Z~Fzo;U literal 0 HcmV?d00001 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/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 6286a1694a..905241989e 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 */