aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/builtins/builtins.qmltypes13
-rw-r--r--src/imports/folderlistmodel/plugins.qmltypes2
-rw-r--r--src/imports/labsmodels/plugins.qmltypes373
-rw-r--r--src/imports/layouts/plugins.qmltypes2
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp4
-rw-r--r--src/imports/localstorage/plugins.qmltypes2
-rw-r--r--src/imports/models/plugins.qmltypes75
-rw-r--r--src/imports/particles/plugins.qmltypes10
-rw-r--r--src/imports/qtqml/dependencies.json2
-rw-r--r--src/imports/qtqml/plugins.qmltypes34
-rw-r--r--src/imports/qtquick2/plugins.qmltypes247
-rw-r--r--src/imports/shapes/plugins.qmltypes10
-rw-r--r--src/imports/statemachine/plugins.qmltypes2
-rw-r--r--src/imports/testlib/main.cpp2
-rw-r--r--src/imports/testlib/plugins.qmltypes8
-rw-r--r--src/imports/wavefrontmesh/plugins.qmltypes2
-rw-r--r--src/imports/window/plugins.qmltypes22
-rw-r--r--src/imports/workerscript/plugins.qmltypes26
-rw-r--r--src/particles/particles.qrc11
-rw-r--r--src/particles/qquickimageparticle.cpp735
-rw-r--r--src/particles/qquickimageparticle_p.h29
-rw-r--r--src/particles/qquickparticlepainter.cpp2
-rw-r--r--src/particles/qquickparticlepainter_p.h1
-rwxr-xr-xsrc/particles/shaders_ng/compile.bat53
-rw-r--r--src/particles/shaders_ng/imageparticle.frag55
-rw-r--r--src/particles/shaders_ng/imageparticle.vert145
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.frag.qsbbin0 -> 1990 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.vert.qsbbin0 -> 3677 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.frag.qsbbin0 -> 2028 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.vert.qsbbin0 -> 5044 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.frag.qsbbin0 -> 2000 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.vert.qsbbin0 -> 3639 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.frag.qsbbin0 -> 2369 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.vert.qsbbin0 -> 5964 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.frag.qsbbin0 -> 2240 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.vert.qsbbin0 -> 5462 bytes
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp12
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc10
-rw-r--r--src/qml/parser/qqmljs.g19
-rw-r--r--src/qml/parser/qqmljsast.cpp73
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqml.h10
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp18
-rw-r--r--src/qml/qml/qqmlapplicationengine.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h1
-rw-r--r--src/qml/qml/qqmlcomponent.cpp74
-rw-r--r--src/qml/qml/qqmlcomponent.h2
-rw-r--r--src/qml/qml/qqmlcomponent_p.h3
-rw-r--r--src/qml/qml/qqmlengine.cpp24
-rw-r--r--src/qml/qml/qqmlimport.cpp10
-rw-r--r--src/qml/qml/qqmlloggingcategory_p.h2
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp18
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp7
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h4
-rw-r--r--src/qml/types/qqmlbind.cpp2
-rw-r--r--src/qml/types/qqmlconnections.cpp75
-rw-r--r--src/qml/types/qqmlconnections_p.h8
-rw-r--r--src/qmlmodels/configure.json2
-rw-r--r--src/qmlmodels/qqmlmodelsmodule.cpp2
-rw-r--r--src/qmltest/quicktestevent.cpp3
-rw-r--r--src/quick/doc/images/declarative-qtlogo.pngbin3436 -> 1214 bytes
-rw-r--r--src/quick/doc/snippets/cmake-macros/examples.cmake6
-rw-r--r--src/quick/doc/snippets/qml/transitions-list.qml135
-rw-r--r--src/quick/doc/src/cmake-macros.qdoc56
-rw-r--r--src/quick/doc/src/concepts/positioning/righttoleft.qdoc2
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc58
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc312
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/topic.qdoc17
-rw-r--r--src/quick/doc/src/examples.qdoc3
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h4
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp16
-rw-r--r--src/quick/items/qquickanimatedimage.cpp6
-rw-r--r--src/quick/items/qquickanimatedimage_p.h6
-rw-r--r--src/quick/items/qquickborderimage.cpp18
-rw-r--r--src/quick/items/qquickevents.cpp2
-rw-r--r--src/quick/items/qquickflickable.cpp5
-rw-r--r--src/quick/items/qquickframebufferobject.cpp4
-rw-r--r--src/quick/items/qquickframebufferobject.h3
-rw-r--r--src/quick/items/qquickimage.cpp17
-rw-r--r--src/quick/items/qquickimage_p.h8
-rw-r--r--src/quick/items/qquickimagebase.cpp42
-rw-r--r--src/quick/items/qquickimagebase_p.h9
-rw-r--r--src/quick/items/qquickimagebase_p_p.h6
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp74
-rw-r--r--src/quick/items/qquickitemview_p.h4
-rw-r--r--src/quick/items/qquicklistview_p.h8
-rw-r--r--src/quick/items/qquickmousearea.cpp2
-rw-r--r--src/quick/items/qquickmousearea_p.h8
-rw-r--r--src/quick/items/qquickpincharea_p.h4
-rw-r--r--src/quick/items/qquickscreen_p.h8
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h4
-rw-r--r--src/quick/items/qquicktextinput_p.h8
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp2
-rw-r--r--src/quick/items/qquickview.cpp18
-rw-r--r--src/quick/items/qquickview.h1
-rw-r--r--src/quick/items/qquickview_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp132
-rw-r--r--src/quick/items/qquickwindow.h10
-rw-r--r--src/quick/items/qquickwindowmodule.cpp8
-rw-r--r--src/quick/items/qquickwindowmodule_p.h4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp113
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp103
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp38
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp4
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp44
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp13
-rw-r--r--src/quick/scenegraph/qsgrhisupport_p.h3
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.vert4
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.vert.qsbbin2030 -> 2099 bytes
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgengine.h2
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp32
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp104
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h70
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp1
-rw-r--r--src/quick/util/qquickpath.cpp118
-rw-r--r--src/quick/util/qquickpath_p.h16
-rw-r--r--src/quick/util/qquickpixmapcache.cpp81
-rw-r--r--src/quick/util/qquickpixmapcache_p.h5
-rw-r--r--src/quick/util/qquickshortcut_p.h4
-rw-r--r--src/quick/util/qquicktransition.cpp20
-rw-r--r--src/quick/util/qquickutilmodule.cpp6
-rw-r--r--src/quickshapes/qquickshape.cpp2
-rw-r--r--src/src.pro7
134 files changed, 3279 insertions, 838 deletions
diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes
index 4ad103f8de..c783c63caf 100644
--- a/src/imports/builtins/builtins.qmltypes
+++ b/src/imports/builtins/builtins.qmltypes
@@ -131,6 +131,13 @@ Module {
}
}
Enum {
+ name: "SplitBehavior"
+ values: {
+ "KeepEmptyParts": 0,
+ "SkipEmptyParts": 1
+ }
+ }
+ Enum {
name: "Alignment"
values: {
"AlignLeft": 1,
@@ -466,7 +473,8 @@ Module {
"AA_DontShowShortcutsInContextMenus": 28,
"AA_CompressTabletEvents": 29,
"AA_DisableWindowContextHelpButton": 30,
- "AA_AttributeCount": 31
+ "AA_DisableSessionManager": 31,
+ "AA_AttributeCount": 32
}
}
Enum {
@@ -1081,7 +1089,8 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
- "AutoText": 2
+ "AutoText": 2,
+ "MarkdownText": 3
}
}
Enum {
diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes
index 6f5466dbda..0fdbae66d3 100644
--- a/src/imports/folderlistmodel/plugins.qmltypes
+++ b/src/imports/folderlistmodel/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.13'
+// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/labsmodels/plugins.qmltypes b/src/imports/labsmodels/plugins.qmltypes
index 6272069060..f2a5752422 100644
--- a/src/imports/labsmodels/plugins.qmltypes
+++ b/src/imports/labsmodels/plugins.qmltypes
@@ -9,6 +9,280 @@ import QtQuick.tooling 1.2
Module {
dependencies: []
Component {
+ name: "QAbstractItemModel"
+ prototype: "QObject"
+ Enum {
+ name: "LayoutChangeHint"
+ values: {
+ "NoLayoutChangeHint": 0,
+ "VerticalSortHint": 1,
+ "HorizontalSortHint": 2
+ }
+ }
+ Enum {
+ name: "CheckIndexOption"
+ values: {
+ "NoOption": 0,
+ "IndexIsValid": 1,
+ "DoNotUseParent": 2,
+ "ParentIsInvalid": 4
+ }
+ }
+ Signal {
+ name: "dataChanged"
+ Parameter { name: "topLeft"; type: "QModelIndex" }
+ Parameter { name: "bottomRight"; type: "QModelIndex" }
+ Parameter { name: "roles"; type: "QVector<int>" }
+ }
+ Signal {
+ name: "dataChanged"
+ Parameter { name: "topLeft"; type: "QModelIndex" }
+ Parameter { name: "bottomRight"; type: "QModelIndex" }
+ }
+ Signal {
+ name: "headerDataChanged"
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "layoutChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
+ }
+ Signal {
+ name: "layoutChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ }
+ Signal { name: "layoutChanged" }
+ Signal {
+ name: "layoutAboutToBeChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
+ }
+ Signal {
+ name: "layoutAboutToBeChanged"
+ Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
+ }
+ Signal { name: "layoutAboutToBeChanged" }
+ Signal {
+ name: "rowsAboutToBeInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsAboutToBeRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "rowsRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsInserted"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal {
+ name: "columnsRemoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "first"; type: "int" }
+ Parameter { name: "last"; type: "int" }
+ }
+ Signal { name: "modelAboutToBeReset" }
+ Signal { name: "modelReset" }
+ Signal {
+ name: "rowsAboutToBeMoved"
+ Parameter { name: "sourceParent"; type: "QModelIndex" }
+ Parameter { name: "sourceStart"; type: "int" }
+ Parameter { name: "sourceEnd"; type: "int" }
+ Parameter { name: "destinationParent"; type: "QModelIndex" }
+ Parameter { name: "destinationRow"; type: "int" }
+ }
+ Signal {
+ name: "rowsMoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "start"; type: "int" }
+ Parameter { name: "end"; type: "int" }
+ Parameter { name: "destination"; type: "QModelIndex" }
+ Parameter { name: "row"; type: "int" }
+ }
+ Signal {
+ name: "columnsAboutToBeMoved"
+ Parameter { name: "sourceParent"; type: "QModelIndex" }
+ Parameter { name: "sourceStart"; type: "int" }
+ Parameter { name: "sourceEnd"; type: "int" }
+ Parameter { name: "destinationParent"; type: "QModelIndex" }
+ Parameter { name: "destinationColumn"; type: "int" }
+ }
+ Signal {
+ name: "columnsMoved"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ Parameter { name: "start"; type: "int" }
+ Parameter { name: "end"; type: "int" }
+ Parameter { name: "destination"; type: "QModelIndex" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method { name: "submit"; type: "bool" }
+ Method { name: "revert" }
+ Method {
+ name: "hasIndex"
+ type: "bool"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "hasIndex"
+ type: "bool"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method {
+ name: "index"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "index"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ }
+ Method {
+ name: "parent"
+ type: "QModelIndex"
+ Parameter { name: "child"; type: "QModelIndex" }
+ }
+ Method {
+ name: "sibling"
+ type: "QModelIndex"
+ Parameter { name: "row"; type: "int" }
+ Parameter { name: "column"; type: "int" }
+ Parameter { name: "idx"; type: "QModelIndex" }
+ }
+ Method {
+ name: "rowCount"
+ type: "int"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "rowCount"; type: "int" }
+ Method {
+ name: "columnCount"
+ type: "int"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "columnCount"; type: "int" }
+ Method {
+ name: "hasChildren"
+ type: "bool"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method { name: "hasChildren"; type: "bool" }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "headerData"
+ type: "QVariant"
+ Parameter { name: "section"; type: "int" }
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ Parameter { name: "role"; type: "int" }
+ }
+ Method {
+ name: "headerData"
+ type: "QVariant"
+ Parameter { name: "section"; type: "int" }
+ Parameter { name: "orientation"; type: "Qt::Orientation" }
+ }
+ Method {
+ name: "fetchMore"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "canFetchMore"
+ type: "bool"
+ Parameter { name: "parent"; type: "QModelIndex" }
+ }
+ Method {
+ name: "flags"
+ type: "Qt::ItemFlags"
+ Parameter { name: "index"; type: "QModelIndex" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "hits"; type: "int" }
+ Parameter { name: "flags"; type: "Qt::MatchFlags" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ Parameter { name: "hits"; type: "int" }
+ }
+ Method {
+ name: "match"
+ type: "QModelIndexList"
+ Parameter { name: "start"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "int" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ }
+ Component { name: "QAbstractTableModel"; prototype: "QAbstractItemModel" }
+ Component {
name: "QQmlAbstractDelegateComponent"
prototype: "QQmlComponent"
exports: ["Qt.labs.qmlmodels/AbstractDelegateComponent 1.0"]
@@ -38,4 +312,103 @@ Module {
Property { name: "role"; type: "string" }
Property { name: "choices"; type: "QQmlDelegateChoice"; isList: true; isReadonly: true }
}
+ Component {
+ name: "QQmlTableModel"
+ defaultProperty: "columns"
+ prototype: "QAbstractTableModel"
+ exports: ["Qt.labs.qmlmodels/TableModel 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "columnCount"; type: "int"; isReadonly: true }
+ Property { name: "rowCount"; type: "int"; isReadonly: true }
+ Property { name: "rows"; type: "QVariant" }
+ Property { name: "columns"; type: "QQmlTableModelColumn"; isList: true; isReadonly: true }
+ Method {
+ name: "appendRow"
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method { name: "clear" }
+ Method {
+ name: "getRow"
+ type: "QVariant"
+ Parameter { name: "rowIndex"; type: "int" }
+ }
+ Method {
+ name: "insertRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method {
+ name: "moveRow"
+ Parameter { name: "fromRowIndex"; type: "int" }
+ Parameter { name: "toRowIndex"; type: "int" }
+ Parameter { name: "rows"; type: "int" }
+ }
+ Method {
+ name: "moveRow"
+ Parameter { name: "fromRowIndex"; type: "int" }
+ Parameter { name: "toRowIndex"; type: "int" }
+ }
+ Method {
+ name: "removeRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "rows"; type: "int" }
+ }
+ Method {
+ name: "removeRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ }
+ Method {
+ name: "setRow"
+ Parameter { name: "rowIndex"; type: "int" }
+ Parameter { name: "row"; type: "QVariant" }
+ }
+ Method {
+ name: "data"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "string" }
+ }
+ Method {
+ name: "setData"
+ type: "bool"
+ Parameter { name: "index"; type: "QModelIndex" }
+ Parameter { name: "role"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ }
+ Component {
+ name: "QQmlTableModelColumn"
+ prototype: "QObject"
+ exports: ["Qt.labs.qmlmodels/TableModelColumn 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "display"; type: "QJSValue" }
+ Property { name: "setDisplay"; type: "QJSValue" }
+ Property { name: "decoration"; type: "QJSValue" }
+ Property { name: "setDecoration"; type: "QJSValue" }
+ Property { name: "edit"; type: "QJSValue" }
+ Property { name: "setEdit"; type: "QJSValue" }
+ Property { name: "toolTip"; type: "QJSValue" }
+ Property { name: "setToolTip"; type: "QJSValue" }
+ Property { name: "statusTip"; type: "QJSValue" }
+ Property { name: "setStatusTip"; type: "QJSValue" }
+ Property { name: "whatsThis"; type: "QJSValue" }
+ Property { name: "setWhatsThis"; type: "QJSValue" }
+ Property { name: "font"; type: "QJSValue" }
+ Property { name: "setFont"; type: "QJSValue" }
+ Property { name: "textAlignment"; type: "QJSValue" }
+ Property { name: "setTextAlignment"; type: "QJSValue" }
+ Property { name: "background"; type: "QJSValue" }
+ Property { name: "setBackground"; type: "QJSValue" }
+ Property { name: "foreground"; type: "QJSValue" }
+ Property { name: "setForeground"; type: "QJSValue" }
+ Property { name: "checkState"; type: "QJSValue" }
+ Property { name: "setCheckState"; type: "QJSValue" }
+ Property { name: "accessibleText"; type: "QJSValue" }
+ Property { name: "setAccessibleText"; type: "QJSValue" }
+ Property { name: "accessibleDescription"; type: "QJSValue" }
+ Property { name: "setAccessibleDescription"; type: "QJSValue" }
+ Property { name: "sizeHint"; type: "QJSValue" }
+ Property { name: "setSizeHint"; type: "QJSValue" }
+ Signal { name: "indexChanged" }
+ }
}
diff --git a/src/imports/layouts/plugins.qmltypes b/src/imports/layouts/plugins.qmltypes
index 22e8d79ece..6015164511 100644
--- a/src/imports/layouts/plugins.qmltypes
+++ b/src/imports/layouts/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Layouts 1.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Layouts 1.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index fa51ef1f2f..af7b1b7340 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -759,7 +759,7 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation,
\since QtQuick.Layouts 1.1
This property holds the layout direction of the row layout - it controls whether items are laid
- out from left ro right or right to left. If \c Qt.RightToLeft is specified,
+ out from left to right or right to left. If \c Qt.RightToLeft is specified,
left-aligned items will be right-aligned and right-aligned items will be left-aligned.
Possible values:
@@ -776,7 +776,7 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation,
\since QtQuick.Layouts 1.1
This property holds the layout direction of the column layout - it controls whether items are laid
- out from left ro right or right to left. If \c Qt.RightToLeft is specified,
+ out from left to right or right to left. If \c Qt.RightToLeft is specified,
left-aligned items will be right-aligned and right-aligned items will be left-aligned.
Possible values:
diff --git a/src/imports/localstorage/plugins.qmltypes b/src/imports/localstorage/plugins.qmltypes
index 3c8c1404f2..6ed334cc9d 100644
--- a/src/imports/localstorage/plugins.qmltypes
+++ b/src/imports/localstorage/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.LocalStorage 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.LocalStorage 2.14'
Module {
dependencies: []
diff --git a/src/imports/models/plugins.qmltypes b/src/imports/models/plugins.qmltypes
index 6e112c41b6..0d8b94df23 100644
--- a/src/imports/models/plugins.qmltypes
+++ b/src/imports/models/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.Models 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.Models 2.14'
Module {
dependencies: []
@@ -441,8 +441,8 @@ Module {
Signal { name: "defaultIncludeChanged" }
Signal {
name: "changed"
- Parameter { name: "removed"; type: "QQmlV4Handle" }
- Parameter { name: "inserted"; type: "QQmlV4Handle" }
+ Parameter { name: "removed"; type: "QJSValue" }
+ Parameter { name: "inserted"; type: "QJSValue" }
}
Method {
name: "insert"
@@ -478,7 +478,7 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
}
@@ -496,6 +496,7 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "dynamicRoles"; type: "bool" }
+ Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
Method { name: "clear" }
Method {
name: "remove"
@@ -511,13 +512,61 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
Method {
name: "set"
Parameter { name: "index"; type: "int" }
- Parameter { type: "QQmlV4Handle" }
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Method {
+ name: "setProperty"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "property"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "move"
+ Parameter { name: "from"; type: "int" }
+ Parameter { name: "to"; type: "int" }
+ Parameter { name: "count"; type: "int" }
+ }
+ Method { name: "sync" }
+ }
+ Component {
+ name: "QQmlListModelWorkerAgent"
+ prototype: "QObject"
+ Property { name: "count"; type: "int"; isReadonly: true }
+ Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ Signal {
+ name: "engineChanged"
+ Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ }
+ Method { name: "addref" }
+ Method { name: "release" }
+ Method { name: "clear" }
+ Method {
+ name: "remove"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "append"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "insert"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "get"
+ type: "QJSValue"
+ Parameter { name: "index"; type: "int" }
+ }
+ Method {
+ name: "set"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "value"; type: "QJSValue" }
}
Method {
name: "setProperty"
@@ -592,4 +641,18 @@ Module {
prototype: "QObject"
Property { name: "index"; type: "int"; isReadonly: true }
}
+ Component {
+ name: "QQuickPackage"
+ defaultProperty: "data"
+ prototype: "QObject"
+ exports: ["QtQml.Models/Package 2.14"]
+ exportMetaObjectRevisions: [0]
+ attachedType: "QQuickPackageAttached"
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "QQuickPackageAttached"
+ prototype: "QObject"
+ Property { name: "name"; type: "string" }
+ }
}
diff --git a/src/imports/particles/plugins.qmltypes b/src/imports/particles/plugins.qmltypes
index b6db00e683..0fe5dc808c 100644
--- a/src/imports/particles/plugins.qmltypes
+++ b/src/imports/particles/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Particles 2.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Particles 2.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -165,7 +165,7 @@ Module {
Property { name: "acceleration"; type: "QQuickDirection"; isPointer: true }
Signal {
name: "affectParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
Parameter { name: "dt"; type: "double" }
}
Signal {
@@ -668,7 +668,7 @@ Module {
Property { name: "velocityFromMovement"; type: "double" }
Signal {
name: "emitParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
}
Signal {
name: "particlesPerSecondChanged"
@@ -1084,8 +1084,8 @@ Module {
Property { name: "emitWidth"; type: "double" }
Signal {
name: "emitFollowParticles"
- Parameter { name: "particles"; type: "QQmlV4Handle" }
- Parameter { name: "followed"; type: "QQmlV4Handle" }
+ Parameter { name: "particles"; type: "QJSValue" }
+ Parameter { name: "followed"; type: "QJSValue" }
}
Signal {
name: "particlesPerParticlePerSecondChanged"
diff --git a/src/imports/qtqml/dependencies.json b/src/imports/qtqml/dependencies.json
new file mode 100644
index 0000000000..0d4f101c7a
--- /dev/null
+++ b/src/imports/qtqml/dependencies.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/src/imports/qtqml/plugins.qmltypes b/src/imports/qtqml/plugins.qmltypes
index d548a78dd0..63f5bada9b 100644
--- a/src/imports/qtqml/plugins.qmltypes
+++ b/src/imports/qtqml/plugins.qmltypes
@@ -4,14 +4,14 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -noforceqtquick QtQml 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml 2.14'
Module {
dependencies: []
Component {
name: "QObject"
- exports: ["QtQml/QtObject 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.0"]
+ exportMetaObjectRevisions: [0, 0]
Property { name: "objectName"; type: "string" }
Signal {
name: "objectNameChanged"
@@ -27,13 +27,27 @@ Module {
Component {
name: "QQmlBind"
prototype: "QObject"
- exports: ["QtQml/Binding 2.0", "QtQml/Binding 2.8"]
- exportMetaObjectRevisions: [0, 8]
+ exports: [
+ "QtQml/Binding 2.0",
+ "QtQml/Binding 2.14",
+ "QtQml/Binding 2.8"
+ ]
+ exportMetaObjectRevisions: [0, 14, 8]
+ Enum {
+ name: "RestorationMode"
+ values: {
+ "RestoreNone": 0,
+ "RestoreBinding": 1,
+ "RestoreValue": 2,
+ "RestoreBindingOrValue": 3
+ }
+ }
Property { name: "target"; type: "QObject"; isPointer: true }
Property { name: "property"; type: "string" }
Property { name: "value"; type: "QVariant" }
Property { name: "when"; type: "bool" }
Property { name: "delayed"; revision: 8; type: "bool" }
+ Property { name: "restoreMode"; revision: 14; type: "RestorationMode" }
}
Component {
name: "QQmlComponent"
@@ -94,11 +108,11 @@ Module {
name: "QQmlConnections"
prototype: "QObject"
exports: ["QtQml/Connections 2.0", "QtQml/Connections 2.3"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 3]
Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "enabled"; revision: 1; type: "bool" }
+ Property { name: "enabled"; revision: 3; type: "bool" }
Property { name: "ignoreUnknownSignals"; type: "bool" }
- Signal { name: "enabledChanged"; revision: 1 }
+ Signal { name: "enabledChanged"; revision: 3 }
}
Component {
name: "QQmlInstanceModel"
@@ -199,7 +213,7 @@ Module {
name: "QQmlLoggingCategory"
prototype: "QObject"
exports: ["QtQml/LoggingCategory 2.12", "QtQml/LoggingCategory 2.8"]
- exportMetaObjectRevisions: [1, 0]
+ exportMetaObjectRevisions: [12, 0]
Enum {
name: "DefaultLogLevel"
values: {
@@ -211,7 +225,7 @@ Module {
}
}
Property { name: "name"; type: "string" }
- Property { name: "defaultLogLevel"; revision: 1; type: "DefaultLogLevel" }
+ Property { name: "defaultLogLevel"; revision: 12; type: "DefaultLogLevel" }
}
Component {
name: "QQmlTimer"
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
index f006c874da..c8aae2087d 100644
--- a/src/imports/qtquick2/plugins.qmltypes
+++ b/src/imports/qtquick2/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick 2.14'
Module {
dependencies: []
@@ -529,8 +529,8 @@ Module {
Signal { name: "defaultIncludeChanged" }
Signal {
name: "changed"
- Parameter { name: "removed"; type: "QQmlV4Handle" }
- Parameter { name: "inserted"; type: "QQmlV4Handle" }
+ Parameter { name: "removed"; type: "QJSValue" }
+ Parameter { name: "inserted"; type: "QJSValue" }
}
Method {
name: "insert"
@@ -566,7 +566,7 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
}
@@ -646,6 +646,7 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "dynamicRoles"; type: "bool" }
+ Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
Method { name: "clear" }
Method {
name: "remove"
@@ -661,13 +662,61 @@ Module {
}
Method {
name: "get"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "index"; type: "int" }
}
Method {
name: "set"
Parameter { name: "index"; type: "int" }
- Parameter { type: "QQmlV4Handle" }
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Method {
+ name: "setProperty"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "property"; type: "string" }
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Method {
+ name: "move"
+ Parameter { name: "from"; type: "int" }
+ Parameter { name: "to"; type: "int" }
+ Parameter { name: "count"; type: "int" }
+ }
+ Method { name: "sync" }
+ }
+ Component {
+ name: "QQmlListModelWorkerAgent"
+ prototype: "QObject"
+ Property { name: "count"; type: "int"; isReadonly: true }
+ Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ Signal {
+ name: "engineChanged"
+ Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
+ }
+ Method { name: "addref" }
+ Method { name: "release" }
+ Method { name: "clear" }
+ Method {
+ name: "remove"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "append"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "insert"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ Method {
+ name: "get"
+ type: "QJSValue"
+ Parameter { name: "index"; type: "int" }
+ }
+ Method {
+ name: "set"
+ Parameter { name: "index"; type: "int" }
+ Parameter { name: "value"; type: "QJSValue" }
}
Method {
name: "setProperty"
@@ -1300,7 +1349,7 @@ Module {
}
Property { name: "available"; type: "bool"; isReadonly: true }
Property { name: "contextType"; type: "string" }
- Property { name: "context"; type: "QQmlV4Handle"; isReadonly: true }
+ Property { name: "context"; type: "QJSValue"; isReadonly: true }
Property { name: "canvasSize"; type: "QSizeF" }
Property { name: "tileSize"; type: "QSize" }
Property { name: "canvasWindow"; type: "QRectF" }
@@ -1480,9 +1529,19 @@ Module {
prototype: "QQuickMultiPointHandler"
exports: ["QtQuick/DragHandler 2.12"]
exportMetaObjectRevisions: [0]
+ Enum {
+ name: "SnapMode"
+ values: {
+ "NoSnap": 0,
+ "SnapAuto": 1,
+ "SnapIfPressedOutsideTarget": 2,
+ "SnapAlways": 3
+ }
+ }
Property { name: "xAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
Property { name: "yAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
Property { name: "translation"; type: "QVector2D"; isReadonly: true }
+ Property { name: "snapMode"; type: "SnapMode" }
}
Component {
name: "QQuickDropArea"
@@ -1959,7 +2018,13 @@ Module {
"Unknown": 0,
"Software": 1,
"OpenGL": 2,
- "Direct3D12": 3
+ "Direct3D12": 3,
+ "OpenVG": 4,
+ "OpenGLRhi": 5,
+ "Direct3D11Rhi": 6,
+ "VulkanRhi": 7,
+ "MetalRhi": 8,
+ "NullRhi": 9
}
}
Enum {
@@ -1967,7 +2032,8 @@ Module {
values: {
"UnknownShadingLanguage": 0,
"GLSL": 1,
- "HLSL": 2
+ "HLSL": 2,
+ "RhiShader": 3
}
}
Enum {
@@ -2131,7 +2197,7 @@ Module {
"QtQuick/Image 2.3",
"QtQuick/Image 2.5"
]
- exportMetaObjectRevisions: [0, 1, 2]
+ exportMetaObjectRevisions: [0, 3, 5]
Enum {
name: "HAlignment"
values: {
@@ -2165,8 +2231,8 @@ Module {
Property { name: "paintedHeight"; type: "double"; isReadonly: true }
Property { name: "horizontalAlignment"; type: "HAlignment" }
Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "mipmap"; revision: 1; type: "bool" }
- Property { name: "autoTransform"; revision: 2; type: "bool" }
+ Property { name: "mipmap"; revision: 3; type: "bool" }
+ Property { name: "autoTransform"; revision: 5; type: "bool" }
Signal { name: "paintedGeometryChanged" }
Signal {
name: "horizontalAlignmentChanged"
@@ -2178,10 +2244,10 @@ Module {
}
Signal {
name: "mipmapChanged"
- revision: 1
+ revision: 3
Parameter { type: "bool" }
}
- Signal { name: "autoTransformChanged"; revision: 2 }
+ Signal { name: "autoTransformChanged"; revision: 5 }
}
Component {
name: "QQuickImageBase"
@@ -2242,7 +2308,7 @@ Module {
"QtQuick/Item 2.4",
"QtQuick/Item 2.7"
]
- exportMetaObjectRevisions: [0, 1, 11, 2, 7]
+ exportMetaObjectRevisions: [0, 1, 11, 4, 7]
Enum {
name: "Flags"
values: {
@@ -2362,14 +2428,14 @@ Module {
Method { name: "update" }
Method {
name: "grabToImage"
- revision: 2
+ revision: 4
type: "bool"
Parameter { name: "callback"; type: "QJSValue" }
Parameter { name: "targetSize"; type: "QSize" }
}
Method {
name: "grabToImage"
- revision: 2
+ revision: 4
type: "bool"
Parameter { name: "callback"; type: "QJSValue" }
}
@@ -2502,7 +2568,7 @@ Module {
"QtQuick/ItemView 2.7"
]
isCreatable: false
- exportMetaObjectRevisions: [1, 13, 2, 7]
+ exportMetaObjectRevisions: [1, 13, 3, 7]
Enum {
name: "LayoutDirection"
values: {
@@ -2546,8 +2612,8 @@ Module {
Property { name: "keyNavigationWraps"; type: "bool" }
Property { name: "keyNavigationEnabled"; revision: 7; type: "bool" }
Property { name: "cacheBuffer"; type: "int" }
- Property { name: "displayMarginBeginning"; revision: 2; type: "int" }
- Property { name: "displayMarginEnd"; revision: 2; type: "int" }
+ Property { name: "displayMarginBeginning"; revision: 3; type: "int" }
+ Property { name: "displayMarginEnd"; revision: 3; type: "int" }
Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
Property { name: "verticalLayoutDirection"; type: "VerticalLayoutDirection" }
@@ -2858,7 +2924,7 @@ Module {
"QtQuick/ListView 2.4",
"QtQuick/ListView 2.7"
]
- exportMetaObjectRevisions: [0, 1, 2, 7]
+ exportMetaObjectRevisions: [0, 1, 4, 7]
attachedType: "QQuickListViewAttached"
Enum {
name: "Orientation"
@@ -2899,10 +2965,10 @@ Module {
Property { name: "section"; type: "QQuickViewSection"; isReadonly: true; isPointer: true }
Property { name: "currentSection"; type: "string"; isReadonly: true }
Property { name: "snapMode"; type: "SnapMode" }
- Property { name: "headerPositioning"; revision: 2; type: "HeaderPositioning" }
- Property { name: "footerPositioning"; revision: 2; type: "FooterPositioning" }
- Signal { name: "headerPositioningChanged"; revision: 2 }
- Signal { name: "footerPositioningChanged"; revision: 2 }
+ Property { name: "headerPositioning"; revision: 4; type: "HeaderPositioning" }
+ Property { name: "footerPositioning"; revision: 4; type: "FooterPositioning" }
+ Signal { name: "headerPositioningChanged"; revision: 4 }
+ Signal { name: "footerPositioningChanged"; revision: 4 }
Method { name: "incrementCurrentIndex" }
Method { name: "decrementCurrentIndex" }
}
@@ -2952,13 +3018,13 @@ Module {
"QtQuick/MouseArea 2.5",
"QtQuick/MouseArea 2.9"
]
- exportMetaObjectRevisions: [0, 1, 2, 9]
+ exportMetaObjectRevisions: [0, 4, 5, 9]
Property { name: "mouseX"; type: "double"; isReadonly: true }
Property { name: "mouseY"; type: "double"; isReadonly: true }
Property { name: "containsMouse"; type: "bool"; isReadonly: true }
Property { name: "pressed"; type: "bool"; isReadonly: true }
Property { name: "enabled"; type: "bool" }
- Property { name: "scrollGestureEnabled"; revision: 2; type: "bool" }
+ Property { name: "scrollGestureEnabled"; revision: 5; type: "bool" }
Property { name: "pressedButtons"; type: "Qt::MouseButtons"; isReadonly: true }
Property { name: "acceptedButtons"; type: "Qt::MouseButtons" }
Property { name: "hoverEnabled"; type: "bool" }
@@ -2966,10 +3032,10 @@ Module {
Property { name: "preventStealing"; type: "bool" }
Property { name: "propagateComposedEvents"; type: "bool" }
Property { name: "cursorShape"; type: "Qt::CursorShape" }
- Property { name: "containsPress"; revision: 1; type: "bool"; isReadonly: true }
+ Property { name: "containsPress"; revision: 4; type: "bool"; isReadonly: true }
Property { name: "pressAndHoldInterval"; revision: 9; type: "int" }
Signal { name: "hoveredChanged" }
- Signal { name: "scrollGestureEnabledChanged"; revision: 2 }
+ Signal { name: "scrollGestureEnabledChanged"; revision: 5 }
Signal {
name: "positionChanged"
Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
@@ -3009,7 +3075,7 @@ Module {
Signal { name: "entered" }
Signal { name: "exited" }
Signal { name: "canceled" }
- Signal { name: "containsPressChanged"; revision: 1 }
+ Signal { name: "containsPressChanged"; revision: 4 }
Signal { name: "pressAndHoldIntervalChanged"; revision: 9 }
}
Component {
@@ -3172,13 +3238,21 @@ Module {
name: "QQuickPath"
defaultProperty: "pathElements"
prototype: "QObject"
- exports: ["QtQuick/Path 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtQuick/Path 2.0", "QtQuick/Path 2.14"]
+ exportMetaObjectRevisions: [0, 14]
Property { name: "pathElements"; type: "QQuickPathElement"; isList: true; isReadonly: true }
Property { name: "startX"; type: "double" }
Property { name: "startY"; type: "double" }
Property { name: "closed"; type: "bool"; isReadonly: true }
+ Property { name: "scale"; revision: 14; type: "QSizeF" }
Signal { name: "changed" }
+ Signal { name: "scaleChanged"; revision: 14 }
+ Method {
+ name: "pointAtPercent"
+ revision: 14
+ type: "QPointF"
+ Parameter { name: "t"; type: "double" }
+ }
}
Component {
name: "QQuickPathAngleArc"
@@ -3250,7 +3324,7 @@ Module {
name: "QQuickPathArc"
prototype: "QQuickCurve"
exports: ["QtQuick/PathArc 2.0", "QtQuick/PathArc 2.9"]
- exportMetaObjectRevisions: [0, 2]
+ exportMetaObjectRevisions: [0, 9]
Enum {
name: "ArcDirection"
values: {
@@ -3262,8 +3336,8 @@ Module {
Property { name: "radiusY"; type: "double" }
Property { name: "useLargeArc"; type: "bool" }
Property { name: "direction"; type: "ArcDirection" }
- Property { name: "xAxisRotation"; revision: 2; type: "double" }
- Signal { name: "xAxisRotationChanged"; revision: 2 }
+ Property { name: "xAxisRotation"; revision: 9; type: "double" }
+ Signal { name: "xAxisRotationChanged"; revision: 9 }
}
Component {
name: "QQuickPathAttribute"
@@ -3322,6 +3396,14 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "QQuickPathMultiline"
+ prototype: "QQuickCurve"
+ exports: ["QtQuick/PathMultiline 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "start"; type: "QPointF"; isReadonly: true }
+ Property { name: "paths"; type: "QVariantList" }
+ }
+ Component {
name: "QQuickPathPercent"
prototype: "QQuickPathElement"
exports: ["QtQuick/PathPercent 2.0"]
@@ -3329,6 +3411,14 @@ Module {
Property { name: "value"; type: "double" }
}
Component {
+ name: "QQuickPathPolyline"
+ prototype: "QQuickCurve"
+ exports: ["QtQuick/PathPolyline 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "start"; type: "QPointF"; isReadonly: true }
+ Property { name: "path"; type: "QVariantList" }
+ }
+ Component {
name: "QQuickPathQuad"
prototype: "QQuickCurve"
exports: ["QtQuick/PathQuad 2.0"]
@@ -3508,7 +3598,7 @@ Module {
defaultProperty: "data"
prototype: "QQuickItem"
exports: ["QtQuick/PinchArea 2.0", "QtQuick/PinchArea 2.5"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 5]
Property { name: "enabled"; type: "bool" }
Property { name: "pinch"; type: "QQuickPinch"; isReadonly: true; isPointer: true }
Signal {
@@ -3525,7 +3615,7 @@ Module {
}
Signal {
name: "smartZoom"
- revision: 1
+ revision: 5
Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
}
}
@@ -3920,7 +4010,7 @@ Module {
defaultProperty: "data"
prototype: "QQuickItem"
exports: ["QtQuick/ShaderEffect 2.0", "QtQuick/ShaderEffect 2.4"]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 4]
Enum {
name: "CullMode"
values: {
@@ -3944,7 +4034,7 @@ Module {
Property { name: "cullMode"; type: "CullMode" }
Property { name: "log"; type: "string"; isReadonly: true }
Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "supportsAtlasTextures"; revision: 1; type: "bool" }
+ Property { name: "supportsAtlasTextures"; revision: 4; type: "bool" }
}
Component {
name: "QQuickShaderEffectMesh"
@@ -3963,7 +4053,7 @@ Module {
"QtQuick/ShaderEffectSource 2.6",
"QtQuick/ShaderEffectSource 2.9"
]
- exportMetaObjectRevisions: [0, 1, 2]
+ exportMetaObjectRevisions: [0, 6, 9]
Enum {
name: "WrapMode"
values: {
@@ -3998,8 +4088,8 @@ Module {
Property { name: "hideSource"; type: "bool" }
Property { name: "mipmap"; type: "bool" }
Property { name: "recursive"; type: "bool" }
- Property { name: "textureMirroring"; revision: 1; type: "TextureMirroring" }
- Property { name: "samples"; revision: 2; type: "int" }
+ Property { name: "textureMirroring"; revision: 6; type: "TextureMirroring" }
+ Property { name: "samples"; revision: 9; type: "int" }
Signal { name: "scheduledUpdateCompleted" }
Method { name: "scheduleUpdate" }
}
@@ -4011,11 +4101,11 @@ Module {
"QtQuick/Shortcut 2.6",
"QtQuick/Shortcut 2.9"
]
- exportMetaObjectRevisions: [0, 1, 9]
+ exportMetaObjectRevisions: [0, 6, 9]
Property { name: "sequence"; type: "QVariant" }
Property { name: "sequences"; revision: 9; type: "QVariantList" }
- Property { name: "nativeText"; revision: 1; type: "string"; isReadonly: true }
- Property { name: "portableText"; revision: 1; type: "string"; isReadonly: true }
+ Property { name: "nativeText"; revision: 6; type: "string"; isReadonly: true }
+ Property { name: "portableText"; revision: 6; type: "string"; isReadonly: true }
Property { name: "enabled"; type: "bool" }
Property { name: "autoRepeat"; type: "bool" }
Property { name: "context"; type: "Qt::ShortcutContext" }
@@ -4229,7 +4319,7 @@ Module {
exports: ["QtQuick/State 2.0"]
exportMetaObjectRevisions: [0]
Property { name: "name"; type: "string" }
- Property { name: "when"; type: "QQmlBinding"; isPointer: true }
+ Property { name: "when"; type: "bool" }
Property { name: "extend"; type: "string" }
Property { name: "changes"; type: "QQuickStateOperation"; isList: true; isReadonly: true }
Signal { name: "completed" }
@@ -4340,8 +4430,8 @@ Module {
name: "QQuickTableView"
defaultProperty: "flickableData"
prototype: "QQuickFlickable"
- exports: ["QtQuick/TableView 2.12"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtQuick/TableView 2.12", "QtQuick/TableView 2.14"]
+ exportMetaObjectRevisions: [0, 14]
attachedType: "QQuickTableViewAttached"
Property { name: "rows"; type: "int"; isReadonly: true }
Property { name: "columns"; type: "int"; isReadonly: true }
@@ -4354,6 +4444,10 @@ Module {
Property { name: "reuseItems"; type: "bool" }
Property { name: "contentWidth"; type: "double" }
Property { name: "contentHeight"; type: "double" }
+ Property { name: "syncView"; revision: 14; type: "QQuickTableView"; isPointer: true }
+ Property { name: "syncDirection"; revision: 14; type: "Qt::Orientations" }
+ Signal { name: "syncViewChanged"; revision: 14 }
+ Signal { name: "syncDirectionChanged"; revision: 14 }
Method { name: "forceLayout" }
}
Component {
@@ -4440,6 +4534,7 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
+ "MarkdownText": 3,
"AutoText": 2,
"StyledText": 4
}
@@ -4631,7 +4726,8 @@ Module {
values: {
"PlainText": 0,
"RichText": 1,
- "AutoText": 2
+ "AutoText": 2,
+ "MarkdownText": 3
}
}
Enum {
@@ -4892,7 +4988,7 @@ Module {
"QtQuick/TextInput 2.7",
"QtQuick/TextInput 2.9"
]
- exportMetaObjectRevisions: [0, 2, 3, 6, 7, 9]
+ exportMetaObjectRevisions: [0, 2, 4, 6, 7, 9]
Enum {
name: "EchoMode"
values: {
@@ -4976,7 +5072,7 @@ Module {
Property { name: "echoMode"; type: "EchoMode" }
Property { name: "activeFocusOnPress"; type: "bool" }
Property { name: "passwordCharacter"; type: "string" }
- Property { name: "passwordMaskDelay"; revision: 3; type: "int" }
+ Property { name: "passwordMaskDelay"; revision: 4; type: "int" }
Property { name: "displayText"; type: "string"; isReadonly: true }
Property { name: "preeditText"; revision: 7; type: "string"; isReadonly: true }
Property { name: "autoScroll"; type: "bool" }
@@ -5036,7 +5132,7 @@ Module {
}
Signal {
name: "passwordMaskDelayChanged"
- revision: 3
+ revision: 4
Parameter { name: "delay"; type: "int" }
}
Signal { name: "preeditTextChanged"; revision: 7 }
@@ -5093,7 +5189,7 @@ Module {
}
Method {
name: "ensureVisible"
- revision: 3
+ revision: 4
Parameter { name: "position"; type: "int" }
}
Method { name: "clear"; revision: 7 }
@@ -5117,7 +5213,7 @@ Module {
}
Method {
name: "inputMethodQuery"
- revision: 3
+ revision: 4
type: "QVariant"
Parameter { name: "query"; type: "Qt::InputMethodQuery" }
Parameter { name: "argument"; type: "QVariant" }
@@ -5272,6 +5368,24 @@ Module {
Property { name: "accepted"; type: "bool" }
}
Component {
+ name: "QQuickWheelHandler"
+ prototype: "QQuickSinglePointHandler"
+ exports: ["QtQuick/WheelHandler 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "orientation"; type: "Qt::Orientation" }
+ Property { name: "invertible"; type: "bool" }
+ Property { name: "activeTimeout"; type: "double" }
+ Property { name: "rotation"; type: "double" }
+ Property { name: "rotationScale"; type: "double" }
+ Property { name: "property"; type: "string" }
+ Property { name: "targetScaleMultiplier"; type: "double" }
+ Property { name: "targetTransformAroundCursor"; type: "bool" }
+ Signal {
+ name: "wheel"
+ Parameter { name: "event"; type: "QQuickPointerScrollEvent"; isPointer: true }
+ }
+ }
+ Component {
name: "QQuickWorkerScript"
prototype: "QObject"
exports: ["QtQuick/WorkerScript 2.0"]
@@ -5279,7 +5393,7 @@ Module {
Property { name: "source"; type: "QUrl" }
Signal {
name: "message"
- Parameter { name: "messageObject"; type: "QQmlV4Handle" }
+ Parameter { name: "messageObject"; type: "QJSValue" }
}
Method {
name: "sendMessage"
@@ -5310,8 +5424,31 @@ Module {
}
}
Component {
+ name: "QRegularExpressionValidator"
+ prototype: "QValidator"
+ exports: ["QtQuick/RegularExpressionValidator 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "regularExpression"; type: "QRegularExpression" }
+ Signal {
+ name: "regularExpressionChanged"
+ Parameter { name: "re"; type: "QRegularExpression" }
+ }
+ Method {
+ name: "setRegularExpression"
+ Parameter { name: "re"; type: "QRegularExpression" }
+ }
+ }
+ Component {
name: "QValidator"
prototype: "QObject"
+ Enum {
+ name: "State"
+ values: {
+ "Invalid": 0,
+ "Intermediate": 1,
+ "Acceptable": 2
+ }
+ }
Signal { name: "changed" }
}
}
diff --git a/src/imports/shapes/plugins.qmltypes b/src/imports/shapes/plugins.qmltypes
index b78c5a1130..cd779e7149 100644
--- a/src/imports/shapes/plugins.qmltypes
+++ b/src/imports/shapes/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -89,8 +89,11 @@ Module {
name: "QQuickShapePath"
defaultProperty: "pathElements"
prototype: "QQuickPath"
- exports: ["QtQuick.Shapes/ShapePath 1.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Shapes/ShapePath 1.0",
+ "QtQuick.Shapes/ShapePath 1.14"
+ ]
+ exportMetaObjectRevisions: [0, 14]
Enum {
name: "FillRule"
values: {
@@ -132,6 +135,7 @@ Module {
Property { name: "dashOffset"; type: "double" }
Property { name: "dashPattern"; type: "QVector<qreal>" }
Property { name: "fillGradient"; type: "QQuickShapeGradient"; isPointer: true }
+ Property { name: "scale"; revision: 14; type: "QSizeF" }
Signal { name: "shapePathChanged" }
}
Component {
diff --git a/src/imports/statemachine/plugins.qmltypes b/src/imports/statemachine/plugins.qmltypes
index f92aeaa080..541b1cc114 100644
--- a/src/imports/statemachine/plugins.qmltypes
+++ b/src/imports/statemachine/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.StateMachine 1.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.StateMachine 1.14'
Module {
dependencies: []
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index c5873c1058..a8bcfa2764 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -150,7 +150,7 @@ public:
qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent");
qmlRegisterType<QuickTestEvent>(uri,1,2,"TestEvent");
qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil");
- qmlRegisterType<QQuickTouchEventSequence>();
+ qmlRegisterAnonymousType<QQuickTouchEventSequence>(uri);
qmlRegisterModule(uri, 1, 15);
}
diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes
index 1e081d82ff..6a1371e5f1 100644
--- a/src/imports/testlib/plugins.qmltypes
+++ b/src/imports/testlib/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtTest 1.13'
+// 'qmlplugindump -nonrelocatable QtTest 1.14'
Module {
dependencies: ["QtQuick 2.0", "QtQuick.Window 2.0"]
@@ -343,7 +343,7 @@ Module {
Property { name: "dragThreshold"; type: "int"; isReadonly: true }
Method {
name: "typeName"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "v"; type: "QVariant" }
}
Method {
@@ -354,10 +354,10 @@ Module {
}
Method {
name: "callerFile"
- type: "QQmlV4Handle"
+ type: "QJSValue"
Parameter { name: "frameIndex"; type: "int" }
}
- Method { name: "callerFile"; type: "QQmlV4Handle" }
+ Method { name: "callerFile"; type: "QJSValue" }
Method {
name: "callerLine"
type: "int"
diff --git a/src/imports/wavefrontmesh/plugins.qmltypes b/src/imports/wavefrontmesh/plugins.qmltypes
index b9dd9e4c46..4e6a1dca73 100644
--- a/src/imports/wavefrontmesh/plugins.qmltypes
+++ b/src/imports/wavefrontmesh/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.wavefrontmesh 1.13'
+// 'qmlplugindump -nonrelocatable Qt.labs.wavefrontmesh 1.14'
Module {
dependencies: ["QtQuick 2.0"]
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
index b5786ed5a6..82b7ce0fc5 100644
--- a/src/imports/window/plugins.qmltypes
+++ b/src/imports/window/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Window 2.13'
+// 'qmlplugindump -nonrelocatable QtQuick.Window 2.14'
Module {
dependencies: ["QtQuick 2.0"]
@@ -26,7 +26,7 @@ Module {
prototype: "QObject"
exports: ["QtQuick.Window/Screen 2.0", "QtQuick.Window/Screen 2.3"]
isCreatable: false
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 3]
attachedType: "QQuickScreenAttached"
}
Component {
@@ -48,7 +48,7 @@ Module {
"QtQuick.Window/ScreenInfo 2.3"
]
isCreatable: false
- exportMetaObjectRevisions: [10, 2]
+ exportMetaObjectRevisions: [10, 3]
Property { name: "name"; type: "string"; isReadonly: true }
Property { name: "manufacturer"; revision: 10; type: "string"; isReadonly: true }
Property { name: "model"; revision: 10; type: "string"; isReadonly: true }
@@ -62,14 +62,14 @@ Module {
Property { name: "devicePixelRatio"; type: "double"; isReadonly: true }
Property { name: "primaryOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
Property { name: "orientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
- Property { name: "virtualX"; revision: 1; type: "int"; isReadonly: true }
- Property { name: "virtualY"; revision: 1; type: "int"; isReadonly: true }
+ Property { name: "virtualX"; revision: 3; type: "int"; isReadonly: true }
+ Property { name: "virtualY"; revision: 3; type: "int"; isReadonly: true }
Signal { name: "manufacturerChanged"; revision: 10 }
Signal { name: "modelChanged"; revision: 10 }
Signal { name: "serialNumberChanged"; revision: 10 }
Signal { name: "desktopGeometryChanged" }
- Signal { name: "virtualXChanged"; revision: 1 }
- Signal { name: "virtualYChanged"; revision: 1 }
+ Signal { name: "virtualXChanged"; revision: 3 }
+ Signal { name: "virtualYChanged"; revision: 3 }
}
Component {
name: "QQuickWindow"
@@ -140,6 +140,8 @@ Module {
Parameter { name: "error"; type: "QQuickWindow::SceneGraphError" }
Parameter { name: "message"; type: "string" }
}
+ Signal { name: "beforeRenderPassRecording"; revision: 14 }
+ Signal { name: "afterRenderPassRecording"; revision: 14 }
Method { name: "update" }
Method { name: "releaseResources" }
}
@@ -164,11 +166,11 @@ Module {
"QtQuick.Window/Window 2.2",
"QtQuick.Window/Window 2.3"
]
- exportMetaObjectRevisions: [0, 13, 1, 2]
+ exportMetaObjectRevisions: [0, 13, 2, 3]
attachedType: "QQuickWindowAttached"
Property { name: "visible"; type: "bool" }
Property { name: "visibility"; type: "Visibility" }
- Property { name: "screen"; revision: 2; type: "QObject"; isPointer: true }
+ Property { name: "screen"; revision: 3; type: "QObject"; isPointer: true }
Signal {
name: "visibleChanged"
Parameter { name: "arg"; type: "bool" }
@@ -177,7 +179,7 @@ Module {
name: "visibilityChanged"
Parameter { name: "visibility"; type: "QWindow::Visibility" }
}
- Signal { name: "screenChanged"; revision: 2 }
+ Signal { name: "screenChanged"; revision: 3 }
}
Component {
name: "QWindow"
diff --git a/src/imports/workerscript/plugins.qmltypes b/src/imports/workerscript/plugins.qmltypes
new file mode 100644
index 0000000000..b1d6107022
--- /dev/null
+++ b/src/imports/workerscript/plugins.qmltypes
@@ -0,0 +1,26 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.WorkerScript 2.14'
+
+Module {
+ dependencies: []
+ Component {
+ name: "QQuickWorkerScript"
+ prototype: "QObject"
+ exports: ["QtQml.WorkerScript/WorkerScript 2.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "source"; type: "QUrl" }
+ Signal {
+ name: "message"
+ Parameter { name: "messageObject"; type: "QJSValue" }
+ }
+ Method {
+ name: "sendMessage"
+ Parameter { type: "QQmlV4Function"; isPointer: true }
+ }
+ }
+}
diff --git a/src/particles/particles.qrc b/src/particles/particles.qrc
index ad44cf406e..c7102b9aa5 100644
--- a/src/particles/particles.qrc
+++ b/src/particles/particles.qrc
@@ -16,5 +16,16 @@
<file>shaders/customparticletemplate_core.vert</file>
<file>shaders/imageparticle_core.frag</file>
<file>shaders/imageparticle_core.vert</file>
+
+ <file>shaders_ng/imageparticle_simple.vert.qsb</file>
+ <file>shaders_ng/imageparticle_simple.frag.qsb</file>
+ <file>shaders_ng/imageparticle_tabled.vert.qsb</file>
+ <file>shaders_ng/imageparticle_tabled.frag.qsb</file>
+ <file>shaders_ng/imageparticle_deformed.vert.qsb</file>
+ <file>shaders_ng/imageparticle_deformed.frag.qsb</file>
+ <file>shaders_ng/imageparticle_sprite.vert.qsb</file>
+ <file>shaders_ng/imageparticle_sprite.frag.qsb</file>
+ <file>shaders_ng/imageparticle_colored.vert.qsb</file>
+ <file>shaders_ng/imageparticle_colored.frag.qsb</file>
</qresource>
</RCC>
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index ae1ef80026..649fbb30c2 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1,6 +1,6 @@
-/****************************************************************************
+/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -41,7 +41,6 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
#include <QtQuick/qsgnode.h>
-#include <QtQuick/qsgtexturematerial.h>
#include <QtQuick/qsgtexture.h>
#include <QFile>
#include <QRandomGenerator>
@@ -56,13 +55,15 @@
#include <private/qqmlglobal_p.h>
#include <QtQml/qqmlinfo.h>
#include <cmath>
+#include <QtGui/private/qrhi_p.h>
QT_BEGIN_NAMESPACE
-//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
+// Must match the shader code
#define UNIFORM_ARRAY_SIZE 64
const qreal CONV = 0.017453292519943295;
+
class ImageMaterialData
{
public:
@@ -85,13 +86,10 @@ class ImageMaterialData
QSizeF animSheetSize;
};
-class TabledMaterialData : public ImageMaterialData {};
-class TabledMaterial : public QSGSimpleMaterialShader<TabledMaterialData>
+class TabledMaterialShader : public QSGMaterialShader
{
- QSG_DECLARE_SIMPLE_SHADER(TabledMaterial, TabledMaterialData)
-
public:
- TabledMaterial()
+ TabledMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -122,36 +120,47 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation";
- };
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation", nullptr };
+ return attr;
+ }
void initialize() override {
- QSGSimpleMaterialShader<TabledMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
program()->setUniformValue("colortable", 1);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
m_timestamp_id = program()->uniformLocation("timestamp");
m_entry_id = program()->uniformLocation("entry");
m_sizetable_id = program()->uniformLocation("sizetable");
m_opacitytable_id = program()->uniformLocation("opacitytable");
}
- void updateState(const TabledMaterialData* d, const TabledMaterialData*) override {
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
glFuncs->glActiveTexture(GL_TEXTURE1);
- d->colorTable->bind();
+ state->colorTable->bind();
glFuncs->glActiveTexture(GL_TEXTURE0);
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
- program()->setUniformValueArray(m_sizetable_id, (const float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1);
- program()->setUniformValueArray(m_opacitytable_id, (const float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
+ program()->setUniformValueArray(m_sizetable_id, (const float*) state->sizeTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValueArray(m_opacitytable_id, (const float*) state->opacityTable, UNIFORM_ARRAY_SIZE, 1);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_entry_id;
int m_timestamp_id;
int m_sizetable_id;
@@ -161,13 +170,91 @@ public:
QOpenGLFunctions* glFuncs;
};
-class DeformableMaterialData : public ImageMaterialData {};
-class DeformableMaterial : public QSGSimpleMaterialShader<DeformableMaterialData>
+class TabledMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ TabledMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_tabled.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_tabled.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ float *p = reinterpret_cast<float *>(buf->data() + 80);
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->sizeTable[i];
+ p += 4;
+ }
+ p = reinterpret_cast<float *>(buf->data() + 80 + (UNIFORM_ARRAY_SIZE * 4 * 4));
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->opacityTable[i];
+ p += 4;
+ }
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 2) {
+ state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->colorTable;
+ } else if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class TabledMaterial : public ImageMaterial
{
- QSG_DECLARE_SIMPLE_SHADER(DeformableMaterial, DeformableMaterialData)
+public:
+ TabledMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new TabledMaterialRhiShader;
+ else
+ return new TabledMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType TabledMaterial::m_type;
+
+class DeformableMaterialShader : public QSGMaterialShader
+{
public:
- DeformableMaterial()
+ DeformableMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -196,27 +283,38 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation";
- };
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation", nullptr };
+ return attr;
+ }
void initialize() override {
- QSGSimpleMaterialShader<DeformableMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
m_timestamp_id = program()->uniformLocation("timestamp");
m_entry_id = program()->uniformLocation("entry");
}
- void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) override {
- d->texture->bind();
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_entry_id;
int m_timestamp_id;
QByteArray m_vertex_code;
@@ -224,13 +322,77 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SpriteMaterialData : public ImageMaterialData {};
-class SpriteMaterial : public QSGSimpleMaterialShader<SpriteMaterialData>
+class DeformableMaterialRhiShader : public QSGMaterialRhiShader
{
- QSG_DECLARE_SIMPLE_SHADER(SpriteMaterial, SpriteMaterialData)
+public:
+ DeformableMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_deformed.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_deformed.frag.qsb"));
+ }
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class DeformableMaterial : public ImageMaterial
+{
public:
- SpriteMaterial()
+ DeformableMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new DeformableMaterialRhiShader;
+ else
+ return new DeformableMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType DeformableMaterial::m_type;
+
+class SpriteMaterialShader : public QSGMaterialShader
+{
+public:
+ SpriteMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -263,17 +425,20 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos";
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPosTex", "vData", "vVec", "vColor", "vDeformVec", "vRotation",
+ "vAnimData", "vAnimPos", nullptr };
+ return attr;
}
void initialize() override {
- QSGSimpleMaterialShader<SpriteMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
program()->setUniformValue("colortable", 1);
glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
//Don't actually expose the animSheetSize in the shader, it's currently only used for CPU calculations.
m_timestamp_id = program()->uniformLocation("timestamp");
m_entry_id = program()->uniformLocation("entry");
@@ -281,20 +446,29 @@ public:
m_opacitytable_id = program()->uniformLocation("opacitytable");
}
- void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) override {
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
+
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
+
glFuncs->glActiveTexture(GL_TEXTURE1);
- d->colorTable->bind();
+ state->colorTable->bind();
// make sure we end by setting GL_TEXTURE0 as active texture
glFuncs->glActiveTexture(GL_TEXTURE0);
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
- program()->setUniformValueArray(m_sizetable_id, (const float*) d->sizeTable, 64, 1);
- program()->setUniformValueArray(m_opacitytable_id, (const float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
+ program()->setUniformValueArray(m_sizetable_id, (const float*) state->sizeTable, 64, 1);
+ program()->setUniformValueArray(m_opacitytable_id, (const float*) state->opacityTable, UNIFORM_ARRAY_SIZE, 1);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
int m_sizetable_id;
@@ -304,13 +478,91 @@ public:
QOpenGLFunctions* glFuncs;
};
-class ColoredMaterialData : public ImageMaterialData {};
-class ColoredMaterial : public QSGSimpleMaterialShader<ColoredMaterialData>
+class SpriteMaterialRhiShader : public QSGMaterialRhiShader
{
- QSG_DECLARE_SIMPLE_SHADER(ColoredMaterial, ColoredMaterialData)
+public:
+ SpriteMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ float *p = reinterpret_cast<float *>(buf->data() + 80);
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->sizeTable[i];
+ p += 4;
+ }
+ p = reinterpret_cast<float *>(buf->data() + 80 + (UNIFORM_ARRAY_SIZE * 4 * 4));
+ for (int i = 0; i < UNIFORM_ARRAY_SIZE; ++i) {
+ *p = state->opacityTable[i];
+ p += 4;
+ }
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 2) {
+ state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->colorTable;
+ } else if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class SpriteMaterial : public ImageMaterial
+{
public:
- ColoredMaterial()
+ SpriteMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new SpriteMaterialRhiShader;
+ else
+ return new SpriteMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType SpriteMaterial::m_type;
+
+class ColoredMaterialShader : public QSGMaterialShader
+{
+public:
+ ColoredMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -337,8 +589,23 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPos", "vData", "vVec", "vColor", nullptr };
+ return attr;
+ }
+
+ void initialize() override {
+ program()->bind();
+ program()->setUniformValue("_qt_texture", 0);
+ glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_timestamp_id = program()->uniformLocation("timestamp");
+ m_entry_id = program()->uniformLocation("entry");
+ }
+
void activate() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@@ -346,33 +613,28 @@ public:
}
void deactivate() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPos" << "vData" << "vVec" << "vColor";
- }
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
- void initialize() override {
- QSGSimpleMaterialShader<ColoredMaterialData>::initialize();
- program()->bind();
- program()->setUniformValue("_qt_texture", 0);
- glFuncs = QOpenGLContext::currentContext()->functions();
- m_timestamp_id = program()->uniformLocation("timestamp");
- m_entry_id = program()->uniformLocation("entry");
- }
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
- void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) override {
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
QByteArray m_vertex_code;
@@ -380,13 +642,77 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SimpleMaterialData : public ImageMaterialData {};
-class SimpleMaterial : public QSGSimpleMaterialShader<SimpleMaterialData>
+class ColoredMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ ColoredMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_colored.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_colored.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class ColoredMaterial : public ImageMaterial
{
- QSG_DECLARE_SIMPLE_SHADER(SimpleMaterial, SimpleMaterialData)
+public:
+ ColoredMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new ColoredMaterialRhiShader;
+ else
+ return new ColoredMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType ColoredMaterial::m_type;
+
+class SimpleMaterialShader : public QSGMaterialShader
+{
public:
- SimpleMaterial()
+ SimpleMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -411,8 +737,23 @@ public:
const char *vertexShader() const override { return m_vertex_code.constData(); }
const char *fragmentShader() const override { return m_fragment_code.constData(); }
+ char const *const *attributeNames() const override
+ {
+ static const char *const attr[] = { "vPos", "vData", "vVec", nullptr };
+ return attr;
+ }
+
+ void initialize() override {
+ program()->bind();
+ program()->setUniformValue("_qt_texture", 0);
+ glFuncs = QOpenGLContext::currentContext()->functions();
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_timestamp_id = program()->uniformLocation("timestamp");
+ m_entry_id = program()->uniformLocation("entry");
+ }
+
void activate() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@@ -420,33 +761,28 @@ public:
}
void deactivate() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
- QList<QByteArray> attributes() const override {
- return QList<QByteArray>() << "vPos" << "vData" << "vVec";
- }
+ void updateState(const RenderState &renderState, QSGMaterial *mat, QSGMaterial *) override {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(mat)->state();
- void initialize() override {
- QSGSimpleMaterialShader<SimpleMaterialData>::initialize();
- program()->bind();
- program()->setUniformValue("_qt_texture", 0);
- glFuncs = QOpenGLContext::currentContext()->functions();
- m_timestamp_id = program()->uniformLocation("timestamp");
- m_entry_id = program()->uniformLocation("entry");
- }
+ if (renderState.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, renderState.combinedMatrix());
+ if (renderState.isOpacityDirty() && m_opacity_id >= 0)
+ program()->setUniformValue(m_opacity_id, renderState.opacity());
- void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) override {
- d->texture->bind();
+ state->texture->bind();
- program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_entry_id, (float) d->entry);
+ program()->setUniformValue(m_timestamp_id, (float) state->timestamp);
+ program()->setUniformValue(m_entry_id, (float) state->entry);
}
+ int m_matrix_id;
+ int m_opacity_id;
int m_timestamp_id;
int m_entry_id;
QByteArray m_vertex_code;
@@ -454,6 +790,73 @@ public:
QOpenGLFunctions* glFuncs;
};
+class SimpleMaterialRhiShader : public QSGMaterialRhiShader
+{
+public:
+ SimpleMaterialRhiShader()
+ {
+ setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_simple.vert.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_simple.frag.qsb"));
+ }
+
+ bool updateUniformData(const RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ QByteArray *buf = renderState.uniformData();
+ Q_ASSERT(buf->size() >= 80 + 2 * (UNIFORM_ARRAY_SIZE * 4 * 4));
+
+ if (renderState.isMatrixDirty()) {
+ const QMatrix4x4 m = renderState.combinedMatrix();
+ memcpy(buf->data(), m.constData(), 64);
+ }
+
+ if (renderState.isOpacityDirty()) {
+ const float opacity = renderState.opacity();
+ memcpy(buf->data() + 64, &opacity, 4);
+ }
+
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+
+ float entry = float(state->entry);
+ memcpy(buf->data() + 68, &entry, 4);
+
+ float timestamp = float(state->timestamp);
+ memcpy(buf->data() + 72, &timestamp, 4);
+
+ return true;
+ }
+
+ void updateSampledImage(const RenderState &renderState, int binding, QSGTexture **texture,
+ QSGMaterial *newMaterial, QSGMaterial *) override
+ {
+ ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
+ if (binding == 1) {
+ state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ *texture = state->texture;
+ }
+ }
+};
+
+class SimpleMaterial : public ImageMaterial
+{
+public:
+ SimpleMaterial() { setFlag(SupportsRhiShader, true); }
+ QSGMaterialShader *createShader() const override {
+ if (flags().testFlag(RhiShaderWanted))
+ return new SimpleMaterialRhiShader;
+ else
+ return new SimpleMaterialShader;
+ }
+ QSGMaterialType *type() const override { return &m_type; }
+
+ ImageMaterialData *state() override { return &m_state; }
+
+private:
+ static QSGMaterialType m_type;
+ ImageMaterialData m_state;
+};
+
+QSGMaterialType SimpleMaterial::m_type;
+
void fillUniformArrayFromImage(float* array, const QImage& img, int size)
{
if (img.isNull()){
@@ -726,6 +1129,8 @@ QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
, m_debugMode(false)
, m_entryEffect(Fade)
, m_startedImageLoading(0)
+ , m_rhi(nullptr)
+ , m_apiChecked(false)
{
setFlag(ItemHasContents);
}
@@ -1000,7 +1405,7 @@ void QQuickImageParticle::setEntryEffect(EntryEffect arg)
if (m_entryEffect != arg) {
m_entryEffect = arg;
if (m_material)
- getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
+ getState(m_material)->entry = (qreal) m_entryEffect;
emit entryEffectChanged(arg);
}
}
@@ -1224,7 +1629,7 @@ void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough)
void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
{
- if (!QOpenGLContext::currentContext())
+ if (!m_rhi && !QOpenGLContext::currentContext())
return;
if (m_count * 4 > 0xffff) {
@@ -1271,28 +1676,38 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
}
}
}
+
+ if (!m_rhi) { // the RHI may be backed by GL but these checks should be obsolete in any case
#ifdef Q_OS_WIN
- if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows.
- perfLevel = Deformable;
+ if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows.
+ perfLevel = Deformable;
#endif
#ifdef Q_OS_MAC
- // OS X 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
- // causing point sprites who read gl_PointCoord in the frag shader to come out as
- // green-red blobs.
- const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
- if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
- perfLevel = Deformable;
- }
+ // macOS 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
+ // causing point sprites who read gl_PointCoord in the frag shader to come out as
+ // green-red blobs.
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
+ perfLevel = Deformable;
+ }
#endif
#ifdef Q_OS_LINUX
- // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
- const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
- if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
- perfLevel = Deformable;
+ // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
+ perfLevel = Deformable;
#endif
+ } else {
+ // Points with a size other than 1 are an optional feature with QRhi
+ // because some of the underlying APIs have no support for this.
+ // Therefore, avoid the point sprite path with APIs like Direct3D.
+ if (perfLevel < Deformable && !m_rhi->isFeatureSupported(QRhi::VertexShaderPointSize))
+ perfLevel = Deformable;
+ }
+
if (perfLevel >= Colored && !m_color.isValid())
m_color = QColor(Qt::white);//Hidden default, but different from unset
@@ -1308,6 +1723,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
bool imageLoaded = false;
switch (perfLevel) {//Fallthrough intended
case Sprites:
+ {
if (!m_spriteEngine) {
qWarning() << "ImageParticle: No sprite engine...";
//Sprite performance mode with static image is supported, but not advised
@@ -1318,16 +1734,19 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
return;
imageLoaded = true;
}
- m_material = SpriteMaterial::createMaterial();
+ m_material = new SpriteMaterial;
+ ImageMaterialData *state = getState(m_material);
if (imageLoaded)
- getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(image);
- getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size() / image.devicePixelRatioF());
+ state->texture = QSGPlainTexture::fromImage(image);
+ state->animSheetSize = QSizeF(image.size() / image.devicePixelRatioF());
if (m_spriteEngine)
m_spriteEngine->setCount(m_count);
+ }
Q_FALLTHROUGH();
case Tabled:
+ {
if (!m_material)
- m_material = TabledMaterial::createMaterial();
+ m_material = new TabledMaterial;
if (m_colorTable) {
if (m_colorTable->pix.isReady())
@@ -1354,21 +1773,29 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied);
colortable.fill(Qt::white);
}
- getState<ImageMaterialData>(m_material)->colorTable = QSGPlainTexture::fromImage(colortable);
- fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE);
- fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE);
+ ImageMaterialData *state = getState(m_material);
+ state->colorTable = QSGPlainTexture::fromImage(colortable);
+ fillUniformArrayFromImage(state->sizeTable, sizetable, UNIFORM_ARRAY_SIZE);
+ fillUniformArrayFromImage(state->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE);
+ }
Q_FALLTHROUGH();
case Deformable:
+ {
if (!m_material)
- m_material = DeformableMaterial::createMaterial();
+ m_material = new DeformableMaterial;
+ }
Q_FALLTHROUGH();
case Colored:
+ {
if (!m_material)
- m_material = ColoredMaterial::createMaterial();
+ m_material = new ColoredMaterial;
+ }
Q_FALLTHROUGH();
default://Also Simple
+ {
if (!m_material)
- m_material = SimpleMaterial::createMaterial();
+ m_material = new SimpleMaterial;
+ ImageMaterialData *state = getState(m_material);
if (!imageLoaded) {
if (!m_image || !m_image->pix.isReady()) {
if (m_image)
@@ -1376,14 +1803,15 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
delete m_material;
return;
}
- //getState<ImageMaterialData>(m_material)->texture //TODO: Shouldn't this be better? But not crash?
+ //state->texture //TODO: Shouldn't this be better? But not crash?
// = QQuickItemPrivate::get(this)->sceneGraphContext()->textureForFactory(m_imagePix.textureFactory());
- getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(m_image->pix.image());
+ state->texture = QSGPlainTexture::fromImage(m_image->pix.image());
}
- getState<ImageMaterialData>(m_material)->texture->setFiltering(QSGTexture::Linear);
- getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
+ state->texture->setFiltering(QSGTexture::Linear);
+ state->entry = (qreal) m_entryEffect;
m_material->setFlag(QSGMaterial::Blending | QSGMaterial::RequiresFullMatrix);
}
+ }
m_nodes.clear();
for (auto groupId : groupIds()) {
@@ -1416,14 +1844,23 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
node->setFlag(QSGNode::OwnsGeometry);
node->setGeometry(g);
if (perfLevel <= Colored){
- g->setDrawingMode(GL_POINTS);
- if (m_debugMode){
- GLfloat pointSizeRange[2];
- QOpenGLContext::currentContext()->functions()->glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
- qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <<pointSizeRange[0] << ":" << pointSizeRange[1];
+ g->setDrawingMode(QSGGeometry::DrawPoints);
+ if (m_debugMode) {
+ if (m_rhi) {
+ qDebug("Using point sprites");
+ } else {
+#if QT_CONFIG(opengl)
+ GLfloat pointSizeRange[2];
+ QOpenGLContext::currentContext()->functions()->glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
+ qDebug() << "Using point sprites, GL_ALIASED_POINT_SIZE_RANGE " <<pointSizeRange[0] << ":" << pointSizeRange[1];
+#else
+ qDebug("Using point sprites");
+#endif
+ }
}
- }else
- g->setDrawingMode(GL_TRIANGLES);
+ } else {
+ g->setDrawingMode(QSGGeometry::DrawTriangles);
+ }
for (int p=0; p < count; ++p)
commit(groupId, p);//commit sets geometry for the node, has its own perfLevel switch
@@ -1464,16 +1901,34 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
update();
}
-static inline bool isOpenGL(QSGRenderContext *rc)
-{
- QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
- return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
-}
-
QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
- if (!node && !isOpenGL(QQuickItemPrivate::get(this)->sceneGraphRenderContext()))
- return nullptr;
+ if (!m_apiChecked || m_windowChanged) {
+ m_apiChecked = true;
+ m_windowChanged = false;
+
+ QSGRenderContext *rc = QQuickItemPrivate::get(this)->sceneGraphRenderContext();
+ QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
+ if (!rif)
+ return nullptr;
+
+ QSGRendererInterface::GraphicsApi api = rif->graphicsApi();
+ const bool isDirectOpenGL = api == QSGRendererInterface::OpenGL;
+ const bool isRhi = QSGRendererInterface::isApiRhiBased(api);
+
+ if (!node && !isDirectOpenGL && !isRhi)
+ return nullptr;
+
+ if (isRhi)
+ m_rhi = static_cast<QRhi *>(rif->getResource(m_window, QSGRendererInterface::RhiResource));
+ else
+ m_rhi = nullptr;
+
+ if (isRhi && !m_rhi) {
+ qWarning("Failed to query QRhi, particles disabled");
+ return nullptr;
+ }
+ }
if (m_pleaseReset){
if (node)
@@ -1541,7 +1996,7 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node)
case Colored:
case Simple:
default: //Also Simple
- getState<ImageMaterialData>(m_material)->timestamp = time;
+ getState(m_material)->timestamp = time;
break;
}
foreach (QSGGeometryNode* node, m_nodes)
@@ -1550,6 +2005,7 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node)
void QQuickImageParticle::spritesUpdate(qreal time)
{
+ ImageMaterialData *state = getState(m_material);
// Sprite progression handled CPU side, so as to have per-frame control.
for (auto groupId : groupIds()) {
for (QQuickParticleData* mainDatum : qAsConst(m_system->groupData[groupId]->data)) {
@@ -1587,7 +2043,7 @@ void QQuickImageParticle::spritesUpdate(qreal time)
}
if (m_spriteEngine->sprite(spriteIdx)->reverse())//### Store this in datum too?
frameAt = (datum->frameCount - 1) - frameAt;
- QSizeF sheetSize = getState<ImageMaterialData>(m_material)->animSheetSize;
+ QSizeF sheetSize = state->animSheetSize;
qreal y = datum->animY / sheetSize.height();
qreal w = datum->animWidth / sheetSize.width();
qreal h = datum->animHeight / sheetSize.height();
@@ -1686,6 +2142,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}
} else {
+ ImageMaterialData *state = getState(m_material);
QQuickParticleData* writeTo = getShadowDatum(datum);
writeTo->animT = datum->t;
writeTo->frameCount = 1;
@@ -1694,8 +2151,8 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
writeTo->animIdx = 0;
writeTo->animT = 0;
writeTo->animX = writeTo->animY = 0;
- writeTo->animWidth = getState<ImageMaterialData>(m_material)->animSheetSize.width();
- writeTo->animHeight = getState<ImageMaterialData>(m_material)->animSheetSize.height();
+ writeTo->animWidth = state->animSheetSize.width();
+ writeTo->animHeight = state->animSheetSize.height();
}
Q_FALLTHROUGH();
case Tabled:
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 95323c25a6..059cf67019 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef ULTRAPARTICLE_H
-#define ULTRAPARTICLE_H
+#ifndef QQUICKIMAGEPARTICLE_P_H
+#define QQUICKIMAGEPARTICLE_P_H
//
// W A R N I N G
@@ -50,21 +50,25 @@
//
// We mean it.
//
+
#include "qquickparticlepainter_p.h"
#include "qquickdirection_p.h"
#include <private/qquickpixmapcache_p.h>
#include <QQmlListProperty>
-#include <QtQuick/qsgsimplematerial.h>
#include <QtGui/qcolor.h>
+#include <QtQuick/qsgmaterial.h>
QT_BEGIN_NAMESPACE
class ImageMaterialData;
class QSGGeometryNode;
+class QSGMaterial;
class QQuickSprite;
class QQuickStochasticEngine;
+class QRhi;
+
struct SimpleVertex {
float x;
float y;
@@ -153,6 +157,12 @@ struct Vertices {
Vertex v4;
};
+class ImageMaterial : public QSGMaterial
+{
+public:
+ virtual ImageMaterialData *state() = 0;
+};
+
class QQuickImageParticle : public QQuickParticlePainter
{
Q_OBJECT
@@ -439,14 +449,17 @@ private:
}
}
- template<class MaterialData>
- static MaterialData* getState(QSGMaterial* m) {
- return static_cast<QSGSimpleMaterial<MaterialData> *>(m)->state();
+ ImageMaterialData *getState(QSGMaterial *m) {
+ return static_cast<ImageMaterial *>(m)->state();
}
+
EntryEffect m_entryEffect;
Status m_status;
int m_startedImageLoading;
+ QRhi *m_rhi;
+ bool m_apiChecked;
};
QT_END_NAMESPACE
-#endif // ULTRAPARTICLE_H
+
+#endif // QQUICKIMAGEPARTICLE_P_H
diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp
index e762b3ae1d..78e11fafcf 100644
--- a/src/particles/qquickparticlepainter.cpp
+++ b/src/particles/qquickparticlepainter.cpp
@@ -70,6 +70,7 @@ QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent)
, m_count(0)
, m_pleaseReset(true)
, m_window(nullptr)
+ , m_windowChanged(false)
, m_groupIdsNeedRecalculation(false)
{
}
@@ -80,6 +81,7 @@ void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &
if (m_window)
disconnect(m_window, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()));
m_window = data.window;
+ m_windowChanged = true;
if (m_window)
connect(m_window, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection);
}
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index ac14a18103..16fc6b6f45 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -141,6 +141,7 @@ protected:
QPointF m_systemOffset;
QQuickWindow *m_window;
+ bool m_windowChanged;
private: // methods
void recalculateGroupIds() const;
diff --git a/src/particles/shaders_ng/compile.bat b/src/particles/shaders_ng/compile.bat
new file mode 100755
index 0000000000..2376d5bf6d
--- /dev/null
+++ b/src/particles/shaders_ng/compile.bat
@@ -0,0 +1,53 @@
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: 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$
+::
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_simple.vert.qsb imageparticle.vert
+qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_simple.frag.qsb imageparticle.frag
+
+qsb -DTABLE -DDEFORM -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_tabled.vert.qsb imageparticle.vert
+qsb -DTABLE -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_tabled.frag.qsb imageparticle.frag
+
+qsb -DDEFORM -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_deformed.vert.qsb imageparticle.vert
+qsb -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_deformed.frag.qsb imageparticle.frag
+
+qsb -DSPRITE -DTABLE -DDEFORM -DCOLOR -b --zorder-loc 8 --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_sprite.vert.qsb imageparticle.vert
+qsb -DSPRITE -DTABLE -DDEFORM -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_sprite.frag.qsb imageparticle.frag
+
+qsb -DCOLOR -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_colored.vert.qsb imageparticle.vert
+qsb -DCOLOR --glsl "150,120,100 es" --hlsl 50 --msl 12 -o imageparticle_colored.frag.qsb imageparticle.frag
diff --git a/src/particles/shaders_ng/imageparticle.frag b/src/particles/shaders_ng/imageparticle.frag
new file mode 100644
index 0000000000..cefb7d2d75
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle.frag
@@ -0,0 +1,55 @@
+#version 440
+
+#if defined(TABLE)
+layout(location = 0) in vec2 tt;
+#endif
+
+#if defined(SPRITE)
+layout(location = 1) in vec4 fTexS;
+#elif defined(DEFORM)
+layout(location = 1) in vec2 fTex;
+#endif
+
+#if defined(COLOR)
+layout(location = 2) in vec4 fColor;
+#else
+layout(location = 2) in float fFade;
+#endif
+
+layout(location = 0) out vec4 fragColor;
+
+layout(std140, binding = 0) uniform buf {
+ mat4 matrix;
+ float opacity;
+ float entry;
+ float timestamp;
+ float sizetable[64];
+ float opacitytable[64];
+} ubuf;
+
+layout(binding = 1) uniform sampler2D _qt_texture;
+
+#if defined(TABLE) || defined(SPRITE)
+layout(binding = 2) uniform sampler2D colortable;
+#endif
+
+void main()
+{
+#if defined(SPRITE)
+ fragColor = mix(texture(_qt_texture, fTexS.xy), texture(_qt_texture, fTexS.zw), tt.y)
+ * fColor
+ * texture(colortable, tt)
+ * ubuf.opacity;
+#elif defined(TABLE)
+ fragColor = texture(_qt_texture, fTex)
+ * fColor
+ * texture(colortable, tt)
+ * ubuf.opacity;
+#elif defined(DEFORM)
+ fragColor = texture(_qt_texture, fTex) * fColor * ubuf.opacity;
+#elif defined(COLOR)
+ fragColor = texture(_qt_texture, gl_PointCoord) * fColor * ubuf.opacity;
+#else
+ fragColor = texture(_qt_texture, gl_PointCoord) * fFade * ubuf.opacity;
+#endif
+}
diff --git a/src/particles/shaders_ng/imageparticle.vert b/src/particles/shaders_ng/imageparticle.vert
new file mode 100644
index 0000000000..870139452b
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle.vert
@@ -0,0 +1,145 @@
+#version 440
+
+layout(location = 1) in vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
+layout(location = 2) in vec4 vVec; // x,y = constant velocity, z,w = acceleration
+
+#if defined(DEFORM)
+layout(location = 0) in vec4 vPosTex;
+#else
+layout(location = 0) in vec2 vPos;
+#endif
+
+#if defined(COLOR)
+layout(location = 3) in vec4 vColor;
+#endif
+
+#if defined(DEFORM)
+layout(location = 4) in vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector
+layout(location = 5) in vec3 vRotation; // x = radians of rotation, y = rotation velocity, z = bool autoRotate
+#endif
+
+#if defined(SPRITE)
+layout(location = 6) in vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress
+layout(location = 7) in vec4 vAnimPos; // x,y, x,y (two frames for interpolation)
+#endif
+
+#if defined(TABLE)
+layout(location = 0) out vec2 tt; //y is progress if Sprite mode
+#endif
+
+#if defined(SPRITE)
+layout(location = 1) out vec4 fTexS;
+#elif defined(DEFORM)
+layout(location = 1) out vec2 fTex;
+#endif
+
+#if defined(COLOR)
+layout(location = 2) out vec4 fColor;
+#else
+layout(location = 2) out float fFade;
+#endif
+
+layout(std140, binding = 0) uniform buf {
+ mat4 matrix;
+ float opacity;
+ float entry;
+ float timestamp;
+ float sizetable[64];
+ float opacitytable[64];
+} ubuf;
+
+out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };
+
+void main()
+{
+ float t = (ubuf.timestamp - vData.x) / vData.y;
+ if (t < 0. || t > 1.) {
+#if defined(DEFORM)
+ gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+#if defined(SPRITE)
+ tt.y = vAnimData.z;
+
+ // Calculate frame location in texture
+ fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;
+
+ // Next frame is also passed, for interpolation
+ fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;
+
+#elif defined(DEFORM)
+ fTex = vPosTex.zw;
+#endif
+ float currentSize = mix(vData.z, vData.w, t * t);
+ float fade = 1.;
+ float fadeIn = min(t * 10., 1.);
+ float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
+
+#if defined(TABLE)
+ currentSize = currentSize * ubuf.sizetable[int(floor(t*64.))];
+ fade = fade * ubuf.opacitytable[int(floor(t*64.))];
+#endif
+
+ if (ubuf.entry == 1.)
+ fade = fade * fadeIn * fadeOut;
+ else if (ubuf.entry == 2.)
+ currentSize = currentSize * fadeIn * fadeOut;
+
+ if (currentSize <= 0.) {
+#if defined(DEFORM)
+ gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+ if (currentSize < 3.) // Sizes too small look jittery as they move
+ currentSize = 3.;
+
+ vec2 pos;
+#if defined(DEFORM)
+ float rotation = vRotation.x + vRotation.y * t * vData.y;
+ if (vRotation.z == 1.0) {
+ vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
+ if (length(curVel) > 0.)
+ rotation += atan(curVel.y, curVel.x);
+ }
+ vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
+ vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);
+ vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;
+ rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));
+ /* The readable version:
+ vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
+ vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
+ vec2 xRotatedDeform;
+ xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
+ xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
+ vec2 yRotatedDeform;
+ yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
+ yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
+ */
+ pos = vPosTex.xy
+ + rotatedDeform.xy
+ + rotatedDeform.zw
+ + vVec.xy * t * vData.y // apply velocity
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
+#else
+ pos = vPos
+ + vVec.xy * t * vData.y // apply velocity vector..
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.);
+ gl_PointSize = currentSize;
+#endif
+ gl_Position = ubuf.matrix * vec4(pos.x, pos.y, 0, 1);
+
+#if defined(COLOR)
+ fColor = vColor * fade;
+#else
+ fFade = fade;
+#endif
+#if defined(TABLE)
+ tt.x = t;
+#endif
+ }
+ }
+}
diff --git a/src/particles/shaders_ng/imageparticle_colored.frag.qsb b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
new file mode 100644
index 0000000000..7ae640d224
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_colored.vert.qsb b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
new file mode 100644
index 0000000000..0e2938b72c
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
new file mode 100644
index 0000000000..fa9d9d35bb
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
new file mode 100644
index 0000000000..65092d5b26
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.frag.qsb b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
new file mode 100644
index 0000000000..a5874cba24
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.vert.qsb b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
new file mode 100644
index 0000000000..da815d7e19
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
new file mode 100644
index 0000000000..778550344b
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
new file mode 100644
index 0000000000..45b21ace8a
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
new file mode 100644
index 0000000000..c5dcc2c68f
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
new file mode 100644
index 0000000000..ea42607570
--- /dev/null
+++ b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
Binary files differ
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
index 120a84566f..f505df1e5a 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
@@ -121,10 +121,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// Passed from the RL to RT when GUI has been locked, waiting for sync.
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is typically
-// a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to maybe release resource if no windows are
// rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -436,14 +432,6 @@ bool QSGD3D12RenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we
- // must not exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 9c106558fd..c71d18418a 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -274,6 +274,16 @@
*/
/*!
+ \fn int qmlRegisterAnonymousType(const char *uri, int versionMajor)
+
+ This template function registers the C++ type in the QML system. Instances of this type cannot be created from the QML system.
+
+ Use this function when the type will not be referenced by name. Use \a uri and \a versionMajor to indicate to which module the type belongs.
+
+ \sa {Choosing the Correct Integration Method Between C++ and QML}
+*/
+
+/*!
\fn int qmlRegisterType()
\relates QQmlEngine
\overload
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 6c9760e472..8ac7633ae0 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -1246,8 +1246,13 @@ UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlId
sym(1).Node = node;
} break;
./
+OptionalSemicolon: | Semicolon;
+/.
+/* we need OptionalSemicolon because UiScriptStatement might already parse the last semicolon
+ and then we would miss a semicolon (see tests/auto/quick/qquickvisualdatamodel/data/objectlist.qml)*/
+ ./
-UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement);
@@ -1259,7 +1264,7 @@ UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatemen
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
@@ -1273,7 +1278,7 @@ UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScr
} break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
+UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
@@ -1287,7 +1292,7 @@ UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScri
} break;
./
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET;
+UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
@@ -1313,7 +1318,7 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET;
+UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
@@ -1341,7 +1346,7 @@ UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlI
} break;
./
-UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer;
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
@@ -1364,7 +1369,7 @@ UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatem
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer;
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 700c191499..b63b2191b9 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -238,12 +238,11 @@ void StringLiteral::accept0(Visitor *visitor)
void TemplateLiteral::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- if (next)
- accept(next, visitor);
+ bool accepted = true;
+ for (TemplateLiteral *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ visitor->endVisit(it);
}
-
- visitor->endVisit(this);
}
void NumericLiteral::accept0(Visitor *visitor)
@@ -1015,13 +1014,13 @@ BoundNames FormalParameterList::boundNames() const
void FormalParameterList::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- accept(element, visitor);
- if (next)
- accept(next, visitor);
+ bool accepted = true;
+ for (FormalParameterList *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ if (accepted)
+ accept(it->element, visitor);
+ visitor->endVisit(it);
}
-
- visitor->endVisit(this);
}
FormalParameterList *FormalParameterList::finish(QQmlJS::MemoryPool *pool)
@@ -1321,12 +1320,14 @@ void UiPragma::accept0(Visitor *visitor)
void UiHeaderItemList::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- accept(headerItem, visitor);
- accept(next, visitor);
- }
+ bool accepted = true;
+ for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ if (accepted)
+ accept(it->headerItem, visitor);
- visitor->endVisit(this);
+ visitor->endVisit(it);
+ }
}
@@ -1391,14 +1392,15 @@ void PatternElement::boundNames(BoundNames *names)
void PatternElementList::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- accept(elision, visitor);
- accept(element, visitor);
- if (next)
- accept(next, visitor);
+ bool accepted = true;
+ for (PatternElementList *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ if (accepted) {
+ accept(it->elision, visitor);
+ accept(it->element, visitor);
+ }
+ visitor->endVisit(it);
}
-
- visitor->endVisit(this);
}
void PatternElementList::boundNames(BoundNames *names)
@@ -1428,13 +1430,13 @@ void PatternProperty::boundNames(BoundNames *names)
void PatternPropertyList::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- accept(property, visitor);
- if (next)
- accept(next, visitor);
+ bool accepted = true;
+ for (PatternPropertyList *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ if (accepted)
+ accept(it->property, visitor);
+ visitor->endVisit(it);
}
-
- visitor->endVisit(this);
}
void PatternPropertyList::boundNames(BoundNames *names)
@@ -1479,13 +1481,14 @@ void ClassDeclaration::accept0(Visitor *visitor)
void ClassElementList::accept0(Visitor *visitor)
{
- if (visitor->visit(this)) {
- accept(property, visitor);
- if (next)
- accept(next, visitor);
- }
+ bool accepted = true;
+ for (ClassElementList *it = this; it && accepted; it = it->next) {
+ accepted = visitor->visit(it);
+ if (accepted)
+ accept(it->property, visitor);
- visitor->endVisit(this);
+ visitor->endVisit(it);
+ }
}
ClassElementList *ClassElementList::finish()
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 08591b5237..2e9c6f3de6 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -186,5 +186,7 @@ qtConfig(qml-network) {
$$PWD/qqmltypeloadernetworkreplyproxy.cpp
}
+android: DEFINES += LIBS_SUFFIX='\\"_$${QT_ARCH}.so\\"'
+
include(ftw/ftw.pri)
include(v8/v8.pri)
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index bfd1c88b28..a93b012c70 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -102,7 +102,7 @@ class QQmlPropertyValueInterceptor;
void Q_QML_EXPORT qmlClearTypeRegistrations();
template<typename T>
-int qmlRegisterType()
+int qmlRegisterAnonymousType(const char *uri, int versionMajor=1)
{
QML_GETTYPENAMES
@@ -115,7 +115,7 @@ int qmlRegisterType()
nullptr,
QString(),
- nullptr, 0, 0, nullptr, &T::staticMetaObject,
+ uri, versionMajor, 0, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -133,6 +133,12 @@ int qmlRegisterType()
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+template<typename T>
+QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
+{
+ return qmlRegisterAnonymousType<T>("");
+}
+
int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
template<typename T>
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index e93cfcadb9..d04a89b514 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -131,7 +131,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
q->objectCreated(nullptr, c->url());
break;
case QQmlComponent::Ready: {
- auto newObj = c->create();
+ auto newObj = initialProperties.empty() ? c->create() : c->createWithInitialProperties(initialProperties);
objects << newObj;
QObject::connect(newObj, &QObject::destroyed, q, [&](QObject *obj) { objects.removeAll(obj); });
q->objectCreated(objects.constLast(), c->url());
@@ -279,6 +279,22 @@ void QQmlApplicationEngine::load(const QString &filePath)
}
/*!
+ Sets the initial properties with which the QML component gets initialized after
+ it gets loaded.
+
+
+ \sa QQmlComponent::setInitialProperties
+ \sa QQmlApplicationEngine::load
+ \sa QQmlApplicationEngine::loadData
+ \since 5.14
+*/
+void QQmlApplicationEngine::setInitialProperties(const QVariantMap &initialProperties)
+{
+ Q_D(QQmlApplicationEngine);
+ d->initialProperties = initialProperties;
+}
+
+/*!
Loads the QML given in \a data. The object tree defined by \a data is
instantiated immediately.
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index bb5d6b5d68..2b4de91154 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -66,6 +66,7 @@ public:
public Q_SLOTS:
void load(const QUrl &url);
void load(const QString &filePath);
+ void setInitialProperties(const QVariantMap &initialProperties);
void loadData(const QByteArray &data, const QUrl &url = QUrl());
Q_SIGNALS:
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
index 7a341847bd..1279e400e8 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -73,6 +73,7 @@ public:
void loadTranslations(const QUrl &rootFile);
void finishLoad(QQmlComponent *component);
QList<QObject *> objects;
+ QVariantMap initialProperties;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index fefe2bc685..ed8c41a582 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -350,6 +350,32 @@ void QQmlComponentPrivate::clear()
compilationUnit = nullptr;
}
+QObject *QQmlComponentPrivate::doBeginCreate(QQmlComponent *q, QQmlContext *context)
+{
+ if (!engine) {
+ // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
+ qWarning("QQmlComponent: Must provide an engine before calling create");
+ return nullptr;
+ }
+ if (!context)
+ context = engine->rootContext();
+ return q->beginCreate(context);
+}
+
+bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& name, const QVariant &value)
+{
+ QQmlProperty prop(component, name);
+ auto privProp = QQmlPropertyPrivate::get(prop);
+ if (!prop.isValid() || !privProp->writeValueProperty(value, nullptr)) {
+ QQmlError error{};
+ error.setUrl(url);
+ error.setDescription(QLatin1String("Could not set property %1").arg(name));
+ state.errors.push_back(error);
+ return false;
+ } else
+ return true;
+}
+
/*!
\internal
*/
@@ -780,18 +806,28 @@ QObject *QQmlComponent::create(QQmlContext *context)
{
Q_D(QQmlComponent);
- if (!d->engine) {
- // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
- qWarning("QQmlComponent: Must provide an engine before calling create");
- return nullptr;
- }
+ QObject *rv = d->doBeginCreate(this, context);
+ if (rv)
+ completeCreate();
+ return rv;
+}
- if (!context)
- context = d->engine->rootContext();
+/*!
+ Create an object instance of this component, and initialize its toplevel properties according to initalPropertyValues.
- QObject *rv = beginCreate(context);
- if (rv)
+
+ \sa QQmlComponent::create
+ \since 5.14
+*/
+QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context)
+{
+ Q_D(QQmlComponent);
+
+ QObject *rv = d->doBeginCreate(this, context);
+ if (rv) {
+ setInitialProperties(rv, initialProperties);
completeCreate();
+ }
return rv;
}
@@ -1067,6 +1103,26 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
enginePriv->incubate(incubator, forContextData);
}
+/*!
+ Set toplevel properties of the component.
+
+
+ This method provides advanced control over component instance creation.
+ In general, programmers should use
+ \l QQmlComponent::createWithInitialProperties to create a component.
+
+ Use this method after beginCreate and before completeCreate has been called.
+ If a provided property does not exist, a warning is issued.
+
+ \since 5.14
+*/
+void QQmlComponent::setInitialProperties(QObject *component, const QVariantMap &properties)
+{
+ Q_D(QQmlComponent);
+ for (auto it = properties.constBegin(); it != properties.constEnd(); ++it)
+ d->setInitialProperty(component, it.key(), it.value());
+}
+
/*
This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData
arguments instead of QQmlContext which means we don't have to construct the rather weighty
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index 39b6d4526f..f259c99b08 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -100,6 +100,8 @@ public:
QUrl url() const;
virtual QObject *create(QQmlContext *context = nullptr);
+ QObject *createWithInitialProperties(const QVariantMap& initialProperties, QQmlContext *context = nullptr);
+ void setInitialProperties(QObject *component, const QVariantMap &properties);
virtual QObject *beginCreate(QQmlContext *);
virtual void completeCreate();
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 9a967501c9..2170646b89 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -143,6 +143,9 @@ public:
static QQmlComponentPrivate *get(QQmlComponent *c) {
return static_cast<QQmlComponentPrivate *>(QObjectPrivate::get(c));
}
+
+ QObject *doBeginCreate(QQmlComponent *q, QQmlContext *context);
+ bool setInitialProperty(QObject *component, const QString &name, const QVariant& value);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 0580efe0d2..a6f7067552 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -206,14 +206,18 @@ void QQmlEnginePrivate::defineModule()
qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding");
qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding"); // Only available in >= 2.8
qmlRegisterType<QQmlBind, 14>(uri, 2, 14, "Binding");
+
+ // TODO: We won't need Connections to be a custom type anymore once we can drop the
+ // automatic signal handler inference from undeclared properties.
qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
- qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3
+ qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3
+
#if QT_CONFIG(qml_animation)
qmlRegisterType<QQmlTimer>(uri, 2, 0, "Timer");
#endif
qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); // Only available in >= 2.8
- qmlRegisterType<QQmlLoggingCategory, 1>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12
+ qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12
#if QT_CONFIG(qml_locale)
qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
@@ -796,11 +800,12 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
QList<QByteArray> parameterTypes = m.parameterTypes();
- int *types = (int *)malloc((parameterTypes.count() + 1) * sizeof(int));
- void **args = (void **) malloc((parameterTypes.count() + 1) *sizeof(void *));
+ QScopedPointer<QMetaCallEvent> ev(new QMetaCallEvent(m.methodIndex(), 0, nullptr,
+ object, index,
+ parameterTypes.count() + 1));
- types[0] = 0; // return type
- args[0] = nullptr; // return value
+ void **args = ev->args();
+ int *types = ev->types();
for (int ii = 0; ii < parameterTypes.count(); ++ii) {
const QByteArray &typeName = parameterTypes.at(ii);
@@ -813,21 +818,16 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
"(Make sure '%s' is registered using qRegisterMetaType().)",
typeName.constData(), typeName.constData());
- free(types);
- free(args);
return;
}
args[ii + 1] = QMetaType::create(types[ii + 1], a[ii + 1]);
}
- QMetaCallEvent *ev = new QMetaCallEvent(m.methodIndex(), 0, nullptr, object, index,
- parameterTypes.count() + 1, types, args);
-
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
mpo->target = object;
mpo->moveToThread(QObjectPrivate::get(object)->threadData->thread.loadAcquire());
- QCoreApplication::postEvent(mpo, ev);
+ QCoreApplication::postEvent(mpo, ev.take());
} else {
QQmlNotifierEndpoint *ep = ddata->notify(index);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 7c9c0da01a..31a7004407 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1852,9 +1852,15 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
QLatin1String(".so"),
QLatin1String(".bundle")
};
-# else // Unix
+#else // Unix
static const QString prefix = QLatin1String("lib");
- static const QStringList suffixes = { QLatin1String(".so") };
+ static const QStringList suffixes = {
+# if defined(Q_OS_ANDROID)
+ QStringLiteral(LIBS_SUFFIX),
+# endif
+ QLatin1String(".so")
+
+ };
#endif
return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName, suffixes, prefix);
diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h
index ece06e04b4..ee5d9af2e7 100644
--- a/src/qml/qml/qqmlloggingcategory_p.h
+++ b/src/qml/qml/qqmlloggingcategory_p.h
@@ -65,7 +65,7 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString name READ name WRITE setName)
- Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 1)
+ Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 12)
public:
enum DefaultLogLevel {
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 71964aca64..7dbcbe986b 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -711,21 +711,25 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope
// Using -1 for the minor version ensures that we get the raw metaObject.
QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType(), -1);
- // Will be true if the assigned type inherits propertyMetaObject
- bool isAssignable = false;
- // Determine isAssignable value
if (propertyMetaObject) {
+ // Will be true if the assigned type inherits propertyMetaObject
+ // Determine isAssignable value
+ bool isAssignable = false;
QQmlPropertyCache *c = propertyCaches.at(binding->value.objectIndex);
while (c && !isAssignable) {
isAssignable |= c == propertyMetaObject;
c = c->parent();
}
- }
- if (!isAssignable) {
- return qQmlCompileError(binding->valueLocation, tr("Cannot assign object of type \"%1\" to property of type \"%2\" as the former is neither the same as the latter nor a sub-class of it.")
- .arg(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex)).arg(QLatin1String(QMetaType::typeName(property->propType()))));
+ if (!isAssignable) {
+ return qQmlCompileError(binding->valueLocation, tr("Cannot assign object of type \"%1\" to property of type \"%2\" as the former is neither the same as the latter nor a sub-class of it.")
+ .arg(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex)).arg(QLatin1String(QMetaType::typeName(property->propType()))));
+ }
+ } else {
+ return qQmlCompileError(binding->valueLocation, tr("Cannot assign to property of unknown type \"%1\".")
+ .arg(QLatin1String(QMetaType::typeName(property->propType()))));
}
+
}
return noError;
}
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 88f7b69dc2..2225191a9d 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -122,8 +122,10 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
return &QQmlRectValueType::staticMetaObject;
case QVariant::RectF:
return &QQmlRectFValueType::staticMetaObject;
+#if QT_CONFIG(easingcurve)
case QVariant::EasingCurve:
return &QQmlEasingValueType::staticMetaObject;
+#endif
#if QT_CONFIG(qml_itemmodel)
case QVariant::ModelIndex:
return &QQmlModelIndexValueType::staticMetaObject;
@@ -201,7 +203,9 @@ const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(int type)
void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor)
{
+#if QT_CONFIG(easingcurve)
qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing");
+#endif
}
QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
@@ -489,6 +493,7 @@ int QQmlRectValueType::bottom() const
return v.bottom();
}
+#if QT_CONFIG(easingcurve)
QQmlEasingValueType::Type QQmlEasingValueType::type() const
{
return (QQmlEasingValueType::Type)v.type();
@@ -572,6 +577,8 @@ QVariantList QQmlEasingValueType::bezierCurve() const
rv << QVariant(point.x()) << QVariant(point.y());
return rv;
}
+#endif // easingcurve
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 89f1b71d61..75150b3f32 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -58,7 +58,9 @@
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
+#if QT_CONFIG(easingcurve)
#include <QtCore/qeasingcurve.h>
+#endif
#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@@ -210,6 +212,7 @@ public:
int bottom() const;
};
+#if QT_CONFIG(easingcurve)
struct QQmlEasingValueType
{
QEasingCurve v;
@@ -260,6 +263,7 @@ public:
void setBezierCurve(const QVariantList &);
QVariantList bezierCurve() const;
};
+#endif
template<typename T>
int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 4b60108597..861243987f 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -357,7 +357,7 @@ void QQmlBind::setDelayed(bool delayed)
\li Binding.RestoreValue The original value is restored if it was a plain
value rather than a binding.
\li Binding.RestoreBindingOrValue The original value is always restored.
- \list
+ \endlist
The default value is Binding.RestoreBinding.
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 8ec754a9df..1e801641e5 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -44,6 +44,7 @@
#include <private/qqmlboundsignal_p.h>
#include <qqmlcontext.h>
#include <private/qqmlcontext_p.h>
+#include <private/qqmlvmemetaobject_p.h>
#include <qqmlinfo.h>
#include <QtCore/qdebug.h>
@@ -105,7 +106,7 @@ public:
\qml
MouseArea {
Connections {
- onClicked: foo(parameters)
+ function onClicked(mouse) { foo(mouse) }
}
}
\endqml
@@ -122,7 +123,7 @@ public:
\qml
Connections {
target: area
- onClicked: foo(parameters)
+ function onClicked(mouse) { foo(mouse) }
}
\endqml
@@ -270,8 +271,76 @@ void QQmlConnections::connectSignals()
if (!d->componentcomplete || (d->targetSet && !target()))
return;
- if (d->bindings.isEmpty())
+ if (d->bindings.isEmpty()) {
+ connectSignalsToMethods();
+ } else {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ qmlWarning(this) << tr("Implicitly defined onFoo properties in Connections are deprecated. "
+ "Use this syntax instead: function onFoo(<arguments>) { ... }");
+#endif
+ connectSignalsToBindings();
+ }
+}
+
+void QQmlConnections::connectSignalsToMethods()
+{
+ Q_D(QQmlConnections);
+
+ QObject *target = this->target();
+ QQmlData *ddata = QQmlData::get(this);
+ if (!ddata)
return;
+
+ QV4::ExecutionEngine *engine = ddata->context->engine->handle();
+
+ QQmlContextData *ctxtdata = ddata->outerContext;
+ for (int i = ddata->propertyCache->methodOffset(),
+ end = ddata->propertyCache->methodOffset() + ddata->propertyCache->methodCount();
+ i < end;
+ ++i) {
+
+ QQmlPropertyData *handler = ddata->propertyCache->method(i);
+ if (!handler || !handler->isVMEFunction())
+ continue;
+
+ const QString propName = handler->name(this);
+
+ QQmlProperty prop(target, propName);
+ if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) {
+ int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex();
+ auto *signal = new QQmlBoundSignal(target, signalIndex, this, qmlEngine(this));
+ signal->setEnabled(d->enabled);
+
+ QV4::Scope scope(engine);
+ QV4::ScopedContext global(scope, engine->rootContext());
+
+ QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(this);
+ Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this
+
+ QV4::ScopedFunctionObject method(scope, vmeMetaObject->vmeMethod(handler->coreIndex()));
+
+ QQmlBoundSignalExpression *expression =
+ ctxtdata ? new QQmlBoundSignalExpression(
+ target, signalIndex, ctxtdata, this,
+ method->as<QV4::FunctionObject>()->function())
+ : nullptr;
+
+ signal->takeExpression(expression);
+ d->boundsignals += signal;
+ } else if (!d->ignoreUnknownSignals
+ && propName.startsWith(QLatin1String("on")) && propName.length() > 2
+ && propName.at(2).isUpper()) {
+ qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
+ "This is probably intended to be a signal handler but no "
+ "signal of the target matches the name.").arg(propName);
+ }
+ }
+}
+
+// TODO: Drop this as soon as we can
+void QQmlConnections::connectSignalsToBindings()
+{
+ Q_D(QQmlConnections);
QObject *target = this->target();
QQmlData *ddata = QQmlData::get(this);
QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr;
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index f6ad1eb46c..5d28e8e8be 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -69,7 +69,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 1)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 3)
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
public:
@@ -87,14 +87,18 @@ public:
Q_SIGNALS:
void targetChanged();
- Q_REVISION(1) void enabledChanged();
+ Q_REVISION(3) void enabledChanged();
private:
void connectSignals();
+ void connectSignalsToMethods();
+ void connectSignalsToBindings();
+
void classBegin() override;
void componentComplete() override;
};
+// TODO: Drop this class as soon as we can
class QQmlConnectionsParser : public QQmlCustomParser
{
public:
diff --git a/src/qmlmodels/configure.json b/src/qmlmodels/configure.json
index 84eefed261..1ccca5e35e 100644
--- a/src/qmlmodels/configure.json
+++ b/src/qmlmodels/configure.json
@@ -30,7 +30,7 @@
"label": "QML table model",
"purpose": "Provides the TableModel QML type.",
"section": "QML",
- "condition": "features.qml-itemmodel",
+ "condition": "features.qml-itemmodel && features.qml-delegate-model",
"output": [ "privateFeature" ]
}
},
diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp
index 884b7f78b2..4b753fe49a 100644
--- a/src/qmlmodels/qqmlmodelsmodule.cpp
+++ b/src/qmlmodels/qqmlmodelsmodule.cpp
@@ -81,7 +81,7 @@ void QQmlModelsModule::defineModule()
qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
qmlRegisterType<QQmlObjectModel,3>(uri, 2, 3, "ObjectModel");
qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator");
- qmlRegisterType<QQmlInstanceModel>();
+ qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2);
#endif
#if QT_CONFIG(itemmodel)
qmlRegisterType<QItemSelectionModel>(uri, 2, 2, "ItemSelectionModel");
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index 5b07220c29..1e949615c2 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -241,7 +241,8 @@ namespace QtQuickTest
QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
- QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), 0, Qt::Vertical, buttons, stateKey);
+ QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons,
+ stateKey, Qt::NoScrollPhase, false);
QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm
if (!qApp->notify(window, &we))
diff --git a/src/quick/doc/images/declarative-qtlogo.png b/src/quick/doc/images/declarative-qtlogo.png
index 940d159ae4..b63f1384b1 100644
--- a/src/quick/doc/images/declarative-qtlogo.png
+++ b/src/quick/doc/images/declarative-qtlogo.png
Binary files differ
diff --git a/src/quick/doc/snippets/cmake-macros/examples.cmake b/src/quick/doc/snippets/cmake-macros/examples.cmake
new file mode 100644
index 0000000000..8ca6180f9b
--- /dev/null
+++ b/src/quick/doc/snippets/cmake-macros/examples.cmake
@@ -0,0 +1,6 @@
+#! [qt5_import_qml_plugins]
+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]
diff --git a/src/quick/doc/snippets/qml/transitions-list.qml b/src/quick/doc/snippets/qml/transitions-list.qml
index 06b9e39cc8..972d3ee14e 100644
--- a/src/quick/doc/snippets/qml/transitions-list.qml
+++ b/src/quick/doc/snippets/qml/transitions-list.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -48,52 +48,105 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.13
Rectangle {
- width: 150; height: 250
+ id: page
+ width: 640
+ height: 500
- Rectangle {
- id: stopLight
- x: 25; y: 15; width: 100; height: 100
- }
- Rectangle {
- id: goLight
- x: 25; y: 135; width: 100; height: 100
- }
+ Image {
+ id: userIcon
+ x: topLeftRect.x
+ y: topLeftRect.y
- states: [
- State {
- name: "stop"
- PropertyChanges { target: stopLight; color: "red" }
- PropertyChanges { target: goLight; color: "black" }
- },
- State {
- name: "go"
- PropertyChanges { target: stopLight; color: "black" }
- PropertyChanges { target: goLight; color: "green" }
+ source: "../../images/declarative-qtlogo.png"
}
- ]
- state: "stop"
+ Rectangle {
+ id: topLeftRect
+ anchors { left: parent.left; top: parent.top; leftMargin: 10; topMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking here sets state to default state, returning image to initial position
+ TapHandler { onTapped: page.state = 'start' }
+ }
+
+ Rectangle {
+ id: middleRightRect
+ anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking in here sets the state to 'middleRight'
+ TapHandler { onTapped: page.state = 'middleRight' }
+ }
- MouseArea {
- anchors.fill: parent
- onClicked: parent.state == "stop" ?
- parent.state = "go" : parent.state = "stop"
- }
+ Rectangle {
+ id: bottomLeftRect
+ anchors { left: parent.left; bottom: parent.bottom; leftMargin: 10; bottomMargin: 20 }
+ width: 46; height: 54
+ color: "Transparent"; border.color: "Gray"; radius: 6
+ // Clicking in here sets the state to 'bottomLeft'
+ TapHandler { onTapped: page.state = 'bottomLeft' }
+ }
- //! [list of transitions]
- transitions: [
- Transition {
- from: "stop"; to: "go"
- PropertyAnimation { target: stopLight
- properties: "color"; duration: 1000 }
- },
- Transition {
- from: "go"; to: "stop"
- PropertyAnimation { target: goLight
- properties: "color"; duration: 1000 }
- } ]
- //! [list of transitions]
+ states: [
+ State {
+ name: "start"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: topLeftRect.x
+ y: topLeftRect.y
+ }
+ },
+ State {
+ name: "middleRight"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: middleRightRect.x
+ y: middleRightRect.y
+ }
+ },
+ State {
+ name: "bottomLeft"
+ PropertyChanges {
+ target: userIcon
+ explicit: true
+ x: bottomLeftRect.x
+ y: bottomLeftRect.y
+ }
+ }
+ ]
+//! [list of transitions]
+ transitions: [
+ Transition {
+ from: "*"; to: "middleRight"
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: Easing.InOutQuad;
+ duration: 2000;
+ }
+ },
+ Transition {
+ from: "*"; to: "bottomLeft";
+ NumberAnimation {
+ properties: "x,y";
+ easing.type: Easing.InOutQuad;
+ duration: 200;
+ }
+ },
+ //If any other rectangle is clicked, the icon will return
+ //to the start position at a slow speed and bounce.
+ Transition {
+ from: "*"; to: "*";
+ NumberAnimation {
+ easing.type: Easing.OutBounce;
+ properties: "x,y";
+ duration: 4000;
+ }
+ }
+ ]
+//! [list of transitions]
}
diff --git a/src/quick/doc/src/cmake-macros.qdoc b/src/quick/doc/src/cmake-macros.qdoc
new file mode 100644
index 0000000000..b643a9e4e4
--- /dev/null
+++ b/src/quick/doc/src/cmake-macros.qdoc
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtqml-cmake-qt5-import-qml-plugins.html
+\ingroup cmake-macros-qtqml
+
+\title qt5_import_qml_plugins
+
+\brief Scans \c{.qml} files and imports required QML static plugins
+
+\section1 Overview
+
+\badcode
+find_package(Qt5QmlImportScanner REQUIRED)
+qt5_import_qml_plugins(<TARGET>)
+\endcode
+
+\section1 Description
+
+Runs \c{qmlimportscanner} at configure time to find the static QML plugins
+used and links them to the given target.
+
+\note When used with a non-static Qt build, this function does nothing.
+
+This CMake command was introduced in Qt 5.14.
+
+\section1 Example
+
+\snippet cmake-macros/examples.cmake qt5_import_qml_plugins
+
+*/
diff --git a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
index 7c8cd735b3..1f3602cde1 100644
--- a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
+++ b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc
@@ -148,7 +148,7 @@ To define the layout direction for a particular locale, declare the dedicated st
You can do this by first introducing this line
\code
-QT_TRANSLATE_NOOP("QGuiApplication", "QT_LAYOUT_DIRECTION");
+qsTr("QT_LAYOUT_DIRECTION","QGuiApplication");
\endcode
somewhere in your QML source code and calling \c lupdate to generate the translation source file.
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index 8edc5cb0b6..e83aa39734 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -31,15 +31,35 @@
\section1 Scene Graph Adaptations in Qt Quick
-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 and with Direct3D 12.
+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.14 onwards, the default adaptation gains the option of rendering via
+a graphics abstraction layer, the Qt Rendering Hardware Interface (RHI),
+provided by the \l QtGui module. When enabled, no direct OpenGL calls are made.
+Rather, the scene graph renders by using the APIs provided by the abstraction
+layer, which is then translated into OpenGL, Vulkan, Metal, or Direct 3D calls.
+Shader handling is also unified by writing shader code once, compiling to
+\l{https://www.khronos.org/spir/}{SPIR-V}, and then translating to the language
+appropriate for the various graphics APIs.
\target Switching Between the Adaptation Used by the Application
\section1 Switch Between Adaptations in Your Application
-The default rendering backend is still OpenGL, but in Qt builds with OpenGL support disabled, the
-default is the software renderer. You can override this in one of two ways:
+Unlike \c software or \c d3d12, 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
+\l QSGRendererInterface::GraphicsApi. When none of this is done, OpenGL is used
+directly like in previous versions.
+
+Switching to a different adaptation can be achieved in two ways:
\list
\li Use an environment variable - Set the \c{QT_QUICK_BACKEND} or the legacy
@@ -51,7 +71,8 @@ default is the software renderer. You can override this in one of two ways:
The following backends are supported:
\list
- \li OpenGL - Request with the \c{""} string or the QSGRendererInterface::OpenGL enum value.
+ \li Default - Request with the \c{""} string or a QSGRendererInterface::GraphicsApi enum value
+ 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
@@ -64,16 +85,25 @@ To find out which backend is in use, you can enable basic scene graph informatio
\c{QSG_INFO} environment variable or the \c{qt.scenegraph.general} logging category. This results
in some information being printed onto the debug output, during application startup.
-\note Typically, adaptations other than OpenGL come with a set of limitations as they are unlikely
- to provide a feature set that's 100% compatible with OpenGL. However, these adaptations may
- provide their own specific advantages in certain areas. For more information on the various
- adaptations, refer to the sections below.
+\note In Qt builds with OpenGL disabled, the default adaptation is \c software.
+This may change in future releases.
+
+\note Typically, adaptations other than the default one come with a set of
+limitations as they are unlikely to provide a feature set that's 100%
+compatible with OpenGL. However, these adaptations may provide their own
+specific advantages in certain areas. For more information on the various
+adaptations, refer to the sections below.
+
+\section1 Default Adaptation
-\section1 OpenGL ES 2.0 and OpenGL 2.0 Adaptation
+When using OpenGL directly, the default adaptation is capable of providing the
+full Qt Quick 2 feature set. For more details, see
+\l{qtquick-visualcanvas-scenegraph-renderer.html}{Default Adaptation}.
-The OpenGL adaptation is the default adaptation, which is capable of providing the full Qt Quick 2
-feature set. For more details, see
-\l{qtquick-visualcanvas-scenegraph-renderer.html}{OpenGL Adaptation}.
+When using OpenGL, Vulkan, Metal, or Direct 3D via the RHI, the default
+adaptation is capable of providing most features, including the full batching
+renderer described in \l{qtquick-visualcanvas-scenegraph-renderer.html}{Default
+Adaptation}, but some additional features may not be available as of Qt 5.14.
\section1 Software Adaptation
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index ee6c501c71..b96d09996d 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -31,15 +31,13 @@
\section1 The Scene Graph in Qt Quick
-Qt Quick 2 makes use of a dedicated scene graph based and a series of
-adaptations of which the default uses OpenGL ES 2.0 or OpenGL 2.0 for
-its rendering. Using a scene graph for graphics rather than the
-traditional imperative painting systems (QPainter and
-similar), means the scene to be rendered can be retained between
-frames and the complete set of primitives to render is known before
-rendering starts. This opens up for a number of optimizations, such as
-batch rendering to minimize state changes and discarding obscured
-primitives.
+Qt Quick 2 makes use of a dedicated scene graph that is then traversed and
+rendered via a graphics API such as OpenGL ES, OpenGL, Vulkan, Metal, or Direct
+3D. Using a scene graph for graphics rather than the traditional imperative
+painting systems (QPainter and similar), means the scene to be rendered can be
+retained between frames and the complete set of primitives to render is known
+before rendering starts. This opens up for a number of optimizations, such as
+batch rendering to minimize state changes and discarding obscured primitives.
For example, say a user-interface contains a list of ten items
where each item has a background color, an icon and a text. Using the
@@ -63,9 +61,10 @@ independently of the state of the items. On many platforms, the scene
graph will even be rendered on a dedicated render thread while the GUI
thread is preparing the next frame's state.
-\note Much of the information listed on this page is specific to the
-default OpenGL adaptation of the Qt Quick Scene graph. For more information
-about the different scene graph adaptations see
+\note Much of the information listed on this page is specific to the built-in,
+default behavior of the Qt Quick Scene graph. When using an alternative scene
+graph adaptation, such as, the \c software adaptation, not all concepts may
+apply. For more information about the different scene graph adaptations see
\l{qtquick-visualcanvas-adaptations.html}{Scene Graph Adaptations}.
@@ -106,10 +105,10 @@ Custom nodes are added to the scene graph by subclassing
QQuickItem::updatePaintNode() and setting the
\l {QQuickItem::ItemHasContents} flag.
-\warning It is crucial that OpenGL operations and interaction with the
-scene graph happens exclusively on the render thread, primarily
-during the updatePaintNode() call. The rule of thumb is to only
-use classes with the "QSG" prefix inside the
+\warning It is crucial that native graphics (OpenGL, Vulkan, Metal, etc.)
+operations and interaction with the scene graph happens exclusively on the
+render thread, primarily during the updatePaintNode() call. The rule of thumb
+is to only use classes with the "QSG" prefix inside the
QQuickItem::updatePaintNode() function.
For more details, see the \l {Scene Graph - Custom Geometry}.
@@ -133,11 +132,11 @@ simplifies cleanup when the scene graph lives outside the GUI thread.
\section2 Materials
-The material describes how the interior of a geometry in a \l
-QSGGeometryNode is filled. It encapsulates an OpenGL shader program
-and provides ample flexibility in what can be achieved, though most of
-the Qt Quick items themselves only use very basic materials, such as
-solid color and texture fills.
+The material describes how the interior of a geometry in a \l QSGGeometryNode
+is filled. It encapsulates graphics shaders for the vertex and fragment stages
+of the graphics pipeline and provides ample flexibility in what can be
+achieved, though most of the Qt Quick items themselves only use very basic
+materials, such as solid color and texture fills.
For users who just want to apply custom shading to a QML Item type,
it is possible to do this directly in QML using the \l ShaderEffect
@@ -151,11 +150,11 @@ For more details, see the \l {Scene Graph - Simple Material}
\section2 Convenience Nodes
-The scene graph API is very low-level and focuses on performance
-rather than convenience. Writing custom geometries and materials from
-scratch, even the most basic ones, requires a non-trivial amount of
-code. For this reason, the API includes a few convenience classes to
-make the most common custom nodes readily available.
+The scene graph API is low-level and focuses on performance rather than
+convenience. Writing custom geometries and materials from scratch, even the
+most basic ones, requires a non-trivial amount of code. For this reason, the
+API includes a few convenience classes to make the most common custom nodes
+readily available.
\list
\li \l QSGSimpleRectNode - a QSGGeometryNode subclass which defines a
@@ -169,15 +168,16 @@ a rectangular geometry with a texture material.
\section1 Scene Graph and Rendering
-The rendering of the scene graph happens internally in the
-QQuickWindow class, and there is no public API to access it. There are,
-however, a few places in the rendering pipeline where the user can
-attach application code. This can be used to add custom scene graph
-content or render raw OpenGL content. The integration points are
-defined by the render loop.
+The rendering of the scene graph happens internally in the QQuickWindow class,
+and there is no public API to access it. There are, however, a few places in
+the rendering pipeline where the user can attach application code. This can be
+used to add custom scene graph content or to insert arbitrary rendering
+commands by directly calling the graphics API (OpenGL, Vulkan, Metal, etc.)
+that is in use by the scene graph. The integration points are defined by the
+render loop.
-For detailed description of how the scene graph renderer for OpenGL
-works, see \l {Qt Quick Scene Graph OpenGL Renderer}.
+For detailed description of how the scene graph renderer works, see \l {Qt
+Quick Scene Graph Default Renderer}.
There are three render loop variants available: \c basic, \c windows,
and \c threaded. Out of these, \c basic and \c windows are
@@ -189,14 +189,14 @@ satisfactory, or for testing purposes, the environment variable
verify which render loop is in use, enable the \c qt.scenegraph.general
\l {QLoggingCategory}{logging category}.
-\note The \c threaded and \c windows render loops rely on the OpenGL
-implementation for throttling by requesting a swap interval of 1. Some
-graphics drivers allow users to override this setting and turn it off,
-ignoring Qt's request. Without blocking in the swap buffers operation
-(or elsewhere), the render loop will run animations too fast and spin
-the CPU at 100%. If a system is known to be unable to provide
-vsync-based throttling, use the \c basic render loop instead by
-setting \c {QSG_RENDER_LOOP=basic} in the environment.
+\note The \c threaded and \c windows render loops rely on the graphics API
+implementation for throttling, for example, by requesting a swap interval of 1
+in case of OpenGL. Some graphics drivers allow users to override this setting
+and turn it off, ignoring Qt's request. Without blocking in the swap buffers
+operation (or elsewhere), the render loop will run animations too fast and spin
+the CPU at 100%. If a system is known to be unable to provide vsync-based
+throttling, use the \c basic render loop instead by setting \c
+{QSG_RENDER_LOOP=basic} in the environment.
\section2 Threaded Render Loop ("threaded")
@@ -207,8 +207,9 @@ waiting for a blocking swap buffer call. This offers significant
performance improvements, but imposes certain restrictions on where
and when interaction with the scene graph can happen.
-The following is a simple outline of how a frame gets
-composed with the threaded render loop.
+The following is a simple outline of how a frame gets rendered with the
+threaded render loop and OpenGL. The steps are the same with other graphics
+APIs as well, apart from the OpenGL context specifics.
\image sg-renderloop-threaded.png
@@ -219,8 +220,8 @@ to be called. This can be the result of for instance an animation or
user input. An event is posted to the render thread to initiate a new
frame.
-\li The render thread prepares to draw a new frame and makes the
-OpenGL context current and initiates a block on the GUI thread.
+\li The render thread prepares to draw a new frame and initiates a block on the
+GUI thread.
\li While the render thread is preparing the new frame, the GUI thread
calls QQuickItem::updatePolish() to do final touch-up of items before
@@ -243,23 +244,27 @@ time the QML items and the nodes in the scene graph interact.
\li The scene graph is rendered:
\list 1
- \li The QQuickWindow::beforeRendering() signal is
- emitted. Applications can make direct connections
- (using Qt::DirectConnection) to this signal to use custom OpenGL calls
- which will then stack visually beneath the QML scene.
+ \li The QQuickWindow::beforeRendering() signal is emitted. Applications can
+ make direct connections (using Qt::DirectConnection) to this signal to use
+ custom graphics API calls which will then stack visually beneath the QML
+ scene.
\li Items that have specified QSGNode::UsePreprocess, will have their
QSGNode::preprocess() function invoked.
- \li The renderer processes the nodes and calls OpenGL functions.
+ \li The renderer processes the nodes.
- \li The QQuickWindow::afterRendering() signal is
- emitted. Applications can make direct connections
- (using Qt::DirectConnection) to this signal to use custom OpenGL calls
- which will then stack visually over the QML scene.
+ \li The renderer generates states and records draw calls for the graphics
+ API in use.
- \li The rendered frame is swapped and QQuickWindow::frameSwapped()
- is emitted.
+ \li The QQuickWindow::afterRendering() signal is emitted. Applications can
+ make direct connections (using Qt::DirectConnection) to this signal to
+ issue custom graphics API calls which will then stack visually over the QML
+ scene.
+
+ \li The frame is now ready. The buffers are swapped (OpenGL), or a present
+ command is recorded and the command buffers are submitted to a graphics
+ queue (Vulkan, Metal). QQuickWindow::frameSwapped() is emitted.
\endlist
@@ -269,37 +274,38 @@ animations, process events, etc.
\endlist
The threaded renderer is currently used by default on Windows with
-opengl32.dll, Linux with non-Mesa based drivers, mobile
-platforms, and Embedded Linux with EGLFS but this is subject to
-change. It is possible to force use of the threaded renderer by
-setting \c {QSG_RENDER_LOOP=threaded} in the environment.
+opengl32.dll, Linux excluding Mesa llvmpipe, \macos with Metal, mobile
+platforms, and Embedded Linux with EGLFS, and with Vulkan regardless of the
+platform, but this is subject to change. It is always possible to force use of
+the threaded renderer by setting \c {QSG_RENDER_LOOP=threaded} in the
+environment.
\section2 Non-threaded Render Loops ("basic" and "windows")
-The non-threaded render loop is currently used by default on Windows
-with ANGLE or a non-default opengl32 implementation, \macos, and Linux with
-Mesa drivers. For the latter this is mostly a precautionary measure,
-as not all combinations of OpenGL drivers and windowing systems have
-been tested. At the same time implementations like ANGLE or Mesa
-llvmpipe are not able to function properly with threaded rendering at
-all so not using threaded rendering is essential for these.
+The non-threaded render loop is currently used by default on Windows with ANGLE
+or a non-default opengl32 implementation, \macos with OpenGL, and Linux with
+some drivers. For the latter this is mostly a precautionary measure, as not all
+combinations of OpenGL drivers and windowing systems have been tested. At the
+same time implementations like ANGLE or Mesa llvmpipe are not able to function
+properly with threaded rendering at all so not using threaded rendering is
+essential for these.
-On macOS, the threaded render loop is not supported when building
-with XCode 10 (10.14 SDK) or later, since this opts in to layer-backed
-views on macOS 10.14. You can build with Xcode 9 (10.13 SDK) to opt
-out of layer-backing, in which case the threaded render loop is
-available and used by default.
+On macOS and OpenGL, the threaded render loop is not supported when building
+with XCode 10 (10.14 SDK) or later, since this opts in to layer-backed views on
+macOS 10.14. You can build with Xcode 9 (10.13 SDK) to opt out of
+layer-backing, in which case the threaded render loop is available and used by
+default. There is no such restriction with Metal.
-By default \c windows is used for non-threaded rendering on Windows
-with ANGLE, while \c basic is used for all other platforms when
-non-threaded rendering is needed.
+By default \c windows is used for non-threaded rendering on Windows with ANGLE,
+while \c basic is used for all other platforms when non-threaded rendering is
+needed.
-Even when using the non-threaded render loop, you should write your
-code as if you are using the threaded renderer, as failing to do so
-will make the code non-portable.
+Even when using the non-threaded render loop, you should write your code as if
+you are using the threaded renderer, as failing to do so will make the code
+non-portable.
-The following is a simplified illustration of the frame rendering
-sequence in the non-threaded renderer.
+The following is a simplified illustration of the frame rendering sequence in
+the non-threaded renderer.
\image sg-renderloop-singlethreaded.png
@@ -314,32 +320,37 @@ time. It is possible to implement either a threaded or non-threaded
behavior similar to the ones shown above.
-\section2 Mixing Scene Graph and OpenGL
+\section2 Mixing Scene Graph and the native graphics API
-The scene graph offers two methods for integrating OpenGL content:
-by calling OpenGL commands directly and by creating a textured node
-in the scene graph.
+The scene graph offers two methods for integrating application-provided
+graphics commands: by issuing OpenGL, Vulkan, Metal, etc. commands directly,
+and by creating a textured node in the scene graph.
By connecting to the \l QQuickWindow::beforeRendering() and \l
-QQuickWindow::afterRendering() signals, applications can make OpenGL
-calls directly into the same context as the scene graph is rendering
-to. As the signal names indicate, the user can then render OpenGL
-content either under a Qt Quick scene or over it. The benefit of
-integrating in this manner is that no extra framebuffer nor memory is
-needed to perform the rendering. The downside is that Qt Quick decides
-when to call the signals and this is the only time the OpenGL
-application is allowed to draw.
+QQuickWindow::afterRendering() signals, applications can make OpenGL calls
+directly into the same context as the scene graph is rendering to. With APIs
+like Vulkan or Metal, applications can query native objects, such as, the scene
+graph's command buffer, via QSGRendererInterface, and record commands to it as
+they see fit. As the signal names indicate, the user can then render content
+either under a Qt Quick scene or over it. The benefit of integrating in this
+manner is that no extra framebuffer nor memory is needed to perform the
+rendering, and a possibly expensive texturing step is eliminated. The downside
+is that Qt Quick decides when to call the signals and this is the only time the
+OpenGL application is allowed to draw.
The \l {Scene Graph - OpenGL Under QML} example gives an example on
-how to use these signals.
+how to use these signals using OpenGL.
+
+The \l {Scene Graph - Metal Under QML} example gives an example on
+how to use these signals using Metal.
-The other alternative is to create a QQuickFramebufferObject, render
-into it, and let it be displayed in the scene graph as a texture.
-The \l {Scene Graph - Rendering FBOs} example shows how this can be
-done. It is also possible to combine multiple rendering contexts and
-multiple threads to create content to be displayed in the scene graph.
-The \l {Scene Graph - Rendering FBOs in a thread} examples show how
-this can be done.
+The other alternative, only available for OpenGL currently, is to create a
+QQuickFramebufferObject, render into it, and let it be displayed in the scene
+graph as a texture. The \l {Scene Graph - Rendering FBOs} example shows how
+this can be done. It is also possible to combine multiple rendering contexts
+and multiple threads to create content to be displayed in the scene graph. The
+\l {Scene Graph - Rendering FBOs in a thread} examples show how this can be
+done.
\warning When mixing OpenGL content with scene graph rendering, it is
important the application does not leave the OpenGL context in a state
@@ -347,8 +358,8 @@ with buffers bound, attributes enabled, special values in the z-buffer
or stencil-buffer or similar. Doing so can result in unpredictable
behavior.
-\warning The OpenGL rendering code must be thread aware, as the
-rendering might be happening outside the GUI thread.
+\warning The custom rendering code must be thread aware in the sense that it
+should not assume being executed on the GUI (main) thread of the application.
\section2 Custom Items using QPainter
@@ -386,6 +397,15 @@ addition to being helpful to Qt contributors.
\endlist
+The legacy \c{QSG_INFO} environment variable is also available. Setting it to a
+non-zero value enables the \c{qt.scenegraph.general} category.
+
+\note When encountering graphics problems, or when in doubt which render loop
+or graphics API is in use, always start the application with at least
+\c{qt.scenegraph.general} and \c{qt.rhi.*} enabled, or \c{QSG_INFO=1} set. This
+will then print some essential information onto the debug output during
+initialization.
+
\section1 Scene Graph Backend
In addition to the public API, the scene graph has an adaptation layer
@@ -419,13 +439,12 @@ with multiple windows.
*/
/*!
- \title Qt Quick Scene Graph OpenGL Renderer
+ \title Qt Quick Scene Graph Default Renderer
\page qtquick-visualcanvas-scenegraph-renderer.html
- This document explains how the scene graph renderer for OpenGL
- works internally
+ This document explains how the default scene graph renderer works internally,
so that one can write code that uses it in an optimal fashion, both
- performance-wise and feature-wise.
+ performance and feature-wise.
One does not need to understand the internals of the renderer to get
good performance. However, it might help when integrating with the
@@ -442,8 +461,8 @@ with multiple windows.
platforms be processed and rendered in a separate thread. The
renderer is a self contained part of the scene graph which traverses
the QSGNode tree and uses geometry defined in QSGGeometryNode and
- shader state defined in QSGMaterial to schedule OpenGL state change
- and draw calls.
+ shader state defined in QSGMaterial to update the graphics state and
+ generate draw calls.
If needed, the renderer can be completely replaced using the
internal scene graph back-end API. This is mostly interesting for
@@ -457,11 +476,15 @@ with multiple windows.
\section1 Batching
- Where a traditional 2D API, such as QPainter, Cairo or Context2D, is
- written to handle thousands of individual draw calls per frame,
- OpenGL is a pure hardware API and performs best when the number of
- draw calls is very low and state changes are kept to a
- minimum. Consider the following use case:
+ Whereas a traditional 2D API, such as QPainter, Cairo or Context2D, is
+ written to handle thousands of individual draw calls per frame, OpenGL and
+ other hardware accelerated APIs perform best when the number of draw calls is
+ very low and state changes are kept to a minimum.
+
+ \note While \c OpenGL is used as an example in the following sections, the
+ same concepts apply to other graphics APIs as well.
+
+ Consider the following use case:
\image visualcanvas_list.png
@@ -934,4 +957,65 @@ with multiple windows.
\image visualize-overdraw-1.png "overdraw-1"
\image visualize-overdraw-2.png "overdraw-2"
\c QSG_VISUALIZE=overdraw
+
+ \section1 Rendering via the Qt Rendering Hardware Interface
+
+ From Qt 5.14 onwards, the default adaptation gains the option of rendering
+ via a graphics abstraction layer, the Qt Rendering Hardware Interface (RHI),
+ provided by the \l QtGui module. When enabled, no direct OpenGL calls are
+ made. Rather, the scene graph renders by using the APIs provided by the
+ abstraction layer, which is then translated into OpenGL, Vulkan, Metal, or
+ Direct 3D calls. Shader handling is also unified by writing shader code once,
+ compiling to \l{https://www.khronos.org/spir/}{SPIR-V}, and then translating
+ to the language appropriate for the various graphics APIs.
+
+ To enable this instead of directly using OpenGL, the following environment
+ variables can be used:
+
+ \table 100%
+ \header
+ \li Environment Variable
+ \li Possible Values
+ \li Description
+
+ \row
+ \li \c QSG_RHI
+ \li \c 1
+ \li Enables rendering via the RHI. The targeted graphics API is chosen based on
+ the platform, unless overridden by \c QSG_RHI_BACKEND. The defaults are currently
+ Direct3D 11 for Windows, Metal for macOS, OpenGL elsehwere.
+
+ \row
+ \li \c QSG_RHI_BACKEND
+ \li \c vulkan, \c metal, \c opengl, \c d3d11
+ \li Requests the specific RHI backend.
+
+ \row
+ \li \c QSG_INFO
+ \li \c 1
+ \li Like with the OpenGL-based rendering path, setting this enables printing system
+ information when initializing the Qt Quick scene graph. This can be very useful for
+ troubleshooting.
+
+ \row
+ \li \c QSG_RHI_DEBUG_LAYER
+ \li \c 1
+ \li Where applicable (Vulkan, Direct3D), enables the graphics API implementation's debug
+ and/or validation layers, if available.
+
+ \endtable
+
+ Applications wishing to always run with a single given graphics API, can
+ request this via C++ as well. For example, the following call made early in
+ main(), before constructing any QQuickWindow, forces the use of Vulkan (and
+ will fail otherwise);
+
+ \badcode
+ QQuickWindow::setSceneGraphBackend(QSGRendererInterface::VulkanRhi);
+ \endcode
+
+ See QSGRendererInterface::GraphicsApi. The enum values ending in \c Rhi are
+ equivalent in effect to running with both \c QSG_RHI and \c QSG_RHI_BACKEND
+ set.
+
*/
diff --git a/src/quick/doc/src/concepts/visualcanvas/topic.qdoc b/src/quick/doc/src/concepts/visualcanvas/topic.qdoc
index cb6b3564f2..677e5bd739 100644
--- a/src/quick/doc/src/concepts/visualcanvas/topic.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/topic.qdoc
@@ -56,12 +56,15 @@ See the documentation about the \l{qtquick-visualcanvas-visualparent.html}
\section1 Scene Graph
Modern computer systems and devices use graphics processing units or GPUs to
-render graphics. Qt Quick can leverage this graphics hardware by using graphics
-APIs like OpenGL. The default graphics adaptation for Qt Quick requires OpenGL and
-it is used to display applications developed with Qt Quick in QML. In particular,
-Qt Quick defines a scene graph which is then rendered. See the documentation about the
-\l{qtquick-visualcanvas-scenegraph.html}{Scene Graph} for in-depth information about
-the concept of a scene graph and why it is beneficial, and about the scene graph
-adaptations provided by Qt Quick.
+render graphics. Qt Quick can leverage this graphics hardware by using graphics
+APIs like \l{https://www.khronos.org/opengl/}{OpenGL},
+\l{https://www.khronos.org/vulkan/}{Vulkan}, or
+\l{https://developer.apple.com/documentation/metal}{Metal}. The default
+graphics adaptation for Qt Quick requires OpenGL and it is used to display
+applications developed with Qt Quick in QML. In particular, Qt Quick defines a
+scene graph which is then rendered. See the documentation about the
+\l{qtquick-visualcanvas-scenegraph.html}{Scene Graph} for in-depth information
+about the concept of a scene graph and why it is beneficial, and about the
+scene graph adaptations provided by Qt Quick.
*/
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index 77475e9812..9034c90eb8 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -172,12 +172,15 @@ Creator.
\b{Scene Graph}
\list
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
+ \li \l{Scene Graph - Metal Under QML}{Metal Under QML}
+ \li \l{Scene Graph - Direct3D 11 Under QML}{Direct3D 11 Under QML}
\li \l{Scene Graph - Painted Item}{Painted Item}
\li \l{Scene Graph - Custom Geometry}{Custom Geometry}
\li \l{Scene Graph - Graph}{Graph}
\li \l{Scene Graph - Simple Material}{Simple Material}
\li \l{Scene Graph - Rendering FBOs}{Rendering FBOs}
\li \l{Scene Graph - Rendering FBOs in a thread}{Rendering FBOs in a thread}
+ \li \l{Scene Graph - Custom Rendering with QSGRenderNode}{Render Node}
\endlist
\enddiv
\enddiv
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index 18c1fd841d..e8f47163ed 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -62,7 +62,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
- Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
+ Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION 14)
public:
enum SnapMode {
@@ -89,7 +89,7 @@ public:
Q_SIGNALS:
void translationChanged();
- void snapModeChanged();
+ Q_REVISION(14) void snapModeChanged();
protected:
void onActiveChanged() override;
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index 255e47d73a..a10064a665 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -78,8 +78,8 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
\l gesturePolicy to \c TapHandler.ReleaseWithinBounds.
For multi-tap gestures (double-tap, triple-tap etc.), the distance moved
- must not exceed QPlatformTheme::MouseDoubleClickDistance with mouse and
- QPlatformTheme::TouchDoubleTapDistance with touch, and the time between
+ must not exceed QStyleHints::mouseDoubleClickDistance() with mouse and
+ QStyleHints::touchDoubleTapDistance() with touch, and the time between
taps must not exceed QStyleHints::mouseDoubleClickInterval().
\sa MouseArea
@@ -90,11 +90,9 @@ QQuickTapHandler::QQuickTapHandler(QQuickItem *parent)
{
if (m_mouseMultiClickDistanceSquared < 0) {
m_multiTapInterval = qApp->styleHints()->mouseDoubleClickInterval() / 1000.0;
- m_mouseMultiClickDistanceSquared = QGuiApplicationPrivate::platformTheme()->
- themeHint(QPlatformTheme::MouseDoubleClickDistance).toInt();
+ m_mouseMultiClickDistanceSquared = qApp->styleHints()->mouseDoubleClickDistance();
m_mouseMultiClickDistanceSquared *= m_mouseMultiClickDistanceSquared;
- m_touchMultiTapDistanceSquared = QGuiApplicationPrivate::platformTheme()->
- themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt();
+ m_touchMultiTapDistanceSquared = qApp->styleHints()->touchDoubleTapDistance();
m_touchMultiTapDistanceSquared *= m_touchMultiTapDistanceSquared;
}
}
@@ -410,9 +408,9 @@ void QQuickTapHandler::updateTimeHeld()
\since 5.11
This signal is emitted when the \c parent Item is tapped twice within a
- short span of time (QStyleHints::mouseDoubleClickInterval) and distance
- (QPlatformTheme::MouseDoubleClickDistance or
- QPlatformTheme::TouchDoubleTapDistance). This signal always occurs after
+ short span of time (QStyleHints::mouseDoubleClickInterval()) and distance
+ (QStyleHints::mouseDoubleClickDistance() or
+ QStyleHints::touchDoubleTapDistance()). This signal always occurs after
\l singleTapped, \l tapped, and \l tapCountChanged. The \c eventPoint
signal parameter contains information from the release event about the
point that was tapped.
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index fe445425e7..bebefc1b22 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
.arg(current));
}
if (!requestedUrl.isEmpty()) {
- if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions()))
+ if (QQuickPixmap::isCached(requestedUrl, QSize(), 0, QQuickImageProviderOptions()))
pixmap = new QQuickPixmap(engine, requestedUrl);
else
pixmap = new QQuickPixmap(requestedUrl, movie->currentImage());
@@ -139,6 +139,8 @@ QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent)
: QQuickImage(*(new QQuickAnimatedImagePrivate), parent)
{
connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged);
+ connect(this, &QQuickImageBase::currentFrameChanged, this, &QQuickAnimatedImage::frameChanged);
+ connect(this, &QQuickImageBase::frameCountChanged, this, &QQuickAnimatedImage::frameCountChanged);
}
QQuickAnimatedImage::~QQuickAnimatedImage()
@@ -464,7 +466,7 @@ void QQuickAnimatedImage::movieUpdate()
if (d->movie) {
d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
- emit frameChanged();
+ emit currentFrameChanged();
}
}
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 6b5db215bd..ef5af6b387 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -85,10 +85,10 @@ public:
bool isPaused() const;
void setPaused(bool pause);
- int currentFrame() const;
- void setCurrentFrame(int frame);
+ int currentFrame() const override;
+ void setCurrentFrame(int frame) override;
- int frameCount() const;
+ int frameCount() const override;
qreal speed() const;
void setSpeed(qreal speed);
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index c53a39ca09..430fa1b094 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -343,7 +343,7 @@ void QQuickBorderImage::load()
QUrl loadUrl = d->url;
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options);
+ d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
if (d->pix.isLoading()) {
if (d->progress != 0.0) {
@@ -534,6 +534,10 @@ void QQuickBorderImage::requestFinished()
d->oldSourceSize = sourceSize();
emit sourceSizeChanged();
}
+ if (d->frameCount != d->pix.frameCount()) {
+ d->frameCount = d->pix.frameCount();
+ emit frameCountChanged();
+ }
pixmapChange();
}
@@ -693,6 +697,18 @@ void QQuickBorderImage::pixmapChange()
update();
}
+/*!
+ \qmlproperty int QtQuick::BorderImage::currentFrame
+ \qmlproperty int QtQuick::BorderImage::frameCount
+ \since 5.14
+
+ currentFrame is the frame that is currently visible. The default is \c 0.
+ You can set it to a number between \c 0 and \c {frameCount - 1} to display a
+ different frame, if the image contains multiple frames.
+
+ frameCount is the number of frames in the image. Most images have only one frame.
+*/
+
QT_END_NAMESPACE
#include "moc_qquickborderimage_p.cpp"
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index ad3a39dd71..b0cfbaad6d 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1448,7 +1448,7 @@ QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
m_synthSource = ev->source();
m_inverted = ev->inverted();
- m_point->reset(Qt::TouchPointMoved, ev->posF(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
+ m_point->reset(Qt::TouchPointMoved, ev->position(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
}
#endif
// TODO else if (event->type() == QEvent::Scroll) ...
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 7e1f54f07e..cf3cd9f48e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1489,7 +1489,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
d->vData.velocity = 0;
d->hData.velocity = 0;
d->timer.start();
- d->maybeBeginDrag(currentTimestamp, event->posF());
+ d->maybeBeginDrag(currentTimestamp, event->position());
break;
case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse
case Qt::ScrollUpdate:
@@ -1571,7 +1571,8 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
QVector2D velocity(xDelta / elapsed, yDelta / elapsed);
d->lastPosTime = currentTimestamp;
d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta());
- d->drag(currentTimestamp, event->type(), event->posF(), d->accumulatedWheelPixelDelta, true, !d->scrollingPhase, true, velocity);
+ d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta,
+ true, !d->scrollingPhase, true, velocity);
event->accept();
}
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 48f8b8db5c..190bc6853c 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -109,6 +109,10 @@ public:
* and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
* classes that consume texture providers.
*
+ * \warning This class is only suitable when working directly with OpenGL. It
+ * is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
+ * path}.
+ *
* \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index d66ca40b3a..db143e48cf 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -44,11 +44,12 @@
QT_BEGIN_NAMESPACE
-
class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
+// ### Qt 6: To be removed. To be seen if an alternative will need to be introduced.
+
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{
Q_OBJECT
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index dfbe271606..c7e7ccea55 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -687,7 +687,6 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
yOffset = qCeil(height() - pixHeight);
switch (d->fillMode) {
- default:
case Stretch:
targetRect = QRectF(0, 0, width(), height());
sourceRect = d->pix.rect();
@@ -699,7 +698,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
break;
case PreserveAspectCrop: {
- targetRect = QRect(0, 0, width(), height());
+ targetRect = QRectF(0, 0, width(), height());
qreal wscale = width() / qreal(d->pix.width());
qreal hscale = height() / qreal(d->pix.height());
@@ -751,7 +750,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
targetRect = QRectF(x + xOffset, y + yOffset, w, h);
sourceRect = QRectF(x, y, w, h);
break;
- };
+ }
qreal nsWidth = (hWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->pix.width() / d->devicePixelRatio : d->pix.width();
qreal nsHeight = (vWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->pix.height() / d->devicePixelRatio : d->pix.height();
@@ -889,4 +888,16 @@ void QQuickImage::setMipmap(bool use)
By default, this property is set to false.
*/
+/*!
+ \qmlproperty int QtQuick::Image::currentFrame
+ \qmlproperty int QtQuick::Image::frameCount
+ \since 5.14
+
+ currentFrame is the frame that is currently visible. The default is \c 0.
+ You can set it to a number between \c 0 and \c {frameCount - 1} to display a
+ different frame, if the image contains multiple frames.
+
+ frameCount is the number of frames in the image. Most images have only one frame.
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 7fb4413900..257cde5313 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -66,8 +66,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
- Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 1)
- Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 2)
+ Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 3)
+ Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5)
public:
QQuickImage(QQuickItem *parent=nullptr);
@@ -112,8 +112,8 @@ Q_SIGNALS:
void paintedGeometryChanged();
void horizontalAlignmentChanged(HAlignment alignment);
void verticalAlignmentChanged(VAlignment alignment);
- Q_REVISION(1) void mipmapChanged(bool);
- Q_REVISION(2) void autoTransformChanged();
+ Q_REVISION(3) void mipmapChanged(bool);
+ Q_REVISION(5) void autoTransformChanged();
private Q_SLOTS:
void invalidateSceneGraph();
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 729d326625..8bab14bfd1 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
// if they're not happy with our implementation of it.
bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio)
{
- // QQuickImageProvider and SVG can generate a high resolution image when
+ // QQuickImageProvider and SVG and PDF can generate a high resolution image when
// sourceSize is set (this function is only called if it's set).
// If sourceSize is not set then the provider default size will be used, as usual.
bool setDevicePixelRatio = false;
@@ -64,7 +64,8 @@ bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio
} else {
QString stringUrl = url.path(QUrl::PrettyDecoded);
if (stringUrl.endsWith(QLatin1String("svg")) ||
- stringUrl.endsWith(QLatin1String("svgz"))) {
+ stringUrl.endsWith(QLatin1String("svgz")) ||
+ stringUrl.endsWith(QLatin1String("pdf"))) {
setDevicePixelRatio = true;
}
}
@@ -210,6 +211,36 @@ bool QQuickImageBase::mirror() const
return d->mirror;
}
+void QQuickImageBase::setCurrentFrame(int frame)
+{
+ Q_D(QQuickImageBase);
+ if (frame == d->currentFrame || frame < 0 || (isComponentComplete() && frame >= d->pix.frameCount()))
+ return;
+
+ d->currentFrame = frame;
+
+ if (isComponentComplete()) {
+ if (frame > 0)
+ d->cache = false;
+ load();
+ update();
+ }
+
+ emit currentFrameChanged();
+}
+
+int QQuickImageBase::currentFrame() const
+{
+ Q_D(const QQuickImageBase);
+ return d->currentFrame;
+}
+
+int QQuickImageBase::frameCount() const
+{
+ Q_D(const QQuickImageBase);
+ return d->frameCount;
+}
+
void QQuickImageBase::load()
{
Q_D(QQuickImageBase);
@@ -260,7 +291,7 @@ void QQuickImageBase::load()
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
}
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions);
+ d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions, d->currentFrame, d->frameCount);
if (d->pix.isLoading()) {
if (d->progress != 0.0) {
@@ -319,6 +350,11 @@ void QQuickImageBase::requestFinished()
d->oldAutoTransform = autoTransform();
emitAutoTransformBaseChanged();
}
+ if (d->frameCount != d->pix.frameCount()) {
+ d->frameCount = d->pix.frameCount();
+ emit frameCountChanged();
+ }
+
update();
}
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index d8d0be9b8c..8cd59c8cea 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -68,6 +68,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged)
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged)
Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
+ Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION 14)
+ Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION 14)
public:
QQuickImageBase(QQuickItem *parent=nullptr);
@@ -95,6 +97,11 @@ public:
virtual void setMirror(bool mirror);
bool mirror() const;
+ virtual void setCurrentFrame(int frame);
+ virtual int currentFrame() const;
+
+ virtual int frameCount() const;
+
virtual void setAutoTransform(bool transform);
bool autoTransform() const;
@@ -112,6 +119,8 @@ Q_SIGNALS:
void asynchronousChanged();
void cacheChanged();
void mirrorChanged();
+ Q_REVISION(14) void currentFrameChanged();
+ Q_REVISION(14) void frameCountChanged();
protected:
virtual void load();
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 1b771166a2..88e18ba32e 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
@@ -68,6 +68,8 @@ public:
: status(QQuickImageBase::Null),
progress(0.0),
devicePixelRatio(1.0),
+ currentFrame(0),
+ frameCount(0),
async(false),
cache(true),
mirror(false),
@@ -85,6 +87,8 @@ public:
QSize oldSourceSize;
qreal devicePixelRatio;
QQuickImageProviderOptions providerOptions;
+ int currentFrame;
+ int frameCount;
bool async : 1;
bool cache : 1;
bool mirror: 1;
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index ad9bab2a90..394a5adb8c 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -318,7 +318,7 @@ public:
void setKeepTouchGrab(bool);
// implemented in qquickitemgrabresult.cpp
- Q_REVISION(2) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
+ Q_REVISION(4) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize());
Q_INVOKABLE virtual bool contains(const QPointF &point) const;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 8aa259a7b6..6db664f705 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -245,28 +245,28 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput");
qmlRegisterType<QQuickTextInput,2>(uri,2,2,"TextInput");
- qmlRegisterType<QQuickTextInput,3>(uri,2,4,"TextInput");
- qmlRegisterType<QQuickItemGrabResult>();
+ qmlRegisterType<QQuickTextInput,4>(uri,2,4,"TextInput");
+ qmlRegisterAnonymousType<QQuickItemGrabResult>(uri, major);
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickItemLayer>();
-#endif
- qmlRegisterType<QQuickAnchors>();
- qmlRegisterType<QQuickKeyEvent>();
- qmlRegisterType<QQuickMouseEvent>();
- qmlRegisterType<QQuickWheelEvent>();
- qmlRegisterType<QQuickCloseEvent>();
- qmlRegisterType<QQuickTransform>();
+ qmlRegisterAnonymousType<QQuickItemLayer>(uri, major);
+#endif
+ qmlRegisterAnonymousType<QQuickAnchors>(uri, major);
+ qmlRegisterAnonymousType<QQuickKeyEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickMouseEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickWheelEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickCloseEvent>(uri, major);
+ qmlRegisterAnonymousType<QQuickTransform>(uri, major);
#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathElement>();
- qmlRegisterType<QQuickCurve>();
+ qmlRegisterAnonymousType<QQuickPathElement>(uri, major);
+ qmlRegisterAnonymousType<QQuickCurve>(uri, major);
#endif
- qmlRegisterType<QQuickScaleGrid>();
- qmlRegisterType<QQuickTextLine>();
- qmlRegisterType<QQuickPen>();
- qmlRegisterType<QQuickFlickableVisibleArea>();
+ qmlRegisterAnonymousType<QQuickScaleGrid>(uri, major);
+ qmlRegisterAnonymousType<QQuickTextLine>(uri, major);
+ qmlRegisterAnonymousType<QQuickPen>(uri, major);
+ qmlRegisterAnonymousType<QQuickFlickableVisibleArea>(uri, major);
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
- qmlRegisterType<QQuickTextDocument>();
+ qmlRegisterAnonymousType<QQuickTextDocument>(uri, major);
qmlRegisterUncreatableType<QQuickKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QQuickKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
@@ -278,7 +278,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPinchArea>(uri,major,minor,"PinchArea");
qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch");
- qmlRegisterType<QQuickPinchEvent>();
+ qmlRegisterAnonymousType<QQuickPinchEvent>(uri, major);
#if QT_CONFIG(quick_shadereffect)
qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
@@ -301,7 +301,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
- qmlRegisterType<QQuickAnchorSet>();
+ qmlRegisterAnonymousType<QQuickAnchorSet>(uri, major);
qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
#if QT_CONFIG(quick_path)
@@ -311,8 +311,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_draganddrop)
qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea");
- qmlRegisterType<QQuickDropEvent>();
- qmlRegisterType<QQuickDropAreaDrag>();
+ qmlRegisterAnonymousType<QQuickDropEvent>(uri, 2);
+ qmlRegisterAnonymousType<QQuickDropAreaDrag>(uri, 2);
qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
#endif
@@ -333,7 +333,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
const char *itemViewName = "ItemView";
const QString itemViewMessage = QQuickItemView::tr("ItemView is an abstract base class");
qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, itemViewName, itemViewMessage);
- qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, itemViewName, itemViewMessage);
+ qmlRegisterUncreatableType<QQuickItemView, 3>(uri, 2, 3, itemViewName, itemViewMessage);
#endif
#if QT_CONFIG(quick_listview)
qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
@@ -348,23 +348,23 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickText, 3>(uri, 2, 3, "Text");
qmlRegisterType<QQuickTextEdit, 3>(uri, 2, 3, "TextEdit");
- qmlRegisterType<QQuickImage, 1>(uri, 2, 3,"Image");
+ qmlRegisterType<QQuickImage, 3>(uri, 2, 3,"Image");
- qmlRegisterType<QQuickItem, 2>(uri, 2, 4, "Item");
+ qmlRegisterType<QQuickItem, 4>(uri, 2, 4, "Item");
#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 2>(uri, 2, 4, "ListView");
+ qmlRegisterType<QQuickListView, 4>(uri, 2, 4, "ListView");
#endif
- qmlRegisterType<QQuickMouseArea, 1>(uri, 2, 4, "MouseArea");
+ qmlRegisterType<QQuickMouseArea, 4>(uri, 2, 4, "MouseArea");
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffect, 1>(uri, 2, 4, "ShaderEffect");
+ qmlRegisterType<QQuickShaderEffect, 4>(uri, 2, 4, "ShaderEffect");
#endif
#if QT_CONFIG(opengl)
qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties"));
#endif
- qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
- qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image");
- qmlRegisterType<QQuickMouseArea, 2>(uri, 2, 5, "MouseArea");
+ qmlRegisterType<QQuickPinchArea, 5>(uri, 2, 5,"PinchArea");
+ qmlRegisterType<QQuickImage, 5>(uri, 2, 5,"Image");
+ qmlRegisterType<QQuickMouseArea, 5>(uri, 2, 5, "MouseArea");
qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
@@ -380,7 +380,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource");
+ qmlRegisterType<QQuickShaderEffectSource, 6>(uri, 2, 6, "ShaderEffectSource");
#endif
qmlRegisterType<QQuickItem, 7>(uri, 2, 7, "Item");
@@ -410,7 +410,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathArc, 2>(uri, 2, 9, "PathArc");
+ qmlRegisterType<QQuickPathArc, 9>(uri, 2, 9, "PathArc");
qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
#endif
@@ -425,7 +425,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#endif
#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource");
+ qmlRegisterType<QQuickShaderEffectSource, 9>(uri, 2, 9, "ShaderEffectSource");
#endif
qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
@@ -479,7 +479,11 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_itemview)
qmlRegisterUncreatableType<QQuickItemView, 13>(uri, 2, 13, itemViewName, itemViewMessage);
+#endif
+#if QT_CONFIG(quick_pathview)
qmlRegisterType<QQuickPathView, 13>(uri, 2, 13, "PathView");
+#endif
+#if QT_CONFIG(quick_gridview)
qmlRegisterType<QQuickGridView, 13>(uri, 2, 13, "GridView");
#endif
#if QT_CONFIG(quick_tableview)
@@ -488,6 +492,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(wheelevent)
qmlRegisterType<QQuickWheelHandler>(uri, 2, 14, "WheelHandler");
#endif
+ qmlRegisterUncreatableType<QQuickImageBase, 14>(uri, 2, 14, "ImageBase",
+ QQuickPointerHandler::tr("ImageBase is an abstract base class"));
+ qmlRegisterType<QQuickImage, 14>(uri, 2, 14, "Image");
+ qmlRegisterType<QQuickDragHandler, 14>(uri, 2, 14, "DragHandler");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 0a0da587b4..66e09f9ed1 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -81,8 +81,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
- Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 2)
- Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 2)
+ Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 3)
+ Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 3)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index 9a9b325b1e..f2bab9e018 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -126,8 +126,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
- Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 2)
- Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 2)
+ Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 4)
+ Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4)
Q_CLASSINFO("DefaultProperty", "data")
@@ -188,8 +188,8 @@ Q_SIGNALS:
void highlightResizeVelocityChanged();
void highlightResizeDurationChanged();
void snapModeChanged();
- Q_REVISION(2) void headerPositioningChanged();
- Q_REVISION(2) void footerPositioningChanged();
+ Q_REVISION(4) void headerPositioningChanged();
+ Q_REVISION(4) void footerPositioningChanged();
protected:
void viewportMoved(Qt::Orientations orient) override;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index bce7ec718b..a8f09dc8be 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -899,7 +899,7 @@ void QQuickMouseArea::wheelEvent(QWheelEvent *event)
}
QQuickWheelEvent &we = d->quickWheelEvent;
- we.reset(event->posF().x(), event->posF().y(), event->angleDelta(), event->pixelDelta(),
+ we.reset(event->position().x(), event->position().y(), event->angleDelta(), event->pixelDelta(),
event->buttons(), event->modifiers(), event->inverted());
we.setAccepted(d->isWheelConnected());
emit wheel(&we);
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 76e5c98b35..0e01fa7915 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -71,7 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION 2)
+ Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION 5)
Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedButtonsChanged)
Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
@@ -83,7 +83,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
#if QT_CONFIG(cursor)
Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged)
#endif
- Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 1)
+ Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 4)
Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9)
public:
@@ -134,7 +134,7 @@ Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
void enabledChanged();
- Q_REVISION(2) void scrollGestureEnabledChanged();
+ Q_REVISION(5) void scrollGestureEnabledChanged();
void pressedButtonsChanged();
void acceptedButtonsChanged();
void hoverEnabledChanged();
@@ -156,7 +156,7 @@ Q_SIGNALS:
void entered();
void exited();
void canceled();
- Q_REVISION(1) void containsPressChanged();
+ Q_REVISION(4) void containsPressChanged();
Q_REVISION(9) void pressAndHoldIntervalChanged();
protected:
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index 8eff53e6dc..cf21555823 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -59,7 +59,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
{
Q_OBJECT
- Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget)
+ Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget NOTIFY targetChanged)
Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
@@ -283,7 +283,7 @@ Q_SIGNALS:
void pinchStarted(QQuickPinchEvent *pinch);
void pinchUpdated(QQuickPinchEvent *pinch);
void pinchFinished(QQuickPinchEvent *pinch);
- Q_REVISION(1) void smartZoom(QQuickPinchEvent *pinch);
+ Q_REVISION(5) void smartZoom(QQuickPinchEvent *pinch);
protected:
bool childMouseEventFilter(QQuickItem *i, QEvent *e) override;
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index e9db07d14c..10e524e4a0 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -83,8 +83,8 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
// TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
- Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 1)
- Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 1)
+ Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3)
+ Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 3)
public:
QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr);
@@ -121,8 +121,8 @@ Q_SIGNALS:
void devicePixelRatioChanged();
void primaryOrientationChanged();
void orientationChanged();
- Q_REVISION(1) void virtualXChanged();
- Q_REVISION(1) void virtualYChanged();
+ Q_REVISION(3) void virtualXChanged();
+ Q_REVISION(3) void virtualYChanged();
protected:
QPointer<QScreen> m_screen;
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index c5bddc40d2..6e2f35882b 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -74,7 +74,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
Q_PROPERTY(CullMode cullMode READ cullMode WRITE setCullMode NOTIFY cullModeChanged)
Q_PROPERTY(QString log READ log NOTIFY logChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 1)
+ Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 4)
public:
enum CullMode {
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index d5bb33902a..d612d1179f 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -87,8 +87,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
- Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1)
- Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 2)
+ Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 6)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9)
public:
enum WrapMode {
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index c46a2f8128..92f3aa62ce 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -93,7 +93,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged)
- Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION 3)
+ Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION 4)
Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
@@ -268,7 +268,7 @@ public:
#if QT_CONFIG(im)
QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
- Q_REVISION(3) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
+ Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
QRectF boundingRect() const override;
@@ -336,7 +336,7 @@ Q_SIGNALS:
void inputMaskChanged(const QString &inputMask);
void echoModeChanged(QQuickTextInput::EchoMode echoMode);
void passwordCharacterChanged();
- Q_REVISION(3) void passwordMaskDelayChanged(int delay);
+ Q_REVISION(4) void passwordMaskDelayChanged(int delay);
void displayTextChanged();
Q_REVISION(7) void preeditTextChanged();
void activeFocusOnPressChanged(bool activeFocusOnPress);
@@ -399,7 +399,7 @@ public Q_SLOTS:
void redo();
void insert(int position, const QString &text);
void remove(int start, int end);
- Q_REVISION(3) void ensureVisible(int position);
+ Q_REVISION(4) void ensureVisible(int position);
Q_REVISION(7) void clear();
private Q_SLOTS:
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 32478ba375..c4a8370f34 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -477,7 +477,7 @@ void QQuickTextNodeEngine::addTextObject(const QTextBlock &block, const QPointF
}
qreal ascent;
- QTextLine line = block.layout()->lineForTextPosition(pos);
+ QTextLine line = block.layout()->lineForTextPosition(pos - block.position());
switch (format.verticalAlignment())
{
case QTextCharFormat::AlignTop:
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index fa9b44aa22..9998dc3605 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -240,6 +240,22 @@ void QQuickView::setSource(const QUrl& url)
}
/*!
+ Sets the initial properties with which the QML component gets initialized after
+ calling \l QQuickView::setSource.
+
+
+ Note that you can only use this function to initialize toplevel properties.
+
+ \sa QQmlComponent::createWithInitialProperties
+ \since 5.14
+*/
+void QQuickView::setInitialProperties(const QVariantMap &initialProperties)
+{
+ Q_D(QQuickView);
+ d->initialProperties = initialProperties;
+}
+
+/*!
\internal
Set the source \a url, \a component and content \a item (root of the QML object hierarchy) directly.
@@ -471,7 +487,7 @@ void QQuickView::continueExecute()
return;
}
- QObject *obj = d->component->create();
+ QObject *obj = d->initialProperties.empty() ? d->component->create() : d->component->createWithInitialProperties(d->initialProperties);
if (d->component->isError()) {
const QList<QQmlError> errorList = d->component->errors();
diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h
index ecae25e90b..4122fcac79 100644
--- a/src/quick/items/qquickview.h
+++ b/src/quick/items/qquickview.h
@@ -88,6 +88,7 @@ public:
public Q_SLOTS:
void setSource(const QUrl&);
+ void setInitialProperties(const QVariantMap &initialProperties);
void setContent(const QUrl& url, QQmlComponent *component, QObject *item);
Q_SIGNALS:
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 3f284c0519..b1ab8d8e8c 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -108,6 +108,8 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
+
+ QVariantMap initialProperties;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index a208e135af..51bcdbf352 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -702,7 +702,7 @@ bool QQuickWindowPrivate::checkIfDoubleTapped(ulong newPressEventTimestamp, QPoi
if (touchMousePressTimestamp > 0) {
QPoint distanceBetweenPresses = newPressPos - touchMousePressPos;
- const int doubleTapDistance = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt();
+ const int doubleTapDistance = QGuiApplication::styleHints()->touchDoubleTapDistance();
doubleClicked = (qAbs(distanceBetweenPresses.x()) <= doubleTapDistance) && (qAbs(distanceBetweenPresses.y()) <= doubleTapDistance);
if (doubleClicked) {
@@ -4224,7 +4224,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
When not running with the RHI (and using OpenGL directly), the signal is
emitted after the renderer has cleared the render target. This makes it
- possible to create appliations that function identically both with and
+ possible to create applications that function identically both with and
without the RHI.
\note Resource updates (uploads, copies) typically cannot be enqueued from
@@ -4255,7 +4255,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
When not running with the RHI (and using OpenGL directly), the signal is
emitted after the renderer has finished its rendering, but before
- afterRendering(). This makes it possible to create appliations that
+ afterRendering(). This makes it possible to create applications that
function identically both with and without the RHI.
\note Resource updates (uploads, copies) typically cannot be enqueued from
@@ -4450,7 +4450,8 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
\note This function only has an effect when using the default OpenGL scene graph
adaptation.
- \note This function has no effect when running on the RHI graphics abstraction.
+ \note This function has no effect when running on the RHI graphics
+ abstraction. Use createTextureFromNativeObject() instead.
\sa sceneGraphInitialized(), QSGTexture
*/
@@ -4458,19 +4459,120 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
{
#if QT_CONFIG(opengl)
Q_D(const QQuickWindow);
- if (!d->rhi && openglContext()) {
- QSGPlainTexture *texture = new QSGPlainTexture();
- texture->setTextureId(id);
+ if (!d->rhi) {
+ if (openglContext()) {
+ QSGPlainTexture *texture = new QSGPlainTexture();
+ texture->setTextureId(id);
+ texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
+ texture->setOwnsTexture(options & TextureOwnsGLTexture);
+ texture->setTextureSize(size);
+ return texture;
+ }
+ } else {
+ qWarning("createTextureFromId() must not be called when running on the RHI. "
+ "Use createTextureFromNativeObject() instead.");
+ }
+#else
+ Q_UNUSED(id)
+ Q_UNUSED(size)
+ Q_UNUSED(options)
+#endif
+ return nullptr;
+}
+
+/*!
+ \enum QQuickWindow::NativeObjectType
+ \since 5.14
+
+ Specifies the type of the native object passed to functions such as
+ createTextureFromNativeObject().
+
+ \value NativeObjectTexture The native object is a 2D texture (OpenGL,
+ Direct3D 11, Metal) or image (Vulkan).
+ */
+
+/*!
+ Creates a new QSGTexture object from an existing native object.
+
+ The native object is wrapped, but not owned, by the resulting QSGTexture.
+ The caller of the function is responsible for deleting the returned
+ QSGTexture, but that will not destroy the underlying native object.
+
+ \a type specifies the type of the object. In practice the type is
+ NativeObjectTexture, indicating that the native object is a texture or
+ image of the underlying graphics API. Other types may be introduced in the
+ future.
+
+ This function is currently suitable for 2D RGBA textures only.
+
+ Unlike createTextureFromId(), this function supports both direct OpenGL
+ usage and the RHI abstracted rendering path.
+
+ \warning This function will return null if the scenegraph has not yet been
+ initialized.
+
+ Use \a options to customize the texture attributes. Only the
+ TextureHasAlphaChannel and TextureHasMipmaps are taken into account here.
+
+ \warning Unlike createTextureFromId(), this function never takes ownership
+ of the native object, and the TextureOwnsGLTexture flag is ignored.
+
+ \a size specifies the size in pixels.
+
+ \a nativeObjectPtr is a pointer to the native object handle. With OpenGL,
+ the native handle is a GLuint value, so \a nativeObjectPtr is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \a
+ nativeObjectPtr is a pointer to a VkImage. With Direct3D 11 and Metal \a
+ nativeObjectPtr is a pointer to a ID3D11Texture2D or MTLTexture pointer.
+
+ \note Pay attention to the fact that \a nativeObjectPtr is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+
+ \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
+
+ \since 5.14
+ */
+QSGTexture *QQuickWindow::createTextureFromNativeObject(NativeObjectType type,
+ const void *nativeObjectPtr,
+ int nativeLayout,
+ const QSize &size,
+ CreateTextureOptions options) const
+{
+ if (type != NativeObjectTexture) {
+ qWarning("createTextureFromNativeObject: only textures are supported");
+ return nullptr;
+ }
+
+#if QT_CONFIG(opengl) /* || QT_CONFIG(vulkan) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) */
+ Q_D(const QQuickWindow);
+ if (d->rhi) {
+ QSGPlainTexture *texture = new QSGPlainTexture;
+ texture->setTextureFromNativeObject(d->rhi, type, nativeObjectPtr, nativeLayout,
+ size, options.testFlag(TextureHasMipmaps));
+ texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
+ // note that the QRhiTexture does not (and cannot) own the native object
+ texture->setOwnsTexture(true); // texture meaning the QRhiTexture here, not the native object
+ texture->setTextureSize(size);
+ return texture;
+ } else if (openglContext()) {
+ QSGPlainTexture *texture = new QSGPlainTexture;
+ texture->setTextureId(*reinterpret_cast<const uint *>(nativeObjectPtr));
texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
texture->setOwnsTexture(options & TextureOwnsGLTexture);
texture->setTextureSize(size);
return texture;
}
#else
- Q_UNUSED(id)
- Q_UNUSED(size)
- Q_UNUSED(options)
+ Q_UNUSED(nativeObjectPtr);
+ Q_UNUSED(nativeLayout);
+ Q_UNUSED(size);
+ Q_UNUSED(options);
#endif
+
return nullptr;
}
@@ -4666,6 +4768,11 @@ const QQuickWindow::GraphicsStateInfo *QQuickWindow::graphicsStateInfo()
beginExternalCommands() and endExternalCommands() together provide a
replacement for resetOpenGLState().
+ Calling this function and endExternalCommands() is not necessary within the
+ \l{QSGRenderNode::render()}{render()} implementation of a QSGRenderNode
+ because the scene graph performs the necessary steps implicitly for render
+ nodes.
+
\note This function has no effect when the scene graph is using OpenGL
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
@@ -4704,6 +4811,11 @@ void QQuickWindow::beginExternalCommands()
beginExternalCommands() and endExternalCommands() together provide a
replacement for resetOpenGLState().
+ Calling this function and beginExternalCommands() is not necessary within the
+ \l{QSGRenderNode::render()}{render()} implementation of a QSGRenderNode
+ because the scene graph performs the necessary steps implicitly for render
+ nodes.
+
\note This function has no effect when the scene graph is using OpenGL
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index ab3046611f..9dbff88f0d 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -109,6 +109,11 @@ public:
};
Q_ENUM(TextRenderType)
+ enum NativeObjectType {
+ NativeObjectTexture
+ };
+ Q_ENUM(NativeObjectType)
+
explicit QQuickWindow(QWindow *parent = nullptr);
explicit QQuickWindow(QQuickRenderControl *renderControl);
@@ -153,6 +158,11 @@ public:
QSGTexture *createTextureFromImage(const QImage &image) const;
QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const;
QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const;
+ QSGTexture *createTextureFromNativeObject(NativeObjectType type,
+ const void *nativeObjectPtr,
+ int nativeLayout,
+ const QSize &size,
+ CreateTextureOptions options = CreateTextureOption()) const;
void setClearBeforeRendering(bool enabled);
bool clearBeforeRendering() const;
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 7b3874dbfe..4b2b8f498d 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -205,11 +205,11 @@ void QQuickWindowModule::defineModule()
qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members
qmlRegisterRevision<QQuickWindow,2>(uri, 2, 2);
qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,1>(uri, 2, 2, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 3, "Window");
+ qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 2, "Window");
+ qmlRegisterType<QQuickWindowQmlImpl,3>(uri, 2, 3, "Window");
qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreen,1>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,2>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
+ qmlRegisterUncreatableType<QQuickScreen,3>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
+ qmlRegisterUncreatableType<QQuickScreenInfo,3>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
qmlRegisterRevision<QWindow,13>(uri, 2, 13);
qmlRegisterRevision<QQuickWindow,13>(uri, 2, 13);
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index e7033e9b8d..1dcf1a1021 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
- Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 2)
+ Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 3)
public:
QQuickWindowQmlImpl(QWindow *parent = nullptr);
@@ -83,7 +83,7 @@ public:
Q_SIGNALS:
void visibleChanged(bool arg);
void visibilityChanged(QWindow::Visibility visibility);
- Q_REVISION(2) void screenChanged();
+ Q_REVISION(3) void screenChanged();
protected:
void classBegin() override;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index f8973af2fb..2d4dcd928d 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -69,10 +69,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// Passed from the RL to RT when GUI has been locked, waiting for sync.
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is typically
-// a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to maybe release resource if no windows are
// rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -353,13 +349,6 @@ bool QSGSoftwareRenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we
- // must not exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 2cd9ee689b..a566a2bed6 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2665,7 +2665,8 @@ void Renderer::updateClipState(const QSGClipNode *clipList, Batch *batch) // RHI
{
// Note: No use of the clip-related speparate m_current* vars is allowed
// here. All stored in batch->clipState instead. To collect state during
- // renderBatches(), m_currentClipState is used.
+ // the prepare steps, m_currentClipState is used. It should not be used in
+ // the render steps afterwards.
// The stenciling logic is slightly different from the legacy GL path as we
// cannot just randomly clear the stencil buffer. We now put all clip
@@ -3491,7 +3492,7 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms,
}
if (pd->textureBindingTable[binding] && pd->samplerBindingTable[binding]) {
- QRhiTexture *texture = pd->textureBindingTable[binding]->rhiTexture();
+ QRhiTexture *texture = QSGTexturePrivate::get(pd->textureBindingTable[binding])->rhiTexture();
// texture may be null if the update above failed for any reason,
// or if the QSGTexture chose to return null intentionally. This is
// valid and we still need to provide something to the shader.
@@ -4089,7 +4090,7 @@ void Renderer::renderBatches()
if (b->merged)
ok = prepareRenderMergedBatch(b, &renderBatch);
else if (b->isRenderNode)
- ok = false; // ###
+ ok = prepareRhiRenderNode(b, &renderBatch);
else
ok = prepareRenderUnmergedBatch(b, &renderBatch);
if (ok)
@@ -4120,7 +4121,7 @@ void Renderer::renderBatches()
if (renderBatch->batch->merged)
renderMergedBatch(renderBatch);
else if (renderBatch->batch->isRenderNode)
- Q_UNREACHABLE(); // ###
+ renderRhiRenderNode(renderBatch->batch);
else
renderUnmergedBatch(renderBatch);
}
@@ -4359,7 +4360,7 @@ struct RenderNodeState : public QSGRenderNode::RenderState
bool m_stencilEnabled;
};
-void Renderer::renderRenderNode(Batch *batch)
+void Renderer::renderRenderNode(Batch *batch) // legacy (GL-only)
{
if (Q_UNLIKELY(debug_render()))
qDebug() << " -" << batch << "rendernode";
@@ -4475,6 +4476,108 @@ void Renderer::renderRenderNode(Batch *batch)
glBindFramebuffer(GL_FRAMEBUFFER, prevFbo);
}
+bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch) // split prepare-render (RHI only)
+{
+ if (Q_UNLIKELY(debug_render()))
+ qDebug() << " -" << batch << "rendernode";
+
+ Q_ASSERT(batch->first->isRenderNode);
+ RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first);
+
+ setActiveRhiShader(nullptr, nullptr);
+
+ QSGNode *clip = e->renderNode->parent();
+ QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode);
+ rd->m_clip_list = nullptr;
+ while (clip != rootNode()) {
+ if (clip->type() == QSGNode::ClipNodeType) {
+ rd->m_clip_list = static_cast<QSGClipNode *>(clip);
+ break;
+ }
+ clip = clip->parent();
+ }
+
+ updateClipState(rd->m_clip_list, batch);
+
+ renderBatch->batch = batch;
+ renderBatch->sms = nullptr;
+
+ return true;
+}
+
+void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render (RHI only)
+{
+ if (batch->clipState.type & ClipState::StencilClip)
+ enqueueStencilDraw(batch);
+
+ RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first);
+ QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(e->renderNode);
+
+ QMatrix4x4 pm = projectionMatrix();
+ if (m_useDepthBuffer) {
+ pm(2, 2) = m_zRange;
+ pm(2, 3) = 1.0f - e->order * m_zRange;
+ }
+
+ RenderNodeState state;
+ state.m_projectionMatrix = &pm;
+ const std::array<int, 4> scissor = batch->clipState.scissor.scissor();
+ state.m_scissorRect = QRect(scissor[0], scissor[1], scissor[2], scissor[3]);
+ state.m_stencilValue = batch->clipState.stencilRef;
+ state.m_scissorEnabled = batch->clipState.type & ClipState::ScissorClip;
+ state.m_stencilEnabled = batch->clipState.type & ClipState::StencilClip;
+
+ QSGNode *xform = e->renderNode->parent();
+ QMatrix4x4 matrix;
+ QSGNode *root = rootNode();
+ if (e->root) {
+ matrix = qsg_matrixForRoot(e->root);
+ root = e->root->sgNode;
+ }
+ while (xform != root) {
+ if (xform->type() == QSGNode::TransformNodeType) {
+ matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
+ break;
+ }
+ xform = xform->parent();
+ }
+ rd->m_matrix = &matrix;
+
+ QSGNode *opacity = e->renderNode->parent();
+ rd->m_opacity = 1.0;
+ while (opacity != rootNode()) {
+ if (opacity->type() == QSGNode::OpacityNodeType) {
+ rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
+ break;
+ }
+ opacity = opacity->parent();
+ }
+
+ const QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
+
+ QRhiCommandBuffer *cb = commandBuffer();
+ cb->beginExternal();
+ e->renderNode->render(&state);
+ cb->endExternal();
+
+ rd->m_matrix = nullptr;
+ rd->m_clip_list = nullptr;
+
+ if ((changes & QSGRenderNode::ViewportState)
+ || (changes & QSGRenderNode::ScissorState))
+ {
+ // Reset both flags if either is reported as changed, since with the rhi
+ // it could be setViewport() that will record the resetting of the scissor.
+ m_pstate.viewportSet = false;
+ m_pstate.scissorSet = false;
+ }
+
+ // Do not bother with RenderTargetState. Where applicable, endExternal()
+ // ensures the correct target is rebound. For others (like Vulkan) it makes
+ // no sense since render() could not possibly do that on our command buffer
+ // which is in renderpass recording state.
+}
+
void Renderer::setCustomRenderMode(const QByteArray &mode)
{
if (mode.isEmpty())
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index ea9dab244f..4e374522d4 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -817,6 +817,8 @@ private:
void enqueueStencilDraw(const Batch *batch);
const QMatrix4x4 &matrixForRoot(Node *node);
void renderRenderNode(Batch *batch);
+ bool prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch);
+ void renderRhiRenderNode(const Batch *batch);
void setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
void setActiveRhiShader(QSGMaterialRhiShader *program, ShaderManager::Shader *shader);
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index df3fa16a32..2892f2f966 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -81,8 +81,10 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
}
/*!
- This function should return a mask where each bit represents graphics states changed by
- the \l render() function:
+ When the underlying rendering API is OpenGL, this function should return a
+ mask where each bit represents graphics states changed by the \l render()
+ function:
+
\list
\li DepthState - depth write mask, depth test enabled, depth comparison function
\li StencilState - stencil write masks, stencil test enabled, stencil operations,
@@ -95,6 +97,29 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
\li RenderTargetState - render target
\endlist
+ 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,
+ 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
+ state objects do not need to be reported here. Similarly, draw call related
+ settings (pipeline states, descriptor sets, vertex or index buffer
+ bindings, root signature, descriptor heaps, etc.) are always set again by
+ the scenegraph so render() can freely change them.
+
+ \note RenderTargetState is no longer supported with APIs like Vulkan. This
+ is by nature. render() is invoked while the Qt Quick scenegraph's main
+ command buffer is recording a renderpass, so there is no possibility of
+ changing the target and starting another renderpass (on that command buffer
+ at least). Therefore returning a value with RenderTargetState set is not
+ sensible.
+
+ The software backend exposes its QPainter and saves and restores before and
+ after invoking render(). Therefore reporting any changed states from here
+ is not necessary.
+
The function is called by the renderer so it can reset the states after
rendering this node. This makes the implementation of render() simpler
since it does not have to query and restore these states.
@@ -102,19 +127,6 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
The default implementation returns 0, meaning no relevant state was changed
in render().
- With APIs other than OpenGL the relevant states are only those that are set
- via the command list (for example, OMSetRenderTargets, RSSetViewports,
- RSSetScissorRects, OMSetBlendFactor, OMSetStencilRef in case of D3D12), and
- only when such commands were added to the scenegraph's command list queried
- via the QSGRendererInterface::CommandList resource enum. States set in
- pipeline state objects do not need to be reported here. Similarly, draw
- call related settings (root signature, descriptor heaps, etc.) are always
- set again by the scenegraph so render() can freely change them.
-
- The software backend exposes its QPainter and saves and restores before and
- after invoking render(). Therefore reporting any changed states from here
- is not necessary.
-
\note This function may be called before render().
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
@@ -149,18 +161,31 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
QQuickFramebufferObject, QQuickWindow::beforeRendering(), or the
equivalents of those for APIs other than OpenGL.
- Clip information is calculated before the function is called, it is however
- not enabled. Implementations wishing to take clipping into account can set
- up scissoring or stencil based on the information in \a state. Some
- scenegraph backends, software in particular, use no scissor or stencil.
- There the clip region is provided as an ordinary QRegion.
+ \note QSGRenderNode can perform significantly better than texture-based
+ approaches (such as, QQuickFramebufferObject), especially on systems where
+ the fragment processing power is limited. This is because it avoids
+ rendering to a texture and then drawing a textured quad. Rather,
+ QSGRenderNode allows recording draw calls in line with the scenegraph's
+ other commands, avoiding an additional render target and the potentially
+ expensive texturing and blending.
+
+ Clip information is calculated before the function is called.
+ Implementations wishing to take clipping into account can set up scissoring
+ or stencil based on the information in \a state. The stencil buffer is
+ filled with the necessary clip shapes, but it is up to the implementation
+ to enable stencil testing.
+
+ Some scenegraph backends, software in particular, use no scissor or
+ stencil. There the clip region is provided as an ordinary QRegion.
+
+ With the legacy, direct OpenGL based renderer, the following states are set
+ on the render thread's context before this function is called:
- For OpenGL the following states are set on the render thread's context
- before this function is called:
\list
+ \li glColorMask(true, true, true, true)
\li glDepthMask(false)
\li glDisable(GL_DEPTH_TEST)
- \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
+ \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) depending on clip
\li glScissor(state.scissorRect.x(), state.scissorRect.y(),
state.scissorRect.width(), state.scissorRect.height()) depending on clip
\li glEnable(GL_BLEND)
@@ -168,23 +193,42 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
\li glDisable(GL_CULL_FACE)
\endlist
- States that are not listed above, but are included in \l StateFlags, can
+ States that are not listed above, but are covered by \l StateFlags, can
have arbitrary values.
+ \note There is no state set with other graphics APIs, considering that many
+ of them do not have a concept of the traditional OpenGL state machine.
+ Rather, it is up to the implementation to create pipeline state objects
+ with the desired blending, scissor, and stencil tests enabled. Note that
+ this also includes OpenGL via the RHI. New QSGRenderNode implementations
+ are recommended to set all scissor, stencil and blend state explicitly (as
+ shown in the above list), even if they are targeting OpenGL.
+
\l changedStates() should return which states this function changes. If a
state is not covered by \l StateFlags, the state should be set to the
default value according to the OpenGL specification. For other APIs, see
the documentation for changedStates() for more information.
- \note Depth writes are disabled when this function is called (for example,
- glDepthMask(false) in case of OpenGL). Enabling depth writes can lead to
- unexpected results, depending on the scenegraph backend in use, so nodes
- should avoid this.
+ \note Depth writes are disabled when this function is called
+ (glDepthMask(false) with OpenGL). Enabling depth writes can lead to
+ unexpected results, depending on the scenegraph backend in use and the
+ content in the scene, so exercise caution with this.
For APIs other than OpenGL, it will likely be necessary to query certain
API-specific resources (for example, the graphics device or the command
list/buffer to add the commands to). This is done via QSGRendererInterface.
+ Assume nothing about the pipelines and dynamic states bound on the command
+ list/buffer when this function is called.
+
+ With some graphics APIs it can be necessary to also connect to the
+ QQuickWindow::beforeRendering() signal, because that is emitted before
+ recording the beginning of a renderpass on the command buffer
+ (vkCmdBeginRenderPass with Vulkan, or starting to encode via
+ MTLRenderCommandEncoder in case of Metal). Recording copy operations cannot
+ be done inside render() with such APIs. Rather, do it in the slot connected
+ (with DirectConnection) to the beforeRendering signal.
+
\sa QSGRendererInterface, QQuickWindow::rendererInterface()
*/
@@ -335,7 +379,8 @@ QSGRenderNode::RenderState::~RenderState()
/*!
\fn const QMatrix4x4 *QSGRenderNode::RenderState::scissorRect() const
- \return the current scissor rectangle when clipping is active.
+ \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,
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index cfd0cb9f06..c47401e5c0 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -696,27 +696,6 @@ void QSGTexture::updateBindOptions(bool force) // legacy (GL-only)
}
/*!
- \return the QRhiTexture for this QSGTexture or null if there is none.
-
- Unlike textureId(), this function is not expected to create a new
- QRhiTexture in case there is none. Just return null in that case. The
- expectation towards the renderer is that a null texture leads to using a
- transparent, dummy texture instead.
-
- \note This function is only used when running the graphics API independent
- rendering path of the scene graph.
-
- \warning This function can only be called from the rendering thread.
-
- \since 5.14
- */
-QRhiTexture *QSGTexture::rhiTexture() const
-{
- Q_D(const QSGTexture);
- return d->rhiTexture();
-}
-
-/*!
Call this function to enqueue image upload operations to \a
resourceUpdates, in case there are any pending ones. When there is no new
data (for example, because there was no setImage() since the last call to
@@ -762,6 +741,23 @@ int QSGTexturePrivate::comparisonKey() const
return q->textureId(); // this is semantically wrong but at least compatible with existing, non-RHI-aware subclasses
}
+/*!
+ \internal
+
+ \return the QRhiTexture for this QSGTexture or null if there is none.
+
+ Unlike textureId(), this function is not expected to create a new
+ QRhiTexture in case there is none. Just return null in that case. The
+ expectation towards the renderer is that a null texture leads to using a
+ transparent, dummy texture instead.
+
+ \note This function is only used when running the graphics API independent
+ rendering path of the scene graph.
+
+ \warning This function can only be called from the rendering thread.
+
+ \since 5.14
+ */
QRhiTexture *QSGTexturePrivate::rhiTexture() const
{
return nullptr;
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h
index f2b0e902f3..4cd2a5cddd 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture.h
@@ -113,7 +113,6 @@ public:
// ### Qt 6: make these virtual
int comparisonKey() const;
- QRhiTexture *rhiTexture() const;
void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates);
// ### Qt 6: make this an argument for removedFromAtlas()
diff --git a/src/quick/scenegraph/coreapi/qsgtexture_p.h b/src/quick/scenegraph/coreapi/qsgtexture_p.h
index 1d248b0305..cb59d32012 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture_p.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture_p.h
@@ -83,9 +83,10 @@ public:
void resetDirtySamplerOptions();
bool hasDirtySamplerOptions() const;
+ virtual QRhiTexture *rhiTexture() const;
+
// ### Qt 6: these should be virtuals in the public class instead
virtual int comparisonKey() const; // ### Qt 6: pure virtual
- virtual QRhiTexture *rhiTexture() const;
virtual void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates);
QRhiResourceUpdateBatch *workResourceUpdateBatch = nullptr; // ### Qt 6: remove
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index db889c3102..8fc8c711c6 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -451,7 +451,9 @@ bool QSGTextMaskRhiShader::updateUniformData(const RenderState &state,
changed = true;
}
- if (updated || !oldMat || oldMat->texture()->rhiTexture() != mat->texture()->rhiTexture()) {
+ QRhiTexture *oldRtex = oldMat ? QSGTexturePrivate::get(oldMat->texture())->rhiTexture() : nullptr;
+ QRhiTexture *newRtex = QSGTexturePrivate::get(mat->texture())->rhiTexture();
+ if (updated || !oldMat || oldRtex != newRtex) {
const QVector2D textureScale = QVector2D(1.0f / mat->rhiGlyphCache()->width(),
1.0f / mat->rhiGlyphCache()->height());
memcpy(buf->data() + 64 + 16, &textureScale, 8);
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index ec835fe3bd..08d1c726ab 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -214,9 +214,7 @@ QSGRenderLoop *QSGRenderLoop::instance()
{
if (!s_instance) {
- // For compatibility with 5.3 and earlier's QSG_INFO environment variables
- if (qEnvironmentVariableIsSet("QSG_INFO"))
- const_cast<QLoggingCategory &>(QSG_LOG_INFO()).setEnabled(QtDebugMsg, true);
+ QSGRhiSupport::checkEnvQSgInfo();
s_instance = QSGContext::createWindowManager();
#ifdef ENABLE_DEFAULT_BACKEND
@@ -244,25 +242,28 @@ QSGRenderLoop *QSGRenderLoop::instance()
}
if (rhiSupport->isRhiEnabled()) {
- // no 'windows' because that's not yet ported to the rhi
- if (loopType == WindowsRenderLoop)
- loopType = BasicRenderLoop;
-
switch (rhiSupport->rhiBackend()) {
- case QRhi::D3D11:
- // D3D11 is forced to 'basic' always for now. The threaded loop's model may
- // not be suitable for DXGI due to the possibility of having the main
- // thread blocked while issuing a Present. To be investigated.
+ case QRhi::Null:
loopType = BasicRenderLoop;
break;
- case QRhi::Null:
- loopType = BasicRenderLoop;
+ case QRhi::D3D11:
+ // The threaded loop's model may not be suitable for DXGI
+ // due to the possibility of having the main thread (with
+ // the Windows message pump) blocked while issuing a
+ // Present on the render thread. However, according to the
+ // docs this can be a problem for fullscreen swapchains
+ // only. So leave threaded enabled by default for now and
+ // revisit later if there are problems.
break;
default:
break;
}
+
+ // no 'windows' because that's not yet ported to the rhi
+ if (loopType == WindowsRenderLoop)
+ loopType = BasicRenderLoop;
}
// The environment variables can always override. This is good
@@ -383,20 +384,23 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
bool current = false;
- if (gl) {
- QSurface *surface = window;
- // There may be no platform window if the window got closed.
- if (!window->handle())
- surface = offscreenSurface;
+ if (gl || rhi) {
if (rhi) {
+ // Direct OpenGL calls in user code need a current context, like
+ // when rendering; ensure this (no-op when not running on GL).
+ // Also works when there is no handle() anymore.
rhi->makeThreadLocalNativeContextCurrent();
current = true;
} else {
+ QSurface *surface = window;
+ // There may be no platform window if the window got closed.
+ if (!window->handle())
+ surface = offscreenSurface;
current = gl->makeCurrent(surface);
}
+ if (Q_UNLIKELY(!current))
+ qCDebug(QSG_LOG_RENDERLOOP, "cleanup without an OpenGL context");
}
- if (Q_UNLIKELY(!current))
- qCDebug(QSG_LOG_RENDERLOOP, "cleanup without an OpenGL context");
#if QT_CONFIG(quick_shadereffect)
QSGRhiShaderEffectNode::cleanupMaterialTypeCache();
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index 8bae24dc76..a92b6b0c84 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -109,6 +109,12 @@ void QSGRhiSupport::applySettings()
{
m_set = true;
+ // This is also done when creating the renderloop but we may be before that
+ // in case we get here due to a setScenegraphBackend() -> configure() early
+ // on in main(). Avoid losing info logs since troubleshooting gets
+ // confusing otherwise.
+ QSGRhiSupport::checkEnvQSgInfo();
+
if (m_requested.valid) {
// explicit rhi backend request from C++ (e.g. via QQuickWindow)
m_enableRhi = m_requested.rhi;
@@ -203,6 +209,13 @@ QSGRhiSupport *QSGRhiSupport::staticInst()
return &inst;
}
+void QSGRhiSupport::checkEnvQSgInfo()
+{
+ // For compatibility with 5.3 and earlier's QSG_INFO environment variables
+ if (qEnvironmentVariableIsSet("QSG_INFO"))
+ const_cast<QLoggingCategory &>(QSG_LOG_INFO()).setEnabled(QtDebugMsg, true);
+}
+
void QSGRhiSupport::configure(QSGRendererInterface::GraphicsApi api)
{
Q_ASSERT(QSGRendererInterface::isApiRhiBased(api));
diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h
index 48ad2f05ae..f2d5837bba 100644
--- a/src/quick/scenegraph/qsgrhisupport_p.h
+++ b/src/quick/scenegraph/qsgrhisupport_p.h
@@ -86,6 +86,7 @@ QT_BEGIN_NAMESPACE
class QSGDefaultRenderContext;
class QVulkanInstance;
+class QOffscreenSurface;
// Opting in/out of QRhi and choosing the default/requested backend is managed
// by this singleton. This is because this information may be needed before
@@ -125,6 +126,8 @@ public:
QImage grabAndBlockInCurrentFrame(QRhi *rhi, QRhiSwapChain *swapchain);
+ static void checkEnvQSgInfo();
+
private:
QSGRhiSupport();
void applySettings();
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index d1258cf903..9e34a2b201 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -147,10 +147,6 @@ const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);
// (updatePaintNode())
const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);
-// Passed by the RT to itself to trigger another render pass. This is
-// typically a result of QQuickWindow::update().
-const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);
-
// Passed by the RL to the RT to free up maybe release SG and GL contexts
// if no windows are rendering.
const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
@@ -510,13 +506,6 @@ bool QSGRenderThread::event(QEvent *e)
return true;
}
- case WM_RequestRepaint:
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestPaint");
- // When GUI posts this event, it is followed by a polishAndSync, so we mustn't
- // exit the event loop yet.
- pendingUpdate |= RepaintRequest;
- break;
-
default:
break;
}
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index ee9ea0f5ed..c345f3b16d 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -53,6 +53,7 @@ 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 \
@@ -69,6 +70,7 @@ 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_ng/visualization.vert b/src/quick/scenegraph/shaders_ng/visualization.vert
index c29492417a..e2447948c2 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.vert
+++ b/src/quick/scenegraph/shaders_ng/visualization.vert
@@ -11,7 +11,7 @@ layout(std140, binding = 0) uniform buf {
int projection;
} ubuf;
-out gl_PerVertex { vec4 gl_Position; };
+out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };
void main()
{
@@ -25,4 +25,6 @@ void main()
}
pos = v.xy * 1.37;
+
+ gl_PointSize = 1.0;
}
diff --git a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
index bd89847dd3..7ba27cb4b5 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/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
index a850f72053..1154c06d7c 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
@@ -183,7 +183,9 @@ void QSGDefaultDepthStencilBuffer::free()
QSGDepthStencilBufferManager::~QSGDepthStencilBufferManager()
{
for (Hash::const_iterator it = m_buffers.constBegin(), cend = m_buffers.constEnd(); it != cend; ++it) {
- QSGDepthStencilBuffer *buffer = it.value().toStrongRef().data();
+ QSharedPointer<QSGDepthStencilBuffer> buffer = it.value().toStrongRef();
+ Q_ASSERT_X(buffer, "~QSGDepthStencilBufferManager",
+ "~QSGDepthStencilBuffer is supposed to unregister from the manager");
buffer->free();
buffer->m_manager = nullptr;
}
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
index c05005c467..4880d98871 100644
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ b/src/quick/scenegraph/util/qsgengine.cpp
@@ -69,6 +69,10 @@ QT_BEGIN_NAMESPACE
Most of the time you will instead want to subclass QQuickItem and insert
your QSGNode in a normal QtQuick scene by overriding QQuickItem::updatePaintNode().
+ \warning This class is only suitable when working directly with OpenGL. It
+ is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
+ path}.
+
\sa QSGAbstractRenderer
*/
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index e48b7784ae..c5a59b47e7 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -54,6 +54,8 @@ class QSGRectangleNode;
class QSGImageNode;
class QSGNinePatchNode;
+// ### Qt 6: Remove or redesign.
+
class Q_QUICK_EXPORT QSGEngine : public QObject
{
Q_OBJECT
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index 4c2b452b45..fdebe03494 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qsgplaintexture_p.h"
+#include "qsgrhinativetextureimporter_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <qmath.h>
#include <private/qquickprofiler_p.h>
@@ -274,6 +275,24 @@ void QSGPlainTexture::setTexture(QRhiTexture *texture) // RHI only
m_mipmaps_generated = false;
}
+void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type,
+ const void *nativeObjectPtr, int nativeLayout,
+ const QSize &size, bool mipmap)
+{
+ Q_UNUSED(type);
+
+ QRhiTexture::Flags flags = 0;
+ 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);
+
+ setTexture(t);
+}
+
int QSGPlainTexturePrivate::comparisonKey() const
{
Q_Q(const QSGPlainTexture);
@@ -378,6 +397,19 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
q->m_texture_size = tmp.size();
}
+ if ((q->mipmapFiltering() != QSGTexture::None
+ || q->horizontalWrapMode() != QSGTexture::ClampToEdge
+ || q->verticalWrapMode() != QSGTexture::ClampToEdge)
+ && !rhi->isFeatureSupported(QRhi::NPOTTextureRepeat))
+ {
+ const int w = qNextPowerOfTwo(tmp.width() - 1);
+ const int h = qNextPowerOfTwo(tmp.height() - 1);
+ if (tmp.width() != w || tmp.height() != h) {
+ tmp = tmp.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ q->m_texture_size = tmp.size();
+ }
+ }
+
bool needsRebuild = q->m_texture && q->m_texture->pixelSize() != q->m_texture_size;
if (mipmappingChanged) {
diff --git a/src/quick/scenegraph/util/qsgplaintexture_p.h b/src/quick/scenegraph/util/qsgplaintexture_p.h
index 69c0153f9a..1eb0b59d2e 100644
--- a/src/quick/scenegraph/util/qsgplaintexture_p.h
+++ b/src/quick/scenegraph/util/qsgplaintexture_p.h
@@ -53,6 +53,7 @@
#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/private/qsgtexture_p.h>
+#include <QtQuick/qquickwindow.h>
QT_BEGIN_NAMESPACE
@@ -85,6 +86,9 @@ public:
void bind() override;
void setTexture(QRhiTexture *texture);
+ void setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type,
+ const void *nativeObjectPtr, int nativeLayout,
+ const QSize &size, bool mipmap);
static QSGPlainTexture *fromImage(const QImage &image) {
QSGPlainTexture *t = new QSGPlainTexture();
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
new file mode 100644
index 0000000000..7a7c19f587
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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
new file mode 100644
index 0000000000..e811109a94
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index a154ae269a..df4e5cfde2 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -164,6 +164,7 @@ void QSGOpaqueTextureMaterialRhiShader::updateSampledImage(const RenderState &st
if (isNpot) {
t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
t->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ t->setMipmapFiltering(QSGTexture::None);
}
}
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index d246ee7910..61319c388c 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -2397,32 +2397,42 @@ void QQuickPathPercent::setValue(qreal value)
\qmlproperty list<point> QtQuick::PathPolyline::path
This property defines the vertices of the polyline.
+
+ It can be a JS array of points constructed with \c Qt.point(),
+ a QList or QVector of QPointF, or QPolygonF.
+ If you are binding this to a custom property in some C++ object,
+ QPolygonF is the most appropriate type to use.
*/
QQuickPathPolyline::QQuickPathPolyline(QObject *parent) : QQuickCurve(parent)
{
}
-QVariantList QQuickPathPolyline::path() const
+QVariant QQuickPathPolyline::path() const
{
- QVariantList res;
- for (int i = 0; i < m_path.length(); ++i) {
- const QPointF &c = m_path.at(i);
- res.append(QVariant::fromValue(c));
- }
-
- return res;
+ return QVariant::fromValue(m_path);
}
-void QQuickPathPolyline::setPath(const QVariantList &path)
+void QQuickPathPolyline::setPath(const QVariant &path)
{
- QVector<QPointF> pathList;
- for (int i = 0; i < path.length(); ++i) {
- const QPointF c = path.at(i).toPointF();
- pathList.append(c);
+ if (path.type() == QVariant::PolygonF) {
+ setPath(path.value<QPolygonF>());
+ } else if (path.canConvert<QVector<QPointF>>()) {
+ setPath(path.value<QVector<QPointF>>());
+ } else if (path.canConvert<QVariantList>()) {
+ // This handles cases other than QPolygonF or QVector<QPointF>, such as
+ // QList<QPointF>, QVector<QPoint>, QVariantList of QPointF, QVariantList of QPoint.
+ QVector<QPointF> pathList;
+ QVariantList vl = path.value<QVariantList>();
+ // If path is a QJSValue, e.g. coming from a JS array of Qt.point() in QML,
+ // then path.value<QVariantList>() is inefficient.
+ // TODO We should be able to iterate over path.value<QSequentialIterable>() eventually
+ for (const QVariant &v : vl)
+ pathList.append(v.toPointF());
+ setPath(pathList);
+ } else {
+ qWarning() << "PathPolyline: path of type" << path.type() << "not supported";
}
-
- setPath(pathList);
}
void QQuickPathPolyline::setPath(const QVector<QPointF> &path)
@@ -2522,48 +2532,60 @@ void QQuickPathPolyline::addToPath(QPainterPath &path, const QQuickPathData &/*d
\qmlproperty list<list<point>> QtQuick::PathMultiline::paths
This property defines the vertices of the polylines.
+
+ It can be a JS array of JS arrays of points constructed with \c Qt.point(),
+ a QList or QVector of QPolygonF, or QVector<QVector<QPointF>>.
+ If you are binding this to a custom property in some C++ object,
+ QVector<QPolygonF> or QVector<QVector<QPointF>> is the most
+ appropriate type to use.
*/
QQuickPathMultiline::QQuickPathMultiline(QObject *parent) : QQuickCurve(parent)
{
}
-QVariantList QQuickPathMultiline::paths() const
-{
- QVariantList res;
- for (int j = 0; j < m_paths.length(); ++j) {
- const QVector<QPointF> &path = m_paths.at(j);
- QVariantList p;
- for (int i = 0; i < path.length(); ++i) {
- const QPointF &c = path.at(i);
- p.append(QVariant::fromValue(c));
- }
- res.append(p);
- }
- return res;
-}
-
-void QQuickPathMultiline::setPaths(const QVariantList &paths)
-{
- QVector<QVector<QPointF>> pathsList;
- for (int j = 0; j < paths.length(); ++j) {
- if (paths.at(j).type() != QVariant::List)
- qWarning() << "QQuickPathMultiLine::setPaths: elements in argument not of type List";
- QVariantList path = paths.at(j).toList();
- QVector<QPointF> l;
- for (int i = 0; i < path.length(); ++i) {
- const QVariant &element = path.at(i);
- const QVariant::Type elementType = element.type();
- if (elementType == QVariant::PointF || elementType == QVariant::Point) {
- const QPointF c = element.toPointF();
- l.append(c);
+QVariant QQuickPathMultiline::paths() const
+{
+ return QVariant::fromValue(m_paths);
+}
+
+void QQuickPathMultiline::setPaths(const QVariant &paths)
+{
+ if (paths.canConvert<QVector<QPolygonF>>()) {
+ const QVector<QPolygonF> pathPolygons = paths.value<QVector<QPolygonF>>();
+ QVector<QVector<QPointF>> pathVectors;
+ for (const QPolygonF &p : pathPolygons)
+ pathVectors << p;
+ setPaths(pathVectors);
+ } else if (paths.canConvert<QVector<QVector<QPointF>>>()) {
+ setPaths(paths.value<QVector<QVector<QPointF>>>());
+ } else if (paths.canConvert<QVariantList>()) {
+ // This handles cases other than QVector<QPolygonF> or QVector<QVector<QPointF>>, such as
+ // QList<QVector<QPointF>>, QList<QList<QPointF>>, QVariantList of QVector<QPointF>,
+ // QVariantList of QVariantList of QPointF, QVector<QList<QPoint>> etc.
+ QVector<QVector<QPointF>> pathsList;
+ QVariantList vll = paths.value<QVariantList>();
+ for (const QVariant &v : vll) {
+ // If we bind a QVector<QPolygonF> property directly, rather than via QVariant,
+ // it will come through as QJSValue that can be converted to QVariantList of QPolygonF.
+ if (v.canConvert<QPolygonF>()) {
+ pathsList.append(v.value<QPolygonF>());
+ } else {
+ QVariantList vl = v.value<QVariantList>();
+ QVector<QPointF> l;
+ for (const QVariant &point : vl) {
+ if (point.canConvert<QPointF>())
+ l.append(point.toPointF());
+ }
+ if (l.size() >= 2)
+ pathsList.append(l);
}
}
- if (l.size() >= 2)
- pathsList.append(l);
+ setPaths(pathsList);
+ } else {
+ qWarning() << "PathMultiline: paths of type" << paths.type() << "not supported";
+ setPaths(QVector<QVector<QPointF>>());
}
-
- setPaths(pathsList);
}
void QQuickPathMultiline::setPaths(const QVector<QVector<QPointF>> &paths)
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index aa3425ff6c..5987ae8f35 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -290,7 +290,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve
Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
- Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 2)
+ Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9)
public:
QQuickPathArc(QObject *parent=nullptr)
@@ -321,7 +321,7 @@ Q_SIGNALS:
void radiusYChanged();
void useLargeArcChanged();
void directionChanged();
- Q_REVISION(2) void xAxisRotationChanged();
+ Q_REVISION(9) void xAxisRotationChanged();
private:
qreal _radiusX = 0;
@@ -428,12 +428,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve
{
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
- Q_PROPERTY(QVariantList path READ path WRITE setPath NOTIFY pathChanged)
+ Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged)
public:
QQuickPathPolyline(QObject *parent=nullptr);
- QVariantList path() const;
- void setPath(const QVariantList &path);
+ QVariant path() const;
+ void setPath(const QVariant &path);
void setPath(const QVector<QPointF> &path);
QPointF start() const;
void addToPath(QPainterPath &path, const QQuickPathData &data) override;
@@ -450,12 +450,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve
{
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
- Q_PROPERTY(QVariantList paths READ paths WRITE setPaths NOTIFY pathsChanged)
+ Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged)
public:
QQuickPathMultiline(QObject *parent=nullptr);
- QVariantList paths() const;
- void setPaths(const QVariantList &paths);
+ QVariant paths() const;
+ void setPaths(const QVariant &paths);
void setPaths(const QVector<QVector<QPointF>> &paths);
QPointF start() const;
void addToPath(QPainterPath &path, const QQuickPathData &) override;
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 78a4e5b998..56ad8ebf0b 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -241,7 +241,7 @@ class QQuickPixmapData
{
public:
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QQuickImageProviderOptions &po, const QString &e)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error),
+ : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Error),
url(u), errorString(e), requestSize(s),
providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr),
@@ -250,8 +250,8 @@ public:
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading),
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Loading),
url(u), requestSize(r),
providerOptions(po), appliedTransform(aTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr),
@@ -261,8 +261,8 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
- const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
+ const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Ready),
url(u), implicitSize(s), requestSize(r),
providerOptions(po), appliedTransform(aTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
@@ -272,7 +272,7 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
+ : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Ready),
appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -299,6 +299,8 @@ public:
void removeFromCache();
uint refCount;
+ int frameCount;
+ int frame;
bool inCache:1;
@@ -396,9 +398,9 @@ static void maybeRemoveAlpha(QImage *image)
}
}
-static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
+static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount,
const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
- QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr)
+ QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0)
{
QImageReader imgio(dev);
if (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform)
@@ -406,6 +408,12 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
else if (appliedTransform)
*appliedTransform = imgio.autoTransform() ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform;
+ if (frame < imgio.imageCount())
+ imgio.jumpToImage(frame);
+
+ if (frameCount)
+ *frameCount = imgio.imageCount();
+
QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions);
if (scSize.isValid())
imgio.setScaledSize(scSize);
@@ -558,9 +566,12 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QByteArray all = reply->readAll();
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize, job->providerOptions))
+ int frameCount;
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, job->data->frame))
error = QQuickPixmapReply::Decoding;
- }
+ else
+ job->data->frameCount = frameCount;
+ }
// send completion event to the QQuickPixmapReply
mutex.lock();
if (!cancelled.contains(job))
@@ -870,10 +881,13 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
mutex.unlock();
return;
} else {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) {
+ int frameCount;
+ if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, runningJob->data->frame)) {
errorCode = QQuickPixmapReply::Loading;
if (f.fileName() != localFile)
errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ } else if (runningJob->data) {
+ runningJob->data->frameCount = frameCount;
}
}
} else {
@@ -982,17 +996,18 @@ class QQuickPixmapKey
public:
const QUrl *url;
const QSize *size;
+ int frame;
QQuickImageProviderOptions options;
};
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options;
+ return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options && lhs.frame == rhs.frame;
}
inline uint qHash(const QQuickPixmapKey &key)
{
- return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^ (key.options.autoTransform() * 0x5c5c5c5c);
}
class QQuickPixmapStore : public QObject
@@ -1254,7 +1269,7 @@ void QQuickPixmapData::release()
void QQuickPixmapData::addToCache()
{
if (!inCache) {
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1265,7 +1280,7 @@ void QQuickPixmapData::addToCache()
void QQuickPixmapData::removeFromCache()
{
if (inCache) {
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1273,7 +1288,7 @@ void QQuickPixmapData::removeFromCache()
}
}
-static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, bool *ok)
+static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
{
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
@@ -1296,7 +1311,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestTexture(imageId(url), &readSize, requestSize);
if (texture) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1307,7 +1322,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1317,7 +1332,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1347,7 +1362,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QQuickTextureFactory *factory = texReader.read();
if (factory) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
} else {
errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
if (f.fileName() != localFile)
@@ -1356,9 +1371,10 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
} else {
QImage image;
QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
- if (readImage(url, &f, &image, &errorString, &readSize, requestSize, providerOptions, &appliedTransform)) {
+ int frameCount;
+ if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestSize, providerOptions, &appliedTransform, frame)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform, frame, frameCount);
} else if (f.fileName() != localFile) {
errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
}
@@ -1476,6 +1492,13 @@ QQuickImageProviderOptions::AutoTransform QQuickPixmap::autoTransform() const
return QQuickImageProviderOptions::UsePluginDefaultTransform;
}
+int QQuickPixmap::frameCount() const
+{
+ if (d)
+ return d->frameCount;
+ return 0;
+}
+
QQuickTextureFactory *QQuickPixmap::textureFactory() const
{
if (d)
@@ -1554,7 +1577,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
load(engine, url, requestSize, options, QQuickImageProviderOptions());
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
{
if (d) {
d->declarativePixmaps.remove(this);
@@ -1562,7 +1585,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
d = nullptr;
}
- QQuickPixmapKey key = { &url, &requestSize, providerOptions };
+ QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
QQuickPixmapStore *store = pixmapStore();
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
@@ -1574,7 +1597,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
QSize dummy;
if (requestSize != dummy)
qWarning() << "Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.";
- const QQuickPixmapKey grabberKey = { &url, &dummy, QQuickImageProviderOptions() };
+ const QQuickPixmapKey grabberKey = { &url, &dummy, 0, QQuickImageProviderOptions() };
iter = store->m_cache.find(grabberKey);
} else if (options & QQuickPixmap::Cache)
iter = store->m_cache.find(key);
@@ -1596,7 +1619,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, &ok);
+ d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, frame, &ok);
if (ok) {
PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
if (options & QQuickPixmap::Cache)
@@ -1613,7 +1636,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
return;
- d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
if (options & QQuickPixmap::Cache)
d->addToCache();
@@ -1647,9 +1670,9 @@ void QQuickPixmap::clear(QObject *obj)
}
}
-bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &options)
+bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
{
- QQuickPixmapKey key = { &url, &requestSize, options };
+ QQuickPixmapKey key = { &url, &requestSize, frame, options };
QQuickPixmapStore *store = pixmapStore();
return store->m_cache.contains(key);
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index f51b65dd76..c4f4d1a101 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -150,6 +150,7 @@ public:
const QSize &implicitSize() const;
const QSize &requestSize() const;
QQuickImageProviderOptions::AutoTransform autoTransform() const;
+ int frameCount() const;
QImage image() const;
void setImage(const QImage &);
void setPixmap(const QQuickPixmap &other);
@@ -164,7 +165,7 @@ public:
void load(QQmlEngine *, const QUrl &, QQuickPixmap::Options options);
void load(QQmlEngine *, const QUrl &, const QSize &);
void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions);
+ void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
void clear();
void clear(QObject *);
@@ -175,7 +176,7 @@ public:
bool connectDownloadProgress(QObject *, int);
static void purgeCache();
- static bool isCached(const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &options);
+ static bool isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options);
static const QLatin1String itemGrabberScheme;
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index c5d5501cb7..712cca7696 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -67,8 +67,8 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL)
Q_PROPERTY(QVariantList sequences READ sequences WRITE setSequences NOTIFY sequencesChanged FINAL REVISION 9)
- Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 1)
- Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 1)
+ Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 6)
+ Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 6)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index c8699426f2..b973309212 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -82,13 +82,15 @@ QT_BEGIN_NAMESPACE
values can be set to restrict the animations to only be applied when changing
from one particular state to another.
- To define multiple transitions, specify \l Item::transitions as a list:
+ To define multiple Transitions, specify \l Item::transitions as a list:
\snippet qml/transitions-list.qml list of transitions
- If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
- state change. In the example above, when changing to \c state1, the first transition will be used, rather
- than the more generic second transition.
+ If multiple Transitions are specified, only a single (best-matching)
+ Transition will be applied for any particular state change. In the
+ example above, if the Rectangle enters a state other than \c "middleRight"
+ or \c "bottomLeft", the third Transition will be carried out, meaning the
+ icon will be moved to the starting point.
If a state change has a Transition that matches the same property as a
\l Behavior, the Transition animation overrides the \l Behavior for that
@@ -298,10 +300,11 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action
\snippet qml/transition-from-to-modified.qml modified transition
- The animation would only be applied when changing from the default state to
- the "brighter" state (i.e. when the mouse is pressed, but not on release).
+ The animation would only be applied when changing from the default state
+ to the "brighter" state (i.e. when the mouse is pressed, but not on release).
- Multiple \c to and \c from values can be set by using a comma-separated string.
+ Multiple \c to and \c from values can be set by using a comma-separated
+ string.
\sa reversible
*/
@@ -323,7 +326,8 @@ void QQuickTransition::setFromState(const QString &f)
/*!
\qmlproperty bool QtQuick::Transition::reversible
- This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
+ This property holds whether the transition should be automatically
+ reversed when the conditions that triggered this transition are reversed.
The default value is false.
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index d222a0c0be..93b6599506 100644
--- a/src/quick/util/qquickutilmodule.cpp
+++ b/src/quick/util/qquickutilmodule.cpp
@@ -99,7 +99,7 @@ void QQuickUtilModule::defineModule()
qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
#if QT_CONFIG(validator)
- qmlRegisterType<QValidator>();
+ qmlRegisterAnonymousType<QValidator>("QtQuick", 2);
qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
@@ -117,7 +117,7 @@ void QQuickUtilModule::defineModule()
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
qmlRegisterType<QQuickUniformAnimator>("QtQuick", 2, 2, "UniformAnimator");
#endif
- qmlRegisterType<QQuickStateOperation>();
+ qmlRegisterAnonymousType<QQuickStateOperation>("QtQuick", 2);
qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser);
@@ -131,7 +131,7 @@ void QQuickUtilModule::defineModule()
#if QT_CONFIG(shortcut)
qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
- qmlRegisterType<QQuickShortcut,1>("QtQuick", 2, 6, "Shortcut");
+ qmlRegisterType<QQuickShortcut,6>("QtQuick", 2, 6, "Shortcut");
qmlRegisterType<QQuickShortcut,9>("QtQuick", 2, 9, "Shortcut");
#endif
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index 04e8de5aa0..c1deb0dced 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -201,7 +201,7 @@ void QQuickShapePath::setStrokeColor(const QColor &color)
}
/*!
- \qmlproperty color QtQuick.Shapes::ShapePath::strokeWidth
+ \qmlproperty real QtQuick.Shapes::ShapePath::strokeWidth
This property holds the stroke width.
diff --git a/src/src.pro b/src/src.pro
index b1e0a72c9f..98e1779dc5 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -11,9 +11,10 @@ qtConfig(qml-worker-script): \
SUBDIRS += qmlworkerscript
qtHaveModule(gui):qtConfig(qml-animation) {
- SUBDIRS += \
- quick \
- quickshapes
+ SUBDIRS += quick
+
+ qtConfig(quick-path): \
+ SUBDIRS += quickshapes
qtConfig(testlib): \
SUBDIRS += qmltest