aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/configure.json21
-rw-r--r--src/quick/dependencies.json1
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata.cpp2
-rw-r--r--src/quick/doc/qtquick.qdocconf5
-rw-r--r--src/quick/doc/snippets/cmake-macros/examples.cmake2
-rw-r--r--src/quick/doc/snippets/qml/listview/ReusableDelegate.qml82
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc250
-rw-r--r--src/quick/doc/src/examples.qdoc1
-rw-r--r--src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc37
-rw-r--r--src/quick/handlers/qquickmultipointhandler_p.h1
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp19
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp9
-rw-r--r--src/quick/handlers/qquickwheelhandler.cpp25
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp13
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h5
-rw-r--r--src/quick/items/qquickevents.cpp133
-rw-r--r--src/quick/items/qquickevents_p_p.h11
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp3
-rw-r--r--src/quick/items/qquickgraphicsinfo.cpp1
-rw-r--r--src/quick/items/qquickgraphicsinfo_p.h1
-rw-r--r--src/quick/items/qquickgridview.cpp4
-rw-r--r--src/quick/items/qquickimage.cpp8
-rw-r--r--src/quick/items/qquickimage_p_p.h13
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--src/quick/items/qquickitem_p.h6
-rw-r--r--src/quick/items/qquickitemsmodule.cpp202
-rw-r--r--src/quick/items/qquickitemview.cpp130
-rw-r--r--src/quick/items/qquickitemview_p.h12
-rw-r--r--src/quick/items/qquickitemview_p_p.h23
-rw-r--r--src/quick/items/qquicklistview.cpp126
-rw-r--r--src/quick/items/qquicklistview_p.h2
-rw-r--r--src/quick/items/qquickmousearea.cpp8
-rw-r--r--src/quick/items/qquickmousearea_p.h1
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp48
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h4
-rw-r--r--src/quick/items/qquickpainteditem.cpp1
-rw-r--r--src/quick/items/qquickpathview.cpp5
-rw-r--r--src/quick/items/qquickscreen.cpp3
-rw-r--r--src/quick/items/qquickscreen_p.h4
-rw-r--r--src/quick/items/qquickshadereffect.cpp239
-rw-r--r--src/quick/items/qquickstateoperations.cpp5
-rw-r--r--src/quick/items/qquicktableview.cpp177
-rw-r--r--src/quick/items/qquicktableview_p_p.h23
-rw-r--r--src/quick/items/qquicktextinput.cpp7
-rw-r--r--src/quick/items/qquickview.cpp9
-rw-r--r--src/quick/items/qquickwindow.cpp28
-rw-r--r--src/quick/items/qquickwindow_p.h13
-rw-r--r--src/quick/qtquick.tracepoints48
-rw-r--r--src/quick/qtquick2.cpp11
-rw-r--r--src/quick/quick.pro9
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp23
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp33
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h109
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp1
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp3
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp9
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp13
-rw-r--r--src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp57
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.h6
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp9
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp1
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp66
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h5
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp60
-rw-r--r--src/quick/scenegraph/qsgrhisupport_p.h3
-rw-r--r--src/quick/scenegraph/qsgrhitextureglyphcache.cpp2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp107
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp20
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext.vert4
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext_core.vert4
-rw-r--r--src/quick/scenegraph/shaders/styledtext.vert3
-rw-r--r--src/quick/scenegraph/shaders/styledtext_core.vert3
-rw-r--r--src/quick/scenegraph/shaders/textmask.vert3
-rw-r--r--src/quick/scenegraph/shaders/textmask_core.vert3
-rw-r--r--src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsbbin1873 -> 1537 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsbbin1754 -> 1399 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsbbin1753 -> 1405 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsbbin1280 -> 909 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsbbin2209 -> 1820 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsbbin2209 -> 1851 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsbbin2210 -> 1814 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsbbin2319 -> 1905 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsbbin2340 -> 1951 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsbbin2334 -> 1914 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsbbin1883 -> 1538 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsbbin2048 -> 1709 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsbbin1883 -> 1542 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.frag.qsbbin1149 -> 917 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.vert.qsbbin1597 -> 1334 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsbbin3314 -> 2898 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsbbin3675 -> 3288 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsbbin3304 -> 2909 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsbbin2411 -> 2015 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsbbin3028 -> 2675 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsbbin2412 -> 2024 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsbbin1173 -> 967 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsbbin1791 -> 1500 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsbbin2549 -> 2162 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.vert3
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsbbin2728 -> 2599 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsbbin1859 -> 1436 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.frag.qsbbin1622 -> 1307 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.vert.qsbbin1860 -> 1561 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsbbin838 -> 700 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsbbin3682 -> 3390 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsbbin1299 -> 1073 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsbbin4350 -> 3957 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.frag.qsbbin1908 -> 1571 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.vert.qsbbin2437 -> 2127 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.frag.qsbbin853 -> 737 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.vert.qsbbin1510 -> 1279 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.frag.qsbbin2210 -> 1805 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.vert3
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.vert.qsbbin2460 -> 2209 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsbbin1631 -> 1212 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.frag.qsbbin1873 -> 1533 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.vert3
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.vert.qsbbin2142 -> 1961 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.frag.qsbbin1618 -> 1302 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.vert.qsbbin1865 -> 1561 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsbbin851 -> 700 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsbbin1837 -> 1542 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.frag.qsbbin1877 -> 1569 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.vert.qsbbin2099 -> 1762 bytes
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture.cpp5
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp19
-rw-r--r--src/quick/scenegraph/util/qsgrhiatlastexture.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp104
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h70
-rw-r--r--src/quick/util/qquickbehavior.cpp2
-rw-r--r--src/quick/util/qquickpath.cpp8
-rw-r--r--src/quick/util/qquickpixmapcache.cpp8
-rw-r--r--src/quick/util/qquickstyledtext.cpp18
-rw-r--r--src/quick/util/qquickutilmodule.cpp131
-rw-r--r--src/quick/util/qquickutilmodule_p.h66
-rw-r--r--src/quick/util/qquickvaluetypes.cpp1
-rw-r--r--src/quick/util/util.pri2
153 files changed, 1362 insertions, 1490 deletions
diff --git a/src/quick/configure.json b/src/quick/configure.json
index 0cb1e7470b..6cd3099a20 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -3,14 +3,15 @@
"depends": [
"core-private",
"qml-private",
+ "gui",
"gui-private",
"qmlmodels-private"
],
+ "condition": "module.gui",
"testDir": "../../config.tests",
"commandline": {
"options": {
- "d3d12": "boolean",
"quick-animatedimage": "boolean",
"quick-canvas": "boolean",
"quick-designer": "boolean",
@@ -26,24 +27,7 @@
}
},
- "tests": {
- "d3d12": {
- "label": "Direct3D 12",
- "type": "compile",
- "test": "d3d12"
- }
- },
-
"features": {
- "d3d12": {
- "label": "Direct3D 12",
- "purpose": "Provides a Direct3D 12 backend for the scenegraph.",
- "section": "Qt Quick",
- "condition": "tests.d3d12",
- "output": [
- "publicFeature"
- ]
- },
"quick-animatedimage": {
"label": "AnimatedImage item",
"purpose": "Provides the AnimatedImage item.",
@@ -200,7 +184,6 @@
{
"section": "Qt Quick",
"entries": [
- "d3d12",
"quick-animatedimage",
"quick-canvas",
"quick-designer",
diff --git a/src/quick/dependencies.json b/src/quick/dependencies.json
new file mode 100644
index 0000000000..fe51488c70
--- /dev/null
+++ b/src/quick/dependencies.json
@@ -0,0 +1 @@
+[]
diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp
index 8989de711e..6b39f5157b 100644
--- a/src/quick/designer/qquickdesignercustomobjectdata.cpp
+++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp
@@ -192,7 +192,7 @@ void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context, const
QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property);
if (binding && !(hasValidResetBinding(propertyName) && getResetBinding(propertyName) == binding)) {
- binding->setEnabled(false, nullptr);
+ binding->setEnabled(false, {});
}
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 91458527dd..0d46e3408d 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -38,7 +38,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtquick/qtquick.tags
-depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns
+depends += qtcore qtqml qtqmlmodels qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns
headerdirs += ..\
../../quick \
@@ -70,6 +70,9 @@ sourcedirs += ../../plugins
#exclude certain directories
excludedirs += ../../imports/models \
+ ../../imports/labsmodels \
+ ../../imports/testlib \
+ ../../imports/workerscript \
../../imports/statemachine
excludefiles += ../util/qquickpropertychanges_p.h
diff --git a/src/quick/doc/snippets/cmake-macros/examples.cmake b/src/quick/doc/snippets/cmake-macros/examples.cmake
index 8ca6180f9b..cecc59debc 100644
--- a/src/quick/doc/snippets/cmake-macros/examples.cmake
+++ b/src/quick/doc/snippets/cmake-macros/examples.cmake
@@ -3,4 +3,4 @@ find_package(Qt5 COMPONENTS Quick QmlImportScanner)
add_executable(myapp main.cpp)
target_link_libraries(myapp Qt5::Quick)
qt5_import_qml_plugins(myapp)
-#! [qt5_import_plugins]
+#! [qt5_import_qml_plugins]
diff --git a/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
new file mode 100644
index 0000000000..050572d5f2
--- /dev/null
+++ b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+//![0]
+Component {
+ id: listViewDelegate
+ Rectangle {
+ width: 100
+ height: 50
+
+ ListView.onPooled: rotationAnimation.pause()
+ ListView.onReused: rotationAnimation.resume()
+
+ Rectangle {
+ id: rect
+ anchors.centerIn: parent
+ width: 40
+ height: 5
+ color: "green"
+
+ RotationAnimation {
+ id: rotationAnimation
+ target: rect
+ duration: (Math.random() * 2000) + 200
+ from: 0
+ to: 359
+ running: true
+ loops: Animation.Infinite
+ }
+ }
+ }
+}
+//![0]
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index e83aa39734..86292921a6 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -34,11 +34,10 @@
Originally, Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) to
parse the scene graph and render the results to a render target
-From Qt 5.8 onwards, Qt Quick also supports rendering in software, with OpenVG,
-and with Direct3D 12. This is realized by having additional scene graph
-adaptations, either in form of plugins (d3d12, openvg) or built-in to the Qt
-Quick library (software). The default adaptation continues to rely directly on
-OpenGL.
+From Qt 5.8 onwards, Qt Quick also supports rendering in software, and with
+OpenVG. This is realized by having additional scene graph adaptations, either
+in form of plugins (openvg) or built-in to the Qt Quick library
+(software). The default adaptation continues to rely directly on OpenGL.
From Qt 5.14 onwards, the default adaptation gains the option of rendering via
a graphics abstraction layer, the Qt Rendering Hardware Interface (RHI),
@@ -52,10 +51,10 @@ appropriate for the various graphics APIs.
\target Switching Between the Adaptation Used by the Application
\section1 Switch Between Adaptations in Your Application
-Unlike \c software or \c d3d12, the RHI-based renderer is not an additional
+Unlike \c software, the RHI-based renderer is not an additional
adaptation, and is always built-in. As of Qt 5.14 it can be enabled by setting
the environment variable \c{QSG_RHI} to a non-zero value before starting the
-application, or via \l QQuickWindow::setScenegraphBackend() in combination with
+application, or via \l QQuickWindow::setSceneGraphBackend() in combination with
\l QSGRendererInterface::GraphicsApi. When none of this is done, OpenGL is used
directly like in previous versions.
@@ -75,8 +74,6 @@ The following backends are supported:
different than the ones listed below.
\li Software - Request with the \c{"software"} string or the QSGRendererInterface::Software
enum value.
- \li Direct3D 12 - Request with the \c{"d3d12"} string or the QSGRendererInterface::Direct3D12
- enum value.
\li OpenVG - Request with the \c{"openvg"} string or the QSGRendererInterface::OpenVG enum
value.
\endlist
@@ -111,12 +108,6 @@ The Software adaptation is an alternative renderer for \l{Qt Quick} 2 that uses
engine to render the contents of the scene graph. For more details, see
\l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation}.
-\section1 Direct3D 12 (experimental)
-
-The Direct3D 12 adaptation is an alternative renderer for \l{Qt Quick} 2 when running on Windows
-10, both for Win32 and UWP applications. For more details, see
-\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation}.
-
\section1 OpenVG
The OpenVG adaptation is an alternative renderer for \l{Qt Quick} 2 that renders the contents of
@@ -172,235 +163,6 @@ behavior, which is only present in the default OpenGL adaptation.
/*!
-\title Qt Quick Direct3D 12 Adaptation
-\page qtquick-visualcanvas-adaptations-d3d12.html
-
-The Direct3D 12 adaptation for Windows 10, both in Win32 (\c windows platform plugin) and in UWP
-(\c winrt platform plugin), is shipped as a dynamically loaded plugin. This adaptation doesn't work
-on earlier Windows versions. Building this plugin is enabled automatically, whenever the necessary
-D3D and DXGI develpoment files are present. In practice, this currently means Visual Studio 2015
-and newer.
-
-The adaptation is available both in normal, OpenGL-enabled Qt builds, and also when Qt is
-configured with \c{-no-opengl}. However, it's never the default, meaning that the user or the
-application has to explicitly request it by setting the \c{QT_QUICK_BACKEND} environment variable
-to \c{d3d12} or by calling QQuickWindow::setSceneGraphBackend().
-
-\section2 Motivation
-
-This experimental adaptation is the first Qt Quick backend that focuses on a modern, lower-level
-graphics API in combination with a windowing system interface that's different from the traditional
-approaches used in combination with OpenGL.
-
-This adaptation also allows better integration with Windows, as Direct3D is the primary
-vendor-supported solution. Consequently, there are fewer problems anticipated with drivers,
-operations like window resizes, and special events like graphics device loss caused by device
-resets or graphics driver updates.
-
-Performance-wise, the general expectation is a somewhat lower CPU usage compared to OpenGL, due to
-lower driver overhead, and a higher GPU utilization with less idle time wastage. The backend
-doesn't heavily utilize threads yet, which means there are opportunities for further improvements
-in the future, for example to further optimize image loading.
-
-The D3D12 backend also introduces support for pre-compiled shaders. All the backend's own shaders
-(used by the built-in materials on which the Rectangle, Image, Text, and other QML types are built
-with) are compiled to D3D shader bytecode when you compile Qt. Applications using ShaderEffect
-items can choose to ship bytecode either in regular files, via the Qt resource system, or use
-High Level Shading Language for DirectX (HLSL) source strings. Unlike OpenGL, the compilation for
-HLSL is properly threaded, meaning shader compilation won't block the application and its user
-interface.
-
-\section2 Graphics Adapters
-
-The plugin does not necessarily require hardware acceleration. You can also use WARP, the Direct3D
-software rasterizer. By default, the first adapter providing hardware acceleration is chosen. To
-override this and use another graphics adapter or to force the use of the software rasterizer, set
-the \c{QT_D3D_ADAPTER_INDEX} environment variable to the index of the adapter. The adapters
-discovered are printed at startup when \c{QSG_INFO} or the \c{qt.scenegraph.general} logging
-category is enabled.
-
-\section2 Troubleshooting
-
-If you encounter issues, always set the \c{QSG_INFO} and \c{QT_D3D_DEBUG} environment variables
-to \c 1, to get debug and warning messages printed on the debug output. \c{QT_D3D_DEBUG} enables
-the Direct3D debug layer.
-
-\note The debug layer shouldn't be enabled in production use, since it can significantly impact
-performance (CPU load) due to increased API overhead.
-
-\section2 Render Loops
-
-By default, the D3D12 adaptation uses a single-threaded render loop similar to OpenGL's \c windows
-render loop. A threaded variant is also available, that you can request by setting the
-\c{QSG_RENDER_LOOP} environment variable to \c threaded. However, due to conceptual limitations in
-DXGI, the windowing system interface, the threaded loop is prone to deadlocks when multiple
-QQuickWindow or QQuickView instances are shown. Consequently, for the time being, the default is
-the single-threaded loop. This means that with the D3D12 backend, applications are expected to move
-their work from the main (GUI) thread out to worker threads, instead of expecting Qt to keep the
-GUI thread responsive and suitable for heavy, blocking operations.
-
-For more information see \l{qtquick-visualcanvas-scenegraph.html}{Qt Quick Scene Graph} for
-details on render loops and
-\l{https://docs.microsoft.com/en-us/windows/desktop/direct3darticles/dxgi-best-practices#multithreading-and-dxgi}{Multithreading and DXGI}
-regarding the issues with multithreading.
-
-\section2 Renderer
-
-The scene graph renderer in the D3D12 adaptation currently doesn't perform any batching. This is
-less of an issue, unlike OpenGL, because state changes don't present any problems in the first
-place. The simpler renderer logic can also lead to lower CPU overhead in some cases. The trade-offs
-between the various approaches are currently under research.
-
-\section2 Shader Effects
-
-The ShaderEffect QML type is fully functional with the D3D12 adaptation as well. However, the
-interpretation of the fragmentShader and vertexShader properties is different than with OpenGL.
-
-With D3D12, these strings can either be a URL for a local file, a file in the resource system,
-or an HLSL source string. Using a URL for a local file or a file in the resource system
-indicates that the file in question contains pre-compiled D3D shader bytecode generated by the
-\c fxc tool, or, alternatively, HLSL source code. The type of file is detected automatically.
-This means that the D3D12 backend supports all options from GraphicsInfo.shaderCompilationType
-and GraphicsInfo.shaderSourceType.
-
-Unlike OpenGL, whenever you open a file, there is a QFileSelector with the extra \c hlsl selector
-used. This provides easy creation of ShaderEffect items that are functional across both backends,
-for example by placing the GLSL source code into \c{shaders/effect.frag}, the HLSL source code or
-- preferably - pre-compiled bytecode into \c{shaders/+hlsl/effect.frag}, while simply writing
-\c{fragmentShader: "qrc:shaders/effect.frag"} in QML. For more details, see ShaderEffect.
-
-\section2 Multisample Render Targets
-
-The Direct3D 12 adaptation ignores the QSurfaceFormat set on the QQuickWindow or QQuickView, or
-set via QSurfaceFormat::setDefaultFormat(), with two exceptions: QSurfaceFormat::samples() and
-QSurfaceFormat::alphaBufferSize() are still taken into account. When the sample value is greater
-than 1, multisample offscreen render targets will be created with the specified sample count at
-the maximum supported quality level. The backend automatically performs resolving into the
-non-multisample swapchain buffers after each frame.
-
-\section2 Semi-transparent Windows
-
-When the alpha channel is enabled either via QQuickWindow::setDefaultAlphaBuffer() or by setting
-alphaBufferSize to a non-zero value in the window's QSurfaceFormat or in the global format managed
-by QSurfaceFormat::setDefaultFormat(), the D3D12 backend will create a swapchain for composition
-and go through DirectComposition. This is necessary, because the mandatory flip model swapchain
-wouldn't support transparency otherwise.
-
-Therefore, it's important not to unneccessarily request an alpha channel. When the alphaBufferSize
-is 0 or the default -1, all these extra steps can be avoided and the traditional window-based
-swapchain is sufficient.
-
-On WinRT, this isn't relevant because the backend there always uses a composition swapchain which
-is associated with the ISwapChainPanel that backs QWindow on that platform.
-
-\section2 Mipmaps
-
-Mipmap generation is supported and handled transparently to the applications via a built-in compute
-shader. However, at the moment, this feature is experimental and only supports power-of-two images.
-Textures of other size will work too, but this involves a QImage-based scaling on the CPU first.
-Therefore, avoid enabling mipmapping for Non-Power-Of-Two (NPOT) images whenever possible.
-
-\section2 Image Formats
-
-When creating textures via C++ scene graph APIs like QQuickWindow::createTextureFromImage(), 32-bit
-formats won't involve any conversion, they'll map directly to the corresponding \c{R8G8B8A8_UNORM}
-or \c{B8G8R8A8_UNORM} format. Everything else will trigger a QImage-based format conversion on the
-CPU first.
-
-\section2 Unsupported Features
-
-Particles and some other OpenGL-dependent utilities, like QQuickFramebufferObject, are currently
-not supported.
-
-Like with \l{qtquick-visualcanvas-adaptations-software.html}{Software adaptation}, text is always
-rendered using the native method. Distance field-based text rendering is currently not implemented.
-
-The shader sources in the \l {Qt Graphical Effects} module have not been ported to any format other
-than the OpenGL 2.0 compatible one, meaning that the QML types provided by that module are currently
-not functional with the D3D12 backend.
-
-Texture atlases are currently not in use.
-
-The renderer may lack support for certain minor features, such as drawing points and lines with a
-width other than 1.
-
-Custom Qt Quick items using custom scene graph nodes can be problematic because materials are
-inherently tied to the graphics API. Therefore, only items that use the utility rectangle and image
-nodes are functional across all adaptations.
-
-QQuickWidget and its underlying OpenGL-based compositing architecture is not supported. If you need
-to mix with QWidget-based user interfaces, use QWidget::createWindowContainer() to embed the native
-window of the QQuickWindow or QQuickView.
-
-Finally, rendering via QSGEngine and QSGAbstractRenderer is not feasible with the D3D12 adaptation
-at the moment.
-
-\section2 Related APIs
-
-To integrate custom Direct3D 12 rendering, use QSGRenderNode in combination with
-QSGRendererInterface. This approach doesn't rely on OpenGL contexts or API specifics like
-framebuffers, and allows exposing the graphics device and command buffer from the adaptation. It's
-not necessarily suitable for easy integration of all types of content, in particular true 3D, so
-it'll likely get complemented by an alternative to QQuickFramebufferObject in future releases.
-
-To perform runtime decisions based on the adaptation, use QSGRendererInterface from C++ and
-GraphicsInfo from QML. They can also be used to check the level of shader support: shading
-language, compilation approach, and so on.
-
-When creating custom items, use the new QSGRectangleNode and QSGImageNode classes. These replace
-the now deprecated QSGSimpleRectNode and QSGSimpleTextureNode. Unlike their predecessors, these new
-classes are interfaces, and implementations are created via the QQuickWindow::createRectangleNode()
-and QQuickWindow::createImageNode() factory functions.
-
-\section2 Advanced Configuration
-
-The D3D12 adaptation can keep multiple frames in flight, similar to modern game engines. This is
-somewhat different from the traditional "render - swap - wait for vsync" model and allows for
-better GPU utilization at the expense of higher resource use. This means that the renderer will
-be a number of frames ahead of what is displayed on the screen.
-
-For a discussion of flip model swap chains and the typical configuration parameters, refer to
-\l{https://software.intel.com/en-us/articles/sample-application-for-direct3d-12-flip-model-swap-chains}
-{Sample Application for Direct3D 12 Flip Model Swap Chains}.
-
-Vertical synchronization is always enabled, meaning Present() is invoked with an interval of 1.
-
-The configuration can be changed by setting the following environment variables:
-
-\table
- \header
- \li Environment variable
- \li Description
- \row
- \li \c{QT_D3D_BUFFER_COUNT}
- \li The number of swap chain buffers in range 2 - 4. The default value is 3.
- \row
- \li \c{QT_D3D_FRAME_COUNT}
- \li The number of frames prepared without blocking in range 1 - 4. The default value is 2.
- Present() starts blocking after queuing 3 frames (regardless of
- \c{QT_D3D_BUFFER_COUNT}), unless the waitable object is in use. Every additional frame
- increases GPU resource usage since geometry and constant buffer data needs to be
- duplicated, and involves more bookkeeping on the CPU side.
- \row
- \li \c{QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY}
- \li The frame latency in range 1 - 16. The default value is 0 (disabled).
- Changes the limit for Present() and triggers a wait for an available swap chain buffer
- when beginning each frame. For a detailed discussion, see the article linked above.
- \note Currently, this behavior is experimental.
- \row
- \li \c{QT_D3D_BLOCKING_PRESENT}
- \li The time the CPU should wait, a non-zero value, for the GPU to finish its work after
- each call to Present(). The default value is 0 (disabled). This behavior effectively
- kills all parallelism but makes the behavior resemble the traditional
- swap-blocks-for-vsync model, which can be useful in some special cases. However, this
- behavior is not the same as setting the frame count to 1 because that still avoids
- blocking after Present(), and may only block when starting to prepare the next frame
- (or may not block at all depending on the time gap between the frames).
-\endtable
-
-*/
-
-/*!
\title Qt Quick OpenVG Adaptation
\page qtquick-visualcanvas-adaptations-openvg.html
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index a913af47c1..9a1308440f 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -177,6 +177,7 @@ Creator.
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
\li \l{Scene Graph - Direct3D 11 Under QML}{Direct3D 11 Under QML}
\li \l{Scene Graph - Vulkan Under QML}{Vulkan Under QML}
+ \li \l{Scene Graph - Vulkan Texture Import}{Vulkan Texture Import}
\li \l{Scene Graph - Custom Rendering with QSGRenderNode}{Render Node}
\li \l{Scene Graph - Painted Item}{Painted Item}
\li \l{Scene Graph - Graph}{Graph}
diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
index f4a1616943..abfff7cc11 100644
--- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
@@ -402,6 +402,43 @@ property MyMenu optionsMenu
For information on performance in QML and Qt Quick,
see \l {Performance Considerations And Suggestions}.
+\section1 Prefer Declarative Bindings Over Imperative Assignments
+
+In QML, it's possible to use imperative JavaScript code to perform tasks
+such as responding to input events, send data over a network, and so on.
+Imperative code has an important place in QML, but it's also important
+to be aware of when not to use it.
+
+For example, consider the following imperative assignment:
+
+\code
+Rectangle {
+ Component.onCompleted: color = "red"
+}
+\endcode
+
+This has the following disadvantages:
+
+\list
+\li It's slow. The color property will first be evaluated with a
+ default-constructed value, and then again with "red" later on.
+\li It delays errors that could be found at build time to run time, slowing
+ down the development process.
+\li It overwrites any declarative binding that was in place. In most cases this
+ is intended, but sometimes it can be unintentional.
+ See \l {Debugging overwriting of bindings} for more information.
+\li It interferes with tooling; Qt Quick Designer, for example, doesn't support
+ JavaScript.
+\endlist
+
+The code can be rewritten to be a declarative binding instead:
+
+\code
+Rectangle {
+ color: "red"
+}
+\endcode
+
\section1 Tools and Utilities
For information on useful tools and utilies that make working with QML and
diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h
index 480f69035b..c0751aa5c5 100644
--- a/src/quick/handlers/qquickmultipointhandler_p.h
+++ b/src/quick/handlers/qquickmultipointhandler_p.h
@@ -81,7 +81,6 @@ public:
signals:
void minimumPointCountChanged();
void maximumPointCountChanged();
- void marginChanged();
void centroidChanged();
protected:
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 884ebd3b86..c498c96454 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -268,8 +268,25 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
} else if ((d->grabPermissions & CanTakeOverFromItems)) {
QQuickItem * existingItemGrabber = point->grabberItem();
if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && point->pointerEvent()->asPointerMouseEvent()) ||
- (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent())))
+ (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent()))) {
allowed = true;
+ // If the handler wants to steal the exclusive grab from an Item, the Item can usually veto
+ // by having its keepMouseGrab flag set. But an exception is if that Item is a parent that
+ // normally filters events (such as a Flickable): it needs to be possible for e.g. a
+ // DragHandler to operate on an Item inside a Flickable. Flickable is aggressive about
+ // grabbing on press (for fear of missing updates), but DragHandler uses a passive grab
+ // at first and then expects to be able to steal the grab later on. It cannot respect
+ // Flickable's wishes in that case, because then it would never have a chance.
+ if (existingItemGrabber->keepMouseGrab() &&
+ !(existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem()))) {
+ QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(parentItem()->window());
+ if (winPriv->isDeliveringTouchAsMouse() && point->pointId() == winPriv->touchMouseId) {
+ qCDebug(lcPointerHandlerGrab) << this << "wants to grab touchpoint" << point->pointId()
+ << "but declines to steal grab from touch-mouse grabber with keepMouseGrab=true" << existingItemGrabber;
+ allowed = false;
+ }
+ }
+ }
}
}
} else {
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index 272ebe6b63..f3674d6fa9 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -132,17 +132,16 @@ bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
}
break;
case QQuickEventPoint::Stationary:
- // Never react in any way when the point hasn't moved.
- // In autotests, the point's position may not even be correct, because
- // QTest::touchEvent(window, touchDevice).stationary(1)
- // provides no opportunity to give a position, so it ends up being random.
+ // If the point hasn't moved since last time, the return value should be the same as last time.
+ // If we return false here, QQuickPointerHandler::handlePointerEvent() will call setActive(false).
+ ret = point->pointId() == this->point().id();
break;
}
// If this is the grabber, returning false from this function will cancel the grab,
// so onGrabChanged(this, CancelGrabExclusive, point) and setPressed(false) will be called.
// But when m_gesturePolicy is DragThreshold, we don't get an exclusive grab, but
// we still don't want to be pressed anymore.
- if (!ret && point->pointId() == this->point().id() && point->state() != QQuickEventPoint::Stationary)
+ if (!ret && point->pointId() == this->point().id())
setPressed(false, true, point);
return ret;
}
diff --git a/src/quick/handlers/qquickwheelhandler.cpp b/src/quick/handlers/qquickwheelhandler.cpp
index 90e4fef97e..16f38af962 100644
--- a/src/quick/handlers/qquickwheelhandler.cpp
+++ b/src/quick/handlers/qquickwheelhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -49,6 +49,7 @@ Q_LOGGING_CATEGORY(lcWheelHandler, "qt.quick.handler.wheel")
/*!
\qmltype WheelHandler
\instantiates QQuickWheelHandler
+ \inherits SinglePointHandler
\inqmlmodule QtQuick
\ingroup qtquick-input-handlers
\brief Handler for the mouse wheel.
@@ -71,7 +72,7 @@ Q_LOGGING_CATEGORY(lcWheelHandler, "qt.quick.handler.wheel")
\snippet pointerHandlers/handlerFlick.qml 0
- Alternatively if \l targetProperty is not set or \l target is null,
+ Alternatively, if \l property is not set or \l target is null,
WheelHandler will not automatically manipulate anything; but the
\l rotation property can be used in a binding to manipulate another
property, or you can implement \c onWheel and handle the wheel event
@@ -79,15 +80,16 @@ Q_LOGGING_CATEGORY(lcWheelHandler, "qt.quick.handler.wheel")
WheelHandler handles only a rotating mouse wheel by default.
Optionally it can handle smooth-scrolling events from touchpad gestures,
- by setting \l acceptedDevices to \c{PointerDevice.Mouse | PointerDevice.TouchPad}.
+ by setting \l {QtQuick::PointerDeviceHandler::}{acceptedDevices} to
+ \c{PointerDevice.Mouse | PointerDevice.TouchPad}.
\note Some non-mouse hardware (such as a touch-sensitive Wacom tablet, or
a Linux laptop touchpad) generates real wheel events from gestures.
WheelHandler will respond to those events as wheel events regardless of the
- setting of the \l acceptedDevices property.
+ setting of the \l {QtQuick::PointerDeviceHandler::}{acceptedDevices}
+ property.
- \sa MouseArea
- \sa Flickable
+ \sa MouseArea, Flickable
*/
QQuickWheelHandler::QQuickWheelHandler(QQuickItem *parent)
@@ -125,13 +127,13 @@ void QQuickWheelHandler::setOrientation(Qt::Orientation orientation)
\qmlproperty bool QtQuick::WheelHandler::invertible
Whether or not to reverse the direction of property change if
- \l QQuickPointerScrollEvent::inverted is true. The default is \c true.
+ QQuickPointerScrollEvent::inverted is true. The default is \c true.
If the operating system has a "natural scrolling" setting that causes
scrolling to be in the same direction as the finger movement, then if this
property is set to \c true, and WheelHandler is directly setting a property
on \l target, the direction of movement will correspond to the system setting.
- If this property is set to \l false, it will invert the \l rotation so that
+ If this property is set to \c false, it will invert the \l rotation so that
the direction of motion is always the same as the direction of finger movement.
*/
bool QQuickWheelHandler::isInvertible() const
@@ -498,6 +500,13 @@ void QQuickWheelHandler::timerEvent(QTimerEvent *event)
}
}
+/*!
+ \qmlsignal QtQuick::WheelHandler::wheel(PointerScrollEvent event)
+
+ This signal is emitted every time this handler receives a \l QWheelEvent:
+ that is, every time the wheel is moved or the scrolling gesture is updated.
+*/
+
QQuickWheelHandlerPrivate::QQuickWheelHandlerPrivate()
: QQuickSinglePointHandlerPrivate()
{
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index c150e4efa2..2da01e9151 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -433,6 +433,19 @@ void QQuickAccessibleAttached::setRole(QAccessible::Role role)
}
}
+bool QQuickAccessibleAttached::wasNameExplicitlySet() const
+{
+ return m_nameExplicitlySet;
+}
+
+// Allows types to attach an accessible name to an item as a convenience,
+// so long as the user hasn't done so themselves.
+void QQuickAccessibleAttached::setNameImplicitly(const QString &name)
+{
+ setName(name);
+ m_nameExplicitlySet = false;
+}
+
QQuickAccessibleAttached *QQuickAccessibleAttached::qmlAttachedProperties(QObject *obj)
{
return new QQuickAccessibleAttached(obj);
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 678c1361ba..b7254d6686 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -122,7 +122,10 @@ public:
return QString();
return m_name;
}
+
+ bool wasNameExplicitlySet() const;
void setName(const QString &name) {
+ m_nameExplicitlySet = true;
if (name != m_name) {
m_name = name;
Q_EMIT nameChanged();
@@ -130,6 +133,7 @@ public:
QAccessible::updateAccessibility(&ev);
}
}
+ void setNameImplicitly(const QString &name);
QString description() const { return m_description; }
void setDescription(const QString &description)
@@ -220,6 +224,7 @@ private:
QAccessible::State m_state;
QAccessible::State m_stateExplicitlySet;
QString m_name;
+ bool m_nameExplicitlySet = false;
QString m_description;
static QMetaMethod sigPress;
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 89340dd992..03280e4c1f 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -448,7 +448,7 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::WheelEvent::inverted
+ \qmlproperty bool QtQuick::WheelEvent::inverted
Returns whether the delta values delivered with the event are inverted.
@@ -1431,6 +1431,135 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
return nullptr;
}
+
+/*!
+ \qmltype PointerScrollEvent
+ \instantiates QQuickPointerScrollEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about a scrolling event, such as from a mouse wheel.
+
+ \sa WheelHandler
+*/
+
+/*!
+ \internal
+ \class QQuickPointerScrollEvent
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::PointerScrollEvent::device
+
+ This property holds the device that generated the event.
+*/
+
+/*!
+ \qmlproperty int QtQuick::PointerScrollEvent::buttons
+
+ This property holds the mouse buttons pressed when the wheel event was generated.
+
+ It contains a bitwise combination of:
+ \list
+ \li \l {Qt::LeftButton} {Qt.LeftButton}
+ \li \l {Qt::RightButton} {Qt.RightButton}
+ \li \l {Qt::MiddleButton} {Qt.MiddleButton}
+ \endlist
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerScrollEvent::modifiers
+
+ This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} keys
+ that were pressed immediately before the event occurred.
+
+ It contains a bitwise combination of the following flags:
+ \value Qt.NoModifier
+ No modifier key is pressed.
+ \value Qt.ShiftModifier
+ A Shift key on the keyboard is pressed.
+ \value Qt.ControlModifier
+ A Ctrl key on the keyboard is pressed.
+ \value Qt.AltModifier
+ An Alt key on the keyboard is pressed.
+ \value Qt.MetaModifier
+ A Meta key on the keyboard is pressed.
+ \value Qt.KeypadModifier
+ A keypad button is pressed.
+
+ For example, to react to a Shift key + Left mouse button click:
+ \qml
+ Item {
+ TapHandler {
+ onTapped: {
+ if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
+ doSomething();
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlproperty point QtQuick::PointerScrollEvent::angleDelta
+
+ This property holds the distance that the wheel is rotated in wheel degrees.
+ The x and y cordinate of this property holds the delta in horizontal and
+ vertical orientation.
+
+ A positive value indicates that the wheel was rotated up/right;
+ a negative value indicates that the wheel was rotated down/left.
+
+ Most mouse types work in steps of 15 degrees, in which case the delta value is a
+ multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
+*/
+
+/*!
+ \qmlproperty point QtQuick::PointerScrollEvent::pixelDelta
+
+ This property holds the delta in screen pixels and is available in platforms that
+ have high-resolution trackpads, such as \macos.
+ The x and y coordinates of this property hold the delta in horizontal and
+ vertical orientation. The value should be used directly to scroll content on screen.
+
+ For platforms without high-resolution touchpad support, pixelDelta will
+ always be (0,0), and angleDelta should be used instead.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::hasAngleDelta
+
+ Returns whether the \l angleDelta property has a non-null value.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::hasPixelDelta
+
+ Returns whether the \l pixelDelta property has a non-null value.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::inverted
+
+ Returns whether the delta values delivered with the event are inverted.
+
+ Normally, a vertical wheel will produce a PointerScrollEvent with positive delta
+ values if the top of the wheel is rotating away from the hand operating it.
+ Similarly, a horizontal wheel movement will produce a PointerScrollEvent with
+ positive delta values if the top of the wheel is moved to the left.
+
+ However, on some platforms this is configurable, so that the same
+ operations described above will produce negative delta values (but with the
+ same magnitude). In a QML component (such as a tumbler or a slider) where
+ it is appropriate to synchronize the movement or rotation of an item with
+ the direction of the wheel, regardless of the system settings, the wheel
+ event handler can use the inverted property to decide whether to negate the
+ \l angleDelta or \l pixelDelta values.
+
+ \note Many platforms provide no such information. On such platforms,
+ \c inverted always returns false.
+*/
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 5acf98d471..4615ce43d2 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -90,7 +90,7 @@ class QQuickKeyEvent : public QObject
public:
QQuickKeyEvent()
- : event(QEvent::None, 0, nullptr)
+ : event(QEvent::None, 0, { })
{}
void reset(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
@@ -144,12 +144,11 @@ public:
QQuickMouseEvent()
: _buttons(Qt::NoButton), _modifiers(Qt::NoModifier)
, _wasHeld(false), _isClick(false), _accepted(false)
- , _flags(Qt::MouseEventFlags(nullptr))
{}
void reset(qreal x, qreal y, Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false,
- Qt::MouseEventFlags flags = nullptr)
+ Qt::MouseEventFlags flags = { })
{
_x = x;
_y = y;
@@ -602,6 +601,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
Q_PROPERTY(bool hasPixelDelta READ hasPixelDelta CONSTANT)
Q_PROPERTY(bool inverted READ isInverted CONSTANT)
+ QML_NAMED_ELEMENT(PointerScrollEvent)
+ QML_UNCREATABLE("PointerScrollEvent is only available via the WheelHandler::wheel signal.")
+ QML_ADDED_IN_MINOR_VERSION(14)
+
public:
QQuickPointerScrollEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
: QQuickSinglePointEvent(parent, device) { }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index d9ec7de611..8ade5b7e37 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -316,7 +316,7 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr
{
Q_Q(QQuickFlickable);
if (item == contentItem) {
- Qt::Orientations orient = nullptr;
+ Qt::Orientations orient;
if (change.xChange())
orient |= Qt::Horizontal;
if (change.yChange())
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index df61ee853d..a3d04f5dd3 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -78,7 +78,6 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_mgr(nullptr)
, m_fragNeedsUpdate(true)
, m_vertNeedsUpdate(true)
- , m_dirty(nullptr)
{
qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type");
for (int i = 0; i < NShader; ++i)
@@ -311,7 +310,7 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui
m_dirty &= ~QSGShaderEffectNode::DirtyShaderGeometry;
}
- m_dirty = nullptr;
+ m_dirty = {};
for (int i = 0; i < NShader; ++i) {
m_dirtyConstants[i].clear();
m_dirtyTextures[i].clear();
diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp
index 8f6f4386fb..adf620b256 100644
--- a/src/quick/items/qquickgraphicsinfo.cpp
+++ b/src/quick/items/qquickgraphicsinfo.cpp
@@ -95,7 +95,6 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
\li GraphicsInfo.Unknown - the default value when no active scenegraph is associated with the item
\li GraphicsInfo.Software - Qt Quick's software renderer based on QPainter with the raster paint engine
\li GraphicsInfo.OpenGL - OpenGL or OpenGL ES
- \li GraphicsInfo.Direct3D12 - Direct3D 12
\li GraphicsInfo.OpenVG - OpenVG
\li GraphicsInfo.OpenGLRhi - OpenGL on top of QRhi, a graphics abstraction layer
\li GraphicsInfo.Direct3D11Rhi - Direct3D 11 on top of QRhi, a graphics abstraction layer
diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h
index 066a419c37..aa7d15f72d 100644
--- a/src/quick/items/qquickgraphicsinfo_p.h
+++ b/src/quick/items/qquickgraphicsinfo_p.h
@@ -85,7 +85,6 @@ public:
Unknown = QSGRendererInterface::Unknown,
Software = QSGRendererInterface::Software,
OpenGL = QSGRendererInterface::OpenGL,
- Direct3D12 = QSGRendererInterface::Direct3D12,
OpenVG = QSGRendererInterface::OpenVG,
OpenGLRhi = QSGRendererInterface::OpenGLRhi,
Direct3D11Rhi = QSGRendererInterface::Direct3D11Rhi,
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index e69e9cff46..5f6c194bcf 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -497,7 +497,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex += count;
if (modelIndex >= model->count())
modelIndex = model->count() - 1;
@@ -576,7 +576,7 @@ void QQuickGridViewPrivate::removeItem(FxViewItem *item)
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
} else {
- releaseItem(item);
+ releaseItem(item, QQmlDelegateModel::NotReusable);
}
}
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 840cfe15da..fccacdcce8 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -76,14 +76,8 @@ QSGTexture *QQuickImageTextureProvider::texture() const {
}
QQuickImagePrivate::QQuickImagePrivate()
- : fillMode(QQuickImage::Stretch)
- , paintedWidth(0)
- , paintedHeight(0)
- , pixmapChanged(false)
+ : pixmapChanged(false)
, mipmap(false)
- , hAlign(QQuickImage::AlignHCenter)
- , vAlign(QQuickImage::AlignVCenter)
- , provider(nullptr)
{
}
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index e2c467c311..1c4ba88655 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -80,19 +80,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate
public:
QQuickImagePrivate();
-
- QQuickImage::FillMode fillMode;
- qreal paintedWidth;
- qreal paintedHeight;
void setImage(const QImage &img);
void setPixmap(const QQuickPixmap &pixmap);
bool pixmapChanged : 1;
bool mipmap : 1;
- QQuickImage::HAlignment hAlign;
- QQuickImage::VAlignment vAlign;
+ QQuickImage::HAlignment hAlign = QQuickImage::AlignHCenter;
+ QQuickImage::VAlignment vAlign = QQuickImage::AlignVCenter;
+ QQuickImage::FillMode fillMode = QQuickImage::Stretch;
- QQuickImageTextureProvider *provider;
+ qreal paintedWidth = 0;
+ qreal paintedHeight = 0;
+ QQuickImageTextureProvider *provider = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 4c20b7e2e1..8454010ee9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2074,10 +2074,10 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
in the GPU equal to \c {width x height x 4}. In memory constrained
configurations, large layers should be used with care.
- In the QPainter / QWidget world, it is some times favorable to
+ In the QPainter / QWidget world, it is sometimes favorable to
cache complex content in a pixmap, image or texture. In Qt Quick,
because of the techniques already applied by the \l {Qt Quick
- Scene Graph OpenGL Renderer} {scene graph renderer}, this will in most
+ Scene Graph Default Renderer} {scene graph renderer}, this will in most
cases not be the case. Excessive draw calls are already reduced
because of batching and a cache will in most cases end up blending
more pixels than the original content. The overhead of rendering
@@ -8812,7 +8812,7 @@ QQuickItemPrivate::ExtraData::ExtraData()
effectRefCount(0), hideRefCount(0),
recursiveEffectRefCount(0),
opacityNode(nullptr), clipNode(nullptr), rootNode(nullptr),
- acceptedMouseButtons(nullptr), origin(QQuickItem::Center),
+ origin(QQuickItem::Center),
transparentForPositioner(false)
{
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 7c3325fd90..baef37a0ff 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -336,7 +336,7 @@ public:
struct ChangeListener {
using ChangeTypes = QQuickItemPrivate::ChangeTypes;
- ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = nullptr)
+ ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = { })
: listener(l)
, types(t)
, gTypes(QQuickGeometryChange::All)
@@ -533,7 +533,7 @@ public:
void refWindow(QQuickWindow *);
void derefWindow();
- QQuickItem *subFocusItem;
+ QPointer<QQuickItem> subFocusItem;
void updateSubFocusItem(QQuickItem *scope, bool focus);
QTransform windowToItemTransform() const;
@@ -937,7 +937,7 @@ private:
Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
{
return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
- (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(nullptr)));
+ (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{}));
}
QSGContext *QQuickItemPrivate::sceneGraphContext() const
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index f7943630c4..bd6b9d741e 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -177,9 +177,6 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject
static void qt_quickitems_defineModule()
{
- const char *uri = "QtQuick";
- const int major = 2;
-
QQmlPrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
@@ -187,205 +184,12 @@ static void qt_quickitems_defineModule()
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
qRegisterMetaType<QQuickHandlerPoint>();
- qmlRegisterModule(uri, major, 15);
-
- // Core QtQuick types
- qmlRegisterTypesAndRevisions<
- QPointingDeviceUniqueIdForeign,
- QQuickAnchorAnimation,
- QQuickAnchorChanges,
- QQuickAnchors,
- QQuickAnchorSet,
- QQuickBorderImage,
- QQuickEnterKeyAttached,
- QQuickEventPoint,
- QQuickEventTouchPoint,
- QQuickFlickable,
- QQuickFlickableVisibleArea,
- QQuickFocusScope,
- QQuickGradient,
- QQuickGradientStop,
- QQuickGraphicsInfo,
- QQuickImage,
- QQuickImageBase,
- QQuickItem,
- QQuickItemGrabResult,
- QQuickKeyNavigationAttached,
- QQuickKeysAttached,
- QQuickLayoutMirroringAttached,
- QQuickLoader,
- QQuickMatrix4x4,
- QQuickMouseArea,
- QQuickMultiPointTouchArea,
- QQuickPaintedItem,
- QQuickParentAnimation,
- QQuickParentChange,
- QQuickPen,
- QQuickPinch,
- QQuickPinchArea,
- QQuickPointerDevice,
- QQuickRectangle,
- QQuickRotation,
- QQuickScale,
- QQuickScaleGrid,
- QQuickTouchPoint,
- QQuickTransform,
- QQuickTranslate
- >(uri, major);
-
- // text-related types
- qmlRegisterTypesAndRevisions<
- QQuickText,
- QQuickTextDocument,
- QQuickTextEdit,
- QQuickTextInput,
- QQuickTextLine
- >(uri, major);
-
- // events
- qmlRegisterTypesAndRevisions<
- QQuickCloseEvent,
- QQuickGrabGestureEvent,
- QQuickKeyEvent,
- QQuickMouseEvent,
- QQuickPinchEvent,
- QQuickPointerEvent,
- QQuickPointerMouseEvent,
- QQuickPointerTouchEvent,
- QQuickWheelEvent
- >(uri, major);
-
- // Input Handlers are part of QtQuick, not a separate module, since 5.12
- qmlRegisterTypesAndRevisions<
- QQuickDragHandler,
- QQuickHoverHandler,
- QQuickPinchHandler,
- QQuickPointerHandler,
- QQuickPointHandler,
- QQuickTapHandler
- >(uri, major);
-
-#if QT_CONFIG(accessibility)
- qmlRegisterTypesAndRevisions<QQuickAccessibleAttached>(uri, major);
-#endif
-
-#if QT_CONFIG(opengl)
- qmlRegisterTypesAndRevisions<QQuickOpenGLInfo>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_animatedimage)
- qmlRegisterTypesAndRevisions<QQuickAnimatedImage>(uri, major);
-#else
+#if !QT_CONFIG(quick_animatedimage)
qmlRegisterTypeNotAvailable(
- uri, major, 15, "AnimatedImage",
+ "QtQuick", 2, 15, "AnimatedImage",
QCoreApplication::translate("QQuickAnimatedImage",
"Qt was built without support for QMovie"));
#endif
-
-#if QT_CONFIG(quick_canvas)
- qmlRegisterTypesAndRevisions<QQuickCanvasItem>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_draganddrop)
- qmlRegisterTypesAndRevisions<
- QQuickDropEvent,
- QQuickDrag,
- QQuickDropArea,
- QQuickDropAreaDrag,
- QQuickDragAttached,
- QQuickDragAxis
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_flipable)
- qmlRegisterTypesAndRevisions<QQuickFlipable>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_positioners)
- qmlRegisterTypesAndRevisions<
- QQuickBasePositioner,
- QQuickColumn,
- QQuickFlow,
- QQuickGrid,
- QQuickRow
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_gridview)
- qmlRegisterTypesAndRevisions<QQuickGridView>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_itemview)
- qmlRegisterTypesAndRevisions<QQuickItemView>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_listview)
- qmlRegisterTypesAndRevisions<
- QQuickViewSection,
- QQuickListView
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_path)
- qmlRegisterTypesAndRevisions<
- QQuickCurve,
- QQuickPath,
- QQuickPathAngleArc,
- QQuickPathAnimation,
- QQuickPathArc,
- QQuickPathAttribute,
- QQuickPathCatmullRomCurve,
- QQuickPathCubic,
- QQuickPathElement,
- QQuickPathInterpolator,
- QQuickPathLine,
- QQuickPathMove,
- QQuickPathMultiline,
- QQuickPathPercent,
- QQuickPathPolyline,
- QQuickPathQuad,
- QQuickPathSvg
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_pathview)
- qmlRegisterTypesAndRevisions<QQuickPathView>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_repeater)
- qmlRegisterTypesAndRevisions<QQuickRepeater>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterTypesAndRevisions<
- QQuickBorderImageMesh,
- QQuickGridMesh,
- QQuickItemLayer,
- QQuickShaderEffect,
- QQuickShaderEffectMesh,
- QQuickShaderEffectSource
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_sprite)
- qmlRegisterTypesAndRevisions<
- QQuickAnimatedSprite,
- QQuickSprite,
- QQuickSpriteSequence
- >(uri, major);
-#endif
-
-#if QT_CONFIG(quick_tableview)
- qmlRegisterTypesAndRevisions<QQuickTableView>(uri, major);
-#endif
-
-#if QT_CONFIG(quick_viewtransitions)
- qmlRegisterTypesAndRevisions<QQuickViewTransitionAttached>(uri, major);
-#endif
-
-#if QT_CONFIG(wheelevent)
- qmlRegisterTypesAndRevisions<QQuickWheelHandler>(uri, major);
-#endif
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 661f19509a..031ac6337a 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -197,6 +197,8 @@ void QQuickItemView::setModel(const QVariant &m)
disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ disconnect(d->model, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ disconnect(d->model, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
}
QQmlInstanceModel *oldModel = d->model;
@@ -232,10 +234,14 @@ void QQuickItemView::setModel(const QVariant &m)
connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ connect(d->model, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ connect(d->model, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
if (isComponentComplete()) {
d->updateSectionCriteria();
d->refill();
- d->currentIndex = -1;
+ /* Setting currentIndex to -2 ensures that we always enter the "currentIndex changed"
+ code path in setCurrentIndex, updating bindings depending on currentIndex.*/
+ d->currentIndex = -2;
setCurrentIndex(d->model->count() > 0 ? 0 : -1);
d->updateViewport();
@@ -252,6 +258,7 @@ void QQuickItemView::setModel(const QVariant &m)
emit countChanged();
}
emit modelChanged();
+ d->moveReason = QQuickItemViewPrivate::Other;
}
QQmlComponent *QQuickItemView::delegate() const
@@ -691,6 +698,28 @@ void QQuickItemView::setHighlightMoveDuration(int duration)
}
}
+bool QQuickItemView::reuseItems() const
+{
+ return bool(d_func()->reusableFlag == QQmlDelegateModel::Reusable);
+}
+
+void QQuickItemView::setReuseItems(bool reuse)
+{
+ Q_D(QQuickItemView);
+ if (reuseItems() == reuse)
+ return;
+
+ d->reusableFlag = reuse ? QQmlDelegateModel::Reusable : QQmlDelegateModel::NotReusable;
+
+ if (!reuse && d->model) {
+ // When we're told to not reuse items, we
+ // immediately, as documented, drain the pool.
+ d->model->drainReusableItemsPool(0);
+ }
+
+ emit reuseItemsChanged();
+}
+
QQuickTransition *QQuickItemView::populateTransition() const
{
Q_D(const QQuickItemView);
@@ -845,7 +874,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
setPosition(qMin(itemPos, maxExtent));
// now release the reference to all the old visible items.
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
item = visibleItem(idx);
}
if (item) {
@@ -1088,8 +1117,8 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const
void QQuickItemViewPrivate::applyDelegateChange()
{
- releaseVisibleItems();
- releaseItem(currentItem);
+ releaseVisibleItems(QQmlDelegateModel::NotReusable);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
updateSectionCriteria();
refill();
@@ -1191,7 +1220,7 @@ void QQuickItemView::destroyRemoved()
} else {
if (hasRemoveTransition)
d->runDelayedRemoveTransition = true;
- d->releaseItem(item);
+ d->releaseItem(item, d->reusableFlag);
it = d->visibleItems.erase(it);
}
} else {
@@ -1635,7 +1664,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (currentItem) {
if (currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
currentIndex = modelIndex;
emit q->currentIndexChanged();
@@ -1672,7 +1701,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (oldCurrentItem != currentItem
&& (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item))
emit q->currentItemChanged();
- releaseItem(oldCurrentItem);
+ releaseItem(oldCurrentItem, reusableFlag);
}
void QQuickItemViewPrivate::clear(bool onDestruction)
@@ -1682,17 +1711,17 @@ void QQuickItemViewPrivate::clear(bool onDestruction)
bufferedChanges.reset();
timeline.clear();
- releaseVisibleItems();
+ releaseVisibleItems(QQmlInstanceModel::NotReusable);
visibleIndex = 0;
for (FxViewItem *item : qAsConst(releasePendingTransition)) {
item->releaseAfterTransition = false;
- releaseItem(item);
+ releaseItem(item, QQmlInstanceModel::NotReusable);
}
releasePendingTransition.clear();
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -1751,7 +1780,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
currentChanges.reset();
bufferedChanges.reset();
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
}
int prevCount = itemCount;
@@ -1790,6 +1819,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (prevCount != itemCount)
emit q->countChanged();
} while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges());
+ storeFirstVisibleItemPosition();
}
void QQuickItemViewPrivate::regenerate(bool orientationChanged)
@@ -1876,6 +1906,7 @@ void QQuickItemViewPrivate::layout()
updateSections();
layoutVisibleItems();
+ storeFirstVisibleItemPosition();
int lastIndexInView = findLastIndexInView();
refill();
@@ -1903,21 +1934,25 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
- for (auto it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) {
- auto old_count = releasePendingTransition.count();
- auto success = prepareNonVisibleItemTransition(*it, viewBounds);
- // prepareNonVisibleItemTransition() may invalidate iterators while in fast flicking
- // invisible animating items are kicked in or out the viewPort
- // use old_count to test if the abrupt erasure occurs
- if (old_count > releasePendingTransition.count()) {
+ // We cannot use iterators here as erasing from a container invalidates them.
+ for (int i = 0, count = releasePendingTransition.count(); i < count;) {
+ auto success = prepareNonVisibleItemTransition(releasePendingTransition[i], viewBounds);
+ // prepareNonVisibleItemTransition() may remove items while in fast flicking.
+ // Invisible animating items are kicked in or out the viewPort.
+ // Recheck count to test if the item got removed. In that case the same index points
+ // to a different item now.
+ const int old_count = count;
+ count = releasePendingTransition.count();
+ if (old_count > count)
continue;
- }
+
if (!success) {
- releaseItem(*it);
- it = releasePendingTransition.erase(it);
- continue;
+ releaseItem(releasePendingTransition[i], reusableFlag);
+ releasePendingTransition.remove(i);
+ --count;
+ } else {
+ ++i;
}
- ++it;
}
for (int i=0; i<visibleItems.count(); i++)
@@ -1960,7 +1995,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
prevFirstItemInViewPos = prevFirstItemInView->position();
prevFirstItemInViewIndex = prevFirstItemInView->index;
}
- qreal prevVisibleItemsFirstPos = visibleItems.count() ? visibleItems.constFirst()->position() : 0.0;
+ qreal prevVisibleItemsFirstPos = visibleItems.count() ? firstVisibleItemPosition : 0.0;
totalInsertionResult->visiblePos = prevFirstItemInViewPos;
totalRemovalResult->visiblePos = prevFirstItemInViewPos;
@@ -2006,6 +2041,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (!insertions.isEmpty()) {
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
layoutVisibleItems(removals.first().index);
+ storeFirstVisibleItemPosition();
}
}
@@ -2026,6 +2062,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (i < insertions.count() - 1) {
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
layoutVisibleItems(insertions[i].index);
+ storeFirstVisibleItemPosition();
}
itemCount += insertions[i].count;
}
@@ -2056,9 +2093,9 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
// Whatever removed/moved items remain are no longer visible items.
prepareRemoveTransitions(&currentChanges.removedItems);
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
+ for (auto it = currentChanges.removedItems.begin();
it != currentChanges.removedItems.end(); ++it) {
- releaseItem(it.value());
+ releaseItem(it.value(), reusableFlag);
}
currentChanges.removedItems.clear();
@@ -2067,7 +2104,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (currentItem->item && currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -2148,11 +2185,11 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQmlChangeSet::Ch
removeResult->sizeChangesAfterVisiblePos += item->size();
}
if (removal.isMove()) {
- currentChanges.removedItems.insert(removal.moveKey(item->index), item);
+ currentChanges.removedItems.replace(removal.moveKey(item->index), item);
item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true);
} else {
// track item so it is released later
- currentChanges.removedItems.insertMulti(QQmlChangeSet::MoveKey(), item);
+ currentChanges.removedItems.insert(QQmlChangeSet::MoveKey(), item);
}
if (!removeResult->changedFirstItem && item == *visibleItems.constBegin())
removeResult->changedFirstItem = true;
@@ -2223,15 +2260,14 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
visibleItems[i]->prepareTransition(transitioner, viewBounds);
}
-void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
+void QQuickItemViewPrivate::prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
{
if (!transitioner)
return;
if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)
|| transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin();
- it != removedItems->end(); ) {
+ for (auto it = removedItems->begin(); it != removedItems->end(); ) {
bool isRemove = it.key().moveId < 0;
if (isRemove) {
FxViewItem *item = *it;
@@ -2274,7 +2310,7 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona
{
for (int i=0; i<releasePendingTransition.count(); i++) {
if (releasePendingTransition.at(i)->transitionableItem == item) {
- releaseItem(releasePendingTransition.takeAt(i));
+ releaseItem(releasePendingTransition.takeAt(i), reusableFlag);
return;
}
}
@@ -2380,7 +2416,23 @@ void QQuickItemView::destroyingItem(QObject *object)
}
}
-bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
+void QQuickItemView::onItemPooled(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->pooled();
+}
+
+void QQuickItemView::onItemReused(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->reused();
+}
+
+bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
Q_Q(QQuickItemView);
if (!item)
@@ -2391,13 +2443,19 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
QQmlInstanceModel::ReleaseFlags flags = {};
if (model && item->item) {
- flags = model->release(item->item);
+ flags = model->release(item->item, reusableFlag);
if (!flags) {
// item was not destroyed, and we no longer reference it.
- QQuickItemPrivate::get(item->item)->setCulled(true);
+ if (item->item->parentItem() == contentItem) {
+ // Only cull the item if its parent item is still our contentItem.
+ // One case where this can happen is moving an item out of one ObjectModel and into another.
+ QQuickItemPrivate::get(item->item)->setCulled(true);
+ }
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
} else if (flags & QQmlInstanceModel::Destroyed) {
item->item->setParentItem(nullptr);
+ } else if (flags & QQmlInstanceModel::Pooled) {
+ item->setVisible(false);
}
}
delete item;
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 6bc00411f0..521580d292 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -110,6 +110,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
+ Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15)
+
QML_NAMED_ELEMENT(ItemView)
QML_UNCREATABLE("ItemView is an abstract base class.")
QML_ADDED_IN_MINOR_VERSION(1)
@@ -226,6 +228,9 @@ public:
int highlightMoveDuration() const;
virtual void setHighlightMoveDuration(int);
+ bool reuseItems() const;
+ void setReuseItems(bool reuse);
+
enum PositionMode { Beginning, Center, End, Visible, Contain, SnapPosition };
Q_ENUM(PositionMode)
@@ -281,6 +286,8 @@ Q_SIGNALS:
void preferredHighlightEndChanged();
void highlightMoveDurationChanged();
+ Q_REVISION(15) void reuseItemsChanged();
+
protected:
void updatePolish() override;
void componentComplete() override;
@@ -296,6 +303,8 @@ protected Q_SLOTS:
virtual void initItem(int index, QObject *item);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
void destroyingItem(QObject *item);
+ void onItemPooled(int modelIndex, QObject *object);
+ void onItemReused(int modelIndex, QObject *object);
void animStopped();
void trackedPositionChanged();
@@ -399,6 +408,9 @@ Q_SIGNALS:
void prevSectionChanged();
void nextSectionChanged();
+ void pooled();
+ void reused();
+
public:
QPointer<QQuickItemView> m_view;
bool m_isCurrent : 1;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index 6442fee27d..48f47a356b 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -92,7 +92,7 @@ public:
int itemCount;
int newCurrentIndex;
QQmlChangeSet pendingChanges;
- QHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
+ QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
bool active : 1;
bool currentChanged : 1;
@@ -174,7 +174,7 @@ public:
void mirrorChange() override;
FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested);
- virtual bool releaseItem(FxViewItem *item);
+ virtual bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag);
QQuickItem *createHighlightItem() const;
QQuickItem *createComponentItem(QQmlComponent *component, qreal zValue, bool createDefault = false) const;
@@ -203,7 +203,7 @@ public:
void createTransitioner();
void prepareVisibleItemTransitions();
- void prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
+ void prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds);
void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override;
@@ -238,15 +238,17 @@ public:
q->polish();
}
- void releaseVisibleItems() {
+ void releaseVisibleItems(QQmlInstanceModel::ReusableFlag reusableFlag) {
// make a copy and clear the visibleItems first to avoid destroyed
// items being accessed during the loop (QTBUG-61294)
const QList<FxViewItem *> oldVisible = visibleItems;
visibleItems.clear();
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
+ virtual QQuickItemViewAttached *getAttachedObject(const QObject *) const { return nullptr; }
+
QPointer<QQmlInstanceModel> model;
QVariant modelVariant;
int itemCount;
@@ -260,6 +262,12 @@ public:
MovementReason moveReason;
QList<FxViewItem *> visibleItems;
+ qreal firstVisibleItemPosition = 0;
+ void storeFirstVisibleItemPosition() {
+ if (!visibleItems.isEmpty()) {
+ firstVisibleItemPosition = visibleItems.constFirst()->position();
+ }
+ }
int visibleIndex;
int currentIndex;
FxViewItem *currentItem;
@@ -282,6 +290,11 @@ public:
QQmlComponent *footerComponent;
FxViewItem *footer;
+ // Reusing delegate items cannot be on by default for backwards compatibility.
+ // Reusing an item will e.g mean that Component.onCompleted will only be called for an
+ // item when it's created and not when it's reused, which will break legacy applications.
+ QQmlInstanceModel::ReusableFlag reusableFlag = QQmlInstanceModel::NotReusable;
+
struct MovedItem {
FxViewItem *item;
QQmlChangeSet::MoveKey moveKey;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 23925871e5..badd2efe29 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -92,7 +92,7 @@ public:
FxViewItem *newViewItem(int index, QQuickItem *item) override;
void initializeViewItem(FxViewItem *item) override;
- bool releaseItem(FxViewItem *item) override;
+ bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) override;
void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override;
void repositionPackageItemAt(QQuickItem *item, int index) override;
void resetFirstItemPosition(qreal pos = 0.0) override;
@@ -139,6 +139,8 @@ public:
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override;
+ QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+
QQuickListView::Orientation orient;
qreal visiblePos;
qreal averageSize;
@@ -634,15 +636,15 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
}
}
-bool QQuickListViewPrivate::releaseItem(FxViewItem *item)
+bool QQuickListViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
if (!item || !model)
- return QQuickItemViewPrivate::releaseItem(item);
+ return QQuickItemViewPrivate::releaseItem(item, reusableFlag);
QPointer<QQuickItem> it = item->item;
QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached);
- bool released = QQuickItemViewPrivate::releaseItem(item);
+ bool released = QQuickItemViewPrivate::releaseItem(item, reusableFlag);
if (released && it && att && att->m_sectionItem) {
// We hold no more references to this item
int i = 0;
@@ -682,7 +684,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
int newModelIdx = qBound(0, modelIndex + count, model->count());
count = newModelIdx - modelIndex;
if (count) {
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex = newModelIdx;
visibleIndex = modelIndex;
visiblePos = itemEnd + count * (averageSize + spacing);
@@ -737,7 +739,7 @@ void QQuickListViewPrivate::removeItem(FxViewItem *item)
releasePendingTransition.append(item);
} else {
qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << (QObject *)(item->item);
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
}
@@ -808,6 +810,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
FxViewItem *firstItem = *visibleItems.constBegin();
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
+ firstVisibleItemPosition = firstItem->position();
qreal sum = firstItem->size();
qreal pos = firstItem->position() + firstItem->size() + spacing;
firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to);
@@ -1771,6 +1774,12 @@ void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *s
sectionItem->setProperty("section", section);
}
+QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *object) const
+{
+ QObject *attachedObject = qmlAttachedPropertiesObject<QQuickListView>(object);
+ return static_cast<QQuickItemViewAttached *>(attachedObject);
+}
+
//----------------------------------------------------------------------------
/*!
@@ -1919,6 +1928,39 @@ void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *s
of type \l [QML] {real}, so it is possible to set fractional
values like \c 0.1.
+ \section1 Reusing items
+
+ Since 5.15, ListView can be configured to recycle items instead of instantiating
+ from the \l delegate whenever new rows are flicked into view. This approach improves
+ performance, depending on the complexity of the delegate. Reusing
+ items is off by default (for backwards compatibility reasons), but can be switched
+ on by setting the \l reuseItems property to \c true.
+
+ When an item is flicked out, it moves to the \e{reuse pool}, which is an
+ internal cache of unused items. When this happens, the \l ListView::pooled
+ signal is emitted to inform the item about it. Likewise, when the item is
+ moved back from the pool, the \l ListView::reused signal is emitted.
+
+ Any item properties that come from the model are updated when the
+ item is reused. This includes \c index and \c row, but also
+ any model roles.
+
+ \note Avoid storing any state inside a delegate. If you do, reset it
+ manually on receiving the \l ListView::reused signal.
+
+ If an item has timers or animations, consider pausing them on receiving
+ the \l ListView::pooled signal. That way you avoid using the CPU resources
+ for items that are not visible. Likewise, if an item has resources that
+ cannot be reused, they could be freed up.
+
+ \note While an item is in the pool, it might still be alive and respond
+ to connected signals and bindings.
+
+ The following example shows a delegate that animates a spinning rectangle. When
+ it is pooled, the animation is temporarily paused:
+
+ \snippet qml/listview/reusabledelegate.qml 0
+
\sa {QML Data Models}, GridView, PathView, {Qt Quick Examples - Views}
*/
QQuickListView::QQuickListView(QQuickItem *parent)
@@ -2085,6 +2127,20 @@ QQuickListView::~QQuickListView()
*/
/*!
+ \qmlproperty bool QtQuick::ListView::reuseItems
+
+ This property enables you to reuse items that are instantiated
+ from the \l delegate. If set to \c false, any currently
+ pooled items are destroyed.
+
+ This property is \c false by default.
+
+ \since 5.15
+
+ \sa {Reusing items}, ListView::pooled, ListView::reused
+*/
+
+/*!
\qmlproperty Component QtQuick::ListView::highlight
This property holds the component to use as the highlight.
@@ -2095,7 +2151,7 @@ QQuickListView::~QQuickListView()
highlight item is \c 0.
\sa highlightItem, highlightFollowsCurrentItem,
- {Qt Quick Examples - Views#Highlight}{ListView highlight example},
+ {Qt Quick Examples - Views#Using Highlight}{ListView Highlight Example},
{Stacking Order in ListView}
*/
@@ -2654,21 +2710,25 @@ void QQuickListView::setSnapMode(SnapMode mode)
This property determines the positioning of the \l{headerItem}{header item}.
- The possible values are:
- \list
- \li ListView.InlineHeader (default) - the header is positioned in the beginning
+ \value ListView.InlineHeader (default) The header is positioned at the beginning
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayHeader - the header is positioned in the beginning of the view.
- \li ListView.PullBackHeader - the header is positioned in the beginning of the view.
+
+ \value ListView.OverlayHeader The header is positioned at the beginning of the view.
+
+ \value ListView.PullBackHeader The header is positioned at the beginning of the view.
The header can be pushed away by moving the content forwards, and pulled back by
moving the content backwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the header. For example, if the header should be shown above the
\l delegate items when using \c ListView.OverlayHeader, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c headerPositioning is not set to \c ListView.InlineHeader, the
+ user cannot press and flick the list from the header. In any case, the
+ \l{headerItem}{header item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::HeaderPositioning QQuickListView::headerPositioning() const
{
@@ -2697,21 +2757,25 @@ void QQuickListView::setHeaderPositioning(QQuickListView::HeaderPositioning posi
This property determines the positioning of the \l{footerItem}{footer item}.
- The possible values are:
- \list
- \li ListView.InlineFooter (default) - the footer is positioned in the end
+ \value ListView.InlineFooter (default) The footer is positioned at the end
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayFooter - the footer is positioned in the end of the view.
- \li ListView.PullBackFooter - the footer is positioned in the end of the view.
+
+ \value ListView.OverlayFooter The footer is positioned at the end of the view.
+
+ \value ListView.PullBackFooter The footer is positioned at the end of the view.
The footer can be pushed away by moving the content backwards, and pulled back by
moving the content forwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the footer. For example, if the footer should be shown above the
\l delegate items when using \c ListView.OverlayFooter, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c footerPositioning is not set to \c ListView.InlineFooter, the
+ user cannot press and flick the list from the footer. In any case, the
+ \l{footerItem}{footer item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::FooterPositioning QQuickListView::footerPositioning() const
{
@@ -3185,6 +3249,13 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickListView);
+
+ if (d->model) {
+ // When the view changes size, we force the pool to
+ // shrink by releasing all pooled items.
+ d->model->drainReusableItemsPool(0);
+ }
+
if (d->isRightToLeft()) {
// maintain position relative to the right edge
qreal dx = newGeometry.width() - oldGeometry.width();
@@ -3592,6 +3663,23 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj)
return new QQuickListViewAttached(obj);
}
+bool QQuickListView::contains(const QPointF &point) const
+{
+ bool ret = QQuickItemView::contains(point);
+ // QTBUG-74046: if a mouse press "falls through" a floating header or footer, don't allow dragging the list from there
+ if (ret) {
+ if (auto header = headerItem()) {
+ if (headerPositioning() != QQuickListView::InlineHeader && header->contains(mapToItem(header, point)))
+ ret = false;
+ }
+ if (auto footer = footerItem()) {
+ if (footerPositioning() != QQuickListView::InlineFooter && footer->contains(mapToItem(footer, point)))
+ ret = false;
+ }
+ }
+ return ret;
+}
+
QT_END_NAMESPACE
#include "moc_qquicklistview_p.cpp"
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index 1c72a10190..be21b93155 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -179,6 +179,8 @@ public:
static QQuickListViewAttached *qmlAttachedProperties(QObject *);
+ bool contains(const QPointF &point) const override;
+
public Q_SLOTS:
void incrementCurrentIndex();
void decrementCurrentIndex();
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index ddf34798d7..57d55172e3 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -62,7 +62,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false), overThreshold(false), pressed(nullptr),
+ propagateComposedEvents(false), overThreshold(false),
pressAndHoldInterval(-1)
#if QT_CONFIG(quick_draganddrop)
, drag(nullptr)
@@ -942,6 +942,12 @@ void QQuickMouseArea::mouseUngrabEvent()
ungrabMouse();
}
+void QQuickMouseArea::touchUngrabEvent()
+{
+ // allow a Pointer Handler to steal the grab from MouseArea
+ ungrabMouse();
+}
+
bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event)
{
Q_D(QQuickMouseArea);
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 3d4d113215..806cc41369 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -170,6 +170,7 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseUngrabEvent() override;
+ void touchUngrabEvent() override;
void hoverEnterEvent(QHoverEvent *event) override;
void hoverMoveEvent(QHoverEvent *event) override;
void hoverLeaveEvent(QHoverEvent *event) override;
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index b02e58fae4..9a371207ce 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -42,6 +42,7 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qevent_p.h>
#include <private/qquickitem_p.h>
+#include <private/qquickwindow_p.h>
#include <private/qguiapplication_p.h>
#include <QEvent>
#include <QMouseEvent>
@@ -448,6 +449,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
: QQuickItem(parent),
_minimumTouchPoints(0),
_maximumTouchPoints(INT_MAX),
+ _touchMouseDevice(nullptr),
_stealMouse(false),
_mouseEnabled(true)
{
@@ -586,10 +588,10 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
bool ended = false;
bool moved = false;
bool started = false;
- bool isMouseEvent = false;
clearTouchLists();
QList<QTouchEvent::TouchPoint> touchPoints;
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window());
switch (event->type()) {
case QEvent::TouchBegin:
@@ -598,6 +600,9 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
touchPoints = static_cast<QTouchEvent*>(event)->touchPoints();
break;
case QEvent::MouseButtonPress:
+ _mouseQpaTouchPoint = QTouchEvent::TouchPoint(windowPriv->touchMouseId);
+ _touchMouseDevice = windowPriv->touchMouseDevice->qTouchDevice();
+ Q_FALLTHROUGH();
case QEvent::MouseMove:
case QEvent::MouseButtonRelease: {
QMouseEvent *me = static_cast<QMouseEvent*>(event);
@@ -617,7 +622,6 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
_mouseQpaTouchPoint.setState(Qt::TouchPointPressed);
}
touchPoints << _mouseQpaTouchPoint;
- isMouseEvent = true;
break;
}
default:
@@ -625,11 +629,6 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
break;
}
- if (!isMouseEvent && _mouseTouchPoint) {
- QQuickWindow *c = window();
- if (c && c->mouseGrabberItem() == this)
- touchPoints << _mouseQpaTouchPoint;
- }
int numTouchPoints = touchPoints.count();
//always remove released touches, and make sure we handle all releases before adds.
for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) {
@@ -756,7 +755,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e)
dtp = new QQuickTouchPoint(false);
updateTouchPoint(dtp, e);
dtp->setPressed(true);
- _touchPoints.insert(-1, dtp);
+ _touchPoints.insert(_touchMouseDevice && _mouseQpaTouchPoint.id() > 0 ? _mouseQpaTouchPoint.id() : -1, dtp);
_pressedTouchPoints.append(dtp);
_mouseTouchPoint = dtp;
}
@@ -839,8 +838,7 @@ void QQuickMultiPointTouchArea::mousePressEvent(QMouseEvent *event)
setKeepMouseGrab(false);
event->setAccepted(true);
_mousePos = event->localPos();
-
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
if (_touchPoints.count() >= _minimumTouchPoints - 1 && _touchPoints.count() < _maximumTouchPoints) {
@@ -855,7 +853,7 @@ void QQuickMultiPointTouchArea::mouseMoveEvent(QMouseEvent *event)
return;
}
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
_movedTouchPoints.clear();
@@ -870,7 +868,7 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
return;
}
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
if (_mouseTouchPoint) {
@@ -880,18 +878,16 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
_mouseTouchPoint = nullptr;
}
- QQuickWindow *c = window();
- if (c && c->mouseGrabberItem() == this)
- ungrabMouse();
setKeepMouseGrab(false);
}
-void QQuickMultiPointTouchArea::ungrab()
+void QQuickMultiPointTouchArea::ungrab(bool normalRelease)
{
_stealMouse = false;
setKeepMouseGrab(false);
setKeepTouchGrab(false);
- ungrabTouchPoints();
+ if (!normalRelease)
+ ungrabTouchPoints();
if (_touchPoints.count()) {
for (QObject *obj : qAsConst(_touchPoints))
@@ -969,13 +965,25 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve
if (!isEnabled() || !isVisible())
return QQuickItem::childMouseEventFilter(receiver, event);
switch (event->type()) {
- case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonPress: {
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window());
+ // If we already got a chance to filter the touchpoint that generated this synth-mouse-press,
+ // and chose not to filter it, ignore it now, too.
+ if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedByQt &&
+ _lastFilterableTouchPointIds.contains(windowPriv->touchMouseId))
+ return false;
+ } Q_FALLTHROUGH();
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
return sendMouseEvent(static_cast<QMouseEvent *>(event));
- break;
case QEvent::TouchBegin:
+ _lastFilterableTouchPointIds.clear();
+ Q_FALLTHROUGH();
case QEvent::TouchUpdate:
+ for (auto tp : static_cast<QTouchEvent*>(event)->touchPoints()) {
+ if (tp.state() == Qt::TouchPointPressed)
+ _lastFilterableTouchPointIds << tp.id();
+ }
if (!shouldFilter(event))
return false;
updateTouchData(event);
@@ -984,7 +992,7 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve
if (!shouldFilter(event))
return false;
updateTouchData(event);
- ungrab();
+ ungrab(true);
}
break;
default:
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 7506be10a1..42b42a45c5 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -289,7 +289,7 @@ protected:
#endif
private:
- void ungrab();
+ void ungrab(bool normalRelease = false);
QMap<int,QQuickTouchPoint*> _touchPrototypes; //TouchPoints defined in QML
QMap<int,QObject*> _touchPoints; //All current touch points
QList<QObject*> _releasedTouchPoints;
@@ -297,8 +297,10 @@ private:
QList<QObject*> _movedTouchPoints;
int _minimumTouchPoints;
int _maximumTouchPoints;
+ QVector<int> _lastFilterableTouchPointIds;
QPointer<QQuickTouchPoint> _mouseTouchPoint; // exists when mouse button is down and _mouseEnabled is true; null otherwise
QTouchEvent::TouchPoint _mouseQpaTouchPoint; // synthetic QPA touch point to hold state and position of the mouse
+ const QTouchDevice *_touchMouseDevice;
QPointF _mousePos;
bool _stealMouse;
bool _mouseEnabled;
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp
index cee73ac2e8..df5ec0c3f2 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -133,7 +133,6 @@ QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
, contentsScale(1.0)
, fillColor(Qt::transparent)
, renderTarget(QQuickPaintedItem::Image)
- , performanceHints(nullptr)
, opaquePainting(false)
, antialiasing(false)
, mipmap(false)
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 6976665134..7ebe174a9e 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1922,9 +1922,10 @@ bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
void QQuickPathView::mouseUngrabEvent()
{
Q_D(QQuickPathView);
- if (d->stealMouse) {
+ if (d->stealMouse ||
+ (!d->flicking && d->snapMode != NoSnap && !qFuzzyCompare(qRound(d->offset), d->offset))) {
// if our mouse grab has been removed (probably by a Flickable),
- // fix our state
+ // or if we should snap but haven't done it, fix our state
d->stealMouse = false;
setKeepMouseGrab(false);
d->timer.invalidate();
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index b17e505f4f..ed2d7eda3e 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -424,9 +424,6 @@ QScreen *QQuickScreenInfo::wrappedScreen() const
QQuickScreenAttached::QQuickScreenAttached(QObject* attachee)
: QQuickScreenInfo(attachee)
- , m_window(nullptr)
- , m_updateMask(nullptr)
- , m_updateMaskSet(false)
{
m_attachee = qobject_cast<QQuickItem*>(attachee);
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 61cbdf7387..b4266d78c7 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -152,10 +152,10 @@ protected Q_SLOTS:
void screenChanged(QScreen*);
private:
- QQuickWindow* m_window;
+ QQuickWindow* m_window = nullptr;
QQuickItem* m_attachee;
Qt::ScreenOrientations m_updateMask;
- bool m_updateMaskSet;
+ bool m_updateMaskSet = false;
};
class Q_QUICK_PRIVATE_EXPORT QQuickScreen : public QObject
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index b3c8386fd9..e71e6dc698 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -179,201 +179,11 @@ QT_BEGIN_NAMESPACE
is a URL with the \c file or \c qrc schema, it is treated as a file
reference and the source code is read from the specified file.
- \section1 Direct3D and HLSL
-
- Direct3D backends provide ShaderEffect support with HLSL. The Direct3D 12
- backend requires using at least Shader Model 5.0 both for vertex and pixel
- shaders. When necessary, GraphicsInfo.shaderType can be used to decide
- at runtime what kind of value to assign to \l fragmentShader or
- \l vertexShader.
-
- All concepts described above for OpenGL and GLSL apply to Direct3D and HLSL
- as well. There are however a number of notable practical differences, which
- are the following:
-
- Instead of uniforms, HLSL shaders are expected to use a single constant
- buffer, assigned to register \c b0. The special names \c qt_Matrix,
- \c qt_Opacity, and \c qt_SubRect_<name> function the same way as with GLSL.
- All other members of the buffer are expected to map to properties in the
- ShaderEffect item.
-
- \note The buffer layout must be compatible for both shaders. This means
- that application-provided shaders must make sure \c qt_Matrix and
- \c qt_Opacity are included in the buffer, starting at offset 0, when custom
- code is provided for one type of shader only, leading to ShaderEffect
- providing the other shader. This is due to ShaderEffect's built-in shader code
- declaring a constant buffer containing \c{float4x4 qt_Matrix; float qt_Opacity;}.
-
- Unlike GLSL's attributes, no names are used for vertex input elements.
- Therefore qt_Vertex and qt_MultiTexCoord0 are not relevant. Instead, the
- standard Direct3D semantics, \c POSITION and \c TEXCOORD (or \c TEXCOORD0)
- are used for identifying the correct input layout.
-
- Unlike GLSL's samplers, texture and sampler objects are separate in HLSL.
- Shaders are expected to expect 2D, non-array, non-multisample textures.
- Both the texture and sampler binding points are expected to be sequential
- and start from 0 (meaning registers \c{t0, t1, ...}, and \c{s0, s1, ...},
- respectively). Unlike with OpenGL, samplers are not mapped to Qt Quick item
- properties and therefore the name of the sampler is not relevant. Instead,
- it is the textures that map to properties referencing \l Image or
- \l ShaderEffectSource items.
-
- Unlike OpenGL, backends for modern APIs will typically prefer offline
- compilation and shipping pre-compiled bytecode with applications instead of
- inlined shader source strings. In this case the string properties for
- vertex and fragment shaders are treated as URLs referring to local files or
- files shipped via the Qt resource system.
-
- To check at runtime what is supported, use the
- GraphicsInfo.shaderSourceType and GraphicsInfo.shaderCompilationType
- properties. Note that these are bitmasks, because some backends may support
- multiple approaches.
-
- In case of Direct3D 12, all combinations are supported. If the vertexShader
- and fragmentShader properties form a valid URL with the \c file or \c qrc
- schema, the bytecode or HLSL source code is read from the specified file.
- The type of the file contents is detected automatically. Otherwise, the
- string is treated as HLSL source code and is compiled at runtime, assuming
- Shader Model 5.0 and an entry point of \c{"main"}. This allows dynamically
- constructing shader strings. However, whenever the shader source code is
- static, it is strongly recommended to pre-compile to bytecode using the
- \c fxc tool and refer to these files from QML. This will be a lot more
- efficient at runtime and allows catching syntax errors in the shaders at
- compile time.
-
- Unlike OpenGL, the Direct3D backend is able to perform runtime shader
- compilation on dedicated threads. This is managed transparently to the
- applications, and means that ShaderEffect items that contain HLSL source
- strings do not block the rendering or other parts of the application until
- the bytecode is ready.
-
- Using files with bytecode is more flexible also when it comes to the entry
- point name (it can be anything, not limited to \c main) and the shader
- model (it can be something newer than 5.0, for instance 5.1).
-
- \table 70%
- \row
- \li \qml
- import QtQuick 2.0
-
- Rectangle {
- width: 200; height: 100
- Row {
- Image { id: img;
- sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
- ShaderEffect {
- width: 100; height: 100
- property variant src: img
- fragmentShader: "qrc:/effect_ps.cso"
- }
- }
- }
- \endqml
- \row
- \li where \c effect_ps.cso is the compiled bytecode for the following HLSL shader:
- \code
- cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
- return float4(col, tex.a) * qt_Opacity;
- }
- \endcode
- \endtable
-
- The above is equivalent to the OpenGL example presented earlier. The vertex
- shader is provided implicitly by ShaderEffect. Note that the output of the
- pixel shader is using premultiplied alpha and that \c qt_Matrix is present
- in the constant buffer at offset 0, even though the pixel shader does not
- use the value.
-
- If desired, the HLSL source code can be placed directly into the QML
- source, similarly to how its done with GLSL. The only difference in this
- case is the entry point name, which must be \c main when using inline
- source strings.
-
- Alternatively, we could also have referred to a file containing the source
- of the effect instead of the compiled bytecode version.
-
- Some effects will want to provide a vertex shader as well. Below is a
- similar effect with both the vertex and fragment shader provided by the
- application. This time the colorization factor is provided by the QML item
- instead of hardcoding it in the shader. This can allow, among others,
- animating the value using QML's and Qt Quick's standard facilities.
-
- \table 70%
- \row
- \li \qml
- import QtQuick 2.0
-
- Rectangle {
- width: 200; height: 100
- Row {
- Image { id: img;
- sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
- ShaderEffect {
- width: 100; height: 100
- property variant src: img
- property variant color: Qt.vector3d(0.344, 0.5, 0.156)
- vertexShader: "qrc:/effect_vs.cso"
- fragmentShader: "qrc:/effect_ps.cso"
- }
- }
- }
- \endqml
- \row
- \li where \c effect_vs.cso and \c effect_ps.cso are the compiled bytecode
- for \c ExampleVertexShader and \c ExamplePixelShader. The source code is
- presented as one snippet here, the shaders can however be placed in
- separate source files as well.
- \code
- cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- float3 color;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- struct PSInput
- {
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- };
- PSInput ExampleVertexShader(float4 position : POSITION, float2 coord : TEXCOORD0)
- {
- PSInput result;
- result.position = mul(qt_Matrix, position);
- result.coord = coord;
- return result;
- }
- float4 ExamplePixelShader(PSInput input) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, color);
- return float4(col, tex.a) * qt_Opacity;
- }
- \endcode
- \endtable
-
- \note With OpenGL the \c y coordinate runs from bottom to top whereas with
- Direct 3D it goes top to bottom. For shader effect sources Qt Quick hides
- the difference by treating QtQuick::ShaderEffectSource::textureMirroring as
- appropriate, meaning texture coordinates in HLSL version of the shaders
- will not need any adjustments compared to the equivalent GLSL code.
-
\section1 Cross-platform, Cross-API ShaderEffect Items
- Some applications will want to be functional with multiple accelerated
- graphics backends. This has consequences for ShaderEffect items because the
- supported shading languages may vary from backend to backend.
+ Some applications will want to be functional with multiple graphics
+ APIs. This has consequences for ShaderEffect items because the supported
+ shading languages may vary from backend to backend.
There are two approaches to handle this: either write conditional property
values based on GraphicsInfo.shaderType, or use file selectors. In practice
@@ -404,20 +214,8 @@ QT_BEGIN_NAMESPACE
gl_FragColor = vec4(vec3(dot(tex.rgb,
vec3(0.344, 0.5, 0.156))),
tex.a) * qt_Opacity;"
- : GraphicsInfo.shaderType === GraphicsInfo.HLSL ?
- "cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
- return float4(col, tex.a) * qt_Opacity;
- }"
+ : GraphicsInfo.shaderType === GraphicsInfo.RhiShader ?
+ "qrc:/shader.frag.qsb"
: ""
}
}
@@ -429,15 +227,14 @@ QT_BEGIN_NAMESPACE
reported by GraphicsInfo is not up-to-date until the ShaderEffect item gets
associated with a QQuickWindow. Before that, the reported value is
GraphicsInfo.UnknownShadingLanguage. The alternative is to place the GLSL
- source code and the compiled D3D bytecode into the files
- \c{shaders/effect.frag} and \c{shaders/+hlsl/effect.frag}, include them in
- the Qt resource system, and let the ShaderEffect's internal QFileSelector
- do its job. The selector-less version is the GLSL source, while the \c hlsl
- selector is used when running on the D3D12 backend. The file under
- \c{+hlsl} can then contain either HLSL source code or compiled bytecode
- from the \c fxc tool. Additionally, when using a version 3.2 or newer core
- profile context with OpenGL, GLSL sources with a core profile compatible
- syntax can be placed under \c{+glslcore}.
+ source code and the RHI-compatible shader pack into the files
+ \c{shaders/effect.frag} and \c{shaders/+qsb/effect.frag}, include them in
+ the Qt resource system, and let the ShaderEffect's internal QFileSelector do
+ its job. The selector-less version is the GLSL source, while the \c qsb
+ selector is used when running with the Qt graphics abstraction (RHI).
+ Additionally, when using a version 3.2 or newer core profile context with
+ OpenGL, GLSL sources with a core profile compatible syntax can be placed
+ under \c{+glslcore}.
\qml
import QtQuick 2.8 // for GraphicsInfo
@@ -552,11 +349,7 @@ QQuickShaderEffect::~QQuickShaderEffect()
With GLSL the default shader expects the texture coordinate to be passed
from the vertex shader as \c{varying highp vec2 qt_TexCoord0}, and it
- samples from a sampler2D named \c source. With HLSL the texture is named
- \c source, while the vertex shader is expected to provide
- \c{float2 coord : TEXCOORD0} in its output in addition to
- \c{float4 position : SV_POSITION} (names can differ since linking is done
- based on the semantics).
+ samples from a sampler2D named \c source.
\sa vertexShader, GraphicsInfo
*/
@@ -593,9 +386,7 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
filesystem or bundled with the executable via Qt's resource system.
With GLSL the default shader passes the texture coordinate along to the
- fragment shader as \c{varying highp vec2 qt_TexCoord0}. With HLSL it is
- enough to use the standard \c TEXCOORD0 semantic, for example
- \c{float2 coord : TEXCOORD0}.
+ fragment shader as \c{varying highp vec2 qt_TexCoord0}.
\sa fragmentShader, GraphicsInfo
*/
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 07767d377d..ddaa1979b6 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -600,11 +600,6 @@ class QQuickAnchorSetPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickAnchorSet)
public:
- QQuickAnchorSetPrivate()
- : usedAnchors(nullptr), resetAnchors(nullptr)
- {
- }
-
QQuickAnchors::Anchors usedAnchors;
QQuickAnchors::Anchors resetAnchors;
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 295c6898bc..fd511bc2ee 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -520,10 +520,10 @@ int QQuickTableViewPrivate::nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge)
// visible, and should be loaded next if the content item moves.
int startIndex = -1;
switch (edge) {
- case Qt::LeftEdge: startIndex = loadedColumns.firstKey() - 1; break;
- case Qt::RightEdge: startIndex = loadedColumns.lastKey() + 1; break;
- case Qt::TopEdge: startIndex = loadedRows.firstKey() - 1; break;
- case Qt::BottomEdge: startIndex = loadedRows.lastKey() + 1; break;
+ case Qt::LeftEdge: startIndex = leftColumn() - 1; break;
+ case Qt::RightEdge: startIndex = rightColumn() + 1; break;
+ case Qt::TopEdge: startIndex = topRow() - 1; break;
+ case Qt::BottomEdge: startIndex = bottomRow() + 1; break;
}
return nextVisibleEdgeIndex(edge, startIndex);
@@ -628,6 +628,12 @@ void QQuickTableViewPrivate::updateContentWidth()
return;
}
+ if (loadedItems.isEmpty()) {
+ QBoolBlocker fixupGuard(inUpdateContentSize, true);
+ q->QQuickFlickable::setContentWidth(0);
+ return;
+ }
+
const int nextColumn = nextVisibleEdgeIndexAroundLoadedTable(Qt::RightEdge);
const int columnsRemaining = nextColumn == kEdgeIndexAtEnd ? 0 : tableSize.width() - nextColumn;
const qreal remainingColumnWidths = columnsRemaining * averageEdgeSize.width();
@@ -655,6 +661,12 @@ void QQuickTableViewPrivate::updateContentHeight()
return;
}
+ if (loadedItems.isEmpty()) {
+ QBoolBlocker fixupGuard(inUpdateContentSize, true);
+ q->QQuickFlickable::setContentHeight(0);
+ return;
+ }
+
const int nextRow = nextVisibleEdgeIndexAroundLoadedTable(Qt::BottomEdge);
const int rowsRemaining = nextRow == kEdgeIndexAtEnd ? 0 : tableSize.height() - nextRow;
const qreal remainingRowHeights = rowsRemaining * averageEdgeSize.height();
@@ -871,17 +883,13 @@ void QQuickTableViewPrivate::syncLoadedTableRectFromLoadedTable()
loadedTableInnerRect = QRectF(topLeftRect.bottomRight(), bottomRightRect.topLeft());
}
-void QQuickTableViewPrivate::forceLayout()
+QQuickTableViewPrivate::RebuildOptions QQuickTableViewPrivate::checkForVisibilityChanges()
{
- if (loadedItems.isEmpty())
- return;
-
- clearEdgeSizeCache();
- RebuildOptions rebuildOptions = RebuildOption::LayoutOnly;
-
// Go through all columns from first to last, find the columns that used
// to be hidden and not loaded, and check if they should become visible
// (and vice versa). If there is a change, we need to rebuild.
+ RebuildOptions rebuildOptions = RebuildOption::None;
+
for (int column = leftColumn(); column <= rightColumn(); ++column) {
const bool wasVisibleFromBefore = loadedColumns.contains(column);
const bool isVisibleNow = !qFuzzyIsNull(getColumnWidth(column));
@@ -916,6 +924,28 @@ void QQuickTableViewPrivate::forceLayout()
break;
}
+ return rebuildOptions;
+}
+
+void QQuickTableViewPrivate::forceLayout()
+{
+ if (loadedItems.isEmpty())
+ return;
+
+ clearEdgeSizeCache();
+ RebuildOptions rebuildOptions = RebuildOption::None;
+
+ const QSize actualTableSize = calculateTableSize();
+ if (tableSize != actualTableSize) {
+ // This can happen if the app is calling forceLayout while
+ // the model is updated, but before we're notified about it.
+ rebuildOptions = RebuildOption::All;
+ } else {
+ rebuildOptions = checkForVisibilityChanges();
+ if (!rebuildOptions)
+ rebuildOptions = RebuildOption::LayoutOnly;
+ }
+
scheduleRebuildTable(rebuildOptions);
auto rootView = rootSyncView();
@@ -1036,21 +1066,16 @@ void QQuickTableViewPrivate::releaseLoadedItems(QQmlTableInstanceModel::Reusable
void QQuickTableViewPrivate::releaseItem(FxTableItem *fxTableItem, QQmlTableInstanceModel::ReusableFlag reusableFlag)
{
Q_Q(QQuickTableView);
+ // Note that fxTableItem->item might already have been destroyed, in case
+ // the item is owned by the QML context rather than the model (e.g ObjectModel etc).
auto item = fxTableItem->item;
- Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
if (fxTableItem->ownItem) {
+ Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
delete item;
- } else {
- // Only QQmlTableInstanceModel supports reusing items
- auto releaseFlag = tableModel ?
- tableModel->release(item, reusableFlag) :
- model->release(item);
-
- if (releaseFlag != QQmlInstanceModel::Destroyed) {
- // When items are not destroyed, it typically means that the
- // item is reused, or that the model is an ObjectModel. If
- // so, we just hide the item instead.
+ } else if (item) {
+ auto releaseFlag = model->release(item, reusableFlag);
+ if (releaseFlag == QQmlInstanceModel::Pooled) {
fxTableItem->setVisible(false);
// If the item (or a descendant) has focus, remove it, so
@@ -1183,19 +1208,14 @@ qreal QQuickTableViewPrivate::sizeHintForRow(int row)
return rowHeight;
}
-void QQuickTableViewPrivate::calculateTableSize()
+void QQuickTableViewPrivate::updateTableSize()
{
// tableSize is the same as row and column count, and will always
// be the same as the number of rows and columns in the model.
Q_Q(QQuickTableView);
- QSize prevTableSize = tableSize;
- if (tableModel)
- tableSize = QSize(tableModel->columns(), tableModel->rows());
- else if (model)
- tableSize = QSize(1, model->count());
- else
- tableSize = QSize(0, 0);
+ const QSize prevTableSize = tableSize;
+ tableSize = calculateTableSize();
if (prevTableSize.width() != tableSize.width())
emit q->columnsChanged();
@@ -1203,6 +1223,16 @@ void QQuickTableViewPrivate::calculateTableSize()
emit q->rowsChanged();
}
+QSize QQuickTableViewPrivate::calculateTableSize()
+{
+ if (tableModel)
+ return QSize(tableModel->columns(), tableModel->rows());
+ else if (model)
+ return QSize(1, model->count());
+
+ return QSize(0, 0);
+}
+
qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
{
// Return the column width specified by the application, or go
@@ -1229,9 +1259,9 @@ qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
if (qIsNaN(columnWidth) || columnWidth <= 0) {
if (!layoutWarningIssued) {
layoutWarningIssued = true;
- qmlWarning(q_func()) << "the delegate's implicitHeight needs to be greater than zero";
+ qmlWarning(q_func()) << "the delegate's implicitWidth needs to be greater than zero";
}
- columnWidth = kDefaultRowHeight;
+ columnWidth = kDefaultColumnWidth;
}
return columnWidth;
@@ -1589,6 +1619,8 @@ void QQuickTableViewPrivate::processRebuildTable()
if (rebuildState == RebuildState::VerifyTable) {
if (loadedItems.isEmpty()) {
qCDebug(lcTableViewDelegateLifecycle()) << "no items loaded!";
+ updateContentWidth();
+ updateContentHeight();
rebuildState = RebuildState::Done;
} else if (!moveToNextRebuildState()) {
return;
@@ -1755,16 +1787,18 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL
void QQuickTableViewPrivate::beginRebuildTable()
{
- calculateTableSize();
+ updateTableSize();
QPoint topLeft;
QPointF topLeftPos;
calculateTopLeft(topLeft, topLeftPos);
- if (rebuildOptions & RebuildOption::All)
- releaseLoadedItems(QQmlTableInstanceModel::NotReusable);
- else if (rebuildOptions & RebuildOption::ViewportOnly)
- releaseLoadedItems(reusableFlag);
+ if (!loadedItems.isEmpty()) {
+ if (rebuildOptions & RebuildOption::All)
+ releaseLoadedItems(QQmlTableInstanceModel::NotReusable);
+ else if (rebuildOptions & RebuildOption::ViewportOnly)
+ releaseLoadedItems(reusableFlag);
+ }
if (rebuildOptions & RebuildOption::All) {
origin = QPointF(0, 0);
@@ -1879,7 +1913,7 @@ void QQuickTableViewPrivate::loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMo
const int edgeIndex = nextVisibleEdgeIndexAroundLoadedTable(edge);
qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex;
- const QList<int> visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge)
+ const auto visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge)
? loadedRows.keys() : loadedColumns.keys();
loadRequest.begin(edge, edgeIndex, visibleCells, incubationMode);
processLoadRequest();
@@ -2016,7 +2050,8 @@ bool QQuickTableViewPrivate::updateTableRecursive()
if (!updateComplete)
return false;
- for (auto syncChild : qAsConst(syncChildren)) {
+ const auto children = syncChildren;
+ for (auto syncChild : children) {
auto syncChild_d = syncChild->d_func();
syncChild_d->scheduledRebuildOptions |= rebuildOptions;
@@ -2196,13 +2231,15 @@ void QQuickTableViewPrivate::syncRebuildOptions()
void QQuickTableViewPrivate::syncDelegate()
{
- if (tableModel && assignedDelegate == tableModel->delegate())
+ if (!tableModel) {
+ // Only the tableModel uses the delegate assigned to a
+ // TableView. DelegateModel has it's own delegate, and
+ // ObjectModel etc. doesn't use one.
return;
+ }
- if (!tableModel)
- createWrapperModel();
-
- tableModel->setDelegate(assignedDelegate);
+ if (assignedDelegate != tableModel->delegate())
+ tableModel->setDelegate(assignedDelegate);
}
void QQuickTableViewPrivate::syncModel()
@@ -2210,8 +2247,10 @@ void QQuickTableViewPrivate::syncModel()
if (modelVariant == assignedModel)
return;
- if (model)
+ if (model) {
disconnectFromModel();
+ releaseLoadedItems(QQmlTableInstanceModel::NotReusable);
+ }
modelVariant = assignedModel;
QVariant effectiveModelVariant = modelVariant;
@@ -2291,6 +2330,7 @@ void QQuickTableViewPrivate::syncSyncView()
void QQuickTableViewPrivate::connectToModel()
{
+ Q_Q(QQuickTableView);
Q_TABLEVIEW_ASSERT(model, "");
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
@@ -2300,6 +2340,8 @@ void QQuickTableViewPrivate::connectToModel()
const auto tm = tableModel.data();
QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
}
if (auto const aim = model->abstractItemModel()) {
@@ -2323,6 +2365,7 @@ void QQuickTableViewPrivate::connectToModel()
void QQuickTableViewPrivate::disconnectFromModel()
{
+ Q_Q(QQuickTableView);
Q_TABLEVIEW_ASSERT(model, "");
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
@@ -2332,6 +2375,7 @@ void QQuickTableViewPrivate::disconnectFromModel()
const auto tm = tableModel.data();
QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
}
if (auto const aim = model->abstractItemModel()) {
@@ -2413,6 +2457,14 @@ void QQuickTableViewPrivate::layoutChangedCallback(const QList<QPersistentModelI
scheduleRebuildTable(RebuildOption::ViewportOnly);
}
+void QQuickTableViewPrivate::fetchMoreData()
+{
+ if (tableModel && tableModel->canFetchMore()) {
+ tableModel->fetchMore();
+ scheduleRebuildTable(RebuildOption::ViewportOnly);
+ }
+}
+
void QQuickTableViewPrivate::modelResetCallback()
{
scheduleRebuildTable(RebuildOption::All);
@@ -2678,6 +2730,23 @@ void QQuickTableView::setContentHeight(qreal height)
QQuickFlickable::setContentHeight(height);
}
+/*!
+ \qmlproperty TableView QtQuick::TableView::syncView
+
+ If this property of a TableView is set to another TableView, both the
+ tables will synchronize with regard to flicking, column widths/row heights,
+ and spacing according to \l syncDirection.
+
+ If \l syncDirection contains \l Qt.Horizontal, current tableView's column
+ widths, column spacing, and horizontal flicking movement synchronizes with
+ syncView's.
+
+ If \l syncDirection contains \l Qt.Vertical, current tableView's row
+ heights, row spacing, and vertical flicking movement synchronizes with
+ syncView's.
+
+ \sa syncDirection
+*/
QQuickTableView *QQuickTableView::syncView() const
{
return d_func()->assignedSyncView;
@@ -2695,6 +2764,24 @@ void QQuickTableView::setSyncView(QQuickTableView *view)
emit syncViewChanged();
}
+/*!
+ \qmlproperty Qt::Orientations QtQuick::TableView::syncDirection
+
+ If the \l syncView is set on a TableView, this property controls
+ synchronization of flicking direction(s) for both tables. The default is \c
+ {Qt.Horizontal | Qt.Vertical}, which means that if you flick either table
+ in either direction, the other table is flicked the same amount in the
+ same direction.
+
+ This property and \l syncView can be used to make two tableViews
+ synchronize with each other smoothly in flicking regardless of the different
+ overshoot/undershoot, velocity, acceleration/deceleration or rebound
+ animation, and so on.
+
+ A typical use case is to make several headers flick along with the table.
+
+ \sa syncView, headerView
+*/
Qt::Orientations QQuickTableView::syncDirection() const
{
return d_func()->assignedSyncDirection;
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index b66ac66dec..7c81882d44 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -54,6 +54,7 @@
#include "qquicktableview_p.h"
#include <QtCore/qtimer.h>
+#include <QtCore/private/qflatmap_p.h>
#include <QtQmlModels/private/qqmltableinstancemodel_p.h>
#include <QtQml/private/qqmlincubator_p.h>
#include <QtQmlModels/private/qqmlchangeset_p.h>
@@ -119,7 +120,7 @@ public:
qCDebug(lcTableViewDelegateLifecycle()) << "begin top-left:" << toString();
}
- void begin(Qt::Edge edgeToLoad, int edgeIndex, const QList<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode)
+ void begin(Qt::Edge edgeToLoad, int edgeIndex, const QVector<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode)
{
Q_ASSERT(!m_active);
m_active = true;
@@ -169,7 +170,7 @@ public:
private:
Qt::Edge m_edge = Qt::Edge(0);
- QList<int> m_visibleCellsInEdge;
+ QVector<int> m_visibleCellsInEdge;
int m_edgeIndex = 0;
int m_currentIndex = 0;
bool m_active = false;
@@ -246,8 +247,8 @@ public:
// we need to fill up with more rows/columns. loadedTableInnerRect describes the pixels
// that the loaded table covers if you remove one row/column on each side of the table, and
// is used to determine rows/columns that are no longer visible and can be unloaded.
- QMap<int, int> loadedColumns;
- QMap<int, int> loadedRows;
+ QFlatMap<int, int> loadedColumns;
+ QFlatMap<int, int> loadedRows;
QRectF loadedTableOuterRect;
QRectF loadedTableInnerRect;
@@ -322,7 +323,8 @@ public:
qreal sizeHintForColumn(int column);
qreal sizeHintForRow(int row);
- void calculateTableSize();
+ QSize calculateTableSize();
+ void updateTableSize();
inline bool isColumnHidden(int column);
inline bool isRowHidden(int row);
@@ -332,10 +334,10 @@ public:
qreal getColumnWidth(int column);
qreal getRowHeight(int row);
- inline int topRow() const { return loadedRows.firstKey(); }
- inline int bottomRow() const { return loadedRows.lastKey(); }
- inline int leftColumn() const { return loadedColumns.firstKey(); }
- inline int rightColumn() const { return loadedColumns.lastKey(); }
+ inline int topRow() const { return loadedRows.cbegin().key(); }
+ inline int bottomRow() const { return (--loadedRows.cend()).key(); }
+ inline int leftColumn() const { return loadedColumns.cbegin().key(); }
+ inline int rightColumn() const { return (--loadedColumns.cend()).key(); }
QQuickTableView *rootSyncView() const;
@@ -351,6 +353,7 @@ public:
void updateContentWidth();
void updateContentHeight();
void updateAverageEdgeSize();
+ RebuildOptions checkForVisibilityChanges();
void forceLayout();
void updateExtents();
@@ -424,6 +427,8 @@ public:
void setLocalViewportY(qreal contentY);
void syncViewportPosRecursive();
+ void fetchMoreData();
+
void _q_componentFinalized();
void registerCallbackWhenBindingsAreEvaluated();
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index a83b9beaa5..eda2029783 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1140,7 +1140,10 @@ QString QQuickTextInput::inputMask() const
void QQuickTextInput::setInputMask(const QString &im)
{
Q_D(QQuickTextInput);
- if (d->inputMask() == im)
+ QString canonicalInputMask = im;
+ if (im.lastIndexOf(QLatin1Char(';')) == -1)
+ canonicalInputMask.append(QLatin1String("; "));
+ if (d->inputMask() == canonicalInputMask)
return;
d->setInputMask(im);
@@ -3954,7 +3957,7 @@ bool QQuickTextInputPrivate::isValidInput(QChar key, QChar mask) const
return true;
break;
case 'X':
- if (key.isPrint())
+ if (key.isPrint() && key != m_blank)
return true;
break;
case 'x':
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 9998dc3605..84488dcaca 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -240,13 +240,12 @@ void QQuickView::setSource(const QUrl& url)
}
/*!
- Sets the initial properties with which the QML component gets initialized after
- calling \l QQuickView::setSource.
+ Sets the initial properties \a initialProperties with which the QML
+ component gets initialized after calling \l QQuickView::setSource().
+ \note You can only use this function to initialize top-level properties.
- Note that you can only use this function to initialize toplevel properties.
-
- \sa QQmlComponent::createWithInitialProperties
+ \sa QQmlComponent::createWithInitialProperties()
\since 5.14
*/
void QQuickView::setInitialProperties(const QVariantMap &initialProperties)
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 9b45750a3b..2eee98a738 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -527,7 +527,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
renderer->setDeviceRect(rect);
renderer->setViewportRect(rect);
const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (flipY)
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags);
@@ -1768,6 +1768,8 @@ bool QQuickWindow::event(QEvent *e)
if (e->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))
update();
+ else if (e->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure))
+ d->windowManager->handleContextCreationFailure(this);
return QWindow::event(e);
}
@@ -3254,10 +3256,9 @@ bool QQuickWindowPrivate::isRenderable() const
void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
- QString *untranslatedMessage,
- bool isEs)
+ QString *untranslatedMessage)
{
- const QString contextType = QLatin1String(isEs ? "EGL" : "OpenGL");
+ const QString contextType = QLatin1String("OpenGL");
QString formatStr;
QDebug(&formatStr) << format;
#if defined(Q_OS_WIN32)
@@ -3282,6 +3283,16 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo
#endif // !Q_OS_WIN32
}
+void QQuickWindowPrivate::rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage)
+{
+ const char msg[] = QT_TRANSLATE_NOOP("QQuickWindow",
+ "Failed to initialize graphics backend for %1.");
+ *translatedMessage = QQuickWindow::tr(msg).arg(backendName);
+ *untranslatedMessage = QString::fromLatin1(msg).arg(backendName);
+}
+
#if QT_DEPRECATED_SINCE(5, 8)
// ### Qt6: remove
@@ -4034,7 +4045,7 @@ QImage QQuickWindow::grabWindow()
Q_D(QQuickWindow);
if (!isVisible() && !d->renderControl) {
- // backends like software and d3d12 can grab regardless of the window state
+ // backends like software can grab regardless of the window state
if (d->windowManager && (d->windowManager->flags() & QSGRenderLoop::SupportsGrabWithoutExpose))
return d->windowManager->grab(this);
}
@@ -4444,7 +4455,7 @@ bool QQuickWindow::clearBeforeRendering() const
QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
{
- return createTextureFromImage(image, nullptr);
+ return createTextureFromImage(image, {});
}
@@ -4603,7 +4614,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
\a nativeLayout is only used for APIs like Vulkan. When applicable, it must
specify the current image layout, such as, a VkImageLayout value.
- \sa sceneGraphInitialized(), QSGTextures
+ \sa sceneGraphInitialized(), QSGTexture, QSGTexture::nativeTexture()
\since 5.14
*/
@@ -5503,9 +5514,6 @@ void QQuickWindow::setSceneGraphBackend(QSGRendererInterface::GraphicsApi api)
case QSGRendererInterface::Software:
setSceneGraphBackend(QStringLiteral("software"));
break;
- case QSGRendererInterface::Direct3D12:
- setSceneGraphBackend(QStringLiteral("d3d12"));
- break;
default:
break;
}
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index af7d65dac5..ef10ba3fe8 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -112,7 +112,8 @@ public:
Q_DECLARE_PUBLIC(QQuickWindow)
enum CustomEvents {
- FullUpdateRequest = QEvent::User + 1
+ FullUpdateRequest = QEvent::User + 1,
+ TriggerContextCreationFailure = QEvent::User + 2
};
static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); }
@@ -206,8 +207,8 @@ public:
};
Q_DECLARE_FLAGS(FocusOptions, FocusOption)
- void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
- void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
+ void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
+ void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
static void notifyFocusChangesRecur(QQuickItem **item, int remaining);
void clearFocusObject() override;
@@ -300,8 +301,10 @@ public:
static void contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
- QString *untranslatedMessage,
- bool isEs);
+ QString *untranslatedMessage);
+ static void rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage);
static void emitBeforeRenderPassRecording(void *ud);
static void emitAfterRenderPassRecording(void *ud);
diff --git a/src/quick/qtquick.tracepoints b/src/quick/qtquick.tracepoints
new file mode 100644
index 0000000000..f6518444d2
--- /dev/null
+++ b/src/quick/qtquick.tracepoints
@@ -0,0 +1,48 @@
+QSG_renderWindow_entry()
+QSG_renderWindow_exit()
+QSG_renderScene_entry()
+QSG_renderScene_exit()
+QSG_syncAndRender_entry()
+QSG_syncAndRender_exit()
+QSG_polishAndSync_entry()
+QSG_polishAndSync_exit()
+QSG_preprocess_entry()
+QSG_preprocess_exit()
+QSG_update_entry()
+QSG_update_exit()
+
+QSG_polishItems_entry()
+QSG_polishItems_exit()
+QSG_sync_entry()
+QSG_sync_exit()
+QSG_wait_entry()
+QSG_wait_exit()
+QSG_render_entry()
+QSG_render_exit()
+QSG_swap_entry()
+QSG_swap_exit()
+QSG_animations_entry()
+QSG_animations_exit()
+
+QSG_texture_prepare_entry()
+QSG_texture_prepare_exit()
+QSG_texture_bind_entry()
+QSG_texture_bind_exit()
+QSG_texture_delete_entry()
+QSG_texture_delete_exit()
+QSG_texture_upload_entry()
+QSG_texture_upload_exit()
+QSG_texture_mipmap_entry()
+QSG_texture_mipmap_exit()
+
+QSG_binding_entry()
+QSG_binding_exit()
+QSG_prepareMaterial_entry()
+QSG_prepareMaterial_exit()
+
+QSGDistanceFieldGlyphCache_update_entry(int count)
+QSGDistanceFieldGlyphCache_update_exit()
+QSGDistanceFieldGlyphCache_glyphRender_entry()
+QSGDistanceFieldGlyphCache_glyphRender_exit()
+QSGDistanceFieldGlyphCache_glyphStore_entry()
+QSGDistanceFieldGlyphCache_glyphStore_exit()
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index 527742ab8a..4ba7e896db 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -39,7 +39,6 @@
#include "qtquick2_p.h"
#include <private/qqmlengine_p.h>
-#include <private/qquickutilmodule_p.h>
#include <private/qquickvaluetypes_p.h>
#include <private/qquickitemsmodule_p.h>
#include <private/qquickaccessiblefactory_p.h>
@@ -55,6 +54,10 @@
#include <qqmlproperty.h>
#include <QtCore/QPointer>
+#if QT_CONFIG(shortcut)
+Q_DECLARE_METATYPE(QKeySequence::StandardKey)
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_CONFIG(qml_debug)
@@ -182,10 +185,12 @@ void QQmlQtQuick2Module::defineModule()
{
QQuick_initializeProviders();
- QQuickUtilModule::defineModule();
- QQuickItemsModule::defineModule();
+#if QT_CONFIG(shortcut)
+ qRegisterMetaType<QKeySequence::StandardKey>();
+#endif
QQuickValueTypes::registerValueTypes();
+ QQuickItemsModule::defineModule();
#if QT_CONFIG(accessibility)
QAccessible::installFactory(&qQuickAccessibleFactory);
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 700f794af4..42bb4b6ec8 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -4,6 +4,9 @@ QT = core-private gui-private qml-private qmlmodels-private
qtConfig(qml-network): \
QT_PRIVATE += network
+TRACEPOINT_PROVIDER = $$PWD/qtquick.tracepoints
+CONFIG += qt_tracepoints
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
msvc:DEFINES *= _CRT_SECURE_NO_WARNINGS
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
@@ -47,3 +50,9 @@ SOURCES += qtquick2.cpp
INCLUDEPATH += $$PWD
load(qt_module)
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick.2
+QML_IMPORT_NAME = QtQuick
+IMPORT_VERSION = 2.15
+CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index ca620965a8..49151551b1 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -77,6 +77,12 @@ QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode *
return m_nodes.value(node, nullptr);
}
+// Used by GammaRay
+const QVector<QSGSoftwareRenderableNode*> &QSGAbstractSoftwareRenderer::renderableNodes() const
+{
+ return m_renderableNodes;
+}
+
void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode)
{
m_nodes.insert(node, renderableNode);
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index e1b477ab97..d4bfb5a9f7 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -87,6 +87,7 @@ protected:
QRect backgroundRect();
// only known after calling optimizeRenderList()
bool isOpaque() const { return m_isOpaque; }
+ const QVector<QSGSoftwareRenderableNode*> &renderableNodes() const;
private:
void nodeAdded(QSGNode *node);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 7b5ee66df6..f1d0e28fc8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -206,12 +206,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const
QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const
{
- return nullptr;
+ return {};
}
QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const
{
- return nullptr;
+ return {};
}
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index da5d39db20..214f7d790b 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -465,7 +465,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter)
m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
- margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
return;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
index 141d8f3c6d..a10a94125c 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
@@ -205,7 +205,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter)
painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height()));
else
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()),
- m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
}
QRectF QSGSoftwareNinePatchNode::bounds() const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index c97dcb9326..c010e0cae5 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -52,6 +52,8 @@
#include <QtGui/QBackingStore>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
QSGSoftwareRenderLoop::QSGSoftwareRenderLoop()
@@ -133,20 +135,25 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (!m_windows.contains(window))
return;
}
+
+ Q_TRACE_SCOPE(QSG_renderWindow)
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -155,8 +162,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
//Tell the renderer about the windows backing store
auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
@@ -167,8 +176,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
grabContent = m_backingStores[window]->handle()->toImage();
@@ -187,6 +198,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index c6b463bb02..1de9415dd0 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -60,6 +60,8 @@
#include <QtGui/QBackingStore>
#include <QtQuick/QQuickWindow>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Passed from the RL to the RT when a window is removed obscured and should be
@@ -421,7 +423,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - sync");
mutex.lock();
- Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked");
+ Q_ASSERT_X(renderLoop->lockedForSync, "QSGSoftwareRenderThread::sync()", "sync triggered with gui not locked");
if (exposedWindow) {
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
@@ -457,6 +459,8 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
void QSGSoftwareRenderThread::syncAndRender()
{
+ Q_TRACE_SCOPE(QSG_syncAndRender);
+ Q_TRACE(QSG_sync_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
QElapsedTimer waitTimer;
@@ -475,6 +479,7 @@ void QSGSoftwareRenderThread::syncAndRender()
if (syncRequested)
sync(exposeRequested);
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
@@ -487,6 +492,7 @@ void QSGSoftwareRenderThread::syncAndRender()
}
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering started");
+ Q_TRACE(QSG_render_entry);
if (rtAnim->isRunning()) {
wd->animationController->lock();
@@ -502,8 +508,10 @@ void QSGSoftwareRenderThread::syncAndRender()
softwareRenderer->setBackingStore(backingStore);
wd->renderSceneGraph(exposedWindow->size());
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (softwareRenderer && (!wd->customRenderStage || !wd->customRenderStage->swap()))
backingStore->flush(softwareRenderer->flushRegion());
@@ -519,8 +527,10 @@ void QSGSoftwareRenderThread::syncAndRender()
wd->fireFrameSwapped();
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - window not ready, skipping render");
}
@@ -532,6 +542,7 @@ void QSGSoftwareRenderThread::syncAndRender()
mutex.unlock();
}
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
}
@@ -947,13 +958,18 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
return;
}
+ Q_TRACE_SCOPE(QSG_polishAndSync);
+
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
wd->polishItems();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_sync_entry);
w->updateDuringSync = false;
@@ -967,15 +983,19 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - wait for sync");
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_wait_entry);
w->thread->waitCondition.wait(&w->thread->mutex);
lockedForSync = false;
w->thread->mutex.unlock();
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - unlock after sync");
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (!animationTimer && m_anim->isRunning()) {
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - advancing animations");
@@ -987,6 +1007,7 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
w->window->requestUpdate();
}
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
index 1a8bddaa6e..65abb2a1af 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -296,7 +296,7 @@ void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdate
return;
}
- QRhiTexture::Flags texFlags = 0;
+ QRhiTexture::Flags texFlags;
if (fmt.second)
texFlags |= QRhiTexture::sRGB;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 45b00d43c4..5401401a0e 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -62,6 +62,8 @@
#include "qsgopenglvisualizer_p.h"
#include "qsgrhivisualizer_p.h"
+#include <qtquick_tracepoints_p.h>
+
#include <algorithm>
#ifndef GL_DOUBLE
@@ -270,6 +272,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, boo
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -332,6 +335,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -379,6 +383,9 @@ void ShaderManager::invalidated()
qDeleteAll(srbCache);
srbCache.clear();
+
+ qDeleteAll(pipelineCache);
+ pipelineCache.clear();
}
void ShaderManager::clearCachedRendererData()
@@ -546,7 +553,7 @@ void Updater::visitNode(Node *n)
m_added = count;
m_force_update = force;
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
void Updater::visitClipNode(Node *n)
@@ -1103,13 +1110,9 @@ void Renderer::destroyGraphicsResources()
// are going to destroy.
m_shaderManager->clearCachedRendererData();
- qDeleteAll(m_pipelines);
qDeleteAll(m_samplers);
-
m_stencilClipCommon.reset();
-
delete m_dummyTexture;
-
m_visualizer->releaseResources();
}
@@ -1119,7 +1122,6 @@ void Renderer::releaseCachedResources()
destroyGraphicsResources();
- m_pipelines.clear();
m_samplers.clear();
m_dummyTexture = nullptr;
@@ -2627,7 +2629,7 @@ QRhiGraphicsPipeline *Renderer::buildStencilPipeline(const Batch *batch, bool fi
QRhiGraphicsPipeline *ps = m_rhi->newGraphicsPipeline();
ps->setFlags(QRhiGraphicsPipeline::UsesStencilRef);
QRhiGraphicsPipeline::TargetBlend blend;
- blend.colorWrite = 0;
+ blend.colorWrite = {};
ps->setTargetBlends({ blend });
ps->setSampleCount(renderTarget()->sampleCount());
ps->setStencilTest(true);
@@ -3237,15 +3239,17 @@ static inline bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f)
bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) // RHI only, [prepare step]
{
- // In unmerged batches the srbs in the elements are all compatible layout-wise.
+ // In unmerged batches the srbs in the elements are all compatible
+ // layout-wise. Note the key's == and qHash implementations: the rp desc and
+ // srb are tested for (layout) compatibility, not pointer equality.
const GraphicsPipelineStateKey k { m_gstate, sms, renderPassDescriptor(), e->srb };
// Note: dynamic state (viewport rect, scissor rect, stencil ref, blend
// constant) is never a part of GraphicsState/QRhiGraphicsPipeline.
// See if there is an existing, matching pipeline state object.
- auto it = m_pipelines.constFind(k);
- if (it != m_pipelines.constEnd()) {
+ auto it = m_shaderManager->pipelineCache.constFind(k);
+ if (it != m_shaderManager->pipelineCache.constEnd()) {
e->ps = *it;
return true;
}
@@ -3257,7 +3261,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
ps->setShaderResourceBindings(e->srb);
ps->setRenderPassDescriptor(renderPassDescriptor());
- QRhiGraphicsPipeline::Flags flags = 0;
+ QRhiGraphicsPipeline::Flags flags;
if (needsBlendConstant(m_gstate.srcColor) || needsBlendConstant(m_gstate.dstColor))
flags |= QRhiGraphicsPipeline::UsesBlendConstants;
if (m_gstate.usesScissor)
@@ -3302,7 +3306,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
return false;
}
- m_pipelines.insert(k, ps);
+ m_shaderManager->pipelineCache.insert(k, ps);
e->ps = ps;
return true;
}
@@ -4643,7 +4647,7 @@ bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
{
return a.state == b.state
&& a.sms->programRhi.program == b.sms->programRhi.program
- && a.rpDesc == b.rpDesc
+ && a.compatibleRenderPassDescriptor->isCompatible(b.compatibleRenderPassDescriptor)
&& a.layoutCompatibleSrb->isLayoutCompatible(b.layoutCompatibleSrb);
}
@@ -4654,7 +4658,8 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
uint qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW
{
- return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed) + qHash(k.rpDesc, seed);
+ // no srb and rp included due to their special comparison semantics and lack of hash keys
+ return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed);
}
Visualizer::Visualizer(Renderer *renderer)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 297df2232a..878b63fc8c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -626,27 +626,65 @@ private:
QMatrix4x4 m_identityMatrix;
};
+struct GraphicsState
+{
+ bool depthTest = false;
+ bool depthWrite = false;
+ QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
+ bool blending = false;
+ QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
+ QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
+ QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
+ QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
+ bool usesScissor = false;
+ bool stencilTest = false;
+ int sampleCount = 1;
+ QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
+ float lineWidth = 1.0f;
+};
+
+bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader;
+
+struct GraphicsPipelineStateKey
+{
+ GraphicsState state;
+ const ShaderManagerShader *sms;
+ const QRhiRenderPassDescriptor *compatibleRenderPassDescriptor;
+ const QRhiShaderResourceBindings *layoutCompatibleSrb;
+};
+
+bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader
+{
+ ~ShaderManagerShader() {
+ delete programRhi.program;
+ delete programGL.program;
+ }
+ struct {
+ QSGMaterialShader *program = nullptr;
+ int pos_order;
+ } programGL;
+ struct {
+ QSGMaterialRhiShader *program = nullptr;
+ QRhiVertexInputLayout inputLayout;
+ QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
+ } programRhi;
+
+ float lastOpacity;
+};
+
class ShaderManager : public QObject
{
Q_OBJECT
public:
- struct Shader {
- ~Shader() {
- delete programRhi.program;
- delete programGL.program;
- }
- struct {
- QSGMaterialShader *program = nullptr;
- int pos_order;
- } programGL;
- struct {
- QSGMaterialRhiShader *program = nullptr;
- QRhiVertexInputLayout inputLayout;
- QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
- } programRhi;
-
- float lastOpacity;
- };
+ using Shader = ShaderManagerShader;
ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(nullptr), context(ctx) { }
~ShaderManager() {
@@ -657,9 +695,10 @@ public:
void clearCachedRendererData();
using ShaderResourceBindingList = QVarLengthArray<QRhiShaderResourceBinding, 8>;
-
QRhiShaderResourceBindings *srb(const ShaderResourceBindingList &bindings);
+ QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache;
+
public Q_SLOTS:
void invalidated();
@@ -677,39 +716,6 @@ private:
QHash<ShaderResourceBindingList, QRhiShaderResourceBindings *> srbCache;
};
-struct GraphicsState
-{
- bool depthTest = false;
- bool depthWrite = false;
- QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
- bool blending = false;
- QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
- QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
- QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
- QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
- bool usesScissor = false;
- bool stencilTest = false;
- int sampleCount = 1;
- QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
- float lineWidth = 1.0f;
-};
-
-bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
-
-struct GraphicsPipelineStateKey
-{
- GraphicsState state;
- const ShaderManager::Shader *sms;
- const QRhiRenderPassDescriptor *rpDesc;
- const QRhiShaderResourceBindings *layoutCompatibleSrb;
-};
-
-bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
-
struct RenderPassState
{
QRhiViewport viewport;
@@ -903,7 +909,6 @@ private:
GraphicsState m_gstate;
RenderPassState m_pstate;
QStack<GraphicsState> m_gstateStack;
- QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> m_pipelines;
QHash<QSGSamplerDescription, QRhiSampler *> m_samplers;
QRhiTexture *m_dummyTexture = nullptr;
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index c8ae26311b..087c3c4cbf 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -153,7 +153,6 @@ static void qt_print_material_count()
*/
QSGMaterial::QSGMaterial()
- : m_flags(nullptr)
{
Q_UNUSED(m_reserved);
#ifndef QT_NO_DEBUG
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
index 117d477f9a..c5cbd0c979 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
@@ -97,14 +97,14 @@ static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage st
Q_UNREACHABLE();
break;
}
- return 0;
+ return { };
}
void QSGMaterialRhiShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
{
ubufBinding = -1;
ubufSize = 0;
- ubufStages = 0;
+ ubufStages = { };
memset(combinedImageSamplerBindings, 0, sizeof(combinedImageSamplerBindings));
vertexShader = fragmentShader = nullptr;
masterUniformData.clear();
@@ -319,7 +319,7 @@ bool QSGMaterialRhiShader::updateUniformData(RenderState &state,
each variable in the material's shaders'
\l{QShaderDescription::combinedImageSamplers()}.
- When \c{*texture} is null, it must be set to a QSGTexture pointer before
+ When *\a{texture} is null, it must be set to a QSGTexture pointer before
returning. When non-null, it is up to the material to decide if a new
\c{QSGTexture *} is stored to it, or if it updates some parameters on the
already known QSGTexture. The ownership of the QSGTexture is not
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 7d9b74bc2b..a35629d874 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -245,7 +245,6 @@ static void qt_print_node_count()
*/
QSGNode::QSGNode()
: m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -264,7 +263,6 @@ QSGNode::QSGNode(NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -283,7 +281,6 @@ QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
, d_ptr(&dd)
{
init();
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index cb677de030..5a7faed5e0 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -146,7 +146,7 @@ public:
QT_DEPRECATED void clearDirty() { }
void markDirty(DirtyState bits);
- QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
+ QT_DEPRECATED DirtyState dirtyState() const { return { }; }
virtual bool isSubtreeBlocked() const;
diff --git a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
index 6c2ff0b176..9282b6c308 100644
--- a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
@@ -202,7 +202,7 @@ void OpenGLVisualizer::visualizeChanges(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 7af932eeb5..90090e1cc0 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -45,6 +45,7 @@
# include <QtGui/QOpenGLFunctions>
#endif
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <QtCore/QElapsedTimer>
@@ -221,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
if (!rootNode())
return;
+ Q_TRACE_SCOPE(QSG_renderScene);
m_is_rendering = true;
@@ -235,11 +237,14 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
m_bindable = &bindable;
preprocess();
+ Q_TRACE(QSG_binding_entry);
bindable.bind();
if (profileFrames)
bindTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_binding_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererBinding);
+ Q_TRACE(QSG_render_entry);
#if QT_CONFIG(opengl)
// Sanity check that attribute registers are disabled
@@ -259,6 +264,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
render();
if (profileFrames)
renderTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererRender);
@@ -305,6 +311,8 @@ void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
void QSGRenderer::preprocess()
{
+ Q_TRACE(QSG_preprocess_entry);
+
m_is_preprocessing = true;
QSGRootNode *root = rootNode();
@@ -331,13 +339,16 @@ void QSGRenderer::preprocess()
bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
if (profileFrames)
preprocessTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_preprocess_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererPreprocess);
+ Q_TRACE(QSG_update_entry);
nodeUpdater()->updateStates(root);
if (profileFrames)
updatePassTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_update_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererUpdate);
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
index 0fee1486cf..9b5701df5a 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
@@ -76,7 +76,6 @@ QT_BEGIN_NAMESPACE
\value Unknown An unknown graphics API is in use
\value Software The Qt Quick 2D Renderer is in use
\value OpenGL OpenGL ES 2.0 or higher
- \value Direct3D12 Direct3D 12
\value OpenVG OpenVG via EGL
\value OpenGLRhi OpenGL ES 2.0 or higher via a graphics abstraction layer. This value was introduced in Qt 5.14.
\value Direct3D11Rhi Direct3D 11 via a graphics abstraction layer. This value was introduced in Qt 5.14.
@@ -189,10 +188,10 @@ QSGRendererInterface::~QSGRendererInterface()
not supported or not available.
When successful, the returned pointer is either a direct pointer to an
- interface (and can be cast, for example, to \c{ID3D12Device *}) or a
- pointer to an opaque handle that needs to be dereferenced first (for
- example, \c{VkDevice dev = *static_cast<VkDevice *>(result)}). The latter
- is necessary since such handles may have sizes different from a pointer.
+ interface, or a pointer to an opaque handle that needs to be dereferenced
+ first (for example, \c{VkDevice dev = *static_cast<VkDevice
+ *>(result)}). The latter is necessary since such handles may have sizes
+ different from a pointer.
\note The ownership of the returned pointer is never transferred to the caller.
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.h b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
index 7aa7d0e769..6224e08e84 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.h
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
@@ -53,7 +53,6 @@ public:
Unknown,
Software,
OpenGL,
- Direct3D12,
OpenVG,
OpenGLRhi,
Direct3D11Rhi,
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 2892f2f966..519e3cd017 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -99,8 +99,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
With APIs other than OpenGL, the only relevant values are the ones that
correspond to dynamic state changes recorded on the command list/buffer.
- For example, RSSetViewports, RSSetScissorRects, OMSetBlendFactor,
- OMSetStencilRef in case of D3D12, or vkCmdSetViewport, vkCmdSetScissor,
+ For example, RSSetViewports, RSSetScissorRects, OMSetBlendState,
+ OMSetDepthStencilState in case of D3D11, or vkCmdSetViewport, vkCmdSetScissor,
vkCmdSetBlendConstants, vkCmdSetStencilRef in case of Vulkan, and only when
such commands were added to the scenegraph's command list queried via the
QSGRendererInterface::CommandList resource enum. States set in pipeline
@@ -131,7 +131,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
{
- return nullptr;
+ return {};
}
/*!
@@ -311,7 +311,7 @@ void QSGRenderNode::releaseResources()
*/
QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
{
- return nullptr;
+ return {};
}
/*!
@@ -381,11 +381,6 @@ QSGRenderNode::RenderState::~RenderState()
\return the current scissor rectangle when clipping is active. x and y are
the bottom left coordinates.
-
- \note Be aware of the differences between graphics APIs: for some the
- scissor rect is only active when scissoring is enabled (for example,
- OpenGL), while for others the scissor rect is equal to the viewport rect
- when there is no need to scissor away anything (for example, Direct3D 12).
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
index 38d4c4440f..a0131a3f67 100644
--- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
@@ -400,7 +400,7 @@ void RhiVisualizer::ChangeVis::gather(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = { };
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index edcee96bdb..715633fdba 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -317,6 +317,34 @@ static void qt_debug_remove_texture(QSGTexture* texture)
\since 5.9
*/
+/*!
+ \class QSGTexture::NativeTexture
+ \brief Contains information about the underlying native resources of a texture.
+ \since 5.15
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::object
+ \brief a pointer to the native object handle.
+
+ With OpenGL, the native handle is a GLuint value, so \c object is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \c
+ object is a pointer to a VkImage. With Direct3D 11 and Metal \c
+ object is a pointer to a ID3D11Texture2D or MTLTexture pointer, respectively.
+
+ \note Pay attention to the fact that \a object is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::layout
+ \brief Specifies the current image layout for APIs like Vulkan.
+
+ For Vulkan, \c layout contains a \c VkImageLayout value.
+ */
+
+
#ifndef QT_NO_DEBUG
Q_QUICK_PRIVATE_EXPORT void qsg_set_material_failure();
#endif
@@ -395,6 +423,9 @@ QSGTexture::~QSGTexture()
Binding a texture may also include uploading the texture data from
a previously set QImage.
+ \warning This function should only be called when running with the
+ direct OpenGL rendering path.
+
\warning This function can only be called from the rendering thread.
*/
@@ -701,8 +732,8 @@ void QSGTexture::updateBindOptions(bool force) // legacy (GL-only)
data (for example, because there was no setImage() since the last call to
this function), the function does nothing.
- Materials involving textures are expected to call this function from their
- updateSampledImage() implementation, typically without any conditions.
+ Materials involving \a rhi textures are expected to call this function from
+ their updateSampledImage() implementation, typically without any conditions.
\note This function is only used when running the graphics API independent
rendering path of the scene graph.
@@ -718,6 +749,28 @@ void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUp
}
/*!
+ \return the platform-specific texture data for this texture.
+
+ \note This is only available when running the graphics API independent
+ rendering path of the scene graph. Use textureId() otherwise.
+
+ Returns an empty result (\c object is null) if there is no available
+ underlying native texture.
+
+ \since 5.15
+ \sa QQuickWindow::createTextureFromNativeObject()
+ */
+QSGTexture::NativeTexture QSGTexture::nativeTexture() const
+{
+ Q_D(const QSGTexture);
+ if (auto *tex = d->rhiTexture()) {
+ auto nativeTexture = tex->nativeTexture();
+ return {nativeTexture.object, nativeTexture.layout};
+ }
+ return {};
+}
+
+/*!
\internal
*/
void QSGTexture::setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates)
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h
index 2efdd8b7c3..207ef52f4e 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture.h
@@ -80,7 +80,13 @@ public:
Anisotropy16x
};
+ struct NativeTexture {
+ const void *object;
+ int layout;
+ };
+
virtual int textureId() const = 0; // ### Qt 6: remove
+ NativeTexture nativeTexture() const;
virtual QSize textureSize() const = 0;
virtual bool hasAlphaChannel() const = 0;
virtual bool hasMipmaps() const = 0;
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index f7b07d724a..eab0369be7 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -50,6 +50,8 @@
#include <private/qquickprofiler_p.h>
#include <QElapsedTimer>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
static QElapsedTimer qsg_render_timer;
@@ -169,10 +171,13 @@ void QSGDistanceFieldGlyphCache::update()
if (m_pendingGlyphs.isEmpty())
return;
+ Q_TRACE_SCOPE(QSGDistanceFieldGlyphCache_update, m_pendingGlyphs.size());
+
bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled();
if (profileFrames)
qsg_render_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_entry);
QList<QDistanceField> distanceFields;
const int pendingGlyphsSize = m_pendingGlyphs.size();
@@ -189,8 +194,11 @@ void QSGDistanceFieldGlyphCache::update()
int count = m_pendingGlyphs.size();
if (profileFrames)
renderTime = qsg_render_timer.nsecsElapsed();
+
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphRender);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_entry);
m_pendingGlyphs.reset();
@@ -210,6 +218,7 @@ void QSGDistanceFieldGlyphCache::update()
int(renderTime / 1000000),
int((now - (renderTime / 1000000))));
}
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_exit);
Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphStore,
(qint64)count);
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 66add51c55..7dfb8488ae 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -87,7 +87,6 @@ struct QSGAdaptationBackendData
};
QSGAdaptationBackendData::QSGAdaptationBackendData()
- : flags(nullptr)
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index f609055677..94f15b55d4 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -60,6 +60,7 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <private/qsgrhishadereffectnode_p.h>
@@ -195,8 +196,16 @@ public:
bool eventFilter(QObject *watched, QEvent *event) override;
struct WindowData {
+ WindowData()
+ : updatePending(false),
+ grabOnly(false),
+ rhiDeviceLost(false),
+ rhiDoomed(false)
+ { }
bool updatePending : 1;
bool grabOnly : 1;
+ bool rhiDeviceLost : 1;
+ bool rhiDoomed : 1;
};
QHash<QQuickWindow *, WindowData> m_windows;
@@ -316,15 +325,19 @@ void QSGRenderLoop::setInstance(QSGRenderLoop *instance)
s_instance = instance;
}
-void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
- bool isEs)
+void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window)
{
QString translatedMessage;
QString untranslatedMessage;
- QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ if (QSGRhiSupport::instance()->isRhiEnabled()) {
+ QQuickWindowPrivate::rhiCreationFailureMessage(QSGRhiSupport::instance()->rhiBackendName(),
&translatedMessage,
- &untranslatedMessage,
- isEs);
+ &untranslatedMessage);
+ } else {
+ QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ &translatedMessage,
+ &untranslatedMessage);
+ }
// If there is a slot connected to the error signal, emit it and leave it to
// the application to do something with the message. If nothing is connected,
// show a message on our own and terminate.
@@ -362,10 +375,7 @@ QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop()
void QSGGuiThreadRenderLoop::show(QQuickWindow *window)
{
- WindowData data;
- data.updatePending = false;
- data.grabOnly = false;
- m_windows[window] = data;
+ m_windows[window] = WindowData();
maybeUpdate(window);
}
@@ -451,8 +461,10 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
rc->invalidate();
- for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it)
+ for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) {
releaseSwapchain(it.key());
+ it->rhiDeviceLost = true;
+ }
delete rhi;
rhi = nullptr;
@@ -508,6 +520,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool enableRhi = rhiSupport->isRhiEnabled();
if (enableRhi && !rhi) {
+ // This block below handles both the initial QRhi initialization and
+ // also the subsequent reinitialization attempts after a device lost
+ // (reset) situation.
+
+ if (data.rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
+
if (!offscreenSurface)
offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
@@ -517,6 +536,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi);
+ data.rhiDeviceLost = false;
+
current = true;
rhi->makeThreadLocalNativeContextCurrent();
@@ -533,7 +554,11 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
rcParams.maybeSurface = window;
cd->context->initialize(&rcParams);
} else {
- handleContextCreationFailure(window, false);
+ if (!data.rhiDeviceLost) {
+ data.rhiDoomed = true;
+ handleContextCreationFailure(window);
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
}
} else if (!enableRhi && !gl) {
gl = new QOpenGLContext();
@@ -542,10 +567,9 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (qt_gl_global_share_context())
gl->setShareContext(qt_gl_global_share_context());
if (!gl->create()) {
- const bool isEs = gl->isOpenGLES();
delete gl;
gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
} else {
if (!offscreenSurface) {
offscreenSurface = new QOffscreenSurface;
@@ -619,7 +643,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
i++;
}
- // Check for context loss.
+ // Check for context loss. (legacy GL only)
if (!current && !rhi && !gl->isValid()) {
for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) {
QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key());
@@ -657,20 +681,25 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
return;
}
+ Q_TRACE_SCOPE(QSG_renderWindow);
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -725,15 +754,20 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
cd->renderSceneGraph(window->size(), effectiveOutputSize);
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
const bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
@@ -747,7 +781,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool needsPresent = alsoSwap && window->isVisible();
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
+ QRhi::EndFrameFlags flags;
if (!needsPresent)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
@@ -767,6 +801,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 02d0b84de1..9fd0ab02f5 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -112,12 +112,11 @@ public:
static void cleanup();
+ void handleContextCreationFailure(QQuickWindow *window);
+
Q_SIGNALS:
void timeToIncubate();
-protected:
- void handleContextCreationFailure(QQuickWindow *window, bool isEs);
-
private:
static QSGRenderLoop *s_instance;
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index 757410eded..952279a3ff 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -388,7 +388,7 @@ void QSGRhiLayer::grab()
m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
m_mirrorVertical ? m_rect.height() : -m_rect.height());
}
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (!m_rhi->isYUpInNDC())
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
m_renderer->setProjectionMatrixToRect(mirrored, matrixFlags);
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index 12c6742342..9194d3e730 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -159,7 +159,7 @@ void QSGRhiSupport::applySettings()
} else {
#if defined(Q_OS_WIN)
m_rhiBackend = QRhi::D3D11;
-#elif defined(Q_OS_DARWIN)
+#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS)
m_rhiBackend = QRhi::Metal;
#else
m_rhiBackend = QRhi::OpenGLES2;
@@ -185,29 +185,10 @@ void QSGRhiSupport::applySettings()
if (m_killDeviceFrameCount > 0 && m_rhiBackend == QRhi::D3D11)
qDebug("Graphics device will be reset every %d frames", m_killDeviceFrameCount);
- const char *backendName = "unknown";
- switch (m_rhiBackend) {
- case QRhi::Null:
- backendName = "Null";
- break;
- case QRhi::Vulkan:
- backendName = "Vulkan";
- break;
- case QRhi::OpenGLES2:
- backendName = "OpenGL";
- break;
- case QRhi::D3D11:
- backendName = "D3D11";
- break;
- case QRhi::Metal:
- backendName = "Metal";
- break;
- default:
- break;
- }
+ const QString backendName = rhiBackendName();
qCDebug(QSG_LOG_INFO,
"Using QRhi with backend %s\n graphics API debug/validation layers: %d\n QRhi profiling and debug markers: %d",
- backendName, m_debugLayer, m_profile);
+ qPrintable(backendName), m_debugLayer, m_profile);
if (m_preferSoftwareRenderer)
qCDebug(QSG_LOG_INFO, "Prioritizing software renderers");
}
@@ -247,6 +228,27 @@ QSGRhiSupport *QSGRhiSupport::instance()
return inst;
}
+QString QSGRhiSupport::rhiBackendName() const
+{
+ if (m_enableRhi) {
+ switch (m_rhiBackend) {
+ case QRhi::Null:
+ return QLatin1String("Null");
+ case QRhi::Vulkan:
+ return QLatin1String("Vulkan");
+ case QRhi::OpenGLES2:
+ return QLatin1String("OpenGL");
+ case QRhi::D3D11:
+ return QLatin1String("D3D11");
+ case QRhi::Metal:
+ return QLatin1String("Metal");
+ default:
+ return QLatin1String("Unknown");
+ }
+ }
+ return QLatin1String("Unknown (RHI not enabled)");
+}
+
QSGRendererInterface::GraphicsApi QSGRhiSupport::graphicsApi() const
{
if (!m_enableRhi)
@@ -350,7 +352,7 @@ static const void *qsgrhi_d3d11_rifResource(QSGRendererInterface::Resource res,
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, const QRhiNativeHandles *nat,
const QRhiNativeHandles *cbNat)
{
@@ -408,7 +410,7 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const
case QRhi::D3D11:
return qsgrhi_d3d11_rifResource(res, nat);
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
case QRhi::Metal:
{
QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer();
@@ -463,9 +465,13 @@ QOffscreenSurface *QSGRhiSupport::maybeCreateOffscreenSurface(QWindow *window)
// must be called on the render thread
QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurface)
{
+#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan)
+ Q_UNUSED(window);
+#endif
+
QRhi *rhi = nullptr;
- QRhi::Flags flags = 0;
+ QRhi::Flags flags;
if (isProfilingRequested())
flags |= QRhi::EnableProfiling | QRhi::EnableDebugMarkers;
if (isSoftwareRendererRequested())
@@ -485,6 +491,8 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhiParams.window = window;
rhi = QRhi::create(backend, &rhiParams, flags);
}
+#else
+ Q_UNUSED(offscreenSurface);
#endif
#if QT_CONFIG(vulkan)
if (backend == QRhi::Vulkan) {
@@ -507,7 +515,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhi = QRhi::create(backend, &rhiParams, flags);
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (backend == QRhi::Metal) {
QRhiMetalInitParams rhiParams;
rhi = QRhi::create(backend, &rhiParams, flags);
diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h
index d008ecd0af..0a95a09ad2 100644
--- a/src/quick/scenegraph/qsgrhisupport_p.h
+++ b/src/quick/scenegraph/qsgrhisupport_p.h
@@ -70,7 +70,7 @@
#include <QtGui/private/qrhid3d11_p.h>
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
#include <QtGui/private/qrhimetal_p.h>
#endif
@@ -109,6 +109,7 @@ public:
bool isRhiEnabled() const { return m_enableRhi; }
QRhi::Implementation rhiBackend() const { return m_rhiBackend; }
+ QString rhiBackendName() const;
QSGRendererInterface::GraphicsApi graphicsApi() const;
bool isDebugLayerRequested() const { return m_debugLayer; }
diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
index d0108bc56e..89c9ea4d5b 100644
--- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
@@ -145,7 +145,9 @@ void QSGRhiTextureGlyphCache::prepareGlyphImage(QImage *img)
{
const int maskWidth = img->width();
const int maskHeight = img->height();
+#if Q_BYTE_ORDER != Q_BIG_ENDIAN
const bool supportsBgra = m_rhi->isTextureFormatSupported(QRhiTexture::BGRA8);
+#endif
m_bgra = false;
if (img->format() == QImage::Format_Mono) {
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index dc1f97de54..4777f46f0a 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -70,6 +70,8 @@
#include <private/qsgrhishadereffectnode_p.h>
#include <private/qsgdefaultrendercontext_p.h>
+#include <qtquick_tracepoints_p.h>
+
/*
Overall design:
@@ -368,6 +370,9 @@ public:
QSize windowSize;
float dpr = 1;
int rhiSampleCount = 1;
+ bool rhiDeviceLost = false;
+ bool rhiDoomed = false;
+ bool guiNotifiedAboutRhiFailure = false;
// Local event queue stuff...
bool stopEventProcessing;
@@ -622,13 +627,15 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
sgrc->initialize(&rcParams);
}
}
- } else {
+ } else if (rhi) {
// With the rhi making the (OpenGL) context current serves only one
// purpose: to enable external OpenGL rendering connected to one of
// the QQuickWindow signals (beforeSynchronizing, beforeRendering,
// etc.) to function like it did on the direct OpenGL path. For our
// own rendering this call would not be necessary.
rhi->makeThreadLocalNativeContextCurrent();
+ } else {
+ current = false;
}
if (current) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -669,6 +676,7 @@ void QSGRenderThread::handleDeviceLoss()
QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown();
sgrc->invalidate();
wm->releaseSwapchain(window);
+ rhiDeviceLost = true;
delete rhi;
rhi = nullptr;
}
@@ -680,7 +688,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
sinceLastTime = threadTimer.nsecsElapsed();
threadTimer.start();
}
+ Q_TRACE_SCOPE(QSG_syncAndRender);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
+ Q_TRACE(QSG_sync_entry);
QElapsedTimer waitTimer;
waitTimer.start();
@@ -693,8 +703,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
const bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage;
const bool syncRequested = (pendingUpdate & SyncRequest) || grabImage;
const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;
- pendingUpdate = 0;
const bool grabRequested = grabImage != nullptr;
+ if (!grabRequested)
+ pendingUpdate = 0;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
// Begin the frame before syncing -> sync is where we may invoke
@@ -767,33 +778,46 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
syncTime = threadTimer.nsecsElapsed();
#endif
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
- if (!syncResultedInChanges && !repaintRequested && sgrc->isValid() && !grabImage) {
- if (gl || !rhi->isRecordingFrame()) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
+ if (!syncResultedInChanges
+ && !repaintRequested
+ && !(pendingUpdate & RepaintRequest) // may have been set in sync()
+ && sgrc->isValid()
+ && !grabRequested
+ && (gl || (rhi && !rhi->isRecordingFrame())))
+ {
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
+ int waitTime = vsyncDelta - (int) waitTimer.elapsed();
+ if (waitTime > 0)
+ msleep(waitTime);
+ return;
}
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
+ Q_TRACE(QSG_render_entry);
+
+ // RepaintRequest may have been set in pendingUpdate in an
+ // updatePaintNode() invoked from sync(). We are about to do a repaint
+ // right now, so reset the flag. (bits other than RepaintRequest cannot
+ // be set in pendingUpdate at this point)
+ if (!grabRequested)
+ pendingUpdate = 0;
- if (animatorDriver->isRunning() && !grabImage) {
+ if (animatorDriver->isRunning() && !grabRequested) {
d->animationController->lock();
animatorDriver->advance();
d->animationController->unlock();
}
bool current = true;
- if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) {
+ if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0 && (gl || rhi)) {
if (gl)
current = gl->makeCurrent(window);
- else if (rhi)
+ else
rhi->makeThreadLocalNativeContextCurrent();
} else {
current = false;
@@ -811,21 +835,23 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
renderTime = threadTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
// With the rhi grabs can only be done by adding a readback and then
// blocking in a real frame. The legacy GL path never gets here with
// grabs as it rather invokes sync/render directly without going
// through syncAndRender().
- if (grabImage) {
+ if (grabRequested) {
Q_ASSERT(rhi && !gl && cd->swapchain);
*grabImage = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain);
}
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
- if (grabImage)
+ QRhi::EndFrameFlags flags;
+ if (grabRequested)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
if (frameResult != QRhi::FrameOpSuccess) {
@@ -841,12 +867,13 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
gl->swapBuffers(window);
}
- if (!grabImage)
+ if (!grabRequested)
d->fireFrameSwapped();
-
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render");
}
@@ -870,7 +897,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
int((renderTime - syncTime) / 1000000),
int(threadTimer.elapsed() - renderTime / 1000000));
-
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
@@ -912,14 +939,21 @@ void QSGRenderThread::processEventsAndWaitForMore()
void QSGRenderThread::ensureRhi()
{
if (!rhi) {
+ if (rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
rhi = rhiSupport->createRhi(window, offscreenSurface);
if (rhi) {
+ rhiDeviceLost = false;
rhiSampleCount = rhiSupport->chooseSampleCountForWindowWithRhi(window, rhi);
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi); // ### this breaks down with multiple windows
} else {
- qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ if (!rhiDeviceLost) {
+ rhiDoomed = true;
+ qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
return;
}
}
@@ -975,9 +1009,24 @@ void QSGRenderThread::run()
if (window) {
if (enableRhi) {
+
ensureRhi();
- if (rhi)
- syncAndRender();
+
+ // We absolutely have to syncAndRender() here, even when QRhi
+ // failed to initialize otherwise the gui thread will be left
+ // in a blocked state. It is up to syncAndRender() to
+ // gracefully skip all graphics stuff when rhi is null.
+
+ syncAndRender();
+
+ // Now we can do something about rhi init failures. (reinit
+ // failure after device reset does not count)
+ if (rhiDoomed && !guiNotifiedAboutRhiFailure) {
+ guiNotifiedAboutRhiFailure = true;
+ QEvent *e = new QEvent(QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure));
+ QCoreApplication::postEvent(window, e);
+ }
+
} else {
if (!sgrc->openglContext() && windowSize.width() > 0 && windowSize.height() > 0 && gl->makeCurrent(window)) {
QSGDefaultRenderContext::InitParams rcParams;
@@ -1282,10 +1331,9 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
w->thread->gl->setFormat(w->window->requestedFormat());
w->thread->gl->setScreen(w->window->screen());
if (!w->thread->gl->create()) {
- const bool isEs = w->thread->gl->isOpenGLES();
delete w->thread->gl;
w->thread->gl = nullptr;
- handleContextCreationFailure(w->window, isEs);
+ handleContextCreationFailure(w->window);
return;
}
@@ -1508,7 +1556,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
return;
}
-
+ Q_TRACE_SCOPE(QSG_polishAndSync);
QElapsedTimer timer;
qint64 polishTime = 0;
qint64 waitTime = 0;
@@ -1517,14 +1565,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
+ Q_TRACE(QSG_polishItems_entry);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
if (profileFrames)
polishTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_wait_entry);
w->updateDuringSync = false;
@@ -1539,8 +1590,11 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync");
if (profileFrames)
waitTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_sync_entry);
+
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
@@ -1548,8 +1602,10 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
syncTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations");
@@ -1570,6 +1626,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
<< " - (on Gui thread) " << window;
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 5b48b86568..20d7c4557f 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -60,6 +60,8 @@
#include <private/qquickopenglshadereffectnode_p.h>
#endif
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Single-threaded render loop with a custom animation driver. Like a
@@ -180,10 +182,9 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
m_gl->setShareContext(qt_gl_global_share_context());
bool created = m_gl->create();
if (!created) {
- const bool isEs = m_gl->isOpenGLES();
delete m_gl;
m_gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
return;
}
@@ -393,6 +394,7 @@ bool QSGWindowsRenderLoop::event(QEvent *event)
void QSGWindowsRenderLoop::render()
{
RLDEBUG("render");
+ Q_TRACE(QSG_render_entry);
bool rendered = false;
for (const WindowData &wd : qAsConst(m_windows)) {
if (wd.pendingUpdate) {
@@ -407,10 +409,13 @@ void QSGWindowsRenderLoop::render()
QThread::msleep(m_vsyncDelta);
}
+ Q_TRACE(QSG_render_exit);
+
if (m_animationDriver->isRunning()) {
RLDEBUG("advancing animations");
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations);
+ Q_TRACE(QSG_animations_entry);
m_animationDriver->advance();
RLDEBUG("animations advanced");
@@ -418,6 +423,7 @@ void QSGWindowsRenderLoop::render()
"animations ticked in %dms",
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1);
// It is not given that animations triggered another maybeUpdate()
@@ -476,15 +482,20 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
if (!windowData(window))
return;
+ Q_TRACE_SCOPE(QSG_renderWindow);
+
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
RLDEBUG(" - polishing");
d->polishItems();
QSG_LOG_TIME_SAMPLE(time_polished);
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -492,17 +503,22 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
d->syncSceneGraph();
if (lastDirtyWindow)
m_rc->endSync();
+ Q_TRACE(QSG_sync_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
RLDEBUG(" - rendering");
d->renderSceneGraph(window->size());
+ Q_TRACE(QSG_render_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
RLDEBUG(" - swapping");
if (!d->customRenderStage || !d->customRenderStage->swap())
m_gl->swapBuffers(window);
+ Q_TRACE(QSG_swap_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 56d97226fb..b12f57d8ef 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -53,7 +53,6 @@ HEADERS += \
$$PWD/util/qsgengine.h \
$$PWD/util/qsgengine_p.h \
$$PWD/util/qsgplaintexture_p.h \
- $$PWD/util/qsgrhinativetextureimporter_p.h \
$$PWD/util/qsgsimplerectnode.h \
$$PWD/util/qsgsimpletexturenode.h \
$$PWD/util/qsgtextureprovider.h \
@@ -70,7 +69,6 @@ SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
$$PWD/util/qsgengine.cpp \
$$PWD/util/qsgplaintexture.cpp \
- $$PWD/util/qsgrhinativetextureimporter.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtextureprovider.cpp \
diff --git a/src/quick/scenegraph/shaders/outlinedtext.vert b/src/quick/scenegraph/shaders/outlinedtext.vert
index ced8afd034..9df832de3c 100644
--- a/src/quick/scenegraph/shaders/outlinedtext.vert
+++ b/src/quick/scenegraph/shaders/outlinedtext.vert
@@ -1,6 +1,7 @@
uniform highp mat4 matrix;
uniform highp vec2 textureScale;
uniform highp vec2 shift;
+uniform highp float dpr;
attribute highp vec4 vCoord;
attribute highp vec2 tCoord;
@@ -18,5 +19,6 @@ void main()
sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale;
sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale;
sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale;
- gl_Position = matrix * vCoord;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/outlinedtext_core.vert b/src/quick/scenegraph/shaders/outlinedtext_core.vert
index 4aa13101fd..a854355460 100644
--- a/src/quick/scenegraph/shaders/outlinedtext_core.vert
+++ b/src/quick/scenegraph/shaders/outlinedtext_core.vert
@@ -12,6 +12,7 @@ out vec2 sCoordRight;
uniform mat4 matrix;
uniform vec2 textureScale;
uniform vec2 shift;
+uniform float dpr;
void main()
{
@@ -20,5 +21,6 @@ void main()
sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale;
sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale;
sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale;
- gl_Position = matrix * vCoord;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/styledtext.vert b/src/quick/scenegraph/shaders/styledtext.vert
index 7001bbc262..29c9902609 100644
--- a/src/quick/scenegraph/shaders/styledtext.vert
+++ b/src/quick/scenegraph/shaders/styledtext.vert
@@ -13,5 +13,6 @@ void main()
{
sampleCoord = tCoord * textureScale;
shiftedSampleCoord = (tCoord - shift) * textureScale;
- gl_Position = matrix * floor(vCoord * dpr + 0.5) / dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders/styledtext_core.vert b/src/quick/scenegraph/shaders/styledtext_core.vert
index c522877bb3..04a0e88da8 100644
--- a/src/quick/scenegraph/shaders/styledtext_core.vert
+++ b/src/quick/scenegraph/shaders/styledtext_core.vert
@@ -15,5 +15,6 @@ void main()
{
sampleCoord = tCoord * textureScale;
shiftedSampleCoord = (tCoord - shift) * textureScale;
- gl_Position = matrix * round(vCoord * dpr) / dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders/textmask.vert b/src/quick/scenegraph/shaders/textmask.vert
index 4c678270d0..1692159d2c 100644
--- a/src/quick/scenegraph/shaders/textmask.vert
+++ b/src/quick/scenegraph/shaders/textmask.vert
@@ -10,5 +10,6 @@ varying highp vec2 sampleCoord;
void main()
{
sampleCoord = tCoord * textureScale;
- gl_Position = matrix * floor(vCoord * dpr + 0.5) / dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders/textmask_core.vert b/src/quick/scenegraph/shaders/textmask_core.vert
index f996040f70..b0efc1e731 100644
--- a/src/quick/scenegraph/shaders/textmask_core.vert
+++ b/src/quick/scenegraph/shaders/textmask_core.vert
@@ -12,5 +12,6 @@ uniform float dpr;
void main()
{
sampleCoord = tCoord * textureScale;
- gl_Position = matrix * round(vCoord * dpr) / dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * dpr + 0.5) / dpr;
+ gl_Position = matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
index b16da4d76a..c49cf9a6d8 100644
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
index 1a12a35b49..f5b3cf91e5 100644
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
index 2d0d23d813..3e0731802d 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
index 65d9af4736..51cfa99402 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
index 5753794649..aecf6ef18d 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
index 6026960d68..e62ec89964 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
index 451ccbac5b..c6e5d2d102 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
index 41ebc12abf..bf6e902f5a 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
index 0c37ccb6ed..398b6adaa2 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
index b92235eec3..e243f3300a 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
index 28ba15e3de..504d586915 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
index 2877ab92db..f020de9f8c 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
index 2e6085aa39..0c80f6dbc4 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
index a528c667fd..7bc588b806 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
index e83de529e6..7ad211c5cf 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
index 81c51321bb..3d31b99fca 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
index 6bf01658a1..82b4a63b65 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
index 4a9ac900a6..ab27f73163 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
index 76c2459edf..9fae9961c7 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
index 7bfa7ccd4a..53c8c3ef48 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
index 8f8304fb49..f7ab8301f3 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
index 0b4554568b..a30e7868c7 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
index 2872af0200..8a62c79ba4 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
index 5ab92fecca..bec0a086af 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
index c683a4273c..023f9dfdc2 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
@@ -28,5 +28,6 @@ void main()
sCoordDown = (tCoord - vec2(0.0, 1.0)) * ubuf.textureScale;
sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * ubuf.textureScale;
sCoordRight = (tCoord - vec2(1.0, 0.0)) * ubuf.textureScale;
- gl_Position = ubuf.matrix * vCoord;
+ vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
+ gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
index 6aee048faa..3f9464dd7c 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
index 6e6b1ab6c2..7f08bcee9e 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
index 4b08ee2ce4..dc3b174553 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
index 4a8c646a21..06e1e3704a 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
index f99cdf1176..2ad3229e4a 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
index 59c4104a2c..7d3a742650 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
index ffaecbb56c..d5b738cc38 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
index b7715d4dd5..50be6d62e0 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
index 45d5bc14ee..f6a7913054 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
index b55f881734..c11191feef 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
index 6ae7a51f7a..0fcd1d3f80 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
index ce2ed3c5b3..6381f6c8d9 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
index 66ebc5f827..ff7eceba83 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert b/src/quick/scenegraph/shaders_ng/styledtext.vert
index 10565107c6..beadf07c79 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert
@@ -22,5 +22,6 @@ void main()
{
sampleCoord = tCoord * ubuf.textureScale;
shiftedSampleCoord = (tCoord - ubuf.shift) * ubuf.textureScale;
- gl_Position = ubuf.matrix * floor((vCoord * ubuf.dpr) + 0.5) / ubuf.dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
+ gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
index 9a27ed0eb8..26f791be7f 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
index 9dd4137072..5e023b086b 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
index b16da4d76a..4cc598c5f8 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert b/src/quick/scenegraph/shaders_ng/textmask.vert
index d7d3bf892e..9d80d5dadb 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.vert
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert
@@ -17,5 +17,6 @@ out gl_PerVertex { vec4 gl_Position; };
void main()
{
sampleCoord = tCoord * ubuf.textureScale;
- gl_Position = ubuf.matrix * floor((vCoord * ubuf.dpr) + 0.5) / ubuf.dpr;
+ vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
+ gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
}
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
index ae196ed0ad..03be2e457d 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.frag.qsb b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
index 3f4aa3713c..55e8c23335 100644
--- a/src/quick/scenegraph/shaders_ng/texture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.vert.qsb b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
index bf0bc7d9fa..7ce3600447 100644
--- a/src/quick/scenegraph/shaders_ng/texture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
index 93965a55dd..2ad3229e4a 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
index 98abe4ef6f..1bea18c036 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
index eadad927dc..6b1a6a6c74 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
index 7ba27cb4b5..5f64c84705 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
index 75a874424a..18c72286d1 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
@@ -59,6 +59,8 @@
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
#ifndef GL_BGRA
@@ -250,14 +252,17 @@ void AtlasBase::bind(QSGTexture::Filtering filtering)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
uploadPendingTexture(i);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index fdebe03494..f00918bb4e 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qsgplaintexture_p.h"
-#include "qsgrhinativetextureimporter_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <qmath.h>
#include <private/qquickprofiler_p.h>
@@ -53,6 +52,8 @@
#endif
#include <QtGui/private/qrhi_p.h>
+#include <qtquick_tracepoints_p.h>
+
#if QT_CONFIG(opengl)
static QElapsedTimer qsg_renderer_timer;
#endif
@@ -150,9 +151,11 @@ void QSGPlainTexture::setTextureId(int id) // legacy (GL-only)
void QSGPlainTexture::bind() // legacy (GL-only)
{
#if QT_CONFIG(opengl)
+ Q_TRACE_SCOPE(QSG_texture_prepare);
QOpenGLContext *context = QOpenGLContext::currentContext();
QOpenGLFunctions *funcs = context->functions();
if (!m_dirty_texture) {
+ Q_TRACE_SCOPE(QSG_texture_bind);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
if (mipmapFiltering() != QSGTexture::None && !m_mipmaps_generated) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -174,6 +177,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
if (m_image.isNull()) {
if (m_texture_id && m_owns_texture) {
+ Q_TRACE_SCOPE(QSG_texture_delete);
funcs->glDeleteTextures(1, &m_texture_id);
qCDebug(QSG_LOG_TIME_TEXTURE, "plain texture deleted in %dms - %dx%d",
(int) qsg_renderer_timer.elapsed(),
@@ -189,6 +193,8 @@ void QSGPlainTexture::bind() // legacy (GL-only)
return;
}
+ Q_TRACE(QSG_texture_bind_entry);
+
if (m_texture_id == 0)
funcs->glGenTextures(1, &m_texture_id);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
@@ -196,8 +202,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 bindTime = 0;
if (profileFrames)
bindTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_bind_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareBind);
+ Q_TRACE(QSG_texture_upload_entry);
// ### TODO: check for out-of-memory situations...
@@ -232,8 +240,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 uploadTime = 0;
if (profileFrames)
uploadTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
+ Q_TRACE(QSG_texture_mipmap_entry);
if (mipmapFiltering() != QSGTexture::None) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -252,6 +262,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
int((mipmapTime - uploadTime)/1000000),
m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : "");
}
+ Q_TRACE(QSG_texture_mipmap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareMipmap);
@@ -281,14 +292,14 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native
{
Q_UNUSED(type);
- QRhiTexture::Flags flags = 0;
+ QRhiTexture::Flags flags;
if (mipmap)
flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
QRhiTexture *t = rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags);
// ownership of the native object is never taken
- QSGRhiNativeTextureImporter::buildWrapper(rhi, t, nativeObjectPtr, nativeLayout);
+ t->buildFrom({nativeObjectPtr, nativeLayout});
setTexture(t);
}
@@ -421,7 +432,7 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
}
if (!q->m_texture) {
- QRhiTexture::Flags f = 0;
+ QRhiTexture::Flags f;
if (hasMipMaps)
f |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
index 3dc1f5f526..6b5f1aec4f 100644
--- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
@@ -49,6 +49,9 @@
#include <private/qquickprofiler_p.h>
#include <private/qsgdefaultrendercontext_p.h>
#include <private/qsgtexture_p.h>
+
+#include <qtquick_tracepoints_p.h>
+
#if 0
#include <private/qsgcompressedtexture_p.h>
#include <private/qsgcompressedatlastexture_p.h>
@@ -197,14 +200,17 @@ void AtlasBase::updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
enqueueTextureUpload(t, resourceUpdates);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
deleted file mode 100644
index 7a7c19f587..0000000000
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgrhinativetextureimporter_p.h"
-#include <private/qsgrhisupport_p.h> // to get all the relevant qrhi headers
-
-QT_BEGIN_NAMESPACE
-
-void QSGRhiNativeTextureImporter::buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout)
-{
-#if !QT_CONFIG(vulkan)
- Q_UNUSED(nativeLayout);
-#endif
-#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
- Q_UNUSED(nativeObjectPtr);
-#endif
-
- switch (rhi->backend()) {
- case QRhi::OpenGLES2:
- {
-#if QT_CONFIG(opengl)
- QRhiGles2TextureNativeHandles h;
- h.texture = *reinterpret_cast<const uint *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Vulkan:
- {
-#if QT_CONFIG(vulkan)
- QRhiVulkanTextureNativeHandles h;
- h.image = *reinterpret_cast<const VkImage *>(nativeObjectPtr);
- h.layout = VkImageLayout(nativeLayout);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::D3D11:
- {
-#ifdef Q_OS_WIN
- QRhiD3D11TextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Metal:
- {
-#ifdef Q_OS_DARWIN
- QRhiMetalTextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Null:
- t->build();
- break;
- default:
- qWarning("QSGRhiNativeTextureImporter: encountered an unsupported QRhi backend (%d)",
- int(rhi->backend()));
- t->build();
- break;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h b/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
deleted file mode 100644
index e811109a94..0000000000
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGRHINATIVETEXTUREIMPORTER_P_H
-#define QSGRHINATIVETEXTUREIMPORTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQuick/private/qtquickglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QRhi;
-class QRhiTexture;
-
-class QSGRhiNativeTextureImporter
-{
-public:
- static void buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout);
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGRHINATIVETEXTUREIMPORTER_P_H
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index ae5c481e2f..eee8562a2a 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -196,7 +196,7 @@ void QQuickBehavior::write(const QVariant &value)
bool bypass = !d->enabled || !d->finalized || QQmlEnginePrivate::designerMode();
if (!bypass)
qmlExecuteDeferred(this);
- if (!d->animation || bypass) {
+ if (QQmlData::wasDeleted(d->animation) || bypass) {
if (d->animationInstance)
d->animationInstance->stop();
QQmlPropertyPrivate::write(d->property, value, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 61319c388c..24b22f00c1 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -918,7 +918,7 @@ QPointF QQuickPath::backwardsPointAt(const QPainterPath &path, const qreal &path
When curves are present, the percentage argument is mapped to the \c t
parameter of the Bezier equations.
- \sa QPainterPath::pointAt
+ \sa QPainterPath::pointAtPercent()
\since QtQuick 2.14
*/
@@ -2370,8 +2370,8 @@ void QQuickPathPercent::setValue(qreal value)
The example below creates a triangular path consisting of four vertices
on the edge of the containing Shape's bounding box.
- Through the containing shape's \l scale property, the path will be
- rescaled together with its containing shape.
+ Through the containing shape's \l {QtQuick::Path::}{scale} property,
+ the path will be rescaled together with its containing shape.
\qml
PathPolyline {
@@ -2488,7 +2488,7 @@ void QQuickPathPolyline::addToPath(QPainterPath &path, const QQuickPathData &/*d
The example below creates a high voltage symbol by adding each path
of the symbol to the list of paths.
The coordinates of the vertices are normalized, and through the containing shape's
- \l scale property, the path will be rescaled together with its containing shape.
+ \l {QtQuick::Path::}{scale} property, the path will be rescaled together with its containing shape.
\qml
PathMultiline {
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 56ad8ebf0b..e1b30f2b2c 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -567,9 +567,10 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
int frameCount;
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, job->data->frame))
+ int const frame = job->data ? job->data->frame : 0;
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, frame))
error = QQuickPixmapReply::Decoding;
- else
+ else if (job->data)
job->data->frameCount = frameCount;
}
// send completion event to the QQuickPixmapReply
@@ -882,7 +883,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
return;
} else {
int frameCount;
- if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, runningJob->data->frame)) {
+ int const frame = runningJob->data ? runningJob->data->frame : 0;
+ if ( !readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, frame)) {
errorCode = QQuickPixmapReply::Loading;
if (f.fileName() != localFile)
errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 7d545cdb2f..08d06c66ab 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -89,8 +89,8 @@ public:
QQmlContext *context,
bool preloadImages,
bool *fontSizeModified)
- : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(true), nbImages(0), updateImagePositions(false)
- , preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
+ : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl),
+ fontSizeModified(fontSizeModified), context(context), preloadImages(preloadImages)
{
}
@@ -122,15 +122,15 @@ public:
QFont baseFont;
QStack<List> listStack;
QUrl baseUrl;
- bool hasNewLine;
- int nbImages;
- bool updateImagePositions;
- bool preFormat;
- bool prependSpace;
- bool hasSpace;
- bool preloadImages;
bool *fontSizeModified;
QQmlContext *context;
+ int nbImages = 0;
+ bool hasNewLine = true;
+ bool updateImagePositions = false;
+ bool preFormat = false;
+ bool prependSpace = false;
+ bool hasSpace = true;
+ bool preloadImages;
static const QChar lessThan;
static const QChar greaterThan;
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
deleted file mode 100644
index 650a8c7e81..0000000000
--- a/src/quick/util/qquickutilmodule.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickutilmodule_p.h"
-#include "qquickanimation_p.h"
-#include "qquickanimation_p_p.h"
-#include "qquickapplication_p.h"
-#include "qquickbehavior_p.h"
-#include "qquicksmoothedanimation_p.h"
-#include "qquickfontloader_p.h"
-#include "qquickfontmetrics_p.h"
-#include "qquickpropertychanges_p.h"
-#include "qquickspringanimation_p.h"
-#include "qquickstategroup_p.h"
-#include "qquickstatechangescript_p.h"
-#include "qquickstate_p.h"
-#include "qquickstate_p_p.h"
-#include "qquicksystempalette_p.h"
-#include "qquicktextmetrics_p.h"
-#include "qquicktransition_p.h"
-#include "qquickanimator_p.h"
-#if QT_CONFIG(shortcut)
-#include "qquickshortcut_p.h"
-#endif
-#include "qquickvalidator_p.h"
-#include "qquickforeignutils_p.h"
-#include <qqmlinfo.h>
-#include <private/qqmltypenotavailable_p.h>
-#include <private/qquickanimationcontroller_p.h>
-#include <QtCore/qcoreapplication.h>
-
-#if QT_CONFIG(shortcut)
-Q_DECLARE_METATYPE(QKeySequence::StandardKey)
-#endif
-
-void QQuickUtilModule::defineModule()
-{
-#if QT_CONFIG(shortcut)
- qRegisterMetaType<QKeySequence::StandardKey>();
-#endif
-
- qmlRegisterTypesAndRevisions<
-#if QT_CONFIG(validator)
- QValidatorForeign,
- QQuickIntValidator,
- QQuickDoubleValidator,
- QRegExpValidatorForeign,
-#if QT_CONFIG(regularexpression)
- QRegularExpressionValidatorForeign,
-#endif // QT_CONFIG(regularexpression)
-#endif // QT_CONFIG(validator)
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
- QQuickUniformAnimator,
-#endif
-#if QT_CONFIG(shortcut)
- QQuickShortcut,
- QKeySequenceForeign,
-#endif
-#if QT_CONFIG(im)
- QInputMethodForeign,
-#endif
- QQuickAbstractAnimation,
- QQuickBehavior,
- QQuickColorAnimation,
- QQuickSmoothedAnimation,
- QQuickFontLoader,
- QQuickNumberAnimation,
- QQuickParallelAnimation,
- QQuickPauseAnimation,
- QQuickPropertyAction,
- QQuickPropertyAnimation,
- QQuickRotationAnimation,
- QQuickScriptAction,
- QQuickSequentialAnimation,
- QQuickSpringAnimation,
- QQuickAnimationController,
- QQuickStateChangeScript,
- QQuickStateGroup,
- QQuickState,
- QQuickSystemPalette,
- QQuickTransition,
- QQuickVector3dAnimation,
- QQuickAnimator,
- QQuickXAnimator,
- QQuickYAnimator,
- QQuickScaleAnimator,
- QQuickRotationAnimator,
- QQuickOpacityAnimator,
- QQuickStateOperation,
- QQuickPropertyChanges,
- QQuickFontMetrics,
- QQuickTextMetrics,
- QQuickApplication
- >("QtQuick", 2);
-}
diff --git a/src/quick/util/qquickutilmodule_p.h b/src/quick/util/qquickutilmodule_p.h
deleted file mode 100644
index b03eeddede..0000000000
--- a/src/quick/util/qquickutilmodule_p.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKUTILMODULE_H
-#define QQUICKUTILMODULE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickUtilModule
-{
-public:
- static void defineModule();
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKUTILMODULE_H
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 0af29aed1c..b47e1a082d 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -50,7 +50,6 @@ namespace QQuickValueTypes {
void registerValueTypes()
{
QQmlValueTypeFactory::registerValueTypes("QtQuick", 2, 0);
- qmlRegisterValueTypeEnums<QQuickFontValueType>("QtQuick", 2, 0, "Font");
}
}
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 3a1addfcd4..f61a967959 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -1,6 +1,5 @@
SOURCES += \
$$PWD/qquickapplication.cpp\
- $$PWD/qquickutilmodule.cpp\
$$PWD/qquickanimation.cpp \
$$PWD/qquicksystempalette.cpp \
$$PWD/qquickspringanimation.cpp \
@@ -32,7 +31,6 @@ qtConfig(qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
- $$PWD/qquickutilmodule_p.h\
$$PWD/qquickanimation_p.h \
$$PWD/qquickanimation_p_p.h \
$$PWD/qquicksystempalette_p.h \