aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/masm.pri4
-rw-r--r--src/3rdparty/masm/wtf/MathExtras.h2
-rw-r--r--src/3rdparty/masm/wtf/Platform.h3
-rw-r--r--src/CMakeLists.txt56
-rw-r--r--src/imports/CMakeLists.txt42
-rw-r--r--src/imports/builtins/.prev_CMakeLists.txt2
-rw-r--r--src/imports/builtins/CMakeLists.txt19
-rw-r--r--src/imports/builtins/builtins.qmltypes1
-rw-r--r--src/imports/folderlistmodel/CMakeLists.txt26
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro2
-rw-r--r--src/imports/folderlistmodel/plugin.cpp11
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h15
-rw-r--r--src/imports/labsanimation/CMakeLists.txt24
-rw-r--r--src/imports/labsanimation/labsanimation.pro2
-rw-r--r--src/imports/labsanimation/qquickboundaryrule_p.h1
-rw-r--r--src/imports/labsmodels/CMakeLists.txt37
-rw-r--r--src/imports/labsmodels/labsmodels.pro2
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent_p.h3
-rw-r--r--src/imports/labsmodels/qqmltablemodel_p.h1
-rw-r--r--src/imports/labsmodels/qqmltablemodelcolumn_p.h1
-rw-r--r--src/imports/layouts/CMakeLists.txt33
-rw-r--r--src/imports/layouts/layouts.pro2
-rw-r--r--src/imports/layouts/qquickgridlayoutengine_p.h5
-rw-r--r--src/imports/layouts/qquicklayout.cpp202
-rw-r--r--src/imports/layouts/qquicklayout_p.h38
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp96
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h10
-rw-r--r--src/imports/layouts/qquickstacklayout.cpp221
-rw-r--r--src/imports/layouts/qquickstacklayout_p.h39
-rw-r--r--src/imports/localstorage/CMakeLists.txt26
-rw-r--r--src/imports/localstorage/localstorage.pro2
-rw-r--r--src/imports/localstorage/qquicklocalstorage_p.h1
-rw-r--r--src/imports/models/CMakeLists.txt23
-rw-r--r--src/imports/models/models.pro4
-rw-r--r--src/imports/particles/CMakeLists.txt25
-rw-r--r--src/imports/particles/particles.pro4
-rw-r--r--src/imports/qtqml/.prev_CMakeLists.txt41
-rw-r--r--src/imports/qtqml/CMakeLists.txt42
-rw-r--r--src/imports/qtqml/plugin.cpp20
-rw-r--r--src/imports/qtqml/qmldir4
-rw-r--r--src/imports/qtqml/qtqml.pro13
-rw-r--r--src/imports/qtquick2/CMakeLists.txt36
-rw-r--r--src/imports/qtquick2/plugin.cpp19
-rw-r--r--src/imports/qtquick2/qmldir1
-rw-r--r--src/imports/qtquick2/qtquick2.pro4
-rw-r--r--src/imports/settings/CMakeLists.txt24
-rw-r--r--src/imports/settings/qqmlsettings_p.h1
-rw-r--r--src/imports/settings/settings.pro2
-rw-r--r--src/imports/shapes/CMakeLists.txt25
-rw-r--r--src/imports/shapes/shapes.pro2
-rw-r--r--src/imports/sharedimage/CMakeLists.txt29
-rw-r--r--src/imports/sharedimage/qsharedimageloader_p.h5
-rw-r--r--src/imports/sharedimage/sharedimage.pro2
-rw-r--r--src/imports/statemachine/CMakeLists.txt30
-rw-r--r--src/imports/statemachine/finalstate.h1
-rw-r--r--src/imports/statemachine/signaltransition.cpp14
-rw-r--r--src/imports/statemachine/signaltransition.h1
-rw-r--r--src/imports/statemachine/state.h1
-rw-r--r--src/imports/statemachine/statemachine.h1
-rw-r--r--src/imports/statemachine/statemachine.pro2
-rw-r--r--src/imports/statemachine/statemachineforeign.h4
-rw-r--r--src/imports/statemachine/timeouttransition.h1
-rw-r--r--src/imports/testlib/.prev_CMakeLists.txt52
-rw-r--r--src/imports/testlib/CMakeLists.txt55
-rw-r--r--src/imports/testlib/qmldir1
-rw-r--r--src/imports/testlib/quicktestevent_p.h4
-rw-r--r--src/imports/testlib/quicktestresultforeign_p.h1
-rw-r--r--src/imports/testlib/quicktestutil.cpp6
-rw-r--r--src/imports/testlib/quicktestutil_p.h1
-rw-r--r--src/imports/testlib/testlib.pro2
-rw-r--r--src/imports/wavefrontmesh/CMakeLists.txt25
-rw-r--r--src/imports/wavefrontmesh/qwavefrontmesh.h1
-rw-r--r--src/imports/wavefrontmesh/wavefrontmesh.pro2
-rw-r--r--src/imports/window/CMakeLists.txt26
-rw-r--r--src/imports/window/plugin.h13
-rw-r--r--src/imports/window/window.pro4
-rw-r--r--src/imports/workerscript/CMakeLists.txt23
-rw-r--r--src/imports/workerscript/qmldir1
-rw-r--r--src/imports/workerscript/workerscript.pro4
-rw-r--r--src/particles/CMakeLists.txt135
-rw-r--r--src/particles/particles.pro4
-rw-r--r--src/particles/qquickage_p.h1
-rw-r--r--src/particles/qquickangledirection_p.h1
-rw-r--r--src/particles/qquickcumulativedirection_p.h1
-rw-r--r--src/particles/qquickcustomaffector.cpp2
-rw-r--r--src/particles/qquickcustomaffector_p.h1
-rw-r--r--src/particles/qquickcustomparticle.cpp2
-rw-r--r--src/particles/qquickcustomparticle_p.h1
-rw-r--r--src/particles/qquickdirection_p.h1
-rw-r--r--src/particles/qquickellipseextruder_p.h1
-rw-r--r--src/particles/qquickfriction_p.h1
-rw-r--r--src/particles/qquickgravity_p.h1
-rw-r--r--src/particles/qquickgroupgoal_p.h1
-rw-r--r--src/particles/qquickimageparticle.cpp22
-rw-r--r--src/particles/qquickimageparticle_p.h1
-rw-r--r--src/particles/qquickitemparticle_p.h1
-rw-r--r--src/particles/qquicklineextruder_p.h1
-rw-r--r--src/particles/qquickmaskextruder_p.h1
-rw-r--r--src/particles/qquickparticleaffector_p.h1
-rw-r--r--src/particles/qquickparticleemitter.cpp2
-rw-r--r--src/particles/qquickparticleemitter_p.h1
-rw-r--r--src/particles/qquickparticleextruder_p.h1
-rw-r--r--src/particles/qquickparticlegroup_p.h1
-rw-r--r--src/particles/qquickparticlepainter_p.h1
-rw-r--r--src/particles/qquickparticlesystem_p.h1
-rw-r--r--src/particles/qquickpointattractor_p.h1
-rw-r--r--src/particles/qquickpointdirection_p.h1
-rw-r--r--src/particles/qquickrectangleextruder_p.h1
-rw-r--r--src/particles/qquickspritegoal_p.h1
-rw-r--r--src/particles/qquicktargetdirection_p.h1
-rw-r--r--src/particles/qquicktrailemitter.cpp11
-rw-r--r--src/particles/qquicktrailemitter_p.h1
-rw-r--r--src/particles/qquickturbulence.cpp2
-rw-r--r--src/particles/qquickturbulence_p.h4
-rw-r--r--src/particles/qquickwander_p.h1
-rw-r--r--src/plugins/CMakeLists.txt8
-rw-r--r--src/plugins/qmltooling/CMakeLists.txt24
-rw-r--r--src/plugins/qmltooling/packetprotocol/CMakeLists.txt16
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt26
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp29
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt28
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_local/CMakeLists.txt18
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt20
-rw-r--r--src/plugins/qmltooling/qmldbg_native/CMakeLists.txt19
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt20
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt31
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt23
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt23
-rw-r--r--src/plugins/qmltooling/qmldbg_server/CMakeLists.txt19
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt19
-rw-r--r--src/plugins/qmltooling/qmltooling.pro2
-rw-r--r--src/plugins/scenegraph/.prev_CMakeLists.txt5
-rw-r--r--src/plugins/scenegraph/CMakeLists.txt5
-rw-r--r--src/plugins/scenegraph/d3d12/d3d12.json3
-rw-r--r--src/plugins/scenegraph/d3d12/d3d12.pro73
-rw-r--r--src/plugins/scenegraph/d3d12/d3d12.tracepoints0
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp87
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp737
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h253
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12context.cpp143
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12context_p.h84
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp3280
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h394
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h455
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp197
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h88
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp90
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp123
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp72
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp370
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h129
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12material.cpp49
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12material_p.h96
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp255
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp250
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h136
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp169
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h90
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp785
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h137
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp548
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h130
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp995
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h176
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp314
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp157
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp1208
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h129
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl27
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl60
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl27
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/shaders.pri141
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl64
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl77
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/sprite.hlsl43
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl26
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/tdr.hlsl11
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/textmask.hlsl104
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/texture.hlsl33
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl32
-rw-r--r--src/plugins/scenegraph/openvg/CMakeLists.txt65
-rw-r--r--src/plugins/scenegraph/scenegraph.pro1
-rw-r--r--src/qml/.prev_CMakeLists.txt625
-rw-r--r--src/qml/CMakeLists.txt634
-rw-r--r--src/qml/Qt6QmlBuildInternals.cmake174
-rw-r--r--src/qml/Qt6QmlMacros.cmake756
-rw-r--r--src/qml/common/qv4compileddata_p.h120
-rw-r--r--src/qml/common/qv4stringtoarrayindex_p.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp39
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h2
-rw-r--r--src/qml/compiler/qv4compiler.cpp14
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/configure.cmake189
-rw-r--r--src/qml/configure.json21
-rw-r--r--src/qml/configure.pri22
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h6
-rw-r--r--src/qml/doc/images/cpp-qml-integration-flowchart.odgbin15311 -> 14778 bytes
-rw-r--r--src/qml/doc/images/cpp-qml-integration-flowchart.pngbin64865 -> 47554 bytes
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs2
-rw-r--r--src/qml/doc/src/cppintegration/data.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc12
-rw-r--r--src/qml/inlinecomponentutils_p.h10
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp4
-rw-r--r--src/qml/jit/qv4baselinejit.cpp2
-rw-r--r--src/qml/jsapi/qjsengine.cpp209
-rw-r--r--src/qml/jsapi/qjsengine.h14
-rw-r--r--src/qml/jsapi/qjsengine_p.h15
-rw-r--r--src/qml/jsapi/qjsvalue.cpp464
-rw-r--r--src/qml/jsapi/qjsvalue.h9
-rw-r--r--src/qml/jsapi/qjsvalue_p.h223
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp6
-rw-r--r--src/qml/jsruntime/jsruntime.pri13
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp53
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h27
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp2
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp30
-rw-r--r--src/qml/jsruntime/qv4engine.cpp212
-rw-r--r--src/qml/jsruntime/qv4engine_p.h22
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp129
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h87
-rw-r--r--src/qml/jsruntime/qv4function.cpp10
-rw-r--r--src/qml/jsruntime/qv4function_p.h7
-rw-r--r--src/qml/jsruntime/qv4global_p.h2
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4identifier_p.h173
-rw-r--r--src/qml/jsruntime/qv4identifierhash.cpp (renamed from src/qml/jsruntime/qv4identifier.cpp)102
-rw-r--r--src/qml/jsruntime/qv4identifierhash_p.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h)59
-rw-r--r--src/qml/jsruntime/qv4identifierhashdata_p.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h)124
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp1
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h2
-rw-r--r--src/qml/jsruntime/qv4include.cpp8
-rw-r--r--src/qml/jsruntime/qv4include_p.h4
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp2
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4managed.cpp6
-rw-r--r--src/qml/jsruntime/qv4managed_p.h2
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp2
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp4
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp116
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h18
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp90
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h26
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp118
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4resolvedtypereference.cpp115
-rw-r--r--src/qml/jsruntime/qv4resolvedtypereference_p.h145
-rw-r--r--src/qml/jsruntime/qv4script.cpp4
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp40
-rw-r--r--src/qml/jsruntime/qv4sparsearray.cpp2
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h2
-rw-r--r--src/qml/jsruntime/qv4string.cpp46
-rw-r--r--src/qml/jsruntime/qv4string_p.h32
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp3
-rw-r--r--src/qml/jsruntime/qv4symbol.cpp5
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp24
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h4
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp1449
-rw-r--r--src/qml/jsruntime/qv4urlobject_p.h317
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp8
-rw-r--r--src/qml/memory/qv4mm_p.h20
-rw-r--r--src/qml/parser/qqmljs.g19
-rw-r--r--src/qml/parser/qqmljsast_p.h14
-rw-r--r--src/qml/parser/qqmljsglobal_p.h28
-rw-r--r--src/qml/parser/qqmljslexer.cpp42
-rw-r--r--src/qml/qml.pro8
-rw-r--r--src/qml/qml/ftw/qfieldlist_p.h118
-rw-r--r--src/qml/qml/ftw/qflagpointer_p.h152
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp2
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h4
-rw-r--r--src/qml/qml/ftw/qlazilyallocated_p.h67
-rw-r--r--src/qml/qml/ftw/qlinkedstringhash_p.h2
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp22
-rw-r--r--src/qml/qml/ftw/qstringhash_p.h74
-rw-r--r--src/qml/qml/qml.pri5
-rw-r--r--src/qml/qml/qqml.cpp172
-rw-r--r--src/qml/qml/qqml.h277
-rw-r--r--src/qml/qml/qqmlabstractbinding_p.h31
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp43
-rw-r--r--src/qml/qml/qqmlapplicationengine.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h2
-rw-r--r--src/qml/qml/qqmlbinding.cpp91
-rw-r--r--src/qml/qml/qqmlbinding_p.h32
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp36
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h28
-rw-r--r--src/qml/qml/qqmlcomponent.cpp52
-rw-r--r--src/qml/qml/qqmlcomponent.h1
-rw-r--r--src/qml/qml/qqmlcomponent_p.h7
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h30
-rw-r--r--src/qml/qml/qqmlcontext.cpp548
-rw-r--r--src/qml/qml/qqmlcontext.h2
-rw-r--r--src/qml/qml/qqmlcontext_p.h336
-rw-r--r--src/qml/qml/qqmlcontextdata.cpp366
-rw-r--r--src/qml/qml/qqmlcontextdata_p.h432
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp12
-rw-r--r--src/qml/qml/qqmldata_p.h47
-rw-r--r--src/qml/qml/qqmldatablob.cpp30
-rw-r--r--src/qml/qml/qqmldatablob_p.h5
-rw-r--r--src/qml/qml/qqmldirdata.cpp2
-rw-r--r--src/qml/qml/qqmldirdata_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp352
-rw-r--r--src/qml/qml/qqmlengine.h23
-rw-r--r--src/qml/qml/qqmlengine_p.h59
-rw-r--r--src/qml/qml/qqmlexpression.cpp41
-rw-r--r--src/qml/qml/qqmlexpression.h2
-rw-r--r--src/qml/qml/qqmlexpression_p.h4
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp10
-rw-r--r--src/qml/qml/qqmlextensionplugin.h1
-rw-r--r--src/qml/qml/qqmlfileselector.cpp69
-rw-r--r--src/qml/qml/qqmlfileselector.h6
-rw-r--r--src/qml/qml/qqmlglobal.cpp4
-rw-r--r--src/qml/qml/qqmlglobal_p.h1
-rw-r--r--src/qml/qml/qqmlguardedcontextdata_p.h131
-rw-r--r--src/qml/qml/qqmlimport.cpp418
-rw-r--r--src/qml/qml/qqmlimport_p.h40
-rw-r--r--src/qml/qml/qqmlincubator.cpp21
-rw-r--r--src/qml/qml/qqmlincubator_p.h2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp51
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h56
-rw-r--r--src/qml/qml/qqmllocale.cpp2
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmlloggingcategory_p.h4
-rw-r--r--src/qml/qml/qqmlmetaobject.cpp8
-rw-r--r--src/qml/qml/qqmlmetatype.cpp335
-rw-r--r--src/qml/qml/qqmlmetatype_p.h46
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp55
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h34
-rw-r--r--src/qml/qml/qqmlmoduleregistration.cpp20
-rw-r--r--src/qml/qml/qqmlmoduleregistration.h7
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp194
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h32
-rw-r--r--src/qml/qml/qqmlparserstatus.cpp2
-rw-r--r--src/qml/qml/qqmlprivate.h139
-rw-r--r--src/qml/qml/qqmlproperty.cpp59
-rw-r--r--src/qml/qml/qqmlproperty.h2
-rw-r--r--src/qml/qml/qqmlproperty_p.h25
-rw-r--r--src/qml/qml/qqmlpropertybinding.cpp129
-rw-r--r--src/qml/qml/qqmlpropertybinding_p.h (renamed from src/qmlworkerscript/qqmlworkerscriptmodule_p.h)40
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp95
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h53
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp7
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h72
-rw-r--r--src/qml/qml/qqmlpropertycachevector_p.h17
-rw-r--r--src/qml/qml/qqmlpropertydata_p.h50
-rw-r--r--src/qml/qml/qqmlpropertyresolver.cpp1
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp25
-rw-r--r--src/qml/qml/qqmlscriptblob.cpp5
-rw-r--r--src/qml/qml/qqmlscriptblob_p.h2
-rw-r--r--src/qml/qml/qqmlscriptdata.cpp70
-rw-r--r--src/qml/qml/qqmlscriptdata_p.h5
-rw-r--r--src/qml/qml/qqmltype.cpp51
-rw-r--r--src/qml/qml/qqmltype_p.h22
-rw-r--r--src/qml/qml/qqmltype_p_p.h9
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp102
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h2
-rw-r--r--src/qml/qml/qqmltypedata.cpp76
-rw-r--r--src/qml/qml/qqmltypedata_p.h9
-rw-r--r--src/qml/qml/qqmltypeloader.cpp78
-rw-r--r--src/qml/qml/qqmltypeloader_p.h9
-rw-r--r--src/qml/qml/qqmltypeloaderthread.cpp6
-rw-r--r--src/qml/qml/qqmltypeloaderthread_p.h6
-rw-r--r--src/qml/qml/qqmltypemodule.cpp24
-rw-r--r--src/qml/qml/qqmltypemodule_p.h15
-rw-r--r--src/qml/qml/qqmltypemodule_p_p.h6
-rw-r--r--src/qml/qml/qqmltypemoduleversion.cpp32
-rw-r--r--src/qml/qml/qqmltypemoduleversion_p.h21
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp8
-rw-r--r--src/qml/qml/qqmltypenotavailable_p.h2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp22
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp7
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h43
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp2
-rw-r--r--src/qml/qml/qqmlvme.cpp2
-rw-r--r--src/qml/qml/qqmlvme_p.h2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp43
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h7
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp40
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp102
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h4
-rw-r--r--src/qml/qmldirparser/qqmldirparser.cpp51
-rw-r--r--src/qml/qmldirparser/qqmldirparser_p.h15
-rw-r--r--src/qml/types/qqmlbind.cpp33
-rw-r--r--src/qml/types/qqmlbind_p.h5
-rw-r--r--src/qml/types/qqmlconnections.cpp6
-rw-r--r--src/qml/types/qqmlconnections_p.h5
-rw-r--r--src/qml/types/qqmlmodelindexvaluetype_p.h10
-rw-r--r--src/qml/types/qqmltimer_p.h1
-rw-r--r--src/qmldebug/CMakeLists.txt39
-rw-r--r--src/qmldebug/qqmldebugconnection.cpp27
-rw-r--r--src/qmldebug/qqmldebugconnection_p.h1
-rw-r--r--src/qmldebug/qqmlprofilereventlocation_p.h2
-rw-r--r--src/qmldebug/qqmlprofilereventtype_p.h2
-rw-r--r--src/qmldevtools/.prev_CMakeLists.txt90
-rw-r--r--src/qmldevtools/CMakeLists.txt137
-rw-r--r--src/qmlmodels/CMakeLists.txt78
-rw-r--r--src/qmlmodels/configure.cmake39
-rw-r--r--src/qmlmodels/doc/qtqmlmodels.qdocconf2
-rw-r--r--src/qmlmodels/qmlmodels.pro7
-rw-r--r--src/qmlmodels/qqmlabstractdelegatecomponent_p.h1
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp4
-rw-r--r--src/qmlmodels/qqmladaptormodel_p.h4
-rw-r--r--src/qmlmodels/qqmlchangeset_p.h2
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp52
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p.h4
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p_p.h12
-rw-r--r--src/qmlmodels/qqmlinstantiator_p.h2
-rw-r--r--src/qmlmodels/qqmllistmodel.cpp73
-rw-r--r--src/qmlmodels/qqmllistmodel_p.h6
-rw-r--r--src/qmlmodels/qqmllistmodel_p_p.h15
-rw-r--r--src/qmlmodels/qqmllistmodelworkeragent_p.h1
-rw-r--r--src/qmlmodels/qqmlmodelsmodule.cpp99
-rw-r--r--src/qmlmodels/qqmlmodelsmodule_p.h11
-rw-r--r--src/qmlmodels/qqmlobjectmodel.cpp5
-rw-r--r--src/qmlmodels/qqmlobjectmodel_p.h19
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp12
-rw-r--r--src/qmlmodels/qqmltableinstancemodel_p.h2
-rw-r--r--src/qmlmodels/qquickpackage_p.h2
-rw-r--r--src/qmltest/.prev_CMakeLists.txt73
-rw-r--r--src/qmltest/CMakeLists.txt82
-rw-r--r--src/qmltest/quicktest.cpp4
-rw-r--r--src/qmltest/quicktestresult_p.h6
-rw-r--r--src/qmltyperegistrar/.prev_CMakeLists.txt38
-rw-r--r--src/qmltyperegistrar/CMakeLists.txt39
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.cpp41
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.pro2
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.cpp52
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.h13
-rw-r--r--src/qmltyperegistrar/qmltypescreator.cpp32
-rw-r--r--src/qmltyperegistrar/qmltypescreator.h4
-rw-r--r--src/qmlworkerscript/.prev_CMakeLists.txt114
-rw-r--r--src/qmlworkerscript/CMakeLists.txt114
-rw-r--r--src/qmlworkerscript/qmlworkerscript.pro6
-rw-r--r--src/qmlworkerscript/qqmlworkerscriptmodule.cpp57
-rw-r--r--src/qmlworkerscript/qquickworkerscript.cpp4
-rw-r--r--src/qmlworkerscript/qquickworkerscript_p.h5
-rw-r--r--src/quick/CMakeLists.txt622
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp4
-rw-r--r--src/quick/configure.cmake109
-rw-r--r--src/quick/configure.json19
-rw-r--r--src/quick/designer/qquickdesignersupport.cpp8
-rw-r--r--src/quick/designer/qquickdesignersupportitems.cpp7
-rw-r--r--src/quick/designer/qquickdesignersupportitems_p.h3
-rw-r--r--src/quick/designer/qquickdesignerwindowmanager.cpp1
-rw-r--r--src/quick/designer/qquickdesignerwindowmanager_p.h2
-rw-r--r--src/quick/doc/images/qml-xmllistmodel-example.pngbin5252 -> 0 bytes
-rw-r--r--src/quick/doc/qtquick.qdocconf2
-rw-r--r--src/quick/doc/snippets/qml/regexp.qml56
-rw-r--r--src/quick/doc/src/concepts/input/textinput.qdoc2
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc248
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc40
-rw-r--r--src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc26
-rw-r--r--src/quick/handlers/qquickdragaxis_p.h2
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h6
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h2
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp43
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h28
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h10
-rw-r--r--src/quick/handlers/qquickpointhandler_p.h2
-rw-r--r--src/quick/handlers/qquicktaphandler_p.h2
-rw-r--r--src/quick/handlers/qquickwheelhandler_p.h2
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp7
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h3
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp4
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp4
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp4
-rw-r--r--src/quick/items/items.pri19
-rw-r--r--src/quick/items/qquickabstractpaletteprovider_p.h64
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h1
-rw-r--r--src/quick/items/qquickanchors_p.h1
-rw-r--r--src/quick/items/qquickanchors_p_p.h5
-rw-r--r--src/quick/items/qquickanimatedimage_p.h5
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp10
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h9
-rw-r--r--src/quick/items/qquickborderimage_p.h1
-rw-r--r--src/quick/items/qquickcolorgroup.cpp571
-rw-r--r--src/quick/items/qquickcolorgroup_p.h231
-rw-r--r--src/quick/items/qquickdrag.cpp1
-rw-r--r--src/quick/items/qquickdrag_p.h2
-rw-r--r--src/quick/items/qquickdroparea_p.h3
-rw-r--r--src/quick/items/qquickevents.cpp37
-rw-r--r--src/quick/items/qquickevents_p_p.h32
-rw-r--r--src/quick/items/qquickflickable.cpp5
-rw-r--r--src/quick/items/qquickflickable_p.h22
-rw-r--r--src/quick/items/qquickflickable_p_p.h1
-rw-r--r--src/quick/items/qquickflipable_p.h1
-rw-r--r--src/quick/items/qquickfocusscope_p.h1
-rw-r--r--src/quick/items/qquickframebufferobject.cpp19
-rw-r--r--src/quick/items/qquickframebufferobject.h5
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp5
-rw-r--r--src/quick/items/qquickgraphicsdevice.cpp216
-rw-r--r--src/quick/items/qquickgraphicsdevice.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h)47
-rw-r--r--src/quick/items/qquickgraphicsdevice_p.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h)75
-rw-r--r--src/quick/items/qquickgraphicsinfo.cpp3
-rw-r--r--src/quick/items/qquickgraphicsinfo_p.h3
-rw-r--r--src/quick/items/qquickgridview.cpp4
-rw-r--r--src/quick/items/qquickgridview_p.h3
-rw-r--r--src/quick/items/qquickimage.cpp4
-rw-r--r--src/quick/items/qquickimage_p.h13
-rw-r--r--src/quick/items/qquickimagebase.cpp5
-rw-r--r--src/quick/items/qquickimagebase_p.h16
-rw-r--r--src/quick/items/qquickitem.cpp90
-rw-r--r--src/quick/items/qquickitem.h30
-rw-r--r--src/quick/items/qquickitem_p.h27
-rw-r--r--src/quick/items/qquickitemanimation_p.h3
-rw-r--r--src/quick/items/qquickitemgrabresult.h1
-rw-r--r--src/quick/items/qquickitemsmodule_p.h4
-rw-r--r--src/quick/items/qquickitemview.cpp4
-rw-r--r--src/quick/items/qquickitemview_p.h24
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h1
-rw-r--r--src/quick/items/qquicklistview.cpp16
-rw-r--r--src/quick/items/qquicklistview_p.h12
-rw-r--r--src/quick/items/qquickloader.cpp12
-rw-r--r--src/quick/items/qquickloader_p.h3
-rw-r--r--src/quick/items/qquickmousearea.cpp17
-rw-r--r--src/quick/items/qquickmousearea_p.h16
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h15
-rw-r--r--src/quick/items/qquickopenglinfo.cpp2
-rw-r--r--src/quick/items/qquickopenglinfo_p.h2
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp3
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp6
-rw-r--r--src/quick/items/qquickopenglshadereffectnode_p.h2
-rw-r--r--src/quick/items/qquickpainteditem.cpp7
-rw-r--r--src/quick/items/qquickpainteditem.h1
-rw-r--r--src/quick/items/qquickpalette.cpp328
-rw-r--r--src/quick/items/qquickpalette_p.h127
-rw-r--r--src/quick/items/qquickpalettecolorprovider.cpp149
-rw-r--r--src/quick/items/qquickpalettecolorprovider_p.h94
-rw-r--r--src/quick/items/qquickpaletteproviderprivatebase_p.h398
-rw-r--r--src/quick/items/qquickpathview_p.h7
-rw-r--r--src/quick/items/qquickpincharea.cpp5
-rw-r--r--src/quick/items/qquickpincharea_p.h8
-rw-r--r--src/quick/items/qquickpositioners_p.h41
-rw-r--r--src/quick/items/qquickrectangle_p.h6
-rw-r--r--src/quick/items/qquickrendercontrol.cpp324
-rw-r--r--src/quick/items/qquickrendercontrol.h19
-rw-r--r--src/quick/items/qquickrendercontrol_p.h18
-rw-r--r--src/quick/items/qquickrendertarget.cpp293
-rw-r--r--src/quick/items/qquickrendertarget.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h)55
-rw-r--r--src/quick/items/qquickrendertarget_p.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h)56
-rw-r--r--src/quick/items/qquickrepeater_p.h1
-rw-r--r--src/quick/items/qquickscalegrid_p_p.h1
-rw-r--r--src/quick/items/qquickscreen.cpp62
-rw-r--r--src/quick/items/qquickscreen_p.h35
-rw-r--r--src/quick/items/qquickshadereffect.cpp245
-rw-r--r--src/quick/items/qquickshadereffect_p.h5
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h4
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h5
-rw-r--r--src/quick/items/qquicksprite_p.h1
-rw-r--r--src/quick/items/qquickspriteengine.cpp2
-rw-r--r--src/quick/items/qquickspritesequence_p.h1
-rw-r--r--src/quick/items/qquickstateoperations_p.h3
-rw-r--r--src/quick/items/qquicktableview.cpp572
-rw-r--r--src/quick/items/qquicktableview_p.h33
-rw-r--r--src/quick/items/qquicktableview_p_p.h55
-rw-r--r--src/quick/items/qquicktext.cpp13
-rw-r--r--src/quick/items/qquicktext_p.h45
-rw-r--r--src/quick/items/qquicktextcontrol.cpp2
-rw-r--r--src/quick/items/qquicktextdocument.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp12
-rw-r--r--src/quick/items/qquicktextedit_p.h54
-rw-r--r--src/quick/items/qquicktextinput.cpp21
-rw-r--r--src/quick/items/qquicktextinput_p.h44
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp3
-rw-r--r--src/quick/items/qquicktranslate.cpp10
-rw-r--r--src/quick/items/qquicktranslate_p.h5
-rw-r--r--src/quick/items/qquickwindow.cpp511
-rw-r--r--src/quick/items/qquickwindow.h49
-rw-r--r--src/quick/items/qquickwindow_p.h48
-rw-r--r--src/quick/items/qquickwindowmodule.cpp37
-rw-r--r--src/quick/items/qquickwindowmodule_p.h6
-rw-r--r--src/quick/items/qquickwindowmodule_p_p.h (renamed from src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h)27
-rw-r--r--src/quick/quick.pro8
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h10
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h3
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp3
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp8
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h4
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp54
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h15
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp18
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h120
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h79
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer_p_p.h (renamed from src/quick/scenegraph/util/qsgengine_p.h)42
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp49
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h8
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialshader.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialshader.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h4
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp9
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp31
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.h4
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode_p.h6
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp108
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.h17
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture_p.h11
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h9
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp2
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext.cpp14
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp13
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.h1
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultinternalimagenode.cpp4
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp28
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultspritenode.cpp4
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp2
-rw-r--r--src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp21
-rw-r--r--src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h8
-rw-r--r--src/quick/scenegraph/qsgopengllayer.cpp13
-rw-r--r--src/quick/scenegraph/qsgopengllayer_p.h10
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp42
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h3
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp22
-rw-r--r--src/quick/scenegraph/qsgrhilayer_p.h15
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp20
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode_p.h6
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp124
-rw-r--r--src/quick/scenegraph/qsgrhisupport_p.h12
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp13
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h2
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp551
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop_p.h129
-rw-r--r--src/quick/scenegraph/scenegraph.pri13
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode_p.h7
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode.cpp13
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode_p.h13
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp8
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h6
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp295
-rw-r--r--src/quick/scenegraph/util/qsgengine.h91
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.cpp12
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.h3
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture.cpp27
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture_p.h6
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp119
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture_p.h9
-rw-r--r--src/quick/scenegraph/util/qsgrhiatlastexture.cpp32
-rw-r--r--src/quick/scenegraph/util/qsgrhiatlastexture_p.h20
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp258
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h226
-rw-r--r--src/quick/scenegraph/util/qsgsimplerectnode.cpp7
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.cpp7
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp6
-rw-r--r--src/quick/util/qquickanimation_p.h13
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h1
-rw-r--r--src/quick/util/qquickanimator_p.h14
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp1
-rw-r--r--src/quick/util/qquickanimatorjob.cpp1
-rw-r--r--src/quick/util/qquickapplication_p.h1
-rw-r--r--src/quick/util/qquickbehavior_p.h5
-rw-r--r--src/quick/util/qquickfontloader.cpp134
-rw-r--r--src/quick/util/qquickfontloader_p.h10
-rw-r--r--src/quick/util/qquickfontmetrics_p.h2
-rw-r--r--src/quick/util/qquickforeignutils_p.h13
-rw-r--r--src/quick/util/qquickglobal.cpp9
-rw-r--r--src/quick/util/qquickimageprovider.h14
-rw-r--r--src/quick/util/qquickpath_p.h31
-rw-r--r--src/quick/util/qquickpathinterpolator_p.h1
-rw-r--r--src/quick/util/qquickpixmapcache.cpp2
-rw-r--r--src/quick/util/qquickpixmapcache_p.h4
-rw-r--r--src/quick/util/qquickpropertychanges.cpp9
-rw-r--r--src/quick/util/qquickpropertychanges_p.h1
-rw-r--r--src/quick/util/qquickshortcut_p.h10
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h1
-rw-r--r--src/quick/util/qquickspringanimation_p.h1
-rw-r--r--src/quick/util/qquickstate_p.h2
-rw-r--r--src/quick/util/qquickstatechangescript_p.h1
-rw-r--r--src/quick/util/qquickstategroup_p.h1
-rw-r--r--src/quick/util/qquicksystempalette_p.h1
-rw-r--r--src/quick/util/qquicktextmetrics_p.h2
-rw-r--r--src/quick/util/qquicktransition_p.h1
-rw-r--r--src/quick/util/qquickvalidator.cpp43
-rw-r--r--src/quick/util/qquickvalidator_p.h3
-rw-r--r--src/quick/util/qquickvaluetypes.cpp29
-rw-r--r--src/quick/util/qquickvaluetypes_p.h84
-rw-r--r--src/quickshapes/CMakeLists.txt80
-rw-r--r--src/quickshapes/qquickshape.cpp2
-rw-r--r--src/quickshapes/qquickshape_p.h12
-rw-r--r--src/quickshapes/qquickshape_p_p.h2
-rw-r--r--src/quickshapes/qquickshapegenericrenderer.cpp18
-rw-r--r--src/quickshapes/quickshapes.pro2
-rw-r--r--src/quickwidgets/CMakeLists.txt33
-rw-r--r--src/quickwidgets/qquickwidget.cpp12
-rw-r--r--src/src.pro3
712 files changed, 18902 insertions, 22044 deletions
diff --git a/src/3rdparty/masm/masm.pri b/src/3rdparty/masm/masm.pri
index 1df4585aae..9a12e65eeb 100644
--- a/src/3rdparty/masm/masm.pri
+++ b/src/3rdparty/masm/masm.pri
@@ -58,7 +58,7 @@ contains(DEFINES, WTF_USE_UDIS86=1) {
udis86.output = udis86_itab.h
udis86.input = ITAB
udis86.CONFIG += no_link
- udis86.commands = python $$PWD/disassembler/udis86/itab.py ${QMAKE_FILE_IN}
+ udis86.commands = $QMAKE_PYTHON $$PWD/disassembler/udis86/itab.py ${QMAKE_FILE_IN}
QMAKE_EXTRA_COMPILERS += udis86
udis86_tab_cfile.target = $$OUT_PWD/udis86_itab.c
@@ -111,7 +111,7 @@ retgen.output = $$GENERATEDDIR/RegExpJitTables.h
retgen.script = $$PWD/yarr/create_regex_tables
retgen.input = retgen.script
retgen.CONFIG += no_link
-retgen.commands = python $$retgen.script > ${QMAKE_FILE_OUT}
+retgen.commands = $$QMAKE_PYTHON $$retgen.script > ${QMAKE_FILE_OUT}
QMAKE_EXTRA_COMPILERS += retgen
# Taken from WebKit/Tools/qmake/mkspecs/features/unix/default_post.prf
diff --git a/src/3rdparty/masm/wtf/MathExtras.h b/src/3rdparty/masm/wtf/MathExtras.h
index a529ba7b37..6af108c886 100644
--- a/src/3rdparty/masm/wtf/MathExtras.h
+++ b/src/3rdparty/masm/wtf/MathExtras.h
@@ -399,7 +399,7 @@ inline void doubleToInteger(double d, unsigned long long& value)
value = 0;
else {
// -2^{64} < fmodValue < 2^{64}.
- double fmodValue = fmod(trunc(d), std::numeric_limits<unsigned long long>::max() + 1.0);
+ double fmodValue = fmod(trunc(d), -2.0 * std::numeric_limits<long long>::min());
if (fmodValue >= 0) {
// 0 <= fmodValue < 2^{64}.
// 0 <= value < 2^{64}. This cast causes no loss.
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h
index ab1da2198a..29decfadcf 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -1043,9 +1043,6 @@
#if PLATFORM(QT)
#include <qglobal.h>
-#if defined(QT_OPENGL_ES_2) && !defined(WTF_USE_OPENGL_ES_2)
-#define WTF_USE_OPENGL_ES_2 1
-#endif
#endif
#if !PLATFORM(IOS) && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000..d3c26e73e6
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,56 @@
+# Generated from src.pro.
+# special case skip regeneration
+
+if (NOT QT_FEATURE_commandlineparser)
+ message(FATAL_ERROR "QT_FEATURE_commandlineparser required to compile qmltyperegistrar")
+endif()
+
+add_subdirectory(qmltyperegistrar)
+add_subdirectory(qml)
+add_subdirectory(qmlmodels)
+
+if(QT_FEATURE_qml_worker_script)
+ add_subdirectory(qmlworkerscript)
+endif()
+
+if(TARGET Qt::Gui AND QT_FEATURE_qml_animation)
+ add_subdirectory(quick)
+ add_subdirectory(quickshapes)
+
+ find_package(Qt6 ${PROJECT_VERSION} CONFIG COMPONENTS Test) # special case
+ if(QT_FEATURE_testlib AND TARGET Qt::Test) # special case
+ add_subdirectory(qmltest)
+ endif()
+
+ if(QT_FEATURE_quick_particles)
+ add_subdirectory(particles)
+ endif()
+
+ if(TARGET Qt::Widgets)
+ add_subdirectory(quickwidgets)
+ endif()
+endif()
+
+# special case begin
+# These need to be included here since they have dependencies on the modules
+# specified above.
+add_subdirectory(plugins)
+
+if(QT_FEATURE_qml_devtools)
+ add_subdirectory(qmldevtools)
+
+ # Build qmlcachegen now, so that we can use it in src/imports.
+ if(QT_FEATURE_qml_devtools AND QT_FEATURE_xmlstreamwriter)
+ add_subdirectory(../tools/qmlcachegen qmlcachegen)
+ endif()
+endif()
+
+add_subdirectory(imports)
+
+if(QT_FEATURE_qml_network)
+
+ if(QT_FEATURE_thread AND QT_FEATURE_localserver AND QT_FEATURE_qml_debug)
+ add_subdirectory(qmldebug)
+ endif()
+endif()
+# special case end
diff --git a/src/imports/CMakeLists.txt b/src/imports/CMakeLists.txt
new file mode 100644
index 0000000000..020f683e41
--- /dev/null
+++ b/src/imports/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Generated from imports.pro.
+
+add_subdirectory(builtins)
+add_subdirectory(qtqml)
+add_subdirectory(models)
+add_subdirectory(labsmodels)
+if(QT_FEATURE_qml_itemmodel)
+ add_subdirectory(folderlistmodel)
+endif()
+if(QT_FEATURE_qml_worker_script)
+ add_subdirectory(workerscript)
+endif()
+if(TARGET Qt::Sql)
+ add_subdirectory(localstorage)
+endif()
+if(QT_FEATURE_settings)
+ add_subdirectory(settings)
+endif()
+if(QT_FEATURE_statemachine)
+ add_subdirectory(statemachine)
+endif()
+if(TARGET Qt::Quick)
+ add_subdirectory(labsanimation)
+ add_subdirectory(layouts)
+ add_subdirectory(qtquick2)
+ add_subdirectory(window)
+endif()
+if(QT_FEATURE_quick_shadereffect AND TARGET Qt::Quick)
+ add_subdirectory(wavefrontmesh)
+endif()
+if(TARGET Qt::Quick AND TARGET Qt::Test)
+ add_subdirectory(testlib)
+endif()
+if(QT_FEATURE_systemsemaphore AND TARGET Qt::Quick)
+ add_subdirectory(sharedimage)
+endif()
+if(QT_FEATURE_quick_particles AND TARGET Qt::Quick)
+ add_subdirectory(particles)
+endif()
+if(QT_FEATURE_quick_path AND TARGET Qt::Quick)
+ add_subdirectory(shapes)
+endif()
diff --git a/src/imports/builtins/.prev_CMakeLists.txt b/src/imports/builtins/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..088b0b73f0
--- /dev/null
+++ b/src/imports/builtins/.prev_CMakeLists.txt
@@ -0,0 +1,2 @@
+# Generated from builtins.pro.
+
diff --git a/src/imports/builtins/CMakeLists.txt b/src/imports/builtins/CMakeLists.txt
new file mode 100644
index 0000000000..00b6b07f0b
--- /dev/null
+++ b/src/imports/builtins/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Generated from builtins.pro.
+
+# special case begin
+
+set(qml_type_file builtins.qmltypes)
+
+qt_path_join(qml_install_dir "${QT_INSTALL_DIR}" "${INSTALL_QMLDIR}")
+qt_copy_or_install(FILES ${qml_type_file}
+ DESTINATION ${qml_install_dir}
+)
+
+if (NOT CMAKE_CROSSCOMPILING)
+
+ add_custom_target(builtins_qmltypes
+ COMMAND qmlplugindump -builtins > ${CMAKE_CURRENT_SOURCE_DIR}/${qml_type_file}
+ )
+endif()
+
+# special case end
diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes
index 765c92fcb9..87d599677a 100644
--- a/src/imports/builtins/builtins.qmltypes
+++ b/src/imports/builtins/builtins.qmltypes
@@ -1543,6 +1543,7 @@ Module {
"MatchStartsWith": 2,
"MatchEndsWith": 3,
"MatchRegExp": 4,
+ "MatchRegularExpression": 4,
"MatchWildcard": 5,
"MatchFixedString": 8,
"MatchCaseSensitive": 16,
diff --git a/src/imports/folderlistmodel/CMakeLists.txt b/src/imports/folderlistmodel/CMakeLists.txt
new file mode 100644
index 0000000000..0bc9f28da6
--- /dev/null
+++ b/src/imports/folderlistmodel/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Generated from folderlistmodel.pro.
+
+#####################################################################
+## qmlfolderlistmodelplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlfolderlistmodelplugin
+ URI "Qt.labs.folderlistmodel"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QmlFolderListModelPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ fileinfothread.cpp fileinfothread_p.h
+ fileproperty_p.h
+ plugin.cpp
+ qquickfolderlistmodel.cpp qquickfolderlistmodel.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:folderlistmodel.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/folderlistmodel"
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
index fd05653879..c95a88430d 100644
--- a/src/imports/folderlistmodel/folderlistmodel.pro
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlfolderlistmodelplugin
TARGETPATH = Qt/labs/folderlistmodel
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT = core-private qml-private
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 7a38769b77..9f8f14093e 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -39,6 +39,7 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
+#include <QtQml/private/qqmlmetatype_p.h>
#include "qquickfolderlistmodel.h"
@@ -64,8 +65,16 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
// Major version 1 only has a single revision, 0.
- qmlRegisterType<QQuickFolderListModel>(uri, 1, 0, "FolderListModel");
+ folderListModelId = qmlRegisterType<QQuickFolderListModel>(uri, 1, 0, "FolderListModel");
}
+
+ void unregisterTypes() override {
+ QQmlMetaType::unregisterType(folderListModelId);
+ folderListModelId = -1;
+ }
+
+private:
+ int folderListModelId = -1;
};
//![class decl]
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index 772976d65a..e21a8d8f37 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -67,19 +67,20 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
- Q_PROPERTY(bool showFiles READ showFiles WRITE setShowFiles REVISION 1)
+ Q_PROPERTY(bool showFiles READ showFiles WRITE setShowFiles REVISION(2, 1))
Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
Q_PROPERTY(bool showDirsFirst READ showDirsFirst WRITE setShowDirsFirst)
Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
- Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION 1)
+ Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION(2, 1))
Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
- Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2)
+ Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION(2, 2))
Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 11)
- Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION 12)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION(2, 11))
+ Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION(2, 12))
//![class props]
QML_NAMED_ELEMENT(FolderListModel)
+ QML_ADDED_IN_VERSION(2, 0)
//![abslistmodel]
public:
QQuickFolderListModel(QObject *parent = nullptr);
@@ -164,8 +165,8 @@ public:
Q_SIGNALS:
void folderChanged();
void rowCountChanged() const;
- Q_REVISION(1) void countChanged() const;
- Q_REVISION(11) void statusChanged();
+ Q_REVISION(2, 1) void countChanged() const;
+ Q_REVISION(2, 11) void statusChanged();
//![notifier]
//![class end]
diff --git a/src/imports/labsanimation/CMakeLists.txt b/src/imports/labsanimation/CMakeLists.txt
new file mode 100644
index 0000000000..a4de38267e
--- /dev/null
+++ b/src/imports/labsanimation/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Generated from labsanimation.pro.
+
+#####################################################################
+## labsanimationplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(labsanimationplugin
+ URI "Qt.labs.animation"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QtLabsAnimationPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qquickboundaryrule.cpp qquickboundaryrule_p.h
+ PUBLIC_LIBRARIES
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:labsanimation.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/animation"
diff --git a/src/imports/labsanimation/labsanimation.pro b/src/imports/labsanimation/labsanimation.pro
index f64ae775c6..5fd8ff25a7 100644
--- a/src/imports/labsanimation/labsanimation.pro
+++ b/src/imports/labsanimation/labsanimation.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = labsanimationplugin
TARGETPATH = Qt/labs/animation
-IMPORT_VERSION = 1.0
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
qquickboundaryrule.cpp \
diff --git a/src/imports/labsanimation/qquickboundaryrule_p.h b/src/imports/labsanimation/qquickboundaryrule_p.h
index 1681558304..33cf0bb094 100644
--- a/src/imports/labsanimation/qquickboundaryrule_p.h
+++ b/src/imports/labsanimation/qquickboundaryrule_p.h
@@ -78,6 +78,7 @@ class QQuickBoundaryRule : public QObject, public QQmlPropertyValueInterceptor
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
Q_PROPERTY(int returnDuration READ returnDuration WRITE setReturnDuration NOTIFY returnDurationChanged)
QML_NAMED_ELEMENT(BoundaryRule)
+ QML_ADDED_IN_VERSION(1, 0)
public:
enum OvershootFilter {
diff --git a/src/imports/labsmodels/CMakeLists.txt b/src/imports/labsmodels/CMakeLists.txt
new file mode 100644
index 0000000000..efd3339e2f
--- /dev/null
+++ b/src/imports/labsmodels/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Generated from labsmodels.pro.
+
+#####################################################################
+## labsmodelsplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(labsmodelsplugin
+ URI "Qt.labs.qmlmodels"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QtQmlLabsModelsPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:labsmodels.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/qmlmodels"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(labsmodelsplugin CONDITION QT_FEATURE_qml_table_model
+ SOURCES
+ qqmltablemodel.cpp qqmltablemodel_p.h
+ qqmltablemodelcolumn.cpp qqmltablemodelcolumn_p.h
+)
+
+qt_extend_target(labsmodelsplugin CONDITION QT_FEATURE_qml_delegate_model
+ SOURCES
+ qqmldelegatecomponent.cpp qqmldelegatecomponent_p.h
+)
diff --git a/src/imports/labsmodels/labsmodels.pro b/src/imports/labsmodels/labsmodels.pro
index 13468348cb..9fc52ce9cc 100644
--- a/src/imports/labsmodels/labsmodels.pro
+++ b/src/imports/labsmodels/labsmodels.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = labsmodelsplugin
TARGETPATH = Qt/labs/qmlmodels
-IMPORT_VERSION = 1.0
+QML_IMPORT_VERSION = $$QT_VERSION
QT = qml-private qmlmodels-private
diff --git a/src/imports/labsmodels/qqmldelegatecomponent_p.h b/src/imports/labsmodels/qqmldelegatecomponent_p.h
index 8473831b1d..9655d1baf9 100644
--- a/src/imports/labsmodels/qqmldelegatecomponent_p.h
+++ b/src/imports/labsmodels/qqmldelegatecomponent_p.h
@@ -69,6 +69,8 @@ class QQmlDelegateChoice : public QObject
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
QML_NAMED_ELEMENT(DelegateChoice)
+ QML_ADDED_IN_VERSION(1, 0)
+
public:
QVariant roleValue() const;
void setRoleValue(const QVariant &roleValue);
@@ -106,6 +108,7 @@ class QQmlDelegateChooser : public QQmlAbstractDelegateComponent
Q_PROPERTY(QQmlListProperty<QQmlDelegateChoice> choices READ choices CONSTANT)
Q_CLASSINFO("DefaultProperty", "choices")
QML_NAMED_ELEMENT(DelegateChooser)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QString role() const { return m_role; }
diff --git a/src/imports/labsmodels/qqmltablemodel_p.h b/src/imports/labsmodels/qqmltablemodel_p.h
index 75e2768849..ae46cbe35c 100644
--- a/src/imports/labsmodels/qqmltablemodel_p.h
+++ b/src/imports/labsmodels/qqmltablemodel_p.h
@@ -74,6 +74,7 @@ class QQmlTableModel : public QAbstractTableModel, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_CLASSINFO("DefaultProperty", "columns")
QML_NAMED_ELEMENT(TableModel)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QQmlTableModel(QObject *parent = nullptr);
diff --git a/src/imports/labsmodels/qqmltablemodelcolumn_p.h b/src/imports/labsmodels/qqmltablemodelcolumn_p.h
index a18f21ab4f..2860a915cc 100644
--- a/src/imports/labsmodels/qqmltablemodelcolumn_p.h
+++ b/src/imports/labsmodels/qqmltablemodelcolumn_p.h
@@ -97,6 +97,7 @@ class QQmlTableModelColumn : public QObject
Q_PROPERTY(QJSValue sizeHint READ sizeHint WRITE setSizeHint NOTIFY sizeHintChanged FINAL)
Q_PROPERTY(QJSValue setSizeHint READ getSetSizeHint WRITE setSetSizeHint NOTIFY setSizeHintChanged FINAL)
QML_NAMED_ELEMENT(TableModelColumn)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QQmlTableModelColumn(QObject *parent = nullptr);
diff --git a/src/imports/layouts/CMakeLists.txt b/src/imports/layouts/CMakeLists.txt
new file mode 100644
index 0000000000..ffde82d340
--- /dev/null
+++ b/src/imports/layouts/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Generated from layouts.pro.
+
+#####################################################################
+## qquicklayoutsplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qquicklayoutsplugin
+ URI "QtQuick.Layouts"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQuickLayoutsPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qquickgridlayoutengine.cpp qquickgridlayoutengine_p.h
+ qquicklayout.cpp qquicklayout_p.h
+ qquicklayoutstyleinfo.cpp qquicklayoutstyleinfo_p.h
+ qquicklinearlayout.cpp qquicklinearlayout_p.h
+ qquickstacklayout.cpp qquickstacklayout_p.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:layouts.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick/Layouts"
diff --git a/src/imports/layouts/layouts.pro b/src/imports/layouts/layouts.pro
index ea7940e4ad..1ae269da32 100644
--- a/src/imports/layouts/layouts.pro
+++ b/src/imports/layouts/layouts.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qquicklayoutsplugin
TARGETPATH = QtQuick/Layouts
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT *= qml-private quick-private gui-private core-private
diff --git a/src/imports/layouts/qquickgridlayoutengine_p.h b/src/imports/layouts/qquickgridlayoutengine_p.h
index c53be89477..5529d1049c 100644
--- a/src/imports/layouts/qquickgridlayoutengine_p.h
+++ b/src/imports/layouts/qquickgridlayoutengine_p.h
@@ -95,7 +95,7 @@ public:
void invalidate()
{
- quickLayoutDebug() << "engine::invalidate()";
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutItem::invalidate()";
sizeHintCacheDirty = true;
}
@@ -112,8 +112,9 @@ public:
const QSizeF newSize = r.size();
m_item->setPosition(r.topLeft());
if (newSize == oldSize) {
+ // We need to enforce a rearrange when the geometry is the same
if (QQuickLayout *lay = qobject_cast<QQuickLayout *>(m_item)) {
- if (lay->arrangementIsDirty())
+ if (lay->invalidatedArrangement())
lay->rearrange(newSize);
}
} else {
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 33c27bd928..9e981f7de6 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -41,6 +41,7 @@
#include <QEvent>
#include <QtCore/qcoreapplication.h>
#include <QtCore/private/qnumeric_p.h>
+#include <QtCore/qstack.h>
#include <QtCore/qmath.h>
#include <QtQml/qqmlinfo.h>
#include <limits>
@@ -90,6 +91,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQuickLayouts, "qt.quick.layouts")
+
QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent)
: QObject(parent),
m_minimumWidth(0),
@@ -378,7 +381,7 @@ void QQuickLayoutAttached::setRow(int row)
{
if (row >= 0 && row != m_row) {
m_row = row;
- repopulateLayout();
+ invalidateItem();
emit rowChanged();
}
}
@@ -399,7 +402,7 @@ void QQuickLayoutAttached::setColumn(int column)
{
if (column >= 0 && column != m_column) {
m_column = column;
- repopulateLayout();
+ invalidateItem();
emit columnChanged();
}
}
@@ -626,7 +629,7 @@ void QQuickLayoutAttached::setRowSpan(int span)
{
if (span != m_rowSpan) {
m_rowSpan = span;
- repopulateLayout();
+ invalidateItem();
emit rowSpanChanged();
}
}
@@ -646,7 +649,7 @@ void QQuickLayoutAttached::setColumnSpan(int span)
{
if (span != m_columnSpan) {
m_columnSpan = span;
- repopulateLayout();
+ invalidateItem();
emit columnSpanChanged();
}
}
@@ -667,20 +670,12 @@ qreal QQuickLayoutAttached::sizeHint(Qt::SizeHint which, Qt::Orientation orienta
void QQuickLayoutAttached::invalidateItem()
{
- if (!m_changesNotificationEnabled)
- return;
- quickLayoutDebug() << "QQuickLayoutAttached::invalidateItem";
+ qCDebug(lcQuickLayouts) << "QQuickLayoutAttached::invalidateItem";
if (QQuickLayout *layout = parentLayout()) {
layout->invalidate(item());
}
}
-void QQuickLayoutAttached::repopulateLayout()
-{
- if (QQuickLayout *layout = parentLayout())
- layout->updateLayoutItems();
-}
-
QQuickLayout *QQuickLayoutAttached::parentLayout() const
{
QQuickItem *parentItem = item();
@@ -698,10 +693,41 @@ QQuickItem *QQuickLayoutAttached::item() const
return qobject_cast<QQuickItem *>(parent());
}
+qreal QQuickLayoutPrivate::getImplicitWidth() const
+{
+ Q_Q(const QQuickLayout);
+ if (q->invalidated()) {
+ QQuickLayoutPrivate *that = const_cast<QQuickLayoutPrivate*>(this);
+ that->implicitWidth = q->sizeHint(Qt::PreferredSize).width();
+ }
+ return implicitWidth;
+}
+
+qreal QQuickLayoutPrivate::getImplicitHeight() const
+{
+ Q_Q(const QQuickLayout);
+ if (q->invalidated()) {
+ QQuickLayoutPrivate *that = const_cast<QQuickLayoutPrivate*>(this);
+ that->implicitHeight = q->sizeHint(Qt::PreferredSize).height();
+ }
+ return implicitHeight;
+}
+
+void QQuickLayoutPrivate::applySizeHints() const {
+ Q_Q(const QQuickLayout);
+ QQuickLayout *that = const_cast<QQuickLayout*>(q);
+ QQuickLayoutAttached *info = attachedLayoutObject(that, true);
+
+ const QSizeF min = q->sizeHint(Qt::MinimumSize);
+ const QSizeF max = q->sizeHint(Qt::MaximumSize);
+ const QSizeF pref = q->sizeHint(Qt::PreferredSize);
+ info->setMinimumImplicitSize(min);
+ info->setMaximumImplicitSize(max);
+ that->setImplicitSize(pref.width(), pref.height());
+}
QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
: QQuickItem(dd, parent)
- , m_dirty(false)
, m_inUpdatePolish(false)
, m_polishInsideUpdatePolish(0)
{
@@ -730,47 +756,66 @@ QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object)
void QQuickLayout::updatePolish()
{
+ qCDebug(lcQuickLayouts) << "updatePolish() ENTERING" << this;
m_inUpdatePolish = true;
+
+ // Might have become "undirty" before we reach this updatePolish()
+ // (e.g. if somebody queried for implicitWidth it will immediately
+ // calculate size hints)
+ if (invalidated()) {
+ // Ensure that all invalidated layouts are synced and valid again. Since
+ // ensureLayoutItemsUpdated() will also call applySizeHints(), and sizeHint() will call its
+ // childrens sizeHint(), and sizeHint() will call ensureLayoutItemsUpdated(), this will be done
+ // recursive as we want.
+ // Note that we need to call ensureLayoutItemsUpdated() *before* we query width() and height(),
+ // because width()/height() might return their implicitWidth/implicitHeight (e.g. for a layout
+ // with no explicitly specified size, (nor anchors.fill: parent))
+ ensureLayoutItemsUpdated();
+ }
rearrange(QSizeF(width(), height()));
m_inUpdatePolish = false;
+ qCDebug(lcQuickLayouts) << "updatePolish() LEAVING" << this;
}
void QQuickLayout::componentComplete()
{
Q_D(QQuickLayout);
d->m_disableRearrange = true;
- QQuickItem::componentComplete(); // will call our geometryChanged(), (where isComponentComplete() == true)
+ QQuickItem::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true)
d->m_disableRearrange = false;
d->m_isReady = true;
}
void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
{
- if (m_dirty)
+ Q_D(QQuickLayout);
+ if (invalidated())
return;
- m_dirty = true;
+ qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate()" << this;
+ d->m_dirty = true;
+ d->m_dirtyArrangement = true;
if (!qobject_cast<QQuickLayout *>(parentItem())) {
- quickLayoutDebug() << "QQuickLayout::invalidate(), polish()";
if (m_inUpdatePolish)
++m_polishInsideUpdatePolish;
else
m_polishInsideUpdatePolish = 0;
- if (m_polishInsideUpdatePolish <= 2)
+ if (m_polishInsideUpdatePolish <= 2) {
// allow at most two consecutive loops in order to respond to height-for-width
// (e.g QQuickText changes implicitHeight when its width gets changed)
+ qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate(), polish()";
polish();
- else
+ } else {
qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations.";
+ }
}
}
bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const
{
- Q_D(const QQuickLayout);
bool ignoreItem = true;
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
if (childPrivate->explicitVisible) {
@@ -789,8 +834,6 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in
if (!ignoreItem && childPrivate->isTransparentForPositioner())
ignoreItem = true;
- if (ignoreItem)
- d->m_ignoredItems << child;
return ignoreItem;
}
@@ -801,6 +844,17 @@ void QQuickLayout::checkAnchors(QQuickItem *item) const
qmlWarning(item) << "Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead.";
}
+void QQuickLayout::ensureLayoutItemsUpdated() const
+{
+ Q_D(const QQuickLayout);
+ if (!invalidated())
+ return;
+ const_cast<QQuickLayout*>(this)->updateLayoutItems();
+ d->m_dirty = false;
+ d->applySizeHints();
+}
+
+
void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == ItemChildAddedChange) {
@@ -809,26 +863,28 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes);
d->m_hasItemChangeListeners = true;
+ qCDebug(lcQuickLayouts) << "ChildAdded" << item;
if (isReady())
- updateLayoutItems();
+ invalidate();
} else if (change == ItemChildRemovedChange) {
QQuickItem *item = value.item;
qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes);
+ qCDebug(lcQuickLayouts) << "ChildRemoved" << item;
if (isReady())
- updateLayoutItems();
+ invalidate();
}
QQuickItem::itemChange(change, value);
}
-void QQuickLayout::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickLayout::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickLayout);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
if (d->m_disableRearrange || !isReady() || !newGeometry.isValid())
return;
- quickLayoutDebug() << "QQuickStackLayout::geometryChanged" << newGeometry << oldGeometry;
+ qCDebug(lcQuickLayouts) << "QQuickLayout::geometryChange" << newGeometry << oldGeometry;
rearrange(newGeometry.size());
}
@@ -870,10 +926,20 @@ void QQuickLayout::deactivateRecur()
}
}
+bool QQuickLayout::invalidated() const
+{
+ return d_func()->m_dirty;
+}
+
+bool QQuickLayout::invalidatedArrangement() const
+{
+ return d_func()->m_dirtyArrangement;
+}
+
void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item)
{
Q_UNUSED(item);
- updateLayoutItems();
+ invalidate();
}
void QQuickLayout::itemImplicitWidthChanged(QQuickItem *item)
@@ -902,7 +968,7 @@ void QQuickLayout::itemVisibilityChanged(QQuickItem *item)
void QQuickLayout::rearrange(const QSizeF &/*size*/)
{
- m_dirty = false;
+ d_func()->m_dirtyArrangement = false;
}
@@ -1156,6 +1222,82 @@ QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item,
}
+void QQuickLayout::_q_dumpLayoutTree() const
+{
+ QString buf;
+ dumpLayoutTreeRecursive(0, buf);
+ qDebug("\n%s", qPrintable(buf));
+}
+void QQuickLayout::dumpLayoutTreeRecursive(int level, QString &buf) const
+{
+ auto formatLine = [&level](const char *fmt) {
+ QString ss(level *4, QLatin1Char(' '));
+ return QString::fromLatin1("%1%2\n").arg(ss).arg(fmt);
+ };
+
+ auto f2s = [](qreal f) {
+ return QString::number(f);
+ };
+ auto b2s = [](bool b) {
+ static const char *strBool[] = {"false", "true"};
+ return QLatin1String(strBool[int(b)]);
+ };
+
+ buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(this));
+ ++level;
+ buf += formatLine("// Effective calculated values:");
+ buf += formatLine("sizeHintDirty: %2").arg(invalidated());
+ QSizeF min = sizeHint(Qt::MinimumSize);
+ buf += formatLine("sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5);
+ QSizeF pref = sizeHint(Qt::PreferredSize);
+ buf += formatLine("sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5);
+ QSizeF max = sizeHint(Qt::MaximumSize);
+ buf += formatLine("sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5);
+
+ for (QQuickItem *item : childItems()) {
+ buf += QLatin1Char('\n');
+ if (QQuickLayout *childLayout = qobject_cast<QQuickLayout*>(item)) {
+ childLayout->dumpLayoutTreeRecursive(level, buf);
+ } else {
+ buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(item));
+ ++level;
+ if (item->implicitWidth() > 0)
+ buf += formatLine("implicitWidth: %1").arg(f2s(item->implicitWidth()));
+ if (item->implicitHeight() > 0)
+ buf += formatLine("implicitHeight: %1").arg(f2s(item->implicitHeight()));
+ QSizeF min;
+ QSizeF pref;
+ QSizeF max;
+ QQuickLayoutAttached *info = attachedLayoutObject(item, false);
+ if (info) {
+ min = QSizeF(info->minimumWidth(), info->minimumHeight());
+ pref = QSizeF(info->preferredWidth(), info->preferredHeight());
+ max = QSizeF(info->maximumWidth(), info->maximumHeight());
+ if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize))
+ buf += formatLine("Layout.minimumWidth: %1").arg(f2s(min.width()));
+ if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize))
+ buf += formatLine("Layout.minimumHeight: %1").arg(f2s(min.height()));
+ if (pref.width() >= 0)
+ buf += formatLine("Layout.preferredWidth: %1").arg(f2s(pref.width()));
+ if (pref.height() >= 0)
+ buf += formatLine("Layout.preferredHeight: %1").arg(f2s(pref.height()));
+ if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize))
+ buf += formatLine("Layout.maximumWidth: %1").arg(f2s(max.width()));
+ if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize))
+ buf += formatLine("Layout.maximumHeight: %1").arg(f2s(max.height()));
+
+ if (info->isFillWidthSet())
+ buf += formatLine("Layout.fillWidth: %1").arg(b2s(info->fillWidth()));
+ if (info->isFillHeightSet())
+ buf += formatLine("Layout.fillHeight: %1").arg(b2s(info->fillHeight()));
+ }
+ --level;
+ buf += formatLine("}");
+ }
+ }
+ --level;
+ buf += formatLine("}");
+}
QT_END_NAMESPACE
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index 3322d03636..77dfb446c8 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -49,12 +49,7 @@
QT_BEGIN_NAMESPACE
class QQuickLayoutAttached;
-
-#if 0 && !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_OUTPUT)
-# define quickLayoutDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug
-#else
-# define quickLayoutDebug QT_NO_QDEBUG_MACRO
-#endif
+Q_DECLARE_LOGGING_CATEGORY(lcQuickLayouts)
class QQuickLayoutPrivate;
class QQuickLayout : public QQuickItem, public QQuickItemChangeListener
@@ -62,6 +57,7 @@ class QQuickLayout : public QQuickItem, public QQuickItemChangeListener
{
Q_OBJECT
QML_NAMED_ELEMENT(Layout)
+ QML_ADDED_IN_VERSION(1, 0)
QML_UNCREATABLE("Do not create objects of type Layout.")
QML_ATTACHED(QQuickLayoutAttached)
@@ -84,13 +80,13 @@ public:
virtual void setAlignment(QQuickItem *item, Qt::Alignment align) = 0;
virtual void invalidate(QQuickItem * childItem = 0);
virtual void updateLayoutItems() = 0;
+ void ensureLayoutItemsUpdated() const;
// iterator
virtual QQuickItem *itemAt(int index) const = 0;
virtual int itemCount() const = 0;
virtual void rearrange(const QSizeF &);
- bool arrangementIsDirty() const { return m_dirty; }
static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight);
static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info);
@@ -98,10 +94,12 @@ public:
void checkAnchors(QQuickItem *item) const;
void itemChange(ItemChange change, const ItemChangeData &value) override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
bool isReady() const;
void deactivateRecur();
+ bool invalidated() const;
+ bool invalidatedArrangement() const;
/* QQuickItemChangeListener */
void itemSiblingOrderChanged(QQuickItem *item) override;
@@ -110,6 +108,9 @@ public:
void itemDestroyed(QQuickItem *item) override;
void itemVisibilityChanged(QQuickItem *item) override;
+ Q_INVOKABLE void _q_dumpLayoutTree() const;
+ void dumpLayoutTreeRecursive(int level, QString &buf) const;
+
protected:
void updatePolish() override;
@@ -123,7 +124,6 @@ protected slots:
void invalidateSenderItem();
private:
- unsigned m_dirty : 1;
unsigned m_inUpdatePolish : 1;
unsigned m_polishInsideUpdatePolish : 2;
@@ -137,9 +137,26 @@ class QQuickLayoutPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickLayout)
public:
- QQuickLayoutPrivate() : m_isReady(false), m_disableRearrange(true), m_hasItemChangeListeners(false) {}
+ QQuickLayoutPrivate() : m_dirty(true), m_dirtyArrangement(true), m_isReady(false), m_disableRearrange(true), m_hasItemChangeListeners(false) {}
+
+ qreal getImplicitWidth() const override;
+ qreal getImplicitHeight() const override;
+
+ void applySizeHints() const;
protected:
+ /* m_dirty == true means that something in the layout was changed,
+ but its state has not been synced to the internal grid layout engine. It is usually:
+ 1. A child item was added or removed from the layout (or made visible/invisble)
+ 2. A child item got one of its size hints changed
+ */
+ mutable unsigned m_dirty : 1;
+ /* m_dirtyArrangement == true means that the layout still needs a rearrange despite that
+ * m_dirty == false. This is only used for the case that a layout has been invalidated,
+ * but its new size is the same as the old size (in that case the child layout won't get
+ * a geometryChanged() notification, which rearrange() usually reacts to)
+ */
+ mutable unsigned m_dirtyArrangement : 1;
unsigned m_isReady : 1;
unsigned m_disableRearrange : 1;
unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners...
@@ -287,7 +304,6 @@ signals:
private:
void invalidateItem();
- void repopulateLayout();
QQuickLayout *parentLayout() const;
QQuickItem *item() const;
private:
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 1004ed8593..7626506c75 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -254,6 +254,7 @@ void QQuickGridLayoutBase::setOrientation(Qt::Orientation orientation)
QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const
{
Q_D(const QQuickGridLayoutBase);
+ ensureLayoutItemsUpdated();
return d->engine.sizeHint(whichSizeHint, QSizeF(), d->styleInfo);
}
@@ -315,14 +316,27 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase()
void QQuickGridLayoutBase::componentComplete()
{
- quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::componentComplete()" << parent();
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::componentComplete()" << this << parent();
QQuickLayout::componentComplete();
- updateLayoutItems();
+
+ /* The layout is invalid when it is constructed, but during construction of the layout and
+ its children (in the "static/from QML" case which this is trying to cover) things
+ change and as a consequence invalidate() and ensureLayoutItemsUpdated() might be called.
+ As soon as ensureLayoutItemsUpdated() is called it will set d->dirty = false.
+ However, a subsequent invalidate() will return early if the component is not completed
+ because it knows that componentComplete() will take care of doing the proper layouting
+ (so it won't set d->dirty = true). When we then call ensureLayoutItemsUpdated() again here
+ it sees that its not dirty and assumes everything up-to-date. For those cases we therefore
+ need to call invalidate() in advance
+ */
+ invalidate();
+ ensureLayoutItemsUpdated();
QQuickItem *par = parentItem();
if (qobject_cast<QQuickLayout*>(par))
return;
rearrange(QSizeF(width(), height()));
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::componentComplete(). COMPLETED" << this << parent();
}
/*
@@ -342,13 +356,12 @@ void QQuickGridLayoutBase::componentComplete()
}
}
- 1. l2->invalidateChildItem(a) is called on l2, where item refers to "a".
+ 1. l2->invalidate(a) is called on l2, where item refers to "a".
(this will dirty the cached size hints of item "a")
- 2. l2->invalidate() is called
- this will :
+ 2. The layout engine will invalidate:
i) invalidate the layout engine
- ii) dirty the cached size hints of item "l2" (by calling parentLayout()->invalidateChildItem
-
+ ii) dirty the cached size hints of item "l2" (by calling parentLayout()->invalidate(l2)
+ The recursion continues to the topmost layout
*/
/*!
\internal
@@ -363,43 +376,29 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem)
Q_D(QQuickGridLayoutBase);
if (!isReady())
return;
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate()" << this << ", invalidated:" << invalidated();
+ if (invalidated()) {
+ return;
+ }
+ qCDebug(lcQuickLayouts) << "d->m_rearranging:" << d->m_rearranging;
if (d->m_rearranging) {
d->m_invalidateAfterRearrange << childItem;
return;
}
- quickLayoutDebug() << "QQuickGridLayoutBase::invalidate()";
-
if (childItem) {
if (QQuickGridLayoutItem *layoutItem = d->engine.findLayoutItem(childItem))
layoutItem->invalidate();
- if (d->m_ignoredItems.contains(childItem)) {
- updateLayoutItems();
- return;
- }
}
// invalidate engine
d->engine.invalidate();
- QQuickLayout::invalidate(this);
+ qCDebug(lcQuickLayouts) << "calling QQuickLayout::invalidate();";
+ QQuickLayout::invalidate();
- QQuickLayoutAttached *info = attachedLayoutObject(this);
-
- const QSizeF min = sizeHint(Qt::MinimumSize);
- const QSizeF pref = sizeHint(Qt::PreferredSize);
- const QSizeF max = sizeHint(Qt::MaximumSize);
-
- const bool old = info->setChangesNotificationEnabled(false);
- info->setMinimumImplicitSize(min);
- info->setMaximumImplicitSize(max);
- info->setChangesNotificationEnabled(old);
- if (pref.width() == implicitWidth() && pref.height() == implicitHeight()) {
- // In case setImplicitSize does not emit implicit{Width|Height}Changed
- if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem()))
- parentLayout->invalidate(this);
- } else {
- setImplicitSize(pref.width(), pref.height());
- }
+ if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem()))
+ parentLayout->invalidate(this);
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::invalidate() LEAVING" << this;
}
void QQuickGridLayoutBase::updateLayoutItems()
@@ -412,23 +411,25 @@ void QQuickGridLayoutBase::updateLayoutItems()
return;
}
- quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems";
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::updateLayoutItems ENTERING" << this;
d->engine.deleteItems();
insertLayoutItems();
-
- invalidate();
- quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems LEAVING";
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::updateLayoutItems() LEAVING" << this;
}
QQuickItem *QQuickGridLayoutBase::itemAt(int index) const
{
Q_D(const QQuickGridLayoutBase);
+ qCDebug(lcQuickLayouts).nospace() << "QQuickGridLayoutBase::itemAt(" << index << ")";
+ ensureLayoutItemsUpdated();
+ qCDebug(lcQuickLayouts).nospace() << "QQuickGridLayoutBase::itemAt(" << index << ") LEAVING";
return static_cast<QQuickGridLayoutItem*>(d->engine.itemAt(index))->layoutItem();
}
int QQuickGridLayoutBase::itemCount() const
{
Q_D(const QQuickGridLayoutBase);
+ ensureLayoutItemsUpdated();
return d->engine.itemCount();
}
@@ -445,7 +446,7 @@ void QQuickGridLayoutBase::itemDestroyed(QQuickItem *item)
if (!isReady())
return;
Q_D(QQuickGridLayoutBase);
- quickLayoutDebug() << "QQuickGridLayoutBase::itemDestroyed";
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::itemDestroyed";
if (QQuickGridLayoutItem *gridItem = d->engine.findLayoutItem(item)) {
removeGridItem(gridItem);
delete gridItem;
@@ -459,8 +460,8 @@ void QQuickGridLayoutBase::itemVisibilityChanged(QQuickItem *item)
if (!isReady())
return;
- quickLayoutDebug() << "QQuickGridLayoutBase::itemVisibilityChanged";
- updateLayoutItems();
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::itemVisibilityChanged()";
+ invalidate(item);
}
void QQuickGridLayoutBase::rearrange(const QSizeF &size)
@@ -469,6 +470,9 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
if (!isReady())
return;
+ ensureLayoutItemsUpdated();
+
+ qCDebug(lcQuickLayouts) << "QQuickGridLayoutBase::rearrange" << d->m_recurRearrangeCounter << this;
const auto refCounter = qScopeGuard([&d] {
--(d->m_recurRearrangeCounter);
});
@@ -480,7 +484,7 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
}
d->m_rearranging = true;
- quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
+ qCDebug(lcQuickLayouts) << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
Qt::LayoutDirection visualDir = effectiveLayoutDirection();
d->engine.setVisualDirection(visualDir);
@@ -502,7 +506,7 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
d->m_invalidateAfterRearrange.clear();
if (d->m_updateAfterRearrange) {
- updateLayoutItems();
+ ensureLayoutItemsUpdated();
d->m_updateAfterRearrange = false;
}
}
@@ -582,7 +586,7 @@ void QQuickGridLayout::setColumns(int columns)
if (d->columns == columns)
return;
d->columns = columns;
- updateLayoutItems();
+ invalidate();
emit columnsChanged();
}
@@ -605,7 +609,7 @@ void QQuickGridLayout::setRows(int rows)
if (d->rows == rows)
return;
d->rows = rows;
- updateLayoutItems();
+ invalidate();
emit rowsChanged();
}
@@ -643,7 +647,7 @@ void QQuickGridLayout::setFlow(QQuickGridLayout::Flow flow)
return;
d->flow = flow;
// If flow is changed, the layout needs to be repopulated
- updateLayoutItems();
+ invalidate();
emit flowChanged();
}
@@ -664,7 +668,6 @@ void QQuickGridLayout::insertLayoutItems()
if (flowBound < 0)
flowBound = std::numeric_limits<int>::max();
- d->m_ignoredItems.clear();
QSizeF sizeHints[Qt::NSizeHints];
const auto items = childItems();
for (QQuickItem *child : items) {
@@ -788,7 +791,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:
@@ -805,7 +808,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:
@@ -852,7 +855,6 @@ void QQuickLinearLayout::setSpacing(qreal space)
void QQuickLinearLayout::insertLayoutItems()
{
Q_D(QQuickLinearLayout);
- d->m_ignoredItems.clear();
QSizeF sizeHints[Qt::NSizeHints];
const auto items = childItems();
for (QQuickItem *child : items) {
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index f36f99741d..1780ba8807 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -56,9 +56,10 @@ class QQuickGridLayoutBase : public QQuickLayout
{
Q_OBJECT
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection
+ NOTIFY layoutDirectionChanged REVISION(1, 1))
QML_ANONYMOUS
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(1, 1)
public:
@@ -92,7 +93,7 @@ protected:
virtual void insertLayoutItems() {}
signals:
- Q_REVISION(1) void layoutDirectionChanged();
+ Q_REVISION(1, 1) void layoutDirectionChanged();
private:
void removeGridItem(QGridLayoutItem *gridItem);
@@ -145,6 +146,7 @@ class QQuickGridLayout : public QQuickGridLayoutBase
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
QML_NAMED_ELEMENT(GridLayout)
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit QQuickGridLayout(QQuickItem *parent = 0);
qreal columnSpacing() const;
@@ -229,6 +231,7 @@ class QQuickRowLayout : public QQuickLinearLayout
{
Q_OBJECT
QML_NAMED_ELEMENT(RowLayout)
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit QQuickRowLayout(QQuickItem *parent = 0)
@@ -245,6 +248,7 @@ class QQuickColumnLayout : public QQuickLinearLayout
{
Q_OBJECT
QML_NAMED_ELEMENT(ColumnLayout)
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit QQuickColumnLayout(QQuickItem *parent = 0)
diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp
index 4c1d611409..3a7e28789d 100644
--- a/src/imports/layouts/qquickstacklayout.cpp
+++ b/src/imports/layouts/qquickstacklayout.cpp
@@ -38,8 +38,11 @@
****************************************************************************/
#include "qquickstacklayout_p.h"
+
#include <limits>
+#include <QtQml/qqmlinfo.h>
+
/*!
\qmltype StackLayout
\instantiates QQuickStackLayout
@@ -99,6 +102,12 @@
QT_BEGIN_NAMESPACE
+static QQuickStackLayoutAttached *attachedStackLayoutObject(QQuickItem *item, bool create = false)
+{
+ return static_cast<QQuickStackLayoutAttached*>(
+ qmlAttachedPropertiesObject<QQuickStackLayout>(item, create));
+}
+
QQuickStackLayout::QQuickStackLayout(QQuickItem *parent) :
QQuickLayout(*new QQuickStackLayoutPrivate, parent)
{
@@ -114,6 +123,7 @@ QQuickStackLayout::QQuickStackLayout(QQuickItem *parent) :
int QQuickStackLayout::count() const
{
Q_D(const QQuickStackLayout);
+ ensureLayoutItemsUpdated();
return d->count;
}
@@ -126,26 +136,42 @@ int QQuickStackLayout::count() const
int QQuickStackLayout::currentIndex() const
{
Q_D(const QQuickStackLayout);
+ ensureLayoutItemsUpdated();
return d->currentIndex;
}
void QQuickStackLayout::setCurrentIndex(int index)
{
Q_D(QQuickStackLayout);
- if (index != d->currentIndex) {
- QQuickItem *prev = itemAt(d->currentIndex);
- QQuickItem *next = itemAt(index);
- d->currentIndex = index;
- d->explicitCurrentIndex = true;
- if (prev)
- prev->setVisible(false);
- if (next)
- next->setVisible(true);
-
- if (isComponentComplete()) {
- rearrange(QSizeF(width(), height()));
- emit currentIndexChanged();
- }
+ ensureLayoutItemsUpdated();
+ if (index == d->currentIndex)
+ return;
+
+ QQuickItem *prev = itemAt(d->currentIndex);
+ QQuickItem *next = itemAt(index);
+ d->currentIndex = index;
+ d->explicitCurrentIndex = true;
+ if (prev)
+ prev->setVisible(false);
+ if (next)
+ next->setVisible(true);
+
+ if (isComponentComplete()) {
+ rearrange(QSizeF(width(), height()));
+ emit currentIndexChanged();
+ }
+
+ // Update attached properties after emitting currentIndexChanged()
+ // to maintain a more sensible emission order.
+ if (prev) {
+ auto stackLayoutAttached = attachedStackLayoutObject(prev);
+ if (stackLayoutAttached)
+ stackLayoutAttached->setIsCurrentItem(false);
+ }
+ if (next) {
+ auto stackLayoutAttached = attachedStackLayoutObject(next);
+ if (stackLayoutAttached)
+ stackLayoutAttached->setIsCurrentItem(true);
}
}
@@ -153,7 +179,7 @@ void QQuickStackLayout::componentComplete()
{
QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true)
- updateLayoutItems();
+ ensureLayoutItemsUpdated();
QQuickItem *par = parentItem();
if (qobject_cast<QQuickLayout*>(par))
@@ -162,8 +188,28 @@ void QQuickStackLayout::componentComplete()
rearrange(QSizeF(width(), height()));
}
+void QQuickStackLayout::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
+{
+ QQuickLayout::itemChange(change, value);
+
+ if (change == ItemChildRemovedChange) {
+ QQuickItem *item = value.item;
+ auto stackLayoutAttached = attachedStackLayoutObject(item);
+ if (stackLayoutAttached) {
+ stackLayoutAttached->setLayout(nullptr);
+ stackLayoutAttached->setIndex(-1);
+ stackLayoutAttached->setIsCurrentItem(false);
+ }
+ invalidate();
+ } else if (change == ItemChildAddedChange) {
+ invalidate();
+ }
+}
+
QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const
{
+ Q_D(const QQuickStackLayout);
+ ensureLayoutItemsUpdated();
QSizeF &askingFor = m_cachedSizeHints[whichSizeHint];
if (!askingFor.isValid()) {
QSizeF &minS = m_cachedSizeHints[Qt::MinimumSize];
@@ -186,11 +232,13 @@ QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const
// Not sure how descent makes sense here...
}
}
+ d->m_dirty = false;
return askingFor;
}
int QQuickStackLayout::indexOf(QQuickItem *childItem) const
{
+ ensureLayoutItemsUpdated();
if (childItem) {
int indexOfItem = 0;
const auto items = childItems();
@@ -205,6 +253,11 @@ int QQuickStackLayout::indexOf(QQuickItem *childItem) const
return -1;
}
+QQuickStackLayoutAttached *QQuickStackLayout::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickStackLayoutAttached(object);
+}
+
QQuickItem *QQuickStackLayout::itemAt(int index) const
{
const auto items = childItems();
@@ -237,13 +290,6 @@ void QQuickStackLayout::setAlignment(QQuickItem * /*item*/, Qt::Alignment /*alig
void QQuickStackLayout::invalidate(QQuickItem *childItem)
{
- Q_D(QQuickStackLayout);
- if (d->m_ignoredItems.contains(childItem)) {
- // If an invalid item gets a valid size, it should be included, as it was added to the layout
- updateLayoutItems();
- return;
- }
-
const int indexOfChild = indexOf(childItem);
if (indexOfChild >= 0 && indexOfChild < m_cachedItemSizeHints.count()) {
m_cachedItemSizeHints[indexOfChild].min() = QSizeF();
@@ -255,23 +301,8 @@ void QQuickStackLayout::invalidate(QQuickItem *childItem)
m_cachedSizeHints[i] = QSizeF();
QQuickLayout::invalidate(this);
- QQuickLayoutAttached *info = attachedLayoutObject(this);
-
- const QSizeF min = sizeHint(Qt::MinimumSize);
- const QSizeF pref = sizeHint(Qt::PreferredSize);
- const QSizeF max = sizeHint(Qt::MaximumSize);
-
- const bool old = info->setChangesNotificationEnabled(false);
- info->setMinimumImplicitSize(min);
- info->setMaximumImplicitSize(max);
- info->setChangesNotificationEnabled(old);
- if (pref.width() == implicitWidth() && pref.height() == implicitHeight()) {
- // In case setImplicitSize does not emit implicit{Width|Height}Changed
- if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem()))
- parentLayout->invalidate(this);
- } else {
- setImplicitSize(pref.width(), pref.height());
- }
+ if (QQuickLayout *parentLayout = qobject_cast<QQuickLayout *>(parentItem()))
+ parentLayout->invalidate(this);
}
void QQuickStackLayout::updateLayoutItems()
@@ -294,9 +325,14 @@ void QQuickStackLayout::updateLayoutItems()
QQuickItem *child = itemAt(i);
checkAnchors(child);
child->setVisible(d->currentIndex == i);
- }
- invalidate();
+ auto stackLayoutAttached = attachedStackLayoutObject(child);
+ if (stackLayoutAttached) {
+ stackLayoutAttached->setLayout(this);
+ stackLayoutAttached->setIndex(i);
+ stackLayoutAttached->setIsCurrentItem(d->currentIndex == i);
+ }
+ }
}
void QQuickStackLayout::rearrange(const QSizeF &newSize)
@@ -304,7 +340,9 @@ void QQuickStackLayout::rearrange(const QSizeF &newSize)
Q_D(QQuickStackLayout);
if (newSize.isNull() || !newSize.isValid())
return;
- (void)sizeHint(Qt::PreferredSize); // Make sure m_cachedItemSizeHints are valid
+
+ qCDebug(lcQuickLayouts) << "QQuickStackLayout::rearrange";
+ ensureLayoutItemsUpdated();
if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count())
return;
@@ -347,6 +385,105 @@ bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const
return ignored;
}
+QQuickStackLayoutAttached::QQuickStackLayoutAttached(QObject *object)
+{
+ auto item = qobject_cast<QQuickItem*>(object);
+ if (!item) {
+ qmlWarning(object) << "StackLayout must be attached to an Item";
+ return;
+ }
+
+ auto stackLayout = qobject_cast<QQuickStackLayout*>(item->parentItem());
+ if (!stackLayout) {
+ // It might not be a child of a StackLayout yet, and that's OK.
+ // The index will get set by updateLayoutItems() when it's reparented.
+ return;
+ }
+
+ if (!stackLayout->isComponentComplete()) {
+ // Don't try to get the index if the StackLayout itself hasn't loaded yet.
+ return;
+ }
+
+ // If we got this far, the item was added as a child to the StackLayout after it loaded.
+ const int index = stackLayout->indexOf(item);
+ setLayout(stackLayout);
+ setIndex(index);
+ setIsCurrentItem(stackLayout->currentIndex() == index);
+}
+
+/*!
+ \qmlattachedproperty int StackLayout::index
+
+ This attached property holds the index of each child item in the
+ \l StackLayout.
+
+ \sa isCurrentItem, layout
+
+ \since QtQuick.Layouts 1.15
+*/
+int QQuickStackLayoutAttached::index() const
+{
+ return m_index;
+}
+
+void QQuickStackLayoutAttached::setIndex(int index)
+{
+ if (index == m_index)
+ return;
+
+ m_index = index;
+ emit indexChanged();
+}
+
+/*!
+ \qmlattachedproperty bool StackLayout::isCurrentItem
+
+ This attached property is \c true if this child is the current item
+ in the \l StackLayout.
+
+ \sa index, layout
+
+ \since QtQuick.Layouts 1.15
+*/
+bool QQuickStackLayoutAttached::isCurrentItem() const
+{
+ return m_isCurrentItem;
+}
+
+void QQuickStackLayoutAttached::setIsCurrentItem(bool isCurrentItem)
+{
+ if (isCurrentItem == m_isCurrentItem)
+ return;
+
+ m_isCurrentItem = isCurrentItem;
+ emit isCurrentItemChanged();
+}
+
+/*!
+ \qmlattachedproperty StackLayout StackLayout::layout
+
+ This attached property holds the \l StackLayout that manages this child
+ item.
+
+ \sa index, isCurrentItem
+
+ \since QtQuick.Layouts 1.15
+*/
+QQuickStackLayout *QQuickStackLayoutAttached::layout() const
+{
+ return m_layout;
+}
+
+void QQuickStackLayoutAttached::setLayout(QQuickStackLayout *layout)
+{
+ if (layout == m_layout)
+ return;
+
+ m_layout = layout;
+ emit layoutChanged();
+}
+
QT_END_NAMESPACE
#include "moc_qquickstacklayout_p.cpp"
diff --git a/src/imports/layouts/qquickstacklayout_p.h b/src/imports/layouts/qquickstacklayout_p.h
index 537d54900f..b641376ed8 100644
--- a/src/imports/layouts/qquickstacklayout_p.h
+++ b/src/imports/layouts/qquickstacklayout_p.h
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
class QQuickStackLayoutPrivate;
+class QQuickStackLayoutAttached;
class QQuickStackLayout : public QQuickLayout
{
@@ -52,7 +53,8 @@ class QQuickStackLayout : public QQuickLayout
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
QML_NAMED_ELEMENT(StackLayout)
- QML_ADDED_IN_MINOR_VERSION(3)
+ QML_ADDED_IN_VERSION(1, 3)
+ QML_ATTACHED(QQuickStackLayoutAttached)
public:
explicit QQuickStackLayout(QQuickItem *parent = 0);
@@ -61,6 +63,7 @@ public:
void setCurrentIndex(int index);
void componentComplete() override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
QSizeF sizeHint(Qt::SizeHint whichSizeHint) const override;
void setAlignment(QQuickItem *item, Qt::Alignment align) override;
void invalidate(QQuickItem *childItem = 0) override;
@@ -72,7 +75,7 @@ public:
int itemCount() const override;
int indexOf(QQuickItem *item) const;
-
+ static QQuickStackLayoutAttached *qmlAttachedProperties(QObject *object);
signals:
void currentIndexChanged();
@@ -85,6 +88,8 @@ private:
bool shouldIgnoreItem(QQuickItem *item) const;
Q_DECLARE_PRIVATE(QQuickStackLayout)
+ friend class QQuickStackLayoutAttached;
+
QList<QQuickItem*> m_items;
typedef struct {
@@ -109,6 +114,36 @@ private:
bool explicitCurrentIndex;
};
+class QQuickStackLayoutAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int index READ index NOTIFY indexChanged)
+ Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY isCurrentItemChanged)
+ Q_PROPERTY(QQuickStackLayout *layout READ layout NOTIFY layoutChanged)
+
+public:
+ QQuickStackLayoutAttached(QObject *object);
+
+ int index() const;
+ void setIndex(int index);
+
+ bool isCurrentItem() const;
+ void setIsCurrentItem(bool isCurrentItem);
+
+ QQuickStackLayout *layout() const;
+ void setLayout(QQuickStackLayout *layout);
+
+signals:
+ void indexChanged();
+ void isCurrentItemChanged();
+ void layoutChanged();
+
+private:
+ int m_index = -1;
+ bool m_isCurrentItem = false;
+ QQuickStackLayout *m_layout = nullptr;
+};
+
QT_END_NAMESPACE
#endif // QQUICKSTACKLAYOUT_H
diff --git a/src/imports/localstorage/CMakeLists.txt b/src/imports/localstorage/CMakeLists.txt
new file mode 100644
index 0000000000..d3fd8ff290
--- /dev/null
+++ b/src/imports/localstorage/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Generated from localstorage.pro.
+
+#####################################################################
+## qmllocalstorageplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmllocalstorageplugin
+ URI "QtQuick.LocalStorage"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QQmlLocalStoragePlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qquicklocalstorage.cpp qquicklocalstorage_p.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+ Qt::Sql
+)
+
+#### Keys ignored in scope 1:.:.:localstorage.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# OTHER_FILES = "localstorage.json"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick/LocalStorage"
diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro
index a95fa04401..6dff4862c7 100644
--- a/src/imports/localstorage/localstorage.pro
+++ b/src/imports/localstorage/localstorage.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmllocalstorageplugin
TARGETPATH = QtQuick/LocalStorage
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT = sql qml-private core-private
diff --git a/src/imports/localstorage/qquicklocalstorage_p.h b/src/imports/localstorage/qquicklocalstorage_p.h
index d2ebc85ce9..f90d6bad28 100644
--- a/src/imports/localstorage/qquicklocalstorage_p.h
+++ b/src/imports/localstorage/qquicklocalstorage_p.h
@@ -61,6 +61,7 @@ class QQuickLocalStorage : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(LocalStorage)
+ QML_ADDED_IN_VERSION(2, 0)
QML_SINGLETON
public:
diff --git a/src/imports/models/CMakeLists.txt b/src/imports/models/CMakeLists.txt
new file mode 100644
index 0000000000..a6d4065202
--- /dev/null
+++ b/src/imports/models/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from models.pro.
+
+#####################################################################
+## modelsplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(modelsplugin
+ URI "QtQml.Models"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQmlModelsPlugin
+ SKIP_TYPE_REGISTRATION
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:models.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQml/Models"
diff --git a/src/imports/models/models.pro b/src/imports/models/models.pro
index fd13b12401..9a22049068 100644
--- a/src/imports/models/models.pro
+++ b/src/imports/models/models.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = modelsplugin
-TARGETPATH = QtQml/Models.2
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+TARGETPATH = QtQml/Models
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/imports/particles/CMakeLists.txt b/src/imports/particles/CMakeLists.txt
new file mode 100644
index 0000000000..6d5e71f7d1
--- /dev/null
+++ b/src/imports/particles/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Generated from particles.pro.
+
+#####################################################################
+## particlesplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(particlesplugin
+ URI "QtQuick.Particles"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QtQuick2ParticlesPlugin
+ SKIP_TYPE_REGISTRATION
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::QmlPrivate
+ Qt::QuickParticlesPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:particles.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick/Particles"
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
index 41146c75b0..c0f2f990b5 100644
--- a/src/imports/particles/particles.pro
+++ b/src/imports/particles/particles.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = particlesplugin
-TARGETPATH = QtQuick/Particles.2
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+TARGETPATH = QtQuick/Particles
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/imports/qtqml/.prev_CMakeLists.txt b/src/imports/qtqml/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..4e17431218
--- /dev/null
+++ b/src/imports/qtqml/.prev_CMakeLists.txt
@@ -0,0 +1,41 @@
+# Generated from qtqml.pro.
+
+set(module_dynamic_qml_imports
+ QtQml.Models
+)
+
+if (QT_FEATURE_qml_worker_script)
+ list(APPEND module_dynamic_qml_imports
+ QtQml.WorkerScript
+ )
+endif()
+
+#####################################################################
+## qmlplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlplugin
+ URI "QtQml"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQmlPlugin
+ SKIP_TYPE_REGISTRATION
+ IMPORTS ${module_dynamic_qml_imports}
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qtqml.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# DYNAMIC_QMLDIR = "module QtQml" "plugin qmlplugin" "classname QtQmlPlugin" "typeinfo plugins.qmltypes" "designersupported" "import QtQml.Models"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQml"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qtqml.pro:QT_FEATURE_qml_worker_script:
+# DYNAMIC_QMLDIR = "import QtQml.WorkerScript"
diff --git a/src/imports/qtqml/CMakeLists.txt b/src/imports/qtqml/CMakeLists.txt
new file mode 100644
index 0000000000..f50f2f69f5
--- /dev/null
+++ b/src/imports/qtqml/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Generated from qtqml.pro.
+
+set(module_dynamic_qml_imports
+ QtQml.Models
+)
+
+if (QT_FEATURE_qml_worker_script)
+ list(APPEND module_dynamic_qml_imports
+ QtQml.WorkerScript
+ )
+endif()
+
+#####################################################################
+## qmlplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlplugin
+ URI "QtQml"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQmlPlugin
+ SKIP_TYPE_REGISTRATION
+ IMPORTS ${module_dynamic_qml_imports}
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+ Qt::CorePrivate # special case
+)
+
+#### Keys ignored in scope 1:.:.:qtqml.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# DYNAMIC_QMLDIR = "module QtQml" "plugin qmlplugin" "classname QtQmlPlugin" "typeinfo plugins.qmltypes" "designersupported" "import QtQml.Models"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQml"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qtqml.pro:QT_FEATURE_qml_worker_script:
+# DYNAMIC_QMLDIR = "import QtQml.WorkerScript"
diff --git a/src/imports/qtqml/plugin.cpp b/src/imports/qtqml/plugin.cpp
index 854ef6d2e6..a32d86eeb1 100644
--- a/src/imports/qtqml/plugin.cpp
+++ b/src/imports/qtqml/plugin.cpp
@@ -40,10 +40,6 @@
#include <QtQml/private/qtqmlglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-#include <QtQmlModels/private/qqmlmodelsmodule_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
/*!
@@ -63,21 +59,6 @@ QT_BEGIN_NAMESPACE
*/
//![class decl]
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-class QtQmlPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-public:
- QtQmlPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
- {
- volatile auto registration = &qml_register_types_QtQml;
- Q_UNUSED(registration);
- }
-
- void registerTypes(const char *) override { QQmlModelsModule::registerQmlTypes(); }
-};
-#else
class QtQmlPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
@@ -89,7 +70,6 @@ public:
Q_UNUSED(registration);
}
};
-#endif
//![class decl]
QT_END_NAMESPACE
diff --git a/src/imports/qtqml/qmldir b/src/imports/qtqml/qmldir
deleted file mode 100644
index f6b51c7970..0000000000
--- a/src/imports/qtqml/qmldir
+++ /dev/null
@@ -1,4 +0,0 @@
-module QtQml
-plugin qmlplugin
-classname QtQmlPlugin
-typeinfo plugins.qmltypes
diff --git a/src/imports/qtqml/qtqml.pro b/src/imports/qtqml/qtqml.pro
index 7a5169b8fc..eac19954b6 100644
--- a/src/imports/qtqml/qtqml.pro
+++ b/src/imports/qtqml/qtqml.pro
@@ -1,7 +1,7 @@
TARGETPATH = QtQml
CXX_MODULE = qml
TARGET = qmlplugin
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
@@ -9,4 +9,15 @@ SOURCES += \
# In Qt6 we won't need qmlmodels-private here
QT = qml-private qmlmodels-private
+DYNAMIC_QMLDIR = \
+ "module QtQml" \
+ "plugin qmlplugin" \
+ "classname QtQmlPlugin" \
+ "typeinfo plugins.qmltypes" \
+ "designersupported" \
+ "import QtQml.Models"
+
+qtConfig(qml-worker-script): DYNAMIC_QMLDIR += \
+ "import QtQml.WorkerScript"
+
load(qml_plugin)
diff --git a/src/imports/qtquick2/CMakeLists.txt b/src/imports/qtquick2/CMakeLists.txt
new file mode 100644
index 0000000000..e007c476f8
--- /dev/null
+++ b/src/imports/qtquick2/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Generated from qtquick2.pro.
+
+#####################################################################
+## qtquick2plugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qtquick2plugin
+ URI "QtQuick"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQuick2Plugin
+ SKIP_TYPE_REGISTRATION
+ IMPORTS
+ QtQml
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qtquick2.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(qtquick2plugin CONDITION QT_FEATURE_qml_worker_script
+ PUBLIC_LIBRARIES
+ Qt::QmlWorkerScriptPrivate
+)
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index 20bc4a3cc0..dde0b7207a 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -38,14 +38,7 @@
****************************************************************************/
#include <QtQml/qqmlextensionplugin.h>
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-#include <QtQml/private/qqmlengine_p.h>
-#include <QtQmlModels/private/qqmlmodelsmodule_p.h>
-#if QT_CONFIG(qml_worker_script)
-#include <QtQmlWorkerScript/private/qqmlworkerscriptmodule_p.h>
-#endif
-#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#include <QtQml/QQmlEngine>
#include <private/qtquick2_p.h>
@@ -68,20 +61,14 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick"));
Q_UNUSED(uri);
moduleDefined = true;
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- QQmlEnginePrivate::registerQuickTypes();
- QQmlModelsModule::registerQuickTypes();
-#if QT_CONFIG(qml_worker_script)
- QQmlWorkerScriptModule::registerQuickTypes();
-#endif
-#endif
QQmlQtQuick2Module::defineModule();
}
- ~QtQuick2Plugin() override
+ void unregisterTypes() override
{
if (moduleDefined)
QQmlQtQuick2Module::undefineModule();
+ moduleDefined = false;
}
bool moduleDefined = false;
diff --git a/src/imports/qtquick2/qmldir b/src/imports/qtquick2/qmldir
index 8167e813df..d74aabd9e9 100644
--- a/src/imports/qtquick2/qmldir
+++ b/src/imports/qtquick2/qmldir
@@ -3,3 +3,4 @@ plugin qtquick2plugin
classname QtQuick2Plugin
typeinfo plugins.qmltypes
designersupported
+import QtQml
diff --git a/src/imports/qtquick2/qtquick2.pro b/src/imports/qtquick2/qtquick2.pro
index 8543049ead..35430d0638 100644
--- a/src/imports/qtquick2/qtquick2.pro
+++ b/src/imports/qtquick2/qtquick2.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qtquick2plugin
-TARGETPATH = QtQuick.2
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+TARGETPATH = QtQuick
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/imports/settings/CMakeLists.txt b/src/imports/settings/CMakeLists.txt
new file mode 100644
index 0000000000..0243e2cf8f
--- /dev/null
+++ b/src/imports/settings/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Generated from settings.pro.
+
+#####################################################################
+## qmlsettingsplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlsettingsplugin
+ URI "Qt.labs.settings"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QmlSettingsPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qqmlsettings.cpp qqmlsettings_p.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Qml
+)
+
+#### Keys ignored in scope 1:.:.:settings.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/settings"
diff --git a/src/imports/settings/qqmlsettings_p.h b/src/imports/settings/qqmlsettings_p.h
index 3f1b83f541..100d0136ff 100644
--- a/src/imports/settings/qqmlsettings_p.h
+++ b/src/imports/settings/qqmlsettings_p.h
@@ -67,6 +67,7 @@ class QQmlSettings : public QObject, public QQmlParserStatus
Q_PROPERTY(QString category READ category WRITE setCategory FINAL)
Q_PROPERTY(QString fileName READ fileName WRITE setFileName FINAL)
QML_NAMED_ELEMENT(Settings)
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit QQmlSettings(QObject *parent = 0);
diff --git a/src/imports/settings/settings.pro b/src/imports/settings/settings.pro
index d8062a2e55..6fd8b8cddd 100644
--- a/src/imports/settings/settings.pro
+++ b/src/imports/settings/settings.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlsettingsplugin
TARGETPATH = Qt/labs/settings
-IMPORT_VERSION = 1.1
+QML_IMPORT_VERSION = $$QT_VERSION
QT = core qml
diff --git a/src/imports/shapes/CMakeLists.txt b/src/imports/shapes/CMakeLists.txt
new file mode 100644
index 0000000000..92ad133fd8
--- /dev/null
+++ b/src/imports/shapes/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Generated from shapes.pro.
+
+#####################################################################
+## qmlshapesplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlshapesplugin
+ URI "QtQuick.Shapes"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QmlShapesPlugin
+ SKIP_TYPE_REGISTRATION
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::GuiPrivate
+ Qt::Qml
+ Qt::QuickPrivate
+ Qt::QuickShapesPrivate
+)
+
+#### Keys ignored in scope 1:.:.:shapes.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick/Shapes"
diff --git a/src/imports/shapes/shapes.pro b/src/imports/shapes/shapes.pro
index 857fcd7564..b5f75343d7 100644
--- a/src/imports/shapes/shapes.pro
+++ b/src/imports/shapes/shapes.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlshapesplugin
TARGETPATH = QtQuick/Shapes
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT = core gui-private qml quick-private quickshapes-private
diff --git a/src/imports/sharedimage/CMakeLists.txt b/src/imports/sharedimage/CMakeLists.txt
new file mode 100644
index 0000000000..c840fda85f
--- /dev/null
+++ b/src/imports/sharedimage/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Generated from sharedimage.pro.
+
+#####################################################################
+## sharedimageplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(sharedimageplugin
+ URI "Qt.labs.sharedimage"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QtQuickSharedImagePlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qsharedimageloader.cpp qsharedimageloader_p.h
+ sharedimageprovider.cpp sharedimageprovider.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::Qml
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:sharedimage.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/sharedimage"
diff --git a/src/imports/sharedimage/qsharedimageloader_p.h b/src/imports/sharedimage/qsharedimageloader_p.h
index 4b0e989c29..ce10d0d72c 100644
--- a/src/imports/sharedimage/qsharedimageloader_p.h
+++ b/src/imports/sharedimage/qsharedimageloader_p.h
@@ -43,6 +43,7 @@
#include <QImage>
#include <QVariant>
#include <QLoggingCategory>
+#include <qqml.h>
QT_BEGIN_NAMESPACE
@@ -55,6 +56,10 @@ class QSharedImageLoader : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QSharedImageLoader)
+ // We need to provide some type, in order to mention the 1.0 version.
+ QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(1, 0)
+
public:
typedef QVector<QVariant> ImageParameters;
diff --git a/src/imports/sharedimage/sharedimage.pro b/src/imports/sharedimage/sharedimage.pro
index 8ab4f10405..cee4c3465e 100644
--- a/src/imports/sharedimage/sharedimage.pro
+++ b/src/imports/sharedimage/sharedimage.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = sharedimageplugin
TARGETPATH = Qt/labs/sharedimage
-IMPORT_VERSION = 1.0
+QML_IMPORT_VERSION = $$QT_VERSION
QT *= quick-private qml gui-private core-private
diff --git a/src/imports/statemachine/CMakeLists.txt b/src/imports/statemachine/CMakeLists.txt
new file mode 100644
index 0000000000..232f3f28d5
--- /dev/null
+++ b/src/imports/statemachine/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Generated from statemachine.pro.
+
+#####################################################################
+## qtqmlstatemachine Plugin:
+#####################################################################
+
+qt_add_qml_module(qtqmlstatemachine
+ URI "QtQml.StateMachine"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QtQmlStateMachinePlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ childrenprivate.h
+ finalstate.cpp finalstate.h
+ plugin.cpp
+ signaltransition.cpp signaltransition.h
+ state.cpp state.h
+ statemachine.cpp statemachine.h
+ statemachineforeign.h
+ timeouttransition.cpp timeouttransition.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:statemachine.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQml/StateMachine"
diff --git a/src/imports/statemachine/finalstate.h b/src/imports/statemachine/finalstate.h
index 117a358e53..fef0e9c092 100644
--- a/src/imports/statemachine/finalstate.h
+++ b/src/imports/statemachine/finalstate.h
@@ -56,6 +56,7 @@ class FinalState : public QFinalState
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged)
Q_CLASSINFO("DefaultProperty", "children")
QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit FinalState(QState *parent = 0);
diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp
index 69edaa4e48..c70a824fb6 100644
--- a/src/imports/statemachine/signaltransition.cpp
+++ b/src/imports/statemachine/signaltransition.cpp
@@ -69,8 +69,7 @@ bool SignalTransition::eventTest(QEvent *event)
QQmlContext *outerContext = QQmlEngine::contextForObject(this);
QQmlContext context(outerContext);
- QQmlContextData::get(outerContext)->imports->addref();
- QQmlContextData::get(&context)->imports = QQmlContextData::get(outerContext)->imports;
+ QQmlContextData::get(&context)->setImports(QQmlContextData::get(outerContext)->imports());
QStateMachine::SignalEvent *e = static_cast<QStateMachine::SignalEvent*>(event);
@@ -106,15 +105,16 @@ void SignalTransition::setSignal(const QJSValue &signal)
if (m_signal.strictlyEquals(signal))
return;
- m_signal = signal;
-
QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle();
QV4::Scope scope(jsEngine);
QObject *sender;
QMetaMethod signalMethod;
- QV4::ScopedValue value(scope, QJSValuePrivate::convertedToValue(jsEngine, m_signal));
+ m_signal = signal;
+ QJSValuePrivate::manageStringOnV4Heap(jsEngine, &m_signal);
+
+ QV4::ScopedValue value(scope, QJSValuePrivate::asReturnedValue(&m_signal));
// Did we get the "slot" that can be used to invoke the signal?
if (QV4::QObjectMethod *signalSlot = value->as<QV4::QObjectMethod>()) {
@@ -162,7 +162,7 @@ void SignalTransition::connectTriggered()
QObject *target = senderObject();
QQmlData *ddata = QQmlData::get(this);
- QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr;
+ QQmlRefPointer<QQmlContextData> ctxtdata = ddata ? ddata->outerContext : nullptr;
Q_ASSERT(m_bindings.count() == 1);
const QV4::CompiledData::Binding *binding = m_bindings.at(0);
@@ -170,7 +170,7 @@ void SignalTransition::connectTriggered()
QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle();
QV4::Scope scope(jsEngine);
- QV4::Scoped<QV4::QObjectMethod> qobjectSignal(scope, QJSValuePrivate::convertedToValue(jsEngine, m_signal));
+ QV4::Scoped<QV4::QObjectMethod> qobjectSignal(scope, QJSValuePrivate::asReturnedValue(&m_signal));
Q_ASSERT(qobjectSignal);
QMetaMethod metaMethod = target->metaObject()->method(qobjectSignal->methodIndex());
int signalIndex = QMetaObjectPrivate::signalIndex(metaMethod);
diff --git a/src/imports/statemachine/signaltransition.h b/src/imports/statemachine/signaltransition.h
index 748e230b3e..4d73368eb0 100644
--- a/src/imports/statemachine/signaltransition.h
+++ b/src/imports/statemachine/signaltransition.h
@@ -58,6 +58,7 @@ class SignalTransition : public QSignalTransition, public QQmlParserStatus
Q_PROPERTY(QJSValue signal READ signal WRITE setSignal NOTIFY qmlSignalChanged)
Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard NOTIFY guardChanged)
QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit SignalTransition(QState *parent = nullptr);
diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h
index 68184775ab..8cb454f3cf 100644
--- a/src/imports/statemachine/state.h
+++ b/src/imports/statemachine/state.h
@@ -56,6 +56,7 @@ class State : public QState, public QQmlParserStatus
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged)
Q_CLASSINFO("DefaultProperty", "children")
QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit State(QState *parent = 0);
diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h
index cc0360db54..85ac4cf26b 100644
--- a/src/imports/statemachine/statemachine.h
+++ b/src/imports/statemachine/statemachine.h
@@ -60,6 +60,7 @@ class StateMachine : public QStateMachine, public QQmlParserStatus
Q_CLASSINFO("DefaultProperty", "children")
QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit StateMachine(QObject *parent = 0);
diff --git a/src/imports/statemachine/statemachine.pro b/src/imports/statemachine/statemachine.pro
index d4977d8eb8..cff81c2416 100644
--- a/src/imports/statemachine/statemachine.pro
+++ b/src/imports/statemachine/statemachine.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qtqmlstatemachine
TARGETPATH = QtQml/StateMachine
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT = core-private qml-private
diff --git a/src/imports/statemachine/statemachineforeign.h b/src/imports/statemachine/statemachineforeign.h
index 363c9d0e31..7543d55fdf 100644
--- a/src/imports/statemachine/statemachineforeign.h
+++ b/src/imports/statemachine/statemachineforeign.h
@@ -51,6 +51,7 @@ struct QHistoryStateForeign
Q_GADGET
QML_FOREIGN(QHistoryState)
QML_NAMED_ELEMENT(HistoryState)
+ QML_ADDED_IN_VERSION(1, 0)
};
struct QStateForeign
@@ -58,6 +59,7 @@ struct QStateForeign
Q_GADGET
QML_FOREIGN(QState)
QML_NAMED_ELEMENT(QState)
+ QML_ADDED_IN_VERSION(1, 0)
QML_UNCREATABLE("Don't use this, use State instead.")
};
@@ -66,6 +68,7 @@ struct QAbstractStateForeign
Q_GADGET
QML_FOREIGN(QAbstractState)
QML_NAMED_ELEMENT(QAbstractState)
+ QML_ADDED_IN_VERSION(1, 0)
QML_UNCREATABLE("Don't use this, use State instead.")
};
@@ -74,6 +77,7 @@ struct QSignalTransitionForeign
Q_GADGET
QML_FOREIGN(QSignalTransition)
QML_NAMED_ELEMENT(QSignalTransition)
+ QML_ADDED_IN_VERSION(1, 0)
QML_UNCREATABLE("Don't use this, use SignalTransition instead.")
};
diff --git a/src/imports/statemachine/timeouttransition.h b/src/imports/statemachine/timeouttransition.h
index cc3a22e0e5..3d056b5e41 100644
--- a/src/imports/statemachine/timeouttransition.h
+++ b/src/imports/statemachine/timeouttransition.h
@@ -53,6 +53,7 @@ class TimeoutTransition : public QSignalTransition, public QQmlParserStatus
Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
Q_INTERFACES(QQmlParserStatus)
QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
public:
TimeoutTransition(QState *parent = nullptr);
diff --git a/src/imports/testlib/.prev_CMakeLists.txt b/src/imports/testlib/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..b7a6ff468a
--- /dev/null
+++ b/src/imports/testlib/.prev_CMakeLists.txt
@@ -0,0 +1,52 @@
+# Generated from testlib.pro.
+
+#####################################################################
+## qmltestplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmltestplugin
+ URI "QtTest"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QTestQmlModule
+ DEPENDENCIES
+ QtQuick.Window/2.0
+ GENERATE_QMLTYPES
+ SOURCES
+ main.cpp
+ quicktestevent.cpp quicktestevent_p.h
+ quicktestresultforeign_p.h
+ quicktestutil.cpp quicktestutil_p.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::Quick
+ Qt::QuickTestPrivate
+ Qt::Test
+)
+
+#### Keys ignored in scope 1:.:.:testlib.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# OTHER_FILES = "testlib.json"
+# QML_FILES = "TestCase.qml" "SignalSpy.qml" "testlogger.js"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtTest"
+
+set(qml_files
+ "TestCase.qml"
+ "SignalSpy.qml"
+ "testlogger.js"
+)
+set_source_files_properties(TestCase.qml PROPERTIES
+ QT_QML_SOURCE_VERSION "1.0"
+)
+set_source_files_properties(SignalSpy.qml PROPERTIES
+ QT_QML_SOURCE_VERSION "1.0"
+)
+
+qt6_target_qml_files(qmltestplugin
+ FILES
+ ${qml_files}
+)
diff --git a/src/imports/testlib/CMakeLists.txt b/src/imports/testlib/CMakeLists.txt
new file mode 100644
index 0000000000..2ce7598f62
--- /dev/null
+++ b/src/imports/testlib/CMakeLists.txt
@@ -0,0 +1,55 @@
+# Generated from testlib.pro.
+
+#####################################################################
+## qmltestplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmltestplugin
+ URI "QtTest"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QTestQmlModule
+ DEPENDENCIES
+ QtQuick.Window/2.0
+ GENERATE_QMLTYPES
+ SOURCES
+ main.cpp
+ quicktestevent.cpp quicktestevent_p.h
+ quicktestresultforeign_p.h
+ quicktestutil.cpp quicktestutil_p.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::Quick
+ Qt::QuickTestPrivate
+ Qt::Test
+)
+
+#### Keys ignored in scope 1:.:.:testlib.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# OTHER_FILES = "testlib.json"
+# QML_FILES = "TestCase.qml" "SignalSpy.qml" "testlogger.js"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtTest"
+
+set(qml_files
+ "TestCase.qml"
+ "SignalSpy.qml"
+ "testlogger.js"
+)
+set_source_files_properties(TestCase.qml PROPERTIES
+ QT_QML_SOURCE_VERSION "1.0"
+)
+set_source_files_properties(SignalSpy.qml PROPERTIES
+ QT_QML_SOURCE_VERSION "1.0"
+)
+set_source_files_properties(testlogger.js PROPERTIES
+ QT_QML_SKIP_QMLDIR_ENTRY TRUE
+)
+
+qt6_target_qml_files(qmltestplugin
+ FILES
+ ${qml_files}
+)
diff --git a/src/imports/testlib/qmldir b/src/imports/testlib/qmldir
index be9039abbb..9c1e8dd61f 100644
--- a/src/imports/testlib/qmldir
+++ b/src/imports/testlib/qmldir
@@ -3,6 +3,5 @@ plugin qmltestplugin
classname QTestQmlModule
typeinfo plugins.qmltypes
TestCase 1.0 TestCase.qml
-TestCase 1.2 TestCase.qml
SignalSpy 1.0 SignalSpy.qml
depends QtQuick.Window 2.0
diff --git a/src/imports/testlib/quicktestevent_p.h b/src/imports/testlib/quicktestevent_p.h
index f452e4ff82..0bbae8434f 100644
--- a/src/imports/testlib/quicktestevent_p.h
+++ b/src/imports/testlib/quicktestevent_p.h
@@ -63,6 +63,7 @@ class QQuickTouchEventSequence : public QObject
{
Q_OBJECT
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(1, 0)
public:
explicit QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item = nullptr);
@@ -83,6 +84,7 @@ class QuickTestEvent : public QObject
Q_OBJECT
Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL)
QML_NAMED_ELEMENT(TestEvent)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QuickTestEvent(QObject *parent = nullptr);
~QuickTestEvent() override;
@@ -97,7 +99,7 @@ public Q_SLOTS:
bool keyReleaseChar(const QString &character, int modifiers, int delay);
bool keyClickChar(const QString &character, int modifiers, int delay);
- Q_REVISION(2) bool keySequence(const QVariant &keySequence);
+ Q_REVISION(1, 2) bool keySequence(const QVariant &keySequence);
bool mousePress(QObject *item, qreal x, qreal y, int button,
int modifiers, int delay);
diff --git a/src/imports/testlib/quicktestresultforeign_p.h b/src/imports/testlib/quicktestresultforeign_p.h
index 92ff8e8a5a..e9dd12fa93 100644
--- a/src/imports/testlib/quicktestresultforeign_p.h
+++ b/src/imports/testlib/quicktestresultforeign_p.h
@@ -61,6 +61,7 @@ struct QuickTestResultForeign
Q_GADGET
QML_FOREIGN(QuickTestResult)
QML_NAMED_ELEMENT(TestResult)
+ QML_ADDED_IN_VERSION(1, 0)
};
QT_END_NAMESPACE
diff --git a/src/imports/testlib/quicktestutil.cpp b/src/imports/testlib/quicktestutil.cpp
index d9e6a2fba5..994c66845b 100644
--- a/src/imports/testlib/quicktestutil.cpp
+++ b/src/imports/testlib/quicktestutil.cpp
@@ -44,6 +44,7 @@
#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQml/private/qv4engine_p.h>
#include <QtQml/private/qv4scopedvalue_p.h>
+#include <QtQml/private/qjsvalue_p.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
@@ -78,7 +79,7 @@ QJSValue QuickTestUtil::typeName(const QVariant &v) const
QQmlEngine *engine = qmlEngine(this);
QV4::ExecutionEngine *v4 = engine->handle();
- return QJSValue(v4, v4->newString(name)->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v4->newString(name)->asReturnedValue());
}
bool QuickTestUtil::compare(const QVariant &act, const QVariant &exp) const {
@@ -93,7 +94,8 @@ QJSValue QuickTestUtil::callerFile(int frameIndex) const
QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
return (stack.size() > frameIndex + 1)
- ? QJSValue(v4, v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue())
+ ? QJSValuePrivate::fromReturnedValue(
+ v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue())
: QJSValue();
}
diff --git a/src/imports/testlib/quicktestutil_p.h b/src/imports/testlib/quicktestutil_p.h
index 2456bf88a7..7e90c1cd1d 100644
--- a/src/imports/testlib/quicktestutil_p.h
+++ b/src/imports/testlib/quicktestutil_p.h
@@ -63,6 +63,7 @@ class QuickTestUtil : public QObject
Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged)
Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged)
QML_NAMED_ELEMENT(TestUtil)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QuickTestUtil(QObject *parent = nullptr) :QObject(parent) {}
~QuickTestUtil() override {}
diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro
index d5e315d7da..2a97213e29 100644
--- a/src/imports/testlib/testlib.pro
+++ b/src/imports/testlib/testlib.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmltestplugin
TARGETPATH = QtTest
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT += quick qmltest-private qml-private core-private testlib gui-private
diff --git a/src/imports/wavefrontmesh/CMakeLists.txt b/src/imports/wavefrontmesh/CMakeLists.txt
new file mode 100644
index 0000000000..3790b7d53e
--- /dev/null
+++ b/src/imports/wavefrontmesh/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Generated from wavefrontmesh.pro.
+
+#####################################################################
+## qmlwavefrontmeshplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(qmlwavefrontmeshplugin
+ URI "Qt.labs.wavefrontmesh"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ CLASSNAME QmlWavefrontMeshPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp
+ qwavefrontmesh.cpp qwavefrontmesh.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:wavefrontmesh.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "Qt/labs/wavefrontmesh"
diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.h b/src/imports/wavefrontmesh/qwavefrontmesh.h
index a8a40c1a6a..67e0527e5d 100644
--- a/src/imports/wavefrontmesh/qwavefrontmesh.h
+++ b/src/imports/wavefrontmesh/qwavefrontmesh.h
@@ -56,6 +56,7 @@ class QWavefrontMesh : public QQuickShaderEffectMesh
Q_PROPERTY(QVector3D projectionPlaneV READ projectionPlaneV WRITE setProjectionPlaneV NOTIFY projectionPlaneVChanged)
Q_PROPERTY(QVector3D projectionPlaneW READ projectionPlaneW WRITE setProjectionPlaneW NOTIFY projectionPlaneWChanged)
QML_NAMED_ELEMENT(WavefrontMesh)
+ QML_ADDED_IN_VERSION(1, 0)
public:
enum Error {
diff --git a/src/imports/wavefrontmesh/wavefrontmesh.pro b/src/imports/wavefrontmesh/wavefrontmesh.pro
index 0b28410750..4aa06b97bf 100644
--- a/src/imports/wavefrontmesh/wavefrontmesh.pro
+++ b/src/imports/wavefrontmesh/wavefrontmesh.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qmlwavefrontmeshplugin
TARGETPATH = Qt/labs/wavefrontmesh
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
QT = core-private qml-private quick-private
diff --git a/src/imports/window/CMakeLists.txt b/src/imports/window/CMakeLists.txt
new file mode 100644
index 0000000000..99cedf333c
--- /dev/null
+++ b/src/imports/window/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Generated from window.pro.
+
+#####################################################################
+## windowplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(windowplugin
+ URI "QtQuick.Window"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQuick2WindowPlugin
+ SKIP_TYPE_REGISTRATION
+ GENERATE_QMLTYPES
+ SOURCES
+ plugin.cpp plugin.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:window.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQuick/Window"
diff --git a/src/imports/window/plugin.h b/src/imports/window/plugin.h
index 3bc2d91ddb..625a77b12c 100644
--- a/src/imports/window/plugin.h
+++ b/src/imports/window/plugin.h
@@ -65,7 +65,7 @@ struct QWindowForeign
Q_GADGET
QML_FOREIGN(QWindow)
QML_ANONYMOUS
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
};
struct QQuickWindowForeign
@@ -73,8 +73,8 @@ struct QQuickWindowForeign
Q_GADGET
QML_FOREIGN(QQuickWindow)
QML_NAMED_ELEMENT(Window)
- QML_ADDED_IN_MINOR_VERSION(0)
- QML_REMOVED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_REMOVED_IN_VERSION(2, 1)
};
struct QQuickWindowForeignAttached
@@ -82,6 +82,7 @@ struct QQuickWindowForeignAttached
Q_GADGET
QML_FOREIGN(QQuickWindowAttached)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
};
struct QQuickScreenInfoForeign
@@ -89,7 +90,7 @@ struct QQuickScreenInfoForeign
Q_GADGET
QML_FOREIGN(QQuickScreenInfo)
QML_NAMED_ELEMENT(ScreenInfo)
- QML_ADDED_IN_MINOR_VERSION(3)
+ QML_ADDED_IN_VERSION(2, 3)
QML_UNCREATABLE("ScreenInfo can only be used via the attached property.")
};
@@ -98,6 +99,7 @@ struct QQuickScreenForeignAttached
Q_GADGET
QML_FOREIGN(QQuickScreenAttached)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
};
struct QQuickScreenForeign
@@ -105,6 +107,7 @@ struct QQuickScreenForeign
Q_GADGET
QML_FOREIGN(QQuickScreen)
QML_NAMED_ELEMENT(Screen)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Screen can only be used via the attached property.")
};
@@ -113,7 +116,7 @@ struct QQuickWindowQmlImplForeign
Q_GADGET
QML_FOREIGN(QQuickWindowQmlImpl)
QML_NAMED_ELEMENT(Window)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
};
struct QQuickRootItemForeign
diff --git a/src/imports/window/window.pro b/src/imports/window/window.pro
index 068169b36f..d8f9b16df4 100644
--- a/src/imports/window/window.pro
+++ b/src/imports/window/window.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = windowplugin
-TARGETPATH = QtQuick/Window.2
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+TARGETPATH = QtQuick/Window
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/imports/workerscript/CMakeLists.txt b/src/imports/workerscript/CMakeLists.txt
new file mode 100644
index 0000000000..57b2739a10
--- /dev/null
+++ b/src/imports/workerscript/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from workerscript.pro.
+
+#####################################################################
+## workerscriptplugin Plugin:
+#####################################################################
+
+qt_add_qml_module(workerscriptplugin
+ URI "QtQml.WorkerScript"
+ VERSION "${CMAKE_PROJECT_VERSION}"
+ DESIGNER_SUPPORTED
+ CLASSNAME QtQmlWorkerScriptPlugin
+ SKIP_TYPE_REGISTRATION
+ SOURCES
+ plugin.cpp
+ PUBLIC_LIBRARIES
+ Qt::QmlPrivate
+ Qt::QmlWorkerScriptPrivate
+)
+
+#### Keys ignored in scope 1:.:.:workerscript.pro:<TRUE>:
+# CXX_MODULE = "qml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+# TARGETPATH = "QtQml/WorkerScript"
diff --git a/src/imports/workerscript/qmldir b/src/imports/workerscript/qmldir
index 1606400a23..02ff9ea188 100644
--- a/src/imports/workerscript/qmldir
+++ b/src/imports/workerscript/qmldir
@@ -1,3 +1,4 @@
module QtQml.WorkerScript
plugin workerscriptplugin
classname QtQmlWorkerScriptPlugin
+designersupported
diff --git a/src/imports/workerscript/workerscript.pro b/src/imports/workerscript/workerscript.pro
index d48e285bda..9c6a65eb05 100644
--- a/src/imports/workerscript/workerscript.pro
+++ b/src/imports/workerscript/workerscript.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = workerscriptplugin
-TARGETPATH = QtQml/WorkerScript.2
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+TARGETPATH = QtQml/WorkerScript
+QML_IMPORT_VERSION = $$QT_VERSION
SOURCES += \
plugin.cpp
diff --git a/src/particles/CMakeLists.txt b/src/particles/CMakeLists.txt
new file mode 100644
index 0000000000..f2da8b3e1c
--- /dev/null
+++ b/src/particles/CMakeLists.txt
@@ -0,0 +1,135 @@
+# Generated from particles.pro.
+
+#####################################################################
+## QuickParticles Module:
+#####################################################################
+
+qt_add_module(QuickParticles
+ INTERNAL_MODULE
+ GENERATE_METATYPES
+ SOURCES
+ qquickage.cpp qquickage_p.h
+ qquickangledirection.cpp qquickangledirection_p.h
+ qquickcumulativedirection.cpp qquickcumulativedirection_p.h
+ qquickcustomaffector.cpp qquickcustomaffector_p.h
+ qquickdirection.cpp qquickdirection_p.h
+ qquickellipseextruder.cpp qquickellipseextruder_p.h
+ qquickfriction.cpp qquickfriction_p.h
+ qquickgravity.cpp qquickgravity_p.h
+ qquickgroupgoal.cpp qquickgroupgoal_p.h
+ qquickimageparticle.cpp qquickimageparticle_p.h
+ qquickitemparticle.cpp qquickitemparticle_p.h
+ qquicklineextruder.cpp qquicklineextruder_p.h
+ qquickmaskextruder.cpp qquickmaskextruder_p.h
+ qquickparticleaffector.cpp qquickparticleaffector_p.h
+ qquickparticleemitter.cpp qquickparticleemitter_p.h
+ qquickparticleextruder.cpp qquickparticleextruder_p.h
+ qquickparticlegroup.cpp qquickparticlegroup_p.h
+ qquickparticlepainter.cpp qquickparticlepainter_p.h
+ qquickparticlesmodule.cpp qquickparticlesmodule_p.h
+ qquickparticlesystem.cpp qquickparticlesystem_p.h
+ qquickpointattractor.cpp qquickpointattractor_p.h
+ qquickpointdirection.cpp qquickpointdirection_p.h
+ qquickrectangleextruder.cpp qquickrectangleextruder_p.h
+ qquickspritegoal.cpp qquickspritegoal_p.h
+ qquicktargetdirection.cpp qquicktargetdirection_p.h
+ qquicktrailemitter.cpp qquicktrailemitter_p.h
+ qquickturbulence.cpp qquickturbulence_p.h
+ qquickv4particledata.cpp qquickv4particledata_p.h
+ qquickwander.cpp qquickwander_p.h
+ qtquickparticlesglobal_p.h
+ DEFINES
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+# Resources:
+set(particles_resource_files
+ "particleresources/fuzzydot.png"
+ "particleresources/glowdot.png"
+ "particleresources/noise.png"
+ "particleresources/star.png"
+)
+
+qt_add_resource(QuickParticles "particles"
+ PREFIX
+ "/"
+ FILES
+ ${particles_resource_files}
+)
+set(particles1_resource_files
+ "shaders/customparticle.frag"
+ "shaders/customparticle.vert"
+ "shaders/customparticle_core.frag"
+ "shaders/customparticle_core.vert"
+ "shaders/customparticletemplate.vert"
+ "shaders/customparticletemplate_core.vert"
+ "shaders/imageparticle.frag"
+ "shaders/imageparticle.vert"
+ "shaders/imageparticle_core.frag"
+ "shaders/imageparticle_core.vert"
+ "shaders_ng/imageparticle_colored.frag.qsb"
+ "shaders_ng/imageparticle_colored.vert.qsb"
+ "shaders_ng/imageparticle_deformed.frag.qsb"
+ "shaders_ng/imageparticle_deformed.vert.qsb"
+ "shaders_ng/imageparticle_simple.frag.qsb"
+ "shaders_ng/imageparticle_simple.vert.qsb"
+ "shaders_ng/imageparticle_sprite.frag.qsb"
+ "shaders_ng/imageparticle_sprite.vert.qsb"
+ "shaders_ng/imageparticle_tabled.frag.qsb"
+ "shaders_ng/imageparticle_tabled.vert.qsb"
+)
+
+qt_add_resource(QuickParticles "particles1"
+ PREFIX
+ "/particles"
+ FILES
+ ${particles1_resource_files}
+)
+
+
+#### Keys ignored in scope 1:.:.:particles.pro:<TRUE>:
+# MODULE = "quickparticles"
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQuick/Particles"
+# QML_IMPORT_NAME = "QtQuick.Particles"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QuickParticles CONDITION MSVC
+ DEFINES
+ _CRT_SECURE_NO_WARNINGS
+)
+
+#### Keys ignored in scope 3:.:.:particles.pro:solaris-cc_x_:
+# QMAKE_CXXFLAGS_RELEASE = "--O2"
+
+qt_extend_target(QuickParticles CONDITION EXISTS "qqml_enable_gcov"
+ LIBRARIES
+ gcov
+ COMPILE_OPTIONS
+ -fno-elide-constructors
+ -fprofile-arcs
+ -ftest-coverage
+)
+
+qt_extend_target(QuickParticles CONDITION QT_FEATURE_quick_shadereffect
+ SOURCES
+ qquickcustomparticle.cpp qquickcustomparticle_p.h
+)
+
+set_target_properties(QuickParticles PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQuick.Particles
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQuick/Particles"
+)
+
+qt6_qml_type_registration(QuickParticles)
diff --git a/src/particles/particles.pro b/src/particles/particles.pro
index aaaa83419a..6a117c65fe 100644
--- a/src/particles/particles.pro
+++ b/src/particles/particles.pro
@@ -17,9 +17,9 @@ exists("qqml_enable_gcov") {
include(particles.pri)
QMLTYPES_FILENAME = plugins.qmltypes
-QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Particles.2
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Particles
QML_IMPORT_NAME = QtQuick.Particles
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
load(qt_module)
diff --git a/src/particles/qquickage_p.h b/src/particles/qquickage_p.h
index 890c6a63c1..1730c25c28 100644
--- a/src/particles/qquickage_p.h
+++ b/src/particles/qquickage_p.h
@@ -60,6 +60,7 @@ class QQuickAgeAffector : public QQuickParticleAffector
Q_PROPERTY(int lifeLeft READ lifeLeft WRITE setLifeLeft NOTIFY lifeLeftChanged)
Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged)
QML_NAMED_ELEMENT(Age)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickAgeAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h
index d0fdf5a68c..9ec9e49d1a 100644
--- a/src/particles/qquickangledirection_p.h
+++ b/src/particles/qquickangledirection_p.h
@@ -63,6 +63,7 @@ class QQuickAngleDirection : public QQuickDirection
Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged)
Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged)
QML_NAMED_ELEMENT(AngleDirection)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickAngleDirection(QObject *parent = 0);
QPointF sample(const QPointF &from) override;
diff --git a/src/particles/qquickcumulativedirection_p.h b/src/particles/qquickcumulativedirection_p.h
index 5160d8f09a..0a54d5dd22 100644
--- a/src/particles/qquickcumulativedirection_p.h
+++ b/src/particles/qquickcumulativedirection_p.h
@@ -62,6 +62,7 @@ class QQuickCumulativeDirection : public QQuickDirection
Q_PROPERTY(QQmlListProperty<QQuickDirection> directions READ directions)
Q_CLASSINFO("DefaultProperty", "directions")
QML_NAMED_ELEMENT(CumulativeDirection)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickCumulativeDirection(QObject *parent = 0);
QQmlListProperty<QQuickDirection> directions();
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index aa2617e64c..67f2922423 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -157,7 +157,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
const auto doAffect = [&](qreal dt) {
affectProperties(toAffect, dt);
QJSValue particles;
- QJSValuePrivate::setValue(&particles, v4, array);
+ QJSValuePrivate::setValue(&particles, array);
emit affectParticles(particles, dt);
};
diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index 5e8671514d..4506ae9d62 100644
--- a/src/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
@@ -68,6 +68,7 @@ class QQuickCustomAffector : public QQuickParticleAffector
Q_PROPERTY(QQuickDirection *velocity READ velocity WRITE setVelocity NOTIFY velocityChanged RESET velocityReset)
Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset)
QML_NAMED_ELEMENT(Affector)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickCustomAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index 91fd63302a..ecb71cb913 100644
--- a/src/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
@@ -39,7 +39,7 @@
#include "qquickcustomparticle_p.h"
#include <QtCore/qrandom.h>
-#include <QtGui/qopenglcontext.h>
+#include <qopenglcontext.h>
#include <QtQuick/private/qquickshadereffectmesh_p.h>
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
#include <QtQml/qqmlinfo.h>
diff --git a/src/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h
index 444f7ad215..90643fe3e4 100644
--- a/src/particles/qquickcustomparticle_p.h
+++ b/src/particles/qquickcustomparticle_p.h
@@ -68,6 +68,7 @@ class QQuickCustomParticle : public QQuickParticlePainter
Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
QML_NAMED_ELEMENT(CustomParticle)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickCustomParticle(QQuickItem* parent=0);
diff --git a/src/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h
index 60b4d8eb1d..e671868ed2 100644
--- a/src/particles/qquickdirection_p.h
+++ b/src/particles/qquickdirection_p.h
@@ -61,6 +61,7 @@ class QQuickDirection : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(NullVector)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
public:
diff --git a/src/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h
index c92443fedf..3268923480 100644
--- a/src/particles/qquickellipseextruder_p.h
+++ b/src/particles/qquickellipseextruder_p.h
@@ -59,6 +59,7 @@ class QQuickEllipseExtruder : public QQuickParticleExtruder
Q_OBJECT
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box
QML_NAMED_ELEMENT(EllipseShape)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickEllipseExtruder(QObject *parent = 0);
QPointF extrude(const QRectF &) override;
diff --git a/src/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h
index 5686bb37d5..952f47b141 100644
--- a/src/particles/qquickfriction_p.h
+++ b/src/particles/qquickfriction_p.h
@@ -60,6 +60,7 @@ class QQuickFrictionAffector : public QQuickParticleAffector
Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged)
Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged)
QML_NAMED_ELEMENT(Friction)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickFrictionAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index ef7cc770b7..351cbb93b1 100644
--- a/src/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
@@ -62,6 +62,7 @@ class QQuickGravityAffector : public QQuickParticleAffector
Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
QML_NAMED_ELEMENT(Gravity)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickGravityAffector(QQuickItem *parent = 0);
qreal magnitude() const;
diff --git a/src/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h
index 022b244ed7..5589483aa6 100644
--- a/src/particles/qquickgroupgoal_p.h
+++ b/src/particles/qquickgroupgoal_p.h
@@ -62,6 +62,7 @@ class QQuickGroupGoalAffector : public QQuickParticleAffector
Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged)
Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
QML_NAMED_ELEMENT(GroupGoal)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickGroupGoalAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index 4d67691771..f2e3715061 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -221,10 +221,10 @@ public:
{
ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
if (binding == 2) {
- state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->colorTable;
} else if (binding == 1) {
- state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->texture;
}
}
@@ -362,7 +362,7 @@ public:
{
ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
if (binding == 1) {
- state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->texture;
}
}
@@ -529,10 +529,10 @@ public:
{
ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
if (binding == 2) {
- state->colorTable->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->colorTable;
} else if (binding == 1) {
- state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->texture;
}
}
@@ -606,14 +606,14 @@ public:
}
void activate() override {
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
+#if !QT_CONFIG(opengles2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
void deactivate() override {
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
+#if !QT_CONFIG(opengles2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
@@ -682,7 +682,7 @@ public:
{
ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
if (binding == 1) {
- state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->texture;
}
}
@@ -754,14 +754,14 @@ public:
}
void activate() override {
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
+#if !QT_CONFIG(opengles2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
}
void deactivate() override {
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
+#if !QT_CONFIG(opengles2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
@@ -830,7 +830,7 @@ public:
{
ImageMaterialData *state = static_cast<ImageMaterial *>(newMaterial)->state();
if (binding == 1) {
- state->texture->updateRhiTexture(renderState.rhi(), renderState.resourceUpdateBatch());
+ state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
*texture = state->texture;
}
}
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index fdb404861c..266054f28e 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -203,6 +203,7 @@ class QQuickImageParticle : public QQuickParticlePainter
Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged)
QML_NAMED_ELEMENT(ImageParticle)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickImageParticle(QQuickItem *parent = 0);
virtual ~QQuickImageParticle();
diff --git a/src/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h
index 32c9881691..fce9e95548 100644
--- a/src/particles/qquickitemparticle_p.h
+++ b/src/particles/qquickitemparticle_p.h
@@ -64,6 +64,7 @@ class QQuickItemParticle : public QQuickParticlePainter
Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
QML_NAMED_ELEMENT(ItemParticle)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQuickItemParticleAttached)
public:
explicit QQuickItemParticle(QQuickItem *parent = 0);
diff --git a/src/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h
index 76ac5aaf11..a337324c6a 100644
--- a/src/particles/qquicklineextruder_p.h
+++ b/src/particles/qquicklineextruder_p.h
@@ -58,6 +58,7 @@ class QQuickLineExtruder : public QQuickParticleExtruder
//Default is topleft to bottom right. Flipped makes it topright to bottom left
Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged)
QML_NAMED_ELEMENT(LineShape)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickLineExtruder(QObject *parent = 0);
diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h
index 419d162811..0d3fa9c15a 100644
--- a/src/particles/qquickmaskextruder_p.h
+++ b/src/particles/qquickmaskextruder_p.h
@@ -62,6 +62,7 @@ class QQuickMaskExtruder : public QQuickParticleExtruder
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
QML_NAMED_ELEMENT(MaskShape)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickMaskExtruder(QObject *parent = 0);
QPointF extrude(const QRectF &) override;
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index fd4887333e..22cebbead1 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -69,6 +69,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleAffector : public QQuickItem
Q_PROPERTY(QQuickParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged)
QML_NAMED_ELEMENT(ParticleAffector)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
public:
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index 3e9d7c02a9..62bf83994f 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -497,7 +497,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
array->put(i, (v = toEmit[i]->v4Value(m_system)));
QJSValue particles;
- QJSValuePrivate::setValue(&particles, v4, array);
+ QJSValuePrivate::setValue(&particles, array);
emit emitParticles(particles);//A chance for arbitrary JS changes
}
diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index b97d3f812a..8c9ca622fb 100644
--- a/src/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
@@ -84,6 +84,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleEmitter : public QQuickItem
Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
Q_PROPERTY(qreal velocityFromMovement READ velocityFromMovement WRITE setVelocityFromMovement NOTIFY velocityFromMovementChanged)
QML_NAMED_ELEMENT(Emitter)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickParticleEmitter(QQuickItem *parent = 0);
diff --git a/src/particles/qquickparticleextruder_p.h b/src/particles/qquickparticleextruder_p.h
index 24f7a0a2fa..7be0ead245 100644
--- a/src/particles/qquickparticleextruder_p.h
+++ b/src/particles/qquickparticleextruder_p.h
@@ -63,6 +63,7 @@ class QQuickParticleExtruder : public QObject
Q_OBJECT
QML_NAMED_ELEMENT(ParticleExtruder)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
public:
diff --git a/src/particles/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h
index 8d068fbe9c..9b13153a95 100644
--- a/src/particles/qquickparticlegroup_p.h
+++ b/src/particles/qquickparticlegroup_p.h
@@ -67,6 +67,7 @@ class QQuickParticleGroup : public QQuickStochasticState, public QQmlParserStatu
Q_PROPERTY(QQmlListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states
Q_CLASSINFO("DefaultProperty", "particleChildren")
QML_NAMED_ELEMENT(ParticleGroup)
+ QML_ADDED_IN_VERSION(2, 0)
Q_INTERFACES(QQmlParserStatus)
public:
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index e3d13b8a21..5236bb6569 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -65,6 +65,7 @@ class QQuickParticlePainter : public QQuickItem
Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
QML_NAMED_ELEMENT(ParticlePainter)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
public: // data
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index 7c0a1ffd7d..b7812c6ea5 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -352,6 +352,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleSystem : public QQuickItem
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
QML_NAMED_ELEMENT(ParticleSystem)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickParticleSystem(QQuickItem *parent = nullptr);
diff --git a/src/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h
index 28bbaaa84f..b3314f1a96 100644
--- a/src/particles/qquickpointattractor_p.h
+++ b/src/particles/qquickpointattractor_p.h
@@ -63,6 +63,7 @@ class QQuickAttractorAffector : public QQuickParticleAffector
Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged)
Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged)
QML_NAMED_ELEMENT(Attractor)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum Proportion{
diff --git a/src/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h
index 9103a570c9..39109d8331 100644
--- a/src/particles/qquickpointdirection_p.h
+++ b/src/particles/qquickpointdirection_p.h
@@ -62,6 +62,7 @@ class QQuickPointDirection : public QQuickDirection
Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged)
Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged)
QML_NAMED_ELEMENT(PointDirection)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickPointDirection(QObject *parent = 0);
QPointF sample(const QPointF &from) override;
diff --git a/src/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h
index 7c0a6c2bf1..f6f39579c4 100644
--- a/src/particles/qquickrectangleextruder_p.h
+++ b/src/particles/qquickrectangleextruder_p.h
@@ -60,6 +60,7 @@ class QQuickRectangleExtruder : public QQuickParticleExtruder
Q_OBJECT
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)
QML_NAMED_ELEMENT(RectangleShape)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickRectangleExtruder(QObject *parent = 0);
diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index d5f9bb88ae..efd9b1ab39 100644
--- a/src/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
@@ -64,6 +64,7 @@ class QQuickSpriteGoalAffector : public QQuickParticleAffector
Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged)
QML_NAMED_ELEMENT(SpriteGoal)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickSpriteGoalAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h
index 232d375d8c..ea6ac24893 100644
--- a/src/particles/qquicktargetdirection_p.h
+++ b/src/particles/qquicktargetdirection_p.h
@@ -71,6 +71,7 @@ class QQuickTargetDirection : public QQuickDirection
Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged)
Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged)
QML_NAMED_ELEMENT(TargetDirection)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickTargetDirection(QObject *parent = 0);
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index 5720460bae..05afdf9d1f 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -278,11 +278,14 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
array->put(i, (v = toEmit[i]->v4Value(m_system)));
QJSValue particles;
- QJSValuePrivate::setValue(&particles, v4, array);
- if (isEmitFollowConnected())
- emit emitFollowParticles(particles, QJSValue(v4, d->v4Value(m_system)));//A chance for many arbitrary JS changes
- else if (isEmitConnected())
+ QJSValuePrivate::setValue(&particles, array);
+ if (isEmitFollowConnected()) {
+ //A chance for many arbitrary JS changes
+ emit emitFollowParticles(
+ particles, QJSValuePrivate::fromReturnedValue(d->v4Value(m_system)));
+ } else if (isEmitConnected()) {
emit emitParticles(particles);//A chance for arbitrary JS changes
+ }
}
m_lastEmission[d->index] = pt;
}
diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index 270bec52cf..bf21b66fb6 100644
--- a/src/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
@@ -65,6 +65,7 @@ class QQuickTrailEmitter : public QQuickParticleEmitter
Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged)
Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged)
QML_NAMED_ELEMENT(TrailEmitter)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum EmitSize {
diff --git a/src/particles/qquickturbulence.cpp b/src/particles/qquickturbulence.cpp
index dff266a6ea..bc051ef6b7 100644
--- a/src/particles/qquickturbulence.cpp
+++ b/src/particles/qquickturbulence.cpp
@@ -85,7 +85,7 @@ QQuickTurbulenceAffector::QQuickTurbulenceAffector(QQuickItem *parent) :
{
}
-void QQuickTurbulenceAffector::geometryChanged(const QRectF &, const QRectF &)
+void QQuickTurbulenceAffector::geometryChange(const QRectF &, const QRectF &)
{
initializeGrid();
}
diff --git a/src/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h
index 52011381e4..e6204f4f0b 100644
--- a/src/particles/qquickturbulence_p.h
+++ b/src/particles/qquickturbulence_p.h
@@ -63,6 +63,7 @@ class QQuickTurbulenceAffector : public QQuickParticleAffector
Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged)
QML_NAMED_ELEMENT(Turbulence)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickTurbulenceAffector(QQuickItem *parent = 0);
@@ -104,8 +105,7 @@ public Q_SLOTS:
}
protected:
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
private:
void ensureInit();
void mapUpdate();
diff --git a/src/particles/qquickwander_p.h b/src/particles/qquickwander_p.h
index bf7acdacfb..174b780562 100644
--- a/src/particles/qquickwander_p.h
+++ b/src/particles/qquickwander_p.h
@@ -72,6 +72,7 @@ class QQuickWanderAffector : public QQuickParticleAffector
Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged)
Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged)
QML_NAMED_ELEMENT(Wander)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum AffectableParameters {
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
new file mode 100644
index 0000000000..5e24a32791
--- /dev/null
+++ b/src/plugins/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Generated from plugins.pro.
+
+if(QT_FEATURE_qml_debug AND QT_FEATURE_thread)
+ add_subdirectory(qmltooling)
+endif()
+if(TARGET Qt::Quick)
+ add_subdirectory(scenegraph)
+endif()
diff --git a/src/plugins/qmltooling/CMakeLists.txt b/src/plugins/qmltooling/CMakeLists.txt
new file mode 100644
index 0000000000..01cd40ffbb
--- /dev/null
+++ b/src/plugins/qmltooling/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Generated from qmltooling.pro.
+
+add_subdirectory(packetprotocol)
+add_subdirectory(qmldbg_native)
+add_subdirectory(qmldbg_messages)
+add_subdirectory(qmldbg_profiler)
+add_subdirectory(qmldbg_debugger)
+add_subdirectory(qmldbg_nativedebugger)
+if(QT_FEATURE_thread)
+ add_subdirectory(qmldbg_server)
+endif()
+if(QT_FEATURE_qml_network)
+ add_subdirectory(qmldbg_tcp)
+endif()
+if(QT_FEATURE_localserver AND QT_FEATURE_qml_network)
+ add_subdirectory(qmldbg_local)
+endif()
+if(TARGET Qt::Quick)
+ add_subdirectory(qmldbg_inspector)
+ add_subdirectory(qmldbg_quickprofiler)
+endif()
+if(QT_FEATURE_qml_network AND QT_FEATURE_settings AND TARGET Qt::Quick)
+ add_subdirectory(qmldbg_preview)
+endif()
diff --git a/src/plugins/qmltooling/packetprotocol/CMakeLists.txt b/src/plugins/qmltooling/packetprotocol/CMakeLists.txt
new file mode 100644
index 0000000000..ddc2af6cfa
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Generated from packetprotocol.pro.
+
+#####################################################################
+## PacketProtocol Module:
+#####################################################################
+
+qt_add_module(PacketProtocol
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qpacket.cpp qpacket_p.h
+ qpacketprotocol.cpp qpacketprotocol_p.h
+ qversionedpacket_p.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt
new file mode 100644
index 0000000000..7f42437e82
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Generated from qmldbg_debugger.pro.
+
+#####################################################################
+## QQmlDebuggerServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlDebuggerServiceFactory
+ OUTPUT_NAME qmldbg_debugger
+ TYPE qmltooling
+ SOURCES
+ qqmldebuggerservicefactory.cpp qqmldebuggerservicefactory.h
+ qqmlenginedebugservice.cpp qqmlenginedebugservice.h
+ qqmlwatcher.cpp qqmlwatcher.h
+ qv4datacollector.cpp qv4datacollector.h
+ qv4debugger.cpp qv4debugger.h
+ qv4debuggeragent.cpp qv4debuggeragent.h
+ qv4debugjob.cpp qv4debugjob.h
+ qv4debugservice.cpp qv4debugservice.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_debugger.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qqmldebuggerservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index d435e82390..1aa24ea3a4 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -389,7 +389,7 @@ void QQmlEngineDebugServiceImpl::buildObjectList(QDataStream &message,
if (!ctxt->isValid())
return;
- QQmlContextData *p = QQmlContextData::get(ctxt);
+ QQmlRefPointer<QQmlContextData> p = QQmlContextData::get(ctxt);
QString ctxtName = ctxt->objectName();
int ctxtId = QQmlDebugService::idForObject(ctxt);
@@ -400,31 +400,31 @@ void QQmlEngineDebugServiceImpl::buildObjectList(QDataStream &message,
int count = 0;
- QQmlContextData *child = p->childContexts;
+ QQmlRefPointer<QQmlContextData> child = p->childContexts();
while (child) {
++count;
- child = child->nextChild;
+ child = child->nextChild();
}
message << count;
- child = p->childContexts;
+ child = p->childContexts();
while (child) {
buildObjectList(message, child->asQQmlContext(), instances);
- child = child->nextChild;
+ child = child->nextChild();
}
count = 0;
for (int ii = 0; ii < instances.count(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
- if (data->context == p)
+ if (data->context == p.data())
count ++;
}
message << count;
for (int ii = 0; ii < instances.count(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
- if (data->context == p)
+ if (data->context == p.data())
message << objectData(instances.at(ii));
}
}
@@ -522,16 +522,11 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
if (engine) {
QQmlContext *rootContext = engine->rootContext();
- // Clean deleted objects
QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(rootContext);
- for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
- if (!ctxtPriv->instances.at(ii)) {
- ctxtPriv->instances.removeAt(ii);
- --ii;
- }
- }
- buildObjectList(rs, rootContext, ctxtPriv->instances);
- buildStatesList(true, ctxtPriv->instances);
+ ctxtPriv->cleanInstances(); // Clean deleted objects
+ const QList<QPointer<QObject>> instances = ctxtPriv->instances();
+ buildObjectList(rs, rootContext, instances);
+ buildStatesList(true, instances);
}
} else if (type == "FETCH_OBJECT") {
@@ -783,7 +778,7 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
QQmlContext *context = qmlContext(object);
if (!object || !context || !context->isValid())
return false;
- QQmlContextData *contextData = QQmlContextData::get(context);
+ QQmlRefPointer<QQmlContextData> contextData = QQmlContextData::get(context);
QQmlPropertyData dummy;
QQmlPropertyData *prop =
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 506ecb64bb..d3134e0727 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -44,7 +44,7 @@
#include <private/qv4script_p.h>
#include <private/qv4string_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4identifier_p.h>
+#include <private/qv4identifierhash_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4identifiertable_p.h>
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index 5521e7628b..314a0adb0f 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -52,7 +52,7 @@ QV4Debugger::BreakPoint::BreakPoint(const QString &fileName, int line)
: fileName(fileName), lineNumber(line)
{}
-inline uint qHash(const QV4Debugger::BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
+inline size_t qHash(const QV4Debugger::BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
{
return qHash(b.fileName, seed) ^ b.lineNumber;
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 333ce4b26f..a70941682b 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -88,10 +88,10 @@ void JavaScriptJob::run()
QV4::ScopedObject withContext(scope, engine->newObject());
QV4::ScopedString k(scope);
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
- QObject *object = ctxtPriv->instances.at(ii);
- if (QQmlContext *context = qmlContext(object)) {
- if (QQmlContextData *cdata = QQmlContextData::get(context)) {
+ const QList<QPointer<QObject>> instances = ctxtPriv->instances();
+ for (const QPointer<QObject> &object : instances) {
+ if (QQmlContext *context = qmlContext(object.data())) {
+ if (QQmlRefPointer<QQmlContextData> cdata = QQmlContextData::get(context)) {
v = QV4::QObjectWrapper::wrap(engine, object);
k = engine->newString(cdata->findObjectId(object));
withContext->put(k, v);
diff --git a/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt
new file mode 100644
index 0000000000..4e2b41c67b
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Generated from qmldbg_inspector.pro.
+
+#####################################################################
+## QQmlInspectorServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlInspectorServiceFactory
+ OUTPUT_NAME qmldbg_inspector
+ TYPE qmltooling
+ SOURCES
+ globalinspector.cpp globalinspector.h
+ highlight.cpp highlight.h
+ inspecttool.cpp inspecttool.h
+ qqmlinspectorservice.cpp
+ qqmlinspectorservicefactory.h
+ qquickwindowinspector.cpp qquickwindowinspector.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_inspector.pro:<TRUE>:
+# OTHER_FILES = "qqmlinspectorservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
index 012730902b..301db59952 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
@@ -298,7 +298,7 @@ QString GlobalInspector::idStringForObject(QObject *obj) const
{
QQmlContext *context = qmlContext(obj);
if (context) {
- QQmlContextData *cdata = QQmlContextData::get(context);
+ QQmlRefPointer<QQmlContextData> cdata = QQmlContextData::get(context);
if (cdata)
return cdata->findObjectId(obj);
}
diff --git a/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt
new file mode 100644
index 0000000000..32cb329cc2
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Generated from qmldbg_local.pro.
+
+#####################################################################
+## QLocalClientConnectionFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QLocalClientConnectionFactory
+ OUTPUT_NAME qmldbg_local
+ TYPE qmltooling
+ SOURCES
+ qlocalclientconnection.cpp
+ qlocalclientconnectionfactory.h
+ PUBLIC_LIBRARIES
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_local.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qlocalclientconnection.json"
diff --git a/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt
new file mode 100644
index 0000000000..83bfbe1c37
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Generated from qmldbg_messages.pro.
+
+#####################################################################
+## QDebugMessageServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QDebugMessageServiceFactory
+ OUTPUT_NAME qmldbg_messages
+ TYPE qmltooling
+ SOURCES
+ qdebugmessageservice.cpp qdebugmessageservice.h
+ qdebugmessageservicefactory.cpp qdebugmessageservicefactory.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_messages.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qdebugmessageservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt
new file mode 100644
index 0000000000..844c35ae4b
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Generated from qmldbg_native.pro.
+
+#####################################################################
+## QQmlNativeDebugConnectorFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlNativeDebugConnectorFactory
+ OUTPUT_NAME qmldbg_native
+ TYPE qmltooling
+ SOURCES
+ qqmlnativedebugconnector.cpp qqmlnativedebugconnector.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_native.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qqmlnativedebugconnector.json"
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt
new file mode 100644
index 0000000000..62aa1399e0
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Generated from qmldbg_nativedebugger.pro.
+
+#####################################################################
+## QQmlNativeDebugServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlNativeDebugServiceFactory
+ OUTPUT_NAME qmldbg_nativedebugger
+ TYPE qmltooling
+ SOURCES
+ qqmlnativedebugservice.cpp qqmlnativedebugservice.h
+ qqmlnativedebugservicefactory.cpp qqmlnativedebugservicefactory.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_nativedebugger.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qqmlnativedebugservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index dceaab9f6d..e9fb58de47 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -46,7 +46,7 @@
#include <private/qv4script_p.h>
#include <private/qv4string_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4identifier_p.h>
+#include <private/qv4identifierhash_p.h>
#include <private/qv4runtime_p.h>
#include <private/qversionedpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
@@ -83,7 +83,7 @@ public:
int hitCount;
};
-inline uint qHash(const BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
+inline size_t qHash(const BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW
{
return qHash(b.fileName, seed) ^ b.lineNumber;
}
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
index 86f2e31d60..00b9749472 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
@@ -47,7 +47,7 @@
#include <private/qv4script_p.h>
#include <private/qv4string_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4identifier_p.h>
+#include <private/qv4identifierhash_p.h>
#include <private/qv4runtime_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
diff --git a/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt
new file mode 100644
index 0000000000..908fd961fe
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Generated from qmldbg_preview.pro.
+
+#####################################################################
+## QQmlPreviewServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlPreviewServiceFactory
+ OUTPUT_NAME qmldbg_preview
+ TYPE qmltooling
+ SOURCES
+ qqmldebugtranslationservice.cpp qqmldebugtranslationservice.h
+ qqmlpreviewblacklist.cpp qqmlpreviewblacklist.h
+ qqmlpreviewfileengine.cpp qqmlpreviewfileengine.h
+ qqmlpreviewfileloader.cpp qqmlpreviewfileloader.h
+ qqmlpreviewhandler.cpp qqmlpreviewhandler.h
+ qqmlpreviewposition.cpp qqmlpreviewposition.h
+ qqmlpreviewservice.cpp qqmlpreviewservice.h
+ qqmlpreviewservicefactory.cpp qqmlpreviewservicefactory.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::Network
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_preview.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qqmlpreviewservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
index 1561777202..5da26e9610 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
@@ -58,7 +58,9 @@ QString QQmlDebugTranslationServiceImpl::foundElidedText(QObject *textObject, co
return elideText;
}
-void QQmlDebugTranslationServiceImpl::foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData)
+void QQmlDebugTranslationServiceImpl::foundTranslationBinding(
+ QQmlTranslationBinding *binding, QObject *scopeObject,
+ const QQmlRefPointer<QQmlContextData> &contextData)
{
Q_UNUSED(binding)
Q_UNUSED(scopeObject)
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
index a337a937a5..802f21ecce 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
@@ -78,7 +78,8 @@ public:
QQmlDebugTranslationServiceImpl(QObject *parent = 0);
QString foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText) override;
- void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) override;
+ void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject,
+ const QQmlRefPointer<QQmlContextData> &contextData) override;
void messageReceived(const QByteArray &message) override;
};
diff --git a/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt
new file mode 100644
index 0000000000..b1ff256a1a
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from qmldbg_profiler.pro.
+
+#####################################################################
+## QQmlProfilerServiceFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlProfilerServiceFactory
+ OUTPUT_NAME qmldbg_profiler
+ TYPE qmltooling
+ SOURCES
+ qqmlenginecontrolservice.cpp qqmlenginecontrolservice.h
+ qqmlprofileradapter.cpp qqmlprofileradapter.h
+ qqmlprofilerservice.cpp qqmlprofilerservice.h
+ qqmlprofilerservicefactory.cpp qqmlprofilerservicefactory.h
+ qv4profileradapter.cpp qv4profileradapter.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_profiler.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qqmlprofilerservice.json"
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt
new file mode 100644
index 0000000000..e67deee569
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from qmldbg_quickprofiler.pro.
+
+#####################################################################
+## QQuickProfilerAdapterFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQuickProfilerAdapterFactory
+ OUTPUT_NAME qmldbg_quickprofiler
+ TYPE qmltooling
+ SOURCES
+ qquickprofileradapter.cpp qquickprofileradapter.h
+ qquickprofileradapterfactory.cpp qquickprofileradapterfactory.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_quickprofiler.pro:<TRUE>:
+# OTHER_FILES = "qquickprofileradapter.json"
diff --git a/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt
new file mode 100644
index 0000000000..58a8b9506b
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Generated from qmldbg_server.pro.
+
+#####################################################################
+## QQmlDebugServerFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QQmlDebugServerFactory
+ OUTPUT_NAME qmldbg_server
+ TYPE qmltooling
+ SOURCES
+ qqmldebugserver.cpp
+ qqmldebugserverfactory.h
+ PUBLIC_LIBRARIES
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_server.pro:<TRUE>:
+# OTHER_FILES = "qqmldebugserver.json"
diff --git a/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt
new file mode 100644
index 0000000000..0c9afa852f
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Generated from qmldbg_tcp.pro.
+
+#####################################################################
+## QTcpServerConnectionFactory Plugin:
+#####################################################################
+
+qt_add_plugin(QTcpServerConnectionFactory
+ OUTPUT_NAME qmldbg_tcp
+ TYPE qmltooling
+ SOURCES
+ qtcpserverconnection.cpp
+ qtcpserverconnectionfactory.h
+ PUBLIC_LIBRARIES
+ Qt::Network
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmldbg_tcp.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/qtcpserverconnection.json"
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index 30097be77b..b5b6e5d7aa 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -36,7 +36,7 @@ qtHaveModule(quick) {
qmldbg_inspector \
qmldbg_quickprofiler
- qtConfig(qml-network): SUBDIRS += qmldbg_preview
+ qtConfig(settings):qtConfig(qml-network): SUBDIRS += qmldbg_preview
qmldbg_inspector.depends = packetprotocol
qmldbg_quickprofiler.depends = packetprotocol
diff --git a/src/plugins/scenegraph/.prev_CMakeLists.txt b/src/plugins/scenegraph/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..0e65d182ee
--- /dev/null
+++ b/src/plugins/scenegraph/.prev_CMakeLists.txt
@@ -0,0 +1,5 @@
+# Generated from scenegraph.pro.
+
+if(QT_FEATURE_openvg)
+ add_subdirectory(openvg)
+endif()
diff --git a/src/plugins/scenegraph/CMakeLists.txt b/src/plugins/scenegraph/CMakeLists.txt
new file mode 100644
index 0000000000..0e65d182ee
--- /dev/null
+++ b/src/plugins/scenegraph/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Generated from scenegraph.pro.
+
+if(QT_FEATURE_openvg)
+ add_subdirectory(openvg)
+endif()
diff --git a/src/plugins/scenegraph/d3d12/d3d12.json b/src/plugins/scenegraph/d3d12/d3d12.json
deleted file mode 100644
index c450a38556..0000000000
--- a/src/plugins/scenegraph/d3d12/d3d12.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": ["d3d12"]
-}
diff --git a/src/plugins/scenegraph/d3d12/d3d12.pro b/src/plugins/scenegraph/d3d12/d3d12.pro
deleted file mode 100644
index 7192efe449..0000000000
--- a/src/plugins/scenegraph/d3d12/d3d12.pro
+++ /dev/null
@@ -1,73 +0,0 @@
-TARGET = qsgd3d12backend
-
-QT += core-private gui-private qml-private quick-private
-
-PLUGIN_TYPE = scenegraph
-PLUGIN_CLASS_NAME = QSGD3D12Adaptation
-load(qt_plugin)
-
-TRACEPOINT_PROVIDER = $$PWD/d3d12.tracepoints
-CONFIG += qt_tracepoints
-debug_and_release {
- CONFIG(debug, debug|release) {
- INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/debug
- } else {
- INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/release
- }
-} else {
- INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/
-}
-
-QMAKE_TARGET_PRODUCT = "Qt Quick D3D12 Renderer (Qt $$QT_VERSION)"
-QMAKE_TARGET_DESCRIPTION = "Quick D3D12 Renderer for Qt."
-
-SOURCES += \
- $$PWD/qsgd3d12adaptation.cpp \
- $$PWD/qsgd3d12renderloop.cpp \
- $$PWD/qsgd3d12threadedrenderloop.cpp \
- $$PWD/qsgd3d12renderer.cpp \
- $$PWD/qsgd3d12context.cpp \
- $$PWD/qsgd3d12rendercontext.cpp \
- $$PWD/qsgd3d12internalrectanglenode.cpp \
- $$PWD/qsgd3d12material.cpp \
- $$PWD/qsgd3d12builtinmaterials.cpp \
- $$PWD/qsgd3d12texture.cpp \
- $$PWD/qsgd3d12internalimagenode.cpp \
- $$PWD/qsgd3d12glyphnode.cpp \
- $$PWD/qsgd3d12glyphcache.cpp \
- $$PWD/qsgd3d12layer.cpp \
- $$PWD/qsgd3d12shadereffectnode.cpp \
- $$PWD/qsgd3d12painternode.cpp \
- $$PWD/qsgd3d12publicnodes.cpp \
- $$PWD/qsgd3d12spritenode.cpp
-
-NO_PCH_SOURCES += \
- $$PWD/qsgd3d12engine.cpp
-
-HEADERS += \
- $$PWD/qsgd3d12adaptation_p.h \
- $$PWD/qsgd3d12renderloop_p.h \
- $$PWD/qsgd3d12threadedrenderloop_p.h \
- $$PWD/qsgd3d12renderer_p.h \
- $$PWD/qsgd3d12context_p.h \
- $$PWD/qsgd3d12rendercontext_p.h \
- $$PWD/qsgd3d12engine_p.h \
- $$PWD/qsgd3d12engine_p_p.h \
- $$PWD/qsgd3d12internalrectanglenode_p.h \
- $$PWD/qsgd3d12material_p.h \
- $$PWD/qsgd3d12builtinmaterials_p.h \
- $$PWD/qsgd3d12texture_p.h \
- $$PWD/qsgd3d12internalimagenode_p.h \
- $$PWD/qsgd3d12glyphnode_p.h \
- $$PWD/qsgd3d12glyphcache_p.h \
- $$PWD/qsgd3d12layer_p.h \
- $$PWD/qsgd3d12shadereffectnode_p.h \
- $$PWD/qsgd3d12painternode_p.h \
- $$PWD/qsgd3d12publicnodes_p.h \
- $$PWD/qsgd3d12spritenode_p.h
-
-LIBS += -ldxgi -ld3d12 -ld3dcompiler -ldcomp
-
-include($$PWD/shaders/shaders.pri)
-
-OTHER_FILES += $$PWD/d3d12.json
diff --git a/src/plugins/scenegraph/d3d12/d3d12.tracepoints b/src/plugins/scenegraph/d3d12/d3d12.tracepoints
deleted file mode 100644
index e69de29bb2..0000000000
--- a/src/plugins/scenegraph/d3d12/d3d12.tracepoints
+++ /dev/null
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp
deleted file mode 100644
index b93da0ae01..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12adaptation_p.h"
-#include "qsgd3d12renderloop_p.h"
-#include "qsgd3d12threadedrenderloop_p.h"
-#include "qsgd3d12context_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12Adaptation::QSGD3D12Adaptation(QObject *parent)
- : QSGContextPlugin(parent)
-{
-}
-
-QStringList QSGD3D12Adaptation::keys() const
-{
- return QStringList() << QLatin1String("d3d12");
-}
-
-QSGContext *QSGD3D12Adaptation::create(const QString &) const
-{
- if (!contextInstance)
- contextInstance = new QSGD3D12Context;
-
- return contextInstance;
-}
-
-QSGContextFactoryInterface::Flags QSGD3D12Adaptation::flags(const QString &) const
-{
- return QSGContextFactoryInterface::SupportsShaderEffectNode;
-}
-
-QSGRenderLoop *QSGD3D12Adaptation::createWindowManager()
-{
- static bool threaded = false;
- static bool envChecked = false;
- if (!envChecked) {
- envChecked = true;
- threaded = qgetenv("QSG_RENDER_LOOP") == QByteArrayLiteral("threaded");
- }
-
- if (threaded)
- return new QSGD3D12ThreadedRenderLoop;
-
- return new QSGD3D12RenderLoop;
-}
-
-QSGD3D12Context *QSGD3D12Adaptation::contextInstance = nullptr;
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp
deleted file mode 100644
index 312e8c19cd..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12builtinmaterials_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include <QQuickWindow>
-#include <QtCore/qmath.h>
-#include <QtGui/private/qfixed_p.h>
-
-#include "vs_vertexcolor.hlslh"
-#include "ps_vertexcolor.hlslh"
-#include "vs_flatcolor.hlslh"
-#include "ps_flatcolor.hlslh"
-#include "vs_smoothcolor.hlslh"
-#include "ps_smoothcolor.hlslh"
-#include "vs_texture.hlslh"
-#include "ps_texture.hlslh"
-#include "vs_smoothtexture.hlslh"
-#include "ps_smoothtexture.hlslh"
-#include "vs_textmask.hlslh"
-#include "ps_textmask24.hlslh"
-#include "ps_textmask32.hlslh"
-#include "ps_textmask8.hlslh"
-#include "vs_styledtext.hlslh"
-#include "ps_styledtext.hlslh"
-#include "vs_outlinedtext.hlslh"
-#include "ps_outlinedtext.hlslh"
-
-QT_BEGIN_NAMESPACE
-
-// NB! In HLSL constant buffer data is packed into 4-byte boundaries and, more
-// importantly, it is packed so that it does not cross a 16-byte (float4)
-// boundary. Hence the need for padding in some cases.
-
-static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity)
-{
- const float o = c.w() * globalOpacity;
- return QVector4D(c.x() * o, c.y() * o, c.z() * o, o);
-}
-
-static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity)
-{
- const float o = c.alphaF() * globalOpacity;
- return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o);
-}
-
-static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b)
-{
- if (a.x() != b.x())
- return a.x() > b.x() ? 1 : -1;
- if (a.y() != b.y())
- return a.y() > b.y() ? 1 : -1;
- if (a.z() != b.z())
- return a.z() > b.z() ? 1 : -1;
- if (a.w() != b.w())
- return a.w() > b.w() ? 1 : -1;
- return 0;
-}
-
-QSGMaterialType QSGD3D12VertexColorMaterial::mtype;
-
-QSGMaterialType *QSGD3D12VertexColorMaterial::type() const
-{
- return &QSGD3D12VertexColorMaterial::mtype;
-}
-
-int QSGD3D12VertexColorMaterial::compare(const QSGMaterial *other) const
-{
- Q_UNUSED(other);
- Q_ASSERT(other && type() == other->type());
- // As the vertex color material has all its state in the vertex attributes
- // defined by the geometry, all such materials will be equal.
- return 0;
-}
-
-static const int VERTEX_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int VERTEX_COLOR_CB_SIZE_1 = sizeof(float); // float
-static const int VERTEX_COLOR_CB_SIZE = VERTEX_COLOR_CB_SIZE_0 + VERTEX_COLOR_CB_SIZE_1;
-
-int QSGD3D12VertexColorMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(VERTEX_COLOR_CB_SIZE);
-}
-
-void QSGD3D12VertexColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_VertexColor;
- pipelineState->shaders.vsSize = sizeof(g_VS_VertexColor);
- pipelineState->shaders.ps = g_PS_VertexColor;
- pipelineState->shaders.psSize = sizeof(g_PS_VertexColor);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), VERTEX_COLOR_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += VERTEX_COLOR_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, VERTEX_COLOR_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
-
- return r;
-}
-
-QSGD3D12FlatColorMaterial::QSGD3D12FlatColorMaterial()
- : m_color(QColor(255, 255, 255))
-{
-}
-
-QSGMaterialType QSGD3D12FlatColorMaterial::mtype;
-
-QSGMaterialType *QSGD3D12FlatColorMaterial::type() const
-{
- return &QSGD3D12FlatColorMaterial::mtype;
-}
-
-int QSGD3D12FlatColorMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12FlatColorMaterial *o = static_cast<const QSGD3D12FlatColorMaterial *>(other);
- return m_color.rgba() - o->color().rgba();
-}
-
-static const int FLAT_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int FLAT_COLOR_CB_SIZE_1 = 4 * sizeof(float); // float4
-static const int FLAT_COLOR_CB_SIZE = FLAT_COLOR_CB_SIZE_0 + FLAT_COLOR_CB_SIZE_1;
-
-int QSGD3D12FlatColorMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(FLAT_COLOR_CB_SIZE);
-}
-
-void QSGD3D12FlatColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_FlatColor;
- pipelineState->shaders.vsSize = sizeof(g_VS_FlatColor);
- pipelineState->shaders.ps = g_PS_FlatColor;
- pipelineState->shaders.psSize = sizeof(g_PS_FlatColor);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12FlatColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), FLAT_COLOR_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += FLAT_COLOR_CB_SIZE_0;
-
- const QVector4D color = qsg_premultiply(m_color, state.opacity());
- const float f[] = { color.x(), color.y(), color.z(), color.w() };
- if (state.isOpacityDirty() || memcmp(p, f, FLAT_COLOR_CB_SIZE_1)) {
- memcpy(p, f, FLAT_COLOR_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
-
- return r;
-}
-
-void QSGD3D12FlatColorMaterial::setColor(const QColor &color)
-{
- m_color = color;
- setFlag(Blending, m_color.alpha() != 0xFF);
-}
-
-QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial()
-{
- setFlag(RequiresFullMatrixExceptTranslate, true);
- setFlag(Blending, true);
-}
-
-QSGMaterialType QSGD3D12SmoothColorMaterial::mtype;
-
-QSGMaterialType *QSGD3D12SmoothColorMaterial::type() const
-{
- return &QSGD3D12SmoothColorMaterial::mtype;
-}
-
-int QSGD3D12SmoothColorMaterial::compare(const QSGMaterial *other) const
-{
- Q_UNUSED(other);
- Q_ASSERT(other && type() == other->type());
- return 0;
-}
-
-static const int SMOOTH_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int SMOOTH_COLOR_CB_SIZE_1 = sizeof(float); // float
-static const int SMOOTH_COLOR_CB_SIZE_2 = 2 * sizeof(float); // float2
-static const int SMOOTH_COLOR_CB_SIZE = SMOOTH_COLOR_CB_SIZE_0 + SMOOTH_COLOR_CB_SIZE_1 + SMOOTH_COLOR_CB_SIZE_2;
-
-int QSGD3D12SmoothColorMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_COLOR_CB_SIZE);
-}
-
-void QSGD3D12SmoothColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_SmoothColor;
- pipelineState->shaders.vsSize = sizeof(g_VS_SmoothColor);
- pipelineState->shaders.ps = g_PS_SmoothColor;
- pipelineState->shaders.psSize = sizeof(g_PS_SmoothColor);
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), SMOOTH_COLOR_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_COLOR_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, SMOOTH_COLOR_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_COLOR_CB_SIZE_1;
-
- if (state.isMatrixDirty()) {
- const QRect viewport = state.viewportRect();
- const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() };
- memcpy(p, v, SMOOTH_COLOR_CB_SIZE_2);
- r |= UpdatedConstantBuffer;
- }
-
- return r;
-}
-
-QSGMaterialType QSGD3D12TextureMaterial::mtype;
-
-QSGMaterialType *QSGD3D12TextureMaterial::type() const
-{
- return &QSGD3D12TextureMaterial::mtype;
-}
-
-int QSGD3D12TextureMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12TextureMaterial *o = static_cast<const QSGD3D12TextureMaterial *>(other);
- if (int diff = m_texture->textureId() - o->texture()->textureId())
- return diff;
- return int(m_filtering) - int(o->m_filtering);
-}
-
-static const int TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int TEXTURE_CB_SIZE_1 = sizeof(float); // float
-static const int TEXTURE_CB_SIZE = TEXTURE_CB_SIZE_0 + TEXTURE_CB_SIZE_1;
-
-int QSGD3D12TextureMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(TEXTURE_CB_SIZE);
-}
-
-void QSGD3D12TextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_Texture;
- pipelineState->shaders.vsSize = sizeof(g_VS_Texture);
- pipelineState->shaders.ps = g_PS_Texture;
- pipelineState->shaders.psSize = sizeof(g_PS_Texture);
-
- pipelineState->shaders.rootSig.textureViewCount = 1;
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12TextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), TEXTURE_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += TEXTURE_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, TEXTURE_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
-
- Q_ASSERT(m_texture);
- m_texture->setFiltering(m_filtering);
- m_texture->setMipmapFiltering(m_mipmap_filtering);
- m_texture->setHorizontalWrapMode(m_horizontal_wrap);
- m_texture->setVerticalWrapMode(m_vertical_wrap);
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- if (m_filtering == QSGTexture::Linear)
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
- else
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
-
- m_texture->bind();
-
- return r;
-}
-
-void QSGD3D12TextureMaterial::setTexture(QSGTexture *texture)
-{
- m_texture = texture;
- setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false);
-}
-
-QSGD3D12SmoothTextureMaterial::QSGD3D12SmoothTextureMaterial()
-{
- setFlag(RequiresFullMatrixExceptTranslate, true);
- setFlag(Blending, true);
-}
-
-QSGMaterialType QSGD3D12SmoothTextureMaterial::mtype;
-
-QSGMaterialType *QSGD3D12SmoothTextureMaterial::type() const
-{
- return &QSGD3D12SmoothTextureMaterial::mtype;
-}
-
-int QSGD3D12SmoothTextureMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12SmoothTextureMaterial *o = static_cast<const QSGD3D12SmoothTextureMaterial *>(other);
- if (int diff = m_texture->textureId() - o->texture()->textureId())
- return diff;
- return int(m_filtering) - int(o->m_filtering);
-}
-
-static const int SMOOTH_TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int SMOOTH_TEXTURE_CB_SIZE_1 = sizeof(float); // float
-static const int SMOOTH_TEXTURE_CB_SIZE_2 = 2 * sizeof(float); // float2
-static const int SMOOTH_TEXTURE_CB_SIZE = SMOOTH_TEXTURE_CB_SIZE_0 + SMOOTH_TEXTURE_CB_SIZE_1 + SMOOTH_TEXTURE_CB_SIZE_2;
-
-int QSGD3D12SmoothTextureMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_TEXTURE_CB_SIZE);
-}
-
-void QSGD3D12SmoothTextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_SmoothTexture;
- pipelineState->shaders.vsSize = sizeof(g_VS_SmoothTexture);
- pipelineState->shaders.ps = g_PS_SmoothTexture;
- pipelineState->shaders.psSize = sizeof(g_PS_SmoothTexture);
-
- pipelineState->shaders.rootSig.textureViewCount = 1;
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), SMOOTH_TEXTURE_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_TEXTURE_CB_SIZE_0;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, SMOOTH_TEXTURE_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
- p += SMOOTH_TEXTURE_CB_SIZE_1;
-
- if (state.isMatrixDirty()) {
- const QRect viewport = state.viewportRect();
- const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() };
- memcpy(p, v, SMOOTH_TEXTURE_CB_SIZE_2);
- r |= UpdatedConstantBuffer;
- }
-
- Q_ASSERT(m_texture);
- m_texture->setFiltering(m_filtering);
- m_texture->setMipmapFiltering(m_mipmap_filtering);
- m_texture->setHorizontalWrapMode(m_horizontal_wrap);
- m_texture->setVerticalWrapMode(m_vertical_wrap);
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- if (m_filtering == QSGTexture::Linear)
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest;
- else
- tv.filter = m_mipmap_filtering == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
-
- m_texture->bind();
-
- return r;
-}
-
-QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc,
- const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
- : m_styleType(styleType),
- m_rc(rc),
- m_font(font)
-{
- setFlag(Blending, true);
-
- QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
- if (QFontEngine *fontEngine = fontD->fontEngine) {
- if (glyphFormat == QFontEngine::Format_None)
- glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None
- ? fontEngine->glyphFormat : QFontEngine::Format_A32;
-
- QSGD3D12Engine *d3dengine = rc->engine();
- const float devicePixelRatio = d3dengine->windowDevicePixelRatio();
- QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio);
- if (!fontEngine->supportsTransformation(glyphCacheTransform))
- glyphCacheTransform = QTransform();
-
- m_glyphCache = fontEngine->glyphCache(d3dengine, glyphFormat, glyphCacheTransform);
- if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) {
- m_glyphCache = new QSGD3D12GlyphCache(d3dengine, glyphFormat, glyphCacheTransform);
- fontEngine->setGlyphCache(d3dengine, m_glyphCache.data());
- rc->registerFontengineForCleanup(fontEngine);
- }
- }
-}
-
-QSGMaterialType QSGD3D12TextMaterial::mtype[QSGD3D12TextMaterial::NTextMaterialTypes];
-
-QSGMaterialType *QSGD3D12TextMaterial::type() const
-{
- // Format_A32 has special blend settings and therefore two materials with
- // the same style but different formats where one is A32 are treated as
- // different. This way the renderer can manage the pipeline state properly.
- const int matStyle = m_styleType * 2;
- const int matFormat = glyphCache()->glyphFormat() != QFontEngine::Format_A32 ? 0 : 1;
- return &QSGD3D12TextMaterial::mtype[matStyle + matFormat];
-}
-
-int QSGD3D12TextMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12TextMaterial *o = static_cast<const QSGD3D12TextMaterial *>(other);
- if (m_styleType != o->m_styleType)
- return m_styleType - o->m_styleType;
- if (m_glyphCache != o->m_glyphCache)
- return m_glyphCache.data() < o->m_glyphCache.data() ? -1 : 1;
- if (m_styleShift != o->m_styleShift)
- return m_styleShift.y() - o->m_styleShift.y();
- int styleColorDiff = qsg_colorDiff(m_styleColor, o->m_styleColor);
- if (styleColorDiff)
- return styleColorDiff;
- return qsg_colorDiff(m_color, o->m_color);
-}
-
-static const int TEXT_CB_SIZE_0 = 16 * sizeof(float); // float4x4 mvp
-static const int TEXT_CB_SIZE_1 = 2 * sizeof(float); // float2 textureScale
-static const int TEXT_CB_SIZE_2 = sizeof(float); // float dpr
-static const int TEXT_CB_SIZE_3 = sizeof(float); // float color
-static const int TEXT_CB_SIZE_4 = 4 * sizeof(float); // float4 colorVec
-static const int TEXT_CB_SIZE_5 = 2 * sizeof(float); // float2 shift
-static const int TEXT_CB_SIZE_5_PADDING = 2 * sizeof(float); // float2 padding (the next float4 would cross the 16-byte boundary)
-static const int TEXT_CB_SIZE_6 = 4 * sizeof(float); // float4 styleColor
-static const int TEXT_CB_SIZE = TEXT_CB_SIZE_0 + TEXT_CB_SIZE_1 + TEXT_CB_SIZE_2 + TEXT_CB_SIZE_3
- + TEXT_CB_SIZE_4 + TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING + TEXT_CB_SIZE_6;
-
-int QSGD3D12TextMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(TEXT_CB_SIZE);
-}
-
-void QSGD3D12TextMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- if (m_styleType == Normal) {
- pipelineState->shaders.vs = g_VS_TextMask;
- pipelineState->shaders.vsSize = sizeof(g_VS_TextMask);
- switch (glyphCache()->glyphFormat()) {
- case QFontEngine::Format_A32:
- pipelineState->shaders.ps = g_PS_TextMask24;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask24);
- break;
- case QFontEngine::Format_ARGB:
- pipelineState->shaders.ps = g_PS_TextMask32;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask32);
- break;
- default:
- pipelineState->shaders.ps = g_PS_TextMask8;
- pipelineState->shaders.psSize = sizeof(g_PS_TextMask8);
- break;
- }
- } else if (m_styleType == Outlined) {
- pipelineState->shaders.vs = g_VS_OutlinedText;
- pipelineState->shaders.vsSize = sizeof(g_VS_OutlinedText);
- pipelineState->shaders.ps = g_PS_OutlinedText;
- pipelineState->shaders.psSize = sizeof(g_PS_OutlinedText);
- } else {
- pipelineState->shaders.vs = g_VS_StyledText;
- pipelineState->shaders.vsSize = sizeof(g_VS_StyledText);
- pipelineState->shaders.ps = g_PS_StyledText;
- pipelineState->shaders.psSize = sizeof(g_PS_StyledText);
- }
-
- pipelineState->shaders.rootSig.textureViewCount = 1;
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
- // can freely change the state due to the way type() works
- pipelineState->blend = QSGD3D12PipelineState::BlendColor;
- extraState->blendFactor = m_color;
- r |= UpdatedBlendFactor; // must be set always as this affects the command list
- }
-
- if (state.isMatrixDirty()) {
- memcpy(p, state.combinedMatrix().constData(), TEXT_CB_SIZE_0);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_0;
-
- const QSize sz = glyphCache()->currentSize();
- const float textureScale[] = { 1.0f / sz.width(), 1.0f / sz.height() };
- if (state.isCachedMaterialDataDirty() || memcmp(p, textureScale, TEXT_CB_SIZE_1)) {
- memcpy(p, textureScale, TEXT_CB_SIZE_1);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_1;
-
- const float dpr = m_rc->engine()->windowDevicePixelRatio();
- if (state.isCachedMaterialDataDirty() || memcmp(p, &dpr, TEXT_CB_SIZE_2)) {
- memcpy(p, &dpr, TEXT_CB_SIZE_2);
- r |= UpdatedConstantBuffer;
- }
- p += TEXT_CB_SIZE_2;
-
- if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) {
- const QVector4D color = qsg_premultiply(m_color, state.opacity());
- const float alpha = color.w();
- if (state.isOpacityDirty() || memcmp(p, &alpha, TEXT_CB_SIZE_3)) {
- memcpy(p, &alpha, TEXT_CB_SIZE_3);
- r |= UpdatedConstantBuffer;
- }
- } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) {
- const float opacity = m_color.w() * state.opacity();
- if (state.isOpacityDirty() || memcmp(p, &opacity, TEXT_CB_SIZE_3)) {
- memcpy(p, &opacity, TEXT_CB_SIZE_3);
- r |= UpdatedConstantBuffer;
- }
- } else {
- const QVector4D color = qsg_premultiply(m_color, state.opacity());
- const float f[] = { color.x(), color.y(), color.z(), color.w() };
- if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_4)) {
- memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4);
- r |= UpdatedConstantBuffer;
- }
- }
- p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4;
-
- if (m_styleType == Styled) {
- const float f[] = { m_styleShift.x(), m_styleShift.y() };
- if (state.isCachedMaterialDataDirty() || memcmp(p, f, TEXT_CB_SIZE_5)) {
- memcpy(p, f, TEXT_CB_SIZE_5);
- r |= UpdatedConstantBuffer;
- }
- }
- p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING;
-
- if (m_styleType == Styled || m_styleType == Outlined) {
- const QVector4D color = qsg_premultiply(m_styleColor, state.opacity());
- const float f[] = { color.x(), color.y(), color.z(), color.w() };
- if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_6)) {
- memcpy(p, f, TEXT_CB_SIZE_6);
- r |= UpdatedConstantBuffer;
- }
- }
-
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]);
- tv.filter = QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = QSGD3D12TextureView::AddressClamp;
- tv.addressModeVert = QSGD3D12TextureView::AddressClamp;
-
- glyphCache()->useTexture();
-
- return r;
-}
-
-void QSGD3D12TextMaterial::populate(const QPointF &p,
- const QVector<quint32> &glyphIndexes,
- const QVector<QPointF> &glyphPositions,
- QSGGeometry *geometry,
- QRectF *boundingRect,
- QPointF *baseLine,
- const QMargins &margins)
-{
- Q_ASSERT(m_font.isValid());
- QVector<QFixedPoint> fixedPointPositions;
- const int glyphPositionsSize = glyphPositions.size();
- fixedPointPositions.reserve(glyphPositionsSize);
- for (int i=0; i < glyphPositionsSize; ++i)
- fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));
-
- QSGD3D12GlyphCache *cache = glyphCache();
- QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
- cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(),
- fixedPointPositions.data());
- cache->fillInPendingGlyphs();
-
- int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat());
-
- float glyphCacheScaleX = cache->transform().m11();
- float glyphCacheScaleY = cache->transform().m22();
- float glyphCacheInverseScaleX = 1.0 / glyphCacheScaleX;
- float glyphCacheInverseScaleY = 1.0 / glyphCacheScaleY;
-
- Q_ASSERT(geometry->indexType() == QSGGeometry::UnsignedShortType);
- geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6);
- QVector4D *vp = reinterpret_cast<QVector4D *>(geometry->vertexDataAsTexturedPoint2D());
- Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D));
- ushort *ip = geometry->indexDataAsUShort();
-
- QPointF position(p.x(), p.y() - m_font.ascent());
- bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
- for (int i = 0; i < glyphIndexes.size(); ++i) {
- QFixed subPixelPosition;
- if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));
-
- QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
- const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
-
- QPointF glyphPosition = glyphPositions.at(i) + position;
- float x = (qFloor(glyphPosition.x() * glyphCacheScaleX) * glyphCacheInverseScaleX)
- + (c.baseLineX * glyphCacheInverseScaleX) - margin;
- float y = (qRound(glyphPosition.y() * glyphCacheScaleY) * glyphCacheInverseScaleY)
- - (c.baseLineY * glyphCacheInverseScaleY) - margin;
-
- float w = c.w * glyphCacheInverseScaleX;
- float h = c.h * glyphCacheInverseScaleY;
-
- *boundingRect |= QRectF(x + margin, y + margin, w, h);
-
- float cx1 = x - margins.left();
- float cx2 = x + w + margins.right();
- float cy1 = y - margins.top();
- float cy2 = y + h + margins.bottom();
-
- float tx1 = c.x - margins.left();
- float tx2 = c.x + c.w + margins.right();
- float ty1 = c.y - margins.top();
- float ty2 = c.y + c.h + margins.bottom();
-
- if (baseLine->isNull())
- *baseLine = glyphPosition;
-
- vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1);
- vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1);
- vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2);
- vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2);
-
- int o = i * 4;
- ip[6 * i + 0] = o + 0;
- ip[6 * i + 1] = o + 2;
- ip[6 * i + 2] = o + 3;
- ip[6 * i + 3] = o + 3;
- ip[6 * i + 4] = o + 1;
- ip[6 * i + 5] = o + 0;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h
deleted file mode 100644
index 8e488f8cd1..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12BUILTINMATERIALS_P_H
-#define QSGD3D12BUILTINMATERIALS_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 "qsgd3d12material_p.h"
-#include "qsgd3d12glyphcache_p.h"
-#include <private/qsgtexture_p.h>
-#include <QRawFont>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-
-class QSGD3D12VertexColorMaterial : public QSGD3D12Material
-{
-public:
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
-private:
- static QSGMaterialType mtype;
-};
-
-class QSGD3D12FlatColorMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12FlatColorMaterial();
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setColor(const QColor &color);
- QColor color() const { return m_color; }
-
-private:
- static QSGMaterialType mtype;
- QColor m_color;
-};
-
-class QSGD3D12SmoothColorMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12SmoothColorMaterial();
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
-private:
- static QSGMaterialType mtype;
-};
-
-class QSGD3D12TextureMaterial : public QSGD3D12Material
-{
-public:
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setTexture(QSGTexture *texture);
- QSGTexture *texture() const { return m_texture; }
-
- void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; }
- QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; }
-
- void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; }
- QSGTexture::Filtering filtering() const { return m_filtering; }
-
- void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; }
- QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; }
-
- void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; }
- QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; }
-
-private:
- static QSGMaterialType mtype;
-
- QSGTexture *m_texture = nullptr;
- QSGTexture::Filtering m_filtering = QSGTexture::Nearest;
- QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None;
- QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge;
- QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge;
-};
-
-class QSGD3D12SmoothTextureMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12SmoothTextureMaterial();
-
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setTexture(QSGTexture *texture) { m_texture = texture; }
- QSGTexture *texture() const { return m_texture; }
-
- void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; }
- QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; }
-
- void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; }
- QSGTexture::Filtering filtering() const { return m_filtering; }
-
- void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; }
- QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; }
-
- void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; }
- QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; }
-
-private:
- static QSGMaterialType mtype;
-
- QSGTexture *m_texture = nullptr;
- QSGTexture::Filtering m_filtering = QSGTexture::Nearest;
- QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None;
- QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge;
- QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge;
-};
-
-class QSGD3D12TextMaterial : public QSGD3D12Material
-{
-public:
- enum StyleType {
- Normal,
- Styled,
- Outlined,
-
- NStyleTypes
- };
- QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, const QRawFont &font,
- QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None);
-
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void setColor(const QColor &c) { m_color = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); }
- void setColor(const QVector4D &color) { m_color = color; }
- const QVector4D &color() const { return m_color; }
-
- void setStyleShift(const QVector2D &shift) { m_styleShift = shift; }
- const QVector2D &styleShift() const { return m_styleShift; }
-
- void setStyleColor(const QColor &c) { m_styleColor = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); }
- void setStyleColor(const QVector4D &color) { m_styleColor = color; }
- const QVector4D &styleColor() const { return m_styleColor; }
-
- void populate(const QPointF &position,
- const QVector<quint32> &glyphIndexes, const QVector<QPointF> &glyphPositions,
- QSGGeometry *geometry, QRectF *boundingRect, QPointF *baseLine,
- const QMargins &margins = QMargins(0, 0, 0, 0));
-
- QSGD3D12GlyphCache *glyphCache() const { return static_cast<QSGD3D12GlyphCache *>(m_glyphCache.data()); }
-
-private:
- static const int NTextMaterialTypes = NStyleTypes * 2;
- static QSGMaterialType mtype[NTextMaterialTypes];
- StyleType m_styleType;
- QSGD3D12RenderContext *m_rc;
- QVector4D m_color;
- QVector2D m_styleShift;
- QVector4D m_styleColor;
- QRawFont m_font;
- QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12BUILTINMATERIALS_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp
deleted file mode 100644
index f9bd04aa54..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12context_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12internalrectanglenode_p.h"
-#include "qsgd3d12internalimagenode_p.h"
-#include "qsgd3d12glyphnode_p.h"
-#include "qsgd3d12layer_p.h"
-#include "qsgd3d12shadereffectnode_p.h"
-#include "qsgd3d12painternode_p.h"
-#include "qsgd3d12publicnodes_p.h"
-#include "qsgd3d12spritenode_p.h"
-#include <QtQuick/qquickwindow.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGRenderContext *QSGD3D12Context::createRenderContext()
-{
- return new QSGD3D12RenderContext(this);
-}
-
-QSGInternalRectangleNode *QSGD3D12Context::createInternalRectangleNode()
-{
- return new QSGD3D12InternalRectangleNode;
-}
-
-QSGInternalImageNode *QSGD3D12Context::createInternalImageNode(QSGRenderContext *renderContext)
-{
- Q_UNUSED(renderContext);
- return new QSGD3D12InternalImageNode;
-}
-
-QSGPainterNode *QSGD3D12Context::createPainterNode(QQuickPaintedItem *item)
-{
- return new QSGD3D12PainterNode(item);
-}
-
-QSGGlyphNode *QSGD3D12Context::createGlyphNode(QSGRenderContext *renderContext, bool preferNativeGlyphNode)
-{
- Q_UNUSED(preferNativeGlyphNode);
- // ### distance field text rendering is not supported atm
-
- QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext);
- return new QSGD3D12GlyphNode(rc);
-}
-
-QSGLayer *QSGD3D12Context::createLayer(QSGRenderContext *renderContext)
-{
- QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext);
- return new QSGD3D12Layer(rc);
-}
-
-QSGGuiThreadShaderEffectManager *QSGD3D12Context::createGuiThreadShaderEffectManager()
-{
- return new QSGD3D12GuiThreadShaderEffectManager;
-}
-
-QSGShaderEffectNode *QSGD3D12Context::createShaderEffectNode(QSGRenderContext *renderContext,
- QSGGuiThreadShaderEffectManager *mgr)
-{
- QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext);
- QSGD3D12GuiThreadShaderEffectManager *dmgr = static_cast<QSGD3D12GuiThreadShaderEffectManager *>(mgr);
- return new QSGD3D12ShaderEffectNode(rc, dmgr);
-}
-
-QSize QSGD3D12Context::minimumFBOSize() const
-{
- return QSize(16, 16);
-}
-
-QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const
-{
- QSurfaceFormat format = QSurfaceFormat::defaultFormat();
-
- if (QQuickWindow::hasDefaultAlphaBuffer())
- format.setAlphaBufferSize(8);
-
- return format;
-}
-
-QSGRendererInterface *QSGD3D12Context::rendererInterface(QSGRenderContext *renderContext)
-{
- return static_cast<QSGD3D12RenderContext *>(renderContext);
-}
-
-QSGRectangleNode *QSGD3D12Context::createRectangleNode()
-{
- return new QSGD3D12RectangleNode;
-}
-
-QSGImageNode *QSGD3D12Context::createImageNode()
-{
- return new QSGD3D12ImageNode;
-}
-
-QSGNinePatchNode *QSGD3D12Context::createNinePatchNode()
-{
- return new QSGD3D12NinePatchNode;
-}
-
-QSGSpriteNode *QSGD3D12Context::createSpriteNode()
-{
- return new QSGD3D12SpriteNode;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h
deleted file mode 100644
index 382183fef6..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12CONTEXT_P_H
-#define QSGD3D12CONTEXT_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 <private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Context : public QSGContext
-{
-public:
- QSGD3D12Context(QObject *parent = 0) : QSGContext(parent) { }
-
- QSGRenderContext *createRenderContext() override;
- QSGInternalRectangleNode *createInternalRectangleNode() override;
- QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) override;
- QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
- QSGGlyphNode *createGlyphNode(QSGRenderContext *renderContext, bool preferNativeGlyphNode) override;
- QSGLayer *createLayer(QSGRenderContext *renderContext) override;
- QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager() override;
- QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext,
- QSGGuiThreadShaderEffectManager *mgr) override;
- QSize minimumFBOSize() const override;
- QSurfaceFormat defaultSurfaceFormat() const override;
- QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
- QSGRectangleNode *createRectangleNode() override;
- QSGImageNode *createImageNode() override;
- QSGNinePatchNode *createNinePatchNode() override;
- QSGSpriteNode *createSpriteNode() override;
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12CONTEXT_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
deleted file mode 100644
index 75bde2c66b..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
+++ /dev/null
@@ -1,3280 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12engine_p_p.h"
-#include "cs_mipmapgen.hlslh"
-#include <QString>
-#include <QColor>
-#include <QLoggingCategory>
-#include <qmath.h>
-#include <qalgorithms.h>
-
-// Comment out to disable DeviceLossTester functionality in order to reduce
-// code size and improve startup perf a tiny bit.
-#define DEVLOSS_TEST
-
-#ifdef DEVLOSS_TEST
-#include "cs_tdr.hlslh"
-#endif
-
-#ifdef Q_OS_WINRT
-#include <QtCore/private/qeventdispatcher_winrt_p.h>
-#include <functional>
-#include <windows.ui.xaml.h>
-#include <windows.ui.xaml.media.dxinterop.h>
-#endif
-
-#include <comdef.h>
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-DECLARE_DEBUG_VAR(descheap)
-DECLARE_DEBUG_VAR(buffer)
-DECLARE_DEBUG_VAR(texture)
-
-// Except for system info on startup.
-Q_LOGGING_CATEGORY(QSG_LOG_INFO_GENERAL, "qt.scenegraph.general")
-
-
-// Any changes to the defaults below must be reflected in adaptations.qdoc as
-// well and proven by qmlbench or similar.
-
-static const int DEFAULT_SWAP_CHAIN_BUFFER_COUNT = 3;
-static const int DEFAULT_FRAME_IN_FLIGHT_COUNT = 2;
-static const int DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY = 0;
-
-static const int MAX_DRAW_CALLS_PER_LIST = 4096;
-
-static const int MAX_CACHED_ROOTSIG = 16;
-static const int MAX_CACHED_PSO = 64;
-
-static const int GPU_CBVSRVUAV_DESCRIPTORS = 512;
-
-static const DXGI_FORMAT RT_COLOR_FORMAT = DXGI_FORMAT_R8G8B8A8_UNORM;
-
-static const int BUCKETS_PER_HEAP = 8; // must match freeMap
-static const int DESCRIPTORS_PER_BUCKET = 32; // the bit map (freeMap) is quint32
-static const int MAX_DESCRIPTORS_PER_HEAP = BUCKETS_PER_HEAP * DESCRIPTORS_PER_BUCKET;
-
-static QString comErrorMessage(HRESULT hr)
-{
-#ifndef Q_OS_WINRT
- const _com_error comError(hr);
-#else
- const _com_error comError(hr, nullptr);
-#endif
- QString result = QLatin1String("Error 0x") + QString::number(ulong(hr), 16);
- if (const wchar_t *msg = comError.ErrorMessage())
- result += QLatin1String(": ") + QString::fromWCharArray(msg);
- return result;
-}
-
-D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12CPUDescriptorHeapManager::allocate(D3D12_DESCRIPTOR_HEAP_TYPE type)
-{
- D3D12_CPU_DESCRIPTOR_HANDLE h = {};
- for (Heap &heap : m_heaps) {
- if (heap.type == type) {
- for (int bucket = 0; bucket < _countof(heap.freeMap); ++bucket)
- if (heap.freeMap[bucket]) {
- uint freePos = qCountTrailingZeroBits(heap.freeMap[bucket]);
- heap.freeMap[bucket] &= ~(1UL << freePos);
- if (Q_UNLIKELY(debug_descheap()))
- qDebug("descriptor handle heap %p type %x reserve in bucket %d index %d", &heap, type, bucket, freePos);
- freePos += bucket * DESCRIPTORS_PER_BUCKET;
- h = heap.start;
- h.ptr += freePos * heap.handleSize;
- return h;
- }
- }
- }
-
- Heap heap;
- heap.type = type;
- heap.handleSize = m_handleSizes[type];
-
- D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
- heapDesc.NumDescriptors = MAX_DESCRIPTORS_PER_HEAP;
- heapDesc.Type = type;
- // The heaps created here are _never_ shader-visible.
-
- HRESULT hr = m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap.heap));
- if (FAILED(hr)) {
- qWarning("Failed to create heap with type 0x%x: %s",
- type, qPrintable(comErrorMessage(hr)));
- return h;
- }
-
- heap.start = heap.heap->GetCPUDescriptorHandleForHeapStart();
-
- if (Q_UNLIKELY(debug_descheap()))
- qDebug("new descriptor heap, type %x, start %llu", type, heap.start.ptr);
-
- heap.freeMap[0] = 0xFFFFFFFE;
- for (int i = 1; i < _countof(heap.freeMap); ++i)
- heap.freeMap[i] = 0xFFFFFFFF;
-
- h = heap.start;
-
- m_heaps.append(heap);
-
- return h;
-}
-
-void QSGD3D12CPUDescriptorHeapManager::release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type)
-{
- for (Heap &heap : m_heaps) {
- if (heap.type == type
- && handle.ptr >= heap.start.ptr
- && handle.ptr < heap.start.ptr + heap.handleSize * MAX_DESCRIPTORS_PER_HEAP) {
- unsigned long pos = (handle.ptr - heap.start.ptr) / heap.handleSize;
- const int bucket = pos / DESCRIPTORS_PER_BUCKET;
- const int indexInBucket = pos - bucket * DESCRIPTORS_PER_BUCKET;
- heap.freeMap[bucket] |= 1UL << indexInBucket;
- if (Q_UNLIKELY(debug_descheap()))
- qDebug("free descriptor handle heap %p type %x bucket %d index %d", &heap, type, bucket, indexInBucket);
- return;
- }
- }
- qWarning("QSGD3D12CPUDescriptorHeapManager: Attempted to release untracked descriptor handle %llu of type %d", handle.ptr, type);
-}
-
-void QSGD3D12CPUDescriptorHeapManager::initialize(ID3D12Device *device)
-{
- m_device = device;
-
- for (int i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i)
- m_handleSizes[i] = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE(i));
-}
-
-void QSGD3D12CPUDescriptorHeapManager::releaseResources()
-{
- for (Heap &heap : m_heaps)
- heap.heap = nullptr;
-
- m_heaps.clear();
-
- m_device = nullptr;
-}
-
-// One device per process, one everything else (engine) per window.
-Q_GLOBAL_STATIC(QSGD3D12DeviceManager, deviceManager)
-
-static void getHardwareAdapter(IDXGIFactory1 *factory, IDXGIAdapter1 **outAdapter)
-{
- const D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0;
- ComPtr<IDXGIAdapter1> adapter;
- DXGI_ADAPTER_DESC1 desc;
-
- for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
- DXGI_ADAPTER_DESC1 desc;
- adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qCDebug(QSG_LOG_INFO_GENERAL, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
- }
-
- if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) {
- const int adapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
- if (SUCCEEDED(factory->EnumAdapters1(adapterIndex, &adapter))) {
- adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- HRESULT hr = D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr);
- if (SUCCEEDED(hr)) {
- qCDebug(QSG_LOG_INFO_GENERAL, "Using requested adapter '%s'", qPrintable(name));
- *outAdapter = adapter.Detach();
- return;
- } else {
- qWarning("Failed to create device for requested adapter '%s': %s",
- qPrintable(name), qPrintable(comErrorMessage(hr)));
- }
- }
- }
-
- for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
- adapter->GetDesc1(&desc);
- if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
- continue;
-
- if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) {
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qCDebug(QSG_LOG_INFO_GENERAL, "Using adapter '%s'", qPrintable(name));
- break;
- }
- }
-
- *outAdapter = adapter.Detach();
-}
-
-ID3D12Device *QSGD3D12DeviceManager::ref()
-{
- ensureCreated();
- m_ref.ref();
- return m_device.Get();
-}
-
-void QSGD3D12DeviceManager::unref()
-{
- if (!m_ref.deref()) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("destroying d3d device");
- m_device = nullptr;
- m_factory = nullptr;
- }
-}
-
-void QSGD3D12DeviceManager::deviceLossDetected()
-{
- for (DeviceLossObserver *observer : qAsConst(m_observers))
- observer->deviceLost();
-
- // Nothing else to do here. All windows are expected to release their
- // resources and call unref() in response immediately.
-}
-
-IDXGIFactory4 *QSGD3D12DeviceManager::dxgi()
-{
- ensureCreated();
- return m_factory.Get();
-}
-
-void QSGD3D12DeviceManager::ensureCreated()
-{
- if (m_device)
- return;
-
- HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&m_factory));
- if (FAILED(hr)) {
- qWarning("Failed to create DXGI: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
-
- ComPtr<IDXGIAdapter1> adapter;
- getHardwareAdapter(m_factory.Get(), &adapter);
-
- bool warp = true;
- if (adapter) {
- HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
- if (SUCCEEDED(hr))
- warp = false;
- else
- qWarning("Failed to create device: %s", qPrintable(comErrorMessage(hr)));
- }
-
- if (warp) {
- qCDebug(QSG_LOG_INFO_GENERAL, "Using WARP");
- m_factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter));
- HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
- if (FAILED(hr)) {
- qWarning("Failed to create WARP device: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
- }
-
- ComPtr<IDXGIAdapter3> adapter3;
- if (SUCCEEDED(adapter.As(&adapter3))) {
- DXGI_QUERY_VIDEO_MEMORY_INFO vidMemInfo;
- if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vidMemInfo))) {
- qCDebug(QSG_LOG_INFO_GENERAL, "Video memory info: LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB",
- vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024,
- vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024);
- }
- if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vidMemInfo))) {
- qCDebug(QSG_LOG_INFO_GENERAL, "Video memory info: NON-LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB",
- vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024,
- vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024);
- }
- }
-}
-
-void QSGD3D12DeviceManager::registerDeviceLossObserver(DeviceLossObserver *observer)
-{
- if (!m_observers.contains(observer))
- m_observers.append(observer);
-}
-
-QSGD3D12Engine::QSGD3D12Engine()
-{
- d = new QSGD3D12EnginePrivate;
-}
-
-QSGD3D12Engine::~QSGD3D12Engine()
-{
- d->waitGPU();
- d->releaseResources();
- delete d;
-}
-
-bool QSGD3D12Engine::attachToWindow(WId window, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha)
-{
- if (d->isInitialized()) {
- qWarning("QSGD3D12Engine: Cannot attach active engine to window");
- return false;
- }
-
- d->initialize(window, size, dpr, surfaceFormatSamples, alpha);
- return d->isInitialized();
-}
-
-void QSGD3D12Engine::releaseResources()
-{
- d->releaseResources();
-}
-
-bool QSGD3D12Engine::hasResources() const
-{
- // An explicit releaseResources() or a device loss results in initialized == false.
- return d->isInitialized();
-}
-
-void QSGD3D12Engine::setWindowSize(const QSize &size, float dpr)
-{
- d->setWindowSize(size, dpr);
-}
-
-WId QSGD3D12Engine::window() const
-{
- return d->currentWindow();
-}
-
-QSize QSGD3D12Engine::windowSize() const
-{
- return d->currentWindowSize();
-}
-
-float QSGD3D12Engine::windowDevicePixelRatio() const
-{
- return d->currentWindowDpr();
-}
-
-uint QSGD3D12Engine::windowSamples() const
-{
- return d->currentWindowSamples();
-}
-
-void QSGD3D12Engine::beginFrame()
-{
- d->beginFrame();
-}
-
-void QSGD3D12Engine::endFrame()
-{
- d->endFrame();
-}
-
-void QSGD3D12Engine::beginLayer()
-{
- d->beginLayer();
-}
-
-void QSGD3D12Engine::endLayer()
-{
- d->endLayer();
-}
-
-void QSGD3D12Engine::invalidateCachedFrameState()
-{
- d->invalidateCachedFrameState();
-}
-
-void QSGD3D12Engine::restoreFrameState(bool minimal)
-{
- d->restoreFrameState(minimal);
-}
-
-void QSGD3D12Engine::finalizePipeline(const QSGD3D12PipelineState &pipelineState)
-{
- d->finalizePipeline(pipelineState);
-}
-
-uint QSGD3D12Engine::genBuffer()
-{
- return d->genBuffer();
-}
-
-void QSGD3D12Engine::releaseBuffer(uint id)
-{
- d->releaseBuffer(id);
-}
-
-void QSGD3D12Engine::resetBuffer(uint id, const quint8 *data, int size)
-{
- d->resetBuffer(id, data, size);
-}
-
-void QSGD3D12Engine::markBufferDirty(uint id, int offset, int size)
-{
- d->markBufferDirty(id, offset, size);
-}
-
-void QSGD3D12Engine::queueViewport(const QRect &rect)
-{
- d->queueViewport(rect);
-}
-
-void QSGD3D12Engine::queueScissor(const QRect &rect)
-{
- d->queueScissor(rect);
-}
-
-void QSGD3D12Engine::queueSetRenderTarget(uint id)
-{
- d->queueSetRenderTarget(id);
-}
-
-void QSGD3D12Engine::queueClearRenderTarget(const QColor &color)
-{
- d->queueClearRenderTarget(color);
-}
-
-void QSGD3D12Engine::queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which)
-{
- d->queueClearDepthStencil(depthValue, stencilValue, which);
-}
-
-void QSGD3D12Engine::queueSetBlendFactor(const QVector4D &factor)
-{
- d->queueSetBlendFactor(factor);
-}
-
-void QSGD3D12Engine::queueSetStencilRef(quint32 ref)
-{
- d->queueSetStencilRef(ref);
-}
-
-void QSGD3D12Engine::queueDraw(const DrawParams &params)
-{
- d->queueDraw(params);
-}
-
-void QSGD3D12Engine::present()
-{
- d->present();
-}
-
-void QSGD3D12Engine::waitGPU()
-{
- d->waitGPU();
-}
-
-uint QSGD3D12Engine::genTexture()
-{
- return d->genTexture();
-}
-
-void QSGD3D12Engine::createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags)
-{
- d->createTexture(id, size, format, flags);
-}
-
-void QSGD3D12Engine::queueTextureResize(uint id, const QSize &size)
-{
- d->queueTextureResize(id, size);
-}
-
-void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos, TextureUploadFlags flags)
-{
- d->queueTextureUpload(id, QVector<QImage>() << image, QVector<QPoint>() << dstPos, flags);
-}
-
-void QSGD3D12Engine::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos,
- TextureUploadFlags flags)
-{
- d->queueTextureUpload(id, images, dstPos, flags);
-}
-
-void QSGD3D12Engine::releaseTexture(uint id)
-{
- d->releaseTexture(id);
-}
-
-void QSGD3D12Engine::useTexture(uint id)
-{
- d->useTexture(id);
-}
-
-uint QSGD3D12Engine::genRenderTarget()
-{
- return d->genRenderTarget();
-}
-
-void QSGD3D12Engine::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples)
-{
- d->createRenderTarget(id, size, clearColor, samples);
-}
-
-void QSGD3D12Engine::releaseRenderTarget(uint id)
-{
- d->releaseRenderTarget(id);
-}
-
-void QSGD3D12Engine::useRenderTargetAsTexture(uint id)
-{
- d->useRenderTargetAsTexture(id);
-}
-
-uint QSGD3D12Engine::activeRenderTarget() const
-{
- return d->activeRenderTarget();
-}
-
-QImage QSGD3D12Engine::executeAndWaitReadbackRenderTarget(uint id)
-{
- return d->executeAndWaitReadbackRenderTarget(id);
-}
-
-void QSGD3D12Engine::simulateDeviceLoss()
-{
- d->simulateDeviceLoss();
-}
-
-void *QSGD3D12Engine::getResource(QQuickWindow *, QSGRendererInterface::Resource resource) const
-{
- return d->getResource(resource);
-}
-
-static inline quint32 alignedSize(quint32 size, quint32 byteAlign)
-{
- return (size + byteAlign - 1) & ~(byteAlign - 1);
-}
-
-quint32 QSGD3D12Engine::alignedConstantBufferSize(quint32 size)
-{
- return alignedSize(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
-}
-
-QSGD3D12Format QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize, int *size)
-{
- QSGD3D12Format format = FmtUnknown;
-
- static const QSGD3D12Format formatMap_ub[] = { FmtUnknown,
- FmtUNormByte,
- FmtUNormByte2,
- FmtUnknown,
- FmtUNormByte4 };
-
- static const QSGD3D12Format formatMap_f[] = { FmtUnknown,
- FmtFloat,
- FmtFloat2,
- FmtFloat3,
- FmtFloat4 };
-
- switch (sgtype) {
- case QSGGeometry::UnsignedByteType:
- format = formatMap_ub[tupleSize];
- if (size)
- *size = tupleSize;
- break;
- case QSGGeometry::FloatType:
- format = formatMap_f[tupleSize];
- if (size)
- *size = sizeof(float) * tupleSize;
- break;
-
- case QSGGeometry::UnsignedShortType:
- format = FmtUnsignedShort;
- if (size)
- *size = sizeof(ushort) * tupleSize;
- break;
- case QSGGeometry::UnsignedIntType:
- format = FmtUnsignedInt;
- if (size)
- *size = sizeof(uint) * tupleSize;
- break;
-
- case QSGGeometry::ByteType:
- case QSGGeometry::IntType:
- case QSGGeometry::ShortType:
- qWarning("no mapping for GL type 0x%x", sgtype);
- break;
-
- default:
- qWarning("unknown GL type 0x%x", sgtype);
- break;
- }
-
- return format;
-}
-
-int QSGD3D12Engine::mipMapLevels(const QSize &size)
-{
- return ceil(log2(qMax(size.width(), size.height()))) + 1;
-}
-
-inline static bool isPowerOfTwo(int x)
-{
- // Assumption: x >= 1
- return x == (x & -x);
-}
-
-QSize QSGD3D12Engine::mipMapAdjustedSourceSize(const QSize &size)
-{
- if (size.isEmpty())
- return size;
-
- QSize adjustedSize = size;
-
- // ### for now only power-of-two sizes are mipmap-capable
- if (!isPowerOfTwo(size.width()))
- adjustedSize.setWidth(qNextPowerOfTwo(size.width()));
- if (!isPowerOfTwo(size.height()))
- adjustedSize.setHeight(qNextPowerOfTwo(size.height()));
-
- return adjustedSize;
-}
-
-void QSGD3D12EnginePrivate::releaseResources()
-{
- if (!initialized)
- return;
-
- mipmapper.releaseResources();
- devLossTest.releaseResources();
-
- frameCommandList = nullptr;
- copyCommandList = nullptr;
-
- copyCommandAllocator = nullptr;
- for (int i = 0; i < frameInFlightCount; ++i) {
- frameCommandAllocator[i] = nullptr;
- pframeData[i].gpuCbvSrvUavHeap = nullptr;
- delete frameFence[i];
- }
-
- defaultDS = nullptr;
- for (int i = 0; i < swapChainBufferCount; ++i) {
- backBufferRT[i] = nullptr;
- defaultRT[i] = nullptr;
- }
-
- psoCache.clear();
- rootSigCache.clear();
- buffers.clear();
- textures.clear();
- renderTargets.clear();
-
- cpuDescHeapManager.releaseResources();
-
- commandQueue = nullptr;
- copyCommandQueue = nullptr;
-
-#ifndef Q_OS_WINRT
- dcompTarget = nullptr;
- dcompVisual = nullptr;
- dcompDevice = nullptr;
-#endif
-
- swapChain = nullptr;
-
- delete presentFence;
- textureUploadFence = nullptr;
-
- deviceManager()->unref();
-
- initialized = false;
-
- // 'window' must be kept, may just be a device loss
-}
-
-void QSGD3D12EnginePrivate::initialize(WId w, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha)
-{
- if (initialized)
- return;
-
- window = w;
- windowSize = size;
- windowDpr = dpr;
- windowSamples = qMax(1, surfaceFormatSamples); // may be -1 or 0, whereas windowSamples is uint and >= 1
- windowAlpha = alpha;
-
- swapChainBufferCount = qMin(qEnvironmentVariableIntValue("QT_D3D_BUFFER_COUNT"), MAX_SWAP_CHAIN_BUFFER_COUNT);
- if (swapChainBufferCount < 2)
- swapChainBufferCount = DEFAULT_SWAP_CHAIN_BUFFER_COUNT;
-
- frameInFlightCount = qMin(qEnvironmentVariableIntValue("QT_D3D_FRAME_COUNT"), MAX_FRAME_IN_FLIGHT_COUNT);
- if (frameInFlightCount < 1)
- frameInFlightCount = DEFAULT_FRAME_IN_FLIGHT_COUNT;
-
- static const char *latReqEnvVar = "QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY";
- if (!qEnvironmentVariableIsSet(latReqEnvVar))
- waitableSwapChainMaxLatency = DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY;
- else
- waitableSwapChainMaxLatency = qBound(0, qEnvironmentVariableIntValue(latReqEnvVar), 16);
-
- if (qEnvironmentVariableIsSet("QSG_INFO"))
- const_cast<QLoggingCategory &>(QSG_LOG_INFO_GENERAL()).setEnabled(QtDebugMsg, true);
-
- qCDebug(QSG_LOG_INFO_GENERAL, "d3d12 engine init. swap chain buffer count %d, max frames prepared without blocking %d",
- swapChainBufferCount, frameInFlightCount);
- if (waitableSwapChainMaxLatency)
- qCDebug(QSG_LOG_INFO_GENERAL, "Swap chain frame latency waitable object enabled. Frame latency is %d", waitableSwapChainMaxLatency);
-
- const bool debugLayer = qEnvironmentVariableIntValue("QT_D3D_DEBUG") != 0;
- if (debugLayer) {
- qCDebug(QSG_LOG_INFO_GENERAL, "Enabling debug layer");
-#if !defined(Q_OS_WINRT) || !defined(NDEBUG)
- ComPtr<ID3D12Debug> debugController;
- if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
- debugController->EnableDebugLayer();
-#else
- qCDebug(QSG_LOG_INFO_GENERAL, "Using DebugInterface will not allow certification to pass");
-#endif
- }
-
- QSGD3D12DeviceManager *dev = deviceManager();
- device = dev->ref();
- dev->registerDeviceLossObserver(this);
-
- if (debugLayer) {
- ComPtr<ID3D12InfoQueue> infoQueue;
- if (SUCCEEDED(device->QueryInterface(IID_PPV_ARGS(&infoQueue)))) {
- infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
- infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
- const bool breakOnWarning = qEnvironmentVariableIntValue("QT_D3D_DEBUG_BREAK_ON_WARNING") != 0;
- infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, breakOnWarning);
- D3D12_INFO_QUEUE_FILTER filter = {};
- D3D12_MESSAGE_ID suppressedMessages[] = {
- // When using a render target other than the default one we
- // have no way to know the custom clear color, if there is one.
- D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE
- };
- filter.DenyList.NumIDs = _countof(suppressedMessages);
- filter.DenyList.pIDList = suppressedMessages;
- // setting the filter would enable Info messages which we don't need
- D3D12_MESSAGE_SEVERITY infoSev = D3D12_MESSAGE_SEVERITY_INFO;
- filter.DenyList.NumSeverities = 1;
- filter.DenyList.pSeverityList = &infoSev;
- infoQueue->PushStorageFilter(&filter);
- }
- }
-
- D3D12_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)))) {
- qWarning("Failed to create command queue");
- return;
- }
-
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
- if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&copyCommandQueue)))) {
- qWarning("Failed to create copy command queue");
- return;
- }
-
-#ifndef Q_OS_WINRT
- HWND hwnd = reinterpret_cast<HWND>(w);
-
- if (windowAlpha) {
- // Go through DirectComposition for semi-transparent windows since the
- // traditional approaches won't fly with flip model swapchains.
- HRESULT hr = DCompositionCreateDevice(nullptr, IID_PPV_ARGS(&dcompDevice));
- if (SUCCEEDED(hr)) {
- hr = dcompDevice->CreateTargetForHwnd(hwnd, true, &dcompTarget);
- if (SUCCEEDED(hr)) {
- hr = dcompDevice->CreateVisual(&dcompVisual);
- if (FAILED(hr)) {
- qWarning("Failed to create DirectComposition visual: %s",
- qPrintable(comErrorMessage(hr)));
- windowAlpha = false;
- }
- } else {
- qWarning("Failed to create DirectComposition target: %s",
- qPrintable(comErrorMessage(hr)));
- windowAlpha = false;
- }
- } else {
- qWarning("Failed to create DirectComposition device: %s",
- qPrintable(comErrorMessage(hr)));
- windowAlpha = false;
- }
- }
-
- if (windowAlpha) {
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
- swapChainDesc.Width = windowSize.width() * windowDpr;
- swapChainDesc.Height = windowSize.height() * windowDpr;
- swapChainDesc.Format = RT_COLOR_FORMAT;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.BufferCount = swapChainBufferCount;
- swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
- swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
- if (waitableSwapChainMaxLatency)
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
-
- ComPtr<IDXGISwapChain1> baseSwapChain;
- HRESULT hr = dev->dxgi()->CreateSwapChainForComposition(commandQueue.Get(), &swapChainDesc, nullptr, &baseSwapChain);
- if (SUCCEEDED(hr)) {
- if (SUCCEEDED(baseSwapChain.As(&swapChain))) {
- hr = dcompVisual->SetContent(swapChain.Get());
- if (SUCCEEDED(hr)) {
- hr = dcompTarget->SetRoot(dcompVisual.Get());
- if (FAILED(hr)) {
- qWarning("SetRoot failed for DirectComposition target: %s",
- qPrintable(comErrorMessage(hr)));
- windowAlpha = false;
- }
- } else {
- qWarning("SetContent failed for DirectComposition visual: %s",
- qPrintable(comErrorMessage(hr)));
- windowAlpha = false;
- }
- } else {
- qWarning("Failed to cast swap chain");
- windowAlpha = false;
- }
- } else {
- qWarning("Failed to create swap chain for composition: 0x%x", hr);
- windowAlpha = false;
- }
- }
-
- if (!windowAlpha) {
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
- swapChainDesc.BufferCount = swapChainBufferCount;
- swapChainDesc.BufferDesc.Width = windowSize.width() * windowDpr;
- swapChainDesc.BufferDesc.Height = windowSize.height() * windowDpr;
- swapChainDesc.BufferDesc.Format = RT_COLOR_FORMAT;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // D3D12 requires the flip model
- swapChainDesc.OutputWindow = hwnd;
- swapChainDesc.SampleDesc.Count = 1; // Flip does not support MSAA so no choice here
- swapChainDesc.Windowed = TRUE;
- if (waitableSwapChainMaxLatency)
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
-
- ComPtr<IDXGISwapChain> baseSwapChain;
- HRESULT hr = dev->dxgi()->CreateSwapChain(commandQueue.Get(), &swapChainDesc, &baseSwapChain);
- if (FAILED(hr)) {
- qWarning("Failed to create swap chain: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
- hr = baseSwapChain.As(&swapChain);
- if (FAILED(hr)) {
- qWarning("Failed to cast swap chain: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
- }
-
- dev->dxgi()->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
-#else
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
- swapChainDesc.Width = windowSize.width() * windowDpr;
- swapChainDesc.Height = windowSize.height() * windowDpr;
- swapChainDesc.Format = RT_COLOR_FORMAT;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.BufferCount = swapChainBufferCount;
- swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
- swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
- if (waitableSwapChainMaxLatency)
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
-
- ComPtr<IDXGISwapChain1> baseSwapChain;
- HRESULT hr = dev->dxgi()->CreateSwapChainForComposition(commandQueue.Get(), &swapChainDesc, nullptr, &baseSwapChain);
- if (FAILED(hr)) {
- qWarning("Failed to create swap chain for composition: 0x%x", hr);
- return;
- }
- if (FAILED(baseSwapChain.As(&swapChain))) {
- qWarning("Failed to cast swap chain");
- return;
- }
-
- // The winrt platform plugin returns an ISwapChainPanel* from winId().
- ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel
- = reinterpret_cast<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel *>(window);
- ComPtr<ISwapChainPanelNative> swapChainPanelNative;
- if (FAILED(swapChainPanel.As(&swapChainPanelNative))) {
- qWarning("Failed to cast swap chain panel to native");
- return;
- }
- hr = QEventDispatcherWinRT::runOnXamlThread([this, &swapChainPanelNative]() {
- return swapChainPanelNative->SetSwapChain(swapChain.Get());
- });
- if (FAILED(hr)) {
- qWarning("Failed to set swap chain on panel: 0x%x", hr);
- return;
- }
-#endif
-
- if (waitableSwapChainMaxLatency) {
- if (FAILED(swapChain->SetMaximumFrameLatency(waitableSwapChainMaxLatency)))
- qWarning("Failed to set maximum frame latency to %d", waitableSwapChainMaxLatency);
- swapEvent = swapChain->GetFrameLatencyWaitableObject();
- }
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frameCommandAllocator[i])))) {
- qWarning("Failed to create command allocator");
- return;
- }
- }
-
- if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&copyCommandAllocator)))) {
- qWarning("Failed to create copy command allocator");
- return;
- }
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (!createCbvSrvUavHeap(i, GPU_CBVSRVUAV_DESCRIPTORS))
- return;
- }
-
- cpuDescHeapManager.initialize(device);
-
- setupDefaultRenderTargets();
-
- if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frameCommandAllocator[0].Get(),
- nullptr, IID_PPV_ARGS(&frameCommandList)))) {
- qWarning("Failed to create command list");
- return;
- }
- // created in recording state, close it for now
- frameCommandList->Close();
-
- if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCommandAllocator.Get(),
- nullptr, IID_PPV_ARGS(&copyCommandList)))) {
- qWarning("Failed to create copy command list");
- return;
- }
- copyCommandList->Close();
-
- frameIndex = 0;
-
- presentFence = createCPUWaitableFence();
- for (int i = 0; i < frameInFlightCount; ++i)
- frameFence[i] = createCPUWaitableFence();
-
- if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&textureUploadFence)))) {
- qWarning("Failed to create fence");
- return;
- }
-
- psoCache.setMaxCost(MAX_CACHED_PSO);
- rootSigCache.setMaxCost(MAX_CACHED_ROOTSIG);
-
- if (!mipmapper.initialize(this))
- return;
-
- if (!devLossTest.initialize(this))
- return;
-
- currentRenderTarget = 0;
-
- initialized = true;
-}
-
-bool QSGD3D12EnginePrivate::createCbvSrvUavHeap(int pframeIndex, int descriptorCount)
-{
- D3D12_DESCRIPTOR_HEAP_DESC gpuDescHeapDesc = {};
- gpuDescHeapDesc.NumDescriptors = descriptorCount;
- gpuDescHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
- gpuDescHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
-
- if (FAILED(device->CreateDescriptorHeap(&gpuDescHeapDesc, IID_PPV_ARGS(&pframeData[pframeIndex].gpuCbvSrvUavHeap)))) {
- qWarning("Failed to create shader-visible CBV-SRV-UAV heap");
- return false;
- }
-
- pframeData[pframeIndex].gpuCbvSrvUavHeapSize = descriptorCount;
-
- return true;
-}
-
-DXGI_SAMPLE_DESC QSGD3D12EnginePrivate::makeSampleDesc(DXGI_FORMAT format, uint samples)
-{
- DXGI_SAMPLE_DESC sampleDesc;
- sampleDesc.Count = 1;
- sampleDesc.Quality = 0;
-
- if (samples > 1) {
- D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {};
- msaaInfo.Format = format;
- msaaInfo.SampleCount = samples;
- if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) {
- if (msaaInfo.NumQualityLevels > 0) {
- sampleDesc.Count = samples;
- sampleDesc.Quality = msaaInfo.NumQualityLevels - 1;
- } else {
- qWarning("No quality levels for multisampling with sample count %d", samples);
- }
- } else {
- qWarning("Failed to query multisample quality levels for sample count %d", samples);
- }
- }
-
- return sampleDesc;
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
- const QVector4D &clearColor, uint samples)
-{
- D3D12_CLEAR_VALUE clearValue = {};
- clearValue.Format = RT_COLOR_FORMAT;
- clearValue.Color[0] = clearColor.x();
- clearValue.Color[1] = clearColor.y();
- clearValue.Color[2] = clearColor.z();
- clearValue.Color[3] = clearColor.w();
-
- D3D12_HEAP_PROPERTIES heapProp = {};
- heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC rtDesc = {};
- rtDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- rtDesc.Width = size.width();
- rtDesc.Height = size.height();
- rtDesc.DepthOrArraySize = 1;
- rtDesc.MipLevels = 1;
- rtDesc.Format = RT_COLOR_FORMAT;
- rtDesc.SampleDesc = makeSampleDesc(rtDesc.Format, samples);
- rtDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
-
- ID3D12Resource *resource = nullptr;
- const D3D12_RESOURCE_STATES initialState = samples <= 1
- ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
- : D3D12_RESOURCE_STATE_RENDER_TARGET;
- if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &rtDesc,
- initialState, &clearValue, IID_PPV_ARGS(&resource)))) {
- qWarning("Failed to create offscreen render target of size %dx%d", size.width(), size.height());
- return nullptr;
- }
-
- device->CreateRenderTargetView(resource, nullptr, viewHandle);
-
- return resource;
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, uint samples)
-{
- D3D12_CLEAR_VALUE depthClearValue = {};
- depthClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthClearValue.DepthStencil.Depth = 1.0f;
- depthClearValue.DepthStencil.Stencil = 0;
-
- D3D12_HEAP_PROPERTIES heapProp = {};
- heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- bufDesc.Width = size.width();
- bufDesc.Height = size.height();
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- bufDesc.SampleDesc = makeSampleDesc(bufDesc.Format, samples);
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- bufDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
-
- ID3D12Resource *resource = nullptr;
- if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc,
- D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthClearValue, IID_PPV_ARGS(&resource)))) {
- qWarning("Failed to create depth-stencil buffer of size %dx%d", size.width(), size.height());
- return nullptr;
- }
-
- D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
- depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthStencilDesc.ViewDimension = bufDesc.SampleDesc.Count <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS;
-
- device->CreateDepthStencilView(resource, &depthStencilDesc, viewHandle);
-
- return resource;
-}
-
-void QSGD3D12EnginePrivate::setupDefaultRenderTargets()
-{
- for (int i = 0; i < swapChainBufferCount; ++i) {
- if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&backBufferRT[i])))) {
- qWarning("Failed to get buffer %d from swap chain", i);
- return;
- }
- defaultRTV[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- if (windowSamples == 1) {
- defaultRT[i] = backBufferRT[i];
- device->CreateRenderTargetView(defaultRT[i].Get(), nullptr, defaultRTV[i]);
- } else {
- const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr);
- // Not optimal if the user called setClearColor, but there's so
- // much we can do. The debug layer warning is suppressed so we're good to go.
- const QColor cc(Qt::white);
- const QVector4D clearColor(cc.redF(), cc.greenF(), cc.blueF(), cc.alphaF());
- ID3D12Resource *msaaRT = createColorBuffer(defaultRTV[i], size, clearColor, windowSamples);
- if (msaaRT)
- defaultRT[i].Attach(msaaRT);
- }
- }
-
- defaultDSV = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr);
- ID3D12Resource *ds = createDepthStencil(defaultDSV, size, windowSamples);
- if (ds)
- defaultDS.Attach(ds);
-
- presentFrameIndex = 0;
-}
-
-void QSGD3D12EnginePrivate::setWindowSize(const QSize &size, float dpr)
-{
- if (!initialized || (windowSize == size && windowDpr == dpr))
- return;
-
- waitGPU();
-
- windowSize = size;
- windowDpr = dpr;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "resize" << size << dpr;
-
- // Clear these, otherwise resizing will fail.
- defaultDS = nullptr;
- cpuDescHeapManager.release(defaultDSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- for (int i = 0; i < swapChainBufferCount; ++i) {
- backBufferRT[i] = nullptr;
- defaultRT[i] = nullptr;
- cpuDescHeapManager.release(defaultRTV[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- }
-
- const int w = windowSize.width() * windowDpr;
- const int h = windowSize.height() * windowDpr;
- HRESULT hr = swapChain->ResizeBuffers(swapChainBufferCount, w, h, RT_COLOR_FORMAT,
- waitableSwapChainMaxLatency ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0);
- if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
- deviceManager()->deviceLossDetected();
- return;
- } else if (FAILED(hr)) {
- qWarning("Failed to resize buffers: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
-
- setupDefaultRenderTargets();
-}
-
-void QSGD3D12EnginePrivate::deviceLost()
-{
- qWarning("D3D device lost, will attempt to reinitialize");
-
- // Release all resources. This is important because otherwise reinitialization may fail.
- releaseResources();
-
- // Now in uninitialized state (but 'window' is still valid). Will recreate
- // all the resources on the next beginFrame().
-}
-
-QSGD3D12CPUWaitableFence *QSGD3D12EnginePrivate::createCPUWaitableFence() const
-{
- QSGD3D12CPUWaitableFence *f = new QSGD3D12CPUWaitableFence;
- HRESULT hr = device->CreateFence(f->value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&f->fence));
- if (FAILED(hr)) {
- qWarning("Failed to create fence: %s", qPrintable(comErrorMessage(hr)));
- return f;
- }
- f->event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- return f;
-}
-
-void QSGD3D12EnginePrivate::waitForGPU(QSGD3D12CPUWaitableFence *f) const
-{
- const UINT64 newValue = f->value.fetchAndAddAcquire(1) + 1;
- commandQueue->Signal(f->fence.Get(), newValue);
- if (f->fence->GetCompletedValue() < newValue) {
- HRESULT hr = f->fence->SetEventOnCompletion(newValue, f->event);
- if (FAILED(hr)) {
- qWarning("SetEventOnCompletion failed: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
- WaitForSingleObject(f->event, INFINITE);
- }
-}
-
-void QSGD3D12EnginePrivate::transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList,
- D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const
-{
- D3D12_RESOURCE_BARRIER barrier;
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier.Transition.pResource = resource;
- barrier.Transition.StateBefore = before;
- barrier.Transition.StateAfter = after;
- barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
-
- commandList->ResourceBarrier(1, &barrier);
-}
-
-void QSGD3D12EnginePrivate::resolveMultisampledTarget(ID3D12Resource *msaa,
- ID3D12Resource *resolve,
- D3D12_RESOURCE_STATES resolveUsage,
- ID3D12GraphicsCommandList *commandList) const
-{
- D3D12_RESOURCE_BARRIER barriers[2];
- for (int i = 0; i < _countof(barriers); ++i) {
- barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barriers[i].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barriers[i].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- }
-
- barriers[0].Transition.pResource = msaa;
- barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
- barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
- barriers[1].Transition.pResource = resolve;
- barriers[1].Transition.StateBefore = resolveUsage;
- barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST;
- commandList->ResourceBarrier(2, barriers);
-
- commandList->ResolveSubresource(resolve, 0, msaa, 0, RT_COLOR_FORMAT);
-
- barriers[0].Transition.pResource = msaa;
- barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
- barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
- barriers[1].Transition.pResource = resolve;
- barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_DEST;
- barriers[1].Transition.StateAfter = resolveUsage;
- commandList->ResourceBarrier(2, barriers);
-}
-
-void QSGD3D12EnginePrivate::uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const
-{
- D3D12_RESOURCE_BARRIER barrier = {};
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
- barrier.UAV.pResource = resource;
-
- commandList->ResourceBarrier(1, &barrier);
-}
-
-ID3D12Resource *QSGD3D12EnginePrivate::createBuffer(int size)
-{
- ID3D12Resource *buf;
-
- D3D12_HEAP_PROPERTIES uploadHeapProp = {};
- uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufDesc.Width = size;
- bufDesc.Height = 1;
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufDesc.SampleDesc.Count = 1;
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-
- HRESULT hr = device->CreateCommittedResource(&uploadHeapProp, D3D12_HEAP_FLAG_NONE, &bufDesc,
- D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buf));
- if (FAILED(hr))
- qWarning("Failed to create buffer resource: %s", qPrintable(comErrorMessage(hr)));
-
- return buf;
-}
-
-void QSGD3D12EnginePrivate::ensureBuffer(Buffer *buf)
-{
- Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]);
- // Only enlarge, never shrink
- const bool newBufferNeeded = bfd.buffer ? (buf->cpuDataRef.size > bfd.resourceSize) : true;
- if (newBufferNeeded) {
- // Round it up and overallocate a little bit so that a subsequent
- // buffer contents rebuild with a slightly larger total size does
- // not lead to creating a new buffer.
- const quint32 sz = alignedSize(buf->cpuDataRef.size, 4096);
- if (Q_UNLIKELY(debug_buffer()))
- qDebug("new buffer[pf=%d] of size %d (actual data size %d)", currentPFrameIndex, sz, buf->cpuDataRef.size);
- bfd.buffer.Attach(createBuffer(sz));
- bfd.resourceSize = sz;
- }
- // Cache the actual data size in the per-in-flight-frame data as well.
- bfd.dataSize = buf->cpuDataRef.size;
-}
-
-void QSGD3D12EnginePrivate::updateBuffer(Buffer *buf)
-{
- if (buf->cpuDataRef.dirty.isEmpty())
- return;
-
- Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]);
- quint8 *p = nullptr;
- const D3D12_RANGE readRange = { 0, 0 };
- if (FAILED(bfd.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) {
- qWarning("Map failed for buffer of size %d", buf->cpuDataRef.size);
- return;
- }
- for (const auto &r : qAsConst(buf->cpuDataRef.dirty)) {
- if (Q_UNLIKELY(debug_buffer()))
- qDebug("%p o %d s %d", buf, r.first, r.second);
- memcpy(p + r.first, buf->cpuDataRef.p + r.first, r.second);
- }
- bfd.buffer->Unmap(0, nullptr);
- buf->cpuDataRef.dirty.clear();
-}
-
-void QSGD3D12EnginePrivate::ensureDevice()
-{
- if (!initialized && window)
- initialize(window, windowSize, windowDpr, windowSamples, windowAlpha);
-}
-
-void QSGD3D12EnginePrivate::beginFrame()
-{
- if (inFrame && !activeLayers)
- qFatal("beginFrame called again without an endFrame, frame index was %d", frameIndex);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "***** begin frame, logical" << frameIndex << "present" << presentFrameIndex << "layer" << activeLayers;
-
- if (inFrame && activeLayers) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("frame %d already in progress", frameIndex);
- if (!currentLayerDepth) {
- // There are layers and the real frame preparation starts now. Prepare for present.
- beginFrameDraw();
- }
- return;
- }
-
- inFrame = true;
-
- // The device may have been lost. This is the point to attempt to start
- // again from scratch. Except when it is not. Operations that can happen
- // out of frame (e.g. textures, render targets) may trigger reinit earlier
- // than beginFrame.
- ensureDevice();
-
- // Wait for a buffer to be available for Present, if the waitable event is in use.
- if (waitableSwapChainMaxLatency)
- WaitForSingleObject(swapEvent, INFINITE);
-
- // Block if needed. With 2 frames in flight frame N waits for frame N - 2, but not N - 1, to finish.
- currentPFrameIndex = frameIndex % frameInFlightCount;
- if (frameIndex >= frameInFlightCount) {
- ID3D12Fence *fence = frameFence[currentPFrameIndex]->fence.Get();
- HANDLE event = frameFence[currentPFrameIndex]->event;
- // Frame fence values start from 1, hence the +1.
- const quint64 inFlightFenceValue = frameIndex - frameInFlightCount + 1;
- if (fence->GetCompletedValue() < inFlightFenceValue) {
- fence->SetEventOnCompletion(inFlightFenceValue, event);
- WaitForSingleObject(event, INFINITE);
- }
- frameCommandAllocator[currentPFrameIndex]->Reset();
- }
-
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
- pfd.cbvSrvUavNextFreeDescriptorIndex = 0;
-
- for (Buffer &b : buffers) {
- if (b.entryInUse())
- b.d[currentPFrameIndex].dirty.clear();
- }
-
- if (frameIndex >= frameInFlightCount - 1) {
- // Now sync the buffer changes from the previous, potentially still in
- // flight, frames. This is done by taking the ranges dirtied in those
- // frames and adding them to the global CPU-side buffer's dirty list,
- // as if this frame changed those ranges. (however, dirty ranges
- // inherited this way are not added to this frame's persistent
- // per-frame dirty list because the next frame after this one should
- // inherit this frame's genuine changes only, the rest will come from
- // the earlier ones)
- for (int delta = frameInFlightCount - 1; delta >= 1; --delta) {
- const int prevPFrameIndex = (frameIndex - delta) % frameInFlightCount;
- PersistentFrameData &prevFrameData(pframeData[prevPFrameIndex]);
- for (uint id : qAsConst(prevFrameData.buffersUsedInFrame)) {
- Buffer &b(buffers[id - 1]);
- if (b.d[currentPFrameIndex].buffer && b.d[currentPFrameIndex].dataSize == b.cpuDataRef.size) {
- if (Q_UNLIKELY(debug_buffer()))
- qDebug() << "frame" << frameIndex << "takes dirty" << b.d[prevPFrameIndex].dirty
- << "from frame" << frameIndex - delta << "for buffer" << id;
- for (const auto &range : qAsConst(b.d[prevPFrameIndex].dirty))
- addDirtyRange(&b.cpuDataRef.dirty, range.first, range.second, b.cpuDataRef.size);
- } else {
- if (Q_UNLIKELY(debug_buffer()))
- qDebug() << "frame" << frameIndex << "makes all dirty from frame" << frameIndex - delta
- << "for buffer" << id;
- addDirtyRange(&b.cpuDataRef.dirty, 0, b.cpuDataRef.size, b.cpuDataRef.size);
- }
- }
- }
- }
-
- if (frameIndex >= frameInFlightCount) {
- // Do some texture upload bookkeeping.
- const quint64 finishedFrameIndex = frameIndex - frameInFlightCount; // we know since we just blocked for this
- // pfd conveniently refers to the same slot that was used by that frame
- if (!pfd.pendingTextureUploads.isEmpty()) {
- if (Q_UNLIKELY(debug_texture()))
- qDebug("Removing texture upload data for frame %d", finishedFrameIndex);
- for (uint id : qAsConst(pfd.pendingTextureUploads)) {
- const int idx = id - 1;
- Texture &t(textures[idx]);
- // fenceValue is 0 when the previous frame cleared it, skip in
- // this case. Skip also when fenceValue > the value it was when
- // adding the last GPU wait - this is the case when more
- // uploads were queued for the same texture in the meantime.
- if (t.fenceValue && t.fenceValue == t.lastWaitFenceValue) {
- t.fenceValue = 0;
- t.lastWaitFenceValue = 0;
- t.stagingBuffers.clear();
- t.stagingHeaps.clear();
- if (Q_UNLIKELY(debug_texture()))
- qDebug("Cleaned staging data for texture %u", id);
- }
- }
- pfd.pendingTextureUploads.clear();
- if (!pfd.pendingTextureMipMap.isEmpty()) {
- if (Q_UNLIKELY(debug_texture()))
- qDebug() << "cleaning mipmap generation data for " << pfd.pendingTextureMipMap;
- // no special cleanup is needed as mipmap generation uses the frame's resources
- pfd.pendingTextureMipMap.clear();
- }
- bool hasPending = false;
- for (int delta = 1; delta < frameInFlightCount; ++delta) {
- const PersistentFrameData &prevFrameData(pframeData[(frameIndex - delta) % frameInFlightCount]);
- if (!prevFrameData.pendingTextureUploads.isEmpty()) {
- hasPending = true;
- break;
- }
- }
- if (!hasPending) {
- if (Q_UNLIKELY(debug_texture()))
- qDebug("no more pending textures");
- copyCommandAllocator->Reset();
- }
- }
-
- // Do the deferred deletes.
- if (!pfd.deleteQueue.isEmpty()) {
- for (PersistentFrameData::DeleteQueueEntry &e : pfd.deleteQueue) {
- e.res = nullptr;
- e.descHeap = nullptr;
- if (e.cpuDescriptorPtr) {
- D3D12_CPU_DESCRIPTOR_HANDLE h = { e.cpuDescriptorPtr };
- cpuDescHeapManager.release(h, e.descHeapType);
- }
- }
- pfd.deleteQueue.clear();
- }
- // Deferred deletes issued outside a begin-endFrame go to the next
- // frame's out-of-frame delete queue as these cannot be executed in the
- // next beginFrame, only in next + frameInFlightCount. Move to the
- // normal queue if this is the next beginFrame.
- if (!pfd.outOfFrameDeleteQueue.isEmpty()) {
- pfd.deleteQueue = pfd.outOfFrameDeleteQueue;
- pfd.outOfFrameDeleteQueue.clear();
- }
-
- // Mark released texture, buffer, etc. slots free.
- if (!pfd.pendingReleases.isEmpty()) {
- for (const auto &pr : qAsConst(pfd.pendingReleases)) {
- Q_ASSERT(pr.id);
- if (pr.type == PersistentFrameData::PendingRelease::TypeTexture) {
- Texture &t(textures[pr.id - 1]);
- Q_ASSERT(t.entryInUse());
- t.flags &= ~RenderTarget::EntryInUse; // createTexture() can now reuse this entry
- t.texture = nullptr;
- } else if (pr.type == PersistentFrameData::PendingRelease::TypeBuffer) {
- Buffer &b(buffers[pr.id - 1]);
- Q_ASSERT(b.entryInUse());
- b.flags &= ~Buffer::EntryInUse;
- for (int i = 0; i < frameInFlightCount; ++i)
- b.d[i].buffer = nullptr;
- } else {
- qFatal("Corrupt pending release list, type %d", pr.type);
- }
- }
- pfd.pendingReleases.clear();
- }
- if (!pfd.outOfFramePendingReleases.isEmpty()) {
- pfd.pendingReleases = pfd.outOfFramePendingReleases;
- pfd.outOfFramePendingReleases.clear();
- }
- }
-
- pfd.buffersUsedInFrame.clear();
-
- beginDrawCalls();
-
- // Prepare for present if this is a frame without layers.
- if (!activeLayers)
- beginFrameDraw();
-}
-
-void QSGD3D12EnginePrivate::beginDrawCalls()
-{
- frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr);
- commandList = frameCommandList.Get();
- invalidateCachedFrameState();
-}
-
-void QSGD3D12EnginePrivate::invalidateCachedFrameState()
-{
- tframeData.drawingMode = QSGGeometry::DrawingMode(-1);
- tframeData.currentIndexBuffer = 0;
- tframeData.activeTextureCount = 0;
- tframeData.drawCount = 0;
- tframeData.lastPso = nullptr;
- tframeData.lastRootSig = nullptr;
- tframeData.descHeapSet = false;
-}
-
-void QSGD3D12EnginePrivate::restoreFrameState(bool minimal)
-{
- queueSetRenderTarget(currentRenderTarget);
- if (!minimal) {
- queueViewport(tframeData.viewport);
- queueScissor(tframeData.scissor);
- queueSetBlendFactor(tframeData.blendFactor);
- queueSetStencilRef(tframeData.stencilRef);
- }
- finalizePipeline(tframeData.pipelineState);
-}
-
-void QSGD3D12EnginePrivate::beginFrameDraw()
-{
- if (windowSamples == 1)
- transitionResource(defaultRT[presentFrameIndex % swapChainBufferCount].Get(), commandList,
- D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
-}
-
-void QSGD3D12EnginePrivate::endFrame()
-{
- if (!inFrame)
- qFatal("endFrame called without beginFrame, frame index %d", frameIndex);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("***** end frame");
-
- endDrawCalls(true);
-
- commandQueue->Signal(frameFence[frameIndex % frameInFlightCount]->fence.Get(), frameIndex + 1);
- ++frameIndex;
-
- inFrame = false;
-}
-
-void QSGD3D12EnginePrivate::endDrawCalls(bool lastInFrame)
-{
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
-
- // Now is the time to sync all the changed areas in the buffers.
- if (Q_UNLIKELY(debug_buffer()))
- qDebug() << "buffers used in drawcall set" << pfd.buffersUsedInDrawCallSet;
- for (uint id : qAsConst(pfd.buffersUsedInDrawCallSet))
- updateBuffer(&buffers[id - 1]);
-
- pfd.buffersUsedInFrame += pfd.buffersUsedInDrawCallSet;
- pfd.buffersUsedInDrawCallSet.clear();
-
- // Add a wait on the 3D queue for the relevant texture uploads on the copy queue.
- if (!pfd.pendingTextureUploads.isEmpty()) {
- quint64 topFenceValue = 0;
- for (uint id : qAsConst(pfd.pendingTextureUploads)) {
- const int idx = id - 1;
- Texture &t(textures[idx]);
- Q_ASSERT(t.fenceValue);
- // skip if already added a Wait in the previous frame
- if (t.lastWaitFenceValue == t.fenceValue)
- continue;
- t.lastWaitFenceValue = t.fenceValue;
- if (t.fenceValue > topFenceValue)
- topFenceValue = t.fenceValue;
- if (t.mipmap())
- pfd.pendingTextureMipMap.insert(id);
- }
- if (topFenceValue) {
- if (Q_UNLIKELY(debug_texture()))
- qDebug("added wait for texture fence %llu", topFenceValue);
- commandQueue->Wait(textureUploadFence.Get(), topFenceValue);
- // Generate mipmaps after the wait, when necessary.
- if (!pfd.pendingTextureMipMap.isEmpty()) {
- if (Q_UNLIKELY(debug_texture()))
- qDebug() << "starting mipmap generation for" << pfd.pendingTextureMipMap;
- for (uint id : qAsConst(pfd.pendingTextureMipMap))
- mipmapper.queueGenerate(textures[id - 1]);
- }
- }
- }
-
- if (lastInFrame) {
- // Resolve and transition the backbuffer for present, if needed.
- const int idx = presentFrameIndex % swapChainBufferCount;
- if (windowSamples == 1) {
- transitionResource(defaultRT[idx].Get(), commandList,
- D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
- } else {
- if (Q_UNLIKELY(debug_render())) {
- const D3D12_RESOURCE_DESC desc = defaultRT[idx]->GetDesc();
- qDebug("added resolve for multisampled render target (count %d, quality %d)",
- desc.SampleDesc.Count, desc.SampleDesc.Quality);
- }
- resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(),
- D3D12_RESOURCE_STATE_PRESENT, commandList);
- }
-
- if (activeLayers) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("this frame had %d layers", activeLayers);
- activeLayers = 0;
- }
- }
-
- // Go!
- HRESULT hr = frameCommandList->Close();
- if (FAILED(hr)) {
- qWarning("Failed to close command list: %s", qPrintable(comErrorMessage(hr)));
- if (hr == E_INVALIDARG)
- qWarning("Invalid arguments. Some of the commands in the list is invalid in some way.");
- }
-
- ID3D12CommandList *commandLists[] = { frameCommandList.Get() };
- commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- commandList = nullptr;
-}
-
-void QSGD3D12EnginePrivate::beginLayer()
-{
- if (inFrame && !activeLayers)
- qFatal("Layer rendering cannot be started while a frame is active");
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("===== beginLayer active %d depth %d (inFrame=%d)", activeLayers, currentLayerDepth, inFrame);
-
- ++activeLayers;
- ++currentLayerDepth;
-
- // Do an early beginFrame. With multiple layers this results in
- // beginLayer - beginFrame - endLayer - beginLayer - beginFrame - endLayer - ... - (*) beginFrame - endFrame
- // where (*) denotes the start of the preparation of the actual, non-layer frame.
-
- if (activeLayers == 1)
- beginFrame();
-}
-
-void QSGD3D12EnginePrivate::endLayer()
-{
- if (!inFrame || !activeLayers || !currentLayerDepth)
- qFatal("Mismatched endLayer");
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("===== endLayer active %d depth %d", activeLayers, currentLayerDepth);
-
- --currentLayerDepth;
-
- // Do not touch activeLayers. It remains valid until endFrame.
-}
-
-// Root signature:
-// [0] CBV - always present
-// [1] table with one SRV per texture (must be a table since root descriptor SRVs cannot be textures) - optional
-// one static sampler per texture - optional
-//
-// SRVs can be created freely via QSGD3D12CPUDescriptorHeapManager and stored
-// in QSGD3D12TextureView. The engine will copy them onto a dedicated,
-// shader-visible CBV-SRV-UAV heap in the correct order.
-
-void QSGD3D12EnginePrivate::finalizePipeline(const QSGD3D12PipelineState &pipelineState)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.pipelineState = pipelineState;
-
- RootSigCacheEntry *cachedRootSig = rootSigCache[pipelineState.shaders.rootSig];
- if (!cachedRootSig) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("NEW ROOTSIG");
-
- cachedRootSig = new RootSigCacheEntry;
-
- D3D12_ROOT_PARAMETER rootParams[4];
- int rootParamCount = 0;
-
- rootParams[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
- rootParams[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParams[0].Descriptor.ShaderRegister = 0; // b0
- rootParams[0].Descriptor.RegisterSpace = 0;
- ++rootParamCount;
-
- D3D12_DESCRIPTOR_RANGE tvDescRange;
- if (pipelineState.shaders.rootSig.textureViewCount > 0) {
- rootParams[rootParamCount].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParams[rootParamCount].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
- rootParams[rootParamCount].DescriptorTable.NumDescriptorRanges = 1;
- tvDescRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- tvDescRange.NumDescriptors = pipelineState.shaders.rootSig.textureViewCount;
- tvDescRange.BaseShaderRegister = 0; // t0, t1, ...
- tvDescRange.RegisterSpace = 0;
- tvDescRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
- rootParams[rootParamCount].DescriptorTable.pDescriptorRanges = &tvDescRange;
- ++rootParamCount;
- }
-
- Q_ASSERT(rootParamCount <= _countof(rootParams));
- D3D12_ROOT_SIGNATURE_DESC desc;
- desc.NumParameters = rootParamCount;
- desc.pParameters = rootParams;
- // Mixing up samplers and resource views in QSGD3D12TextureView means
- // that the number of static samplers has to match the number of
- // textures. This is not really ideal in general but works for Quick's use cases.
- // The shaders can still choose to declare and use fewer samplers, if they want to.
- desc.NumStaticSamplers = pipelineState.shaders.rootSig.textureViewCount;
- D3D12_STATIC_SAMPLER_DESC staticSamplers[8];
- int sdIdx = 0;
- Q_ASSERT(pipelineState.shaders.rootSig.textureViewCount <= _countof(staticSamplers));
- for (int i = 0; i < pipelineState.shaders.rootSig.textureViewCount; ++i) {
- const QSGD3D12TextureView &tv(pipelineState.shaders.rootSig.textureViews[i]);
- D3D12_STATIC_SAMPLER_DESC sd = {};
- sd.Filter = D3D12_FILTER(tv.filter);
- sd.AddressU = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeHoriz);
- sd.AddressV = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeVert);
- sd.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sd.MinLOD = 0.0f;
- sd.MaxLOD = D3D12_FLOAT32_MAX;
- sd.ShaderRegister = sdIdx; // t0, t1, ...
- sd.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
- staticSamplers[sdIdx++] = sd;
- }
- desc.pStaticSamplers = staticSamplers;
- desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
-
- ComPtr<ID3DBlob> signature;
- ComPtr<ID3DBlob> error;
- if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) {
- QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize());
- qWarning("Failed to serialize root signature: %s", qPrintable(msg));
- return;
- }
- if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(),
- IID_PPV_ARGS(&cachedRootSig->rootSig)))) {
- qWarning("Failed to create root signature");
- return;
- }
-
- rootSigCache.insert(pipelineState.shaders.rootSig, cachedRootSig);
- }
-
- PSOCacheEntry *cachedPso = psoCache[pipelineState];
- if (!cachedPso) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("NEW PSO");
-
- cachedPso = new PSOCacheEntry;
-
- D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
-
- D3D12_INPUT_ELEMENT_DESC inputElements[QSGD3D12_MAX_INPUT_ELEMENTS];
- int ieIdx = 0;
- for (int i = 0; i < pipelineState.inputElementCount; ++i) {
- const QSGD3D12InputElement &ie(pipelineState.inputElements[i]);
- D3D12_INPUT_ELEMENT_DESC ieDesc = {};
- ieDesc.SemanticName = ie.semanticName;
- ieDesc.SemanticIndex = ie.semanticIndex;
- ieDesc.Format = DXGI_FORMAT(ie.format);
- ieDesc.InputSlot = ie.slot;
- ieDesc.AlignedByteOffset = ie.offset;
- ieDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
- if (Q_UNLIKELY(debug_render()))
- qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.semanticName, ie.offset, ie.format, ie.slot);
- inputElements[ieIdx++] = ieDesc;
- }
-
- psoDesc.InputLayout = { inputElements, UINT(ieIdx) };
-
- psoDesc.pRootSignature = cachedRootSig->rootSig.Get();
-
- D3D12_SHADER_BYTECODE vshader;
- vshader.pShaderBytecode = pipelineState.shaders.vs;
- vshader.BytecodeLength = pipelineState.shaders.vsSize;
- D3D12_SHADER_BYTECODE pshader;
- pshader.pShaderBytecode = pipelineState.shaders.ps;
- pshader.BytecodeLength = pipelineState.shaders.psSize;
-
- psoDesc.VS = vshader;
- psoDesc.PS = pshader;
-
- D3D12_RASTERIZER_DESC rastDesc = {};
- rastDesc.FillMode = D3D12_FILL_MODE_SOLID;
- rastDesc.CullMode = D3D12_CULL_MODE(pipelineState.cullMode);
- rastDesc.FrontCounterClockwise = pipelineState.frontCCW;
- rastDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
- rastDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
- rastDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
- rastDesc.DepthClipEnable = TRUE;
-
- psoDesc.RasterizerState = rastDesc;
-
- D3D12_BLEND_DESC blendDesc = {};
- if (pipelineState.blend == QSGD3D12PipelineState::BlendNone) {
- D3D12_RENDER_TARGET_BLEND_DESC noBlendDesc = {};
- noBlendDesc.RenderTargetWriteMask = pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0;
- blendDesc.RenderTarget[0] = noBlendDesc;
- } else if (pipelineState.blend == QSGD3D12PipelineState::BlendPremul) {
- const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = {
- TRUE, FALSE,
- D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_LOGIC_OP_NOOP,
- UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0)
- };
- blendDesc.RenderTarget[0] = premulBlendDesc;
- } else if (pipelineState.blend == QSGD3D12PipelineState::BlendColor) {
- const D3D12_RENDER_TARGET_BLEND_DESC colorBlendDesc = {
- TRUE, FALSE,
- D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_COLOR, D3D12_BLEND_OP_ADD,
- D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
- D3D12_LOGIC_OP_NOOP,
- UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0)
- };
- blendDesc.RenderTarget[0] = colorBlendDesc;
- }
- psoDesc.BlendState = blendDesc;
-
- psoDesc.DepthStencilState.DepthEnable = pipelineState.depthEnable;
- psoDesc.DepthStencilState.DepthWriteMask = pipelineState.depthWrite ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
- psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC(pipelineState.depthFunc);
-
- psoDesc.DepthStencilState.StencilEnable = pipelineState.stencilEnable;
- psoDesc.DepthStencilState.StencilReadMask = psoDesc.DepthStencilState.StencilWriteMask = 0xFF;
- D3D12_DEPTH_STENCILOP_DESC stencilOpDesc = {
- D3D12_STENCIL_OP(pipelineState.stencilFailOp),
- D3D12_STENCIL_OP(pipelineState.stencilDepthFailOp),
- D3D12_STENCIL_OP(pipelineState.stencilPassOp),
- D3D12_COMPARISON_FUNC(pipelineState.stencilFunc)
- };
- psoDesc.DepthStencilState.FrontFace = psoDesc.DepthStencilState.BackFace = stencilOpDesc;
-
- psoDesc.SampleMask = UINT_MAX;
- psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE(pipelineState.topologyType);
- psoDesc.NumRenderTargets = 1;
- psoDesc.RTVFormats[0] = RT_COLOR_FORMAT;
- psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
- psoDesc.SampleDesc = defaultRT[0]->GetDesc().SampleDesc;
-
- HRESULT hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&cachedPso->pso));
- if (FAILED(hr)) {
- qWarning("Failed to create graphics pipeline state: %s",
- qPrintable(comErrorMessage(hr)));
- return;
- }
-
- psoCache.insert(pipelineState, cachedPso);
- }
-
- if (cachedPso->pso.Get() != tframeData.lastPso) {
- tframeData.lastPso = cachedPso->pso.Get();
- commandList->SetPipelineState(tframeData.lastPso);
- }
-
- if (cachedRootSig->rootSig.Get() != tframeData.lastRootSig) {
- tframeData.lastRootSig = cachedRootSig->rootSig.Get();
- commandList->SetGraphicsRootSignature(tframeData.lastRootSig);
- }
-
- if (pipelineState.shaders.rootSig.textureViewCount > 0)
- setDescriptorHeaps();
-}
-
-void QSGD3D12EnginePrivate::setDescriptorHeaps(bool force)
-{
- if (force || !tframeData.descHeapSet) {
- tframeData.descHeapSet = true;
- ID3D12DescriptorHeap *heaps[] = { pframeData[currentPFrameIndex].gpuCbvSrvUavHeap.Get() };
- commandList->SetDescriptorHeaps(_countof(heaps), heaps);
- }
-}
-
-void QSGD3D12EnginePrivate::queueViewport(const QRect &rect)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.viewport = rect;
- const D3D12_VIEWPORT viewport = { float(rect.x()), float(rect.y()), float(rect.width()), float(rect.height()), 0, 1 };
- commandList->RSSetViewports(1, &viewport);
-}
-
-void QSGD3D12EnginePrivate::queueScissor(const QRect &rect)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.scissor = rect;
- const D3D12_RECT scissorRect = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
- commandList->RSSetScissorRects(1, &scissorRect);
-}
-
-void QSGD3D12EnginePrivate::queueSetRenderTarget(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle;
- D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle;
-
- if (!id) {
- rtvHandle = defaultRTV[presentFrameIndex % swapChainBufferCount];
- dsvHandle = defaultDSV;
- } else {
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse());
- RenderTarget &rt(renderTargets[idx]);
- rtvHandle = rt.rtv;
- dsvHandle = rt.dsv;
- if (!(rt.flags & RenderTarget::NeedsReadBarrier)) {
- rt.flags |= RenderTarget::NeedsReadBarrier;
- if (!(rt.flags & RenderTarget::Multisample))
- transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
- D3D12_RESOURCE_STATE_RENDER_TARGET);
- }
- }
-
- commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
-
- currentRenderTarget = id;
-}
-
-void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- const float clearColor[] = { float(color.redF()), float(color.blueF()), float(color.greenF()), float(color.alphaF()) };
- D3D12_CPU_DESCRIPTOR_HANDLE rtv = !currentRenderTarget
- ? defaultRTV[presentFrameIndex % swapChainBufferCount]
- : renderTargets[currentRenderTarget - 1].rtv;
- commandList->ClearRenderTargetView(rtv, clearColor, 0, nullptr);
-}
-
-void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- D3D12_CPU_DESCRIPTOR_HANDLE dsv = !currentRenderTarget
- ? defaultDSV
- : renderTargets[currentRenderTarget - 1].dsv;
- commandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr);
-}
-
-void QSGD3D12EnginePrivate::queueSetBlendFactor(const QVector4D &factor)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.blendFactor = factor;
- const float f[4] = { factor.x(), factor.y(), factor.z(), factor.w() };
- commandList->OMSetBlendFactor(f);
-}
-
-void QSGD3D12EnginePrivate::queueSetStencilRef(quint32 ref)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- tframeData.stencilRef = ref;
- commandList->OMSetStencilRef(ref);
-}
-
-void QSGD3D12EnginePrivate::queueDraw(const QSGD3D12Engine::DrawParams &params)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- const bool skip = tframeData.scissor.isEmpty();
-
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
-
- pfd.buffersUsedInDrawCallSet.insert(params.vertexBuf);
- const int vertexBufIdx = params.vertexBuf - 1;
- Q_ASSERT(params.vertexBuf && vertexBufIdx < buffers.count() && buffers[vertexBufIdx].entryInUse());
- pfd.buffersUsedInDrawCallSet.insert(params.constantBuf);
- const int constantBufIdx = params.constantBuf - 1;
- Q_ASSERT(params.constantBuf && constantBufIdx < buffers.count() && buffers[constantBufIdx].entryInUse());
- int indexBufIdx = -1;
- if (params.indexBuf) {
- pfd.buffersUsedInDrawCallSet.insert(params.indexBuf);
- indexBufIdx = params.indexBuf - 1;
- Q_ASSERT(indexBufIdx < buffers.count() && buffers[indexBufIdx].entryInUse());
- }
-
- // Ensure buffers are created but do not copy the data here, leave that to endDrawCalls().
- ensureBuffer(&buffers[vertexBufIdx]);
- ensureBuffer(&buffers[constantBufIdx]);
- if (indexBufIdx >= 0)
- ensureBuffer(&buffers[indexBufIdx]);
-
- // Set the CBV.
- if (!skip && params.cboOffset >= 0) {
- ID3D12Resource *cbuf = buffers[constantBufIdx].d[currentPFrameIndex].buffer.Get();
- if (cbuf)
- commandList->SetGraphicsRootConstantBufferView(0, cbuf->GetGPUVirtualAddress() + params.cboOffset);
- }
-
- // Set up vertex and index buffers.
- ID3D12Resource *vbuf = buffers[vertexBufIdx].d[currentPFrameIndex].buffer.Get();
- ID3D12Resource *ibuf = indexBufIdx >= 0 && params.startIndexIndex >= 0
- ? buffers[indexBufIdx].d[currentPFrameIndex].buffer.Get() : nullptr;
-
- if (!skip && params.mode != tframeData.drawingMode) {
- D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
- switch (params.mode) {
- case QSGGeometry::DrawPoints:
- topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
- break;
- case QSGGeometry::DrawLines:
- topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
- break;
- case QSGGeometry::DrawLineStrip:
- topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
- break;
- case QSGGeometry::DrawTriangles:
- topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- break;
- case QSGGeometry::DrawTriangleStrip:
- topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
- break;
- default:
- qFatal("Unsupported drawing mode 0x%x", params.mode);
- break;
- }
- commandList->IASetPrimitiveTopology(topology);
- tframeData.drawingMode = params.mode;
- }
-
- if (!skip) {
- D3D12_VERTEX_BUFFER_VIEW vbv;
- vbv.BufferLocation = vbuf->GetGPUVirtualAddress() + params.vboOffset;
- vbv.SizeInBytes = params.vboSize;
- vbv.StrideInBytes = params.vboStride;
-
- // must be set after the topology
- commandList->IASetVertexBuffers(0, 1, &vbv);
- }
-
- if (!skip && params.startIndexIndex >= 0 && ibuf && tframeData.currentIndexBuffer != params.indexBuf) {
- tframeData.currentIndexBuffer = params.indexBuf;
- D3D12_INDEX_BUFFER_VIEW ibv;
- ibv.BufferLocation = ibuf->GetGPUVirtualAddress();
- ibv.SizeInBytes = buffers[indexBufIdx].cpuDataRef.size;
- ibv.Format = DXGI_FORMAT(params.indexFormat);
- commandList->IASetIndexBuffer(&ibv);
- }
-
- // Copy the SRVs to a drawcall-dedicated area of the shader-visible descriptor heap.
- Q_ASSERT(tframeData.activeTextureCount == tframeData.pipelineState.shaders.rootSig.textureViewCount);
- if (tframeData.activeTextureCount > 0) {
- if (!skip) {
- ensureGPUDescriptorHeap(tframeData.activeTextureCount);
- const uint stride = cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- D3D12_CPU_DESCRIPTOR_HANDLE dst = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart();
- dst.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
- for (int i = 0; i < tframeData.activeTextureCount; ++i) {
- const TransientFrameData::ActiveTexture &t(tframeData.activeTextures[i]);
- Q_ASSERT(t.id);
- const int idx = t.id - 1;
- const bool isTex = t.type == TransientFrameData::ActiveTexture::TypeTexture;
- device->CopyDescriptorsSimple(1, dst, isTex ? textures[idx].srv : renderTargets[idx].srv,
- D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- dst.ptr += stride;
- }
-
- D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart();
- gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
- commandList->SetGraphicsRootDescriptorTable(1, gpuAddr);
-
- pfd.cbvSrvUavNextFreeDescriptorIndex += tframeData.activeTextureCount;
- }
- tframeData.activeTextureCount = 0;
- }
-
- // Add the draw call.
- if (!skip) {
- ++tframeData.drawCount;
- if (params.startIndexIndex >= 0)
- commandList->DrawIndexedInstanced(params.count, 1, params.startIndexIndex, 0, 0);
- else
- commandList->DrawInstanced(params.count, 1, 0, 0);
- }
-
- if (tframeData.drawCount == MAX_DRAW_CALLS_PER_LIST) {
- if (Q_UNLIKELY(debug_render()))
- qDebug("Limit of %d draw calls reached, executing command list", MAX_DRAW_CALLS_PER_LIST);
- // submit the command list
- endDrawCalls();
- // start a new one
- beginDrawCalls();
- // prepare for the upcoming drawcalls
- restoreFrameState();
- }
-}
-
-void QSGD3D12EnginePrivate::ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount)
-{
- PersistentFrameData &pfd(pframeData[currentPFrameIndex]);
- int newSize = pfd.gpuCbvSrvUavHeapSize;
- while (pfd.cbvSrvUavNextFreeDescriptorIndex + cbvSrvUavDescriptorCount > newSize)
- newSize *= 2;
- if (newSize != pfd.gpuCbvSrvUavHeapSize) {
- if (Q_UNLIKELY(debug_descheap()))
- qDebug("Out of space for SRVs, creating new CBV-SRV-UAV descriptor heap with descriptor count %d", newSize);
- deferredDelete(pfd.gpuCbvSrvUavHeap);
- createCbvSrvUavHeap(currentPFrameIndex, newSize);
- setDescriptorHeaps(true);
- pfd.cbvSrvUavNextFreeDescriptorIndex = 0;
- }
-}
-
-void QSGD3D12EnginePrivate::present()
-{
- if (!initialized)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("--- present with vsync ---");
-
- // This call will not block the CPU unless at least 3 buffers are queued,
- // unless the waitable frame latency event is enabled. Then the latency of
- // 3 is changed to whatever value desired, and blocking happens in
- // beginFrame. If none of these hold, the fence-based wait in beginFrame
- // throttles. Vsync (interval 1) is always enabled.
- HRESULT hr = swapChain->Present(1, 0);
- if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
- deviceManager()->deviceLossDetected();
- return;
- } else if (FAILED(hr)) {
- qWarning("Present failed: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
-
-#ifndef Q_OS_WINRT
- if (dcompDevice)
- dcompDevice->Commit();
-#endif
-
- ++presentFrameIndex;
-}
-
-void QSGD3D12EnginePrivate::waitGPU()
-{
- if (!initialized)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("--- blocking wait for GPU ---");
-
- waitForGPU(presentFence);
-}
-
-template<class T> uint newId(T *tbl)
-{
- uint id = 0;
- for (int i = 0; i < tbl->count(); ++i) {
- if (!(*tbl)[i].entryInUse()) {
- id = i + 1;
- break;
- }
- }
-
- if (!id) {
- tbl->resize(tbl->size() + 1);
- id = tbl->count();
- }
-
- (*tbl)[id - 1].flags = 0x01; // reset flags and set EntryInUse
-
- return id;
-}
-
-template<class T> void syncEntryFlags(T *e, int flag, bool b)
-{
- if (b)
- e->flags |= flag;
- else
- e->flags &= ~flag;
-}
-
-uint QSGD3D12EnginePrivate::genBuffer()
-{
- return newId(&buffers);
-}
-
-void QSGD3D12EnginePrivate::releaseBuffer(uint id)
-{
- if (!id || !initialized)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count());
-
- if (Q_UNLIKELY(debug_buffer()))
- qDebug("releasing buffer %u", id);
-
- Buffer &b(buffers[idx]);
- if (!b.entryInUse())
- return;
-
- // Do not null out and do not mark the entry reusable yet.
- // Do that only when the frames potentially in flight have finished for sure.
-
- for (int i = 0; i < frameInFlightCount; ++i) {
- if (b.d[i].buffer)
- deferredDelete(b.d[i].buffer);
- }
-
- QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame
- ? &pframeData[currentPFrameIndex].pendingReleases
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases;
-
- pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeBuffer, id));
-}
-
-void QSGD3D12EnginePrivate::resetBuffer(uint id, const quint8 *data, int size)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse());
- Buffer &b(buffers[idx]);
-
- if (Q_UNLIKELY(debug_buffer()))
- qDebug("reset buffer %u, size %d", id, size);
-
- b.cpuDataRef.p = data;
- b.cpuDataRef.size = size;
-
- b.cpuDataRef.dirty.clear();
- b.d[currentPFrameIndex].dirty.clear();
-
- if (size > 0) {
- const QPair<int, int> range = qMakePair(0, size);
- b.cpuDataRef.dirty.append(range);
- b.d[currentPFrameIndex].dirty.append(range);
- }
-}
-
-void QSGD3D12EnginePrivate::addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize)
-{
- // Bail out when the dirty list already spans the entire buffer.
- if (!dirty->isEmpty()) {
- if (dirty->at(0).first == 0 && dirty->at(0).second == bufferSize)
- return;
- }
-
- const QPair<int, int> range = qMakePair(offset, size);
- if (!dirty->contains(range))
- dirty->append(range);
-}
-
-void QSGD3D12EnginePrivate::markBufferDirty(uint id, int offset, int size)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse());
- Buffer &b(buffers[idx]);
-
- addDirtyRange(&b.cpuDataRef.dirty, offset, size, b.cpuDataRef.size);
- addDirtyRange(&b.d[currentPFrameIndex].dirty, offset, size, b.cpuDataRef.size);
-}
-
-uint QSGD3D12EnginePrivate::genTexture()
-{
- const uint id = newId(&textures);
- textures[id - 1].fenceValue = 0;
- return id;
-}
-
-static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap, bool force32bit,
- QImage::Format *imageFormat, int *bytesPerPixel)
-{
- DXGI_FORMAT f = DXGI_FORMAT_R8G8B8A8_UNORM;
- QImage::Format convFormat = format;
- int bpp = 4;
-
- if (!mipmap) {
- switch (format) {
- case QImage::Format_Grayscale8:
- case QImage::Format_Indexed8:
- case QImage::Format_Alpha8:
- if (!force32bit) {
- f = DXGI_FORMAT_R8_UNORM;
- bpp = 1;
- } else {
- convFormat = QImage::Format_RGBA8888;
- }
- break;
- case QImage::Format_RGB32:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- break;
- case QImage::Format_ARGB32:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- convFormat = wantsAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- break;
- case QImage::Format_ARGB32_Premultiplied:
- f = DXGI_FORMAT_B8G8R8A8_UNORM;
- convFormat = wantsAlpha ? format : QImage::Format_RGB32;
- break;
- default:
- convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888;
- break;
- }
- } else {
- // Mipmap generation needs unordered access and BGRA is not an option for that. Stick to RGBA.
- convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888;
- }
-
- if (imageFormat)
- *imageFormat = convFormat;
-
- if (bytesPerPixel)
- *bytesPerPixel = bpp;
-
- return f;
-}
-
-static inline QImage::Format imageFormatForTexture(DXGI_FORMAT format)
-{
- QImage::Format f = QImage::Format_Invalid;
-
- switch (format) {
- case DXGI_FORMAT_R8G8B8A8_UNORM:
- f = QImage::Format_RGBA8888_Premultiplied;
- break;
- case DXGI_FORMAT_B8G8R8A8_UNORM:
- f = QImage::Format_ARGB32_Premultiplied;
- break;
- case DXGI_FORMAT_R8_UNORM:
- f = QImage::Format_Grayscale8;
- break;
- default:
- break;
- }
-
- return f;
-}
-
-void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Format format,
- QSGD3D12Engine::TextureCreateFlags createFlags)
-{
- ensureDevice();
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
-
- syncEntryFlags(&t, Texture::Alpha, createFlags & QSGD3D12Engine::TextureWithAlpha);
- syncEntryFlags(&t, Texture::MipMap, createFlags & QSGD3D12Engine::TextureWithMipMaps);
-
- const QSize adjustedSize = !t.mipmap() ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size);
-
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC textureDesc = {};
- textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- textureDesc.Width = adjustedSize.width();
- textureDesc.Height = adjustedSize.height();
- textureDesc.DepthOrArraySize = 1;
- textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize);
- textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(),
- createFlags.testFlag(QSGD3D12Engine::TextureAlways32Bit),
- nullptr, nullptr);
- textureDesc.SampleDesc.Count = 1;
- textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- if (t.mipmap())
- textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture));
- if (FAILED(hr)) {
- qWarning("Failed to create texture resource: %s", qPrintable(comErrorMessage(hr)));
- return;
- }
-
- t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- srvDesc.Format = textureDesc.Format;
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MipLevels = textureDesc.MipLevels;
-
- device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv);
-
- if (t.mipmap()) {
- // Mipmap generation will need an UAV for each level that needs to be generated.
- t.mipUAVs.clear();
- for (int level = 1; level < textureDesc.MipLevels; ++level) {
- D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
- uavDesc.Format = textureDesc.Format;
- uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
- uavDesc.Texture2D.MipSlice = level;
- D3D12_CPU_DESCRIPTOR_HANDLE h = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- device->CreateUnorderedAccessView(t.texture.Get(), nullptr, &uavDesc, h);
- t.mipUAVs.append(h);
- }
- }
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("created texture %u, size %dx%d, miplevels %d", id, adjustedSize.width(), adjustedSize.height(), textureDesc.MipLevels);
-}
-
-void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size)
-{
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
-
- if (!t.texture) {
- qWarning("Cannot resize non-created texture %u", id);
- return;
- }
-
- if (t.mipmap()) {
- qWarning("Cannot resize mipmapped texture %u", id);
- return;
- }
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("resizing texture %u, size %dx%d", id, size.width(), size.height());
-
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
- textureDesc.Width = size.width();
- textureDesc.Height = size.height();
-
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- ComPtr<ID3D12Resource> oldTexture = t.texture;
- deferredDelete(t.texture);
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture));
- if (FAILED(hr)) {
- qWarning("Failed to create resized texture resource: %s",
- qPrintable(comErrorMessage(hr)));
- return;
- }
-
- deferredDelete(t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- srvDesc.Format = textureDesc.Format;
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MipLevels = textureDesc.MipLevels;
-
- device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv);
-
- D3D12_TEXTURE_COPY_LOCATION dstLoc;
- dstLoc.pResource = t.texture.Get();
- dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- dstLoc.SubresourceIndex = 0;
-
- D3D12_TEXTURE_COPY_LOCATION srcLoc;
- srcLoc.pResource = oldTexture.Get();
- srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- srcLoc.SubresourceIndex = 0;
-
- copyCommandList->Reset(copyCommandAllocator.Get(), nullptr);
-
- copyCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
-
- copyCommandList->Close();
- ID3D12CommandList *commandLists[] = { copyCommandList.Get() };
- copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1;
- copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue);
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("submitted old content copy for texture %u on the copy queue, fence %llu", id, t.fenceValue);
-}
-
-void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos,
- QSGD3D12Engine::TextureUploadFlags flags)
-{
- Q_ASSERT(id);
- Q_ASSERT(images.count() == dstPos.count());
- if (images.isEmpty())
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
- Texture &t(textures[idx]);
- Q_ASSERT(t.texture);
-
- // When mipmapping is not in use, image can be smaller than the size passed
- // to createTexture() and dstPos can specify a non-zero destination position.
-
- if (t.mipmap() && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) {
- qWarning("Mipmapped textures (%u) do not support partial uploads", id);
- return;
- }
-
- // Make life simpler by disallowing queuing a new mipmapped upload before the previous one finishes.
- if (t.mipmap() && t.fenceValue) {
- qWarning("Attempted to queue mipmapped texture upload (%u) while a previous upload is still in progress", id);
- return;
- }
-
- t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1;
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("adding upload for texture %u on the copy queue, fence %llu", id, t.fenceValue);
-
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
- const QSize adjustedTextureSize(textureDesc.Width, textureDesc.Height);
-
- int totalSize = 0;
- for (const QImage &image : images) {
- int bytesPerPixel;
- textureFormat(image.format(), t.alpha(), t.mipmap(),
- flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit),
- nullptr, &bytesPerPixel);
- const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width();
- const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height();
- const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
- totalSize += alignedSize(h * stride, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
- }
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("%d sub-uploads, heap size %d bytes", images.count(), totalSize);
-
- // Instead of individual committed resources for each upload buffer,
- // allocate only once and use placed resources.
- D3D12_HEAP_PROPERTIES uploadHeapProp = {};
- uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
- D3D12_HEAP_DESC uploadHeapDesc = {};
- uploadHeapDesc.SizeInBytes = totalSize;
- uploadHeapDesc.Properties = uploadHeapProp;
- uploadHeapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
-
- Texture::StagingHeap sheap;
- if (FAILED(device->CreateHeap(&uploadHeapDesc, IID_PPV_ARGS(&sheap.heap)))) {
- qWarning("Failed to create texture upload heap of size %d", totalSize);
- return;
- }
- t.stagingHeaps.append(sheap);
-
- copyCommandList->Reset(copyCommandAllocator.Get(), nullptr);
-
- int placedOffset = 0;
- for (int i = 0; i < images.count(); ++i) {
- QImage::Format convFormat;
- int bytesPerPixel;
- textureFormat(images[i].format(), t.alpha(), t.mipmap(),
- flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit),
- &convFormat, &bytesPerPixel);
- if (Q_UNLIKELY(debug_texture() && i == 0))
- qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel);
-
- QImage convImage = images[i].format() == convFormat ? images[i] : images[i].convertToFormat(convFormat);
-
- if (t.mipmap() && adjustedTextureSize != convImage.size())
- convImage = convImage.scaled(adjustedTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-
- const int stride = alignedSize(convImage.width() * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufDesc.Width = stride * convImage.height();
- bufDesc.Height = 1;
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufDesc.SampleDesc.Count = 1;
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-
- Texture::StagingBuffer sbuf;
- if (FAILED(device->CreatePlacedResource(sheap.heap.Get(), placedOffset,
- &bufDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
- nullptr, IID_PPV_ARGS(&sbuf.buffer)))) {
- qWarning("Failed to create texture upload buffer");
- return;
- }
-
- quint8 *p = nullptr;
- const D3D12_RANGE readRange = { 0, 0 };
- if (FAILED(sbuf.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) {
- qWarning("Map failed (texture upload buffer)");
- return;
- }
- for (int y = 0, ye = convImage.height(); y < ye; ++y) {
- memcpy(p, convImage.constScanLine(y), convImage.width() * bytesPerPixel);
- p += stride;
- }
- sbuf.buffer->Unmap(0, nullptr);
-
- D3D12_TEXTURE_COPY_LOCATION dstLoc;
- dstLoc.pResource = t.texture.Get();
- dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- dstLoc.SubresourceIndex = 0;
-
- D3D12_TEXTURE_COPY_LOCATION srcLoc;
- srcLoc.pResource = sbuf.buffer.Get();
- srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
- srcLoc.PlacedFootprint.Offset = 0;
- srcLoc.PlacedFootprint.Footprint.Format = textureDesc.Format;
- srcLoc.PlacedFootprint.Footprint.Width = convImage.width();
- srcLoc.PlacedFootprint.Footprint.Height = convImage.height();
- srcLoc.PlacedFootprint.Footprint.Depth = 1;
- srcLoc.PlacedFootprint.Footprint.RowPitch = stride;
-
- copyCommandList->CopyTextureRegion(&dstLoc, dstPos[i].x(), dstPos[i].y(), 0, &srcLoc, nullptr);
-
- t.stagingBuffers.append(sbuf);
- placedOffset += alignedSize(bufDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
- }
-
- copyCommandList->Close();
- ID3D12CommandList *commandLists[] = { copyCommandList.Get() };
- copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
- copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue);
-}
-
-void QSGD3D12EnginePrivate::releaseTexture(uint id)
-{
- if (!id || !initialized)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count());
-
- if (Q_UNLIKELY(debug_texture()))
- qDebug("releasing texture %d", id);
-
- Texture &t(textures[idx]);
- if (!t.entryInUse())
- return;
-
- if (t.texture) {
- deferredDelete(t.texture);
- deferredDelete(t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- for (D3D12_CPU_DESCRIPTOR_HANDLE h : t.mipUAVs)
- deferredDelete(h, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- }
-
- QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame
- ? &pframeData[currentPFrameIndex].pendingReleases
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases;
-
- pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeTexture, id));
-}
-
-void QSGD3D12EnginePrivate::useTexture(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
-
- // Within one frame the order of calling this function determines the
- // texture register (0, 1, ...) so fill up activeTextures accordingly.
- tframeData.activeTextures[tframeData.activeTextureCount++]
- = TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeTexture, id);
-
- if (textures[idx].fenceValue)
- pframeData[currentPFrameIndex].pendingTextureUploads.insert(id);
-}
-
-bool QSGD3D12EnginePrivate::MipMapGen::initialize(QSGD3D12EnginePrivate *enginePriv)
-{
- engine = enginePriv;
-
- D3D12_STATIC_SAMPLER_DESC sampler = {};
- sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
- sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
- sampler.MinLOD = 0.0f;
- sampler.MaxLOD = D3D12_FLOAT32_MAX;
-
- D3D12_DESCRIPTOR_RANGE descRange[2];
- descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- descRange[0].NumDescriptors = 1;
- descRange[0].BaseShaderRegister = 0; // t0
- descRange[0].RegisterSpace = 0;
- descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
- descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
- descRange[1].NumDescriptors = 4;
- descRange[1].BaseShaderRegister = 0; // u0..u3
- descRange[1].RegisterSpace = 0;
- descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
-
- // Split into two to allow switching between the first and second set of UAVs later.
- D3D12_ROOT_PARAMETER rootParameters[3];
- rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[0].DescriptorTable.NumDescriptorRanges = 1;
- rootParameters[0].DescriptorTable.pDescriptorRanges = &descRange[0];
-
- rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[1].DescriptorTable.NumDescriptorRanges = 1;
- rootParameters[1].DescriptorTable.pDescriptorRanges = &descRange[1];
-
- rootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
- rootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- rootParameters[2].Constants.Num32BitValues = 4; // uint2 mip1Size, uint sampleLevel, uint totalMips
- rootParameters[2].Constants.ShaderRegister = 0; // b0
- rootParameters[2].Constants.RegisterSpace = 0;
-
- D3D12_ROOT_SIGNATURE_DESC desc = {};
- desc.NumParameters = 3;
- desc.pParameters = rootParameters;
- desc.NumStaticSamplers = 1;
- desc.pStaticSamplers = &sampler;
-
- ComPtr<ID3DBlob> signature;
- ComPtr<ID3DBlob> error;
- if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) {
- QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize());
- qWarning("Failed to serialize compute root signature: %s", qPrintable(msg));
- return false;
- }
- if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(),
- IID_PPV_ARGS(&rootSig)))) {
- qWarning("Failed to create compute root signature");
- return false;
- }
-
- D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
- psoDesc.pRootSignature = rootSig.Get();
- psoDesc.CS.pShaderBytecode = g_CS_Generate4MipMaps;
- psoDesc.CS.BytecodeLength = sizeof(g_CS_Generate4MipMaps);
-
- if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) {
- qWarning("Failed to create compute pipeline state");
- return false;
- }
-
- return true;
-}
-
-void QSGD3D12EnginePrivate::MipMapGen::releaseResources()
-{
- pipelineState = nullptr;
- rootSig = nullptr;
-}
-
-// The mipmap generator is used to insert commands on the main 3D queue. It is
-// guaranteed that the queue has a wait for the base texture level upload
-// before invoking queueGenerate(). There can be any number of invocations
-// without waiting for earlier ones to finish. finished() is invoked when it is
-// known for sure that frame containing the upload and mipmap generation has
-// finished on the GPU.
-
-void QSGD3D12EnginePrivate::MipMapGen::queueGenerate(const Texture &t)
-{
- D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc();
-
- engine->commandList->SetPipelineState(pipelineState.Get());
- engine->commandList->SetComputeRootSignature(rootSig.Get());
-
- // 1 SRV + (miplevels - 1) UAVs
- const int descriptorCount = 1 + (textureDesc.MipLevels - 1);
-
- engine->ensureGPUDescriptorHeap(descriptorCount);
-
- // The descriptor heap is set on the command list either because the
- // ensure() call above resized, or, typically, due to a texture-dependent
- // draw call earlier.
-
- engine->transitionResource(t.texture.Get(), engine->commandList,
- D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
-
- QSGD3D12EnginePrivate::PersistentFrameData &pfd(engine->pframeData[engine->currentPFrameIndex]);
-
- const uint stride = engine->cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- D3D12_CPU_DESCRIPTOR_HANDLE h = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart();
- h.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
-
- engine->device->CopyDescriptorsSimple(1, h, t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- h.ptr += stride;
-
- for (int level = 1; level < textureDesc.MipLevels; ++level, h.ptr += stride)
- engine->device->CopyDescriptorsSimple(1, h, t.mipUAVs[level - 1], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart();
- gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
-
- engine->commandList->SetComputeRootDescriptorTable(0, gpuAddr);
- gpuAddr.ptr += stride; // now points to the first UAV
-
- for (int level = 1; level < textureDesc.MipLevels; level += 4, gpuAddr.ptr += stride * 4) {
- engine->commandList->SetComputeRootDescriptorTable(1, gpuAddr);
-
- QSize sz(textureDesc.Width, textureDesc.Height);
- sz.setWidth(qMax(1, sz.width() >> level));
- sz.setHeight(qMax(1, sz.height() >> level));
-
- const quint32 constants[4] = { quint32(sz.width()), quint32(sz.height()),
- quint32(level - 1),
- quint32(textureDesc.MipLevels - 1) };
-
- engine->commandList->SetComputeRoot32BitConstants(2, 4, constants, 0);
- engine->commandList->Dispatch(sz.width(), sz.height(), 1);
- engine->uavBarrier(t.texture.Get(), engine->commandList);
- }
-
- engine->transitionResource(t.texture.Get(), engine->commandList,
- D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
-
- pfd.cbvSrvUavNextFreeDescriptorIndex += descriptorCount;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12Resource> res)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.res = res;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12DescriptorHeap> dh)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.descHeap = dh;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-void QSGD3D12EnginePrivate::deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h, D3D12_DESCRIPTOR_HEAP_TYPE type)
-{
- PersistentFrameData::DeleteQueueEntry e;
- e.cpuDescriptorPtr = h.ptr;
- e.descHeapType = type;
- QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame
- ? &pframeData[currentPFrameIndex].deleteQueue
- : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue;
- (*dq) << e;
-}
-
-uint QSGD3D12EnginePrivate::genRenderTarget()
-{
- return newId(&renderTargets);
-}
-
-void QSGD3D12EnginePrivate::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples)
-{
- ensureDevice();
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse());
- RenderTarget &rt(renderTargets[idx]);
-
- rt.rtv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- rt.dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- rt.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-
- ID3D12Resource *res = createColorBuffer(rt.rtv, size, clearColor, samples);
- if (res)
- rt.color.Attach(res);
-
- ID3D12Resource *dsres = createDepthStencil(rt.dsv, size, samples);
- if (dsres)
- rt.ds.Attach(dsres);
-
- const bool multisample = rt.color->GetDesc().SampleDesc.Count > 1;
- syncEntryFlags(&rt, RenderTarget::Multisample, multisample);
-
- if (!multisample) {
- device->CreateShaderResourceView(rt.color.Get(), nullptr, rt.srv);
- } else {
- D3D12_HEAP_PROPERTIES defaultHeapProp = {};
- defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
-
- D3D12_RESOURCE_DESC textureDesc = {};
- textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- textureDesc.Width = size.width();
- textureDesc.Height = size.height();
- textureDesc.DepthOrArraySize = 1;
- textureDesc.MipLevels = 1;
- textureDesc.Format = RT_COLOR_FORMAT;
- textureDesc.SampleDesc.Count = 1;
- textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-
- HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
- D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&rt.colorResolve));
- if (FAILED(hr)) {
- qWarning("Failed to create resolve buffer: %s",
- qPrintable(comErrorMessage(hr)));
- return;
- }
-
- device->CreateShaderResourceView(rt.colorResolve.Get(), nullptr, rt.srv);
- }
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("created new render target %u, size %dx%d, samples %d", id, size.width(), size.height(), samples);
-}
-
-void QSGD3D12EnginePrivate::releaseRenderTarget(uint id)
-{
- if (!id || !initialized)
- return;
-
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count());
- RenderTarget &rt(renderTargets[idx]);
- if (!rt.entryInUse())
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("releasing render target %u", id);
-
- if (rt.colorResolve) {
- deferredDelete(rt.colorResolve);
- rt.colorResolve = nullptr;
- }
- if (rt.color) {
- deferredDelete(rt.color);
- rt.color = nullptr;
- deferredDelete(rt.rtv, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- deferredDelete(rt.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- }
- if (rt.ds) {
- deferredDelete(rt.ds);
- rt.ds = nullptr;
- deferredDelete(rt.dsv, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- }
-
- rt.flags &= ~RenderTarget::EntryInUse;
-}
-
-void QSGD3D12EnginePrivate::useRenderTargetAsTexture(uint id)
-{
- if (!inFrame) {
- qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
- return;
- }
-
- Q_ASSERT(id);
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count());
- RenderTarget &rt(renderTargets[idx]);
- Q_ASSERT(rt.entryInUse() && rt.color);
-
- if (rt.flags & RenderTarget::NeedsReadBarrier) {
- rt.flags &= ~RenderTarget::NeedsReadBarrier;
- if (rt.flags & RenderTarget::Multisample)
- resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, commandList);
- else
- transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- }
-
- tframeData.activeTextures[tframeData.activeTextureCount++] =
- TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeRenderTarget, id);
-}
-
-QImage QSGD3D12EnginePrivate::executeAndWaitReadbackRenderTarget(uint id)
-{
- // Readback due to QQuickWindow::grabWindow() happens outside
- // begin-endFrame, but QQuickItemGrabResult leads to rendering a layer
- // without a real frame afterwards and triggering readback. This has to be
- // supported as well.
- if (inFrame && (!activeLayers || currentLayerDepth)) {
- qWarning("%s: Cannot be called while frame preparation is active", __FUNCTION__);
- return QImage();
- }
-
- // Due to the above we insert a fake "real" frame when a layer was just rendered into.
- if (inFrame) {
- beginFrame();
- endFrame();
- }
-
- frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr);
-
- D3D12_RESOURCE_STATES bstate;
- bool needsBarrier = false;
- ID3D12Resource *rtRes;
- if (id == 0) {
- const int idx = presentFrameIndex % swapChainBufferCount;
- if (windowSamples > 1) {
- resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(),
- D3D12_RESOURCE_STATE_COPY_SOURCE, frameCommandList.Get());
- } else {
- bstate = D3D12_RESOURCE_STATE_PRESENT;
- needsBarrier = true;
- }
- rtRes = backBufferRT[idx].Get();
- } else {
- const int idx = id - 1;
- Q_ASSERT(idx < renderTargets.count());
- RenderTarget &rt(renderTargets[idx]);
- Q_ASSERT(rt.entryInUse() && rt.color);
-
- if (rt.flags & RenderTarget::Multisample) {
- resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(),
- D3D12_RESOURCE_STATE_COPY_SOURCE, frameCommandList.Get());
- rtRes = rt.colorResolve.Get();
- } else {
- rtRes = rt.color.Get();
- bstate = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
- needsBarrier = true;
- }
- }
-
- ComPtr<ID3D12Resource> readbackBuf;
-
- D3D12_RESOURCE_DESC rtDesc = rtRes->GetDesc();
- UINT64 textureByteSize = 0;
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT textureLayout = {};
- device->GetCopyableFootprints(&rtDesc, 0, 1, 0, &textureLayout, nullptr, nullptr, &textureByteSize);
-
- D3D12_HEAP_PROPERTIES heapProp = {};
- heapProp.Type = D3D12_HEAP_TYPE_READBACK;
-
- D3D12_RESOURCE_DESC bufDesc = {};
- bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufDesc.Width = textureByteSize;
- bufDesc.Height = 1;
- bufDesc.DepthOrArraySize = 1;
- bufDesc.MipLevels = 1;
- bufDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufDesc.SampleDesc.Count = 1;
- bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
-
- if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc,
- D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&readbackBuf)))) {
- qWarning("Failed to create committed resource (readback buffer)");
- return QImage();
- }
-
- D3D12_TEXTURE_COPY_LOCATION dstLoc;
- dstLoc.pResource = readbackBuf.Get();
- dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
- dstLoc.PlacedFootprint = textureLayout;
- D3D12_TEXTURE_COPY_LOCATION srcLoc;
- srcLoc.pResource = rtRes;
- srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
- srcLoc.SubresourceIndex = 0;
-
- ID3D12GraphicsCommandList *cl = frameCommandList.Get();
- if (needsBarrier)
- transitionResource(rtRes, cl, bstate, D3D12_RESOURCE_STATE_COPY_SOURCE);
- cl->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
- if (needsBarrier)
- transitionResource(rtRes, cl, D3D12_RESOURCE_STATE_COPY_SOURCE, bstate);
-
- cl->Close();
- ID3D12CommandList *commandLists[] = { cl };
- commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- QScopedPointer<QSGD3D12CPUWaitableFence> f(createCPUWaitableFence());
- waitForGPU(f.data()); // uh oh
-
- QImage::Format fmt = imageFormatForTexture(rtDesc.Format);
- if (fmt == QImage::Format_Invalid) {
- qWarning("Could not map render target format %d to a QImage format", rtDesc.Format);
- return QImage();
- }
- QImage img(rtDesc.Width, rtDesc.Height, fmt);
- quint8 *p = nullptr;
- const D3D12_RANGE readRange = { 0, 0 };
- if (FAILED(readbackBuf->Map(0, &readRange, reinterpret_cast<void **>(&p)))) {
- qWarning("Mapping the readback buffer failed");
- return QImage();
- }
- const int bpp = 4; // ###
- if (id == 0) {
- for (UINT y = 0; y < rtDesc.Height; ++y) {
- quint8 *dst = img.scanLine(y);
- memcpy(dst, p, rtDesc.Width * bpp);
- p += textureLayout.Footprint.RowPitch;
- }
- } else {
- for (int y = rtDesc.Height - 1; y >= 0; --y) {
- quint8 *dst = img.scanLine(y);
- memcpy(dst, p, rtDesc.Width * bpp);
- p += textureLayout.Footprint.RowPitch;
- }
- }
- readbackBuf->Unmap(0, nullptr);
-
- return img;
-}
-
-void QSGD3D12EnginePrivate::simulateDeviceLoss()
-{
- qWarning("QSGD3D12Engine: Triggering device loss via TDR");
- devLossTest.killDevice();
-}
-
-bool QSGD3D12EnginePrivate::DeviceLossTester::initialize(QSGD3D12EnginePrivate *enginePriv)
-{
- engine = enginePriv;
-
-#ifdef DEVLOSS_TEST
- D3D12_DESCRIPTOR_RANGE descRange[2];
- descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
- descRange[0].NumDescriptors = 1;
- descRange[0].BaseShaderRegister = 0;
- descRange[0].RegisterSpace = 0;
- descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
- descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
- descRange[1].NumDescriptors = 1;
- descRange[1].BaseShaderRegister = 0;
- descRange[1].RegisterSpace = 0;
- descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
-
- D3D12_ROOT_PARAMETER param;
- param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- param.DescriptorTable.NumDescriptorRanges = 2;
- param.DescriptorTable.pDescriptorRanges = descRange;
-
- D3D12_ROOT_SIGNATURE_DESC desc = {};
- desc.NumParameters = 1;
- desc.pParameters = &param;
-
- ComPtr<ID3DBlob> signature;
- ComPtr<ID3DBlob> error;
- if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) {
- QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize());
- qWarning("Failed to serialize compute root signature: %s", qPrintable(msg));
- return false;
- }
- if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(),
- IID_PPV_ARGS(&computeRootSignature)))) {
- qWarning("Failed to create compute root signature");
- return false;
- }
-
- D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
- psoDesc.pRootSignature = computeRootSignature.Get();
- psoDesc.CS.pShaderBytecode = g_timeout;
- psoDesc.CS.BytecodeLength = sizeof(g_timeout);
-
- if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&computeState)))) {
- qWarning("Failed to create compute pipeline state");
- return false;
- }
-#endif
-
- return true;
-}
-
-void QSGD3D12EnginePrivate::DeviceLossTester::releaseResources()
-{
- computeState = nullptr;
- computeRootSignature = nullptr;
-}
-
-void QSGD3D12EnginePrivate::DeviceLossTester::killDevice()
-{
-#ifdef DEVLOSS_TEST
- ID3D12CommandAllocator *ca = engine->frameCommandAllocator[engine->frameIndex % engine->frameInFlightCount].Get();
- ID3D12GraphicsCommandList *cl = engine->frameCommandList.Get();
- cl->Reset(ca, computeState.Get());
-
- cl->SetComputeRootSignature(computeRootSignature.Get());
- cl->Dispatch(256, 1, 1);
-
- cl->Close();
- ID3D12CommandList *commandLists[] = { cl };
- engine->commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
-
- engine->waitGPU();
-#endif
-}
-
-void *QSGD3D12EnginePrivate::getResource(QSGRendererInterface::Resource resource) const
-{
- switch (resource) {
- case QSGRendererInterface::DeviceResource:
- return device;
- case QSGRendererInterface::CommandQueueResource:
- return commandQueue.Get();
- case QSGRendererInterface::CommandListResource:
- return commandList;
- default:
- break;
- }
- return nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
deleted file mode 100644
index b80de28bed..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12ENGINE_P_H
-#define QSGD3D12ENGINE_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 <QWindow>
-#include <QImage>
-#include <QVector4D>
-#include <qsggeometry.h>
-#include <qsgrendererinterface.h>
-#include <qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-
-// No D3D or COM headers must be pulled in here. All that has to be isolated
-// to engine_p_p.h and engine.cpp.
-
-class QSGD3D12EnginePrivate;
-
-// Shader bytecode and other strings are expected to be static so that a
-// different pointer means a different shader.
-
-enum QSGD3D12Format {
- FmtUnknown = 0,
-
- FmtFloat4 = 2, // DXGI_FORMAT_R32G32B32A32_FLOAT
- FmtFloat3 = 6, // DXGI_FORMAT_R32G32B32_FLOAT
- FmtFloat2 = 16, // DXGI_FORMAT_R32G32_FLOAT
- FmtFloat = 41, // DXGI_FORMAT_R32_FLOAT
-
- // glVertexAttribPointer with GL_UNSIGNED_BYTE and normalized == true maps to the UNORM formats below
- FmtUNormByte4 = 28, // DXGI_FORMAT_R8G8B8A8_UNORM
- FmtUNormByte2 = 49, // DXGI_FORMAT_R8G8_UNORM
- FmtUNormByte = 61, // DXGI_FORMAT_R8_UNORM
-
- // Index data types
- FmtUnsignedShort = 57, // DXGI_FORMAT_R16_UINT
- FmtUnsignedInt = 42 // DXGI_FORMAT_R32_UINT
-};
-
-struct QSGD3D12InputElement
-{
- const char *semanticName = nullptr;
- int semanticIndex = 0;
- QSGD3D12Format format = FmtFloat4;
- quint32 slot = 0;
- quint32 offset = 0;
-
- bool operator==(const QSGD3D12InputElement &other) const {
- return semanticName == other.semanticName && semanticIndex == other.semanticIndex
- && format == other.format && slot == other.slot && offset == other.offset;
- }
-};
-
-inline uint qHash(const QSGD3D12InputElement &key, uint seed = 0)
-{
- return qHash(key.semanticName, seed) + key.semanticIndex + key.format + key.offset;
-}
-
-struct QSGD3D12TextureView
-{
- enum Filter {
- FilterNearest = 0,
- FilterLinear = 0x15,
- FilterMinMagNearestMipLinear = 0x1,
- FilterMinMagLinearMipNearest = 0x14
- };
-
- enum AddressMode {
- AddressWrap = 1,
- AddressClamp = 3
- };
-
- Filter filter = FilterLinear;
- AddressMode addressModeHoriz = AddressClamp;
- AddressMode addressModeVert = AddressClamp;
-
- bool operator==(const QSGD3D12TextureView &other) const {
- return filter == other.filter
- && addressModeHoriz == other.addressModeHoriz
- && addressModeVert == other.addressModeVert;
- }
-};
-
-inline uint qHash(const QSGD3D12TextureView &key, uint seed = 0)
-{
- Q_UNUSED(seed);
- return key.filter + key.addressModeHoriz + key.addressModeVert;
-}
-
-const int QSGD3D12_MAX_TEXTURE_VIEWS = 8;
-
-struct QSGD3D12RootSignature
-{
- int textureViewCount = 0;
- QSGD3D12TextureView textureViews[QSGD3D12_MAX_TEXTURE_VIEWS];
-
- bool operator==(const QSGD3D12RootSignature &other) const {
- if (textureViewCount != other.textureViewCount)
- return false;
- for (int i = 0; i < textureViewCount; ++i)
- if (!(textureViews[i] == other.textureViews[i]))
- return false;
- return true;
- }
-};
-
-inline uint qHash(const QSGD3D12RootSignature &key, uint seed = 0)
-{
- return key.textureViewCount + (key.textureViewCount > 0 ? qHash(key.textureViews[0], seed) : 0);
-}
-
-// Shader bytecode blobs and root signature-related data.
-struct QSGD3D12ShaderState
-{
- const quint8 *vs = nullptr;
- quint32 vsSize = 0;
- const quint8 *ps = nullptr;
- quint32 psSize = 0;
-
- QSGD3D12RootSignature rootSig;
-
- bool operator==(const QSGD3D12ShaderState &other) const {
- return vs == other.vs && vsSize == other.vsSize
- && ps == other.ps && psSize == other.psSize
- && rootSig == other.rootSig;
- }
-};
-
-inline uint qHash(const QSGD3D12ShaderState &key, uint seed = 0)
-{
- return qHash(key.vs, seed) + key.vsSize + qHash(key.ps, seed) + key.psSize + qHash(key.rootSig, seed);
-}
-
-const int QSGD3D12_MAX_INPUT_ELEMENTS = 8;
-
-struct QSGD3D12PipelineState
-{
- enum CullMode {
- CullNone = 1,
- CullFront,
- CullBack
- };
-
- enum CompareFunc {
- CompareNever = 1,
- CompareLess,
- CompareEqual,
- CompareLessEqual,
- CompareGreater,
- CompareNotEqual,
- CompareGreaterEqual,
- CompareAlways
- };
-
- enum StencilOp {
- StencilKeep = 1,
- StencilZero,
- StencilReplace,
- StencilIncrSat,
- StencilDecrSat,
- StencilInvert,
- StencilIncr,
- StencilDescr
- };
-
- enum TopologyType {
- TopologyTypePoint = 1,
- TopologyTypeLine,
- TopologyTypeTriangle
- };
-
- enum BlendType {
- BlendNone,
- BlendPremul, // == GL_ONE, GL_ONE_MINUS_SRC_ALPHA
- BlendColor // == GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR
- };
-
- QSGD3D12ShaderState shaders;
-
- int inputElementCount = 0;
- QSGD3D12InputElement inputElements[QSGD3D12_MAX_INPUT_ELEMENTS];
-
- CullMode cullMode = CullNone;
- bool frontCCW = true;
- bool colorWrite = true;
- BlendType blend = BlendNone;
- bool depthEnable = true;
- CompareFunc depthFunc = CompareLess;
- bool depthWrite = true;
- bool stencilEnable = false;
- CompareFunc stencilFunc = CompareEqual;
- StencilOp stencilFailOp = StencilKeep;
- StencilOp stencilDepthFailOp = StencilKeep;
- StencilOp stencilPassOp = StencilKeep;
- TopologyType topologyType = TopologyTypeTriangle;
-
- bool operator==(const QSGD3D12PipelineState &other) const {
- bool eq = shaders == other.shaders
- && inputElementCount == other.inputElementCount
- && cullMode == other.cullMode
- && frontCCW == other.frontCCW
- && colorWrite == other.colorWrite
- && blend == other.blend
- && depthEnable == other.depthEnable
- && (!depthEnable || depthFunc == other.depthFunc)
- && depthWrite == other.depthWrite
- && stencilEnable == other.stencilEnable
- && (!stencilEnable || stencilFunc == other.stencilFunc)
- && (!stencilEnable || stencilFailOp == other.stencilFailOp)
- && (!stencilEnable || stencilDepthFailOp == other.stencilDepthFailOp)
- && (!stencilEnable || stencilPassOp == other.stencilPassOp)
- && topologyType == other.topologyType;
- if (eq) {
- for (int i = 0; i < inputElementCount; ++i) {
- if (!(inputElements[i] == other.inputElements[i])) {
- eq = false;
- break;
- }
- }
- }
- return eq;
- }
-};
-
-inline uint qHash(const QSGD3D12PipelineState &key, uint seed = 0)
-{
- return qHash(key.shaders, seed) + key.inputElementCount
- + key.cullMode + key.frontCCW
- + key.colorWrite + key.blend
- + key.depthEnable + key.depthWrite
- + key.stencilEnable
- + key.topologyType;
-}
-
-class QSGD3D12Engine
-{
-public:
- QSGD3D12Engine();
- ~QSGD3D12Engine();
-
- bool attachToWindow(WId window, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha);
- void releaseResources();
- bool hasResources() const;
- void setWindowSize(const QSize &size, float dpr);
- WId window() const;
- QSize windowSize() const;
- float windowDevicePixelRatio() const;
- uint windowSamples() const;
-
- void beginFrame();
- void endFrame();
- void beginLayer();
- void endLayer();
- void invalidateCachedFrameState();
- void restoreFrameState(bool minimal = false);
-
- uint genBuffer();
- void releaseBuffer(uint id);
- void resetBuffer(uint id, const quint8 *data, int size);
- void markBufferDirty(uint id, int offset, int size);
-
- enum ClearFlag {
- ClearDepth = 0x1,
- ClearStencil = 0x2
- };
- Q_DECLARE_FLAGS(ClearFlags, ClearFlag)
-
- void queueViewport(const QRect &rect);
- void queueScissor(const QRect &rect);
- void queueSetRenderTarget(uint id = 0);
- void queueClearRenderTarget(const QColor &color);
- void queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which);
- void queueSetBlendFactor(const QVector4D &factor);
- void queueSetStencilRef(quint32 ref);
-
- void finalizePipeline(const QSGD3D12PipelineState &pipelineState);
-
- struct DrawParams {
- QSGGeometry::DrawingMode mode = QSGGeometry::DrawTriangles;
- int count = 0;
- uint vertexBuf = 0;
- uint indexBuf = 0;
- uint constantBuf = 0;
- int vboOffset = 0;
- int vboSize = 0;
- int vboStride = 0;
- int cboOffset = 0;
- int startIndexIndex = -1;
- QSGD3D12Format indexFormat = FmtUnsignedShort;
- };
-
- void queueDraw(const DrawParams &params);
-
- void present();
- void waitGPU();
-
- static quint32 alignedConstantBufferSize(quint32 size);
- static QSGD3D12Format toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize = 1, int *size = nullptr);
- static int mipMapLevels(const QSize &size);
- static QSize mipMapAdjustedSourceSize(const QSize &size);
-
- enum TextureCreateFlag {
- TextureWithAlpha = 0x01,
- TextureWithMipMaps = 0x02,
- TextureAlways32Bit = 0x04
- };
- Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag)
-
- enum TextureUploadFlag {
- TextureUploadAlways32Bit = 0x01
- };
- Q_DECLARE_FLAGS(TextureUploadFlags, TextureUploadFlag)
-
- uint genTexture();
- void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags);
- void queueTextureResize(uint id, const QSize &size);
- void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint(), TextureUploadFlags flags = { });
- void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, TextureUploadFlags flags = { });
- void releaseTexture(uint id);
- void useTexture(uint id);
-
- uint genRenderTarget();
- void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples);
- void releaseRenderTarget(uint id);
- void useRenderTargetAsTexture(uint id);
- uint activeRenderTarget() const;
-
- QImage executeAndWaitReadbackRenderTarget(uint id = 0);
-
- void simulateDeviceLoss();
-
- void *getResource(QQuickWindow *window, QSGRendererInterface::Resource resource) const;
-
-private:
- QSGD3D12EnginePrivate *d;
- Q_DISABLE_COPY(QSGD3D12Engine)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureUploadFlags)
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12ENGINE_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h
deleted file mode 100644
index a95cbb1cbb..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12ENGINE_P_P_H
-#define QSGD3D12ENGINE_P_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 "qsgd3d12engine_p.h"
-#include <QCache>
-
-#include <d3d12.h>
-#include <dxgi1_4.h>
-#include <dcomp.h>
-#include <wrl/client.h>
-
-using namespace Microsoft::WRL;
-
-// No moc-related features (Q_OBJECT, signals, etc.) can be used here to due
-// moc-generated code failing to compile when combined with COM stuff.
-
-// Recommended reading before moving further: https://github.com/Microsoft/DirectXTK/wiki/ComPtr
-// Note esp. operator= vs. Attach and operator& vs. GetAddressOf
-
-// ID3D12* is never passed to Qt containers directly. Always use ComPtr and put it into a struct.
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12CPUDescriptorHeapManager
-{
-public:
- void initialize(ID3D12Device *device);
-
- void releaseResources();
-
- D3D12_CPU_DESCRIPTOR_HANDLE allocate(D3D12_DESCRIPTOR_HEAP_TYPE type);
- void release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type);
- quint32 handleSize(D3D12_DESCRIPTOR_HEAP_TYPE type) const { return m_handleSizes[type]; }
-
-private:
- ID3D12Device *m_device = nullptr;
- struct Heap {
- D3D12_DESCRIPTOR_HEAP_TYPE type;
- ComPtr<ID3D12DescriptorHeap> heap;
- D3D12_CPU_DESCRIPTOR_HANDLE start;
- quint32 handleSize;
- quint32 freeMap[8];
- };
- QVector<Heap> m_heaps;
- quint32 m_handleSizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
-};
-
-class QSGD3D12DeviceManager
-{
-public:
- ID3D12Device *ref();
- void unref();
- void deviceLossDetected();
- IDXGIFactory4 *dxgi();
-
- struct DeviceLossObserver {
- virtual void deviceLost() = 0;
- virtual ~DeviceLossObserver() = default;
- };
- void registerDeviceLossObserver(DeviceLossObserver *observer);
-
-private:
- void ensureCreated();
-
- ComPtr<ID3D12Device> m_device;
- ComPtr<IDXGIFactory4> m_factory;
- QAtomicInt m_ref;
- QVector<DeviceLossObserver *> m_observers;
-};
-
-struct QSGD3D12CPUWaitableFence
-{
- ~QSGD3D12CPUWaitableFence() {
- if (event)
- CloseHandle(event);
- }
- ComPtr<ID3D12Fence> fence;
- HANDLE event = nullptr;
- QAtomicInt value;
-};
-
-class QSGD3D12EnginePrivate : public QSGD3D12DeviceManager::DeviceLossObserver
-{
-public:
- void initialize(WId w, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha);
- bool isInitialized() const { return initialized; }
- void releaseResources();
- void setWindowSize(const QSize &size, float dpr);
- WId currentWindow() const { return window; }
- QSize currentWindowSize() const { return windowSize; }
- float currentWindowDpr() const { return windowDpr; }
- uint currentWindowSamples() const { return windowSamples; }
-
- void beginFrame();
- void endFrame();
- void beginLayer();
- void endLayer();
- void invalidateCachedFrameState();
- void restoreFrameState(bool minimal = false);
-
- uint genBuffer();
- void releaseBuffer(uint id);
- void resetBuffer(uint id, const quint8 *data, int size);
- void markBufferDirty(uint id, int offset, int size);
-
- void queueViewport(const QRect &rect);
- void queueScissor(const QRect &rect);
- void queueSetRenderTarget(uint id);
- void queueClearRenderTarget(const QColor &color);
- void queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which);
- void queueSetBlendFactor(const QVector4D &factor);
- void queueSetStencilRef(quint32 ref);
-
- void finalizePipeline(const QSGD3D12PipelineState &pipelineState);
-
- void queueDraw(const QSGD3D12Engine::DrawParams &params);
-
- void present();
- void waitGPU();
-
- uint genTexture();
- void createTexture(uint id, const QSize &size, QImage::Format format, QSGD3D12Engine::TextureCreateFlags flags);
- void queueTextureResize(uint id, const QSize &size);
- void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos,
- QSGD3D12Engine::TextureUploadFlags flags);
- void releaseTexture(uint id);
- void useTexture(uint id);
-
- uint genRenderTarget();
- void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples);
- void releaseRenderTarget(uint id);
- void useRenderTargetAsTexture(uint id);
- uint activeRenderTarget() const { return currentRenderTarget; }
-
- QImage executeAndWaitReadbackRenderTarget(uint id);
-
- void simulateDeviceLoss();
-
- void *getResource(QSGRendererInterface::Resource resource) const;
-
- // the device is intentionally hidden here. all resources have to go
- // through the engine and, unlike with GL, cannot just be created in random
- // places due to the need for proper tracking, managing and releasing.
-private:
- void ensureDevice();
- void setupDefaultRenderTargets();
- void deviceLost() override;
-
- bool createCbvSrvUavHeap(int pframeIndex, int descriptorCount);
- void setDescriptorHeaps(bool force = false);
- void ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount);
-
- DXGI_SAMPLE_DESC makeSampleDesc(DXGI_FORMAT format, uint samples);
- ID3D12Resource *createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
- const QVector4D &clearColor, uint samples);
- ID3D12Resource *createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, uint samples);
-
- QSGD3D12CPUWaitableFence *createCPUWaitableFence() const;
- void waitForGPU(QSGD3D12CPUWaitableFence *f) const;
-
- void transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList,
- D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const;
- void resolveMultisampledTarget(ID3D12Resource *msaa, ID3D12Resource *resolve, D3D12_RESOURCE_STATES resolveUsage,
- ID3D12GraphicsCommandList *commandList) const;
- void uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const;
-
- ID3D12Resource *createBuffer(int size);
-
- typedef QVector<QPair<int, int> > DirtyList;
- void addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize);
-
- struct PersistentFrameData {
- ComPtr<ID3D12DescriptorHeap> gpuCbvSrvUavHeap;
- int gpuCbvSrvUavHeapSize;
- int cbvSrvUavNextFreeDescriptorIndex;
- QSet<uint> pendingTextureUploads;
- QSet<uint> pendingTextureMipMap;
- struct DeleteQueueEntry {
- ComPtr<ID3D12Resource> res;
- ComPtr<ID3D12DescriptorHeap> descHeap;
- SIZE_T cpuDescriptorPtr = 0;
- D3D12_DESCRIPTOR_HEAP_TYPE descHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
- };
- QVector<DeleteQueueEntry> deleteQueue;
- QVector<DeleteQueueEntry> outOfFrameDeleteQueue;
- QSet<uint> buffersUsedInDrawCallSet;
- QSet<uint> buffersUsedInFrame;
- struct PendingRelease {
- enum Type {
- TypeTexture,
- TypeBuffer
- };
- Type type = TypeTexture;
- uint id = 0;
- PendingRelease(Type type, uint id) : type(type), id(id) { }
- PendingRelease() { }
- bool operator==(const PendingRelease &other) const { return type == other.type && id == other.id; }
- };
- QSet<PendingRelease> pendingReleases;
- QSet<PendingRelease> outOfFramePendingReleases;
- };
- friend uint qHash(const PersistentFrameData::PendingRelease &pr, uint seed);
-
- void deferredDelete(ComPtr<ID3D12Resource> res);
- void deferredDelete(ComPtr<ID3D12DescriptorHeap> dh);
- void deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h, D3D12_DESCRIPTOR_HEAP_TYPE type);
-
- struct Buffer;
- void ensureBuffer(Buffer *buf);
- void updateBuffer(Buffer *buf);
-
- void beginDrawCalls();
- void beginFrameDraw();
- void endDrawCalls(bool lastInFrame = false);
-
- static const int MAX_SWAP_CHAIN_BUFFER_COUNT = 4;
- static const int MAX_FRAME_IN_FLIGHT_COUNT = 4;
-
- bool initialized = false;
- bool inFrame = false;
- WId window = 0;
- QSize windowSize;
- float windowDpr;
- uint windowSamples;
- bool windowAlpha;
- int swapChainBufferCount;
- int frameInFlightCount;
- int waitableSwapChainMaxLatency;
- ID3D12Device *device;
- ComPtr<ID3D12CommandQueue> commandQueue;
- ComPtr<ID3D12CommandQueue> copyCommandQueue;
- ComPtr<IDXGISwapChain3> swapChain;
- HANDLE swapEvent;
- ComPtr<ID3D12Resource> backBufferRT[MAX_SWAP_CHAIN_BUFFER_COUNT];
- ComPtr<ID3D12Resource> defaultRT[MAX_SWAP_CHAIN_BUFFER_COUNT];
- D3D12_CPU_DESCRIPTOR_HANDLE defaultRTV[MAX_SWAP_CHAIN_BUFFER_COUNT];
- ComPtr<ID3D12Resource> defaultDS;
- D3D12_CPU_DESCRIPTOR_HANDLE defaultDSV;
- ComPtr<ID3D12CommandAllocator> frameCommandAllocator[MAX_FRAME_IN_FLIGHT_COUNT];
- ComPtr<ID3D12CommandAllocator> copyCommandAllocator;
- ComPtr<ID3D12GraphicsCommandList> frameCommandList;
- ComPtr<ID3D12GraphicsCommandList> copyCommandList;
- QSGD3D12CPUDescriptorHeapManager cpuDescHeapManager;
- quint64 presentFrameIndex;
- quint64 frameIndex;
- QSGD3D12CPUWaitableFence *presentFence = nullptr;
- QSGD3D12CPUWaitableFence *frameFence[MAX_FRAME_IN_FLIGHT_COUNT];
-
- PersistentFrameData pframeData[MAX_FRAME_IN_FLIGHT_COUNT];
- int currentPFrameIndex;
- ID3D12GraphicsCommandList *commandList = nullptr;
- int activeLayers = 0;
- int currentLayerDepth = 0;
-
- struct PSOCacheEntry {
- ComPtr<ID3D12PipelineState> pso;
- };
- QCache<QSGD3D12PipelineState, PSOCacheEntry> psoCache;
- struct RootSigCacheEntry {
- ComPtr<ID3D12RootSignature> rootSig;
- };
- QCache<QSGD3D12RootSignature, RootSigCacheEntry> rootSigCache;
-
- struct Texture {
- enum Flag {
- EntryInUse = 0x01,
- Alpha = 0x02,
- MipMap = 0x04
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- bool alpha() const { return flags & Alpha; }
- bool mipmap() const { return flags & MipMap; }
- ComPtr<ID3D12Resource> texture;
- D3D12_CPU_DESCRIPTOR_HANDLE srv;
- quint64 fenceValue = 0;
- quint64 lastWaitFenceValue = 0;
- struct StagingHeap {
- ComPtr<ID3D12Heap> heap;
- };
- QVector<StagingHeap> stagingHeaps;
- struct StagingBuffer {
- ComPtr<ID3D12Resource> buffer;
- };
- QVector<StagingBuffer> stagingBuffers;
- QVector<D3D12_CPU_DESCRIPTOR_HANDLE> mipUAVs;
- };
-
- QVector<Texture> textures;
- ComPtr<ID3D12Fence> textureUploadFence;
- QAtomicInt nextTextureUploadFenceValue;
-
- struct TransientFrameData {
- QSGGeometry::DrawingMode drawingMode;
- uint currentIndexBuffer;
- struct ActiveTexture {
- enum Type {
- TypeTexture,
- TypeRenderTarget
- };
- Type type = TypeTexture;
- uint id = 0;
- ActiveTexture(Type type, uint id) : type(type), id(id) { }
- ActiveTexture() { }
- };
- int activeTextureCount;
- ActiveTexture activeTextures[QSGD3D12_MAX_TEXTURE_VIEWS];
- int drawCount;
- ID3D12PipelineState *lastPso;
- ID3D12RootSignature *lastRootSig;
- bool descHeapSet;
-
- QRect viewport;
- QRect scissor;
- QVector4D blendFactor = QVector4D(1, 1, 1, 1);
- quint32 stencilRef = 1;
- QSGD3D12PipelineState pipelineState;
- };
- TransientFrameData tframeData;
-
- struct MipMapGen {
- bool initialize(QSGD3D12EnginePrivate *enginePriv);
- void releaseResources();
- void queueGenerate(const Texture &t);
-
- QSGD3D12EnginePrivate *engine;
- ComPtr<ID3D12RootSignature> rootSig;
- ComPtr<ID3D12PipelineState> pipelineState;
- };
-
- MipMapGen mipmapper;
-
- struct RenderTarget {
- enum Flag {
- EntryInUse = 0x01,
- NeedsReadBarrier = 0x02,
- Multisample = 0x04
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- ComPtr<ID3D12Resource> color;
- ComPtr<ID3D12Resource> colorResolve;
- D3D12_CPU_DESCRIPTOR_HANDLE rtv;
- ComPtr<ID3D12Resource> ds;
- D3D12_CPU_DESCRIPTOR_HANDLE dsv;
- D3D12_CPU_DESCRIPTOR_HANDLE srv;
- };
-
- QVector<RenderTarget> renderTargets;
- uint currentRenderTarget;
-
- struct CPUBufferRef {
- const quint8 *p = nullptr;
- quint32 size = 0;
- DirtyList dirty;
- CPUBufferRef() { dirty.reserve(16); }
- };
-
- struct Buffer {
- enum Flag {
- EntryInUse = 0x01
- };
- int flags = 0;
- bool entryInUse() const { return flags & EntryInUse; }
- struct InFlightData {
- ComPtr<ID3D12Resource> buffer;
- DirtyList dirty;
- quint32 dataSize = 0;
- quint32 resourceSize = 0;
- InFlightData() { dirty.reserve(16); }
- };
- InFlightData d[MAX_FRAME_IN_FLIGHT_COUNT];
- CPUBufferRef cpuDataRef;
- };
-
- QVector<Buffer> buffers;
-
- struct DeviceLossTester {
- bool initialize(QSGD3D12EnginePrivate *enginePriv);
- void releaseResources();
- void killDevice();
-
- QSGD3D12EnginePrivate *engine;
- ComPtr<ID3D12PipelineState> computeState;
- ComPtr<ID3D12RootSignature> computeRootSignature;
- };
-
- DeviceLossTester devLossTest;
-
-#ifndef Q_OS_WINRT
- ComPtr<IDCompositionDevice> dcompDevice;
- ComPtr<IDCompositionTarget> dcompTarget;
- ComPtr<IDCompositionVisual> dcompVisual;
-#endif
-};
-
-inline uint qHash(const QSGD3D12EnginePrivate::PersistentFrameData::PendingRelease &pr, uint seed = 0)
-{
- Q_UNUSED(seed);
- return pr.id + pr.type;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp
deleted file mode 100644
index 915917c3d5..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12glyphcache_p.h"
-#include "qsgd3d12engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// Convert A8 glyphs to 32-bit in the engine. This is here to work around
-// QTBUG-55330 for AMD cards.
-// If removing, textmask.hlsl must be adjusted! (.a -> .r)
-#define ALWAYS_32BIT
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12GlyphCache::QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QTextureGlyphCache(format, matrix),
- m_engine(engine)
-{
-}
-
-QSGD3D12GlyphCache::~QSGD3D12GlyphCache()
-{
- if (m_id)
- m_engine->releaseTexture(m_id);
-}
-
-void QSGD3D12GlyphCache::createTextureData(int width, int height)
-{
- width = qMax(128, width);
- height = qMax(32, height);
-
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("new glyph cache texture %u of size %dx%d, fontengine format %d", m_id, width, height, m_format);
-
- m_size = QSize(width, height);
-
- const QImage::Format imageFormat =
- m_format == QFontEngine::Format_A8 ? QImage::Format_Alpha8 : QImage::Format_ARGB32_Premultiplied;
- m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::TextureWithAlpha
-#ifdef ALWAYS_32BIT
- | QSGD3D12Engine::TextureAlways32Bit
-#endif
- );
-}
-
-void QSGD3D12GlyphCache::resizeTextureData(int width, int height)
-{
- width = qMax(128, width);
- height = qMax(32, height);
-
- if (m_size.width() >= width && m_size.height() >= height)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("glyph cache texture %u resize to %dx%d", m_id, width, height);
-
- m_size = QSize(width, height);
-
- m_engine->queueTextureResize(m_id, m_size);
-}
-
-void QSGD3D12GlyphCache::beginFillTexture()
-{
- Q_ASSERT(m_glyphImages.isEmpty() && m_glyphPos.isEmpty());
-}
-
-void QSGD3D12GlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
-{
- QImage mask = textureMapForGlyph(glyph, subPixelPosition);
- const int maskWidth = mask.width();
- const int maskHeight = mask.height();
-
- if (mask.format() == QImage::Format_Mono) {
- mask = mask.convertToFormat(QImage::Format_Indexed8);
- for (int y = 0; y < maskHeight; ++y) {
- uchar *src = mask.scanLine(y);
- for (int x = 0; x < maskWidth; ++x)
- src[x] = -src[x]; // convert 0 and 1 into 0 and 255
- }
- } else if (mask.depth() == 32) {
- if (mask.format() == QImage::Format_RGB32) {
- // We need to make the alpha component equal to the average of the RGB values.
- // This is needed when drawing sub-pixel antialiased text on translucent targets.
- for (int y = 0; y < maskHeight; ++y) {
- QRgb *src = reinterpret_cast<QRgb *>(mask.scanLine(y));
- for (int x = 0; x < maskWidth; ++x) {
- const int r = qRed(src[x]);
- const int g = qGreen(src[x]);
- const int b = qBlue(src[x]);
- int avg;
- if (mask.format() == QImage::Format_RGB32)
- avg = (r + g + b + 1) / 3; // "+1" for rounding.
- else // Format_ARGB32_Premultiplied
- avg = qAlpha(src[x]);
- src[x] = qRgba(r, g, b, avg);
- }
- }
- }
- }
-
- m_glyphImages.append(mask);
- m_glyphPos.append(QPoint(c.x, c.y));
-}
-
-void QSGD3D12GlyphCache::endFillTexture()
-{
- if (m_glyphImages.isEmpty())
- return;
-
- Q_ASSERT(m_id);
-
- m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos
-#ifdef ALWAYS_32BIT
- , QSGD3D12Engine::TextureUploadAlways32Bit
-#endif
- );
-
- // Nothing else left to do, it is up to the text material to call
- // useTexture() which will then add the texture dependency to the frame.
-
- m_glyphImages.clear();
- m_glyphPos.clear();
-}
-
-int QSGD3D12GlyphCache::glyphPadding() const
-{
- return 1;
-}
-
-int QSGD3D12GlyphCache::maxTextureWidth() const
-{
- return 16384;
-}
-
-int QSGD3D12GlyphCache::maxTextureHeight() const
-{
- return 16384;
-}
-
-void QSGD3D12GlyphCache::useTexture()
-{
- if (m_id)
- m_engine->useTexture(m_id);
-}
-
-QSize QSGD3D12GlyphCache::currentSize() const
-{
- return m_size;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h
deleted file mode 100644
index 88d3d36f33..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12GLYPHCACHE_P_H
-#define QSGD3D12GLYPHCACHE_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 <QtGui/private/qtextureglyphcache_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-
-class QSGD3D12GlyphCache : public QTextureGlyphCache
-{
-public:
- QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix);
- ~QSGD3D12GlyphCache();
-
- void createTextureData(int width, int height) override;
- void resizeTextureData(int width, int height) override;
- void beginFillTexture() override;
- void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override;
- void endFillTexture() override;
- int glyphPadding() const override;
- int maxTextureWidth() const override;
- int maxTextureHeight() const override;
-
- void useTexture();
- QSize currentSize() const;
-
-private:
- QSGD3D12Engine *m_engine;
- uint m_id = 0;
- QVector<QImage> m_glyphImages;
- QVector<QPoint> m_glyphPos;
- QSize m_size;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12GLYPHCACHE_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp
deleted file mode 100644
index e559739018..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12glyphnode_p.h"
-#include "qsgd3d12builtinmaterials_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void QSGD3D12GlyphNode::setMaterialColor(const QColor &color)
-{
- static_cast<QSGD3D12TextMaterial *>(m_material)->setColor(color);
-}
-
-void QSGD3D12GlyphNode::update()
-{
- QRawFont font = m_glyphs.rawFont();
- QMargins margins(0, 0, 0, 0);
-
- if (m_style == QQuickText::Normal) {
- // QSGBasicGlyphNode dtor will delete
- m_material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Normal, m_rc, font);
- } else if (m_style == QQuickText::Outline) {
- QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Outlined,
- m_rc, font, QFontEngine::Format_A8);
- material->setStyleColor(m_styleColor);
- m_material = material;
- margins = QMargins(1, 1, 1, 1);
- } else {
- QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Styled,
- m_rc, font, QFontEngine::Format_A8);
- if (m_style == QQuickText::Sunken) {
- material->setStyleShift(QVector2D(0, -1));
- margins.setTop(1);
- } else if (m_style == QQuickText::Raised) {
- material->setStyleShift(QVector2D(0, 1));
- margins.setBottom(1);
- }
- material->setStyleColor(m_styleColor);
- m_material = material;
- }
-
- QSGD3D12TextMaterial *textMaterial = static_cast<QSGD3D12TextMaterial *>(m_material);
- textMaterial->setColor(m_color);
-
- QRectF boundingRect;
- textMaterial->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(),
- &boundingRect, &m_baseLine, margins);
- setBoundingRect(boundingRect);
-
- setMaterial(m_material);
- markDirty(DirtyGeometry);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp
deleted file mode 100644
index aa163cacbf..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12internalimagenode_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12InternalImageNode::QSGD3D12InternalImageNode()
-{
- setMaterial(&m_material);
-}
-
-void QSGD3D12InternalImageNode::setFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.filtering() == filtering)
- return;
-
- m_material.setFiltering(filtering);
- m_smoothMaterial.setFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12InternalImageNode::setMipmapFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.mipmapFiltering() == filtering)
- return;
-
- m_material.setMipmapFiltering(filtering);
- m_smoothMaterial.setMipmapFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12InternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
-{
- if (m_material.verticalWrapMode() == wrapMode)
- return;
-
- m_material.setVerticalWrapMode(wrapMode);
- m_smoothMaterial.setVerticalWrapMode(wrapMode);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12InternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
-{
- if (m_material.horizontalWrapMode() == wrapMode)
- return;
-
- m_material.setHorizontalWrapMode(wrapMode);
- m_smoothMaterial.setHorizontalWrapMode(wrapMode);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12InternalImageNode::updateMaterialAntialiasing()
-{
- if (m_antialiasing)
- setMaterial(&m_smoothMaterial);
- else
- setMaterial(&m_material);
-}
-
-void QSGD3D12InternalImageNode::setMaterialTexture(QSGTexture *texture)
-{
- m_material.setTexture(texture);
- m_smoothMaterial.setTexture(texture);
-}
-
-QSGTexture *QSGD3D12InternalImageNode::materialTexture() const
-{
- return m_material.texture();
-}
-
-bool QSGD3D12InternalImageNode::updateMaterialBlending()
-{
- const bool alpha = m_material.flags() & QSGMaterial::Blending;
- if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) {
- m_material.setFlag(QSGMaterial::Blending, !alpha);
- return true;
- }
- return false;
-}
-
-bool QSGD3D12InternalImageNode::supportsWrap(const QSize &) const
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp
deleted file mode 100644
index 2d9c5b55d1..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12internalrectanglenode_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12InternalRectangleNode::QSGD3D12InternalRectangleNode()
-{
- setMaterial(&m_material);
-}
-
-void QSGD3D12InternalRectangleNode::updateMaterialAntialiasing()
-{
- if (m_antialiasing)
- setMaterial(&m_smoothMaterial);
- else
- setMaterial(&m_material);
-}
-
-void QSGD3D12InternalRectangleNode::updateMaterialBlending(QSGNode::DirtyState *state)
-{
- // smoothed material is always blended, so no change in material state
- if (material() == &m_material) {
- bool wasBlending = (m_material.flags() & QSGMaterial::Blending);
- bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque)
- || (m_color.alpha() < 255 && m_color.alpha() != 0)
- || (m_pen_width > 0 && m_border_color.alpha() < 255);
- if (wasBlending != isBlending) {
- m_material.setFlag(QSGMaterial::Blending, isBlending);
- *state |= QSGNode::DirtyMaterial;
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp
deleted file mode 100644
index b9d3a180cf..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12layer_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12renderer_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc)
- : QSGLayer(*(new QSGD3D12LayerPrivate)),
- m_rc(rc)
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("new layer %p", this);
-}
-
-QSGD3D12Layer::~QSGD3D12Layer()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("destroying layer %p", this);
-
- cleanup();
-}
-
-// QSGTexture
-
-int QSGD3D12Layer::textureId() const
-{
- return m_rt; // not a texture id per se but will do
-}
-
-int QSGD3D12LayerPrivate::comparisonKey() const
-{
- Q_Q(const QSGD3D12Layer);
- return q->m_rt;
-}
-
-QSize QSGD3D12Layer::textureSize() const
-{
- return m_size;
-}
-
-bool QSGD3D12Layer::hasAlphaChannel() const
-{
- return true;
-}
-
-bool QSGD3D12Layer::hasMipmaps() const
-{
- // mipmapped layers are not supported for now
- return false;
-}
-
-QRectF QSGD3D12Layer::normalizedTextureSubRect() const
-{
- return QRectF(m_mirrorHorizontal ? 1 : 0,
- m_mirrorVertical ? 0 : 1,
- m_mirrorHorizontal ? -1 : 1,
- m_mirrorVertical ? 1 : -1);
-}
-
-void QSGD3D12Layer::bind()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p bind rt=%u", this, m_rt);
-
- QSGD3D12Engine *engine = m_rc->engine();
- Q_ASSERT(m_rt);
-
-#ifndef QT_NO_DEBUG
- // Should not use the color buffer as a texture while it is the current render target.
- if (!m_recursive && engine->activeRenderTarget() == m_rt && engine->windowSamples() == 1)
- qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively.");
-#endif
-
- engine->useRenderTargetAsTexture(m_rt);
-}
-
-// QSGDynamicTexture
-
-bool QSGD3D12Layer::updateTexture()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p updateTexture", this);
-
- const bool doUpdate = (m_live || m_updateContentPending) && m_dirtyTexture;
-
- if (doUpdate)
- updateContent();
-
- if (m_updateContentPending) {
- m_updateContentPending = false;
- emit scheduledUpdateCompleted();
- }
-
- return doUpdate;
-}
-
-// QSGLayer
-
-void QSGD3D12Layer::setItem(QSGNode *item)
-{
- if (m_item == item)
- return;
-
- if (m_live && !item)
- resetRenderTarget();
-
- m_item = item;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setRect(const QRectF &rect)
-{
- if (m_rect == rect)
- return;
-
- m_rect = rect;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setSize(const QSize &size)
-{
- if (m_size == size)
- return;
-
- if (m_live && size.isNull())
- resetRenderTarget();
-
- m_size = size;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::scheduleUpdate()
-{
- if (m_updateContentPending)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p scheduleUpdate", this);
-
- m_updateContentPending = true;
-
- if (m_dirtyTexture)
- emit updateRequested();
-}
-
-QImage QSGD3D12Layer::toImage() const
-{
- return m_rc->engine()->executeAndWaitReadbackRenderTarget(m_rt);
-}
-
-void QSGD3D12Layer::setLive(bool live)
-{
- if (m_live == live)
- return;
-
- if (live && (!m_item || m_size.isNull()))
- resetRenderTarget();
-
- m_live = live;
- markDirtyTexture();
-}
-
-void QSGD3D12Layer::setRecursive(bool recursive)
-{
- m_recursive = recursive;
-}
-
-void QSGD3D12Layer::setFormat(uint format)
-{
- Q_UNUSED(format);
-}
-
-void QSGD3D12Layer::setHasMipmaps(bool mipmap)
-{
- // mipmapped layers are not supported for now
- Q_UNUSED(mipmap);
-}
-
-void QSGD3D12Layer::setDevicePixelRatio(qreal ratio)
-{
- m_dpr = ratio;
-}
-
-void QSGD3D12Layer::setMirrorHorizontal(bool mirror)
-{
- m_mirrorHorizontal = mirror;
-}
-
-void QSGD3D12Layer::setMirrorVertical(bool mirror)
-{
- m_mirrorVertical = mirror;
-}
-
-void QSGD3D12Layer::markDirtyTexture()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p markDirtyTexture", this);
-
- m_dirtyTexture = true;
-
- if (m_live || m_updateContentPending)
- emit updateRequested();
-}
-
-void QSGD3D12Layer::invalidated()
-{
- cleanup();
-}
-
-void QSGD3D12Layer::cleanup()
-{
- if (!m_renderer && !m_rt)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p cleanup renderer=%p rt=%u", this, m_renderer, m_rt);
-
- delete m_renderer;
- m_renderer = nullptr;
-
- resetRenderTarget();
-}
-
-void QSGD3D12Layer::resetRenderTarget()
-{
- if (!m_rt)
- return;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p resetRenderTarget rt=%u", this, m_rt);
-
- m_rc->engine()->releaseRenderTarget(m_rt);
- m_rt = 0;
-
- if (m_secondaryRT) {
- m_rc->engine()->releaseRenderTarget(m_secondaryRT);
- m_secondaryRT = 0;
- }
-}
-
-void QSGD3D12Layer::updateContent()
-{
- if (Q_UNLIKELY(debug_render()))
- qDebug("layer %p updateContent", this);
-
- if (!m_item || m_size.isNull()) {
- resetRenderTarget();
- m_dirtyTexture = false;
- return;
- }
-
- QSGNode *root = m_item;
- while (root->firstChild() && root->type() != QSGNode::RootNodeType)
- root = root->firstChild();
-
- if (root->type() != QSGNode::RootNodeType)
- return;
-
- if (!m_renderer) {
- m_renderer = m_rc->createRenderer();
- static_cast<QSGD3D12Renderer *>(m_renderer)->turnToLayerRenderer();
- connect(m_renderer, &QSGRenderer::sceneGraphChanged, this, &QSGD3D12Layer::markDirtyTexture);
- }
-
- m_renderer->setDevicePixelRatio(m_dpr);
- m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
-
- QSGD3D12Engine *engine = m_rc->engine();
- const uint sampleCount = engine->windowSamples();
- const QVector4D clearColor;
-
- if (!m_rt || m_rtSize != m_size) {
- if (m_rt)
- resetRenderTarget();
-
- m_rt = engine->genRenderTarget();
- m_rtSize = m_size;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("new render target for layer %p, size=%dx%d, samples=%d",
- this, m_size.width(), m_size.height(), sampleCount);
-
- engine->createRenderTarget(m_rt, m_rtSize, clearColor, sampleCount);
-
- // For multisampling the resolving via an extra non-ms color buffer is
- // handled internally in the engine, no need to worry about it here.
- }
-
- if (m_recursive && !m_secondaryRT && sampleCount == 1) {
- m_secondaryRT = engine->genRenderTarget();
- engine->createRenderTarget(m_secondaryRT, m_rtSize, clearColor, sampleCount);
- }
-
- m_dirtyTexture = false;
-
- m_renderer->setDeviceRect(m_size);
- m_renderer->setViewportRect(m_size);
-
- // Note that the handling of vertical mirroring differs from OpenGL here
- // due to y running top-bottom with D3D as opposed to bottom-top with GL.
- // The common parts of Quick follow OpenGL so vertical mirroring is
- // typically enabled.
- QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
- m_mirrorVertical ? m_rect.top() : m_rect.bottom(),
- m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
- m_mirrorVertical ? m_rect.height() : -m_rect.height());
-
- m_renderer->setProjectionMatrixToRect(mirrored);
- m_renderer->setClearColor(Qt::transparent);
-
- if (!m_recursive || sampleCount > 1) {
- m_renderer->renderScene(m_rt);
- } else {
- m_renderer->renderScene(m_secondaryRT);
- qSwap(m_rt, m_secondaryRT);
- }
-
- if (m_recursive)
- markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h
deleted file mode 100644
index 42a56877cf..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12LAYER_P_H
-#define QSGD3D12LAYER_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 <private/qsgadaptationlayer_p.h>
-#include <private/qsgtexture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-class QSGD3D12LayerPrivate;
-
-class QSGD3D12Layer : public QSGLayer
-{
- Q_DECLARE_PRIVATE(QSGD3D12Layer)
- Q_OBJECT
-
-public:
- QSGD3D12Layer(QSGD3D12RenderContext *rc);
- ~QSGD3D12Layer();
-
- int textureId() const override;
- QSize textureSize() const override;
- bool hasAlphaChannel() const override;
- bool hasMipmaps() const override;
- QRectF normalizedTextureSubRect() const override;
- void bind() override;
-
- bool updateTexture() override;
-
- void setItem(QSGNode *item) override;
- void setRect(const QRectF &rect) override;
- void setSize(const QSize &size) override;
- void scheduleUpdate() override;
- QImage toImage() const override;
- void setLive(bool live) override;
- void setRecursive(bool recursive) override;
- void setFormat(uint format) override;
- void setHasMipmaps(bool mipmap) override;
- void setDevicePixelRatio(qreal ratio) override;
- void setMirrorHorizontal(bool mirror) override;
- void setMirrorVertical(bool mirror) override;
- void setSamples(int) override { }
-
-public Q_SLOTS:
- void markDirtyTexture() override;
- void invalidated() override;
-
-private:
- void cleanup();
- void resetRenderTarget();
- void updateContent();
-
- QSGD3D12RenderContext *m_rc;
- uint m_rt = 0;
- uint m_secondaryRT = 0;
- QSize m_rtSize;
- QSize m_size;
- QRectF m_rect;
- QSGNode *m_item = nullptr;
- QSGRenderer *m_renderer = nullptr;
- float m_dpr = 1;
- bool m_mirrorHorizontal = false;
- bool m_mirrorVertical = true;
- bool m_live = true;
- bool m_recursive = false;
- bool m_dirtyTexture = true;
- bool m_updateContentPending = false;
-};
-
-class QSGD3D12LayerPrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGD3D12Layer)
-public:
- int comparisonKey() const override;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12LAYER_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp
deleted file mode 100644
index 1b638106ee..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12material_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGMaterialShader *QSGD3D12Material::createShader() const
-{
- return nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h
deleted file mode 100644
index 65d53600c3..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12MATERIAL_P_H
-#define QSGD3D12MATERIAL_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/qsgmaterial.h>
-#include "qsgd3d12engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGRenderer;
-
-// The D3D renderer works with QSGD3D12Material as the "base" class since
-// QSGMaterial and its GL program related bits are not suitable. Also, there is
-// no split like with QSGMaterialShader.
-
-typedef QSGMaterialShader::RenderState QSGD3D12MaterialRenderState;
-
-class QSGD3D12Material : public QSGMaterial
-{
-public:
- struct ExtraState {
- QVector4D blendFactor;
- };
-
- enum UpdateResult {
- UpdatedShaders = 0x0001,
- UpdatedConstantBuffer = 0x0002,
- UpdatedBlendFactor = 0x0004
- };
- Q_DECLARE_FLAGS(UpdateResults, UpdateResult)
-
- virtual int constantBufferSize() const = 0;
- virtual void preparePipeline(QSGD3D12PipelineState *pipelineState) = 0;
- virtual UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) = 0;
-
-private:
- QSGMaterialShader *createShader() const override; // dummy, QSGMaterialShader is too GL dependent
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::UpdateResults)
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12MATERIAL_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp
deleted file mode 100644
index b22c42f2e5..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12painternode_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12engine_p.h"
-#include <private/qquickitem_p.h>
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12PainterTexture::QSGD3D12PainterTexture(QSGD3D12Engine *engine)
- : QSGD3D12Texture(engine)
-{
-}
-
-void QSGD3D12PainterTexture::bind()
-{
- if (m_image.isNull()) {
- if (!m_id) {
- m_id = m_engine->genTexture();
- m_engine->createTexture(m_id, QSize(16, 16), QImage::Format_RGB32, 0);
- }
- } else if (m_image.size() != lastSize) {
- lastSize = m_image.size();
- if (m_id)
- m_engine->releaseTexture(m_id);
- m_id = m_engine->genTexture();
- m_engine->createTexture(m_id, m_image.size(), m_image.format(), QSGD3D12Engine::TextureWithAlpha);
- m_engine->queueTextureUpload(m_id, m_image);
- } else if (!dirty.isEmpty()) {
- const int bpl = m_image.bytesPerLine();
- const uchar *p = m_image.constBits() + dirty.y() * bpl + dirty.x() * 4;
- QImage subImg(p, dirty.width(), dirty.height(), bpl, QImage::Format_ARGB32_Premultiplied);
- m_engine->queueTextureUpload(m_id, subImg, dirty.topLeft());
- }
-
- dirty = QRect();
-
- m_engine->useTexture(m_id);
-}
-
-QSGD3D12PainterNode::QSGD3D12PainterNode(QQuickPaintedItem *item)
- : m_item(item),
- m_engine(static_cast<QSGD3D12RenderContext *>(QQuickItemPrivate::get(item)->sceneGraphRenderContext())->engine()),
- m_texture(new QSGD3D12PainterTexture(m_engine)),
- m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4),
- m_dirtyGeometry(false),
- m_dirtyContents(false)
-{
- setGeometry(&m_geometry);
- m_material.setTexture(m_texture);
- setMaterial(&m_material);
-}
-
-QSGD3D12PainterNode::~QSGD3D12PainterNode()
-{
- delete m_texture;
-}
-
-void QSGD3D12PainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget)
-{
- // always QImage-based
-}
-
-void QSGD3D12PainterNode::setSize(const QSize &size)
-{
- if (m_size == size)
- return;
-
- m_size = size;
- m_dirtyGeometry = true;
-}
-
-void QSGD3D12PainterNode::setDirty(const QRect &dirtyRect)
-{
- m_dirtyRect = dirtyRect;
- m_dirtyContents = true;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12PainterNode::setOpaquePainting(bool)
-{
- // ignored
-}
-
-void QSGD3D12PainterNode::setLinearFiltering(bool linearFiltering)
-{
- m_material.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12PainterNode::setMipmapping(bool)
-{
- // ### not yet
-}
-
-void QSGD3D12PainterNode::setSmoothPainting(bool s)
-{
- if (m_smoothPainting == s)
- return;
-
- m_smoothPainting = s;
- m_dirtyContents = true;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12PainterNode::setFillColor(const QColor &c)
-{
- if (m_fillColor == c)
- return;
-
- m_fillColor = c;
- m_dirtyContents = true;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12PainterNode::setContentsScale(qreal s)
-{
- if (m_contentsScale == s)
- return;
-
- m_contentsScale = s;
- m_dirtyContents = true;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12PainterNode::setFastFBOResizing(bool)
-{
- // nope
-}
-
-void QSGD3D12PainterNode::setTextureSize(const QSize &size)
-{
- if (m_textureSize == size)
- return;
-
- m_textureSize = size;
- m_dirtyGeometry = true;
-}
-
-QImage QSGD3D12PainterNode::toImage() const
-{
- return *m_texture->image();
-}
-
-void QSGD3D12PainterNode::update()
-{
- if (m_dirtyGeometry) {
- m_dirtyGeometry = false;
- QRectF src(0, 0, 1, 1);
- QRectF dst(QPointF(0, 0), m_size);
- QSGGeometry::updateTexturedRectGeometry(&m_geometry, dst, src);
- markDirty(DirtyGeometry);
- }
-
- QImage *img = m_texture->image();
- if (img->size() != m_textureSize) {
- *img = QImage(m_textureSize, QImage::Format_ARGB32_Premultiplied);
- img->fill(Qt::transparent);
- m_dirtyContents = true;
- }
-
- if (m_dirtyContents) {
- m_dirtyContents = false;
- if (!img->isNull()) {
- QRect dirtyRect = m_dirtyRect.isNull() ? QRect(QPoint(0, 0), m_size) : m_dirtyRect;
- QPainter painter;
- painter.begin(img);
- if (m_smoothPainting)
- painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
-
- QRect clipRect;
- QRect dirtyTextureRect;
-
- if (m_contentsScale == 1) {
- float scaleX = m_textureSize.width() / (float) m_size.width();
- float scaleY = m_textureSize.height() / (float) m_size.height();
- painter.scale(scaleX, scaleY);
- clipRect = dirtyRect;
- dirtyTextureRect = QRectF(dirtyRect.x() * scaleX,
- dirtyRect.y() * scaleY,
- dirtyRect.width() * scaleX,
- dirtyRect.height() * scaleY).toAlignedRect();
- } else {
- painter.scale(m_contentsScale, m_contentsScale);
- QRect sclip(qFloor(dirtyRect.x() / m_contentsScale),
- qFloor(dirtyRect.y() / m_contentsScale),
- qCeil(dirtyRect.width() / m_contentsScale + dirtyRect.x() / m_contentsScale
- - qFloor(dirtyRect.x() / m_contentsScale)),
- qCeil(dirtyRect.height() / m_contentsScale + dirtyRect.y() / m_contentsScale
- - qFloor(dirtyRect.y() / m_contentsScale)));
- clipRect = sclip;
- dirtyTextureRect = dirtyRect;
- }
-
- // only clip if we were originally updating only a subrect
- if (!m_dirtyRect.isNull())
- painter.setClipRect(clipRect);
-
- painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(clipRect, m_fillColor);
- painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-
- m_item->paint(&painter);
- painter.end();
-
- m_texture->dirty = dirtyTextureRect;
- }
- m_dirtyRect = QRect();
- }
-}
-
-QSGTexture *QSGD3D12PainterNode::texture() const
-{
- return m_texture;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp
deleted file mode 100644
index 1f01c440e5..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12publicnodes_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGD3D12RectangleNode::QSGD3D12RectangleNode()
- : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
-{
- QSGGeometry::updateRectGeometry(&m_geometry, QRectF());
- setMaterial(&m_material);
- setGeometry(&m_geometry);
-#ifdef QSG_RUNTIME_DESCRIPTION
- qsgnode_set_description(this, QLatin1String("rectangle"));
-#endif
-}
-
-void QSGD3D12RectangleNode::setRect(const QRectF &rect)
-{
- QSGGeometry::updateRectGeometry(&m_geometry, rect);
- markDirty(QSGNode::DirtyGeometry);
-}
-
-QRectF QSGD3D12RectangleNode::rect() const
-{
- const QSGGeometry::Point2D *pts = m_geometry.vertexDataAsPoint2D();
- return QRectF(pts[0].x,
- pts[0].y,
- pts[3].x - pts[0].x,
- pts[3].y - pts[0].y);
-}
-
-void QSGD3D12RectangleNode::setColor(const QColor &color)
-{
- if (color != m_material.color()) {
- m_material.setColor(color);
- markDirty(QSGNode::DirtyMaterial);
- }
-}
-
-QColor QSGD3D12RectangleNode::color() const
-{
- return m_material.color();
-}
-
-QSGD3D12ImageNode::QSGD3D12ImageNode()
- : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4),
- m_texCoordMode(QSGD3D12ImageNode::NoTransform),
- m_isAtlasTexture(false),
- m_ownsTexture(false)
-{
- setGeometry(&m_geometry);
- setMaterial(&m_material);
- m_material.setMipmapFiltering(QSGTexture::None);
-#ifdef QSG_RUNTIME_DESCRIPTION
- qsgnode_set_description(this, QLatin1String("image"));
-#endif
-}
-
-QSGD3D12ImageNode::~QSGD3D12ImageNode()
-{
- if (m_ownsTexture)
- delete m_material.texture();
-}
-
-void QSGD3D12ImageNode::setFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.filtering() == filtering)
- return;
-
- m_material.setFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-QSGTexture::Filtering QSGD3D12ImageNode::filtering() const
-{
- return m_material.filtering();
-}
-
-void QSGD3D12ImageNode::setMipmapFiltering(QSGTexture::Filtering filtering)
-{
- if (m_material.mipmapFiltering() == filtering)
- return;
-
- m_material.setMipmapFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-QSGTexture::Filtering QSGD3D12ImageNode::mipmapFiltering() const
-{
- return m_material.mipmapFiltering();
-}
-
-void QSGD3D12ImageNode::setRect(const QRectF &r)
-{
- if (m_rect == r)
- return;
-
- m_rect = r;
- QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
- markDirty(DirtyGeometry);
-}
-
-QRectF QSGD3D12ImageNode::rect() const
-{
- return m_rect;
-}
-
-void QSGD3D12ImageNode::setSourceRect(const QRectF &r)
-{
- if (m_sourceRect == r)
- return;
-
- m_sourceRect = r;
- QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
- markDirty(DirtyGeometry);
-}
-
-QRectF QSGD3D12ImageNode::sourceRect() const
-{
- return m_sourceRect;
-}
-
-void QSGD3D12ImageNode::setTexture(QSGTexture *texture)
-{
- Q_ASSERT(texture);
-
- if (m_ownsTexture)
- delete m_material.texture();
-
- m_material.setTexture(texture);
- QSGImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode);
-
- DirtyState dirty = DirtyMaterial;
- const bool wasAtlas = m_isAtlasTexture;
- m_isAtlasTexture = texture->isAtlasTexture();
- if (wasAtlas || m_isAtlasTexture)
- dirty |= DirtyGeometry;
-
- markDirty(dirty);
-}
-
-QSGTexture *QSGD3D12ImageNode::texture() const
-{
- return m_material.texture();
-}
-
-void QSGD3D12ImageNode::setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode)
-{
- if (m_texCoordMode == mode)
- return;
-
- m_texCoordMode = mode;
- QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
- markDirty(DirtyMaterial);
-}
-
-QSGD3D12ImageNode::TextureCoordinatesTransformMode QSGD3D12ImageNode::textureCoordinatesTransform() const
-{
- return m_texCoordMode;
-}
-
-void QSGD3D12ImageNode::setOwnsTexture(bool owns)
-{
- m_ownsTexture = owns;
-}
-
-bool QSGD3D12ImageNode::ownsTexture() const
-{
- return m_ownsTexture;
-}
-
-QSGD3D12NinePatchNode::QSGD3D12NinePatchNode()
- : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
-{
- m_geometry.setDrawingMode(QSGGeometry::DrawTriangleStrip);
- setGeometry(&m_geometry);
- setMaterial(&m_material);
-}
-
-QSGD3D12NinePatchNode::~QSGD3D12NinePatchNode()
-{
- delete m_material.texture();
-}
-
-void QSGD3D12NinePatchNode::setTexture(QSGTexture *texture)
-{
- delete m_material.texture();
- m_material.setTexture(texture);
-}
-
-void QSGD3D12NinePatchNode::setBounds(const QRectF &bounds)
-{
- m_bounds = bounds;
-}
-
-void QSGD3D12NinePatchNode::setDevicePixelRatio(qreal ratio)
-{
- m_devicePixelRatio = ratio;
-}
-
-void QSGD3D12NinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom)
-{
- m_padding = QVector4D(left, top, right, bottom);
-}
-
-void QSGD3D12NinePatchNode::update()
-{
- QSGNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio);
- markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h
deleted file mode 100644
index 6150083aaf..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12PUBLICNODES_P_H
-#define QSGD3D12PUBLICNODES_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/qsgrectanglenode.h>
-#include <QtQuick/qsgimagenode.h>
-#include <QtQuick/qsgninepatchnode.h>
-#include "qsgd3d12builtinmaterials_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RectangleNode : public QSGRectangleNode
-{
-public:
- QSGD3D12RectangleNode();
-
- void setRect(const QRectF &rect) override;
- QRectF rect() const override;
-
- void setColor(const QColor &color) override;
- QColor color() const override;
-
-private:
- QSGGeometry m_geometry;
- QSGD3D12FlatColorMaterial m_material;
-};
-
-class QSGD3D12ImageNode : public QSGImageNode
-{
-public:
- QSGD3D12ImageNode();
- ~QSGD3D12ImageNode();
-
- void setRect(const QRectF &rect) override;
- QRectF rect() const override;
-
- void setSourceRect(const QRectF &r) override;
- QRectF sourceRect() const override;
-
- void setTexture(QSGTexture *texture) override;
- QSGTexture *texture() const override;
-
- void setFiltering(QSGTexture::Filtering filtering) override;
- QSGTexture::Filtering filtering() const override;
-
- void setMipmapFiltering(QSGTexture::Filtering filtering) override;
- QSGTexture::Filtering mipmapFiltering() const override;
-
- void setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode) override;
- TextureCoordinatesTransformMode textureCoordinatesTransform() const override;
-
- void setOwnsTexture(bool owns) override;
- bool ownsTexture() const override;
-
-private:
- QSGGeometry m_geometry;
- QSGD3D12TextureMaterial m_material;
- QRectF m_rect;
- QRectF m_sourceRect;
- TextureCoordinatesTransformMode m_texCoordMode;
- uint m_isAtlasTexture : 1;
- uint m_ownsTexture : 1;
-};
-
-class QSGD3D12NinePatchNode : public QSGNinePatchNode
-{
-public:
- QSGD3D12NinePatchNode();
- ~QSGD3D12NinePatchNode();
-
- void setTexture(QSGTexture *texture) override;
- void setBounds(const QRectF &bounds) override;
- void setDevicePixelRatio(qreal ratio) override;
- void setPadding(qreal left, qreal top, qreal right, qreal bottom) override;
- void update() override;
-
-private:
- QSGGeometry m_geometry;
- QSGD3D12TextureMaterial m_material;
- QRectF m_bounds;
- qreal m_devicePixelRatio;
- QVector4D m_padding;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp
deleted file mode 100644
index 48693207c6..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12renderer_p.h"
-#include "qsgd3d12texture_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(render)
-
-QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx)
- : QSGRenderContext(ctx)
-{
-}
-
-bool QSGD3D12RenderContext::isValid() const
-{
- // The render thread sets an engine when it starts up and resets when it
- // quits. The rc is initialized and functional between those two points,
- // regardless of any calls to invalidate(). See setEngine().
- return m_engine != nullptr;
-}
-
-void QSGD3D12RenderContext::initialize(const InitParams *)
-{
- if (m_initialized)
- return;
-
- m_initialized = true;
- emit initialized();
-}
-
-void QSGD3D12RenderContext::invalidate()
-{
- if (!m_initialized)
- return;
-
- m_initialized = false;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug("rendercontext invalidate engine %p, %d/%d/%d", m_engine,
- m_texturesToDelete.count(), m_textures.count(), m_fontEnginesToClean.count());
-
- qDeleteAll(m_texturesToDelete);
- m_texturesToDelete.clear();
-
- qDeleteAll(m_textures);
- m_textures.clear();
-
- for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(),
- end = m_fontEnginesToClean.constEnd(); it != end; ++it) {
- (*it)->clearGlyphCache(m_engine);
- if (!(*it)->ref.deref())
- delete *it;
- }
- m_fontEnginesToClean.clear();
-
- m_sg->renderContextInvalidated(this);
- emit invalidated();
-}
-
-QSGTexture *QSGD3D12RenderContext::createTexture(const QImage &image, uint flags) const
-{
- Q_ASSERT(m_engine);
- QSGD3D12Texture *t = new QSGD3D12Texture(m_engine);
- t->create(image, flags);
- return t;
-}
-
-QSGRenderer *QSGD3D12RenderContext::createRenderer()
-{
- return new QSGD3D12Renderer(this);
-}
-
-int QSGD3D12RenderContext::maxTextureSize() const
-{
- return 16384; // D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION
-}
-
-void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo)
-{
- static_cast<QSGD3D12Renderer *>(renderer)->renderScene(fbo);
-}
-
-void QSGD3D12RenderContext::setEngine(QSGD3D12Engine *engine)
-{
- if (m_engine == engine)
- return;
-
- m_engine = engine;
-
- if (m_engine)
- initialize(nullptr);
-}
-
-QSGRendererInterface::GraphicsApi QSGD3D12RenderContext::graphicsApi() const
-{
- return Direct3D12;
-}
-
-void *QSGD3D12RenderContext::getResource(QQuickWindow *window, Resource resource) const
-{
- if (!m_engine) {
- qWarning("getResource: No D3D12 engine available yet (window not exposed?)");
- return nullptr;
- }
- // window can be ignored since the rendercontext and engine are both per window
- return m_engine->getResource(window, resource);
-}
-
-QSGRendererInterface::ShaderType QSGD3D12RenderContext::shaderType() const
-{
- return HLSL;
-}
-
-QSGRendererInterface::ShaderCompilationTypes QSGD3D12RenderContext::shaderCompilationType() const
-{
- return RuntimeCompilation | OfflineCompilation;
-}
-
-QSGRendererInterface::ShaderSourceTypes QSGD3D12RenderContext::shaderSourceType() const
-{
- return ShaderSourceString | ShaderSourceFile | ShaderByteCode;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h
deleted file mode 100644
index c555c0808e..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERCONTEXT_P_H
-#define QSGD3D12RENDERCONTEXT_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 <private/qsgcontext_p.h>
-#include <qsgrendererinterface.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-
-class QSGD3D12RenderContext : public QSGRenderContext, public QSGRendererInterface
-{
-public:
- QSGD3D12RenderContext(QSGContext *ctx);
- bool isValid() const override;
- void initialize(const InitParams *params) override;
- void invalidate() override;
- void renderNextFrame(QSGRenderer *renderer, uint fbo) override;
- QSGTexture *createTexture(const QImage &image, uint flags) const override;
- QSGRenderer *createRenderer() override;
- int maxTextureSize() const override;
-
- void setEngine(QSGD3D12Engine *engine);
- QSGD3D12Engine *engine() { return m_engine; }
-
- // QSGRendererInterface
- GraphicsApi graphicsApi() const override;
- void *getResource(QQuickWindow *window, Resource resource) const override;
- ShaderType shaderType() const override;
- ShaderCompilationTypes shaderCompilationType() const override;
- ShaderSourceTypes shaderSourceType() const override;
-
-private:
- QSGD3D12Engine *m_engine = nullptr;
- bool m_initialized = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERCONTEXT_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp
deleted file mode 100644
index c38c616ae6..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp
+++ /dev/null
@@ -1,785 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12renderer_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include <private/qsgnodeupdater_p.h>
-#include <private/qsgrendernode_p.h>
-
-#include "vs_stencilclip.hlslh"
-#include "ps_stencilclip.hlslh"
-
-//#define I_LIKE_STENCIL
-
-QT_BEGIN_NAMESPACE
-
-#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(build)
-DECLARE_DEBUG_VAR(change)
-DECLARE_DEBUG_VAR(render)
-
-class DummyUpdater : public QSGNodeUpdater
-{
-public:
- void updateState(QSGNode *) { };
-};
-
-QSGD3D12Renderer::QSGD3D12Renderer(QSGRenderContext *context)
- : QSGRenderer(context),
- m_vboData(1024),
- m_iboData(256),
- m_cboData(4096),
- m_renderList(16)
-{
- setNodeUpdater(new DummyUpdater);
-}
-
-QSGD3D12Renderer::~QSGD3D12Renderer()
-{
- if (m_engine) {
- m_engine->releaseBuffer(m_vertexBuf);
- m_engine->releaseBuffer(m_indexBuf);
- m_engine->releaseBuffer(m_constantBuf);
- }
-}
-
-void QSGD3D12Renderer::renderScene(GLuint fboId)
-{
- m_renderTarget = fboId;
-
- struct DummyBindable : public QSGBindable {
- void bind() const { }
- } bindable;
-
- QSGRenderer::renderScene(bindable); // calls back render()
-}
-
-// Search through the node set and remove nodes that are descendants of other
-// nodes in the same set.
-static QSet<QSGNode *> qsg_removeDescendants(const QSet<QSGNode *> &nodes, QSGRootNode *root)
-{
- QSet<QSGNode *> result = nodes;
- for (QSGNode *node : nodes) {
- QSGNode *n = node;
- while (n != root) {
- if (n != node && result.contains(n)) {
- result.remove(node);
- break;
- }
- n = n->parent();
- }
- }
- return result;
-}
-
-void QSGD3D12Renderer::updateMatrices(QSGNode *node, QSGTransformNode *xform)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::TransformNodeType) {
- QSGTransformNode *tn = static_cast<QSGTransformNode *>(node);
- if (xform)
- tn->setCombinedMatrix(xform->combinedMatrix() * tn->matrix());
- else
- tn->setCombinedMatrix(tn->matrix());
- QSGNODE_TRAVERSE(node)
- updateMatrices(child, tn);
- } else {
- if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) {
- m_nodeDirtyMap[node] |= QSGD3D12MaterialRenderState::DirtyMatrix;
- QSGBasicGeometryNode *gnode = static_cast<QSGBasicGeometryNode *>(node);
- const QMatrix4x4 *newMatrix = xform ? &xform->combinedMatrix() : nullptr;
- // NB the newMatrix ptr is usually the same as before as it just
- // references the transform node's own matrix.
- gnode->setRendererMatrix(newMatrix);
- }
- QSGNODE_TRAVERSE(node)
- updateMatrices(child, xform);
- }
-}
-
-void QSGD3D12Renderer::updateOpacities(QSGNode *node, float inheritedOpacity)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::OpacityNodeType) {
- QSGOpacityNode *on = static_cast<QSGOpacityNode *>(node);
- float combined = inheritedOpacity * on->opacity();
- on->setCombinedOpacity(combined);
- QSGNODE_TRAVERSE(node)
- updateOpacities(child, combined);
- } else {
- if (node->type() == QSGNode::GeometryNodeType) {
- m_nodeDirtyMap[node] |= QSGD3D12MaterialRenderState::DirtyOpacity;
- QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node);
- gn->setInheritedOpacity(inheritedOpacity);
- }
- QSGNODE_TRAVERSE(node)
- updateOpacities(child, inheritedOpacity);
- }
-}
-
-void QSGD3D12Renderer::buildRenderList(QSGNode *node, QSGClipNode *clip)
-{
- if (node->isSubtreeBlocked())
- return;
-
- if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) {
- QSGBasicGeometryNode *gn = static_cast<QSGBasicGeometryNode *>(node);
- QSGGeometry *g = gn->geometry();
-
- Element e;
- e.node = gn;
-
- if (g->vertexCount() > 0) {
- e.vboOffset = m_vboData.size();
- const int vertexSize = g->sizeOfVertex() * g->vertexCount();
- m_vboData.resize(m_vboData.size() + vertexSize);
- memcpy(m_vboData.data() + e.vboOffset, g->vertexData(), vertexSize);
- }
-
- if (g->indexCount() > 0) {
- e.iboOffset = m_iboData.size();
- e.iboStride = g->sizeOfIndex();
- const int indexSize = e.iboStride * g->indexCount();
- m_iboData.resize(m_iboData.size() + indexSize);
- memcpy(m_iboData.data() + e.iboOffset, g->indexData(), indexSize);
- }
-
- e.cboOffset = m_cboData.size();
- if (node->type() == QSGNode::GeometryNodeType) {
- QSGD3D12Material *m = static_cast<QSGD3D12Material *>(static_cast<QSGGeometryNode *>(node)->activeMaterial());
- e.cboSize = m->constantBufferSize();
- } else {
- // Stencil-based clipping needs a 4x4 matrix.
- e.cboSize = QSGD3D12Engine::alignedConstantBufferSize(16 * sizeof(float));
- }
- m_cboData.resize(m_cboData.size() + e.cboSize);
-
- m_renderList.add(e);
-
- gn->setRendererClipList(clip);
- if (node->type() == QSGNode::ClipNodeType)
- clip = static_cast<QSGClipNode *>(node);
- } else if (node->type() == QSGNode::RenderNodeType) {
- QSGRenderNode *rn = static_cast<QSGRenderNode *>(node);
- Element e;
- e.node = rn;
- m_renderList.add(e);
- }
-
- QSGNODE_TRAVERSE(node)
- buildRenderList(child, clip);
-}
-
-void QSGD3D12Renderer::render()
-{
- QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(context());
- m_engine = rc->engine();
- if (!m_layerRenderer)
- m_engine->beginFrame();
- else
- m_engine->beginLayer();
-
- m_activeScissorRect = QRect();
-
- if (m_rebuild) {
- m_rebuild = false;
-
- m_dirtyTransformNodes.clear();
- m_dirtyTransformNodes.insert(rootNode());
- m_dirtyOpacityNodes.clear();
- m_dirtyOpacityNodes.insert(rootNode());
-
- m_renderList.reset();
- m_vboData.reset();
- m_iboData.reset();
- m_cboData.reset();
-
- buildRenderList(rootNode(), nullptr);
-
- if (!m_vertexBuf)
- m_vertexBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_vertexBuf, m_vboData.data(), m_vboData.size());
-
- if (!m_constantBuf)
- m_constantBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_constantBuf, m_cboData.data(), m_cboData.size());
-
- if (m_iboData.size()) {
- if (!m_indexBuf)
- m_indexBuf = m_engine->genBuffer();
- m_engine->resetBuffer(m_indexBuf, m_iboData.data(), m_iboData.size());
- } else if (m_indexBuf) {
- m_engine->releaseBuffer(m_indexBuf);
- m_indexBuf = 0;
- }
-
- if (Q_UNLIKELY(debug_build())) {
- qDebug("renderList: %d elements in total", m_renderList.size());
- for (int i = 0; i < m_renderList.size(); ++i) {
- const Element &e = m_renderList.at(i);
- qDebug() << " - " << e.vboOffset << e.iboOffset << e.cboOffset << e.cboSize << e.node;
- }
- }
- }
-
- const QRect devRect = deviceRect();
- m_projectionChangedDueToDeviceSize = devRect != m_lastDeviceRect;
- if (m_projectionChangedDueToDeviceSize)
- m_lastDeviceRect = devRect;
-
- if (m_dirtyTransformNodes.size()) {
- const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyTransformNodes, rootNode());
- for (QSGNode *node : subTreeRoots) {
- // First find the parent transform so we have the accumulated
- // matrix up until this point.
- QSGTransformNode *xform = 0;
- QSGNode *n = node;
- if (n->type() == QSGNode::TransformNodeType)
- n = node->parent();
- while (n != rootNode() && n->type() != QSGNode::TransformNodeType)
- n = n->parent();
- if (n != rootNode())
- xform = static_cast<QSGTransformNode *>(n);
-
- // Then update in the subtree
- updateMatrices(node, xform);
- }
- }
-
- if (m_dirtyOpacityNodes.size()) {
- const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyOpacityNodes, rootNode());
- for (QSGNode *node : subTreeRoots) {
- float opacity = 1.0f;
- QSGNode *n = node;
- if (n->type() == QSGNode::OpacityNodeType)
- n = node->parent();
- while (n != rootNode() && n->type() != QSGNode::OpacityNodeType)
- n = n->parent();
- if (n != rootNode())
- opacity = static_cast<QSGOpacityNode *>(n)->combinedOpacity();
-
- updateOpacities(node, opacity);
- }
- m_dirtyOpaqueElements = true;
- }
-
- if (m_dirtyOpaqueElements) {
- m_dirtyOpaqueElements = false;
- m_opaqueElements.clear();
- m_opaqueElements.resize(m_renderList.size());
- for (int i = 0; i < m_renderList.size(); ++i) {
- const Element &e = m_renderList.at(i);
- if (e.node->type() == QSGNode::GeometryNodeType) {
- const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node);
- if (gn->inheritedOpacity() > 0.999f && ((gn->activeMaterial()->flags() & QSGMaterial::Blending) == 0))
- m_opaqueElements.setBit(i);
- }
- // QSGRenderNodes are always treated as non-opaque
- }
- }
-
- // Build pipeline state and draw calls.
- renderElements();
-
- m_dirtyTransformNodes.clear();
- m_dirtyOpacityNodes.clear();
- m_dirtyOpaqueElements = false;
- m_nodeDirtyMap.clear();
-
- // Finalize buffers and execute commands.
- if (!m_layerRenderer)
- m_engine->endFrame();
- else
- m_engine->endLayer();
-}
-
-void QSGD3D12Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
-{
- // note that with DirtyNodeRemoved the window and all the graphics engine may already be gone
-
- if (Q_UNLIKELY(debug_change())) {
- QDebug debug = qDebug();
- debug << "dirty:";
- if (state & QSGNode::DirtyGeometry)
- debug << "Geometry";
- if (state & QSGNode::DirtyMaterial)
- debug << "Material";
- if (state & QSGNode::DirtyMatrix)
- debug << "Matrix";
- if (state & QSGNode::DirtyNodeAdded)
- debug << "Added";
- if (state & QSGNode::DirtyNodeRemoved)
- debug << "Removed";
- if (state & QSGNode::DirtyOpacity)
- debug << "Opacity";
- if (state & QSGNode::DirtySubtreeBlocked)
- debug << "SubtreeBlocked";
- if (state & QSGNode::DirtyForceUpdate)
- debug << "ForceUpdate";
-
- // when removed, some parts of the node could already have been destroyed
- // so don't debug it out.
- if (state & QSGNode::DirtyNodeRemoved)
- debug << (void *) node << node->type();
- else
- debug << node;
- }
-
- if (state & (QSGNode::DirtyNodeAdded
- | QSGNode::DirtyNodeRemoved
- | QSGNode::DirtySubtreeBlocked
- | QSGNode::DirtyGeometry
- | QSGNode::DirtyForceUpdate))
- m_rebuild = true;
-
- if (state & QSGNode::DirtyMatrix)
- m_dirtyTransformNodes << node;
-
- if (state & QSGNode::DirtyOpacity)
- m_dirtyOpacityNodes << node;
-
- if (state & QSGNode::DirtyMaterial)
- m_dirtyOpaqueElements = true;
-
- QSGRenderer::nodeChanged(node, state);
-}
-
-void QSGD3D12Renderer::renderElements()
-{
- m_engine->queueSetRenderTarget(m_renderTarget);
- m_engine->queueViewport(viewportRect());
- m_engine->queueClearRenderTarget(clearColor());
- m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearDepth | QSGD3D12Engine::ClearStencil);
-
- m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendNone;
- m_pipelineState.depthEnable = m_freshPipelineState.depthEnable = true;
- m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = true;
-
- // First do opaque...
- // The algorithm is quite simple. We traverse the list back-to-front, and
- // for every item we start a second traversal and draw all elements which
- // have identical material. Then we clear the bit for this in the rendered
- // list so we don't draw it again when we come to that index.
- QBitArray rendered = m_opaqueElements;
- for (int i = m_renderList.size() - 1; i >= 0; --i) {
- if (rendered.testBit(i)) {
- renderElement(i);
- for (int j = i - 1; j >= 0; --j) {
- if (rendered.testBit(j)) {
- const QSGGeometryNode *gni = static_cast<QSGGeometryNode *>(m_renderList.at(i).node);
- const QSGGeometryNode *gnj = static_cast<QSGGeometryNode *>(m_renderList.at(j).node);
- if (gni->clipList() == gnj->clipList()
- && gni->inheritedOpacity() == gnj->inheritedOpacity()
- && gni->geometry()->drawingMode() == gnj->geometry()->drawingMode()
- && gni->geometry()->attributes() == gnj->geometry()->attributes()) {
- const QSGMaterial *ami = gni->activeMaterial();
- const QSGMaterial *amj = gnj->activeMaterial();
- if (ami->type() == amj->type()
- && ami->flags() == amj->flags()
- && ami->compare(amj) == 0) {
- renderElement(j);
- rendered.clearBit(j);
- }
- }
- }
- }
- }
- }
-
- m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendPremul;
- m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = false;
-
- // ...then the alpha ones
- for (int i = 0; i < m_renderList.size(); ++i) {
- if ((m_renderList.at(i).node->type() == QSGNode::GeometryNodeType && !m_opaqueElements.testBit(i))
- || m_renderList.at(i).node->type() == QSGNode::RenderNodeType)
- renderElement(i);
- }
-}
-
-struct RenderNodeState : public QSGRenderNode::RenderState
-{
- const QMatrix4x4 *projectionMatrix() const override { return m_projectionMatrix; }
- QRect scissorRect() const override { return m_scissorRect; }
- bool scissorEnabled() const override { return m_scissorEnabled; }
- int stencilValue() const override { return m_stencilValue; }
- bool stencilEnabled() const override { return m_stencilEnabled; }
- const QRegion *clipRegion() const override { return nullptr; }
-
- const QMatrix4x4 *m_projectionMatrix;
- QRect m_scissorRect;
- bool m_scissorEnabled;
- int m_stencilValue;
- bool m_stencilEnabled;
-};
-
-void QSGD3D12Renderer::renderElement(int elementIndex)
-{
- Element &e = m_renderList.at(elementIndex);
- Q_ASSERT(e.node->type() == QSGNode::GeometryNodeType || e.node->type() == QSGNode::RenderNodeType);
-
- if (e.node->type() == QSGNode::RenderNodeType) {
- renderRenderNode(static_cast<QSGRenderNode *>(e.node), elementIndex);
- return;
- }
-
- if (e.vboOffset < 0)
- return;
-
- Q_ASSERT(e.cboOffset >= 0);
-
- const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node);
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "renderElement:" << elementIndex << gn << e.vboOffset << e.iboOffset << gn->inheritedOpacity() << gn->clipList();
-
- if (gn->inheritedOpacity() < 0.001f) // pretty much invisible, don't draw it
- return;
-
- // Update the QSGRenderer members which the materials will access.
- m_current_projection_matrix = projectionMatrix();
- const float scale = 1.0 / m_renderList.size();
- m_current_projection_matrix(2, 2) = scale;
- m_current_projection_matrix(2, 3) = 1.0f - (elementIndex + 1) * scale;
- m_current_model_view_matrix = gn->matrix() ? *gn->matrix() : QMatrix4x4();
- m_current_determinant = m_current_model_view_matrix.determinant();
- m_current_opacity = gn->inheritedOpacity();
-
- const QSGGeometry *g = gn->geometry();
- QSGD3D12Material *m = static_cast<QSGD3D12Material *>(gn->activeMaterial());
-
- if (m->type() != m_lastMaterialType) {
- m_pipelineState = m_freshPipelineState;
- m->preparePipeline(&m_pipelineState);
- }
-
- QSGD3D12MaterialRenderState::DirtyStates dirtyState = m_nodeDirtyMap.value(e.node);
-
- // After a rebuild everything in the cbuffer has to be updated.
- if (!e.cboPrepared) {
- e.cboPrepared = true;
- dirtyState = QSGD3D12MaterialRenderState::DirtyAll;
- }
-
- // DirtyMatrix does not include projection matrix changes that can arise
- // due to changing the render target's size (and there is no rebuild).
- // Accommodate for this.
- if (m_projectionChangedDueToDeviceSize)
- dirtyState |= QSGD3D12MaterialRenderState::DirtyMatrix;
-
- quint8 *cboPtr = nullptr;
- if (e.cboSize > 0)
- cboPtr = m_cboData.data() + e.cboOffset;
-
- if (Q_UNLIKELY(debug_render()))
- qDebug() << "dirty state for" << e.node << "is" << dirtyState;
-
- QSGD3D12Material::ExtraState extraState;
- QSGD3D12Material::UpdateResults updRes = m->updatePipeline(state(dirtyState),
- &m_pipelineState,
- &extraState,
- cboPtr);
-
- if (updRes.testFlag(QSGD3D12Material::UpdatedConstantBuffer))
- m_engine->markBufferDirty(m_constantBuf, e.cboOffset, e.cboSize);
-
- if (updRes.testFlag(QSGD3D12Material::UpdatedBlendFactor))
- m_engine->queueSetBlendFactor(extraState.blendFactor);
-
- setInputLayout(g, &m_pipelineState);
-
- m_lastMaterialType = m->type();
-
- setupClipping(gn->clipList(), elementIndex);
-
- // ### Lines and points with sizes other than 1 have to be implemented in some other way. Just ignore for now.
- if (g->drawingMode() == QSGGeometry::DrawLineStrip || g->drawingMode() == QSGGeometry::DrawLines) {
- if (g->lineWidth() != 1.0f)
- qWarning("QSGD3D12Renderer: Line widths other than 1 are not supported by this renderer");
- } else if (g->drawingMode() == QSGGeometry::DrawPoints) {
- if (g->lineWidth() != 1.0f)
- qWarning("QSGD3D12Renderer: Point sprites are not supported by this renderer");
- }
-
- m_engine->finalizePipeline(m_pipelineState);
-
- queueDrawCall(g, e);
-}
-
-void QSGD3D12Renderer::setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->inputElementCount = g->attributeCount();
- const QSGGeometry::Attribute *attrs = g->attributes();
- quint32 offset = 0;
- for (int i = 0; i < g->attributeCount(); ++i) {
- QSGD3D12InputElement &ie(pipelineState->inputElements[i]);
- static const char *semanticNames[] = { "UNKNOWN", "POSITION", "COLOR", "TEXCOORD", "TEXCOORD", "TEXCOORD" };
- static const int semanticIndices[] = { 0, 0, 0, 0, 1, 2 };
- const int semantic = attrs[i].attributeType;
- Q_ASSERT(semantic >= 1 && semantic < _countof(semanticNames));
- const int tupleSize = attrs[i].tupleSize;
- ie.semanticName = semanticNames[semantic];
- ie.semanticIndex = semanticIndices[semantic];
- ie.offset = offset;
- int bytesPerTuple = 0;
- ie.format = QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type(attrs[i].type), tupleSize, &bytesPerTuple);
- if (ie.format == FmtUnknown)
- qFatal("QSGD3D12Renderer: unsupported tuple size for attribute type 0x%x", attrs[i].type);
- offset += bytesPerTuple;
- // There is one buffer with interleaved data so the slot is always 0.
- ie.slot = 0;
- }
-}
-
-void QSGD3D12Renderer::queueDrawCall(const QSGGeometry *g, const QSGD3D12Renderer::Element &e)
-{
- QSGD3D12Engine::DrawParams dp;
- dp.mode = QSGGeometry::DrawingMode(g->drawingMode());
- dp.vertexBuf = m_vertexBuf;
- dp.constantBuf = m_constantBuf;
- dp.vboOffset = e.vboOffset;
- dp.vboSize = g->vertexCount() * g->sizeOfVertex();
- dp.vboStride = g->sizeOfVertex();
- dp.cboOffset = e.cboOffset;
-
- if (e.iboOffset >= 0) {
- const QSGGeometry::Type indexType = QSGGeometry::Type(g->indexType());
- const QSGD3D12Format indexFormat = QSGD3D12Engine::toDXGIFormat(indexType);
- if (indexFormat == FmtUnknown)
- qFatal("QSGD3D12Renderer: unsupported index type 0x%x", indexType);
- dp.count = g->indexCount();
- dp.indexBuf = m_indexBuf;
- dp.startIndexIndex = e.iboOffset / e.iboStride;
- dp.indexFormat = indexFormat;
- } else {
- dp.count = g->vertexCount();
- }
-
- m_engine->queueDraw(dp);
-}
-
-void QSGD3D12Renderer::setupClipping(const QSGClipNode *clip, int elementIndex)
-{
- const QRect devRect = deviceRect();
- QRect scissorRect;
- int clipTypes = 0;
- quint32 stencilValue = 0;
-
- while (clip) {
- QMatrix4x4 m = projectionMatrix();
- if (clip->matrix())
- m *= *clip->matrix();
-
-#ifndef I_LIKE_STENCIL
- const bool isRectangleWithNoPerspective = clip->isRectangular()
- && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1));
- const bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0));
- const bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1));
-
- if (isRectangleWithNoPerspective && (noRotate || isRotate90)) {
- QRectF bbox = clip->clipRect();
- float invW = 1.0f / m(3, 3);
- float fx1, fy1, fx2, fy2;
- if (noRotate) {
- fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW;
- fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW;
- fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW;
- fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW;
- } else {
- Q_ASSERT(isRotate90);
- fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW;
- fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW;
- fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW;
- fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW;
- }
-
- if (fx1 > fx2)
- qSwap(fx1, fx2);
- if (fy1 > fy2)
- qSwap(fy1, fy2);
-
- int ix1 = qRound((fx1 + 1) * devRect.width() * 0.5f);
- int iy1 = qRound((fy1 + 1) * devRect.height() * 0.5f);
- int ix2 = qRound((fx2 + 1) * devRect.width() * 0.5f);
- int iy2 = qRound((fy2 + 1) * devRect.height() * 0.5f);
-
- if (!(clipTypes & ClipScissor)) {
- scissorRect = QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1);
- clipTypes |= ClipScissor;
- } else {
- scissorRect &= QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1);
- }
- } else
-#endif
- {
- clipTypes |= ClipStencil;
- renderStencilClip(clip, elementIndex, m, stencilValue);
- }
-
- clip = clip->clipList();
- }
-
- setScissor((clipTypes & ClipScissor) ? scissorRect : viewportRect());
-
- if (clipTypes & ClipStencil) {
- m_pipelineState.stencilEnable = true;
- m_engine->queueSetStencilRef(stencilValue);
- m_currentStencilValue = stencilValue;
- } else {
- m_pipelineState.stencilEnable = false;
- m_currentStencilValue = 0;
- }
-
- m_currentClipTypes = clipTypes;
-}
-
-void QSGD3D12Renderer::setScissor(const QRect &r)
-{
- if (m_activeScissorRect == r)
- return;
-
- m_activeScissorRect = r;
- m_engine->queueScissor(r);
-}
-
-void QSGD3D12Renderer::renderStencilClip(const QSGClipNode *clip, int elementIndex,
- const QMatrix4x4 &m, quint32 &stencilValue)
-{
- QSGD3D12PipelineState sps;
- sps.shaders.vs = g_VS_StencilClip;
- sps.shaders.vsSize = sizeof(g_VS_StencilClip);
- sps.shaders.ps = g_PS_StencilClip;
- sps.shaders.psSize = sizeof(g_PS_StencilClip);
-
- m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearStencil);
- sps.stencilEnable = true;
- sps.colorWrite = false;
- sps.depthWrite = false;
-
- sps.stencilFunc = QSGD3D12PipelineState::CompareEqual;
- sps.stencilFailOp = QSGD3D12PipelineState::StencilKeep;
- sps.stencilDepthFailOp = QSGD3D12PipelineState::StencilKeep;
- sps.stencilPassOp = QSGD3D12PipelineState::StencilIncr;
-
- m_engine->queueSetStencilRef(stencilValue);
-
- int clipIndex = elementIndex;
- while (m_renderList.at(--clipIndex).node != clip) {
- Q_ASSERT(clipIndex >= 0);
- }
- const Element &ce = m_renderList.at(clipIndex);
- Q_ASSERT(ce.node == clip);
-
- const QSGGeometry *g = clip->geometry();
- Q_ASSERT(g->attributeCount() == 1);
- Q_ASSERT(g->attributes()[0].tupleSize == 2);
- Q_ASSERT(g->attributes()[0].type == QSGGeometry::FloatType);
-
- setInputLayout(g, &sps);
- m_engine->finalizePipeline(sps);
-
- Q_ASSERT(ce.cboSize > 0);
- quint8 *p = m_cboData.data() + ce.cboOffset;
- memcpy(p, m.constData(), 16 * sizeof(float));
- m_engine->markBufferDirty(m_constantBuf, ce.cboOffset, ce.cboSize);
-
- queueDrawCall(g, ce);
-
- ++stencilValue;
-}
-
-void QSGD3D12Renderer::renderRenderNode(QSGRenderNode *node, int elementIndex)
-{
- QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(node);
- RenderNodeState state;
-
- setupClipping(rd->m_clip_list, elementIndex);
-
- QMatrix4x4 pm = projectionMatrix();
- state.m_projectionMatrix = &pm;
- state.m_scissorEnabled = m_currentClipTypes & ClipScissor;
- state.m_stencilEnabled = m_currentClipTypes & ClipStencil;
- state.m_scissorRect = m_activeScissorRect;
- state.m_stencilValue = m_currentStencilValue;
-
- // ### rendernodes do not have the QSGBasicGeometryNode infrastructure
- // for storing combined matrices, opacity and such, but perhaps they should.
- QSGNode *xform = node->parent();
- QSGNode *root = rootNode();
- QMatrix4x4 modelview;
- while (xform != root) {
- if (xform->type() == QSGNode::TransformNodeType) {
- modelview *= static_cast<QSGTransformNode *>(xform)->combinedMatrix();
- break;
- }
- xform = xform->parent();
- }
- rd->m_matrix = &modelview;
-
- QSGNode *opacity = node->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();
- }
-
- node->render(&state);
-
- m_engine->invalidateCachedFrameState();
- // For simplicity, reset viewport, scissor, blend factor, stencil ref when
- // any of them got changed. This will likely be rare so skip these otherwise.
- // Render target, pipeline state, draw call related stuff will be reset always.
- const bool restoreMinimal = node->changedStates() == 0;
- m_engine->restoreFrameState(restoreMinimal);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h
deleted file mode 100644
index df30a49f0d..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERER_P_H
-#define QSGD3D12RENDERER_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 <private/qsgrenderer_p.h>
-#include <QtGui/private/qdatabuffer_p.h>
-#include <QtCore/qbitarray.h>
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12material_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGRenderNode;
-
-class QSGD3D12Renderer : public QSGRenderer
-{
-public:
- QSGD3D12Renderer(QSGRenderContext *context);
- ~QSGD3D12Renderer();
-
- void renderScene(GLuint fboId) override;
- void render() override;
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
-
- void turnToLayerRenderer() { m_layerRenderer = true; }
-
-private:
- void updateMatrices(QSGNode *node, QSGTransformNode *xform);
- void updateOpacities(QSGNode *node, float inheritedOpacity);
- void buildRenderList(QSGNode *node, QSGClipNode *clip);
- void renderElements();
- void renderElement(int elementIndex);
- void setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState);
- void setupClipping(const QSGClipNode *clip, int elementIndex);
- void setScissor(const QRect &r);
- void renderStencilClip(const QSGClipNode *clip, int elementIndex, const QMatrix4x4 &m, quint32 &stencilValue);
- void renderRenderNode(QSGRenderNode *node, int elementIndex);
-
- struct Element {
- QSGNode *node = nullptr;
- qint32 vboOffset = -1;
- qint32 iboOffset = -1;
- quint32 iboStride = 0;
- qint32 cboOffset = -1;
- quint32 cboSize = 0;
- bool cboPrepared = false;
- };
-
- void queueDrawCall(const QSGGeometry *g, const Element &e);
-
- bool m_layerRenderer = false;
- QSet<QSGNode *> m_dirtyTransformNodes;
- QSet<QSGNode *> m_dirtyOpacityNodes;
- QBitArray m_opaqueElements;
- bool m_rebuild = true;
- bool m_dirtyOpaqueElements = true;
- QDataBuffer<quint8> m_vboData;
- QDataBuffer<quint8> m_iboData;
- QDataBuffer<quint8> m_cboData;
- QDataBuffer<Element> m_renderList;
- uint m_vertexBuf = 0;
- uint m_indexBuf = 0;
- uint m_constantBuf = 0;
- QSGD3D12Engine *m_engine = nullptr;
-
- QSGMaterialType *m_lastMaterialType = nullptr;
- QSGD3D12PipelineState m_pipelineState;
- QSGD3D12PipelineState m_freshPipelineState;
-
- typedef QHash<QSGNode *, QSGD3D12MaterialRenderState::DirtyStates> NodeDirtyMap;
- NodeDirtyMap m_nodeDirtyMap;
-
- QRect m_activeScissorRect;
- QRect m_lastDeviceRect;
- bool m_projectionChangedDueToDeviceSize;
-
- uint m_renderTarget = 0;
- quint32 m_currentStencilValue;
- enum ClipType {
- ClipScissor = 0x1,
- ClipStencil = 0x2
- };
- int m_currentClipTypes;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERER_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
deleted file mode 100644
index 79ffee7689..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12renderloop_p.h"
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12context_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12shadereffectnode_p.h"
-#include <private/qquickwindow_p.h>
-#include <private/qquickprofiler_p.h>
-#include <private/qquickanimatorcontroller_p.h>
-#include <QElapsedTimer>
-#include <QGuiApplication>
-#include <QScreen>
-
-#include <qtquick_tracepoints_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(loop)
-DECLARE_DEBUG_VAR(time)
-
-
-// This render loop operates on the gui (main) thread.
-// Conceptually it matches the OpenGL 'windows' render loop.
-
-static inline int qsgrl_animation_interval()
-{
- const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0;
- return refreshRate < 1 ? 16 : int(1000 / refreshRate);
-}
-
-QSGD3D12RenderLoop::QSGD3D12RenderLoop()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("new d3d12 render loop");
-
- sg = new QSGD3D12Context;
-
- m_anims = sg->createAnimationDriver(this);
- connect(m_anims, &QAnimationDriver::started, this, &QSGD3D12RenderLoop::onAnimationStarted);
- connect(m_anims, &QAnimationDriver::stopped, this, &QSGD3D12RenderLoop::onAnimationStopped);
- m_anims->install();
-
- m_vsyncDelta = qsgrl_animation_interval();
-}
-
-QSGD3D12RenderLoop::~QSGD3D12RenderLoop()
-{
- delete sg;
-}
-
-void QSGD3D12RenderLoop::show(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "show" << window;
-}
-
-void QSGD3D12RenderLoop::hide(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "hide" << window;
-}
-
-void QSGD3D12RenderLoop::resize(QQuickWindow *window)
-{
- if (!m_windows.contains(window) || window->size().isEmpty())
- return;
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "resize" << window;
-
- const WindowData &data(m_windows[window]);
-
- if (!data.exposed)
- return;
-
- if (data.engine)
- data.engine->setWindowSize(window->size(), window->effectiveDevicePixelRatio());
-}
-
-void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "window destroyed" << window;
-
- if (!m_windows.contains(window))
- return;
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->fireAboutToStop();
-
- WindowData &data(m_windows[window]);
- QSGD3D12Engine *engine = data.engine;
- QSGD3D12RenderContext *rc = data.rc;
- m_windows.remove(window);
-
- // QSGNode destruction may release graphics resources in use so wait first.
- engine->waitGPU();
-
- // Bye bye nodes...
- wd->cleanupNodesOnShutdown();
-
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
-
- rc->invalidate();
-
- delete rc;
- delete engine;
-
- wd->animationController.reset();
-}
-
-void QSGD3D12RenderLoop::exposeWindow(QQuickWindow *window)
-{
- WindowData data;
- data.exposed = true;
- data.engine = new QSGD3D12Engine;
- data.rc = static_cast<QSGD3D12RenderContext *>(QQuickWindowPrivate::get(window)->context);
- data.rc->setEngine(data.engine);
- m_windows[window] = data;
-
- const int samples = window->format().samples();
- const bool alpha = window->format().alphaBufferSize() > 0;
- const qreal dpr = window->effectiveDevicePixelRatio();
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "initializing D3D12 engine" << window << window->size() << dpr << samples << alpha;
-
- data.engine->attachToWindow(window->winId(), window->size(), dpr, samples, alpha);
-}
-
-void QSGD3D12RenderLoop::obscureWindow(QQuickWindow *window)
-{
- m_windows[window].exposed = false;
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->fireAboutToStop();
-}
-
-void QSGD3D12RenderLoop::exposureChanged(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "exposure changed" << window << window->isExposed();
-
- if (window->isExposed()) {
- if (!m_windows.contains(window))
- exposeWindow(window);
-
- // Stop non-visual animation timer as we now have a window rendering.
- if (m_animationTimer && somethingVisible()) {
- killTimer(m_animationTimer);
- m_animationTimer = 0;
- }
- // If we have a pending timer and we get an expose, we need to stop it.
- // Otherwise we get two frames and two animation ticks in the same time interval.
- if (m_updateTimer) {
- killTimer(m_updateTimer);
- m_updateTimer = 0;
- }
-
- WindowData &data(m_windows[window]);
- data.exposed = true;
- data.updatePending = true;
-
- render();
-
- } else if (m_windows.contains(window)) {
- obscureWindow(window);
-
- // Potentially start the non-visual animation timer if nobody is rendering.
- if (m_anims->isRunning() && !somethingVisible() && !m_animationTimer)
- m_animationTimer = startTimer(m_vsyncDelta);
- }
-}
-
-QImage QSGD3D12RenderLoop::grab(QQuickWindow *window)
-{
- const bool tempExpose = !m_windows.contains(window);
- if (tempExpose)
- exposeWindow(window);
-
- m_windows[window].grabOnly = true;
-
- renderWindow(window);
-
- QImage grabbed = m_grabContent;
- m_grabContent = QImage();
-
- if (tempExpose)
- obscureWindow(window);
-
- return grabbed;
-}
-
-bool QSGD3D12RenderLoop::somethingVisible() const
-{
- for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it) {
- if (it.key()->isVisible() && it.key()->isExposed())
- return true;
- }
- return false;
-}
-
-void QSGD3D12RenderLoop::maybePostUpdateTimer()
-{
- if (!m_updateTimer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("starting update timer");
- m_updateTimer = startTimer(m_vsyncDelta / 3);
- }
-}
-
-void QSGD3D12RenderLoop::update(QQuickWindow *window)
-{
- maybeUpdate(window);
-}
-
-void QSGD3D12RenderLoop::maybeUpdate(QQuickWindow *window)
-{
- if (!m_windows.contains(window) || !somethingVisible())
- return;
-
- m_windows[window].updatePending = true;
- maybePostUpdateTimer();
-}
-
-QAnimationDriver *QSGD3D12RenderLoop::animationDriver() const
-{
- return m_anims;
-}
-
-QSGContext *QSGD3D12RenderLoop::sceneGraphContext() const
-{
- return sg;
-}
-
-QSGRenderContext *QSGD3D12RenderLoop::createRenderContext(QSGContext *) const
-{
- // The rendercontext and engine are per-window, like with the threaded
- // loop, but unlike the non-threaded OpenGL variants.
- return sg->createRenderContext();
-}
-
-void QSGD3D12RenderLoop::releaseResources(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "releaseResources" << window;
-}
-
-void QSGD3D12RenderLoop::postJob(QQuickWindow *window, QRunnable *job)
-{
- Q_UNUSED(window);
- Q_ASSERT(job);
- Q_ASSERT(window);
- job->run();
- delete job;
-}
-
-QSurface::SurfaceType QSGD3D12RenderLoop::windowSurfaceType() const
-{
- return QSurface::OpenGLSurface;
-}
-
-bool QSGD3D12RenderLoop::interleaveIncubation() const
-{
- return m_anims->isRunning() && somethingVisible();
-}
-
-void QSGD3D12RenderLoop::onAnimationStarted()
-{
- if (!somethingVisible()) {
- if (!m_animationTimer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("starting non-visual animation timer");
- m_animationTimer = startTimer(m_vsyncDelta);
- }
- } else {
- maybePostUpdateTimer();
- }
-}
-
-void QSGD3D12RenderLoop::onAnimationStopped()
-{
- if (m_animationTimer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("stopping non-visual animation timer");
- killTimer(m_animationTimer);
- m_animationTimer = 0;
- }
-}
-
-bool QSGD3D12RenderLoop::event(QEvent *event)
-{
- switch (event->type()) {
- case QEvent::Timer:
- {
- QTimerEvent *te = static_cast<QTimerEvent *>(event);
- if (te->timerId() == m_animationTimer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("animation tick while no windows exposed");
- m_anims->advance();
- } else if (te->timerId() == m_updateTimer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("update timeout - rendering");
- killTimer(m_updateTimer);
- m_updateTimer = 0;
- render();
- }
- return true;
- }
- default:
- break;
- }
-
- return QObject::event(event);
-}
-
-void QSGD3D12RenderLoop::render()
-{
- bool rendered = false;
- for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) {
- if (it->updatePending) {
- it->updatePending = false;
- renderWindow(it.key());
- rendered = true;
- }
- }
-
- if (!rendered) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("render - no changes, sleep");
- QThread::msleep(m_vsyncDelta);
- }
-
- if (m_anims->isRunning()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("render - advancing animations");
-
- m_anims->advance();
-
- // It is not given that animations triggered another maybeUpdate()
- // and thus another render pass, so to keep things running,
- // make sure there is another frame pending.
- maybePostUpdateTimer();
-
- emit timeToIncubate();
- }
-}
-
-void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "renderWindow" << window;
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- if (!m_windows.contains(window) || !window->geometry().isValid())
- return;
-
- WindowData &data(m_windows[window]);
- if (!data.exposed) { // not the same as window->isExposed(), when grabbing invisible windows for instance
- if (Q_UNLIKELY(debug_loop()))
- qDebug("renderWindow - not exposed, abort");
- return;
- }
-
- Q_TRACE_SCOPE(QSG_renderWindow);
-
- if (!data.grabOnly)
- wd->flushFrameSynchronousEvents();
-
- QElapsedTimer renderTimer;
- qint64 renderTime = 0, syncTime = 0, polishTime = 0;
- const bool profileFrames = debug_time();
- if (profileFrames)
- renderTimer.start();
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
- Q_TRACE(QSG_polishItems_entry);
-
- wd->polishItems();
-
- if (profileFrames)
- polishTime = renderTimer.nsecsElapsed();
- Q_TRACE(QSG_polishItems_exit);
- Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
- QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphPolishPolish);
- Q_TRACE(QSG_sync_entry);
-
- emit window->afterAnimating();
-
- // The native window may change in some (quite artificial) cases, e.g. due
- // to a hide - destroy - show on the QWindow.
- bool needsWindow = !data.engine->window();
- if (data.engine->window() && data.engine->window() != window->winId()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("sync - native window handle changes for active engine");
- data.engine->waitGPU();
- wd->cleanupNodesOnShutdown();
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
- data.rc->invalidate();
- data.engine->releaseResources();
- needsWindow = true;
- }
- if (needsWindow) {
- // Must only ever get here when there is no window or releaseResources() has been called.
- const int samples = window->format().samples();
- const bool alpha = window->format().alphaBufferSize() > 0;
- const qreal dpr = window->effectiveDevicePixelRatio();
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "sync - reinitializing D3D12 engine" << window << window->size() << dpr << samples << alpha;
- data.engine->attachToWindow(window->winId(), window->size(), dpr, samples, alpha);
- }
-
- // Recover from device loss.
- if (!data.engine->hasResources()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("sync - device was lost, resetting scenegraph");
- wd->cleanupNodesOnShutdown();
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
- data.rc->invalidate();
- }
-
- data.rc->initialize(nullptr);
-
- wd->syncSceneGraph();
- data.rc->endSync();
-
- if (profileFrames)
- syncTime = renderTimer.nsecsElapsed();
- Q_TRACE(QSG_sync_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSync);
- Q_TRACE(QSG_render_entry);
-
- wd->renderSceneGraph(window->size());
-
- if (profileFrames)
- renderTime = renderTimer.nsecsElapsed();
- Q_TRACE(QSG_render_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopRender);
- Q_TRACE(QSG_swap_entry);
-
- if (!data.grabOnly) {
- // The engine is able to have multiple frames in flight. This in effect is
- // similar to BufferQueueingOpenGL. Provide an env var to force the
- // traditional blocking swap behavior, just in case.
- static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0;
-
- if (window->isVisible()) {
- data.engine->present();
- if (blockOnEachFrame)
- data.engine->waitGPU();
- // The concept of "frame swaps" is quite misleading by default, when
- // blockOnEachFrame is not used, but emit it for compatibility.
- wd->fireFrameSwapped();
- } else {
- if (blockOnEachFrame)
- data.engine->waitGPU();
- }
- } else {
- m_grabContent = data.engine->executeAndWaitReadbackRenderTarget();
- data.grabOnly = false;
- }
-
- qint64 swapTime = 0;
- if (profileFrames)
- swapTime = renderTimer.nsecsElapsed();
- Q_TRACE(QSG_swap_exit);
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSwap);
-
- if (Q_UNLIKELY(debug_time())) {
- static QTime lastFrameTime = QTime::currentTime();
- qDebug("Frame rendered with 'd3d12' renderloop in %dms, polish=%d, sync=%d, render=%d, swap=%d, frameDelta=%d",
- int(swapTime / 1000000),
- int(polishTime / 1000000),
- int((syncTime - polishTime) / 1000000),
- int((renderTime - syncTime) / 1000000),
- int((swapTime - renderTime) / 10000000),
- int(lastFrameTime.msecsTo(QTime::currentTime())));
- lastFrameTime = QTime::currentTime();
- }
-
- // Simulate device loss if requested.
- static int devLossTest = qEnvironmentVariableIntValue("QT_D3D_TEST_DEVICE_LOSS");
- if (devLossTest > 0) {
- static QElapsedTimer kt;
- static bool timerRunning = false;
- if (!timerRunning) {
- kt.start();
- timerRunning = true;
- } else if (kt.elapsed() > 5000) {
- --devLossTest;
- kt.restart();
- data.engine->simulateDeviceLoss();
- }
- }
-}
-
-int QSGD3D12RenderLoop::flags() const
-{
- return SupportsGrabWithoutExpose;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h
deleted file mode 100644
index c0333ffad0..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12RENDERLOOP_P_H
-#define QSGD3D12RENDERLOOP_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 <private/qsgrenderloop_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-class QSGD3D12Context;
-class QSGD3D12RenderContext;
-
-class QSGD3D12RenderLoop : public QSGRenderLoop
-{
- Q_OBJECT
-
-public:
- QSGD3D12RenderLoop();
- ~QSGD3D12RenderLoop();
-
- void show(QQuickWindow *window) override;
- void hide(QQuickWindow *window) override;
- void resize(QQuickWindow *window) override;
-
- void windowDestroyed(QQuickWindow *window) override;
-
- void exposureChanged(QQuickWindow *window) override;
-
- QImage grab(QQuickWindow *window) override;
-
- void update(QQuickWindow *window) override;
- void maybeUpdate(QQuickWindow *window) override;
-
- QAnimationDriver *animationDriver() const override;
-
- QSGContext *sceneGraphContext() const override;
- QSGRenderContext *createRenderContext(QSGContext *) const override;
-
- void releaseResources(QQuickWindow *window) override;
- void postJob(QQuickWindow *window, QRunnable *job) override;
-
- QSurface::SurfaceType windowSurfaceType() const override;
- bool interleaveIncubation() const override;
- int flags() const override;
-
- bool event(QEvent *event) override;
-
-public Q_SLOTS:
- void onAnimationStarted();
- void onAnimationStopped();
-
-private:
- void exposeWindow(QQuickWindow *window);
- void obscureWindow(QQuickWindow *window);
- void renderWindow(QQuickWindow *window);
- void render();
- void maybePostUpdateTimer();
- bool somethingVisible() const;
-
- QSGD3D12Context *sg;
- QAnimationDriver *m_anims;
- int m_vsyncDelta;
- int m_updateTimer = 0;
- int m_animationTimer = 0;
-
- struct WindowData {
- QSGD3D12RenderContext *rc = nullptr;
- QSGD3D12Engine *engine = nullptr;
- bool updatePending = false;
- bool grabOnly = false;
- bool exposed = false;
- };
-
- QHash<QQuickWindow *, WindowData> m_windows;
-
- QImage m_grabContent;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12RENDERLOOP_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
deleted file mode 100644
index 1f574a9802..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
+++ /dev/null
@@ -1,995 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12shadereffectnode_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12texture_p.h"
-#include "qsgd3d12engine_p.h"
-#include <QtCore/qthreadpool.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qfileselector.h>
-#include <QtQml/qqmlfile.h>
-#include <qsgtextureprovider.h>
-
-#include <d3d12shader.h>
-#include <d3dcompiler.h>
-
-#include "vs_shadereffectdefault.hlslh"
-#include "ps_shadereffectdefault.hlslh"
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(shader)
-
-void QSGD3D12ShaderLinker::reset(const QByteArray &vertBlob, const QByteArray &fragBlob)
-{
- Q_ASSERT(!vertBlob.isEmpty() && !fragBlob.isEmpty());
- vs = vertBlob;
- fs = fragBlob;
-
- error = false;
-
- constantBufferSize = 0;
- constants.clear();
- samplers.clear();
- textures.clear();
- textureNameMap.clear();
-}
-
-void QSGD3D12ShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices)
-{
- Q_ASSERT(shader.shaderInfo.variables.count() == shader.varData.count());
- if (!dirtyIndices) {
- constantBufferSize = qMax(constantBufferSize, shader.shaderInfo.constantDataSize);
- for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) {
- const auto &var(shader.shaderInfo.variables.at(i));
- if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Constant) {
- const auto &vd(shader.varData.at(i));
- Constant c;
- c.size = var.size;
- c.specialType = vd.specialType;
- if (c.specialType != QSGShaderEffectNode::VariableData::SubRect) {
- c.value = vd.value;
- } else {
- Q_ASSERT(var.name.startsWith(QByteArrayLiteral("qt_SubRect_")));
- c.value = var.name.mid(11);
- }
- constants[var.offset] = c;
- }
- }
- } else {
- for (int idx : *dirtyIndices)
- constants[shader.shaderInfo.variables.at(idx).offset].value = shader.varData.at(idx).value;
- }
-}
-
-void QSGD3D12ShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &shader)
-{
- for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) {
- const auto &var(shader.shaderInfo.variables.at(i));
- if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) {
- Q_ASSERT(shader.varData.at(i).specialType == QSGShaderEffectNode::VariableData::Unused);
- samplers.insert(var.bindPoint);
- }
- }
-}
-
-void QSGD3D12ShaderLinker::feedTextures(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices)
-{
- if (!dirtyIndices) {
- for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) {
- const auto &var(shader.shaderInfo.variables.at(i));
- const auto &vd(shader.varData.at(i));
- if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Texture) {
- Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source);
- textures.insert(var.bindPoint, vd.value);
- textureNameMap.insert(var.name, var.bindPoint);
- }
- }
- } else {
- for (int idx : *dirtyIndices) {
- const auto &var(shader.shaderInfo.variables.at(idx));
- const auto &vd(shader.varData.at(idx));
- textures.insert(var.bindPoint, vd.value);
- textureNameMap.insert(var.name, var.bindPoint);
- }
- }
-}
-
-void QSGD3D12ShaderLinker::linkTextureSubRects()
-{
- // feedConstants stores <name> in Constant::value for subrect entries. Now
- // that both constants and textures are known, replace the name with the
- // texture bind point.
- for (Constant &c : constants) {
- if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
- if (c.value.type() == QVariant::ByteArray) {
- const QByteArray name = c.value.toByteArray();
- if (!textureNameMap.contains(name))
- qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", qPrintable(name));
- c.value = textureNameMap[name];
- }
- }
- }
-}
-
-void QSGD3D12ShaderLinker::dump()
-{
- if (error) {
- qDebug() << "Failed to generate program data";
- return;
- }
- qDebug() << "Combined shader data" << vs.size() << fs.size() << "cbuffer size" << constantBufferSize;
- qDebug() << " - constants" << constants;
- qDebug() << " - samplers" << samplers;
- qDebug() << " - textures" << textures;
-}
-
-QDebug operator<<(QDebug debug, const QSGD3D12ShaderLinker::Constant &c)
-{
- QDebugStateSaver saver(debug);
- debug.space();
- debug << "size" << c.size;
- if (c.specialType != QSGShaderEffectNode::VariableData::None)
- debug << "special" << c.specialType;
- else
- debug << "value" << c.value;
- return debug;
-}
-
-QSGD3D12ShaderEffectMaterial::QSGD3D12ShaderEffectMaterial(QSGD3D12ShaderEffectNode *node)
- : node(node)
-{
- setFlag(Blending | RequiresFullMatrix, true); // may be changed in sync()
-}
-
-QSGD3D12ShaderEffectMaterial::~QSGD3D12ShaderEffectMaterial()
-{
- delete dummy;
-}
-
-struct QSGD3D12ShaderMaterialTypeCache
-{
- QSGMaterialType *get(const QByteArray &vs, const QByteArray &fs);
- void reset() { qDeleteAll(m_types); m_types.clear(); }
-
- struct Key {
- QByteArray blob[2];
- Key() { }
- Key(const QByteArray &vs, const QByteArray &fs) { blob[0] = vs; blob[1] = fs; }
- bool operator==(const Key &other) const {
- return blob[0] == other.blob[0] && blob[1] == other.blob[1];
- }
- };
- QHash<Key, QSGMaterialType *> m_types;
-};
-
-uint qHash(const QSGD3D12ShaderMaterialTypeCache::Key &key, uint seed = 0)
-{
- uint hash = seed;
- for (int i = 0; i < 2; ++i)
- hash = hash * 31337 + qHash(key.blob[i]);
- return hash;
-}
-
-QSGMaterialType *QSGD3D12ShaderMaterialTypeCache::get(const QByteArray &vs, const QByteArray &fs)
-{
- const Key k(vs, fs);
- if (m_types.contains(k))
- return m_types.value(k);
-
- QSGMaterialType *t = new QSGMaterialType;
- m_types.insert(k, t);
- return t;
-}
-
-Q_GLOBAL_STATIC(QSGD3D12ShaderMaterialTypeCache, shaderMaterialTypeCache)
-
-void QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache()
-{
- shaderMaterialTypeCache()->reset();
-}
-
-QSGMaterialType *QSGD3D12ShaderEffectMaterial::type() const
-{
- return mtype;
-}
-
-static bool hasAtlasTexture(const QVector<QSGTextureProvider *> &textureProviders)
-{
- for (int i = 0; i < textureProviders.count(); ++i) {
- QSGTextureProvider *t = textureProviders.at(i);
- if (t && t->texture() && t->texture()->isAtlasTexture())
- return true;
- }
- return false;
-}
-
-int QSGD3D12ShaderEffectMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QSGD3D12ShaderEffectMaterial *o = static_cast<const QSGD3D12ShaderEffectMaterial *>(other);
-
- if (int diff = cullMode - o->cullMode)
- return diff;
-
- if (int diff = textureProviders.count() - o->textureProviders.count())
- return diff;
-
- if (linker.constants != o->linker.constants)
- return 1;
-
- if ((hasAtlasTexture(textureProviders) && !geometryUsesTextureSubRect)
- || (hasAtlasTexture(o->textureProviders) && !o->geometryUsesTextureSubRect))
- return 1;
-
- for (int i = 0; i < textureProviders.count(); ++i) {
- QSGTextureProvider *tp1 = textureProviders.at(i);
- QSGTextureProvider *tp2 = o->textureProviders.at(i);
- if (!tp1 || !tp2)
- return tp1 == tp2 ? 0 : 1;
- QSGTexture *t1 = tp1->texture();
- QSGTexture *t2 = tp2->texture();
- if (!t1 || !t2)
- return t1 == t2 ? 0 : 1;
- if (int diff = t1->textureId() - t2->textureId())
- return diff;
- }
-
- return 0;
-}
-
-int QSGD3D12ShaderEffectMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(linker.constantBufferSize);
-}
-
-void QSGD3D12ShaderEffectMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = reinterpret_cast<const quint8 *>(linker.vs.constData());
- pipelineState->shaders.vsSize = linker.vs.size();
- pipelineState->shaders.ps = reinterpret_cast<const quint8 *>(linker.fs.constData());
- pipelineState->shaders.psSize = linker.fs.size();
-
- pipelineState->shaders.rootSig.textureViewCount = textureProviders.count();
-}
-
-static inline QColor qsg_premultiply_color(const QColor &c)
-{
- return QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF());
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12ShaderEffectMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = 0;
- quint8 *p = constantBuffer;
-
- for (auto it = linker.constants.constBegin(), itEnd = linker.constants.constEnd(); it != itEnd; ++it) {
- quint8 *dst = p + it.key();
- const QSGD3D12ShaderLinker::Constant &c(it.value());
- if (c.specialType == QSGShaderEffectNode::VariableData::Opacity) {
- if (state.isOpacityDirty()) {
- const float f = state.opacity();
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, &f, sizeof(f));
- r |= UpdatedConstantBuffer;
- }
- } else if (c.specialType == QSGShaderEffectNode::VariableData::Matrix) {
- if (state.isMatrixDirty()) {
- const int sz = 16 * sizeof(float);
- Q_ASSERT(sz == c.size);
- memcpy(dst, state.combinedMatrix().constData(), sz);
- r |= UpdatedConstantBuffer;
- }
- } else if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
- // float4
- QRectF subRect(0, 0, 1, 1);
- int srcBindPoint = c.value.toInt(); // filled in by linkTextureSubRects
- if (QSGTexture *t = textureProviders.at(srcBindPoint)->texture())
- subRect = t->normalizedTextureSubRect();
- const float f[4] = { float(subRect.x()), float(subRect.y()),
- float(subRect.width()), float(subRect.height()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- } else if (c.specialType == QSGShaderEffectNode::VariableData::None) {
- r |= UpdatedConstantBuffer;
- switch (c.value.type()) {
- case QMetaType::QColor: {
- const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value));
- const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::Float: {
- const float f = qvariant_cast<float>(c.value);
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, &f, sizeof(f));
- break;
- }
- case QMetaType::Double: {
- const float f = float(qvariant_cast<double>(c.value));
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, &f, sizeof(f));
- break;
- }
- case QMetaType::Int: {
- const int i = c.value.toInt();
- Q_ASSERT(sizeof(i) == c.size);
- memcpy(dst, &i, sizeof(i));
- break;
- }
- case QMetaType::Bool: {
- const bool b = c.value.toBool();
- Q_ASSERT(sizeof(b) == c.size);
- memcpy(dst, &b, sizeof(b));
- break;
- }
- case QMetaType::QTransform: { // float3x3
- const QTransform v = qvariant_cast<QTransform>(c.value);
- const float m[3][3] = {
- { float(v.m11()), float(v.m12()), float(v.m13()) },
- { float(v.m21()), float(v.m22()), float(v.m23()) },
- { float(v.m31()), float(v.m32()), float(v.m33()) }
- };
- Q_ASSERT(sizeof(m) == c.size);
- memcpy(dst, m[0], sizeof(m));
- break;
- }
- case QMetaType::QSize:
- case QMetaType::QSizeF: { // float2
- const QSizeF v = c.value.toSizeF();
- const float f[2] = { float(v.width()), float(v.height()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QPoint:
- case QMetaType::QPointF: { // float2
- const QPointF v = c.value.toPointF();
- const float f[2] = { float(v.x()), float(v.y()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QRect:
- case QMetaType::QRectF: { // float4
- const QRectF v = c.value.toRectF();
- const float f[4] = { float(v.x()), float(v.y()), float(v.width()), float(v.height()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QVector2D: { // float2
- const QVector2D v = qvariant_cast<QVector2D>(c.value);
- const float f[2] = { float(v.x()), float(v.y()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QVector3D: { // float3
- const QVector3D v = qvariant_cast<QVector3D>(c.value);
- const float f[3] = { float(v.x()), float(v.y()), float(v.z()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QVector4D: { // float4
- const QVector4D v = qvariant_cast<QVector4D>(c.value);
- const float f[4] = { float(v.x()), float(v.y()), float(v.z()), float(v.w()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QQuaternion: { // float4
- const QQuaternion v = qvariant_cast<QQuaternion>(c.value);
- const float f[4] = { float(v.x()), float(v.y()), float(v.z()), float(v.scalar()) };
- Q_ASSERT(sizeof(f) == c.size);
- memcpy(dst, f, sizeof(f));
- break;
- }
- case QMetaType::QMatrix4x4: { // float4x4
- const QMatrix4x4 v = qvariant_cast<QMatrix4x4>(c.value);
- const int sz = 16 * sizeof(float);
- Q_ASSERT(sz == c.size);
- memcpy(dst, v.constData(), sz);
- break;
- }
- default:
- break;
- }
- }
- }
-
- for (int i = 0; i < textureProviders.count(); ++i) {
- QSGTextureProvider *tp = textureProviders[i];
- QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[i]);
- if (tp) {
- if (QSGTexture *t = tp->texture()) {
- if (t->isAtlasTexture() && !geometryUsesTextureSubRect) {
- QSGTexture *newTexture = t->removedFromAtlas();
- if (newTexture)
- t = newTexture;
- }
- tv.filter = t->filtering() == QSGTexture::Linear
- ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = t->horizontalWrapMode() == QSGTexture::ClampToEdge
- ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = t->verticalWrapMode() == QSGTexture::ClampToEdge
- ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap;
- t->bind();
- continue;
- }
- }
- if (!dummy) {
- dummy = new QSGD3D12Texture(node->renderContext()->engine());
- QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
- dummy->create(img, QSGRenderContext::CreateTexture_Alpha);
- }
- tv.filter = QSGD3D12TextureView::FilterNearest;
- tv.addressModeHoriz = QSGD3D12TextureView::AddressWrap;
- tv.addressModeVert = QSGD3D12TextureView::AddressWrap;
- dummy->bind();
- }
-
- switch (cullMode) {
- case QSGShaderEffectNode::FrontFaceCulling:
- pipelineState->cullMode = QSGD3D12PipelineState::CullFront;
- break;
- case QSGShaderEffectNode::BackFaceCulling:
- pipelineState->cullMode = QSGD3D12PipelineState::CullBack;
- break;
- default:
- pipelineState->cullMode = QSGD3D12PipelineState::CullNone;
- break;
- }
-
- return r;
-}
-
-void QSGD3D12ShaderEffectMaterial::updateTextureProviders(bool layoutChange)
-{
- if (layoutChange) {
- for (QSGTextureProvider *tp : textureProviders) {
- if (tp) {
- QObject::disconnect(tp, SIGNAL(textureChanged()), node,
- SLOT(handleTextureChange()));
- QObject::disconnect(tp, SIGNAL(destroyed(QObject*)), node,
- SLOT(handleTextureProviderDestroyed(QObject*)));
- }
- }
-
- textureProviders.fill(nullptr, linker.textures.count());
- }
-
- for (auto it = linker.textures.constBegin(), itEnd = linker.textures.constEnd(); it != itEnd; ++it) {
- const int bindPoint = it.key();
- // Now that the linker has merged the textures, we can switch over to a
- // simple vector indexed by the binding point for textureProviders.
- Q_ASSERT(bindPoint >= 0 && bindPoint < textureProviders.count());
- QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(it.value()));
- QSGTextureProvider *newProvider = source && source->isTextureProvider() ? source->textureProvider() : nullptr;
- QSGTextureProvider *&activeProvider(textureProviders[bindPoint]);
- if (newProvider != activeProvider) {
- if (activeProvider) {
- QObject::disconnect(activeProvider, SIGNAL(textureChanged()), node,
- SLOT(handleTextureChange()));
- QObject::disconnect(activeProvider, SIGNAL(destroyed(QObject*)), node,
- SLOT(handleTextureProviderDestroyed(QObject*)));
- }
- if (newProvider) {
- Q_ASSERT_X(newProvider->thread() == QThread::currentThread(),
- "QSGD3D12ShaderEffectMaterial::updateTextureProviders",
- "Texture provider must belong to the rendering thread");
- QObject::connect(newProvider, SIGNAL(textureChanged()), node, SLOT(handleTextureChange()));
- QObject::connect(newProvider, SIGNAL(destroyed(QObject*)), node,
- SLOT(handleTextureProviderDestroyed(QObject*)));
- } else {
- const char *typeName = source ? source->metaObject()->className() : it.value().typeName();
- qWarning("ShaderEffect: Texture t%d is not assigned a valid texture provider (%s).",
- bindPoint, typeName);
- }
- activeProvider = newProvider;
- }
- }
-}
-
-QSGD3D12ShaderEffectNode::QSGD3D12ShaderEffectNode(QSGD3D12RenderContext *rc, QSGD3D12GuiThreadShaderEffectManager *mgr)
- : QSGShaderEffectNode(mgr),
- m_rc(rc),
- m_mgr(mgr),
- m_material(this)
-{
- setFlag(UsePreprocess, true);
- setMaterial(&m_material);
-}
-
-QRectF QSGD3D12ShaderEffectNode::updateNormalizedTextureSubRect(bool supportsAtlasTextures)
-{
- QRectF srcRect(0, 0, 1, 1);
- bool geometryUsesTextureSubRect = false;
- if (supportsAtlasTextures && m_material.textureProviders.count() == 1) {
- QSGTextureProvider *provider = m_material.textureProviders.at(0);
- if (provider->texture()) {
- srcRect = provider->texture()->normalizedTextureSubRect();
- geometryUsesTextureSubRect = true;
- }
- }
-
- if (m_material.geometryUsesTextureSubRect != geometryUsesTextureSubRect) {
- m_material.geometryUsesTextureSubRect = geometryUsesTextureSubRect;
- markDirty(QSGNode::DirtyMaterial);
- }
-
- return srcRect;
-}
-
-void QSGD3D12ShaderEffectNode::syncMaterial(SyncData *syncData)
-{
- if (Q_UNLIKELY(debug_shader()))
- qDebug() << "shadereffect node sync" << syncData->dirty;
-
- if (bool(m_material.flags() & QSGMaterial::Blending) != syncData->blending) {
- m_material.setFlag(QSGMaterial::Blending, syncData->blending);
- markDirty(QSGNode::DirtyMaterial);
- }
-
- if (m_material.cullMode != syncData->cullMode) {
- m_material.cullMode = syncData->cullMode;
- markDirty(QSGNode::DirtyMaterial);
- }
-
- if (syncData->dirty & QSGShaderEffectNode::DirtyShaders) {
- QByteArray vertBlob, fragBlob;
-
- m_material.hasCustomVertexShader = syncData->vertex.shader->hasShaderCode;
- if (m_material.hasCustomVertexShader) {
- vertBlob = syncData->vertex.shader->shaderInfo.blob;
- } else {
- vertBlob = QByteArray::fromRawData(reinterpret_cast<const char *>(g_VS_DefaultShaderEffect),
- sizeof(g_VS_DefaultShaderEffect));
- }
-
- m_material.hasCustomFragmentShader = syncData->fragment.shader->hasShaderCode;
- if (m_material.hasCustomFragmentShader) {
- fragBlob = syncData->fragment.shader->shaderInfo.blob;
- } else {
- fragBlob = QByteArray::fromRawData(reinterpret_cast<const char *>(g_PS_DefaultShaderEffect),
- sizeof(g_PS_DefaultShaderEffect));
- }
-
- m_material.mtype = shaderMaterialTypeCache()->get(vertBlob, fragBlob);
- m_material.linker.reset(vertBlob, fragBlob);
-
- if (m_material.hasCustomVertexShader) {
- m_material.linker.feedConstants(*syncData->vertex.shader);
- } else {
- QSGShaderEffectNode::ShaderData defaultSD;
- defaultSD.shaderInfo.blob = vertBlob;
- defaultSD.shaderInfo.type = QSGGuiThreadShaderEffectManager::ShaderInfo::TypeVertex;
-
- // { float4x4 qt_Matrix; float qt_Opacity; } where only the matrix is used
- QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v;
- v.name = QByteArrayLiteral("qt_Matrix");
- v.offset = 0;
- v.size = 16 * sizeof(float);
- defaultSD.shaderInfo.variables.append(v);
- QSGShaderEffectNode::VariableData vd;
- vd.specialType = QSGShaderEffectNode::VariableData::Matrix;
- defaultSD.varData.append(vd);
- defaultSD.shaderInfo.constantDataSize = (16 + 1) * sizeof(float);
- m_material.linker.feedConstants(defaultSD);
- }
-
- m_material.linker.feedSamplers(*syncData->vertex.shader);
- m_material.linker.feedTextures(*syncData->vertex.shader);
-
- if (m_material.hasCustomFragmentShader) {
- m_material.linker.feedConstants(*syncData->fragment.shader);
- } else {
- QSGShaderEffectNode::ShaderData defaultSD;
- defaultSD.shaderInfo.blob = fragBlob;
- defaultSD.shaderInfo.type = QSGGuiThreadShaderEffectManager::ShaderInfo::TypeFragment;
-
- // { float4x4 qt_Matrix; float qt_Opacity; } where only the opacity is used
- QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v;
- v.name = QByteArrayLiteral("qt_Opacity");
- v.offset = 16 * sizeof(float);
- v.size = sizeof(float);
- defaultSD.shaderInfo.variables.append(v);
- QSGShaderEffectNode::VariableData vd;
- vd.specialType = QSGShaderEffectNode::VariableData::Opacity;
- defaultSD.varData.append(vd);
-
- v.name = QByteArrayLiteral("source");
- v.bindPoint = 0;
- v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Texture;
- defaultSD.shaderInfo.variables.append(v);
- vd.specialType = QSGShaderEffectNode::VariableData::Source;
- defaultSD.varData.append(vd);
-
- v.name = QByteArrayLiteral("sourceSampler");
- v.bindPoint = 0;
- v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler;
- defaultSD.shaderInfo.variables.append(v);
- vd.specialType = QSGShaderEffectNode::VariableData::Unused;
- defaultSD.varData.append(vd);
-
- defaultSD.shaderInfo.constantDataSize = (16 + 1) * sizeof(float);
-
- m_material.linker.feedConstants(defaultSD);
- m_material.linker.feedSamplers(defaultSD);
- m_material.linker.feedTextures(defaultSD);
- }
-
- // While this may seem unnecessary for the built-in shaders, the value
- // of 'source' is still in there and we have to process it.
- m_material.linker.feedSamplers(*syncData->fragment.shader);
- m_material.linker.feedTextures(*syncData->fragment.shader);
-
- m_material.linker.linkTextureSubRects();
-
- m_material.updateTextureProviders(true);
-
- markDirty(QSGNode::DirtyMaterial);
-
- if (Q_UNLIKELY(debug_shader()))
- m_material.linker.dump();
- } else {
- if (syncData->dirty & QSGShaderEffectNode::DirtyShaderConstant) {
- if (!syncData->vertex.dirtyConstants->isEmpty())
- m_material.linker.feedConstants(*syncData->vertex.shader, syncData->vertex.dirtyConstants);
- if (!syncData->fragment.dirtyConstants->isEmpty())
- m_material.linker.feedConstants(*syncData->fragment.shader, syncData->fragment.dirtyConstants);
- markDirty(QSGNode::DirtyMaterial);
- if (Q_UNLIKELY(debug_shader()))
- m_material.linker.dump();
- }
-
- if (syncData->dirty & QSGShaderEffectNode::DirtyShaderTexture) {
- if (!syncData->vertex.dirtyTextures->isEmpty())
- m_material.linker.feedTextures(*syncData->vertex.shader, syncData->vertex.dirtyTextures);
- if (!syncData->fragment.dirtyTextures->isEmpty())
- m_material.linker.feedTextures(*syncData->fragment.shader, syncData->fragment.dirtyTextures);
- m_material.linker.linkTextureSubRects();
- m_material.updateTextureProviders(false);
- markDirty(QSGNode::DirtyMaterial);
- if (Q_UNLIKELY(debug_shader()))
- m_material.linker.dump();
- }
- }
-
- if (bool(m_material.flags() & QSGMaterial::RequiresFullMatrix) != m_material.hasCustomVertexShader) {
- m_material.setFlag(QSGMaterial::RequiresFullMatrix, m_material.hasCustomVertexShader);
- markDirty(QSGNode::DirtyMaterial);
- }
-}
-
-void QSGD3D12ShaderEffectNode::handleTextureChange()
-{
- markDirty(QSGNode::DirtyMaterial);
- emit m_mgr->textureChanged();
-}
-
-void QSGD3D12ShaderEffectNode::handleTextureProviderDestroyed(QObject *object)
-{
- for (QSGTextureProvider *&tp : m_material.textureProviders) {
- if (tp == object)
- tp = nullptr;
- }
-}
-
-void QSGD3D12ShaderEffectNode::preprocess()
-{
- for (QSGTextureProvider *tp : m_material.textureProviders) {
- if (tp) {
- if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(tp->texture()))
- texture->updateTexture();
- }
- }
-}
-
-bool QSGD3D12GuiThreadShaderEffectManager::hasSeparateSamplerAndTextureObjects() const
-{
- return true;
-}
-
-QString QSGD3D12GuiThreadShaderEffectManager::log() const
-{
- return m_log;
-}
-
-QSGGuiThreadShaderEffectManager::Status QSGD3D12GuiThreadShaderEffectManager::status() const
-{
- return m_status;
-}
-
-struct RefGuard {
- RefGuard(IUnknown *p) : p(p) { }
- ~RefGuard() { p->Release(); }
- IUnknown *p;
-};
-
-class QSGD3D12ShaderCompileTask : public QRunnable
-{
-public:
- QSGD3D12ShaderCompileTask(QSGD3D12GuiThreadShaderEffectManager *mgr,
- QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::Type typeHint,
- const QByteArray &src,
- QSGD3D12GuiThreadShaderEffectManager::ShaderInfo *result)
- : mgr(mgr), typeHint(typeHint), src(src), result(result) { }
-
- void run() override;
-
-private:
- QSGD3D12GuiThreadShaderEffectManager *mgr;
- QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::Type typeHint;
- QByteArray src;
- QSGD3D12GuiThreadShaderEffectManager::ShaderInfo *result;
-};
-
-void QSGD3D12ShaderCompileTask::run()
-{
- const char *target = typeHint == QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::TypeVertex ? "vs_5_0" : "ps_5_0";
- ID3DBlob *bytecode = nullptr;
- ID3DBlob *errors = nullptr;
- HRESULT hr = D3DCompile(src.constData(), src.size(), nullptr, nullptr, nullptr,
- "main", target, 0, 0, &bytecode, &errors);
- if (FAILED(hr) || !bytecode) {
- qWarning("HLSL shader compilation failed: 0x%x", hr);
- if (errors) {
- mgr->m_log += QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()), errors->GetBufferSize());
- errors->Release();
- }
- mgr->m_status = QSGGuiThreadShaderEffectManager::Error;
- emit mgr->shaderCodePrepared(false, typeHint, src, result);
- emit mgr->logAndStatusChanged();
- return;
- }
-
- result->blob.resize(bytecode->GetBufferSize());
- memcpy(result->blob.data(), bytecode->GetBufferPointer(), result->blob.size());
- bytecode->Release();
-
- const bool ok = mgr->reflect(result);
- mgr->m_status = ok ? QSGGuiThreadShaderEffectManager::Compiled : QSGGuiThreadShaderEffectManager::Error;
- emit mgr->shaderCodePrepared(ok, typeHint, src, result);
- emit mgr->logAndStatusChanged();
-}
-
-static const int BYTECODE_MAGIC = 0x43425844; // 'DXBC'
-
-void QSGD3D12GuiThreadShaderEffectManager::prepareShaderCode(ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result)
-{
- // The D3D12 backend's ShaderEffect implementation supports both HLSL
- // source strings and bytecode or source in files as input. Bytecode is
- // strongly recommended, but in order to make ShaderEffect users' (and
- // anything that stiches shader strings together dynamically, e.g.
- // qtgraphicaleffects) life easier, and since we link to d3dcompiler
- // anyways, compiling from source is also supported.
-
- QByteArray shaderSourceCode = src;
- QUrl srcUrl(QString::fromUtf8(src));
- if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) {
- if (!m_fileSelector) {
- m_fileSelector = new QFileSelector(this);
- m_fileSelector->setExtraSelectors(QStringList() << QStringLiteral("hlsl"));
- }
- const QString fn = m_fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl));
- QFile f(fn);
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning("ShaderEffect: Failed to read %s", qPrintable(fn));
- emit shaderCodePrepared(false, typeHint, src, result);
- return;
- }
- QByteArray blob = f.readAll();
- f.close();
- if (blob.size() > 4) {
- const quint32 *p = reinterpret_cast<const quint32 *>(blob.constData());
- if (*p == BYTECODE_MAGIC) {
- // already compiled D3D bytecode, skip straight to reflection
- result->blob = blob;
- const bool ok = reflect(result);
- m_status = ok ? Compiled : Error;
- emit shaderCodePrepared(ok, typeHint, src, result);
- emit logAndStatusChanged();
- return;
- }
- // assume the file contained HLSL source code
- shaderSourceCode = blob;
- }
- }
-
- QThreadPool::globalInstance()->start(new QSGD3D12ShaderCompileTask(this, typeHint, shaderSourceCode, result));
-}
-
-bool QSGD3D12GuiThreadShaderEffectManager::reflect(ShaderInfo *result)
-{
- ID3D12ShaderReflection *reflector;
- HRESULT hr = D3DReflect(result->blob.constData(), result->blob.size(), IID_PPV_ARGS(&reflector));
- if (FAILED(hr)) {
- qWarning("D3D shader reflection failed: 0x%x", hr);
- return false;
- }
- RefGuard rg(reflector);
-
- D3D12_SHADER_DESC shaderDesc;
- reflector->GetDesc(&shaderDesc);
-
- const uint progType = (shaderDesc.Version & 0xFFFF0000) >> 16;
- const uint major = (shaderDesc.Version & 0x000000F0) >> 4;
- const uint minor = (shaderDesc.Version & 0x0000000F);
-
- switch (progType) {
- case D3D12_SHVER_VERTEX_SHADER:
- result->type = ShaderInfo::TypeVertex;
- break;
- case D3D12_SHVER_PIXEL_SHADER:
- result->type = ShaderInfo::TypeFragment;
- break;
- default:
- result->type = ShaderInfo::TypeOther;
- qWarning("D3D shader is of unknown type 0x%x", shaderDesc.Version);
- return false;
- }
-
- if (major < 5) {
- qWarning("D3D shader model version %u.%u is too low", major, minor);
- return false;
- }
-
- const int ieCount = shaderDesc.InputParameters;
- const int cbufferCount = shaderDesc.ConstantBuffers;
- const int boundResCount = shaderDesc.BoundResources;
-
- result->constantDataSize = 0;
-
- if (ieCount < 1) {
- qWarning("Invalid shader: Not enough input parameters (%d)", ieCount);
- return false;
- }
- if (cbufferCount < 1) {
- qWarning("Invalid shader: Shader has no constant buffers");
- return false;
- }
- if (boundResCount < 1) {
- qWarning("Invalid shader: No resources bound. Expected to have at least a constant buffer bound.");
- return false;
- }
-
- if (Q_UNLIKELY(debug_shader()))
- qDebug("Shader reflection size %d type %d v%u.%u input elems %d cbuffers %d boundres %d",
- result->blob.size(), result->type, major, minor, ieCount, cbufferCount, boundResCount);
-
- for (int i = 0; i < boundResCount; ++i) {
- D3D12_SHADER_INPUT_BIND_DESC desc;
- if (FAILED(reflector->GetResourceBindingDesc(i, &desc))) {
- qWarning("D3D reflection: Failed to query resource binding %d", i);
- continue;
- }
- bool gotCBuffer = false;
- if (desc.Type == D3D_SIT_CBUFFER) {
- ID3D12ShaderReflectionConstantBuffer *cbuf = reflector->GetConstantBufferByName(desc.Name);
- D3D12_SHADER_BUFFER_DESC bufDesc;
- if (FAILED(cbuf->GetDesc(&bufDesc))) {
- qWarning("D3D reflection: Failed to query constant buffer description");
- continue;
- }
- if (gotCBuffer) {
- qWarning("D3D reflection: Found more than one constant buffers. Only the first one is used.");
- continue;
- }
- gotCBuffer = true;
- result->constantDataSize = bufDesc.Size;
- for (uint cbIdx = 0; cbIdx < bufDesc.Variables; ++cbIdx) {
- ID3D12ShaderReflectionVariable *cvar = cbuf->GetVariableByIndex(cbIdx);
- D3D12_SHADER_VARIABLE_DESC varDesc;
- if (FAILED(cvar->GetDesc(&varDesc))) {
- qWarning("D3D reflection: Failed to query constant buffer variable %d", cbIdx);
- return false;
- }
- // we report the full size of the buffer but only return variables that are actually used by this shader
- if (!(varDesc.uFlags & D3D_SVF_USED))
- continue;
- ShaderInfo::Variable v;
- v.type = ShaderInfo::Constant;
- v.name = QByteArray(varDesc.Name);
- v.offset = varDesc.StartOffset;
- v.size = varDesc.Size;
- result->variables.append(v);
- }
- } else if (desc.Type == D3D_SIT_TEXTURE) {
- if (desc.Dimension != D3D_SRV_DIMENSION_TEXTURE2D) {
- qWarning("D3D reflection: Texture %s is not a 2D texture, ignoring.", qPrintable(desc.Name));
- continue;
- }
- if (desc.NumSamples != (UINT) -1) {
- qWarning("D3D reflection: Texture %s is multisample (%u), ignoring.", qPrintable(desc.Name), desc.NumSamples);
- continue;
- }
- if (desc.BindCount != 1) {
- qWarning("D3D reflection: Texture %s is an array, ignoring.", qPrintable(desc.Name));
- continue;
- }
- if (desc.Space != 0) {
- qWarning("D3D reflection: Texture %s is not using register space 0, ignoring.", qPrintable(desc.Name));
- continue;
- }
- ShaderInfo::Variable v;
- v.type = ShaderInfo::Texture;
- v.name = QByteArray(desc.Name);
- v.bindPoint = desc.BindPoint;
- result->variables.append(v);
- } else if (desc.Type == D3D_SIT_SAMPLER) {
- if (desc.BindCount != 1) {
- qWarning("D3D reflection: Sampler %s is an array, ignoring.", qPrintable(desc.Name));
- continue;
- }
- if (desc.Space != 0) {
- qWarning("D3D reflection: Sampler %s is not using register space 0, ignoring.", qPrintable(desc.Name));
- continue;
- }
- ShaderInfo::Variable v;
- v.type = ShaderInfo::Sampler;
- v.name = QByteArray(desc.Name);
- v.bindPoint = desc.BindPoint;
- result->variables.append(v);
- } else {
- qWarning("D3D reflection: Resource binding %d has an unknown type of %d and will be ignored.", i, desc.Type);
- continue;
- }
- }
-
- if (Q_UNLIKELY(debug_shader()))
- qDebug() << "Variables:" << result->variables << "cbuffer size" << result->constantDataSize;
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h
deleted file mode 100644
index dec85fd782..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12SHADEREFFECTNODE_P_H
-#define QSGD3D12SHADEREFFECTNODE_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 <private/qsgadaptationlayer_p.h>
-#include "qsgd3d12material_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12RenderContext;
-class QSGD3D12GuiThreadShaderEffectManager;
-class QSGD3D12ShaderEffectNode;
-class QSGD3D12Texture;
-class QFileSelector;
-
-class QSGD3D12ShaderLinker
-{
-public:
- void reset(const QByteArray &vertBlob, const QByteArray &fragBlob);
-
- void feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr);
- void feedSamplers(const QSGShaderEffectNode::ShaderData &shader);
- void feedTextures(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr);
- void linkTextureSubRects();
-
- void dump();
-
- struct Constant {
- uint size;
- QSGShaderEffectNode::VariableData::SpecialType specialType;
- QVariant value;
- bool operator==(const Constant &other) const {
- return size == other.size && specialType == other.specialType
- && (specialType == QSGShaderEffectNode::VariableData::None ? value == other.value : true);
- }
- };
-
- bool error;
- QByteArray vs;
- QByteArray fs;
- uint constantBufferSize;
- QHash<uint, Constant> constants; // offset -> Constant
- QSet<int> samplers; // bindpoint
- QHash<int, QVariant> textures; // bindpoint -> value (source ref)
- QHash<QByteArray, int> textureNameMap; // name -> bindpoint
-};
-
-QDebug operator<<(QDebug debug, const QSGD3D12ShaderLinker::Constant &c);
-
-class QSGD3D12ShaderEffectMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12ShaderEffectMaterial(QSGD3D12ShaderEffectNode *node);
- ~QSGD3D12ShaderEffectMaterial();
-
- QSGMaterialType *type() const override;
- int compare(const QSGMaterial *other) const override;
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- void updateTextureProviders(bool layoutChange);
-
- QSGD3D12ShaderEffectNode *node;
- bool valid = false;
- QSGShaderEffectNode::CullMode cullMode = QSGShaderEffectNode::NoCulling;
- bool hasCustomVertexShader = false;
- bool hasCustomFragmentShader = false;
- QSGD3D12ShaderLinker linker;
- QSGMaterialType *mtype = nullptr;
- QVector<QSGTextureProvider *> textureProviders;
- QSGD3D12Texture *dummy = nullptr;
- bool geometryUsesTextureSubRect = false;
-};
-
-class QSGD3D12ShaderEffectNode : public QObject, public QSGShaderEffectNode
-{
- Q_OBJECT
-
-public:
- QSGD3D12ShaderEffectNode(QSGD3D12RenderContext *rc, QSGD3D12GuiThreadShaderEffectManager *mgr);
-
- QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) override;
- void syncMaterial(SyncData *syncData) override;
-
- static void cleanupMaterialTypeCache();
-
- void preprocess() override;
-
- QSGD3D12RenderContext *renderContext() { return m_rc; }
-
-private Q_SLOTS:
- void handleTextureChange();
- void handleTextureProviderDestroyed(QObject *object);
-
-private:
- QSGD3D12RenderContext *m_rc;
- QSGD3D12GuiThreadShaderEffectManager *m_mgr;
- QSGD3D12ShaderEffectMaterial m_material;
-};
-
-class QSGD3D12GuiThreadShaderEffectManager : public QSGGuiThreadShaderEffectManager
-{
-public:
- bool hasSeparateSamplerAndTextureObjects() const override;
-
- QString log() const override;
- Status status() const override;
-
- void prepareShaderCode(ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result) override;
-
-private:
- bool reflect(ShaderInfo *result);
- QString m_log;
- Status m_status = Uncompiled;
- QFileSelector *m_fileSelector = nullptr;
-
- friend class QSGD3D12ShaderCompileTask;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12SHADEREFFECTNODE_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp
deleted file mode 100644
index 807fbcdcec..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12spritenode_p.h"
-#include "qsgd3d12material_p.h"
-
-#include "vs_sprite.hlslh"
-#include "ps_sprite.hlslh"
-
-QT_BEGIN_NAMESPACE
-
-struct SpriteVertex
-{
- float x;
- float y;
- float tx;
- float ty;
-};
-
-struct SpriteVertices
-{
- SpriteVertex v1;
- SpriteVertex v2;
- SpriteVertex v3;
- SpriteVertex v4;
-};
-
-class QSGD3D12SpriteMaterial : public QSGD3D12Material
-{
-public:
- QSGD3D12SpriteMaterial();
- ~QSGD3D12SpriteMaterial();
-
- QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
-
- int compare(const QSGMaterial *other) const override
- {
- return this - static_cast<const QSGD3D12SpriteMaterial *>(other);
- }
-
- int constantBufferSize() const override;
- void preparePipeline(QSGD3D12PipelineState *pipelineState) override;
- UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *pipelineState,
- ExtraState *extraState,
- quint8 *constantBuffer) override;
-
- QSGTexture *texture;
-
- float animT;
- float animX1;
- float animY1;
- float animX2;
- float animY2;
- float animW;
- float animH;
-};
-
-QSGD3D12SpriteMaterial::QSGD3D12SpriteMaterial()
- : texture(nullptr),
- animT(0.0f),
- animX1(0.0f),
- animY1(0.0f),
- animX2(0.0f),
- animY2(0.0f),
- animW(1.0f),
- animH(1.0f)
-{
- setFlag(Blending, true);
-}
-
-QSGD3D12SpriteMaterial::~QSGD3D12SpriteMaterial()
-{
- delete texture;
-}
-
-static const int SPRITE_CB_SIZE_0 = 16 * sizeof(float); // float4x4
-static const int SPRITE_CB_SIZE_1 = 4 * sizeof(float); // float4
-static const int SPRITE_CB_SIZE_2 = 3 * sizeof(float); // float3
-static const int SPRITE_CB_SIZE_3 = sizeof(float); // float
-static const int SPRITE_CB_SIZE = SPRITE_CB_SIZE_0 + SPRITE_CB_SIZE_1 + SPRITE_CB_SIZE_2 + SPRITE_CB_SIZE_3;
-
-int QSGD3D12SpriteMaterial::constantBufferSize() const
-{
- return QSGD3D12Engine::alignedConstantBufferSize(SPRITE_CB_SIZE);
-}
-
-void QSGD3D12SpriteMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState)
-{
- pipelineState->shaders.vs = g_VS_Sprite;
- pipelineState->shaders.vsSize = sizeof(g_VS_Sprite);
- pipelineState->shaders.ps = g_PS_Sprite;
- pipelineState->shaders.psSize = sizeof(g_PS_Sprite);
-
- pipelineState->shaders.rootSig.textureViewCount = 1;
-}
-
-QSGD3D12Material::UpdateResults QSGD3D12SpriteMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state,
- QSGD3D12PipelineState *,
- ExtraState *,
- quint8 *constantBuffer)
-{
- QSGD3D12Material::UpdateResults r = UpdatedConstantBuffer;
- quint8 *p = constantBuffer;
-
- if (state.isMatrixDirty())
- memcpy(p, state.combinedMatrix().constData(), SPRITE_CB_SIZE_0);
- p += SPRITE_CB_SIZE_0;
-
- {
- const float v[] = { animX1, animY1, animX2, animY2 };
- memcpy(p, v, SPRITE_CB_SIZE_1);
- }
- p += SPRITE_CB_SIZE_1;
-
- {
- const float v[] = { animW, animH, animT };
- memcpy(p, v, SPRITE_CB_SIZE_2);
- }
- p += SPRITE_CB_SIZE_2;
-
- if (state.isOpacityDirty()) {
- const float opacity = state.opacity();
- memcpy(p, &opacity, SPRITE_CB_SIZE_3);
- }
-
- texture->bind();
-
- return r;
-}
-
-static QSGGeometry::Attribute Sprite_Attributes[] = {
- QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute),
- QSGGeometry::Attribute::createWithAttributeType(1, 2, QSGGeometry::FloatType, QSGGeometry::TexCoordAttribute),
-};
-
-static QSGGeometry::AttributeSet Sprite_AttributeSet = { 2, 4 * sizeof(float), Sprite_Attributes };
-
-QSGD3D12SpriteNode::QSGD3D12SpriteNode()
- : m_material(new QSGD3D12SpriteMaterial)
- , m_geometryDirty(true)
- , m_sheetSize(QSize(64, 64))
-{
- m_geometry = new QSGGeometry(Sprite_AttributeSet, 4, 6);
- m_geometry->setDrawingMode(QSGGeometry::DrawTriangles);
-
- quint16 *indices = m_geometry->indexDataAsUShort();
- indices[0] = 0;
- indices[1] = 1;
- indices[2] = 2;
- indices[3] = 1;
- indices[4] = 3;
- indices[5] = 2;
-
- setGeometry(m_geometry);
- setMaterial(m_material);
- setFlag(OwnsGeometry, true);
- setFlag(OwnsMaterial, true);
-}
-
-void QSGD3D12SpriteNode::setTexture(QSGTexture *texture)
-{
- m_material->texture = texture;
- m_geometryDirty = true;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12SpriteNode::setTime(float time)
-{
- m_material->animT = time;
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12SpriteNode::setSourceA(const QPoint &source)
-{
- if (m_sourceA != source) {
- m_sourceA = source;
- m_material->animX1 = static_cast<float>(source.x()) / m_sheetSize.width();
- m_material->animY1 = static_cast<float>(source.y()) / m_sheetSize.height();
- markDirty(DirtyMaterial);
- }
-}
-
-void QSGD3D12SpriteNode::setSourceB(const QPoint &source)
-{
- if (m_sourceB != source) {
- m_sourceB = source;
- m_material->animX2 = static_cast<float>(source.x()) / m_sheetSize.width();
- m_material->animY2 = static_cast<float>(source.y()) / m_sheetSize.height();
- markDirty(DirtyMaterial);
- }
-}
-
-void QSGD3D12SpriteNode::setSpriteSize(const QSize &size)
-{
- if (m_spriteSize != size) {
- m_spriteSize = size;
- m_material->animW = static_cast<float>(size.width()) / m_sheetSize.width();
- m_material->animH = static_cast<float>(size.height()) / m_sheetSize.height();
- markDirty(DirtyMaterial);
- }
-}
-
-void QSGD3D12SpriteNode::setSheetSize(const QSize &size)
-{
- if (m_sheetSize != size) {
- m_sheetSize = size;
-
- // Update all dependent properties
- m_material->animX1 = static_cast<float>(m_sourceA.x()) / m_sheetSize.width();
- m_material->animY1 = static_cast<float>(m_sourceA.y()) / m_sheetSize.height();
- m_material->animX2 = static_cast<float>(m_sourceB.x()) / m_sheetSize.width();
- m_material->animY2 = static_cast<float>(m_sourceB.y()) / m_sheetSize.height();
- m_material->animW = static_cast<float>(m_spriteSize.width()) / m_sheetSize.width();
- m_material->animH = static_cast<float>(m_spriteSize.height()) / m_sheetSize.height();
-
- markDirty(DirtyMaterial);
- }
-}
-
-void QSGD3D12SpriteNode::setSize(const QSizeF &size)
-{
- if (m_size != size) {
- m_size = size;
- m_geometryDirty = true;
- }
-}
-
-void QSGD3D12SpriteNode::setFiltering(QSGTexture::Filtering filtering)
-{
- m_material->texture->setFiltering(filtering);
- markDirty(DirtyMaterial);
-}
-
-void QSGD3D12SpriteNode::update()
-{
- if (m_geometryDirty) {
- m_geometryDirty = false;
- updateGeometry();
- }
-}
-
-void QSGD3D12SpriteNode::updateGeometry()
-{
- if (!m_material->texture)
- return;
-
- SpriteVertices *p = static_cast<SpriteVertices *>(m_geometry->vertexData());
- const QRectF texRect = m_material->texture->normalizedTextureSubRect();
-
- p->v1.tx = texRect.topLeft().x();
- p->v1.ty = texRect.topLeft().y();
-
- p->v2.tx = texRect.topRight().x();
- p->v2.ty = texRect.topRight().y();
-
- p->v3.tx = texRect.bottomLeft().x();
- p->v3.ty = texRect.bottomLeft().y();
-
- p->v4.tx = texRect.bottomRight().x();
- p->v4.ty = texRect.bottomRight().y();
-
- p->v1.x = 0;
- p->v1.y = 0;
-
- p->v2.x = m_size.width();
- p->v2.y = 0;
-
- p->v3.x = 0;
- p->v3.y = m_size.height();
-
- p->v4.x = m_size.width();
- p->v4.y = m_size.height();
-
- markDirty(DirtyGeometry);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp
deleted file mode 100644
index b49b851c23..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12texture_p.h"
-#include "qsgd3d12engine_p.h"
-#include <private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#define RETAIN_IMAGE
-
-void QSGD3D12Texture::create(const QImage &image, uint flags)
-{
- // ### atlas?
-
- const bool alphaRequest = flags & QSGRenderContext::CreateTexture_Alpha;
- m_alphaWanted = alphaRequest && image.hasAlphaChannel();
-
- // The engine maps 8-bit formats to R8. This is fine for glyphs and such
- // but may not be what apps expect for ordinary image data. The OpenGL
- // implementation maps these to ARGB32_Pre so let's follow suit.
- if (image.depth() != 8)
- m_image = image;
- else
- m_image = image.convertToFormat(m_alphaWanted ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
-
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
-
- // We could kick off the texture creation and the async upload right here.
- // Unfortunately we cannot tell at this stage if mipmaps will be enabled
- // via an Image element's mipmap property...so defer to bind().
- m_createPending = true;
-}
-
-QSGD3D12Texture::QSGD3D12Texture(QSGD3D12Engine *engine)
- : QSGTexture(*(new QSGD3D12TexturePrivate)),
- m_engine(engine)
-{
-}
-
-QSGD3D12Texture::~QSGD3D12Texture()
-{
- if (m_id)
- m_engine->releaseTexture(m_id);
-}
-
-int QSGD3D12Texture::textureId() const
-{
- return m_id;
-}
-
-int QSGD3D12TexturePrivate::comparisonKey() const
-{
- Q_Q(const QSGD3D12Texture);
- return q->m_id;
-}
-
-QSize QSGD3D12Texture::textureSize() const
-{
- return m_image.size();
-}
-
-bool QSGD3D12Texture::hasAlphaChannel() const
-{
- return m_alphaWanted;
-}
-
-bool QSGD3D12Texture::hasMipmaps() const
-{
- return mipmapFiltering() != QSGTexture::None;
-}
-
-QRectF QSGD3D12Texture::normalizedTextureSubRect() const
-{
- return QRectF(0, 0, 1, 1);
-}
-
-void QSGD3D12Texture::bind()
-{
- // Called when the texture material updates the pipeline state.
-
- if (!m_createPending && hasMipmaps() != m_createdWithMipMaps) {
-#ifdef RETAIN_IMAGE
- m_engine->releaseTexture(m_id);
- m_id = m_engine->genTexture();
- Q_ASSERT(m_id);
- m_createPending = true;
-#else
- // ### this can be made working some day (something similar to
- // queueTextureResize) but skip for now
- qWarning("D3D12: mipmap property cannot be changed once the texture is created");
-#endif
- }
-
- if (m_createPending) {
- m_createPending = false;
-
- QSGD3D12Engine::TextureCreateFlags createFlags = 0;
- if (m_alphaWanted)
- createFlags |= QSGD3D12Engine::TextureWithAlpha;
-
- m_createdWithMipMaps = hasMipmaps();
- if (m_createdWithMipMaps)
- createFlags |= QSGD3D12Engine::TextureWithMipMaps;
-
- m_engine->createTexture(m_id, m_image.size(), m_image.format(), createFlags);
- m_engine->queueTextureUpload(m_id, m_image);
-
-#ifndef RETAIN_IMAGE
- m_image = QImage();
-#endif
- }
-
- // Here we know that the texture is going to be used in the current frame
- // by the next draw call. Notify the engine so that it can wait for
- // possible pending uploads and set up the pipeline accordingly.
- m_engine->useTexture(m_id);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
deleted file mode 100644
index 91a35627ea..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
+++ /dev/null
@@ -1,1208 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgd3d12threadedrenderloop_p.h"
-#include "qsgd3d12engine_p.h"
-#include "qsgd3d12context_p.h"
-#include "qsgd3d12rendercontext_p.h"
-#include "qsgd3d12shadereffectnode_p.h"
-#include <private/qsgrenderer_p.h>
-#include <private/qquickwindow_p.h>
-#include <private/qquickanimatorcontroller_p.h>
-#include <private/qquickprofiler_p.h>
-#include <private/qqmldebugserviceinterfaces_p.h>
-#include <private/qqmldebugconnector_p.h>
-#include <QElapsedTimer>
-#include <QQueue>
-#include <QGuiApplication>
-
-#include <qtquick_tracepoints_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// NOTE: Avoid categorized logging. It is slow.
-
-#define DECLARE_DEBUG_VAR(variable) \
- static bool debug_ ## variable() \
- { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
-
-DECLARE_DEBUG_VAR(loop)
-DECLARE_DEBUG_VAR(time)
-
-
-// NOTE: The threaded renderloop is not currently safe to use in practice as it
-// is prone to deadlocks, in particular when multiple windows are active. This
-// is because DXGI's limitation of relying on the gui message pump in certain
-// cases. See
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx#multithreading_and_dxgi
-//
-// This means that if swap chain functions like create, release, and
-// potentially even Present, are called outside the gui thread, then the
-// application must ensure the gui thread does not ever block and wait for the
-// render thread - since on the render thread a DXGI call may be in turn
-// waiting for the gui thread to deliver a window message...
-//
-// Ensuring this is impossible with the current design where the gui thread
-// must block at certain points, waiting for the render thread. Qt moves out
-// rendering from the main thread, in order to make application's life easier,
-// whereas the typical DXGI-compatible model would require moving work, but not
-// windowing and presenting, out to additional threads.
-
-
-/*
- The D3D render loop mostly mirrors the threaded OpenGL render loop.
-
- There are two classes here. QSGD3D12ThreadedRenderLoop and
- QSGD3D12RenderThread. All communication between the two is based on event
- passing and we have a number of custom events.
-
- Render loop is per process, render thread is per window. The
- QSGD3D12RenderContext and QSGD3D12Engine are per window as well. The former
- is created (but not owned) by QQuickWindow. The D3D device is per process.
-
- In this implementation, the render thread is never blocked and the GUI
- thread will initiate a polishAndSync which will block and wait for the
- render thread to pick it up and release the block only after the render
- thread is done syncing. The reason for this is:
-
- 1. Clear blocking paradigm. We only have one real "block" point
- (polishAndSync()) and all blocking is initiated by GUI and picked up by
- Render at specific times based on events. This makes the execution
- deterministic.
-
- 2. Render does not have to interact with GUI. This is done so that the
- render thread can run its own animation system which stays alive even when
- the GUI thread is blocked doing I/O, object instantiation, QPainter-painting
- or any other non-trivial task.
-
- The render thread has affinity to the GUI thread until a window is shown.
- From that moment and until the window is destroyed, it will have affinity to
- the render thread. (moved back at the end of run for cleanup).
- */
-
-// Passed from the RL to the RT when a window is removed obscured and should be
-// removed from the render loop.
-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 RL to the RT to maybe release resource if no windows are
-// rendering.
-const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
-
-// Passed by the RL to the RT when a QQuickWindow::grabWindow() is called.
-const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5);
-
-// Passed by the window when there is a render job to run.
-const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6);
-
-class QSGD3D12WindowEvent : public QEvent
-{
-public:
- QSGD3D12WindowEvent(QQuickWindow *c, QEvent::Type type) : QEvent(type), window(c) { }
- QQuickWindow *window;
-};
-
-class QSGD3D12TryReleaseEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12TryReleaseEvent(QQuickWindow *win, bool destroy)
- : QSGD3D12WindowEvent(win, WM_TryRelease), destroying(destroy) { }
- bool destroying;
-};
-
-class QSGD3D12SyncEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12SyncEvent(QQuickWindow *c, bool inExpose, bool force)
- : QSGD3D12WindowEvent(c, WM_RequestSync)
- , size(c->size())
- , dpr(c->effectiveDevicePixelRatio())
- , syncInExpose(inExpose)
- , forceRenderPass(force) { }
- QSize size;
- float dpr;
- bool syncInExpose;
- bool forceRenderPass;
-};
-
-class QSGD3D12GrabEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12GrabEvent(QQuickWindow *c, QImage *result)
- : QSGD3D12WindowEvent(c, WM_Grab), image(result) { }
- QImage *image;
-};
-
-class QSGD3D12JobEvent : public QSGD3D12WindowEvent
-{
-public:
- QSGD3D12JobEvent(QQuickWindow *c, QRunnable *postedJob)
- : QSGD3D12WindowEvent(c, WM_PostJob), job(postedJob) { }
- ~QSGD3D12JobEvent() { delete job; }
- QRunnable *job;
-};
-
-class QSGD3D12EventQueue : public QQueue<QEvent *>
-{
-public:
- void addEvent(QEvent *e) {
- mutex.lock();
- enqueue(e);
- if (waiting)
- condition.wakeOne();
- mutex.unlock();
- }
-
- QEvent *takeEvent(bool wait) {
- mutex.lock();
- if (isEmpty() && wait) {
- waiting = true;
- condition.wait(&mutex);
- waiting = false;
- }
- QEvent *e = dequeue();
- mutex.unlock();
- return e;
- }
-
- bool hasMoreEvents() {
- mutex.lock();
- bool has = !isEmpty();
- mutex.unlock();
- return has;
- }
-
-private:
- QMutex mutex;
- QWaitCondition condition;
- bool waiting = false;
-};
-
-static inline int qsgrl_animation_interval()
-{
- const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0;
- return refreshRate < 1 ? 16 : int(1000 / refreshRate);
-}
-
-class QSGD3D12RenderThread : public QThread
-{
- Q_OBJECT
-
-public:
- QSGD3D12RenderThread(QSGD3D12ThreadedRenderLoop *rl, QSGRenderContext *renderContext)
- : renderLoop(rl)
- {
- rc = static_cast<QSGD3D12RenderContext *>(renderContext);
- vsyncDelta = qsgrl_animation_interval();
- }
-
- ~QSGD3D12RenderThread()
- {
- delete rc;
- }
-
- bool event(QEvent *e);
- void run();
-
- void syncAndRender();
- void sync(bool inExpose);
-
- void requestRepaint()
- {
- if (sleeping)
- stopEventProcessing = true;
- if (exposedWindow)
- pendingUpdate |= RepaintRequest;
- }
-
- void processEventsAndWaitForMore();
- void processEvents();
- void postEvent(QEvent *e);
-
- enum UpdateRequest {
- SyncRequest = 0x01,
- RepaintRequest = 0x02,
- ExposeRequest = 0x04 | RepaintRequest | SyncRequest
- };
-
- QSGD3D12Engine *engine = nullptr;
- QSGD3D12ThreadedRenderLoop *renderLoop;
- QSGD3D12RenderContext *rc;
- QAnimationDriver *rtAnim = nullptr;
- volatile bool active = false;
- uint pendingUpdate = 0;
- bool sleeping = false;
- bool syncResultedInChanges = false;
- float vsyncDelta;
- QMutex mutex;
- QWaitCondition waitCondition;
- QQuickWindow *exposedWindow = nullptr;
- bool stopEventProcessing = false;
- QSGD3D12EventQueue eventQueue;
- QElapsedTimer threadTimer;
- qint64 syncTime;
- qint64 renderTime;
- qint64 sinceLastTime;
-
-public slots:
- void onSceneGraphChanged() {
- syncResultedInChanges = true;
- }
-};
-
-bool QSGD3D12RenderThread::event(QEvent *e)
-{
- switch (e->type()) {
-
- case WM_Obscure:
- Q_ASSERT(!exposedWindow || exposedWindow == static_cast<QSGD3D12WindowEvent *>(e)->window);
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_Obscure" << exposedWindow;
- mutex.lock();
- if (exposedWindow) {
- QQuickWindowPrivate::get(exposedWindow)->fireAboutToStop();
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Obscure - window removed");
- exposedWindow = nullptr;
- }
- waitCondition.wakeOne();
- mutex.unlock();
- return true;
-
- case WM_RequestSync: {
- QSGD3D12SyncEvent *wme = static_cast<QSGD3D12SyncEvent *>(e);
- if (sleeping)
- stopEventProcessing = true;
- // One thread+engine for each window. However, the native window may
- // change in some (quite artificial) cases, e.g. due to a hide -
- // destroy - show on the QWindow.
- bool needsWindow = !engine->window();
- if (engine->window() && engine->window() != wme->window->winId()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestSync - native window handle changes for active engine");
- engine->waitGPU();
- QQuickWindowPrivate::get(wme->window)->cleanupNodesOnShutdown();
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
- rc->invalidate();
- engine->releaseResources();
- needsWindow = true;
- }
- if (needsWindow) {
- // Must only ever get here when there is no window or releaseResources() has been called.
- const int samples = wme->window->format().samples();
- const bool alpha = wme->window->format().alphaBufferSize() > 0;
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_RequestSync - initializing D3D12 engine" << wme->window
- << wme->size << wme->dpr << samples << alpha;
- engine->attachToWindow(wme->window->winId(), wme->size, wme->dpr, samples, alpha);
- }
- exposedWindow = wme->window;
- engine->setWindowSize(wme->size, wme->dpr);
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "RT - WM_RequestSync" << exposedWindow;
- pendingUpdate |= SyncRequest;
- if (wme->syncInExpose) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestSync - triggered from expose");
- pendingUpdate |= ExposeRequest;
- }
- if (wme->forceRenderPass) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_RequestSync - repaint regardless");
- pendingUpdate |= RepaintRequest;
- }
- return true;
- }
-
- case WM_TryRelease: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease");
- mutex.lock();
- renderLoop->lockedForSync = true;
- QSGD3D12TryReleaseEvent *wme = static_cast<QSGD3D12TryReleaseEvent *>(e);
- // Only when no windows are exposed anymore or we are shutting down.
- if (!exposedWindow || wme->destroying) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease - invalidating rc");
- if (wme->window) {
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window);
- if (wme->destroying) {
- // QSGNode destruction may release graphics resources in use so wait first.
- engine->waitGPU();
- // Bye bye nodes...
- wd->cleanupNodesOnShutdown();
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
- }
- rc->invalidate();
- QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
- if (wme->destroying)
- wd->animationController.reset();
- }
- if (wme->destroying)
- active = false;
- if (sleeping)
- stopEventProcessing = true;
- } else {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_TryRelease - not releasing because window is still active");
- }
- waitCondition.wakeOne();
- renderLoop->lockedForSync = false;
- mutex.unlock();
- return true;
- }
-
- case WM_Grab: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Grab");
- QSGD3D12GrabEvent *wme = static_cast<QSGD3D12GrabEvent *>(e);
- Q_ASSERT(wme->window);
- Q_ASSERT(wme->window == exposedWindow || !exposedWindow);
- mutex.lock();
- if (wme->window) {
- // Grabbing is generally done by rendering a frame and reading the
- // color buffer contents back, without presenting, and then
- // creating a QImage from the returned data. It is terribly
- // inefficient since it involves a full blocking wait for the GPU.
- // However, our hands are tied by the existing, synchronous APIs of
- // QQuickWindow and such.
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window);
- rc->initialize(nullptr);
- wd->syncSceneGraph();
- rc->endSync();
- wd->renderSceneGraph(wme->window->size());
- *wme->image = engine->executeAndWaitReadbackRenderTarget();
- }
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_Grab - waking gui to handle result");
- waitCondition.wakeOne();
- mutex.unlock();
- return true;
- }
-
- case WM_PostJob: {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_PostJob");
- QSGD3D12JobEvent *wme = static_cast<QSGD3D12JobEvent *>(e);
- Q_ASSERT(wme->window == exposedWindow);
- if (exposedWindow) {
- wme->job->run();
- delete wme->job;
- wme->job = nullptr;
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - WM_PostJob - job done");
- }
- return true;
- }
-
- default:
- break;
- }
-
- return QThread::event(e);
-}
-
-void QSGD3D12RenderThread::postEvent(QEvent *e)
-{
- eventQueue.addEvent(e);
-}
-
-void QSGD3D12RenderThread::processEvents()
-{
- while (eventQueue.hasMoreEvents()) {
- QEvent *e = eventQueue.takeEvent(false);
- event(e);
- delete e;
- }
-}
-
-void QSGD3D12RenderThread::processEventsAndWaitForMore()
-{
- stopEventProcessing = false;
- while (!stopEventProcessing) {
- QEvent *e = eventQueue.takeEvent(true);
- event(e);
- delete e;
- }
-}
-
-void QSGD3D12RenderThread::run()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - run()");
-
- engine = new QSGD3D12Engine;
- rc->setEngine(engine);
-
- rtAnim = rc->sceneGraphContext()->createAnimationDriver(nullptr);
- rtAnim->install();
-
- if (QQmlDebugConnector::service<QQmlProfilerService>())
- QQuickProfiler::registerAnimationCallback();
-
- while (active) {
- if (exposedWindow)
- syncAndRender();
-
- processEvents();
- QCoreApplication::processEvents();
-
- if (pendingUpdate == 0 || !exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - done drawing, sleep");
- sleeping = true;
- processEventsAndWaitForMore();
- sleeping = false;
- }
- }
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - run() exiting");
-
- delete rtAnim;
- rtAnim = nullptr;
-
- rc->moveToThread(renderLoop->thread());
- moveToThread(renderLoop->thread());
-
- rc->setEngine(nullptr);
- delete engine;
- engine = nullptr;
-}
-
-void QSGD3D12RenderThread::sync(bool inExpose)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync");
-
- mutex.lock();
- Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked");
-
- // Recover from device loss.
- if (!engine->hasResources()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync - device was lost, resetting scenegraph");
- QQuickWindowPrivate::get(exposedWindow)->cleanupNodesOnShutdown();
- QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache();
- rc->invalidate();
- }
-
- if (engine->window()) {
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
- bool hadRenderer = wd->renderer != nullptr;
- // If the scene graph was touched since the last sync() make sure it sends the
- // changed signal.
- if (wd->renderer)
- wd->renderer->clearChangedFlag();
-
- rc->initialize(nullptr);
- wd->syncSceneGraph();
- rc->endSync();
-
- if (!hadRenderer && wd->renderer) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - created renderer");
- syncResultedInChanges = true;
- connect(wd->renderer, &QSGRenderer::sceneGraphChanged, this,
- &QSGD3D12RenderThread::onSceneGraphChanged, Qt::DirectConnection);
- }
-
- // Process deferred deletes now, directly after the sync as deleteLater
- // on the GUI must now also have resulted in SG changes and the delete
- // is a safe operation.
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
- }
-
- if (!inExpose) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - sync complete, waking gui");
- waitCondition.wakeOne();
- mutex.unlock();
- }
-}
-
-void QSGD3D12RenderThread::syncAndRender()
-{
- Q_TRACE_SCOPE(QSG_syncAndRender);
- if (Q_UNLIKELY(debug_time())) {
- sinceLastTime = threadTimer.nsecsElapsed();
- threadTimer.start();
- }
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
- Q_TRACE(QSG_sync_entry);
-
- QElapsedTimer waitTimer;
- waitTimer.start();
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - syncAndRender()");
-
- syncResultedInChanges = false;
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
-
- const bool repaintRequested = (pendingUpdate & RepaintRequest) || wd->customRenderStage;
- const bool syncRequested = pendingUpdate & SyncRequest;
- const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;
- pendingUpdate = 0;
-
- if (syncRequested)
- sync(exposeRequested);
-
-#ifndef QSG_NO_RENDER_TIMING
- if (Q_UNLIKELY(debug_time()))
- syncTime = threadTimer.nsecsElapsed();
-#endif
- Q_TRACE(QSG_sync_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSync);
-
- if (!syncResultedInChanges && !repaintRequested) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
- Q_TRACE(QSG_render_entry);
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - rendering started");
-
- if (rtAnim->isRunning()) {
- wd->animationController->lock();
- rtAnim->advance();
- wd->animationController->unlock();
- }
-
- bool canRender = wd->renderer != nullptr;
- // Recover from device loss.
- if (!engine->hasResources()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - syncAndRender - device was lost, posting FullUpdateRequest");
- // Cannot do anything here because gui is not locked. Request a new
- // sync+render round on the gui thread and let the sync handle it.
- QCoreApplication::postEvent(exposedWindow, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)));
- canRender = false;
- }
-
- if (canRender) {
- wd->renderSceneGraph(engine->windowSize());
- if (Q_UNLIKELY(debug_time()))
- renderTime = threadTimer.nsecsElapsed();
- Q_TRACE(QSG_render_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopRender);
- Q_TRACE(QSG_swap_entry);
-
- // The engine is able to have multiple frames in flight. This in effect is
- // similar to BufferQueueingOpenGL. Provide an env var to force the
- // traditional blocking swap behavior, just in case.
- static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0;
-
- if (!wd->customRenderStage || !wd->customRenderStage->swap())
- engine->present();
-
- if (blockOnEachFrame)
- engine->waitGPU();
-
- // The concept of "frame swaps" is quite misleading by default, when
- // blockOnEachFrame is not used, but emit it for compatibility.
- wd->fireFrameSwapped();
- } else {
- Q_TRACE(QSG_render_exit);
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSync, 1);
- Q_TRACE(QSG_swap_entry);
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - window not ready, skipping render");
- }
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - rendering done");
-
- if (exposeRequested) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("RT - wake gui after initial expose");
- waitCondition.wakeOne();
- mutex.unlock();
- }
-
- if (Q_UNLIKELY(debug_time()))
- qDebug("Frame rendered with 'd3d12' renderloop in %dms, sync=%d, render=%d, swap=%d - (on render thread)",
- int(threadTimer.elapsed()),
- int((syncTime/1000000)),
- int((renderTime - syncTime) / 1000000),
- int(threadTimer.elapsed() - renderTime / 1000000));
-
- Q_TRACE(QSG_swap_exit);
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSwap);
-
- static int devLossTest = qEnvironmentVariableIntValue("QT_D3D_TEST_DEVICE_LOSS");
- if (devLossTest > 0) {
- static QElapsedTimer kt;
- static bool timerRunning = false;
- if (!timerRunning) {
- kt.start();
- timerRunning = true;
- } else if (kt.elapsed() > 5000) {
- --devLossTest;
- kt.restart();
- engine->simulateDeviceLoss();
- }
- }
-}
-
-template<class T> T *windowFor(const QVector<T> &list, QQuickWindow *window)
-{
- for (const T &t : list) {
- if (t.window == window)
- return const_cast<T *>(&t);
- }
- return nullptr;
-}
-
-QSGD3D12ThreadedRenderLoop::QSGD3D12ThreadedRenderLoop()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("d3d12 THREADED render loop ctor");
-
- sg = new QSGD3D12Context;
-
- anim = sg->createAnimationDriver(this);
- connect(anim, &QAnimationDriver::started, this, &QSGD3D12ThreadedRenderLoop::onAnimationStarted);
- connect(anim, &QAnimationDriver::stopped, this, &QSGD3D12ThreadedRenderLoop::onAnimationStopped);
- anim->install();
-}
-
-QSGD3D12ThreadedRenderLoop::~QSGD3D12ThreadedRenderLoop()
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug("d3d12 THREADED render loop dtor");
-
- delete sg;
-}
-
-void QSGD3D12ThreadedRenderLoop::show(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "show" << window;
-}
-
-void QSGD3D12ThreadedRenderLoop::hide(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "hide" << window;
-
- if (window->isExposed())
- handleObscurity(windowFor(windows, window));
-
- releaseResources(window);
-}
-
-void QSGD3D12ThreadedRenderLoop::resize(QQuickWindow *window)
-{
- if (!window->isExposed() || window->size().isEmpty())
- return;
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "resize" << window << window->size();
-}
-
-void QSGD3D12ThreadedRenderLoop::windowDestroyed(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "window destroyed" << window;
-
- WindowData *w = windowFor(windows, window);
- if (!w)
- return;
-
- handleObscurity(w);
- handleResourceRelease(w, true);
-
- QSGD3D12RenderThread *thread = w->thread;
- while (thread->isRunning())
- QThread::yieldCurrentThread();
-
- Q_ASSERT(thread->thread() == QThread::currentThread());
- delete thread;
-
- for (int i = 0; i < windows.size(); ++i) {
- if (windows.at(i).window == window) {
- windows.removeAt(i);
- break;
- }
- }
-
- // Now that we altered the window list, we may need to stop the animation
- // timer even if we didn't via handleObscurity. This covers the case where
- // we destroy a visible & exposed QQuickWindow.
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12ThreadedRenderLoop::exposureChanged(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "exposure changed" << window;
-
- if (window->isExposed()) {
- handleExposure(window);
- } else {
- WindowData *w = windowFor(windows, window);
- if (w)
- handleObscurity(w);
- }
-}
-
-QImage QSGD3D12ThreadedRenderLoop::grab(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "grab" << window;
-
- WindowData *w = windowFor(windows, window);
- // Have to support invisible (but created()'ed) windows as well.
- // Unlike with GL, leaving that case for QQuickWindow to handle is not feasible.
- const bool tempExpose = !w;
- if (tempExpose) {
- handleExposure(window);
- w = windowFor(windows, window);
- Q_ASSERT(w);
- }
-
- if (!w->thread->isRunning())
- return QImage();
-
- if (!window->handle())
- window->create();
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->polishItems();
-
- QImage result;
- w->thread->mutex.lock();
- lockedForSync = true;
- w->thread->postEvent(new QSGD3D12GrabEvent(window, &result));
- w->thread->waitCondition.wait(&w->thread->mutex);
- lockedForSync = false;
- w->thread->mutex.unlock();
-
- result.setDevicePixelRatio(window->effectiveDevicePixelRatio());
-
- if (tempExpose)
- handleObscurity(w);
-
- return result;
-}
-
-void QSGD3D12ThreadedRenderLoop::update(QQuickWindow *window)
-{
- WindowData *w = windowFor(windows, window);
- if (!w)
- return;
-
- if (w->thread == QThread::currentThread()) {
- w->thread->requestRepaint();
- return;
- }
-
- // We set forceRenderPass because we want to make sure the QQuickWindow
- // actually does a full render pass after the next sync.
- w->forceRenderPass = true;
- scheduleUpdate(w);
-}
-
-void QSGD3D12ThreadedRenderLoop::maybeUpdate(QQuickWindow *window)
-{
- WindowData *w = windowFor(windows, window);
- if (w)
- scheduleUpdate(w);
-}
-
-// called in response to window->requestUpdate()
-void QSGD3D12ThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleUpdateRequest" << window;
-
- WindowData *w = windowFor(windows, window);
- if (w)
- polishAndSync(w, false);
-}
-
-QAnimationDriver *QSGD3D12ThreadedRenderLoop::animationDriver() const
-{
- return anim;
-}
-
-QSGContext *QSGD3D12ThreadedRenderLoop::sceneGraphContext() const
-{
- return sg;
-}
-
-QSGRenderContext *QSGD3D12ThreadedRenderLoop::createRenderContext(QSGContext *) const
-{
- return sg->createRenderContext();
-}
-
-void QSGD3D12ThreadedRenderLoop::releaseResources(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "releaseResources" << window;
-
- WindowData *w = windowFor(windows, window);
- if (w)
- handleResourceRelease(w, false);
-}
-
-void QSGD3D12ThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job)
-{
- WindowData *w = windowFor(windows, window);
- if (w && w->thread && w->thread->exposedWindow)
- w->thread->postEvent(new QSGD3D12JobEvent(window, job));
- else
- delete job;
-}
-
-QSurface::SurfaceType QSGD3D12ThreadedRenderLoop::windowSurfaceType() const
-{
- return QSurface::OpenGLSurface;
-}
-
-bool QSGD3D12ThreadedRenderLoop::interleaveIncubation() const
-{
- bool somethingVisible = false;
- for (const WindowData &w : windows) {
- if (w.window->isVisible() && w.window->isExposed()) {
- somethingVisible = true;
- break;
- }
- }
- return somethingVisible && anim->isRunning();
-}
-
-int QSGD3D12ThreadedRenderLoop::flags() const
-{
- return SupportsGrabWithoutExpose;
-}
-
-bool QSGD3D12ThreadedRenderLoop::event(QEvent *e)
-{
- if (e->type() == QEvent::Timer) {
- QTimerEvent *te = static_cast<QTimerEvent *>(e);
- if (te->timerId() == animationTimer) {
- anim->advance();
- emit timeToIncubate();
- return true;
- }
- }
-
- return QObject::event(e);
-}
-
-void QSGD3D12ThreadedRenderLoop::onAnimationStarted()
-{
- startOrStopAnimationTimer();
-
- for (const WindowData &w : qAsConst(windows))
- w.window->requestUpdate();
-}
-
-void QSGD3D12ThreadedRenderLoop::onAnimationStopped()
-{
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12ThreadedRenderLoop::startOrStopAnimationTimer()
-{
- int exposedWindowCount = 0;
- const WindowData *exposed = nullptr;
-
- for (int i = 0; i < windows.size(); ++i) {
- const WindowData &w(windows[i]);
- if (w.window->isVisible() && w.window->isExposed()) {
- ++exposedWindowCount;
- exposed = &w;
- }
- }
-
- if (animationTimer && (exposedWindowCount == 1 || !anim->isRunning())) {
- killTimer(animationTimer);
- animationTimer = 0;
- // If animations are running, make sure we keep on animating
- if (anim->isRunning())
- exposed->window->requestUpdate();
- } else if (!animationTimer && exposedWindowCount != 1 && anim->isRunning()) {
- animationTimer = startTimer(qsgrl_animation_interval());
- }
-}
-
-void QSGD3D12ThreadedRenderLoop::handleExposure(QQuickWindow *window)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleExposure" << window;
-
- WindowData *w = windowFor(windows, window);
- if (!w) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("adding window to list");
- WindowData win;
- win.window = window;
- QSGRenderContext *rc = QQuickWindowPrivate::get(window)->context; // will transfer ownership
- win.thread = new QSGD3D12RenderThread(this, rc);
- win.updateDuringSync = false;
- win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt
- windows.append(win);
- w = &windows.last();
- }
-
- // set this early as we'll be rendering shortly anyway and this avoids
- // special casing exposure in polishAndSync.
- w->thread->exposedWindow = window;
-
- if (w->window->size().isEmpty()
- || (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) {
-#ifndef QT_NO_DEBUG
- qWarning().noquote().nospace() << "QSGD3D12ThreadedRenderLoop: expose event received for window "
- << w->window << " with invalid geometry: " << w->window->geometry()
- << " on " << w->window->screen();
-#endif
- }
-
- if (!w->window->handle())
- w->window->create();
-
- // Start render thread if it is not running
- if (!w->thread->isRunning()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("starting render thread");
- // Push a few things to the render thread.
- QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController.data();
- if (controller->thread() != w->thread)
- controller->moveToThread(w->thread);
- if (w->thread->thread() == QThread::currentThread()) {
- w->thread->rc->moveToThread(w->thread);
- w->thread->moveToThread(w->thread);
- }
-
- w->thread->active = true;
- w->thread->start();
-
- if (!w->thread->isRunning())
- qFatal("Render thread failed to start, aborting application.");
- }
-
- polishAndSync(w, true);
-
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12ThreadedRenderLoop::handleObscurity(WindowData *w)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleObscurity" << w->window;
-
- if (w->thread->isRunning()) {
- w->thread->mutex.lock();
- w->thread->postEvent(new QSGD3D12WindowEvent(w->window, WM_Obscure));
- w->thread->waitCondition.wait(&w->thread->mutex);
- w->thread->mutex.unlock();
- }
-
- startOrStopAnimationTimer();
-}
-
-void QSGD3D12ThreadedRenderLoop::scheduleUpdate(WindowData *w)
-{
- if (!QCoreApplication::instance())
- return;
-
- if (!w || !w->thread->isRunning())
- return;
-
- QThread *current = QThread::currentThread();
- if (current != QCoreApplication::instance()->thread() && (current != w->thread || !lockedForSync)) {
- qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()";
- return;
- }
-
- if (current == w->thread) {
- w->updateDuringSync = true;
- return;
- }
-
- w->window->requestUpdate();
-}
-
-void QSGD3D12ThreadedRenderLoop::handleResourceRelease(WindowData *w, bool destroying)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window;
-
- w->thread->mutex.lock();
- if (w->thread->isRunning() && w->thread->active) {
- QQuickWindow *window = w->window;
-
- // Note that window->handle() is typically null by this time because
- // the platform window is already destroyed. This should not be a
- // problem for the D3D cleanup.
-
- w->thread->postEvent(new QSGD3D12TryReleaseEvent(window, destroying));
- w->thread->waitCondition.wait(&w->thread->mutex);
-
- // Avoid a shutdown race condition.
- // If SG is invalidated and 'active' becomes false, the thread's run()
- // method will exit. handleExposure() relies on QThread::isRunning() (because it
- // potentially needs to start the thread again) and our mutex cannot be used to
- // track the thread stopping, so we wait a few nanoseconds extra so the thread
- // can exit properly.
- if (!w->thread->active)
- w->thread->wait();
- }
- w->thread->mutex.unlock();
-}
-
-void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
-{
- if (Q_UNLIKELY(debug_loop()))
- qDebug() << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window;
-
- QQuickWindow *window = w->window;
- if (!w->thread || !w->thread->exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - not exposed, abort");
- return;
- }
-
- Q_TRACE_SCOPE(QSG_polishAndSync);
-
- // Flush pending touch events.
- QQuickWindowPrivate::get(window)->flushFrameSynchronousEvents();
- // The delivery of the event might have caused the window to stop rendering
- w = windowFor(windows, window);
- if (!w || !w->thread || !w->thread->exposedWindow) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - removed after touch event flushing, abort");
- return;
- }
-
- QElapsedTimer timer;
- qint64 polishTime = 0;
- qint64 waitTime = 0;
- qint64 syncTime = 0;
- if (Q_UNLIKELY(debug_time()))
- timer.start();
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
- Q_TRACE(QSG_polishItems_entry);
-
- QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
- wd->polishItems();
-
- if (Q_UNLIKELY(debug_time()))
- polishTime = timer.nsecsElapsed();
- Q_TRACE(QSG_polishItems_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
- QQuickProfiler::SceneGraphPolishAndSyncPolish);
- Q_TRACE(QSG_wait_entry);
-
- w->updateDuringSync = false;
-
- emit window->afterAnimating();
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - lock for sync");
- w->thread->mutex.lock();
- lockedForSync = true;
- w->thread->postEvent(new QSGD3D12SyncEvent(window, inExpose, w->forceRenderPass));
- w->forceRenderPass = false;
-
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - wait for sync");
- if (Q_UNLIKELY(debug_time()))
- waitTime = timer.nsecsElapsed();
- Q_TRACE(QSG_wait_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
- QQuickProfiler::SceneGraphPolishAndSyncWait);
- Q_TRACE(QSG_sync_entry);
-
- w->thread->waitCondition.wait(&w->thread->mutex);
- lockedForSync = false;
- w->thread->mutex.unlock();
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - unlock after sync");
-
- if (Q_UNLIKELY(debug_time()))
- syncTime = timer.nsecsElapsed();
- Q_TRACE(QSG_sync_exit);
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
- QQuickProfiler::SceneGraphPolishAndSyncSync);
- Q_TRACE(QSG_animations_entry);
-
- if (!animationTimer && anim->isRunning()) {
- if (Q_UNLIKELY(debug_loop()))
- qDebug("polishAndSync - advancing animations");
- anim->advance();
- // We need to trigger another sync to keep animations running...
- w->window->requestUpdate();
- emit timeToIncubate();
- } else if (w->updateDuringSync) {
- w->window->requestUpdate();
- }
-
- if (Q_UNLIKELY(debug_time()))
- qDebug().nospace()
- << "Frame prepared with 'd3d12' renderloop"
- << ", polish=" << (polishTime / 1000000)
- << ", lock=" << (waitTime - polishTime) / 1000000
- << ", blockedForSync=" << (syncTime - waitTime) / 1000000
- << ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
- << " - (on gui thread) " << window;
-
- Q_TRACE(QSG_animations_exit);
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
- QQuickProfiler::SceneGraphPolishAndSyncAnimations);
-}
-
-#include "qsgd3d12threadedrenderloop.moc"
-
-QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h
deleted file mode 100644
index 46f62948f1..0000000000
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGD3D12THREADEDRENDERLOOP_P_H
-#define QSGD3D12THREADEDRENDERLOOP_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 <private/qsgrenderloop_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGD3D12Engine;
-class QSGD3D12Context;
-class QSGD3D12RenderContext;
-class QSGD3D12RenderThread;
-
-class QSGD3D12ThreadedRenderLoop : public QSGRenderLoop
-{
- Q_OBJECT
-
-public:
- QSGD3D12ThreadedRenderLoop();
- ~QSGD3D12ThreadedRenderLoop();
-
- void show(QQuickWindow *window) override;
- void hide(QQuickWindow *window) override;
- void resize(QQuickWindow *window) override;
-
- void windowDestroyed(QQuickWindow *window) override;
-
- void exposureChanged(QQuickWindow *window) override;
-
- QImage grab(QQuickWindow *window) override;
-
- void update(QQuickWindow *window) override;
- void maybeUpdate(QQuickWindow *window) override;
- void handleUpdateRequest(QQuickWindow *window) override;
-
- QAnimationDriver *animationDriver() const override;
-
- QSGContext *sceneGraphContext() const override;
- QSGRenderContext *createRenderContext(QSGContext *) const override;
-
- void releaseResources(QQuickWindow *window) override;
- void postJob(QQuickWindow *window, QRunnable *job) override;
-
- QSurface::SurfaceType windowSurfaceType() const override;
- bool interleaveIncubation() const override;
- int flags() const override;
-
- bool event(QEvent *e) override;
-
-public Q_SLOTS:
- void onAnimationStarted();
- void onAnimationStopped();
-
-private:
- struct WindowData {
- QQuickWindow *window;
- QSGD3D12RenderThread *thread;
- uint updateDuringSync : 1;
- uint forceRenderPass : 1;
- };
-
- void startOrStopAnimationTimer();
- void handleExposure(QQuickWindow *window);
- void handleObscurity(WindowData *w);
- void scheduleUpdate(WindowData *w);
- void handleResourceRelease(WindowData *w, bool destroying);
- void polishAndSync(WindowData *w, bool inExpose);
-
- QSGD3D12Context *sg;
- QAnimationDriver *anim;
- int animationTimer = 0;
- bool lockedForSync = false;
- QVector<WindowData> windows;
-
- friend class QSGD3D12RenderThread;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGD3D12THREADEDRENDERLOOP_P_H
diff --git a/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl
deleted file mode 100644
index 034b51435a..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl
+++ /dev/null
@@ -1,27 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float4 color;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
-};
-
-PSInput VS_FlatColor(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, input.position);
- return result;
-}
-
-float4 PS_FlatColor(PSInput input) : SV_TARGET
-{
- return color;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl b/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl
deleted file mode 100644
index 6793b534b0..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl
+++ /dev/null
@@ -1,60 +0,0 @@
-static const uint GROUP_DIM = 8; // 2 ^ (out_mip_count - 1)
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-cbuffer ConstantBuffer : register(b0)
-{
- uint2 mip1Size;
- uint sampleLevel;
- uint totalMips;
-}
-
-RWTexture2D<float4> mip1 : register(u0);
-RWTexture2D<float4> mip2 : register(u1);
-RWTexture2D<float4> mip3 : register(u2);
-RWTexture2D<float4> mip4 : register(u3);
-
-groupshared float4 groupColor[GROUP_DIM][GROUP_DIM];
-
-[numthreads(GROUP_DIM, GROUP_DIM, 1)]
-void CS_Generate4MipMaps(uint3 localId: SV_GroupThreadId, uint3 globalId: SV_DispatchThreadID)
-{
- const float2 coord = float2(1.0f / float(mip1Size.x), 1.0f / float(mip1Size.y)) * (globalId.xy + 0.5);
- float4 c = tex.SampleLevel(samp, coord, sampleLevel);
-
- mip1[globalId.xy] = c;
- groupColor[localId.y][localId.x] = c;
-
- if (sampleLevel + 1 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 1) == 0 && (localId.y & 1) == 0) {
- c = (c + groupColor[localId.y][localId.x + 1] + groupColor[localId.y + 1][localId.x] + groupColor[localId.y + 1][localId.x + 1]) / 4.0;
- mip2[globalId.xy / 2] = c;
- groupColor[localId.y][localId.x] = c;
- }
-
- if (sampleLevel + 2 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 3) == 0 && (localId.y & 3) == 0) {
- c = (c + groupColor[localId.y][localId.x + 2] + groupColor[localId.y + 2][localId.x] + groupColor[localId.y + 2][localId.x + 2]) / 4.0;
- mip3[globalId.xy / 4] = c;
- groupColor[localId.y][localId.x] = c;
- }
-
- if (sampleLevel + 3 >= totalMips)
- return;
-
- GroupMemoryBarrierWithGroupSync();
-
- if ((localId.x & 7) == 0 && (localId.y & 7) == 0) {
- c = (c + groupColor[localId.y][localId.x + 3] + groupColor[localId.y + 3][localId.x] + groupColor[localId.y + 3][localId.x + 3]) / 4.0;
- mip4[globalId.xy / 8] = c;
- }
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl b/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl
deleted file mode 100644
index 94672d6267..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl
+++ /dev/null
@@ -1,27 +0,0 @@
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 qt_Matrix;
- float qt_Opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
-};
-
-Texture2D source : register(t0);
-SamplerState sourceSampler : register(s0);
-
-PSInput VS_DefaultShaderEffect(float4 position : POSITION, float2 coord : TEXCOORD0)
-{
- PSInput result;
- result.position = mul(qt_Matrix, position);
- result.coord = coord;
- return result;
-}
-
-float4 PS_DefaultShaderEffect(PSInput input) : SV_TARGET
-{
- return source.Sample(sourceSampler, input.coord) * qt_Opacity;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/shaders.pri b/src/plugins/scenegraph/d3d12/shaders/shaders.pri
deleted file mode 100644
index 963f4c5d8c..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/shaders.pri
+++ /dev/null
@@ -1,141 +0,0 @@
-vertexcolor_VSPS = $$PWD/vertexcolor.hlsl
-vertexcolor_vshader.input = vertexcolor_VSPS
-vertexcolor_vshader.header = vs_vertexcolor.hlslh
-vertexcolor_vshader.entry = VS_VertexColor
-vertexcolor_vshader.type = vs_5_0
-vertexcolor_pshader.input = vertexcolor_VSPS
-vertexcolor_pshader.header = ps_vertexcolor.hlslh
-vertexcolor_pshader.entry = PS_VertexColor
-vertexcolor_pshader.type = ps_5_0
-
-flatcolor_VSPS = $$PWD/flatcolor.hlsl
-flatcolor_vshader.input = flatcolor_VSPS
-flatcolor_vshader.header = vs_flatcolor.hlslh
-flatcolor_vshader.entry = VS_FlatColor
-flatcolor_vshader.type = vs_5_0
-flatcolor_pshader.input = flatcolor_VSPS
-flatcolor_pshader.header = ps_flatcolor.hlslh
-flatcolor_pshader.entry = PS_FlatColor
-flatcolor_pshader.type = ps_5_0
-
-stencilclip_VSPS = $$PWD/stencilclip.hlsl
-stencilclip_vshader.input = stencilclip_VSPS
-stencilclip_vshader.header = vs_stencilclip.hlslh
-stencilclip_vshader.entry = VS_StencilClip
-stencilclip_vshader.type = vs_5_0
-stencilclip_pshader.input = stencilclip_VSPS
-stencilclip_pshader.header = ps_stencilclip.hlslh
-stencilclip_pshader.entry = PS_StencilClip
-stencilclip_pshader.type = ps_5_0
-
-smoothcolor_VSPS = $$PWD/smoothcolor.hlsl
-smoothcolor_vshader.input = smoothcolor_VSPS
-smoothcolor_vshader.header = vs_smoothcolor.hlslh
-smoothcolor_vshader.entry = VS_SmoothColor
-smoothcolor_vshader.type = vs_5_0
-smoothcolor_pshader.input = smoothcolor_VSPS
-smoothcolor_pshader.header = ps_smoothcolor.hlslh
-smoothcolor_pshader.entry = PS_SmoothColor
-smoothcolor_pshader.type = ps_5_0
-
-texture_VSPS = $$PWD/texture.hlsl
-texture_vshader.input = texture_VSPS
-texture_vshader.header = vs_texture.hlslh
-texture_vshader.entry = VS_Texture
-texture_vshader.type = vs_5_0
-texture_pshader.input = texture_VSPS
-texture_pshader.header = ps_texture.hlslh
-texture_pshader.entry = PS_Texture
-texture_pshader.type = ps_5_0
-
-smoothtexture_VSPS = $$PWD/smoothtexture.hlsl
-smoothtexture_vshader.input = smoothtexture_VSPS
-smoothtexture_vshader.header = vs_smoothtexture.hlslh
-smoothtexture_vshader.entry = VS_SmoothTexture
-smoothtexture_vshader.type = vs_5_0
-smoothtexture_pshader.input = smoothtexture_VSPS
-smoothtexture_pshader.header = ps_smoothtexture.hlslh
-smoothtexture_pshader.entry = PS_SmoothTexture
-smoothtexture_pshader.type = ps_5_0
-
-mipmapgen_CS = $$PWD/mipmapgen.hlsl
-mipmapgen_cshader.input = mipmapgen_CS
-mipmapgen_cshader.header = cs_mipmapgen.hlslh
-mipmapgen_cshader.entry = CS_Generate4MipMaps
-mipmapgen_cshader.type = cs_5_0
-
-textmask_VSPS = $$PWD/textmask.hlsl
-textmask_vshader.input = textmask_VSPS
-textmask_vshader.header = vs_textmask.hlslh
-textmask_vshader.entry = VS_TextMask
-textmask_vshader.type = vs_5_0
-textmask_pshader24.input = textmask_VSPS
-textmask_pshader24.header = ps_textmask24.hlslh
-textmask_pshader24.entry = PS_TextMask24
-textmask_pshader24.type = ps_5_0
-textmask_pshader32.input = textmask_VSPS
-textmask_pshader32.header = ps_textmask32.hlslh
-textmask_pshader32.entry = PS_TextMask32
-textmask_pshader32.type = ps_5_0
-textmask_pshader8.input = textmask_VSPS
-textmask_pshader8.header = ps_textmask8.hlslh
-textmask_pshader8.entry = PS_TextMask8
-textmask_pshader8.type = ps_5_0
-styledtext_vshader.input = textmask_VSPS
-styledtext_vshader.header = vs_styledtext.hlslh
-styledtext_vshader.entry = VS_StyledText
-styledtext_vshader.type = vs_5_0
-styledtext_pshader.input = textmask_VSPS
-styledtext_pshader.header = ps_styledtext.hlslh
-styledtext_pshader.entry = PS_StyledText
-styledtext_pshader.type = ps_5_0
-outlinedtext_vshader.input = textmask_VSPS
-outlinedtext_vshader.header = vs_outlinedtext.hlslh
-outlinedtext_vshader.entry = VS_OutlinedText
-outlinedtext_vshader.type = vs_5_0
-outlinedtext_pshader.input = textmask_VSPS
-outlinedtext_pshader.header = ps_outlinedtext.hlslh
-outlinedtext_pshader.entry = PS_OutlinedText
-outlinedtext_pshader.type = ps_5_0
-
-shadereffectdefault_VSPS = $$PWD/shadereffectdefault.hlsl
-shadereffectdefault_vshader.input = shadereffectdefault_VSPS
-shadereffectdefault_vshader.header = vs_shadereffectdefault.hlslh
-shadereffectdefault_vshader.entry = VS_DefaultShaderEffect
-shadereffectdefault_vshader.type = vs_5_0
-shadereffectdefault_pshader.input = shadereffectdefault_VSPS
-shadereffectdefault_pshader.header = ps_shadereffectdefault.hlslh
-shadereffectdefault_pshader.entry = PS_DefaultShaderEffect
-shadereffectdefault_pshader.type = ps_5_0
-
-sprite_VSPS = $$PWD/sprite.hlsl
-sprite_vshader.input = sprite_VSPS
-sprite_vshader.header = vs_sprite.hlslh
-sprite_vshader.entry = VS_Sprite
-sprite_vshader.type = vs_5_0
-sprite_pshader.input = sprite_VSPS
-sprite_pshader.header = ps_sprite.hlslh
-sprite_pshader.entry = PS_Sprite
-sprite_pshader.type = ps_5_0
-
-tdr_CS = $$PWD/tdr.hlsl
-tdr_cshader.input = tdr_CS
-tdr_cshader.header = cs_tdr.hlslh
-tdr_cshader.entry = timeout
-tdr_cshader.type = cs_5_0
-
-HLSL_SHADERS = \
- vertexcolor_vshader vertexcolor_pshader \
- flatcolor_vshader flatcolor_pshader \
- stencilclip_vshader stencilclip_pshader \
- smoothcolor_vshader smoothcolor_pshader \
- texture_vshader texture_pshader \
- smoothtexture_vshader smoothtexture_pshader \
- mipmapgen_cshader \
- textmask_vshader textmask_pshader24 textmask_pshader32 textmask_pshader8 \
- styledtext_vshader styledtext_pshader outlinedtext_vshader outlinedtext_pshader \
- shadereffectdefault_vshader shadereffectdefault_pshader \
- sprite_vshader sprite_pshader \
- tdr_cshader
-
-load(hlsl_bytecode_header)
diff --git a/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl
deleted file mode 100644
index 4f69eea60f..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl
+++ /dev/null
@@ -1,64 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float4 color : COLOR;
- float2 offset : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
- float2 pixelSize;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float4 color : COLOR;
-};
-
-PSInput VS_SmoothColor(VSInput input)
-{
- PSInput result;
-
- float4 pos = mul(mvp, input.position);
-
- if (input.offset.x != 0.0) {
- // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL).
- float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x;
- float2 dir = delta.xy * pos.w - pos.xy * delta.w;
- float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
- dir -= ndir * delta.w * pos.w;
- float numerator = dot(dir, ndir * pos.w * pos.w);
- float scale = 0.0;
- if (numerator < 0.0)
- scale = 1.0;
- else
- scale = min(1.0, numerator / dot(dir, dir));
- pos += scale * delta;
- }
-
- if (input.offset.y != 0.0) {
- float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y;
- float2 dir = delta.xy * pos.w - pos.xy * delta.w;
- float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
- dir -= ndir * delta.w * pos.w;
- float numerator = dot(dir, ndir * pos.w * pos.w);
- float scale = 0.0;
- if (numerator < 0.0)
- scale = 1.0;
- else
- scale = min(1.0, numerator / dot(dir, dir));
- pos += scale * delta;
- }
-
- result.position = pos;
- result.color = input.color * opacity;
- return result;
-}
-
-float4 PS_SmoothColor(PSInput input) : SV_TARGET
-{
- return input.color;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl b/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl
deleted file mode 100644
index 05b1c6e9d4..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl
+++ /dev/null
@@ -1,77 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
- float2 offset : TEXCOORD1;
- float2 coordOffset : TEXCOORD2;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
- float2 pixelSize;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float vertexOpacity : TEXCOORD3;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_SmoothTexture(VSInput input)
-{
- PSInput result;
-
- float4 pos = mul(mvp, input.position);
- float2 coord = input.coord;
-
- if (input.offset.x != 0.0) {
- // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL).
- float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x;
- float2 dir = delta.xy * pos.w - pos.xy * delta.w;
- float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
- dir -= ndir * delta.w * pos.w;
- float numerator = dot(dir, ndir * pos.w * pos.w);
- float scale = 0.0;
- if (numerator < 0.0)
- scale = 1.0;
- else
- scale = min(1.0, numerator / dot(dir, dir));
- pos += scale * delta;
- coord.x += scale * input.coordOffset.x;
- }
-
- if (input.offset.y != 0.0) {
- float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y;
- float2 dir = delta.xy * pos.w - pos.xy * delta.w;
- float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
- dir -= ndir * delta.w * pos.w;
- float numerator = dot(dir, ndir * pos.w * pos.w);
- float scale = 0.0;
- if (numerator < 0.0)
- scale = 1.0;
- else
- scale = min(1.0, numerator / dot(dir, dir));
- pos += scale * delta;
- coord.y += scale * input.coordOffset.y;
- }
-
- if ((input.offset.x != 0.0 || input.offset.y != 0.0) && (input.coordOffset.x == 0.0 && input.coordOffset.y == 0.0))
- result.vertexOpacity = 0.0;
- else
- result.vertexOpacity = opacity;
-
- result.position = pos;
- result.coord = coord;
- return result;
-}
-
-float4 PS_SmoothTexture(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * input.vertexOpacity;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl b/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl
deleted file mode 100644
index d4e3b066ee..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl
+++ /dev/null
@@ -1,43 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float4 animPos;
- float3 animData;
- float opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float4 fTexS : TEXCOORD0;
- float progress : TEXCOORD1;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_Sprite(VSInput input)
-{
- PSInput result;
-
- result.position = mul(mvp, input.position);
- result.progress = animData.z;
-
- // Calculate frame location in texture
- result.fTexS.xy = animPos.xy + input.coord.xy * animData.xy;
- // Next frame is also passed, for interpolation
- result.fTexS.zw = animPos.zw + input.coord.xy * animData.xy;
-
- return result;
-}
-
-float4 PS_Sprite(PSInput input) : SV_TARGET
-{
- return lerp(tex.Sample(samp, input.fTexS.xy), tex.Sample(samp, input.fTexS.zw), input.progress) * opacity;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl b/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl
deleted file mode 100644
index 9aff84d261..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
-};
-
-PSInput VS_StencilClip(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, input.position);
- return result;
-}
-
-float4 PS_StencilClip(PSInput input) : SV_TARGET
-{
- return float4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw!
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl b/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl
deleted file mode 100644
index f32d4fbace..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl
+++ /dev/null
@@ -1,11 +0,0 @@
-// http://gamedev.stackexchange.com/questions/108141/how-can-i-test-dxgi-error-device-removed-error-handling
-
-RWBuffer<uint> uav;
-cbuffer ConstantBuffer { uint zero; }
-
-[numthreads(256, 1, 1)]
-void timeout(uint3 id: SV_DispatchThreadID)
-{
- while (zero == 0)
- uav[id.x] = zero;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl b/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl
deleted file mode 100644
index bb9381e7c0..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl
+++ /dev/null
@@ -1,104 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float2 textureScale;
- float dpr;
- float color; // for TextMask24 and 32
- float4 colorVec; // for TextMask8 and Styled and Outlined
- float2 shift; // for Styled
- float4 styleColor; // for Styled and Outlined
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_TextMask(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- return result;
-}
-
-float4 PS_TextMask24(PSInput input) : SV_TARGET
-{
- float4 glyph = tex.Sample(samp, input.coord);
- return float4(glyph.rgb * color, glyph.a);
-}
-
-float4 PS_TextMask32(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * color;
-}
-
-float4 PS_TextMask8(PSInput input) : SV_TARGET
-{
- return colorVec * tex.Sample(samp, input.coord).a;
-}
-
-struct StyledPSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float2 shiftedCoord : TEXCOORD1;
-};
-
-StyledPSInput VS_StyledText(VSInput input)
-{
- StyledPSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- result.shiftedCoord = (input.coord - shift) * textureScale;
- return result;
-}
-
-float4 PS_StyledText(StyledPSInput input) : SV_TARGET
-{
- float glyph = tex.Sample(samp, input.coord).a;
- float style = clamp(tex.Sample(samp, input.shiftedCoord).a - glyph, 0.0, 1.0);
- return style * styleColor + glyph * colorVec;
-}
-
-struct OutlinedPSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- float2 coordUp : TEXCOORD1;
- float2 coordDown : TEXCOORD2;
- float2 coordLeft : TEXCOORD3;
- float2 coordRight : TEXCOORD4;
-};
-
-OutlinedPSInput VS_OutlinedText(VSInput input)
-{
- OutlinedPSInput result;
- result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr);
- result.coord = input.coord * textureScale;
- result.coordUp = (input.coord - float2(0.0, -1.0)) * textureScale;
- result.coordDown = (input.coord - float2(0.0, 1.0)) * textureScale;
- result.coordLeft = (input.coord - float2(-1.0, 0.0)) * textureScale;
- result.coordRight = (input.coord - float2(1.0, 0.0)) * textureScale;
- return result;
-}
-
-float4 PS_OutlinedText(OutlinedPSInput input) : SV_TARGET
-{
- float glyph = tex.Sample(samp, input.coord).a;
- float outline = clamp(clamp(tex.Sample(samp, input.coordUp).a
- + tex.Sample(samp, input.coordDown).a
- + tex.Sample(samp, input.coordLeft).a
- + tex.Sample(samp, input.coordRight).a, 0.0, 1.0) - glyph, 0.0, 1.0);
- return outline * styleColor + glyph * colorVec;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/texture.hlsl b/src/plugins/scenegraph/d3d12/shaders/texture.hlsl
deleted file mode 100644
index 1ae6579e8d..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/texture.hlsl
+++ /dev/null
@@ -1,33 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float2 coord : TEXCOORD0;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
-};
-
-Texture2D tex : register(t0);
-SamplerState samp : register(s0);
-
-PSInput VS_Texture(VSInput input)
-{
- PSInput result;
- result.position = mul(mvp, input.position);
- result.coord = input.coord;
- return result;
-}
-
-float4 PS_Texture(PSInput input) : SV_TARGET
-{
- return tex.Sample(samp, input.coord) * opacity;
-}
diff --git a/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl
deleted file mode 100644
index a0569bb5c1..0000000000
--- a/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl
+++ /dev/null
@@ -1,32 +0,0 @@
-struct VSInput
-{
- float4 position : POSITION;
- float4 color : COLOR;
-};
-
-cbuffer ConstantBuffer : register(b0)
-{
- float4x4 mvp;
- float opacity;
-};
-
-struct PSInput
-{
- float4 position : SV_POSITION;
- float4 color : COLOR;
-};
-
-PSInput VS_VertexColor(VSInput input)
-{
- PSInput result;
-
- result.position = mul(mvp, input.position);
- result.color = input.color * opacity;
-
- return result;
-}
-
-float4 PS_VertexColor(PSInput input) : SV_TARGET
-{
- return input.color;
-}
diff --git a/src/plugins/scenegraph/openvg/CMakeLists.txt b/src/plugins/scenegraph/openvg/CMakeLists.txt
new file mode 100644
index 0000000000..3acfa066f4
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Generated from openvg.pro.
+
+#####################################################################
+## QSGOpenVGAdaptation Plugin:
+#####################################################################
+
+qt_add_plugin(QSGOpenVGAdaptation
+ OUTPUT_NAME qsgopenvgbackend
+ TYPE scenegraph
+ SOURCES
+ qopenvgcontext.cpp qopenvgcontext_p.h
+ qopenvgmatrix.cpp qopenvgmatrix.h
+ qopenvgoffscreensurface.cpp qopenvgoffscreensurface.h
+ qsgopenvgadaptation.cpp qsgopenvgadaptation_p.h
+ qsgopenvgcontext.cpp qsgopenvgcontext_p.h
+ qsgopenvgfontglyphcache.cpp qsgopenvgfontglyphcache.h
+ qsgopenvgglyphnode.cpp qsgopenvgglyphnode_p.h
+ qsgopenvghelpers.cpp qsgopenvghelpers.h
+ qsgopenvginternalimagenode.cpp qsgopenvginternalimagenode.h
+ qsgopenvginternalrectanglenode.cpp qsgopenvginternalrectanglenode.h
+ qsgopenvglayer.cpp qsgopenvglayer.h
+ qsgopenvgnodevisitor.cpp qsgopenvgnodevisitor.h
+ qsgopenvgpainternode.cpp qsgopenvgpainternode.h
+ qsgopenvgpublicnodes.cpp qsgopenvgpublicnodes.h
+ qsgopenvgrenderable.cpp qsgopenvgrenderable.h
+ qsgopenvgrenderer.cpp qsgopenvgrenderer_p.h
+ qsgopenvgrenderloop.cpp qsgopenvgrenderloop_p.h
+ qsgopenvgtexture.cpp qsgopenvgtexture.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+ openvg
+)
+
+#### Keys ignored in scope 1:.:.:openvg.pro:<TRUE>:
+# OTHER_FILES = "$$PWD/openvg.json"
+# QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
+# QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QSGOpenVGAdaptation CONDITION CMAKE_BUILD_TYPE STREQUAL Debug AND debug_and_release
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen/debug
+)
+
+qt_extend_target(QSGOpenVGAdaptation CONDITION debug_and_release AND NOT CMAKE_BUILD_TYPE STREQUAL Debug
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen/release
+)
+
+qt_extend_target(QSGOpenVGAdaptation CONDITION NOT debug_and_release
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen
+)
+
+qt_extend_target(QSGOpenVGAdaptation CONDITION QT_FEATURE_quick_sprite
+ SOURCES
+ qsgopenvgspritenode.cpp qsgopenvgspritenode.h
+)
diff --git a/src/plugins/scenegraph/scenegraph.pro b/src/plugins/scenegraph/scenegraph.pro
index 39c0c0815c..9cc521a191 100644
--- a/src/plugins/scenegraph/scenegraph.pro
+++ b/src/plugins/scenegraph/scenegraph.pro
@@ -1,5 +1,4 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += quick
-qtConfig(d3d12): SUBDIRS += d3d12
qtConfig(openvg): SUBDIRS += openvg
diff --git a/src/qml/.prev_CMakeLists.txt b/src/qml/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..90cb65a95c
--- /dev/null
+++ b/src/qml/.prev_CMakeLists.txt
@@ -0,0 +1,625 @@
+# Generated from qml.pro.
+
+#####################################################################
+## Qml Module:
+#####################################################################
+
+qt_add_module(Qml
+ GENERATE_METATYPES
+ PLUGIN_TYPES qmltooling
+ SOURCES
+ ../3rdparty/masm/assembler/*.h
+ ../3rdparty/masm/assembler/ARMv7Assembler.cpp
+ ../3rdparty/masm/assembler/LinkBuffer.cpp
+ ../3rdparty/masm/disassembler/ARM64/A64DOpcode.cpp ../3rdparty/masm/disassembler/ARM64/A64DOpcode.h
+ ../3rdparty/masm/disassembler/ARM64Disassembler.cpp
+ ../3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp ../3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h
+ ../3rdparty/masm/disassembler/ARMv7Disassembler.cpp
+ ../3rdparty/masm/disassembler/Disassembler.cpp
+ ../3rdparty/masm/disassembler/Mips32Disassembler.cpp
+ ../3rdparty/masm/disassembler/UDis86Disassembler.cpp
+ ../3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp ../3rdparty/masm/disassembler/mips32/Mips32Opcode.h
+ ../3rdparty/masm/stubs/Options.cpp
+ ../3rdparty/masm/stubs/WTFStubs.cpp ../3rdparty/masm/stubs/WTFStubs.h
+ ../3rdparty/masm/stubs/wtf/FastAllocBase.h
+ ../3rdparty/masm/stubs/wtf/FastMalloc.h
+ ../3rdparty/masm/stubs/wtf/Noncopyable.h
+ ../3rdparty/masm/stubs/wtf/OwnPtr.h
+ ../3rdparty/masm/stubs/wtf/PassOwnPtr.h
+ ../3rdparty/masm/stubs/wtf/PassRefPtr.h
+ ../3rdparty/masm/stubs/wtf/RefCounted.h
+ ../3rdparty/masm/stubs/wtf/RefPtr.h
+ ../3rdparty/masm/stubs/wtf/TypeTraits.h
+ ../3rdparty/masm/stubs/wtf/UnusedParam.h
+ ../3rdparty/masm/stubs/wtf/Vector.h
+ ../3rdparty/masm/stubs/yarr/YarrUnicodeProperties.cpp
+ ../3rdparty/masm/wtf/*.h
+ ../3rdparty/masm/wtf/FilePrintStream.cpp ../3rdparty/masm/wtf/FilePrintStream.h
+ ../3rdparty/masm/wtf/OSAllocator.h
+ ../3rdparty/masm/wtf/PageAllocation.h
+ ../3rdparty/masm/wtf/PageAllocationAligned.cpp ../3rdparty/masm/wtf/PageAllocationAligned.h
+ ../3rdparty/masm/wtf/PageBlock.cpp ../3rdparty/masm/wtf/PageBlock.h
+ ../3rdparty/masm/wtf/PageReservation.h
+ ../3rdparty/masm/wtf/PrintStream.cpp ../3rdparty/masm/wtf/PrintStream.h
+ ../3rdparty/masm/wtf/RawPointer.h
+ ../3rdparty/masm/yarr/Yarr.h
+ ../3rdparty/masm/yarr/YarrCanonicalizeUCS2.cpp ../3rdparty/masm/yarr/YarrCanonicalizeUCS2.h
+ ../3rdparty/masm/yarr/YarrCanonicalizeUnicode.cpp
+ ../3rdparty/masm/yarr/YarrInterpreter.cpp ../3rdparty/masm/yarr/YarrInterpreter.h
+ ../3rdparty/masm/yarr/YarrJIT.cpp ../3rdparty/masm/yarr/YarrJIT.h
+ ../3rdparty/masm/yarr/YarrParser.h
+ ../3rdparty/masm/yarr/YarrPattern.cpp ../3rdparty/masm/yarr/YarrPattern.h
+ ../3rdparty/masm/yarr/YarrSyntaxChecker.cpp ../3rdparty/masm/yarr/YarrSyntaxChecker.h
+ ../3rdparty/masm/yarr/YarrUnicodeProperties.h
+ common/qqmlapiversion_p.h
+ common/qqmljsdiagnosticmessage_p.h
+ common/qqmljsfixedpoolarray_p.h
+ common/qqmljsmemorypool_p.h
+ common/qqmljssourcelocation_p.h
+ common/qv4alloca_p.h
+ common/qv4calldata_p.h
+ common/qv4compileddata_p.h
+ common/qv4staticvalue_p.h
+ common/qv4stringtoarrayindex_p.h
+ compiler/qqmlirbuilder.cpp compiler/qqmlirbuilder_p.h
+ compiler/qv4bytecodegenerator.cpp compiler/qv4bytecodegenerator_p.h
+ compiler/qv4bytecodehandler.cpp compiler/qv4bytecodehandler_p.h
+ compiler/qv4codegen.cpp compiler/qv4codegen_p.h
+ compiler/qv4compiler.cpp compiler/qv4compiler_p.h
+ compiler/qv4compilercontext.cpp compiler/qv4compilercontext_p.h
+ compiler/qv4compilercontrolflow_p.h
+ compiler/qv4compilerglobal_p.h
+ compiler/qv4compilerscanfunctions.cpp compiler/qv4compilerscanfunctions_p.h
+ compiler/qv4instr_moth.cpp compiler/qv4instr_moth_p.h
+ compiler/qv4util_p.h
+ debugger/qqmldebug.h
+ debugger/qqmldebugconnector_p.h
+ debugger/qqmldebugserviceinterfaces_p.h
+ debugger/qqmldebugstatesdelegate_p.h
+ debugger/qqmlprofiler_p.h
+ inlinecomponentutils_p.h
+ jsapi/qjsengine.cpp jsapi/qjsengine.h jsapi/qjsengine_p.h
+ jsapi/qjsvalue.cpp jsapi/qjsvalue.h jsapi/qjsvalue_p.h
+ jsapi/qjsvalueiterator.cpp jsapi/qjsvalueiterator.h jsapi/qjsvalueiterator_p.h
+ jsruntime/qv4argumentsobject.cpp jsruntime/qv4argumentsobject_p.h
+ jsruntime/qv4arraybuffer.cpp jsruntime/qv4arraybuffer_p.h
+ jsruntime/qv4arraydata.cpp jsruntime/qv4arraydata_p.h
+ jsruntime/qv4arrayiterator.cpp jsruntime/qv4arrayiterator_p.h
+ jsruntime/qv4arrayobject.cpp jsruntime/qv4arrayobject_p.h
+ jsruntime/qv4atomics.cpp jsruntime/qv4atomics_p.h
+ jsruntime/qv4booleanobject.cpp jsruntime/qv4booleanobject_p.h
+ jsruntime/qv4compilationunitmapper.cpp jsruntime/qv4compilationunitmapper_p.h
+ jsruntime/qv4context.cpp jsruntime/qv4context_p.h
+ jsruntime/qv4dataview.cpp jsruntime/qv4dataview_p.h
+ jsruntime/qv4dateobject.cpp jsruntime/qv4dateobject_p.h
+ jsruntime/qv4debugging_p.h
+ jsruntime/qv4engine.cpp jsruntime/qv4engine_p.h
+ jsruntime/qv4enginebase_p.h
+ jsruntime/qv4errorobject.cpp jsruntime/qv4errorobject_p.h
+ jsruntime/qv4estable.cpp jsruntime/qv4estable_p.h
+ jsruntime/qv4executableallocator.cpp jsruntime/qv4executableallocator_p.h
+ jsruntime/qv4executablecompilationunit.cpp jsruntime/qv4executablecompilationunit_p.h
+ jsruntime/qv4function.cpp jsruntime/qv4function_p.h
+ jsruntime/qv4functionobject.cpp jsruntime/qv4functionobject_p.h
+ jsruntime/qv4functiontable_p.h
+ jsruntime/qv4generatorobject.cpp jsruntime/qv4generatorobject_p.h
+ jsruntime/qv4global_p.h
+ jsruntime/qv4globalobject.cpp jsruntime/qv4globalobject_p.h
+ jsruntime/qv4identifierhash.cpp jsruntime/qv4identifierhash_p.h
+ jsruntime/qv4identifierhashdata_p.h
+ jsruntime/qv4identifiertable.cpp jsruntime/qv4identifiertable_p.h
+ jsruntime/qv4include.cpp jsruntime/qv4include_p.h
+ jsruntime/qv4internalclass.cpp jsruntime/qv4internalclass_p.h
+ jsruntime/qv4iterator.cpp jsruntime/qv4iterator_p.h
+ jsruntime/qv4jscall_p.h
+ jsruntime/qv4jsonobject.cpp jsruntime/qv4jsonobject_p.h
+ jsruntime/qv4lookup.cpp jsruntime/qv4lookup_p.h
+ jsruntime/qv4managed.cpp jsruntime/qv4managed_p.h
+ jsruntime/qv4mapiterator.cpp jsruntime/qv4mapiterator_p.h
+ jsruntime/qv4mapobject.cpp jsruntime/qv4mapobject_p.h
+ jsruntime/qv4math_p.h
+ jsruntime/qv4mathobject.cpp jsruntime/qv4mathobject_p.h
+ jsruntime/qv4memberdata.cpp jsruntime/qv4memberdata_p.h
+ jsruntime/qv4module.cpp jsruntime/qv4module_p.h
+ jsruntime/qv4numberobject.cpp jsruntime/qv4numberobject_p.h
+ jsruntime/qv4object.cpp jsruntime/qv4object_p.h
+ jsruntime/qv4objectiterator.cpp jsruntime/qv4objectiterator_p.h
+ jsruntime/qv4objectproto.cpp jsruntime/qv4objectproto_p.h
+ jsruntime/qv4persistent.cpp jsruntime/qv4persistent_p.h
+ jsruntime/qv4profiling_p.h
+ jsruntime/qv4promiseobject.cpp jsruntime/qv4promiseobject_p.h
+ jsruntime/qv4property_p.h
+ jsruntime/qv4propertykey.cpp jsruntime/qv4propertykey_p.h
+ jsruntime/qv4proxy.cpp jsruntime/qv4proxy_p.h
+ jsruntime/qv4qmlcontext.cpp jsruntime/qv4qmlcontext_p.h
+ jsruntime/qv4qobjectwrapper.cpp jsruntime/qv4qobjectwrapper_p.h
+ jsruntime/qv4reflect.cpp jsruntime/qv4reflect_p.h
+ jsruntime/qv4regexp.cpp jsruntime/qv4regexp_p.h
+ jsruntime/qv4regexpobject.cpp jsruntime/qv4regexpobject_p.h
+ jsruntime/qv4resolvedtypereference.cpp jsruntime/qv4resolvedtypereference_p.h
+ jsruntime/qv4runtime.cpp jsruntime/qv4runtime_p.h
+ jsruntime/qv4runtimeapi_p.h
+ jsruntime/qv4runtimecodegen.cpp jsruntime/qv4runtimecodegen_p.h
+ jsruntime/qv4scopedvalue_p.h
+ jsruntime/qv4script.cpp jsruntime/qv4script_p.h
+ jsruntime/qv4setiterator.cpp jsruntime/qv4setiterator_p.h
+ jsruntime/qv4setobject.cpp jsruntime/qv4setobject_p.h
+ jsruntime/qv4sparsearray.cpp jsruntime/qv4sparsearray_p.h
+ jsruntime/qv4stackframe.cpp jsruntime/qv4stackframe_p.h
+ jsruntime/qv4string.cpp jsruntime/qv4string_p.h
+ jsruntime/qv4stringiterator.cpp jsruntime/qv4stringiterator_p.h
+ jsruntime/qv4stringobject.cpp jsruntime/qv4stringobject_p.h
+ jsruntime/qv4symbol.cpp jsruntime/qv4symbol_p.h
+ jsruntime/qv4typedarray.cpp jsruntime/qv4typedarray_p.h
+ jsruntime/qv4urlobject.cpp jsruntime/qv4urlobject_p.h
+ jsruntime/qv4value.cpp jsruntime/qv4value_p.h
+ jsruntime/qv4variantobject.cpp jsruntime/qv4variantobject_p.h
+ jsruntime/qv4vme_moth.cpp jsruntime/qv4vme_moth_p.h
+ jsruntime/qv4vtable_p.h
+ memory/qv4heap_p.h
+ memory/qv4mm.cpp memory/qv4mm_p.h
+ memory/qv4mmdefs_p.h
+ memory/qv4writebarrier_p.h
+ parser/qqmljsast.cpp parser/qqmljsast_p.h
+ parser/qqmljsastfwd_p.h
+ parser/qqmljsastvisitor.cpp parser/qqmljsastvisitor_p.h
+ parser/qqmljsengine_p.cpp parser/qqmljsengine_p.h
+ parser/qqmljsglobal_p.h
+ parser/qqmljskeywords_p.h
+ parser/qqmljslexer.cpp parser/qqmljslexer_p.h
+ qml/ftw/qbitfield_p.h
+ qml/ftw/qfieldlist_p.h
+ qml/ftw/qfinitestack_p.h
+ qml/ftw/qflagpointer_p.h
+ qml/ftw/qhashedstring.cpp qml/ftw/qhashedstring_p.h
+ qml/ftw/qintrusivelist.cpp qml/ftw/qintrusivelist_p.h
+ qml/ftw/qlazilyallocated_p.h
+ qml/ftw/qlinkedstringhash_p.h
+ qml/ftw/qpodvector_p.h
+ qml/ftw/qprimefornumbits_p.h
+ qml/ftw/qqmlnullablevalue_p.h
+ qml/ftw/qqmlrefcount_p.h
+ qml/ftw/qqmlthread.cpp qml/ftw/qqmlthread_p.h
+ qml/ftw/qrecursionwatcher_p.h
+ qml/ftw/qrecyclepool_p.h
+ qml/ftw/qstringhash_p.h
+ qml/qqml.cpp qml/qqml.h
+ qml/qqmlabstractbinding.cpp qml/qqmlabstractbinding_p.h
+ qml/qqmlabstracturlinterceptor.cpp qml/qqmlabstracturlinterceptor.h
+ qml/qqmlapplicationengine.cpp qml/qqmlapplicationengine.h qml/qqmlapplicationengine_p.h
+ qml/qqmlbinding.cpp qml/qqmlbinding_p.h
+ qml/qqmlboundsignal.cpp qml/qqmlboundsignal_p.h
+ qml/qqmlboundsignalexpressionpointer_p.h
+ qml/qqmlcleanup.cpp qml/qqmlcleanup_p.h
+ qml/qqmlcomponent.cpp qml/qqmlcomponent.h qml/qqmlcomponent_p.h
+ qml/qqmlcomponentattached_p.h
+ qml/qqmlcontext.cpp qml/qqmlcontext.h qml/qqmlcontext_p.h
+ qml/qqmlcontextdata.cpp qml/qqmlcontextdata_p.h
+ qml/qqmlcustomparser.cpp qml/qqmlcustomparser_p.h
+ qml/qqmldata_p.h
+ qml/qqmldatablob.cpp qml/qqmldatablob_p.h
+ qml/qqmldelayedcallqueue.cpp qml/qqmldelayedcallqueue_p.h
+ qml/qqmldirdata.cpp qml/qqmldirdata_p.h
+ qml/qqmlengine.cpp qml/qqmlengine.h qml/qqmlengine_p.h
+ qml/qqmlenumdata_p.h
+ qml/qqmlenumvalue_p.h
+ qml/qqmlerror.cpp qml/qqmlerror.h
+ qml/qqmlexpression.cpp qml/qqmlexpression.h qml/qqmlexpression_p.h
+ qml/qqmlextensioninterface.h
+ qml/qqmlextensionplugin.cpp qml/qqmlextensionplugin.h qml/qqmlextensionplugin_p.h
+ qml/qqmlfile.cpp qml/qqmlfile.h
+ qml/qqmlfileselector.cpp qml/qqmlfileselector.h qml/qqmlfileselector_p.h
+ qml/qqmlglobal.cpp qml/qqmlglobal_p.h
+ qml/qqmlguard_p.h
+ qml/qqmlguardedcontextdata_p.h
+ qml/qqmlimport.cpp qml/qqmlimport_p.h
+ qml/qqmlincubator.cpp qml/qqmlincubator.h qml/qqmlincubator_p.h
+ qml/qqmlinfo.cpp qml/qqmlinfo.h
+ qml/qqmlirloader.cpp qml/qqmlirloader_p.h
+ qml/qqmljavascriptexpression.cpp qml/qqmljavascriptexpression_p.h
+ qml/qqmllist.cpp qml/qqmllist.h qml/qqmllist_p.h
+ qml/qqmllistwrapper.cpp qml/qqmllistwrapper_p.h
+ qml/qqmlloggingcategory.cpp qml/qqmlloggingcategory_p.h
+ qml/qqmlmetaobject.cpp qml/qqmlmetaobject_p.h
+ qml/qqmlmetatype.cpp qml/qqmlmetatype_p.h
+ qml/qqmlmetatypedata.cpp qml/qqmlmetatypedata_p.h
+ qml/qqmlmoduleregistration.cpp qml/qqmlmoduleregistration.h
+ qml/qqmlnetworkaccessmanagerfactory.cpp qml/qqmlnetworkaccessmanagerfactory.h
+ qml/qqmlnotifier.cpp qml/qqmlnotifier_p.h
+ qml/qqmlobjectcreator.cpp qml/qqmlobjectcreator_p.h
+ qml/qqmlobjectorgadget.cpp qml/qqmlobjectorgadget_p.h
+ qml/qqmlopenmetaobject.cpp qml/qqmlopenmetaobject_p.h
+ qml/qqmlparserstatus.cpp qml/qqmlparserstatus.h
+ qml/qqmlplatform.cpp qml/qqmlplatform_p.h
+ qml/qqmlprivate.h
+ qml/qqmlproperty.cpp qml/qqmlproperty.h qml/qqmlproperty_p.h
+ qml/qqmlpropertybinding.cpp qml/qqmlpropertybinding_p.h
+ qml/qqmlpropertycache.cpp qml/qqmlpropertycache_p.h
+ qml/qqmlpropertycachecreator.cpp qml/qqmlpropertycachecreator_p.h
+ qml/qqmlpropertycachemethodarguments_p.h
+ qml/qqmlpropertycachevector_p.h
+ qml/qqmlpropertydata_p.h
+ qml/qqmlpropertyindex_p.h
+ qml/qqmlpropertyresolver.cpp qml/qqmlpropertyresolver_p.h
+ qml/qqmlpropertyvalidator.cpp qml/qqmlpropertyvalidator_p.h
+ qml/qqmlpropertyvalueinterceptor.cpp qml/qqmlpropertyvalueinterceptor_p.h
+ qml/qqmlpropertyvaluesource.cpp qml/qqmlpropertyvaluesource.h
+ qml/qqmlproxymetaobject.cpp qml/qqmlproxymetaobject_p.h
+ qml/qqmlscriptblob.cpp qml/qqmlscriptblob_p.h
+ qml/qqmlscriptdata.cpp qml/qqmlscriptdata_p.h
+ qml/qqmlscriptstring.cpp qml/qqmlscriptstring.h qml/qqmlscriptstring_p.h
+ qml/qqmlsourcecoordinate_p.h
+ qml/qqmlstaticmetaobject.cpp qml/qqmlstaticmetaobject_p.h
+ qml/qqmlstringconverters.cpp qml/qqmlstringconverters_p.h
+ qml/qqmltype.cpp qml/qqmltype_p.h
+ qml/qqmltype_p_p.h
+ qml/qqmltypecompiler.cpp qml/qqmltypecompiler_p.h
+ qml/qqmltypedata.cpp qml/qqmltypedata_p.h
+ qml/qqmltypeloader.cpp qml/qqmltypeloader_p.h
+ qml/qqmltypeloaderqmldircontent.cpp qml/qqmltypeloaderqmldircontent_p.h
+ qml/qqmltypeloaderthread.cpp qml/qqmltypeloaderthread_p.h
+ qml/qqmltypemodule.cpp qml/qqmltypemodule_p.h
+ qml/qqmltypemodule_p_p.h
+ qml/qqmltypemoduleversion.cpp qml/qqmltypemoduleversion_p.h
+ qml/qqmltypenamecache.cpp qml/qqmltypenamecache_p.h
+ qml/qqmltypenotavailable.cpp qml/qqmltypenotavailable_p.h
+ qml/qqmltypewrapper.cpp qml/qqmltypewrapper_p.h
+ qml/qqmlvaluetype.cpp qml/qqmlvaluetype_p.h
+ qml/qqmlvaluetypeproxybinding.cpp qml/qqmlvaluetypeproxybinding_p.h
+ qml/qqmlvaluetypewrapper.cpp
+ qml/qqmlvme.cpp qml/qqmlvme_p.h
+ qml/qqmlvmemetaobject.cpp qml/qqmlvmemetaobject_p.h
+ qml/v8/qqmlbuiltinfunctions.cpp qml/v8/qqmlbuiltinfunctions_p.h
+ qml/v8/qv4domerrors.cpp qml/v8/qv4domerrors_p.h
+ qml/v8/qv4sqlerrors.cpp qml/v8/qv4sqlerrors_p.h
+ qmldirparser/qqmldirparser.cpp qmldirparser/qqmldirparser_p.h
+ qtqmlcompilerglobal.h qtqmlcompilerglobal_p.h
+ qtqmlglobal.h qtqmlglobal_p.h
+ types/qqmlbind.cpp types/qqmlbind_p.h
+ types/qqmlconnections.cpp types/qqmlconnections_p.h
+ util/qqmlpropertymap.cpp util/qqmlpropertymap.h
+ DEFINES
+ BUILDING_QT__
+ ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
+ ENABLE_DFG_JIT=0
+ ENABLE_DFG_JIT_UTILITY_METHODS=1
+ ENABLE_JIT_CONSTANT_BLINDING=0
+ ENABLE_LLINT=0
+ JS_EXPORT_PRIVATE=""
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ WTFInvokeCrashHook=qmlWTFInvokeCrashHook
+ WTFReportAssertionFailure=qmlWTFReportAssertionFailure
+ WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
+ WTFReportBacktrace=qmlWTFReportBacktrace
+ WTF_EXPORT_PRIVATE=""
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/compiler
+ ${CMAKE_CURRENT_BINARY_DIR}/jsruntime
+ ${CMAKE_CURRENT_BINARY_DIR}/memory
+ ${CMAKE_CURRENT_BINARY_DIR}/qmldirparser
+ ../3rdparty/masm
+ ../3rdparty/masm/assembler
+ ../3rdparty/masm/disassembler
+ ../3rdparty/masm/disassembler/udis86
+ ../3rdparty/masm/jit
+ ../3rdparty/masm/runtime
+ ../3rdparty/masm/stubs
+ ../3rdparty/masm/stubs/runtime
+ ../3rdparty/masm/stubs/wtf
+ ../3rdparty/masm/wtf
+ .generated
+ compiler
+ debugger
+ jsruntime
+ memory
+ qmldirparser
+ LIBRARIES
+ Qt::CorePrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+)
+
+# QLALR Grammars:
+qt_process_qlalr(
+ Qml
+ parser/qqmljs.g
+ ""
+)
+
+#### Keys ignored in scope 1:.:.:qml.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQml"
+# QML_IMPORT_NAME = "QtQml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_network
+ SOURCES
+ qml/qqmltypeloadernetworkreplyproxy.cpp qml/qqmltypeloadernetworkreplyproxy_p.h
+ PUBLIC_LIBRARIES
+ Qt::Network
+)
+
+qt_extend_target(Qml CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386")
+ LINK_OPTIONS
+ "/BASE:0x66000000"
+)
+
+qt_extend_target(Qml CONDITION MSVC
+ DEFINES
+ _CRT_SECURE_NO_WARNINGS
+)
+
+qt_extend_target(Qml CONDITION WIN32 AND NOT WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorWin.cpp
+ PUBLIC_LIBRARIES
+ shell32
+)
+
+#### Keys ignored in scope 6:.:.:qml.pro:solaris-cc_x_:
+# QMAKE_CXXFLAGS_RELEASE = "--O2"
+
+qt_extend_target(Qml CONDITION GCC AND (TEST_architecture_arch STREQUAL "mips")
+ COMPILE_OPTIONS
+ -fno-reorder-blocks
+)
+
+qt_extend_target(Qml CONDITION EXISTS "qqml_enable_gcov"
+ LIBRARIES
+ gcov
+ COMPILE_OPTIONS
+ -fno-elide-constructors
+ -fprofile-arcs
+ -ftest-coverage
+)
+
+qt_extend_target(Qml CONDITION release AND MSVC AND (QT_CL_MAJOR_VERSION EQUAL 19) AND (QT_CL_MINOR_VERSION EQUAL 00) AND (QT_CL_PATCH_VERSION GREATER 24212)
+ COMPILE_OPTIONS
+ -d2SSAOptimizer-
+)
+
+#### Keys ignored in scope 10:.:.:qml.pro:ICC:
+# WERROR = "-ww2415"
+
+#### Keys ignored in scope 11:.:.:qml.pro:(QT_CLANG_MAJOR_VERSION GREATER 3) OR (QT_CLANG_MINOR_VERSION GREATER 3) OR (QT_APPLE_CLANG_MAJOR_VERSION GREATER 5) OR ( (QT_APPLE_CLANG_MAJOR_VERSION EQUAL 5) AND (QT_APPLE_CLANG_MINOR_VERSION GREATER 0) ):
+# WERROR = "-Wno-error=unused-const-variable"
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_jit
+ SOURCES
+ jit/qv4assemblercommon.cpp jit/qv4assemblercommon_p.h
+ jit/qv4baselineassembler.cpp jit/qv4baselineassembler_p.h
+ jit/qv4baselinejit.cpp jit/qv4baselinejit_p.h
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/jit
+ jit
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_animation
+ SOURCES
+ animations/qabstractanimationjob.cpp animations/qabstractanimationjob_p.h
+ animations/qanimationgroupjob.cpp animations/qanimationgroupjob_p.h
+ animations/qanimationjobutil_p.h
+ animations/qcontinuinganimationgroupjob.cpp animations/qcontinuinganimationgroupjob_p.h
+ animations/qparallelanimationgroupjob.cpp animations/qparallelanimationgroupjob_p.h
+ animations/qpauseanimationjob.cpp animations/qpauseanimationjob_p.h
+ animations/qsequentialanimationgroupjob.cpp animations/qsequentialanimationgroupjob_p.h
+ types/qqmltimer.cpp types/qqmltimer_p.h
+ INCLUDE_DIRECTORIES
+ animations
+)
+
+#### Keys ignored in scope 17:.:common:common/common.pri:NOT build_pass:
+# compile_hash_contents = "// Generated file, DO NOT EDIT" "$${LITERAL_HASH}define QML_COMPILE_HASH "$$QML_COMPILE_HASH"" "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
+# tag = <EMPTY>
+# tagFile = "$$PWD/../../.tag"
+
+#### Keys ignored in scope 18:.:common:common/common.pri:EXISTS _ss_tagFile:
+# QMAKE_INTERNAL_INCLUDED_FILES = "$$tagFile"
+# tag = "$$cat($$tagFile, singleline)"
+
+#### Keys ignored in scope 19:.:common:common/common.pri:NOT tag___equals____ss_{LITERAL_DOLLAR}Format AND %H_ss_{LITERAL_DOLLAR}:
+# QML_COMPILE_HASH = "$$tag"
+
+#### Keys ignored in scope 21:.:common:common/common.pri:EXISTS _ss_PWD/../../.git:
+# QML_COMPILE_HASH = "$$commit"
+# commit = "$$system(git rev-parse HEAD)"
+
+qt_extend_target(Qml CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5
+ COMPILE_OPTIONS
+ -fno-strict-aliasing
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_debug
+ SOURCES
+ debugger/qqmlabstractprofileradapter.cpp debugger/qqmlabstractprofileradapter_p.h
+ debugger/qqmlconfigurabledebugservice_p.h
+ debugger/qqmldebug.cpp
+ debugger/qqmldebugconnector.cpp
+ debugger/qqmldebugpluginmanager_p.h
+ debugger/qqmldebugserver_p.h
+ debugger/qqmldebugserverconnection_p.h
+ debugger/qqmldebugservice.cpp debugger/qqmldebugservice_p.h
+ debugger/qqmldebugservicefactory_p.h
+ debugger/qqmldebugserviceinterfaces.cpp
+ debugger/qqmlprofiler.cpp
+ debugger/qqmlprofilerdefinitions_p.h
+ jsruntime/qv4profiling.cpp
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_sequence_object
+ SOURCES
+ jsruntime/qv4sequenceobject.cpp jsruntime/qv4sequenceobject_p.h
+)
+
+qt_extend_target(Qml CONDITION UNIX
+ SOURCES
+ jsruntime/qv4compilationunitmapper_unix.cpp
+ jsruntime/qv4functiontable_unix.cpp
+)
+
+qt_extend_target(Qml CONDITION WIN32
+ SOURCES
+ jsruntime/qv4compilationunitmapper_win.cpp
+ DEFINES
+ NOMINMAX
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "x86_64") AND WIN32 AND NOT WINRT
+ SOURCES
+ jsruntime/qv4functiontable_win64.cpp
+)
+
+qt_extend_target(Qml CONDITION WIN32 AND (WINRT OR NOT (TEST_architecture_arch STREQUAL "x86_64"))
+ SOURCES
+ jsruntime/qv4functiontable_noop.cpp
+)
+
+qt_extend_target(Qml CONDITION valgrind
+ DEFINES
+ V4_USE_VALGRIND
+)
+
+qt_extend_target(Qml CONDITION heaptrack
+ DEFINES
+ V4_USE_HEAPTRACK
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_xml_http_request
+ SOURCES
+ qml/qqmlxmlhttprequest.cpp qml/qqmlxmlhttprequest_p.h
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_locale
+ SOURCES
+ qml/qqmllocale.cpp qml/qqmllocale_p.h
+)
+
+qt_extend_target(Qml CONDITION ANDROID
+ DEFINES
+ LIBS_SUFFIX="_${CMAKE_SYSTEM_PROCESSOR}.so"
+)
+
+qt_extend_target(Qml CONDITION hpux-_x_ OR solaris-_x_ OR (QT_FEATURE_clock_gettime AND linux-_x_)
+ LIBRARIES
+ rt
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_itemmodel
+ SOURCES
+ types/qqmlmodelindexvaluetype.cpp types/qqmlmodelindexvaluetype_p.h
+)
+
+qt_extend_target(Qml CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64"))
+ DEFINES
+ WTF_USE_UDIS86=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler
+ DEFINES
+ WTF_USE_ARMV7_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler
+ DEFINES
+ WTF_USE_ARM64_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler
+ DEFINES
+ WTF_USE_MIPS32_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION NOT disassembler
+ DEFINES
+ WTF_USE_UDIS86=0
+)
+
+qt_extend_target(Qml CONDITION CMAKE_BUILD_TYPE STREQUAL Release
+ DEFINES
+ NDEBUG
+)
+
+qt_extend_target(Qml CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC
+ COMPILE_OPTIONS
+ -Wno-expansion-to-defined
+)
+
+#### Keys ignored in scope 65:.:../3rdparty/masm:../3rdparty/masm/masm-defs.pri:(QT_COMPILER_VERSION_MAJOR STRGREATER 6):
+# QMAKE_CXXFLAGS_WARN_ON = "-Wno-expansion-to-defined"
+
+qt_extend_target(Qml CONDITION WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorWinRT.cpp
+)
+
+qt_extend_target(Qml CONDITION INTEGRITY
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorIntegrity.cpp
+)
+
+qt_extend_target(Qml CONDITION UNIX AND NOT INTEGRITY AND NOT WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorPosix.cpp
+)
+
+qt_extend_target(Qml CONDITION DEFINES___contains___WTF_USE_UDIS86=1
+ SOURCES
+ ../3rdparty/masm/disassembler/udis86/udis86.c
+ ../3rdparty/masm/disassembler/udis86/udis86_decode.c
+ ../3rdparty/masm/disassembler/udis86/udis86_input.c
+ ../3rdparty/masm/disassembler/udis86/udis86_itab_holder.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn-att.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn-intel.c
+)
+
+#### Keys ignored in scope 73:.:../3rdparty/masm:../3rdparty/masm/masm.pri:DEFINES___contains___WTF_USE_UDIS86=1:
+# ITAB = "$$PWD/disassembler/udis86/optable.xml"
+# QMAKE_EXTRA_COMPILERS = "udis86"
+# QMAKE_EXTRA_TARGETS = "udis86_tab_cfile"
+# udis86.CONFIG = "no_link"
+# udis86.commands = "python" "$$PWD/disassembler/udis86/itab.py" "${QMAKE_FILE_IN}"
+# udis86.input = "ITAB"
+# udis86.output = "udis86_itab.h"
+# udis86_tab_cfile.depends = "udis86_itab.h"
+# udis86_tab_cfile.target = "$$OUT_PWD/udis86_itab.c"
+
+#### Keys ignored in scope 75:.:../3rdparty/masm:../3rdparty/masm/masm.pri:(CMAKE_BUILD_TYPE STREQUAL Debug):
+# GENERATEDDIR = "$$GENERATEDDIR/debug"
+
+#### Keys ignored in scope 76:.:../3rdparty/masm:../3rdparty/masm/masm.pri:else:
+# GENERATEDDIR = "$$GENERATEDDIR/release"
+
+qt_extend_target(Qml CONDITION (NOT c++11 AND NOT ICC) AND (CLANG)
+ COMPILE_OPTIONS
+ -Wno-c++0x-extensions
+ -Wno-c++11-extensions
+)
+
+qt_extend_target(Qml CONDITION (((NOT c++11 AND NOT ICC) AND (NOT (CLANG))) AND (GCC)) AND ((QT_COMPILER_VERSION_MAJOR STRGREATER 4) OR (QT_COMPILER_VERSION_MINOR STRGREATER 5))
+ COMPILE_OPTIONS
+ -Wno-c++0x-compat
+)
+
+
+qt_create_tracepoints(Qml qtqml.tracepoints)
+qt_add_docs(Qml
+ doc/qtqml.qdocconf
+)
+
+
+set_target_properties(Qml PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQml
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQml"
+)
+
+qt6_qml_type_registration(Qml)
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
new file mode 100644
index 0000000000..381a76cb12
--- /dev/null
+++ b/src/qml/CMakeLists.txt
@@ -0,0 +1,634 @@
+# Generated from qml.pro.
+
+#####################################################################
+## Qml Module:
+#####################################################################
+
+qt_add_module(Qml
+ GENERATE_METATYPES
+ PLUGIN_TYPES qmltooling
+ SOURCES
+ # ../3rdparty/masm/assembler/*.h special case remove
+ ../3rdparty/masm/assembler/ARMv7Assembler.cpp
+ ../3rdparty/masm/assembler/LinkBuffer.cpp
+ ../3rdparty/masm/disassembler/ARM64/A64DOpcode.cpp ../3rdparty/masm/disassembler/ARM64/A64DOpcode.h
+ ../3rdparty/masm/disassembler/ARM64Disassembler.cpp
+ ../3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.cpp ../3rdparty/masm/disassembler/ARMv7/ARMv7DOpcode.h
+ ../3rdparty/masm/disassembler/ARMv7Disassembler.cpp
+ ../3rdparty/masm/disassembler/Disassembler.cpp
+ ../3rdparty/masm/disassembler/Mips32Disassembler.cpp
+ ../3rdparty/masm/disassembler/UDis86Disassembler.cpp
+ ../3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp ../3rdparty/masm/disassembler/mips32/Mips32Opcode.h
+ ../3rdparty/masm/stubs/Options.cpp
+ ../3rdparty/masm/stubs/WTFStubs.cpp ../3rdparty/masm/stubs/WTFStubs.h
+ ../3rdparty/masm/stubs/wtf/FastAllocBase.h
+ ../3rdparty/masm/stubs/wtf/FastMalloc.h
+ ../3rdparty/masm/stubs/wtf/Noncopyable.h
+ ../3rdparty/masm/stubs/wtf/OwnPtr.h
+ ../3rdparty/masm/stubs/wtf/PassOwnPtr.h
+ ../3rdparty/masm/stubs/wtf/PassRefPtr.h
+ ../3rdparty/masm/stubs/wtf/RefCounted.h
+ ../3rdparty/masm/stubs/wtf/RefPtr.h
+ ../3rdparty/masm/stubs/wtf/TypeTraits.h
+ ../3rdparty/masm/stubs/wtf/UnusedParam.h
+ ../3rdparty/masm/stubs/wtf/Vector.h
+ ../3rdparty/masm/stubs/yarr/YarrUnicodeProperties.cpp
+ # ../3rdparty/masm/wtf/*.h special case remove
+ ../3rdparty/masm/wtf/FilePrintStream.cpp ../3rdparty/masm/wtf/FilePrintStream.h
+ ../3rdparty/masm/wtf/OSAllocator.h
+ ../3rdparty/masm/wtf/PageAllocation.h
+ ../3rdparty/masm/wtf/PageAllocationAligned.cpp ../3rdparty/masm/wtf/PageAllocationAligned.h
+ ../3rdparty/masm/wtf/PageBlock.cpp ../3rdparty/masm/wtf/PageBlock.h
+ ../3rdparty/masm/wtf/PageReservation.h
+ ../3rdparty/masm/wtf/PrintStream.cpp ../3rdparty/masm/wtf/PrintStream.h
+ ../3rdparty/masm/wtf/RawPointer.h
+ ../3rdparty/masm/yarr/Yarr.h
+ ../3rdparty/masm/yarr/YarrCanonicalizeUCS2.cpp ../3rdparty/masm/yarr/YarrCanonicalizeUCS2.h
+ ../3rdparty/masm/yarr/YarrCanonicalizeUnicode.cpp
+ ../3rdparty/masm/yarr/YarrInterpreter.cpp ../3rdparty/masm/yarr/YarrInterpreter.h
+ ../3rdparty/masm/yarr/YarrJIT.cpp ../3rdparty/masm/yarr/YarrJIT.h
+ ../3rdparty/masm/yarr/YarrParser.h
+ ../3rdparty/masm/yarr/YarrPattern.cpp ../3rdparty/masm/yarr/YarrPattern.h
+ ../3rdparty/masm/yarr/YarrSyntaxChecker.cpp ../3rdparty/masm/yarr/YarrSyntaxChecker.h
+ ../3rdparty/masm/yarr/YarrUnicodeProperties.h
+ common/qqmlapiversion_p.h
+ common/qqmljsdiagnosticmessage_p.h
+ common/qqmljsfixedpoolarray_p.h
+ common/qqmljsmemorypool_p.h
+ common/qqmljssourcelocation_p.h
+ common/qv4alloca_p.h
+ common/qv4calldata_p.h
+ common/qv4compileddata_p.h
+ common/qv4staticvalue_p.h
+ common/qv4stringtoarrayindex_p.h
+ compiler/qqmlirbuilder.cpp compiler/qqmlirbuilder_p.h
+ compiler/qv4bytecodegenerator.cpp compiler/qv4bytecodegenerator_p.h
+ compiler/qv4bytecodehandler.cpp compiler/qv4bytecodehandler_p.h
+ compiler/qv4codegen.cpp compiler/qv4codegen_p.h
+ compiler/qv4compiler.cpp compiler/qv4compiler_p.h
+ compiler/qv4compilercontext.cpp compiler/qv4compilercontext_p.h
+ compiler/qv4compilercontrolflow_p.h
+ compiler/qv4compilerglobal_p.h
+ compiler/qv4compilerscanfunctions.cpp compiler/qv4compilerscanfunctions_p.h
+ compiler/qv4instr_moth.cpp compiler/qv4instr_moth_p.h
+ compiler/qv4util_p.h
+ debugger/qqmldebug.h
+ debugger/qqmldebugconnector_p.h
+ debugger/qqmldebugserviceinterfaces_p.h
+ debugger/qqmldebugstatesdelegate_p.h
+ debugger/qqmlprofiler_p.h
+ inlinecomponentutils_p.h
+ jsapi/qjsengine.cpp jsapi/qjsengine.h jsapi/qjsengine_p.h
+ jsapi/qjsvalue.cpp jsapi/qjsvalue.h jsapi/qjsvalue_p.h
+ jsapi/qjsvalueiterator.cpp jsapi/qjsvalueiterator.h jsapi/qjsvalueiterator_p.h
+ jsruntime/qv4argumentsobject.cpp jsruntime/qv4argumentsobject_p.h
+ jsruntime/qv4arraybuffer.cpp jsruntime/qv4arraybuffer_p.h
+ jsruntime/qv4arraydata.cpp jsruntime/qv4arraydata_p.h
+ jsruntime/qv4arrayiterator.cpp jsruntime/qv4arrayiterator_p.h
+ jsruntime/qv4arrayobject.cpp jsruntime/qv4arrayobject_p.h
+ jsruntime/qv4atomics.cpp jsruntime/qv4atomics_p.h
+ jsruntime/qv4booleanobject.cpp jsruntime/qv4booleanobject_p.h
+ jsruntime/qv4compilationunitmapper.cpp jsruntime/qv4compilationunitmapper_p.h
+ jsruntime/qv4context.cpp jsruntime/qv4context_p.h
+ jsruntime/qv4dataview.cpp jsruntime/qv4dataview_p.h
+ jsruntime/qv4dateobject.cpp jsruntime/qv4dateobject_p.h
+ jsruntime/qv4debugging_p.h
+ jsruntime/qv4engine.cpp jsruntime/qv4engine_p.h
+ jsruntime/qv4enginebase_p.h
+ jsruntime/qv4errorobject.cpp jsruntime/qv4errorobject_p.h
+ jsruntime/qv4estable.cpp jsruntime/qv4estable_p.h
+ jsruntime/qv4executableallocator.cpp jsruntime/qv4executableallocator_p.h
+ jsruntime/qv4executablecompilationunit.cpp jsruntime/qv4executablecompilationunit_p.h
+ jsruntime/qv4function.cpp jsruntime/qv4function_p.h
+ jsruntime/qv4functionobject.cpp jsruntime/qv4functionobject_p.h
+ jsruntime/qv4functiontable_p.h
+ jsruntime/qv4generatorobject.cpp jsruntime/qv4generatorobject_p.h
+ jsruntime/qv4global_p.h
+ jsruntime/qv4globalobject.cpp jsruntime/qv4globalobject_p.h
+ jsruntime/qv4identifierhash.cpp jsruntime/qv4identifierhash_p.h
+ jsruntime/qv4identifierhashdata_p.h
+ jsruntime/qv4identifiertable.cpp jsruntime/qv4identifiertable_p.h
+ jsruntime/qv4include.cpp jsruntime/qv4include_p.h
+ jsruntime/qv4internalclass.cpp jsruntime/qv4internalclass_p.h
+ jsruntime/qv4iterator.cpp jsruntime/qv4iterator_p.h
+ jsruntime/qv4jscall_p.h
+ jsruntime/qv4jsonobject.cpp jsruntime/qv4jsonobject_p.h
+ jsruntime/qv4lookup.cpp jsruntime/qv4lookup_p.h
+ jsruntime/qv4managed.cpp jsruntime/qv4managed_p.h
+ jsruntime/qv4mapiterator.cpp jsruntime/qv4mapiterator_p.h
+ jsruntime/qv4mapobject.cpp jsruntime/qv4mapobject_p.h
+ jsruntime/qv4math_p.h
+ jsruntime/qv4mathobject.cpp jsruntime/qv4mathobject_p.h
+ jsruntime/qv4memberdata.cpp jsruntime/qv4memberdata_p.h
+ jsruntime/qv4module.cpp jsruntime/qv4module_p.h
+ jsruntime/qv4numberobject.cpp jsruntime/qv4numberobject_p.h
+ jsruntime/qv4object.cpp jsruntime/qv4object_p.h
+ jsruntime/qv4objectiterator.cpp jsruntime/qv4objectiterator_p.h
+ jsruntime/qv4objectproto.cpp jsruntime/qv4objectproto_p.h
+ jsruntime/qv4persistent.cpp jsruntime/qv4persistent_p.h
+ jsruntime/qv4profiling_p.h
+ jsruntime/qv4promiseobject.cpp jsruntime/qv4promiseobject_p.h
+ jsruntime/qv4property_p.h
+ jsruntime/qv4propertykey.cpp jsruntime/qv4propertykey_p.h
+ jsruntime/qv4proxy.cpp jsruntime/qv4proxy_p.h
+ jsruntime/qv4qmlcontext.cpp jsruntime/qv4qmlcontext_p.h
+ jsruntime/qv4qobjectwrapper.cpp jsruntime/qv4qobjectwrapper_p.h
+ jsruntime/qv4reflect.cpp jsruntime/qv4reflect_p.h
+ jsruntime/qv4regexp.cpp jsruntime/qv4regexp_p.h
+ jsruntime/qv4regexpobject.cpp jsruntime/qv4regexpobject_p.h
+ jsruntime/qv4resolvedtypereference.cpp jsruntime/qv4resolvedtypereference_p.h
+ jsruntime/qv4runtime.cpp jsruntime/qv4runtime_p.h
+ jsruntime/qv4runtimeapi_p.h
+ jsruntime/qv4runtimecodegen.cpp jsruntime/qv4runtimecodegen_p.h
+ jsruntime/qv4scopedvalue_p.h
+ jsruntime/qv4script.cpp jsruntime/qv4script_p.h
+ jsruntime/qv4setiterator.cpp jsruntime/qv4setiterator_p.h
+ jsruntime/qv4setobject.cpp jsruntime/qv4setobject_p.h
+ jsruntime/qv4sparsearray.cpp jsruntime/qv4sparsearray_p.h
+ jsruntime/qv4stackframe.cpp jsruntime/qv4stackframe_p.h
+ jsruntime/qv4string.cpp jsruntime/qv4string_p.h
+ jsruntime/qv4stringiterator.cpp jsruntime/qv4stringiterator_p.h
+ jsruntime/qv4stringobject.cpp jsruntime/qv4stringobject_p.h
+ jsruntime/qv4symbol.cpp jsruntime/qv4symbol_p.h
+ jsruntime/qv4typedarray.cpp jsruntime/qv4typedarray_p.h
+ jsruntime/qv4urlobject.cpp jsruntime/qv4urlobject_p.h
+ jsruntime/qv4value.cpp jsruntime/qv4value_p.h
+ jsruntime/qv4variantobject.cpp jsruntime/qv4variantobject_p.h
+ jsruntime/qv4vme_moth.cpp jsruntime/qv4vme_moth_p.h
+ jsruntime/qv4vtable_p.h
+ memory/qv4heap_p.h
+ memory/qv4mm.cpp memory/qv4mm_p.h
+ memory/qv4mmdefs_p.h
+ memory/qv4writebarrier_p.h
+ parser/qqmljsast.cpp parser/qqmljsast_p.h
+ parser/qqmljsastfwd_p.h
+ parser/qqmljsastvisitor.cpp parser/qqmljsastvisitor_p.h
+ parser/qqmljsengine_p.cpp parser/qqmljsengine_p.h
+ parser/qqmljsglobal_p.h
+ parser/qqmljskeywords_p.h
+ parser/qqmljslexer.cpp parser/qqmljslexer_p.h
+ qml/ftw/qbitfield_p.h
+ qml/ftw/qfieldlist_p.h
+ qml/ftw/qfinitestack_p.h
+ qml/ftw/qflagpointer_p.h
+ qml/ftw/qhashedstring.cpp qml/ftw/qhashedstring_p.h
+ qml/ftw/qintrusivelist.cpp qml/ftw/qintrusivelist_p.h
+ qml/ftw/qlazilyallocated_p.h
+ qml/ftw/qlinkedstringhash_p.h
+ qml/ftw/qpodvector_p.h
+ qml/ftw/qprimefornumbits_p.h
+ qml/ftw/qqmlnullablevalue_p.h
+ qml/ftw/qqmlrefcount_p.h
+ qml/ftw/qqmlthread.cpp qml/ftw/qqmlthread_p.h
+ qml/ftw/qrecursionwatcher_p.h
+ qml/ftw/qrecyclepool_p.h
+ qml/ftw/qstringhash_p.h
+ qml/qqml.cpp qml/qqml.h
+ qml/qqmlabstractbinding.cpp qml/qqmlabstractbinding_p.h
+ qml/qqmlabstracturlinterceptor.cpp qml/qqmlabstracturlinterceptor.h
+ qml/qqmlapplicationengine.cpp qml/qqmlapplicationengine.h qml/qqmlapplicationengine_p.h
+ qml/qqmlbinding.cpp qml/qqmlbinding_p.h
+ qml/qqmlboundsignal.cpp qml/qqmlboundsignal_p.h
+ qml/qqmlboundsignalexpressionpointer_p.h
+ qml/qqmlcleanup.cpp qml/qqmlcleanup_p.h
+ qml/qqmlcomponent.cpp qml/qqmlcomponent.h qml/qqmlcomponent_p.h
+ qml/qqmlcomponentattached_p.h
+ qml/qqmlcontext.cpp qml/qqmlcontext.h qml/qqmlcontext_p.h
+ qml/qqmlcontextdata.cpp qml/qqmlcontextdata_p.h
+ qml/qqmlcustomparser.cpp qml/qqmlcustomparser_p.h
+ qml/qqmldata_p.h
+ qml/qqmldatablob.cpp qml/qqmldatablob_p.h
+ qml/qqmldelayedcallqueue.cpp qml/qqmldelayedcallqueue_p.h
+ qml/qqmldirdata.cpp qml/qqmldirdata_p.h
+ qml/qqmlengine.cpp qml/qqmlengine.h qml/qqmlengine_p.h
+ qml/qqmlenumdata_p.h
+ qml/qqmlenumvalue_p.h
+ qml/qqmlerror.cpp qml/qqmlerror.h
+ qml/qqmlexpression.cpp qml/qqmlexpression.h qml/qqmlexpression_p.h
+ qml/qqmlextensioninterface.h
+ qml/qqmlextensionplugin.cpp qml/qqmlextensionplugin.h qml/qqmlextensionplugin_p.h
+ qml/qqmlfile.cpp qml/qqmlfile.h
+ qml/qqmlfileselector.cpp qml/qqmlfileselector.h qml/qqmlfileselector_p.h
+ qml/qqmlglobal.cpp qml/qqmlglobal_p.h
+ qml/qqmlguard_p.h
+ qml/qqmlguardedcontextdata_p.h
+ qml/qqmlimport.cpp qml/qqmlimport_p.h
+ qml/qqmlincubator.cpp qml/qqmlincubator.h qml/qqmlincubator_p.h
+ qml/qqmlinfo.cpp qml/qqmlinfo.h
+ qml/qqmlirloader.cpp qml/qqmlirloader_p.h
+ qml/qqmljavascriptexpression.cpp qml/qqmljavascriptexpression_p.h
+ qml/qqmllist.cpp qml/qqmllist.h qml/qqmllist_p.h
+ qml/qqmllistwrapper.cpp qml/qqmllistwrapper_p.h
+ qml/qqmlloggingcategory.cpp qml/qqmlloggingcategory_p.h
+ qml/qqmlmetaobject.cpp qml/qqmlmetaobject_p.h
+ qml/qqmlmetatype.cpp qml/qqmlmetatype_p.h
+ qml/qqmlmetatypedata.cpp qml/qqmlmetatypedata_p.h
+ qml/qqmlmoduleregistration.cpp qml/qqmlmoduleregistration.h
+ qml/qqmlnetworkaccessmanagerfactory.cpp qml/qqmlnetworkaccessmanagerfactory.h
+ qml/qqmlnotifier.cpp qml/qqmlnotifier_p.h
+ qml/qqmlobjectcreator.cpp qml/qqmlobjectcreator_p.h
+ qml/qqmlobjectorgadget.cpp qml/qqmlobjectorgadget_p.h
+ qml/qqmlopenmetaobject.cpp qml/qqmlopenmetaobject_p.h
+ qml/qqmlparserstatus.cpp qml/qqmlparserstatus.h
+ qml/qqmlplatform.cpp qml/qqmlplatform_p.h
+ qml/qqmlprivate.h
+ qml/qqmlproperty.cpp qml/qqmlproperty.h qml/qqmlproperty_p.h
+ qml/qqmlpropertybinding.cpp qml/qqmlpropertybinding_p.h
+ qml/qqmlpropertycache.cpp qml/qqmlpropertycache_p.h
+ qml/qqmlpropertycachecreator.cpp qml/qqmlpropertycachecreator_p.h
+ qml/qqmlpropertycachemethodarguments_p.h
+ qml/qqmlpropertycachevector_p.h
+ qml/qqmlpropertydata_p.h
+ qml/qqmlpropertyindex_p.h
+ qml/qqmlpropertyresolver.cpp qml/qqmlpropertyresolver_p.h
+ qml/qqmlpropertyvalidator.cpp qml/qqmlpropertyvalidator_p.h
+ qml/qqmlpropertyvalueinterceptor.cpp qml/qqmlpropertyvalueinterceptor_p.h
+ qml/qqmlpropertyvaluesource.cpp qml/qqmlpropertyvaluesource.h
+ qml/qqmlproxymetaobject.cpp qml/qqmlproxymetaobject_p.h
+ qml/qqmlscriptblob.cpp qml/qqmlscriptblob_p.h
+ qml/qqmlscriptdata.cpp qml/qqmlscriptdata_p.h
+ qml/qqmlscriptstring.cpp qml/qqmlscriptstring.h qml/qqmlscriptstring_p.h
+ qml/qqmlsourcecoordinate_p.h
+ qml/qqmlstaticmetaobject.cpp qml/qqmlstaticmetaobject_p.h
+ qml/qqmlstringconverters.cpp qml/qqmlstringconverters_p.h
+ qml/qqmltype.cpp qml/qqmltype_p.h
+ qml/qqmltype_p_p.h
+ qml/qqmltypecompiler.cpp qml/qqmltypecompiler_p.h
+ qml/qqmltypedata.cpp qml/qqmltypedata_p.h
+ qml/qqmltypeloader.cpp qml/qqmltypeloader_p.h
+ qml/qqmltypeloaderqmldircontent.cpp qml/qqmltypeloaderqmldircontent_p.h
+ qml/qqmltypeloaderthread.cpp qml/qqmltypeloaderthread_p.h
+ qml/qqmltypemodule.cpp qml/qqmltypemodule_p.h
+ qml/qqmltypemodule_p_p.h
+ qml/qqmltypemoduleversion.cpp qml/qqmltypemoduleversion_p.h
+ qml/qqmltypenamecache.cpp qml/qqmltypenamecache_p.h
+ qml/qqmltypenotavailable.cpp qml/qqmltypenotavailable_p.h
+ qml/qqmltypewrapper.cpp qml/qqmltypewrapper_p.h
+ qml/qqmlvaluetype.cpp qml/qqmlvaluetype_p.h
+ qml/qqmlvaluetypeproxybinding.cpp qml/qqmlvaluetypeproxybinding_p.h
+ qml/qqmlvaluetypewrapper.cpp
+ qml/qqmlvme.cpp qml/qqmlvme_p.h
+ qml/qqmlvmemetaobject.cpp qml/qqmlvmemetaobject_p.h
+ qml/v8/qqmlbuiltinfunctions.cpp qml/v8/qqmlbuiltinfunctions_p.h
+ qml/v8/qv4domerrors.cpp qml/v8/qv4domerrors_p.h
+ qml/v8/qv4sqlerrors.cpp qml/v8/qv4sqlerrors_p.h
+ qmldirparser/qqmldirparser.cpp qmldirparser/qqmldirparser_p.h
+ qtqmlcompilerglobal.h qtqmlcompilerglobal_p.h
+ qtqmlglobal.h qtqmlglobal_p.h
+ types/qqmlbind.cpp types/qqmlbind_p.h
+ types/qqmlconnections.cpp types/qqmlconnections_p.h
+ util/qqmlpropertymap.cpp util/qqmlpropertymap.h
+ DEFINES
+ BUILDING_QT__
+ ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
+ ENABLE_DFG_JIT=0
+ ENABLE_DFG_JIT_UTILITY_METHODS=1
+ ENABLE_JIT_CONSTANT_BLINDING=0
+ ENABLE_LLINT=0
+ JS_EXPORT_PRIVATE= # special case
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ WTFInvokeCrashHook=qmlWTFInvokeCrashHook
+ WTFReportAssertionFailure=qmlWTFReportAssertionFailure
+ WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
+ WTFReportBacktrace=qmlWTFReportBacktrace
+ WTF_EXPORT_PRIVATE= # special case
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/compiler
+ ${CMAKE_CURRENT_BINARY_DIR}/jsruntime
+ ${CMAKE_CURRENT_BINARY_DIR}/memory
+ ${CMAKE_CURRENT_BINARY_DIR}/qmldirparser
+ ../3rdparty/masm
+ ../3rdparty/masm/assembler
+ ../3rdparty/masm/disassembler
+ ../3rdparty/masm/disassembler/udis86
+ ../3rdparty/masm/jit
+ ../3rdparty/masm/runtime
+ ../3rdparty/masm/stubs
+ ../3rdparty/masm/stubs/runtime
+ ../3rdparty/masm/stubs/wtf
+ ../3rdparty/masm/wtf
+ .generated
+ compiler
+ debugger
+ jsruntime
+ memory
+ qmldirparser
+ LIBRARIES
+ Qt::CorePrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+)
+
+# special case begin remove the block, handled manually
+# QLALR Grammars:
+#qt_process_qlalr(
+# Qml
+# parser/qqmljs.g
+# ""
+#)
+
+qt_declarative_write_tag_header(Qml)
+set(_qt_qlalr_flags "--no-debug" "--qt")
+qt_process_qlalr(Qml "${CMAKE_CURRENT_SOURCE_DIR}/parser/qqmljs.g" "${_qt_qlalr_flags}")
+qt_declarative_generate_reg_exp_jit_tables(Qml)
+# special case end
+
+#### Keys ignored in scope 1:.:.:qml.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQml"
+# QML_IMPORT_NAME = "QtQml"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_network
+ SOURCES
+ qml/qqmltypeloadernetworkreplyproxy.cpp qml/qqmltypeloadernetworkreplyproxy_p.h
+ PUBLIC_LIBRARIES
+ Qt::Network
+)
+
+qt_extend_target(Qml CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386")
+ LINK_OPTIONS
+ "/BASE:0x66000000"
+)
+
+qt_extend_target(Qml CONDITION MSVC
+ DEFINES
+ _CRT_SECURE_NO_WARNINGS
+)
+
+qt_extend_target(Qml CONDITION WIN32 AND NOT WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorWin.cpp
+ PUBLIC_LIBRARIES
+ shell32
+)
+
+#### Keys ignored in scope 6:.:.:qml.pro:solaris-cc_x_:
+# QMAKE_CXXFLAGS_RELEASE = "--O2"
+
+qt_extend_target(Qml CONDITION GCC AND (TEST_architecture_arch STREQUAL "mips")
+ COMPILE_OPTIONS
+ -fno-reorder-blocks
+)
+
+qt_extend_target(Qml CONDITION EXISTS "qqml_enable_gcov"
+ LIBRARIES
+ gcov
+ COMPILE_OPTIONS
+ -fno-elide-constructors
+ -fprofile-arcs
+ -ftest-coverage
+)
+
+qt_extend_target(Qml CONDITION release AND MSVC AND (QT_CL_MAJOR_VERSION EQUAL 19) AND (QT_CL_MINOR_VERSION EQUAL 00) AND (QT_CL_PATCH_VERSION GREATER 24212)
+ COMPILE_OPTIONS
+ -d2SSAOptimizer-
+)
+
+#### Keys ignored in scope 10:.:.:qml.pro:ICC:
+# WERROR = "-ww2415"
+
+#### Keys ignored in scope 11:.:.:qml.pro:(QT_CLANG_MAJOR_VERSION GREATER 3) OR (QT_CLANG_MINOR_VERSION GREATER 3) OR (QT_APPLE_CLANG_MAJOR_VERSION GREATER 5) OR ( (QT_APPLE_CLANG_MAJOR_VERSION EQUAL 5) AND (QT_APPLE_CLANG_MINOR_VERSION GREATER 0) ):
+# WERROR = "-Wno-error=unused-const-variable"
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_jit
+ SOURCES
+ jit/qv4assemblercommon.cpp jit/qv4assemblercommon_p.h
+ jit/qv4baselineassembler.cpp jit/qv4baselineassembler_p.h
+ jit/qv4baselinejit.cpp jit/qv4baselinejit_p.h
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/jit
+ jit
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_animation
+ SOURCES
+ animations/qabstractanimationjob.cpp animations/qabstractanimationjob_p.h
+ animations/qanimationgroupjob.cpp animations/qanimationgroupjob_p.h
+ animations/qanimationjobutil_p.h
+ animations/qcontinuinganimationgroupjob.cpp animations/qcontinuinganimationgroupjob_p.h
+ animations/qparallelanimationgroupjob.cpp animations/qparallelanimationgroupjob_p.h
+ animations/qpauseanimationjob.cpp animations/qpauseanimationjob_p.h
+ animations/qsequentialanimationgroupjob.cpp animations/qsequentialanimationgroupjob_p.h
+ types/qqmltimer.cpp types/qqmltimer_p.h
+ INCLUDE_DIRECTORIES
+ animations
+)
+
+#### Keys ignored in scope 17:.:common:common/common.pri:NOT build_pass:
+# compile_hash_contents = "// Generated file, DO NOT EDIT" "$${LITERAL_HASH}define QML_COMPILE_HASH "$$QML_COMPILE_HASH"" "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
+# tag = <EMPTY>
+# tagFile = "$$PWD/../../.tag"
+
+#### Keys ignored in scope 18:.:common:common/common.pri:EXISTS _ss_tagFile:
+# QMAKE_INTERNAL_INCLUDED_FILES = "$$tagFile"
+# tag = "$$cat($$tagFile, singleline)"
+
+#### Keys ignored in scope 19:.:common:common/common.pri:NOT tag___equals____ss_{LITERAL_DOLLAR}Format AND %H_ss_{LITERAL_DOLLAR}:
+# QML_COMPILE_HASH = "$$tag"
+
+#### Keys ignored in scope 21:.:common:common/common.pri:EXISTS _ss_PWD/../../.git:
+# QML_COMPILE_HASH = "$$commit"
+# commit = "$$system(git rev-parse HEAD)"
+
+qt_extend_target(Qml CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5
+ COMPILE_OPTIONS
+ -fno-strict-aliasing
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_debug
+ SOURCES
+ debugger/qqmlabstractprofileradapter.cpp debugger/qqmlabstractprofileradapter_p.h
+ debugger/qqmlconfigurabledebugservice_p.h
+ debugger/qqmldebug.cpp
+ debugger/qqmldebugconnector.cpp
+ debugger/qqmldebugpluginmanager_p.h
+ debugger/qqmldebugserver_p.h
+ debugger/qqmldebugserverconnection_p.h
+ debugger/qqmldebugservice.cpp debugger/qqmldebugservice_p.h
+ debugger/qqmldebugservicefactory_p.h
+ debugger/qqmldebugserviceinterfaces.cpp
+ debugger/qqmlprofiler.cpp
+ debugger/qqmlprofilerdefinitions_p.h
+ jsruntime/qv4profiling.cpp
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_sequence_object
+ SOURCES
+ jsruntime/qv4sequenceobject.cpp jsruntime/qv4sequenceobject_p.h
+)
+
+qt_extend_target(Qml CONDITION UNIX
+ SOURCES
+ jsruntime/qv4compilationunitmapper_unix.cpp
+ jsruntime/qv4functiontable_unix.cpp
+)
+
+qt_extend_target(Qml CONDITION WIN32
+ SOURCES
+ jsruntime/qv4compilationunitmapper_win.cpp
+ DEFINES
+ NOMINMAX
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "x86_64") AND WIN32 AND NOT WINRT
+ SOURCES
+ jsruntime/qv4functiontable_win64.cpp
+)
+
+qt_extend_target(Qml CONDITION WIN32 AND (WINRT OR NOT (TEST_architecture_arch STREQUAL "x86_64"))
+ SOURCES
+ jsruntime/qv4functiontable_noop.cpp
+)
+
+qt_extend_target(Qml CONDITION valgrind
+ DEFINES
+ V4_USE_VALGRIND
+)
+
+qt_extend_target(Qml CONDITION heaptrack
+ DEFINES
+ V4_USE_HEAPTRACK
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_xml_http_request
+ SOURCES
+ qml/qqmlxmlhttprequest.cpp qml/qqmlxmlhttprequest_p.h
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_locale
+ SOURCES
+ qml/qqmllocale.cpp qml/qqmllocale_p.h
+)
+
+qt_extend_target(Qml CONDITION ANDROID
+ DEFINES
+ LIBS_SUFFIX="_${CMAKE_SYSTEM_PROCESSOR}.so"
+)
+
+qt_extend_target(Qml CONDITION hpux-_x_ OR solaris-_x_ OR (QT_FEATURE_clock_gettime AND linux-_x_)
+ LIBRARIES
+ rt
+)
+
+qt_extend_target(Qml CONDITION QT_FEATURE_qml_itemmodel
+ SOURCES
+ types/qqmlmodelindexvaluetype.cpp types/qqmlmodelindexvaluetype_p.h
+)
+
+qt_extend_target(Qml CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64"))
+ DEFINES
+ WTF_USE_UDIS86=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler
+ DEFINES
+ WTF_USE_ARMV7_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler
+ DEFINES
+ WTF_USE_ARM64_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler
+ DEFINES
+ WTF_USE_MIPS32_DISASSEMBLER=1
+)
+
+qt_extend_target(Qml CONDITION NOT disassembler
+ DEFINES
+ WTF_USE_UDIS86=0
+)
+
+qt_extend_target(Qml CONDITION CMAKE_BUILD_TYPE STREQUAL Release
+ DEFINES
+ NDEBUG
+)
+
+qt_extend_target(Qml CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC
+ COMPILE_OPTIONS
+ -Wno-expansion-to-defined
+)
+
+#### Keys ignored in scope 65:.:../3rdparty/masm:../3rdparty/masm/masm-defs.pri:(QT_COMPILER_VERSION_MAJOR STRGREATER 6):
+# QMAKE_CXXFLAGS_WARN_ON = "-Wno-expansion-to-defined"
+
+qt_extend_target(Qml CONDITION WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorWinRT.cpp
+)
+
+qt_extend_target(Qml CONDITION INTEGRITY
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorIntegrity.cpp
+)
+
+qt_extend_target(Qml CONDITION UNIX AND NOT INTEGRITY AND NOT WINRT
+ SOURCES
+ ../3rdparty/masm/wtf/OSAllocatorPosix.cpp
+)
+
+qt_extend_target(Qml CONDITION DEFINES___contains___WTF_USE_UDIS86=1
+ SOURCES
+ ../3rdparty/masm/disassembler/udis86/udis86.c
+ ../3rdparty/masm/disassembler/udis86/udis86_decode.c
+ ../3rdparty/masm/disassembler/udis86/udis86_input.c
+ ../3rdparty/masm/disassembler/udis86/udis86_itab_holder.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn-att.c
+ ../3rdparty/masm/disassembler/udis86/udis86_syn-intel.c
+)
+
+#### Keys ignored in scope 73:.:../3rdparty/masm:../3rdparty/masm/masm.pri:DEFINES___contains___WTF_USE_UDIS86=1:
+# ITAB = "$$PWD/disassembler/udis86/optable.xml"
+# QMAKE_EXTRA_COMPILERS = "udis86"
+# QMAKE_EXTRA_TARGETS = "udis86_tab_cfile"
+# udis86.CONFIG = "no_link"
+# udis86.commands = "python" "$$PWD/disassembler/udis86/itab.py" "${QMAKE_FILE_IN}"
+# udis86.input = "ITAB"
+# udis86.output = "udis86_itab.h"
+# udis86_tab_cfile.depends = "udis86_itab.h"
+# udis86_tab_cfile.target = "$$OUT_PWD/udis86_itab.c"
+
+#### Keys ignored in scope 75:.:../3rdparty/masm:../3rdparty/masm/masm.pri:(CMAKE_BUILD_TYPE STREQUAL Debug):
+# GENERATEDDIR = "$$GENERATEDDIR/debug"
+
+#### Keys ignored in scope 76:.:../3rdparty/masm:../3rdparty/masm/masm.pri:else:
+# GENERATEDDIR = "$$GENERATEDDIR/release"
+
+qt_extend_target(Qml CONDITION (NOT c++11 AND NOT ICC) AND (CLANG)
+ COMPILE_OPTIONS
+ -Wno-c++0x-extensions
+ -Wno-c++11-extensions
+)
+
+qt_extend_target(Qml CONDITION (((NOT c++11 AND NOT ICC) AND (NOT (CLANG))) AND (GCC)) AND ((QT_COMPILER_VERSION_MAJOR STRGREATER 4) OR (QT_COMPILER_VERSION_MINOR STRGREATER 5))
+ COMPILE_OPTIONS
+ -Wno-c++0x-compat
+)
+
+
+qt_create_tracepoints(Qml qtqml.tracepoints)
+qt_add_docs(Qml
+ doc/qtqml.qdocconf
+)
+
+
+set_target_properties(Qml PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQml
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQml"
+)
+
+qt6_qml_type_registration(Qml)
+
+include(Qt6QmlBuildInternals.cmake) # special case
diff --git a/src/qml/Qt6QmlBuildInternals.cmake b/src/qml/Qt6QmlBuildInternals.cmake
new file mode 100644
index 0000000000..a17cae8bf8
--- /dev/null
+++ b/src/qml/Qt6QmlBuildInternals.cmake
@@ -0,0 +1,174 @@
+#
+# QtDeclarative Specific extensions
+#
+
+include_guard(GLOBAL)
+
+# This function creates a CMake target for qml modules. It will also make
+# sure that if no C++ source are present, that qml files show up in the project
+# in an IDE. Finally, it will also create a custom ${target}_qmltypes which
+# can be used to generate the respective plugin.qmltypes file.
+#
+# CPP_PLUGIN: Whether this qml module has any c++ source files.
+# URI: Module's uri.
+# TARGET_PATH: Expected installation path for the Qml Module. Equivalent
+# to the module's URI where '.' is replaced with '/'. Use this to override the
+# default substitution pattern.
+# VERSION: Version of the qml module
+# QML_PLUGINDUMP_DEPENDENCIES: Path to a dependencies.json file to be consumed
+# with the ${target}_qmltypes target (optional)
+# SKIP_TYPE_REGISTRATION: All qml files are expected to be registered by the
+# c++ plugin code.
+#
+function(qt_add_qml_module target)
+
+ set(qml_module_optional_args
+ GENERATE_QMLTYPES
+ DESIGNER_SUPPORTED
+ DO_NOT_INSTALL
+ SKIP_TYPE_REGISTRATION
+ )
+
+ set(qml_module_single_args
+ URI
+ TARGET_PATH
+ VERSION
+ QML_PLUGINDUMP_DEPENDENCIES
+ CLASSNAME
+ )
+
+ set(qml_module_multi_args
+ IMPORTS
+ TYPEINFO
+ DEPENDENCIES
+ )
+
+ qt_parse_all_arguments(arg "qt_add_qml_module"
+ "${__qt_add_plugin_optional_args};${qml_module_optional_args}"
+ "${__qt_add_plugin_single_args};${qml_module_single_args}"
+ "${__qt_add_plugin_multi_args};${qml_module_multi_args}" ${ARGN})
+
+ if (NOT arg_URI)
+ message(FATAL_ERROR "qt_add_qml_module called without specifying the module's uri. Please specify one using the URI parameter.")
+ endif()
+
+ set(target_path ${arg_TARGET_PATH})
+
+ if (NOT arg_VERSION)
+ message(FATAL_ERROR "qt_add_qml_module called without specifying the module's import version. Please specify one using the VERSION parameter.")
+ endif()
+
+ if (NOT arg_TARGET_PATH)
+ string(REPLACE "." "/" arg_TARGET_PATH ${arg_URI})
+ endif()
+
+ qt_remove_args(plugin_args
+ ARGS_TO_REMOVE
+ ${target}
+ ${qml_module_multi_args}
+ ${qml_module_single_args}
+ ALL_ARGS
+ ${__qt_add_plugin_optional_args}
+ ${__qt_add_plugin_single_args}
+ ${qml_module_single_args}
+ ${__qt_add_plugin_multi_args}
+ ${qml_module_multi_args}
+ ARGS
+ ${ARGV}
+ )
+
+ # If we have no sources, but qml files, create a custom target so the
+ # qml file will be visibile in an IDE.
+ if (arg_SOURCES)
+ qt_add_plugin(${target}
+ TYPE
+ qml_plugin
+ QML_TARGET_PATH
+ "${arg_TARGET_PATH}"
+ ${plugin_args}
+ )
+ endif()
+
+
+ if (arg_CPP_PLUGIN)
+ set(no_create_option DO_NOT_CREATE_TARGET)
+ endif()
+
+ if (arg_CLASSNAME)
+ set(classname_arg CLASSNAME ${arg_CLASSNAME})
+ endif()
+
+ if (arg_DESIGNER_SUPPORTED)
+ set(designer_supported_arg DESIGNER_SUPPORTED)
+ endif()
+
+ if (arg_SKIP_TYPE_REGISTRATION)
+ set(skip_registration_arg SKIP_TYPE_REGISTRATION)
+ endif()
+
+ if (arg_GENERATE_QMLTYPES)
+ set(generate_qmltypes_arg GENERATE_QMLTYPES)
+ endif()
+
+ qt_path_join(qml_module_install_dir ${QT_INSTALL_DIR} "${INSTALL_QMLDIR}/${arg_TARGET_PATH}")
+
+ qt6_add_qml_module(${target}
+ ${designer_supported_arg}
+ ${no_create_option}
+ ${skip_registration_arg}
+ ${classname_arg}
+ ${generate_qmltypes_arg}
+ RESOURCE_PREFIX "/qt-project.org/imports"
+ TARGET_PATH ${arg_TARGET_PATH}
+ URI ${arg_URI}
+ VERSION ${arg_VERSION}
+ QML_FILES ${arg_QML_FILES}
+ IMPORTS "${arg_IMPORTS}"
+ TYPEINFO "${arg_TYPEINFO}"
+ DO_NOT_INSTALL_METADATA
+ DO_NOT_CREATE_TARGET
+ INSTALL_QML_FILES
+ INSTALL_LOCATION "${qml_module_install_dir}"
+ DEPENDENCIES ${arg_DEPENDENCIES}
+ RESOURCE_EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets"
+ )
+
+ get_target_property(qmldir_file ${target} QT_QML_MODULE_QMLDIR_FILE)
+ get_target_property(plugin_types ${target} QT_QML_MODULE_PLUGIN_TYPES_FILE)
+ set(files_to_install)
+ if (EXISTS ${plugin_types})
+ list(APPEND files_to_install ${plugin_types})
+ qt_copy_or_install(FILES ${plugin_types}
+ DESTINATION "${qml_module_install_dir}"
+ )
+
+ if(QT_WILL_INSTALL)
+ # plugin.qmltypes when present should also be copied to the
+ # cmake binary dir when doing prefix builds
+ file(COPY ${plugin_types}
+ DESTINATION "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/${arg_TARGET_PATH}"
+ )
+ endif()
+ endif()
+
+ list(APPEND files_to_install ${qmldir_file})
+ if (QT_WILL_INSTALL)
+ install(FILES ${files_to_install} DESTINATION ${qml_module_install_dir})
+ endif()
+
+ set(copy_destination "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/${arg_TARGET_PATH}")
+ foreach(file IN LISTS files_to_install)
+ get_filename_component(file_name "${file}" NAME)
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${file}"
+ "${copy_destination}/${file_name}"
+ COMMENT "Copying ${file} to ${copy_destination}"
+ )
+ endforeach()
+endfunction()
+
+function(add_qml_module)
+ qt_add_qml_module(${ARGV})
+endfunction()
+
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
new file mode 100644
index 0000000000..1e3ac50b57
--- /dev/null
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -0,0 +1,756 @@
+#
+# Q6QmlMacros
+#
+
+#
+# Create a Qml Module. Arguments:
+#
+# URI: Declares the module identifier of the module. The module identifier is
+# the (dotted URI notation) identifier for the module, which must match the
+# module's install path. (REQUIRED)
+#
+# VERSION: The module's version. (REQUIRED)
+#
+# TARGET_PATH: Overwrite the generated target path. By default the target path
+# is generated from the URI by replacing the '.' with a '/'. However, under
+# certain circumstance this may not be enough. Use this argument to provide
+# a replacement. (OPTIONAL)
+#
+# RESOURCE_PREFIX: Resource Prefix to be used when generating a static library.
+# When building a static library, the qmldir file is embedded into the library
+# using rcc. It is is also used by the Qt Quick Compiler to embed compiled
+# Qml files into a shared or static library. If none is supplied we will
+# generate the following prefix: /org.qt-project/imports/${target_path}.
+# (OPTIONAL)
+#
+# OUTPUT_DIRECTORY: If the module is not to be build under
+# ${CMAKE_CURRENT_BINARY_DIR}. This ensures the qmldir file is copied to the
+# right location. (OPTIONAL)
+#
+# INSTALL_LOCATION: Intended installation directory for this module. If no
+# value is supplied, the default installation path will be ${INSTALL_QMLDIR}.
+# (OPTIONAL).
+#
+# DO_NOT_INSTALL_METADATA: When present, will not install the supporting files.
+#
+# INSTALL_QML_FILES: When present, will install the qml files along side the
+# plugin.
+#
+# SOURCES: List of C++ sources. (OPTIONAL)
+#
+# DEPENDENCIES: List of QML Module dependencies and their versions. The module
+# and its version must be separated via a slash(/). E.g. QtQuick/2.0
+#
+# QML_FILES: List of Qml files. See qt6_target_qml_files for more information
+# on how to specify additional properties on qml files. (OPTIONAL)
+#
+# CLASSNAME: Provides the class name of the C++ plugin used by the module. This
+# information is required for all the QML modules that depend on a C++ plugin
+# for additional functionality. Qt Quick applications built with static
+# linking cannot resolve the module imports without this information.
+# (REQUIRED for static targets)
+#
+# DESIGNER_SUPPORTED: Specify this argument if the plugin is supported by Qt
+# Quick Designer. By default, the plugin will not be supported. (OPTIONAL)
+#
+# TYPEINFO: Path to a file which declares a type description file for the module
+# that can be read by QML tools such as Qt Creator to access information about
+# the types defined by the module's plugins. (OPTIONAL)
+#
+# IMPORTS: List of other Qml Modules that this module imports. (OPTIONAL)
+#
+# RESOURCE_EXPORT: In static builds, when Qml files are processed via the Qt
+# Quick Compiler generate a separate static library that will be linked in
+# as an Interface. Supply an output variable to perform any custom actions
+# on these extra generated targets.
+#
+# SKIP_TYPE_REGISTRATION: When present will cause the generated qmldir file
+# to not list any qml types. These are expected to be registered by the
+# c++ plugin code instead.
+#
+
+function(qt6_add_qml_module target)
+
+ set(args_optional
+ GENERATE_QMLTYPES
+ DESIGNER_SUPPORTED
+ DO_NOT_INSTALL_METADATA
+ SKIP_TYPE_REGISTRATION
+ INSTALL_QML_FILES
+ )
+
+ if (QT_BUILDING_QT)
+ list(APPEND args_optional DO_NOT_CREATE_TARGET)
+ endif()
+
+ set(args_single
+ RESOURCE_PREFIX
+ URI
+ TARGET_PATH
+ VERSION
+ OUTPUT_DIRECTORY
+ INSTALL_LOCATION
+ CLASSNAME
+ TYPEINFO
+ RESOURCE_EXPORT
+ )
+
+ set(args_multi
+ SOURCES
+ QML_FILES
+ IMPORTS
+ DEPENDENCIES
+ )
+
+ cmake_parse_arguments(arg
+ "${args_optional}"
+ "${args_single}"
+ "${args_multi}"
+ ${ARGN}
+ )
+
+ if (NOT arg_URI)
+ message(FATAL_ERROR "qt6_add_qml_module called without a module URI. Please specify one using the URI argument.")
+ endif()
+
+ if (NOT arg_VERSION)
+ message(FATAL_ERROR "qt6_add_qml_module called without a module version. Please specify one using the VERSION argument.")
+ endif()
+
+ if (NOT "${arg_VERSION}" MATCHES "[0-9]+\\.[0-9]+")
+ message(FATAL_ERROR "qt6_add_qml_module called with an invalid version argument: '${arg_VERSION}'. Expected version style: VersionMajor.VersionMinor.")
+ endif()
+
+ if (NOT BUILD_SHARED_LIBS AND NOT arg_CLASSNAME)
+ message(FATAL_ERROR "qt6_add_qml_module Static builds of Qml modules require a class name, none was provided. Please specify one using the CLASSNAME argument.")
+ endif()
+
+ if (arg_DO_NOT_CREATE_TARGET AND NOT TARGET ${target})
+ message(FATAL_ERROR "qt6_add_qml_module called with DO_NOT_CREATE_TARGET, but the given target '${target}' is not a cmake target")
+ endif()
+
+ if (arg_DO_NOT_CREATE_TARGET)
+ get_target_property(target_type ${target} TYPE)
+ if (target_type STREQUAL "STATIC_LIBRARY")
+ set(is_static TRUE)
+ elseif(target_type STREQUAL "MODULE_LIBRARY")
+ set(is_static FALSE)
+ else()
+ message(FATAL_ERROR "qt6_add_qml_module called with DO_NOT_CREATE_TARGET, but target '${target}' is neither a static or a module library.")
+ endif()
+ else()
+ if(NOT BUILD_SHARED_LIBS)
+ add_library(${target} STATIC)
+ set(is_static TRUE)
+ else()
+ add_library(${target} MODULE)
+ set(is_static FALSE)
+ endif()
+ endif()
+
+ if (NOT arg_TARGET_PATH)
+ string(REPLACE "." "/" arg_TARGET_PATH ${arg_URI})
+ endif()
+
+ if (NOT arg_RESOURCE_PREFIX)
+ set(arg_RESOURCE_PREFIX "/org.qt-project/imports")
+ endif()
+
+ if (NOT arg_INSTALL_LOCATION)
+ set(arg_INSTALL_LOCATION "${INSTALL_QMLDIR}/${arg_TARGET_PATH}")
+ endif()
+ if (DEFINED QT_WILL_INSTALL AND NOT QT_WILL_INSTALL
+ AND NOT IS_ABSOLUTE "${arg_INSTALL_LOCATION}")
+ set(arg_INSTALL_LOCATION "${QT_BUILD_DIR}/${arg_INSTALL_LOCATION}")
+ endif()
+
+ set_target_properties(${target}
+ PROPERTIES
+ QT_QML_MODULE_TARGET_PATH ${arg_TARGET_PATH}
+ QT_QML_MODULE_URI ${arg_URI}
+ QT_RESOURCE_PREFIX ${arg_RESOURCE_PREFIX}/${arg_TARGET_PATH}
+ QT_QML_MODULE_VERSION ${arg_VERSION}
+ QT_QML_MODULE_INSTALL_DIR ${arg_INSTALL_LOCATION}
+ QT_QML_MODULE_RESOURCE_EXPORT "${arg_RESOURCE_EXPORT}"
+ )
+
+ if (arg_OUTPUT_DIRECTORY AND NOT DO_NOT_CREATE_TARGET)
+ set_target_properties(${target}
+ PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY}
+ ARCHIVE_OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY}
+ )
+ endif()
+ if (arg_OUTPUT_DIRECTORY)
+ set(target_output_dir ${arg_OUTPUT_DIRECTORY})
+ else()
+ if(is_static)
+ get_target_property(target_output_dir ${target} ARCHIVE_OUTPUT_DIRECTORY)
+ else()
+ get_target_property(target_output_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
+ endif()
+ endif()
+
+ if (arg_INSTALL_QML_FILES)
+ set_target_properties(${target} PROPERTIES QT_QML_MODULE_INSTALL_QML_FILES TRUE)
+ endif()
+
+ if (arg_SKIP_TYPE_REGISTRATION)
+ set_target_properties(${target} PROPERTIES QT_QML_MODULE_SKIP_TYPE_REGISTRATION TRUE)
+ endif()
+
+ if (arg_SOURCES)
+ target_sources(${target} PRIVATE ${arg_SOURCES})
+ endif()
+
+ # Tracker so we can generate unique resource names for multiple
+ # target_qml_files() calls.
+ set_target_properties(${target} PROPERTIES QT6_QML_MODULE_ADD_QML_FILES_COUNT 1)
+
+ # Generate qmldir file
+ set(qmldir_file "${CMAKE_CURRENT_BINARY_DIR}/qmldir")
+ set_target_properties(${target} PROPERTIES QT_QML_MODULE_QMLDIR_FILE ${qmldir_file})
+ set(qmldir_file_contents "module ${arg_URI}\n")
+ string(APPEND qmldir_file_contents "plugin ${target}\n")
+ if (arg_CLASSNAME)
+ string(APPEND qmldir_file_contents "classname ${arg_CLASSNAME}\n")
+ endif()
+ if (arg_DESIGNER_SUPPORTED)
+ string(APPEND qmldir_file_contents "designersupported\n")
+ endif()
+ if (arg_TYPEINFO)
+ string(APPEND qmldir_file_contents "typeinfo ${arg_TYPEINFO}\n")
+ else()
+ # This always need to be written out since at the moment we have cases
+ # where qmltyperegistrar is not run with the plugin but on a module
+ # e.g: src/qml generates the qmltypes for src/imports/qtqml.
+ # When this has been fixed/standardized we should move this to
+ # qt6_qml_type_registration() so that it is written out when the
+ # plugins.qmltypes is actually generated.
+ string(APPEND qmldir_file_contents "typeinfo plugins.qmltypes\n")
+ endif()
+ foreach(import IN LISTS arg_IMPORTS)
+ string(APPEND qmldir_file_contents "import ${import}\n")
+ endforeach()
+
+ foreach(dependency IN LISTS arg_DEPENDENCIES)
+ string(FIND ${dependency} "/" slash_position REVERSE)
+ if (slash_position EQUAL -1)
+ message(FATAL_ERROR "Dependencies should follow the format 'ModuleName/VersionMajor.VersionMinor'")
+ endif()
+ string(SUBSTRING ${dependency} 0 ${slash_position} dep_module)
+ math(EXPR slash_position "${slash_position} + 1")
+ string(SUBSTRING ${dependency} ${slash_position} -1 dep_version)
+ if (NOT dep_version MATCHES "[0-9]+\\.[0-9]+")
+ message(FATAL_ERROR "Invalid module dependency version number. Expected VersionMajor.VersionMinor.")
+ endif()
+ string(APPEND qmldir_file_contents "depends ${dep_module} ${dep_version}\n")
+ endforeach()
+
+ file(WRITE ${qmldir_file} ${qmldir_file_contents})
+
+ # Process qml files
+ if (arg_QML_FILES)
+ qt6_target_qml_files(${target} FILES ${arg_QML_FILES})
+ endif()
+
+ # Embed qmldir in static builds
+ if (is_static)
+ string(REPLACE "/" "_" qmldir_resource_name ${arg_TARGET_PATH})
+ string(APPEND qmldir_resource_name "_qmldir")
+
+ set_source_files_properties("${qmldir_file}"
+ PROPERTIES QT_RESOURCE_ALIAS "qmldir"
+ )
+
+ set(resource_target "Foo")
+ QT6_ADD_RESOURCES(${target} ${qmldir_resource_name}
+ PREFIX ${target_resource_prefix}
+ FILES "${qmldir_file}"
+ OUTPUT_TARGETS resource_targets
+ )
+
+ if (resource_targets AND arg_RESOURCE_EXPORT)
+ install(TARGETS ${resource_targets}
+ EXPORT "${arg_RESOURCE_EXPORT}"
+ DESTINATION ${arg_INSTALL_LOCATION}
+ )
+ endif()
+ else()
+ # Copy QMLDIR file to build directory
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${qmldir_file}
+ ${target_output_dir}
+ )
+
+ # Install QMLDIR file
+ if (NOT DO_NOT_INSTALL_METADATA)
+ install(FILES ${qmldir_file}
+ DESTINATION ${arg_INSTALL_LOCATION}
+ )
+ endif()
+ endif()
+
+ # Install and Copy plugin.qmltypes if exists
+ set(target_plugin_qmltypes "${CMAKE_CURRENT_SOURCE_DIR}/plugins.qmltypes")
+ if (EXISTS ${target_plugin_qmltypes})
+ set_target_properties(${target}
+ PROPERTIES QT_QML_MODULE_PLUGIN_TYPES_FILE "${target_plugin_qmltypes}"
+ )
+ file(APPEND ${qmldir_file} "typeinfo plugins.qmltypes\n")
+ if (NOT arg_DO_NOT_INSTALL_METADATA)
+ install(FILES ${target_plugin_qmltypes}
+ DESTINATION ${arg_INSTALL_LOCATION}
+ )
+ endif()
+
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${target_plugin_qmltypes}
+ ${target_output_dir}
+ )
+ endif()
+
+ # Copy/Install type info file
+ if (EXISTS ${arg_TYPEINFO})
+ if (NOT arg_DO_NOT_INSTALL_METADATA)
+ install(FILES ${arg_TYPEINFO}
+ DESTINATION ${arg_INSTALL_LOCATION}
+ )
+ endif()
+
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${arg_TYPEINFO}
+ ${target_output_dir}
+ )
+ endif()
+
+ # Generate meta types data
+ if (arg_GENERATE_QMLTYPES)
+ qt6_qml_type_registration(${target})
+ endif()
+endfunction()
+
+
+#
+# Add Qml files (.qml,.js,.mjs) to a Qml module. This will also append the
+# qml files to the qmldir file of the module. Two source file properties can
+# be used to control the generated qmldir entry.
+#
+# QT_QML_SOURCE_VERSION: Version for this qml file. If not present the module
+# version will be used.
+# QT_QML_SOURCE_TYPENAME: Override the file's type name. If not present the
+# type name will be deduced using the file's basename.
+# QT_QML_SINGLETON_TYPE: Set to true if this qml file contains a singleton
+# type.
+# QT_QML_INTERNAL_TYPE: When set to true, the type specified by
+# QT_QML_SOURCE_TYPENAME will not be available to users of this module.
+# QT_QML_SKIP_QMLDIR_ENTRY: When set to true, no qmldir entry will be created for
+# the source file. Useful if a file needs to be installed (like a private JS
+# file) but does not expose a public type.
+#
+# e.g.:
+# set_source_files_properties(my_qml_file.qml
+# PROPERTIES
+# QT_QML_SOURCE_VERSION 2.0
+# QT_QML_SOURCE_TYPENAME MyQmlFile
+#
+# qt6_target_qml_files(my_qml_module
+# FILES
+# my_qml_file.qml
+# )
+#
+# Will produce the following entry in the qmldir file
+#
+# MyQmlFile 2.0 my_qml_file.qml
+#
+#
+function(qt6_target_qml_files target)
+
+ cmake_parse_arguments(arg "" "" "FILES" ${ARGN})
+ get_target_property(resource_count ${target} QT6_QML_MODULE_ADD_QML_FILES_COUNT)
+ get_target_property(qmldir_file ${target} QT_QML_MODULE_QMLDIR_FILE)
+ get_target_property(install_qml_files ${target} QT_QML_MODULE_INSTALL_QML_FILES)
+ if (NOT qmldir_file)
+ message(FATAL_ERROR "qt6_target_qml_file: ${target} is not a Qml module")
+ endif()
+
+ if (NOT arg_FILES)
+ return()
+ endif()
+ math(EXPR new_count "${resource_count} + 1")
+ set_target_properties(${target} PROPERTIES QT6_QML_MODULE_ADD_QML_FILES_COUNT ${new_count})
+
+ qt6_add_resources(${target} "qml_files${new_count}"
+ FILES ${arg_FILES}
+ OUTPUT_TARGETS resource_targets
+ )
+ get_target_property(skip_type_registration ${target} QT_QML_MODULE_SKIP_TYPE_REGISTRATION)
+ get_target_property(target_resource_export ${target} QT_QML_MODULE_RESOURCE_EXPORT)
+ get_target_property(qml_module_install_dir ${target} QT_QML_MODULE_INSTALL_DIR)
+ if (resource_targets)
+ install(TARGETS ${resource_targets}
+ EXPORT "${target_resource_export}"
+ DESTINATION ${qm_module_install_dir}
+ )
+ endif()
+
+ set(file_contents "")
+ foreach(qml_file IN LISTS arg_FILES)
+ if (install_qml_files)
+ if (NOT QT_WILL_INSTALL)
+ file(COPY "${qml_file}" DESTINATION "${qml_module_install_dir}")
+ else()
+ install(FILES "${qml_file}" DESTINATION "${qml_module_install_dir}")
+ endif()
+ endif()
+
+ if (skip_type_registration AND qml_file MATCHES "\\.qml$")
+ continue()
+ endif()
+
+ get_source_file_property(qml_file_skip_qmldir ${qml_file} QT_QML_SKIP_QMLDIR_ENTRY)
+ if (qml_file_skip_qmldir)
+ continue()
+ endif()
+
+ get_source_file_property(qml_file_version ${qml_file} QT_QML_SOURCE_VERSION)
+ get_source_file_property(qml_file_typename ${qml_file} QT_QML_SOURCE_TYPENAME)
+ get_source_file_property(qml_file_singleton ${qml_file} QT_QML_SINGLETON_TYPE)
+ get_source_file_property(qml_file_internal ${qml_file} QT_QML_INTERNAL_TYPE)
+ get_target_property(qml_module_version ${target} QT_QML_MODULE_VERSION)
+
+ if (NOT qml_file_version)
+ set(qml_file_version ${qml_module_version})
+ endif()
+
+ if (NOT qml_file_typename)
+ get_filename_component(qml_file_typename ${qml_file} NAME_WLE)
+ endif()
+
+ if (qml_file_singleton)
+ string(APPEND file_contents "[singleton] ")
+ endif()
+
+ string(APPEND file_contents "${qml_file_typename} ${qml_file_version} ${qml_file}\n")
+
+ if (qml_file_internal)
+ string(APPEND file_contents "internal ${qml_file_typename} ${qml_file}\n")
+ endif()
+
+ endforeach()
+ file(APPEND ${qmldir_file} ${file_contents})
+endfunction()
+
+# QT_QMLTYPES_FILENAME: If the target has the target property QT_QMLTPYES_FILENAME set, it will be
+# used for the name of the generated file. Otherwise, the file will be named plugins.qmltypes if the
+# target is a plugin, or ${target}.qmltypes in all other cases
+function(qt6_qml_type_registration target)
+
+ get_target_property(import_name ${target} QT_QML_MODULE_URI)
+ if (NOT import_name)
+ message(FATAL_ERROR "Target ${target} is not a QML module")
+ endif()
+ get_target_property(qmltypes_output_name ${target} QT_QMLTYPES_FILENAME)
+ if (NOT qmltypes_output_name)
+ get_target_property(compile_definitions_list ${target} COMPILE_DEFINITIONS)
+ list(FIND compile_definitions_list QT_PLUGIN is_a_plugin)
+ if (is_a_plugin GREATER_EQUAL 0)
+ set(qmltypes_output_name "plugins.qmltypes")
+ else()
+ set(qmltypes_output_name ${target}.qmltypes)
+ endif()
+ endif()
+
+ cmake_parse_arguments(arg "COPY_OVER_INSTALL" "INSTALL_DIR" "" ${ARGN})
+
+ set(meta_types_args)
+ if (QT_BUILDING_QT AND NOT QT_WILL_INSTALL)
+ set(arg_COPY_OVER_INSTALL TRUE)
+ endif()
+ if (arg_INSTALL_DIR)
+ list(APPEND meta_types_args INSTALL_DIR "${arg_INSTALL_DIR}")
+ endif()
+ if (arg_COPY_OVER_INSTALL)
+ list(APPEND meta_types_args COPY_OVER_INSTALL)
+ endif()
+
+ qt6_generate_meta_types_json_file(${target} ${meta_types_args})
+
+ get_target_property(import_version ${target} QT_QML_MODULE_VERSION)
+ get_target_property(target_source_dir ${target} SOURCE_DIR)
+ get_target_property(target_binary_dir ${target} BINARY_DIR)
+ get_target_property(target_metatypes_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
+ if (NOT target_metatypes_file)
+ message(FATAL_ERROR "Target ${target} does not have a meta types file")
+ endif()
+
+ # Extract major and minor version
+ if (NOT import_version MATCHES "[0-9]+\\.[0-9]+")
+ message(FATAL_ERROR "Invalid module dependency version number. Expected VersionMajor.VersionMinor.")
+ endif()
+ #string(FIND "${import_version}" "." dot_location)
+ #string(SUBSTRING ${import_version} 0 ${dot_location} major_version)
+ #math(EXPR dot_location "${dot_location}+1")
+ #string(SUBSTRING ${import_version} ${dot_location} -1 minor_version)
+ string(REPLACE "." ";" import_version_split "${import_version}")
+ list(LENGTH import_version_split import_version_split_length)
+ if(import_version_split_length GREATER 0)
+ list(GET import_version_split 0 major_version)
+ endif()
+ if(import_version_split_length GREATER 1)
+ list(GET import_version_split 1 minor_version)
+ endif()
+
+ # check if plugins.qmltypes is already defined
+ get_target_property(target_plugin_qmltypes ${target} QT_QML_MODULE_PLUGIN_TYPES_FILE)
+ if (target_plugin_qmltypes)
+ message(FATAL_ERROR "Target ${target} already has a qmltypes file set.")
+ endif()
+
+ set(cmd_args)
+ set(plugin_types_file ${target_binary_dir}/${qmltypes_output_name})
+ set_target_properties(${target} PROPERTIES
+ QT_QML_MODULE_PLUGIN_TYPES_FILE ${plugin_types_file}
+ )
+ list(APPEND cmd_args
+ --generate-qmltypes=${plugin_types_file}
+ --import-name=${import_name}
+ --major-version=${major_version}
+ --minor-version=${minor_version}
+ )
+
+ # Run a script to recursively evaluate all the metatypes.json files in order
+ # to collect all foreign types.
+ string(TOLOWER "${target}_qmltyperegistrations.cpp" type_registration_cpp_file_name)
+ set(foreign_types_file "${target_binary_dir}/qmltypes/foreign_types.txt")
+ set(type_registration_cpp_file "${target_binary_dir}/${type_registration_cpp_file_name}")
+
+ set(dependency_file_cpp "${target_binary_dir}/qmltypes/${type_registration_cpp_file_name}.d")
+ file(RELATIVE_PATH cpp_file_name "${${CMAKE_PROJECT_NAME}_BINARY_DIR}" "${type_registration_cpp_file}")
+
+ set (use_dep_files FALSE)
+ if (CMAKE_GENERATOR STREQUAL "Ninja" OR CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
+ set(use_dep_files TRUE)
+ endif()
+
+ # Enable evaluation of metatypes.json source interfaces
+ set_target_properties(${target} PROPERTIES QT_CONSUMES_METATYPES TRUE)
+ set(genex_list "$<REMOVE_DUPLICATES:$<FILTER:$<TARGET_PROPERTY:${target},SOURCES>,INCLUDE,metatypes.json$>>")
+ set(genex_main "$<JOIN:${genex_list},$<COMMA>>")
+ file(GENERATE OUTPUT "${foreign_types_file}"
+ CONTENT "$<IF:$<BOOL:${genex_list}>,--foreign-types=${genex_main},\n>"
+ )
+
+ list(APPEND cmd_args
+ "@${foreign_types_file}"
+ )
+
+ set(dependencies_json_file "${target_source_dir}/dependencies.json")
+ if (EXISTS ${dependencies_json_file})
+ list(APPEND cmd_args --dependencies=${dependencies_json_file})
+ endif()
+
+ if (TARGET ${target}Private)
+ list(APPEND cmd_args --private-includes)
+ endif()
+
+ get_target_property(target_metatypes_json_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
+ if (NOT target_metatypes_json_file)
+ message(FATAL_ERROR "Need target metatypes.json file")
+ endif()
+
+ set(registration_cpp_file_dep_args)
+ if (use_dep_files)
+ set(registration_cpp_file_dep_args DEPFILE ${dependency_file_cpp})
+ file(GENERATE OUTPUT "${dependency_file_cpp}"
+ CONTENT "${cpp_file_name}: $<IF:$<BOOL:${genex_list}>,\\\n$<JOIN:${genex_list}, \\\n>, \\\n>"
+ )
+ endif()
+
+ set(extra_env_command)
+ if (WIN32)
+ file(TO_NATIVE_PATH "${${PROJECT_NAME}_BINARY_DIR}/bin$<SEMICOLON>${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}$<SEMICOLON>%PATH%" env_path_native)
+ set(extra_env_command COMMAND set PATH=${env_path_native})
+ endif()
+ add_custom_command(OUTPUT ${type_registration_cpp_file}
+ DEPENDS
+ ${foreign_types_file}
+ ${target_metatypes_json_file}
+ ${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
+ ${extra_env_command}
+ COMMAND
+ $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
+ ${cmd_args}
+ -o ${type_registration_cpp_file}
+ ${target_metatypes_json_file}
+ ${registration_cpp_file_dep_args}
+ COMMENT "Automatic QML type registration for target ${target}"
+ )
+
+ target_sources(${target} PRIVATE ${type_registration_cpp_file})
+ set_source_files_properties(${type_registration_cpp_file} PROPERTIES
+ SKIP_AUTOGEN ON
+ )
+
+ # Only install qml types if necessary
+ get_target_property(install_qmltypes ${target} QT_QML_MODULE_INSTALL_QMLTYPES)
+ if (install_qmltypes)
+ get_target_property(qml_install_dir ${target} QT_QML_MODULE_INSTALL_DIR)
+ if(NOT arg_COPY_OVER_INSTALL)
+ install(FILES ${plugin_types_file} DESTINATION ${qml_install_dir})
+ else()
+ # For regular modules that have not been declared using
+ # qt_add_qml_module (e.g: src/quick)
+ if (DEFINED QT_WILL_INSTALL AND NOT QT_WILL_INSTALL
+ AND NOT IS_ABSOLUTE "${qml_install_dir}")
+ set(qml_install_dir "${QT_BUILD_DIR}/${qml_install_dir}")
+ endif()
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${plugin_types_file}"
+ "${qml_install_dir}/${qmltypes_output_name}"
+ COMMENT "Copying ${plugin_types_file} to ${qml_install_dir}"
+ )
+ endif()
+ endif()
+
+ target_include_directories(${target} PRIVATE
+ $<TARGET_PROPERTY:Qt::QmlPrivate,INTERFACE_INCLUDE_DIRECTORIES>
+ )
+endfunction()
+
+
+# Enable the qt6_quick_compiler_process_resources function in qt6_add_resource()
+set(QT6_ADD_RESOURCE_DECLARATIVE_EXTENSIONS TRUE)
+
+# Inspect all files passed to a call to qt_add_resource. If there are any
+# files present, invoke the quick compiler and return the remaining resource
+# files that have not been processed in OUTPUT_REMAINING_RESOURCES as well as the new
+# name for the resource in OUTPUT_RESOURCE_NAME.
+function(qt6_quick_compiler_process_resources target resource_name)
+
+ cmake_parse_arguments(arg
+ "" "PREFIX;OUTPUT_REMAINING_RESOURCES;OUTPUT_RESOURCE_NAME;OUTPUT_GENERATED_TARGET" "FILES" ${ARGN}
+ )
+
+ set(qml_files)
+ set(resource_files)
+ # scan for qml files
+ foreach(file IN LISTS arg_FILES)
+ # check whether this resource should not be processed by the qt quick
+ # compiler
+ get_source_file_property(skip_compiler_check ${file} QT_SKIP_QUICKCOMPILER)
+ if (skip_compiler_check)
+ list(APPEND resource_files ${file})
+ continue()
+ endif()
+
+ if (${file} MATCHES "\.js$"
+ OR ${file} MATCHES "\.mjs$"
+ OR ${file} MATCHES "\.qml$")
+ list(APPEND qml_files ${file})
+ endif()
+ list(APPEND resource_files ${file})
+ endforeach()
+ if (NOT TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen AND qml_files)
+ message(WARNING "QT6_PROCESS_RESOURCE: Qml files were detected but the qmlcachgen target is not defined. Consider adding QmlTools to your find_package command.")
+ endif()
+
+ if (TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen AND qml_files)
+ # Enable qt quick compiler support
+ set(qml_resource_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/${resource_name}.qrc")
+ if (resource_files)
+ set(chained_resource_name "${resource_name}_qmlcache")
+ endif()
+
+ foreach(file IN LISTS qml_files)
+ get_filename_component(file_absolute ${file} ABSOLUTE)
+ file(RELATIVE_PATH file_relative ${CMAKE_CURRENT_SOURCE_DIR} ${file_absolute})
+ __qt_get_relative_resource_path_for_file(file_resource_path ${file})
+ if (arg_PREFIX STREQUAL "/")
+ # TO_CMAKE_PATH does not clean up cases such as //Foo
+ set(file_resource_path "/${file_resource_path}")
+ else()
+ set(file_resource_path "${arg_PREFIX}/${file_resource_path}")
+ endif()
+ file(TO_CMAKE_PATH ${file_resource_path} file_resource_path)
+ list(APPEND file_resource_paths ${file_resource_path})
+ string(REGEX REPLACE "\.js$" "_js" compiled_file ${file_relative})
+ string(REGEX REPLACE "\.mjs$" "_mjs" compiled_file ${compiled_file})
+ string(REGEX REPLACE "\.qml$" "_qml" compiled_file ${compiled_file})
+ string(REGEX REPLACE "[\$#\?]+" "_" compiled_file ${compiled_file})
+ set(compiled_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/${compiled_file}.cpp")
+ get_filename_component(out_dir ${compiled_file} DIRECTORY)
+ if(NOT EXISTS ${out_dir})
+ file(MAKE_DIRECTORY ${out_dir})
+ endif()
+ add_custom_command(
+ OUTPUT ${compiled_file}
+ ${QT_TOOL_PATH_SETUP_COMMAND}
+ COMMAND
+ ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen
+ --resource-path "${file_resource_path}"
+ -o "${compiled_file}"
+ "${file_absolute}"
+ DEPENDS
+ $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen>
+ "${file_absolute}"
+ )
+ target_sources(${target} PRIVATE ${compiled_file})
+ endforeach()
+
+ set(qmlcache_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qml_loader_file_list.rsp")
+ file(GENERATE
+ OUTPUT ${qmlcache_loader_list}
+ CONTENT "$<JOIN:${file_resource_paths},\n>"
+ )
+
+ set(qmlcache_loader_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qmlcache_loader.cpp")
+ set(resource_name_arg "${resource_name}.qrc")
+ if (chained_resource_name)
+ set(resource_name_arg "${resource_name_arg}=${chained_resource_name}")
+ endif()
+
+ add_custom_command(
+ OUTPUT ${qmlcache_loader_file}
+ ${QT_TOOL_PATH_SETUP_COMMAND}
+ COMMAND
+ ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen
+ --resource-name "${resource_name_arg}"
+ -o "${qmlcache_loader_file}"
+ "@${qmlcache_loader_list}"
+ DEPENDS
+ $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen>
+ "${qmlcache_loader_list}"
+ )
+
+ __qt_propagate_generated_resource(${target}
+ ${resource_name}
+ ${qmlcache_loader_file}
+ output_target)
+
+ set(${arg_OUTPUT_GENERATED_TARGET} "${output_target}" PARENT_SCOPE)
+
+ if (resource_files)
+ set(resource_name ${chained_resource_name})
+ endif()
+
+ # The generated qmlcache_loader source file uses private headers of Qml, so make sure
+ # if the object library was created, it depends on the Qml target. If there's no target,
+ # that means the target is a shared library and the sources are directly added to the target
+ # via target_sources, so add dependency in that case as well.
+ set(chosen_target "target") # shared library case
+ if(output_target)
+ set(chosen_target "output_target") # static library case.
+ endif()
+ target_link_libraries(${${chosen_target}} PRIVATE ${QT_CMAKE_EXPORT_NAMESPACE}::Qml)
+ else()
+ set(resource_files ${arg_FILES})
+ endif()
+
+ set(${arg_OUTPUT_REMAINING_RESOURCES} ${resource_files} PARENT_SCOPE)
+ set(${arg_OUTPUT_RESOURCE_NAME} ${resource_name} PARENT_SCOPE)
+endfunction()
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index a5a1cf8969..152c70f107 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -57,6 +57,8 @@
#include <QtCore/qvector.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qhash.h>
+#include <QtCore/qversionnumber.h>
+#include <QtCore/qlocale.h>
#if QT_CONFIG(temporaryfile)
#include <QtCore/qsavefile.h>
@@ -65,6 +67,7 @@
#include <private/qendian_p.h>
#include <private/qv4staticvalue_p.h>
#include <functional>
+#include <limits.h>
QT_BEGIN_NAMESPACE
@@ -75,13 +78,17 @@ QT_BEGIN_NAMESPACE
// Also change the comment behind the number to describe the latest change. This has the added
// benefit that if another patch changes the version too, it will result in a merge conflict, and
// not get removed silently.
-#define QV4_DATA_STRUCTURE_VERSION 0x29// support additional required property features
+#define QV4_DATA_STRUCTURE_VERSION 0x30// support additional required property features
class QIODevice;
class QQmlTypeNameCache;
class QQmlType;
class QQmlEngine;
+namespace QQmlPrivate {
+struct AOTCompiledFunction;
+}
+
namespace QmlIR {
struct Document;
}
@@ -127,6 +134,13 @@ struct Location
};
Location() : _dummy(0) { }
+ Location(quint32 l, quint32 c)
+ {
+ line = l;
+ column = c;
+ Q_ASSERT(line == l);
+ Q_ASSERT(column == c);
+ }
inline bool operator<(const Location &other) const {
return line < other.line ||
@@ -195,39 +209,14 @@ struct JSClass
};
static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-// This data structure is intended to be binary compatible with QStringData/QStaticStringData on
-// 64-bit and 32-bit little-endian architectures, in all directions. So the same structure mapped
-// from a file must be castable to a QStringData regardless of the pointer size. With the first
-// few fields that's easy, they're always 32-bit. However the offset field of QArrayData is a
-// ptrdiff_t and thus variable in size.
-// On 64-bit systems compilers enforce an 8-byte alignment and thus place it at offset 16, while
-// on 32-bit systems offset 12 is sufficient. Therefore the two values don't overlap and contain
-// the same value.
struct String
{
- qint32_le refcount; // -1
qint32_le size;
- quint32_le allocAndCapacityReservedFlag; // 0
- quint32_le offsetOn32Bit;
- quint64_le offsetOn64Bit;
- // uint16 strdata[]
static int calculateSize(const QString &str) {
return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
}
};
-static_assert(sizeof(String) == 24, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-// Ensure compatibility with QString
-static_assert(offsetof(QArrayData, ref) == offsetof(String, refcount), "refcount must be at the same location");
-static_assert(offsetof(QArrayData, size) == offsetof(String, size), "size must be at the same location");
-static_assert(offsetof(String, offsetOn64Bit) == 16, "offset must be at 8-byte aligned location");
-static_assert(offsetof(String, offsetOn32Bit) == 12, "offset must be at 4-byte aligned location");
-#if QT_POINTER_SIZE == 8
-static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn64Bit), "offset must be at the same location");
-#else
-static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn32Bit), "offset must be at the same location");
-#endif
struct CodeOffsetToLine {
quint32_le codeOffset;
@@ -472,7 +461,8 @@ struct Binding
IsBindingToAlias = 0x40,
IsDeferredBinding = 0x80,
IsCustomParserBinding = 0x100,
- IsFunctionExpression = 0x200
+ IsFunctionExpression = 0x200,
+ IsPropertyObserver = 0x400
};
union {
@@ -498,7 +488,8 @@ struct Binding
|| type == Type_GroupProperty)
return false;
if (flags & IsSignalHandlerExpression
- || flags & IsSignalHandlerObject)
+ || flags & IsSignalHandlerObject
+ || flags & IsPropertyObserver)
return false;
return true;
}
@@ -508,7 +499,7 @@ struct Binding
bool isSignalHandler() const
{
- if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) {
+ if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject || flags & IsPropertyObserver) {
Q_ASSERT(!isValueBinding());
Q_ASSERT(!isAttachedProperty());
Q_ASSERT(!isGroupProperty());
@@ -692,6 +683,11 @@ struct Property
builtinTypeOrTypeNameIndex = nameIndex;
isBuiltinType = false;
}
+
+ int customType() const
+ {
+ return isBuiltinType ? -1 : builtinTypeOrTypeNameIndex;
+ }
};
static_assert(sizeof(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
@@ -905,14 +901,16 @@ struct Import
quint32_le uriIndex;
quint32_le qualifierIndex;
- qint32_le majorVersion;
- qint32_le minorVersion;
-
Location location;
+ QTypeRevision version;
+ quint16_le reserved;
- Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; }
+ Import()
+ {
+ type = 0; uriIndex = 0; qualifierIndex = 0; version = QTypeRevision::zero(); reserved = 0;
+ }
};
-static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Import) == 20, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct QmlUnit
{
@@ -1016,14 +1014,13 @@ struct Unit
const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
const quint32_le offset = offsetTable[idx];
const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
+ Q_ASSERT(str->size >= 0);
if (str->size == 0)
return QString();
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- if (flags & StaticData) {
- const QStringDataPtr holder = { const_cast<QStringData *>(reinterpret_cast<const QStringData*>(str)) };
- return QString(holder);
- }
const QChar *characters = reinterpret_cast<const QChar *>(str + 1);
+ if (flags & StaticData)
+ return QString::fromRawData(characters, str->size);
return QString(characters, str->size);
#else
const quint16_le *characters = reinterpret_cast<const quint16_le *>(str + 1);
@@ -1209,6 +1206,7 @@ struct CompilationUnit : public CompilationUnitBase
const Unit *data = nullptr;
const QmlUnit *qmlData = nullptr;
QStringList dynamicStrings;
+ const QQmlPrivate::AOTCompiledFunction *aotCompiledFunctions = nullptr;
public:
using CompiledObject = CompiledData::Object;
@@ -1218,6 +1216,13 @@ public:
setUnitData(unitData, nullptr, fileName, finalUrlString);
}
+ explicit CompilationUnit(const Unit *unitData, const QQmlPrivate::AOTCompiledFunction *aotCompiledFunctions,
+ const QString &fileName = QString(), const QString &finalUrlString = QString())
+ : CompilationUnit(unitData, fileName, finalUrlString)
+ {
+ this->aotCompiledFunctions = aotCompiledFunctions;
+ }
+
~CompilationUnit()
{
if (data) {
@@ -1251,6 +1256,7 @@ public:
qmlData = other.qmlData;
other.qmlData = nullptr;
dynamicStrings = std::move(other.dynamicStrings);
+ aotCompiledFunctions = other.aotCompiledFunctions;
other.dynamicStrings.clear();
m_fileName = std::move(other.m_fileName);
other.m_fileName.clear();
@@ -1308,6 +1314,44 @@ public:
Heap::Module *module() const { return m_module; }
void setModule(Heap::Module *module) { m_module = module; }
+ QString bindingValueAsString(const CompiledData::Binding *binding) const
+ {
+ using namespace CompiledData;
+ switch (binding->type) {
+ case Binding::Type_Script:
+ case Binding::Type_String:
+ return stringAt(binding->stringIndex);
+ case Binding::Type_Null:
+ return QStringLiteral("null");
+ case Binding::Type_Boolean:
+ return binding->value.b ? QStringLiteral("true") : QStringLiteral("false");
+ case Binding::Type_Number:
+ return QString::number(bindingValueAsNumber(binding), 'g', QLocale::FloatingPointShortest);
+ case Binding::Type_Invalid:
+ return QString();
+ case Binding::Type_TranslationById:
+ case Binding::Type_Translation:
+ return stringAt(data->translations()[binding->value.translationDataIndex].stringIndex);
+ default:
+ break;
+ }
+ return QString();
+ }
+
+ QString bindingValueAsScriptString(const CompiledData::Binding *binding) const
+ {
+ return (binding->type == CompiledData::Binding::Type_String)
+ ? CompiledData::Binding::escapedString(stringAt(binding->stringIndex))
+ : bindingValueAsString(binding);
+ }
+
+ double bindingValueAsNumber(const CompiledData::Binding *binding) const
+ {
+ if (binding->type != CompiledData::Binding::Type_Number)
+ return 0.0;
+ return constants[binding->value.constantValueIndex].doubleValue();
+ }
+
private:
QString m_fileName; // initialized from data->sourceFileIndex
QString m_finalUrlString; // initialized from data->finalUrlIndex
diff --git a/src/qml/common/qv4stringtoarrayindex_p.h b/src/qml/common/qv4stringtoarrayindex_p.h
index 61bd988d1e..d4b064f865 100644
--- a/src/qml/common/qv4stringtoarrayindex_p.h
+++ b/src/qml/common/qv4stringtoarrayindex_p.h
@@ -65,6 +65,8 @@ inline uint charToUInt(const char *ch) { return static_cast<unsigned char>(*ch);
template <typename T>
uint stringToArrayIndex(const T *ch, const T *end)
{
+ if (ch == end)
+ return std::numeric_limits<uint>::max();
uint i = charToUInt(ch) - '0';
if (i > 9)
return std::numeric_limits<uint>::max();
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 89f99e21cd..bc979a81e0 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -407,11 +407,7 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString &
QV4::CompiledData::Import *import = engine->pool()->New<QV4::CompiledData::Import>();
import->type = QV4::CompiledData::Import::ImportLibrary;
import->uriIndex = jsGenerator->registerString(uri);
- int vmaj;
- int vmin;
- IRBuilder::extractVersion(QStringRef(&version), &vmaj, &vmin);
- import->majorVersion = vmaj;
- import->minorVersion = vmin;
+ import->version = IRBuilder::extractVersion(QStringRef(&version));
import->qualifierIndex = jsGenerator->registerString(module);
import->location.line = lineNumber;
import->location.column = column;
@@ -758,16 +754,10 @@ bool IRBuilder::visit(QQmlJS::AST::UiImport *node)
}
if (node->version) {
- import->majorVersion = node->version->majorVersion;
- import->minorVersion = node->version->minorVersion;
- } else if (import->type == QV4::CompiledData::Import::ImportLibrary) {
- recordError(node->importIdToken, QCoreApplication::translate("QQmlParser","Library import requires a version"));
- return false;
+ import->version = node->version->version;
} else {
- // For backward compatibility in how the imports are loaded we
- // must otherwise initialize the major and minor version to -1.
- import->majorVersion = -1;
- import->minorVersion = -1;
+ // Otherwise initialize the major and minor version to invalid to signal "latest".
+ import->version = QTypeRevision();
}
import->location.line = node->importToken.startLine;
@@ -1061,22 +1051,15 @@ QStringRef IRBuilder::asStringRef(QQmlJS::AST::Node *node)
return textRefAt(node->firstSourceLocation(), node->lastSourceLocation());
}
-void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min)
+QTypeRevision IRBuilder::extractVersion(const QStringRef &string)
{
- *maj = -1; *min = -1;
-
- if (!string.isEmpty()) {
-
- int dot = string.indexOf(QLatin1Char('.'));
+ if (string.isEmpty())
+ return QTypeRevision();
- if (dot < 0) {
- *maj = string.toInt();
- *min = 0;
- } else {
- *maj = string.left(dot).toInt();
- *min = string.mid(dot + 1).toInt();
- }
- }
+ const int dot = string.indexOf(QLatin1Char('.'));
+ return (dot < 0)
+ ? QTypeRevision::fromMajorVersion(string.toInt())
+ : QTypeRevision::fromVersion(string.left(dot).toInt(), string.mid(dot + 1).toInt());
}
QStringRef IRBuilder::textRefAt(const QQmlJS::SourceLocation &first, const QQmlJS::SourceLocation &last) const
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 9629a73199..254d21001b 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -498,7 +498,7 @@ public:
static QString asString(QQmlJS::AST::UiQualifiedId *node);
QStringRef asStringRef(QQmlJS::AST::Node *node);
- static void extractVersion(const QStringRef &string, int *maj, int *min);
+ static QTypeRevision extractVersion(const QStringRef &string);
QStringRef textRefAt(const QQmlJS::SourceLocation &loc) const
{ return QStringRef(&sourceCode, loc.offset, loc.length); }
QStringRef textRefAt(const QQmlJS::SourceLocation &first,
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index acc4b02e96..0c0a005689 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -47,6 +48,7 @@
#include <private/qml_compile_hash_p.h>
#include <private/qqmlirbuilder_p.h>
#include <QCryptographicHash>
+#include <QtEndian>
// Efficient implementation that takes advantage of powers of two.
static inline size_t roundUpToMultipleOf(size_t divisor, size_t x)
@@ -108,19 +110,11 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
QV4::CompiledData::String *s = reinterpret_cast<QV4::CompiledData::String *>(stringData);
Q_ASSERT(reinterpret_cast<uintptr_t>(s) % alignof(QV4::CompiledData::String) == 0);
- s->refcount = -1;
+ Q_ASSERT(qstr.length() >= 0);
s->size = qstr.length();
- s->allocAndCapacityReservedFlag = 0;
- s->offsetOn32Bit = sizeof(QV4::CompiledData::String);
- s->offsetOn64Bit = sizeof(QV4::CompiledData::String);
ushort *uc = reinterpret_cast<ushort *>(reinterpret_cast<char *>(s) + sizeof(*s));
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- memcpy(uc, qstr.constData(), s->size * sizeof(ushort));
-#else
- for (int i = 0; i < s->size; ++i)
- uc[i] = qToLittleEndian<ushort>(qstr.at(i).unicode());
-#endif
+ qToLittleEndian<ushort>(qstr.constData(), s->size, uc);
uc[s->size] = 0;
stringData += QV4::CompiledData::String::calculateSize(qstr);
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index c0dd696b8a..254e1c46e9 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -348,7 +348,7 @@ QT_BEGIN_NAMESPACE
#endif
#endif
-#define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QV4::Moth::Instr) - 1)
+#define MOTH_INSTR_ALIGN_MASK (alignof(QV4::Moth::Instr) - 1)
#define MOTH_INSTR_ENUM(I) I, I##_Wide,
#define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I))
diff --git a/src/qml/configure.cmake b/src/qml/configure.cmake
new file mode 100644
index 0000000000..00936ff53c
--- /dev/null
+++ b/src/qml/configure.cmake
@@ -0,0 +1,189 @@
+
+
+#### Inputs
+
+
+
+#### Libraries
+
+
+
+#### Tests
+
+# cxx14_make_unique
+qt_config_compile_test(cxx14_make_unique
+ LABEL "C++14 make_unique()"
+ CODE
+"
+#include <memory>
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+std::unique_ptr<int> ptr = std::make_unique<int>();
+ /* END TEST: */
+ return 0;
+}
+")
+
+# pointer_32bit
+qt_config_compile_test(pointer_32bit
+ LABEL "32bit pointers"
+ CODE
+"
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+static_assert(sizeof(void *) == 4, \"fail\");
+ /* END TEST: */
+ return 0;
+}
+")
+
+# pointer_64bit
+qt_config_compile_test(pointer_64bit
+ LABEL "64bit pointers"
+ CODE
+"
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+static_assert(sizeof(void *) == 8, \"fail\");
+ /* END TEST: */
+ return 0;
+}
+")
+
+# arm_thumb
+qt_config_compile_test(arm_thumb
+ LABEL "THUMB mode on ARM"
+ CODE
+"
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+#if defined(thumb2) || defined(__thumb2__)
+# define THUMB_OK
+#elif (defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4
+# define THUMB_OK
+#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2
+// clang 3.5 and later will set this if the core supports the Thumb-2 ISA.
+# define THUMB_OK
+#else
+# error \"fail\"
+#endif
+ /* END TEST: */
+ return 0;
+}
+")
+
+# arm_fp
+qt_config_compile_test(arm_fp
+ LABEL "Sufficiently recent FPU on ARM"
+ CODE
+"
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+// if !defined(__ARM_FP) we might be on MSVC or we might have a device
+// without an FPU.
+// TODO: The latter case is not supported, but the test still succeeds.
+#if defined(__ARM_FP) && (__ARM_FP <= 0x04)
+# error \"fail\"
+#endif
+ /* END TEST: */
+ return 0;
+}
+")
+
+
+
+#### Features
+
+qt_feature("cxx14_make_unique" PRIVATE
+ LABEL "C++14 make_unique"
+ CONDITION QT_FEATURE_cxx14 OR TEST_cxx14_make_unique
+)
+qt_feature("qml-network" PUBLIC
+ SECTION "QML"
+ LABEL "QML network support"
+ PURPOSE "Provides network transparency."
+ CONDITION QT_FEATURE_network
+)
+# On arm and arm64 we need a specialization of cacheFlush() for each OS to be enabeled. Therefore the config white list. Also Mind that e.g. x86_32 has arch.x86_64 but 32bit pointers. Therefore the checks for architecture and pointer size. Finally, ios and tvos can technically use the JIT but Apple does not allow it. Therefore, it's disabled by default.
+qt_feature("qml-jit" PRIVATE
+ SECTION "QML"
+ LABEL "QML just-in-time compiler"
+ PURPOSE "Provides a JIT for QML and JavaScript"
+ AUTODETECT NOT IOS AND NOT TVOS
+ CONDITION ( ( ( TEST_architecture_arch STREQUAL i386 ) AND TEST_pointer_32bit AND QT_FEATURE_sse2 ) OR ( ( TEST_architecture_arch STREQUAL x86_64 ) AND TEST_pointer_64bit AND QT_FEATURE_sse2 ) OR ( ( TEST_architecture_arch STREQUAL arm ) AND TEST_pointer_32bit AND TEST_arm_fp AND TEST_arm_thumb AND ( LINUX OR IOS OR TVOS OR QNX ) ) OR ( ( TEST_architecture_arch STREQUAL arm64 ) AND TEST_pointer_64bit AND TEST_arm_fp AND ( LINUX OR IOS OR TVOS OR QNX OR INTEGRITY ) ) )
+)
+qt_feature("qml-debug" PUBLIC
+ SECTION "QML"
+ LABEL "QML debugging and profiling support"
+ PURPOSE "Provides infrastructure and plugins for debugging and profiling."
+)
+qt_feature("qml-profiler" PRIVATE
+ SECTION "QML"
+ LABEL "Command line QML Profiler"
+ PURPOSE "Supports retrieving QML tracing data from an application."
+ CONDITION ( QT_FEATURE_commandlineparser ) AND ( QT_FEATURE_qml_debug ) AND ( QT_FEATURE_qml_network AND QT_FEATURE_localserver ) AND ( QT_FEATURE_xmlstreamwriter )
+)
+qt_feature("qml-preview" PRIVATE
+ SECTION "QML"
+ LABEL "Command line QML Preview tool"
+ PURPOSE "Updates QML documents in your application live as you change them on disk"
+ CONDITION ( QT_FEATURE_commandlineparser ) AND ( QT_FEATURE_filesystemwatcher ) AND ( QT_FEATURE_qml_network AND QT_FEATURE_localserver ) AND ( QT_FEATURE_process ) AND ( QT_FEATURE_qml_debug )
+)
+qt_feature("qml-devtools" PRIVATE
+ SECTION "QML"
+ LABEL "QML Development Tools"
+ PURPOSE "Provides the QmlDevtools library and various utilities."
+)
+qt_feature("qml-sequence-object" PRIVATE
+ SECTION "QML"
+ LABEL "QML sequence object"
+ PURPOSE "Supports mapping sequence types into QML."
+)
+qt_feature("qml-xml-http-request" PRIVATE
+ SECTION "QML"
+ LABEL "QML XML http request"
+ PURPOSE "Provides support for sending XML http requests."
+ CONDITION ( QT_FEATURE_xmlstreamreader ) AND ( QT_FEATURE_qml_network )
+)
+qt_feature("qml-locale" PRIVATE
+ SECTION "QML"
+ LABEL "QML Locale"
+ PURPOSE "Provides support for locales in QML."
+)
+qt_feature("qml-animation" PRIVATE
+ SECTION "QML"
+ LABEL "QML Animations"
+ PURPOSE "Provides support for animations and timers in QML."
+ CONDITION QT_FEATURE_animation
+)
+qt_feature("qml-worker-script" PRIVATE
+ SECTION "QML"
+ LABEL "QML WorkerScript"
+ PURPOSE "Enables the use of threads in QML."
+ CONDITION QT_FEATURE_thread
+)
+qt_feature("qml-itemmodel" PRIVATE
+ SECTION "QML"
+ LABEL "QML Item Model"
+ PURPOSE "Provides the item model for item views in QML"
+ CONDITION QT_FEATURE_itemmodel
+)
diff --git a/src/qml/configure.json b/src/qml/configure.json
index 3fc1fd528b..944358bc48 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -69,6 +69,11 @@
"#endif"
]
}
+ },
+ "qml-python": {
+ "label": "python",
+ "type": "detectPython",
+ "log": "location"
}
},
@@ -185,9 +190,25 @@
"section": "QML",
"condition": "features.itemmodel",
"output": [ "privateFeature" ]
+ },
+ "qml-python": {
+ "label": "python",
+ "condition": "tests.qml-python",
+ "output": [
+ "privateFeature",
+ { "type": "varAssign", "name": "QMAKE_PYTHON", "value": "tests.qml-python.location" }
+ ]
}
},
+ "report": [
+ {
+ "type": "error",
+ "condition": "!features.qml-python",
+ "message": "Python is required to build QtQml."
+ }
+ ],
+
"summary": [
{
"section": "Qt QML",
diff --git a/src/qml/configure.pri b/src/qml/configure.pri
new file mode 100644
index 0000000000..2ab5f9454d
--- /dev/null
+++ b/src/qml/configure.pri
@@ -0,0 +1,22 @@
+equals(QMAKE_HOST.os, Windows): EXE_SUFFIX = .exe
+
+defineTest(qtConfTest_detectPython) {
+ PYTHON_NAMES = python$$EXE_SUFFIX python2$${EXE_SUFFIX} python3$${EXE_SUFFIX} py$${EXE_SUFFIX}
+ for (name, PYTHON_NAMES) {
+ python_path = $$qtConfFindInPath("$$name")
+ !isEmpty(python_path): \
+ break()
+ }
+ isEmpty(python_path) {
+ qtLog("No $$PYTHON_NAMES are found in PATH. Giving up.")
+ return(false)
+ }
+
+ # Make tests.python.location available in configure.json.
+ $${1}.location = $$clean_path($$python_path)
+ export($${1}.location)
+ $${1}.cache += location
+ export($${1}.cache)
+
+ return(true)
+}
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index b259e047a1..df1ed68c7b 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -107,7 +107,8 @@ class QQmlNativeDebugService {};
class QQmlDebugTranslationService {
public:
virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};}
- virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *, QQmlContextData *) {}
+ virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *,
+ const QQmlRefPointer<QQmlContextData> &) {}
};
#else
@@ -175,7 +176,8 @@ public:
static const QString s_key;
virtual QString foundElidedText(QObject *qQuickTextObject, const QString &layoutText, const QString &elideText) = 0;
- virtual void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) = 0;
+ virtual void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject,
+ const QQmlRefPointer<QQmlContextData> &contextData) = 0;
protected:
friend class QQmlDebugConnector;
diff --git a/src/qml/doc/images/cpp-qml-integration-flowchart.odg b/src/qml/doc/images/cpp-qml-integration-flowchart.odg
index 026f89fd73..5b9ed20dd7 100644
--- a/src/qml/doc/images/cpp-qml-integration-flowchart.odg
+++ b/src/qml/doc/images/cpp-qml-integration-flowchart.odg
Binary files differ
diff --git a/src/qml/doc/images/cpp-qml-integration-flowchart.png b/src/qml/doc/images/cpp-qml-integration-flowchart.png
index 97f075f51e..a714075181 100644
--- a/src/qml/doc/images/cpp-qml-integration-flowchart.png
+++ b/src/qml/doc/images/cpp-qml-integration-flowchart.png
Binary files differ
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 07ab974289..48d7f5a328 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -34,7 +34,7 @@ qhp.QtQml.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqml/qtqml.tags
-depends += qtcore qtqmlmodels qtqmlworkerscript qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets qtxmlpatterns qtquickcontrols
+depends += qtcore qtqmlmodels qtqmlworkerscript qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets qtquickcontrols
headerdirs += .. \
../../qml
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs
index ef7688693d..86c3e078c8 100644
--- a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs
+++ b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs
@@ -48,7 +48,7 @@
**
****************************************************************************/
//![0]
-// script.js
+// script.mjs
import { factorial } from "factorial.mjs"
function showCalculations(value) {
diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc
index 0dec7fd66d..9dfb7837e5 100644
--- a/src/qml/doc/src/cppintegration/data.qdoc
+++ b/src/qml/doc/src/cppintegration/data.qdoc
@@ -303,7 +303,7 @@ In particular, QML currently supports:
\li \c {std::vector<bool>}
\endlist
-and all registered QList, QVector, QQueue, QStack, QSet, QLinkedList, std::list,
+and all registered QList, QVector, QQueue, QStack, QSet, std::list,
std::vector that contain a type marked with \l Q_DECLARE_METATYPE.
These sequence types are implemented directly in terms of the underlying C++
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 0ff0de1ef9..f6ed2306c0 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -79,6 +79,16 @@
Declares the enclosing type or namespace to be available in QML, using \a name
as the element name. Otherwise behaves the same as QML_ELEMENT.
+ \code
+ class SqlEventDatabase : public QObject
+ {
+ Q_OBJECT
+ QML_NAMED_ELEMENT(EventDatabase)
+
+ // ...
+ };
+ \endcode
+
\sa {Choosing the Correct Integration Method Between C++ and QML}, QML_ELEMENT
*/
@@ -141,6 +151,8 @@
\l QML_NAMED_ELEMENT(). For such types, \l QML_UNCREATABLE() can be used to
provide a custom error message.
+ Since Qt 6.0 you can use "" instead of a reason to use a standard message instead.
+
\sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS
*/
diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h
index 99b28349cd..ae436d53b0 100644
--- a/src/qml/inlinecomponentutils_p.h
+++ b/src/qml/inlinecomponentutils_p.h
@@ -51,7 +51,7 @@
//
#include <private/qv4compileddata_p.h>
-#include <private/qv4executablecompilationunit_p.h>
+#include <private/qv4resolvedtypereference_p.h>
namespace icutils {
struct Node {
@@ -88,10 +88,12 @@ void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer, Adja
const CompiledObject *obj = objectContainer->objectAt(ic.objectIndex);
QV4::ResolvedTypeReference *currentICTypeRef = objectContainer->resolvedType(ic.nameIndex);
auto createEdgeFromTypeRef = [&](QV4::ResolvedTypeReference *targetTypeRef) {
- if (targetTypeRef && targetTypeRef->type.isInlineComponentType()) {
- if (targetTypeRef->type.containingType() == currentICTypeRef->type.containingType()) {
+ if (targetTypeRef) {
+ const auto targetType = targetTypeRef->type();
+ if (targetType.isInlineComponentType()
+ && targetType.containingType() == currentICTypeRef->type().containingType()) {
auto icIt = std::find_if(allICs.cbegin(), allICs.cend(), [&](const QV4::CompiledData::InlineComponent &icSearched){
- return int(icSearched.objectIndex) == targetTypeRef->type.inlineComponentObjectId();
+ return int(icSearched.objectIndex) == targetType.inlineComponentObjectId();
});
Q_ASSERT(icIt != allICs.cend());
Node& target = nodes[i];
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 25652e0a63..dd6a40afe0 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -89,6 +89,8 @@ public:
PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
+ else if (AccumulatorRegister == ReturnValueRegister)
+ loadUndefined();
}
void saveReturnValueInAccumulator()
@@ -388,6 +390,8 @@ public:
PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
+ else if (AccumulatorRegisterValue == ReturnValueRegisterValue)
+ loadUndefined();
}
void saveReturnValueInAccumulator()
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index fcaa87290e..d329a5afec 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -65,6 +65,8 @@ void BaselineJIT::generate()
labels.insert(int(function->compiledFunction->labelInfoTable()[i]));
as->generatePrologue();
+ // Make sure the ACC register is initialized and not clobbered by the caller.
+ as->loadAccumulatorFromFrame();
decode(code, len);
as->generateEpilogue();
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 6946a64d11..3bcb12a8b6 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -451,10 +451,7 @@ void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSVal
}
QV4::Scope scope(m_v4Engine);
- QV4::ScopedObject obj(scope);
- QV4::Value *val = QJSValuePrivate::getValue(&object);
- if (val)
- obj = val;
+ QV4::ScopedObject obj(scope, QJSValuePrivate::asReturnedValue(&object));
if (!obj)
obj = scope.engine->globalObject;
@@ -548,9 +545,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
if (v4->isInterrupted.loadAcquire())
result = v4->newErrorObject(QStringLiteral("Interrupted"));
- QJSValue retval(v4, result->asReturnedValue());
-
- return retval;
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -578,18 +573,17 @@ QJSValue QJSEngine::importModule(const QString &fileName)
const QUrl url = urlForFileName(QFileInfo(fileName).canonicalFilePath());
auto moduleUnit = m_v4Engine->loadModule(url);
if (m_v4Engine->hasException)
- return QJSValue(m_v4Engine, m_v4Engine->catchException());
+ return QJSValuePrivate::fromReturnedValue(m_v4Engine->catchException());
QV4::Scope scope(m_v4Engine);
QV4::Scoped<QV4::Module> moduleNamespace(scope, moduleUnit->instantiate(m_v4Engine));
if (m_v4Engine->hasException)
- return QJSValue(m_v4Engine, m_v4Engine->catchException());
+ return QJSValuePrivate::fromReturnedValue(m_v4Engine->catchException());
moduleUnit->evaluate();
if (!m_v4Engine->isInterrupted.loadAcquire())
- return QJSValue(m_v4Engine, moduleNamespace->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(moduleNamespace->asReturnedValue());
- return QJSValue(
- m_v4Engine,
+ return QJSValuePrivate::fromReturnedValue(
m_v4Engine->newErrorObject(QStringLiteral("Interrupted"))->asReturnedValue());
}
@@ -605,7 +599,7 @@ QJSValue QJSEngine::newObject()
{
QV4::Scope scope(m_v4Engine);
QV4::ScopedValue v(scope, m_v4Engine->newObject());
- return QJSValue(m_v4Engine, v->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
/*!
@@ -647,7 +641,7 @@ QJSValue QJSEngine::newErrorObject(QJSValue::ErrorType errorType, const QString
case QJSValue::NoError:
return QJSValue::UndefinedValue;
}
- return QJSValue(m_v4Engine, error->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(error->asReturnedValue());
}
/*!
@@ -662,7 +656,7 @@ QJSValue QJSEngine::newArray(uint length)
if (length < 0x1000)
array->arrayReserve(length);
array->setArrayLengthUnchecked(length);
- return QJSValue(m_v4Engine, array.asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(array.asReturnedValue());
}
/*!
@@ -695,7 +689,7 @@ QJSValue QJSEngine::newQObject(QObject *object)
QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
}
QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(v4, object));
- return QJSValue(v4, v->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
/*!
@@ -716,7 +710,7 @@ QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
QV4::ScopedValue v(scope, QV4::QMetaObjectWrapper::create(v4, metaObject));
- return QJSValue(v4, v->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
/*! \fn template <typename T> QJSValue QJSEngine::newQMetaObject()
@@ -743,7 +737,7 @@ QJSValue QJSEngine::globalObject() const
{
QV4::Scope scope(m_v4Engine);
QV4::ScopedValue v(scope, m_v4Engine->globalObject);
- return QJSValue(m_v4Engine, v->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
/*!
@@ -754,7 +748,7 @@ QJSValue QJSEngine::create(int type, const void *ptr)
{
QV4::Scope scope(m_v4Engine);
QV4::ScopedValue v(scope, scope.engine->metaTypeToJS(type, ptr));
- return QJSValue(m_v4Engine, v->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
/*!
@@ -763,118 +757,57 @@ QJSValue QJSEngine::create(int type, const void *ptr)
*/
bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
{
- QV4::ExecutionEngine *v4 = QJSValuePrivate::engine(&value);
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(&value, &scratch);
- if (v4) {
- QV4::Scope scope(v4);
- QV4::ScopedValue v(scope, *val);
- return scope.engine->metaTypeFromJS(v, type, ptr);
- }
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(&value);
- Q_ASSERT(variant);
-
- if (variant->userType() == QMetaType::QString) {
- QString string = variant->toString();
- // have a string based value without engine. Do conversion manually
- if (type == QMetaType::Bool) {
- *reinterpret_cast<bool*>(ptr) = string.length() != 0;
- return true;
- }
- if (type == QMetaType::QString) {
- *reinterpret_cast<QString*>(ptr) = string;
- return true;
- }
- double d = QV4::RuntimeHelpers::stringToNumber(string);
- switch (type) {
- case QMetaType::Int:
- *reinterpret_cast<int*>(ptr) = QV4::Value::toInt32(d);
- return true;
- case QMetaType::UInt:
- *reinterpret_cast<uint*>(ptr) = QV4::Value::toUInt32(d);
- return true;
- case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(ptr) = QV4::Value::toInteger(d);
- return true;
- case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(ptr) = QV4::Value::toInteger(d);
- return true;
- case QMetaType::Double:
- *reinterpret_cast<double*>(ptr) = d;
- return true;
- case QMetaType::Float:
- *reinterpret_cast<float*>(ptr) = d;
- return true;
- case QMetaType::Short:
- *reinterpret_cast<short*>(ptr) = QV4::Value::toInt32(d);
- return true;
- case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(ptr) = QV4::Value::toUInt32(d);
- return true;
- case QMetaType::Char:
- *reinterpret_cast<char*>(ptr) = QV4::Value::toInt32(d);
- return true;
- case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(ptr) = QV4::Value::toUInt32(d);
- return true;
- case QMetaType::QChar:
- *reinterpret_cast<QChar*>(ptr) = QV4::Value::toUInt32(d);
- return true;
- default:
- return false;
- }
- } else {
- return QMetaType::convert(&variant->data_ptr(), variant->userType(), ptr, type);
+ if (const QString *string = QJSValuePrivate::asQString(&value)) {
+ // have a string based value without engine. Do conversion manually
+ if (type == QMetaType::Bool) {
+ *reinterpret_cast<bool*>(ptr) = string->length() != 0;
+ return true;
}
- }
-
- Q_ASSERT(val);
-
- switch (type) {
- case QMetaType::Bool:
- *reinterpret_cast<bool*>(ptr) = val->toBoolean();
+ if (type == QMetaType::QString) {
+ *reinterpret_cast<QString*>(ptr) = *string;
return true;
+ }
+ double d = QV4::RuntimeHelpers::stringToNumber(*string);
+ switch (type) {
case QMetaType::Int:
- *reinterpret_cast<int*>(ptr) = val->toInt32();
+ *reinterpret_cast<int*>(ptr) = QV4::Value::toInt32(d);
return true;
case QMetaType::UInt:
- *reinterpret_cast<uint*>(ptr) = val->toUInt32();
+ *reinterpret_cast<uint*>(ptr) = QV4::Value::toUInt32(d);
return true;
case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(ptr) = val->toInteger();
+ *reinterpret_cast<qlonglong*>(ptr) = QV4::Value::toInteger(d);
return true;
case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(ptr) = val->toInteger();
+ *reinterpret_cast<qulonglong*>(ptr) = QV4::Value::toInteger(d);
return true;
case QMetaType::Double:
- *reinterpret_cast<double*>(ptr) = val->toNumber();
- return true;
- case QMetaType::QString:
- *reinterpret_cast<QString*>(ptr) = val->toQStringNoThrow();
+ *reinterpret_cast<double*>(ptr) = d;
return true;
case QMetaType::Float:
- *reinterpret_cast<float*>(ptr) = val->toNumber();
+ *reinterpret_cast<float*>(ptr) = d;
return true;
case QMetaType::Short:
- *reinterpret_cast<short*>(ptr) = val->toInt32();
+ *reinterpret_cast<short*>(ptr) = QV4::Value::toInt32(d);
return true;
case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(ptr) = val->toUInt16();
+ *reinterpret_cast<unsigned short*>(ptr) = QV4::Value::toUInt32(d);
return true;
case QMetaType::Char:
- *reinterpret_cast<char*>(ptr) = val->toInt32();
+ *reinterpret_cast<char*>(ptr) = QV4::Value::toInt32(d);
return true;
case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(ptr) = val->toUInt16();
+ *reinterpret_cast<unsigned char*>(ptr) = QV4::Value::toUInt32(d);
return true;
case QMetaType::QChar:
- *reinterpret_cast<QChar*>(ptr) = val->toUInt16();
+ *reinterpret_cast<QChar*>(ptr) = QV4::Value::toUInt32(d);
return true;
default:
return false;
+ }
}
+
+ return QV4::ExecutionEngine::metaTypeFromJS(QJSValuePrivate::asReturnedValue(&value), type, ptr);
}
/*! \fn template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)
@@ -991,7 +924,7 @@ void QJSEngine::throwError(QJSValue::ErrorType errorType, const QString &message
{
QV4::Scope scope(m_v4Engine);
QJSValue error = newErrorObject(errorType, message);
- QV4::ScopedObject e(scope, QJSValuePrivate::getValue(&error));
+ QV4::ScopedObject e(scope, QJSValuePrivate::asReturnedValue(&error));
if (!e)
return;
m_v4Engine->throwError(e);
@@ -1074,6 +1007,72 @@ QJSEngine *qjsEngine(const QObject *object)
return data->jsWrapper.engine()->jsEngine();
}
+
+/*!
+ \enum QJSEngine::ObjectOwnership
+
+ ObjectOwnership controls whether or not the JavaScript memory manager automatically destroys the
+ QObject when the corresponding JavaScript object is garbage collected by the
+ engine. The two ownership options are:
+
+ \value CppOwnership The object is owned by C++ code and the JavaScript memory manager will never
+ delete it. The JavaScript destroy() method cannot be used on these objects. This
+ option is similar to QScriptEngine::QtOwnership.
+
+ \value JavaScriptOwnership The object is owned by JavaScript. When the object
+ is returned to the JavaScript memory manager as the return value of a method call, the JavaScript
+ memory manager will track it and delete it if there are no remaining JavaScript references to it
+ and it has no QObject::parent(). An object tracked by one QJSEngine will be deleted during that
+ QJSEngine's destructor. Thus, JavaScript references between objects with JavaScriptOwnership from
+ two different engines will not be valid if one of these engines is deleted. This option is similar
+ to QScriptEngine::ScriptOwnership.
+
+ Generally an application doesn't need to set an object's ownership explicitly. the JavaScript
+ memory manager uses a heuristic to set the default ownership. By default, an object that is
+ created by the JavaScript memory manager has JavaScriptOwnership. The exception to this are the
+ root objects created by calling QQmlComponent::create() or QQmlComponent::beginCreate(), which
+ have CppOwnership by default. The ownership of these root-level objects is considered to have been
+ transferred to the C++ caller.
+
+ Objects not-created by the JavaScript memory manager have CppOwnership by default. The exception
+ to this are objects returned from C++ method calls; their ownership will be set to
+ JavaScriptOwnership. This applies only to explicit invocations of Q_INVOKABLE methods or slots,
+ but not to property getter invocations.
+
+ Calling setObjectOwnership() overrides the default ownership.
+*/
+
+/*!
+ Sets the \a ownership of \a object.
+*/
+void QJSEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
+{
+ if (!object)
+ return;
+
+ QQmlData *ddata = QQmlData::get(object, true);
+ if (!ddata)
+ return;
+
+ ddata->indestructible = (ownership == CppOwnership)?true:false;
+ ddata->explicitIndestructibleSet = true;
+}
+
+/*!
+ Returns the ownership of \a object.
+*/
+QJSEngine::ObjectOwnership QJSEngine::objectOwnership(QObject *object)
+{
+ if (!object)
+ return CppOwnership;
+
+ QQmlData *ddata = QQmlData::get(object, false);
+ if (!ddata)
+ return CppOwnership;
+ else
+ return ddata->indestructible?CppOwnership:JavaScriptOwnership;
+}
+
QT_END_NAMESPACE
#include "moc_qjsengine.cpp"
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 31229e1f20..643c5d5a38 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -100,6 +100,10 @@ public:
void collectGarbage();
+ enum ObjectOwnership { CppOwnership, JavaScriptOwnership };
+ static void setObjectOwnership(QObject *, ObjectOwnership);
+ static ObjectOwnership objectOwnership(QObject *);
+
#if QT_DEPRECATED_SINCE(5, 6)
QT_DEPRECATED void installTranslatorFunctions(const QJSValue &object = QJSValue());
#endif
@@ -133,7 +137,8 @@ private:
static bool convertV2(const QJSValue &value, int type, void *ptr);
- friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *);
+ template<typename T>
+ friend inline T qjsvalue_cast(const QJSValue &);
protected:
QJSEngine(QJSEnginePrivate &dd, QObject *parent = nullptr);
@@ -146,18 +151,13 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QJSEngine::Extensions)
-inline bool qjsvalue_cast_helper(const QJSValue &value, int type, void *ptr)
-{
- return QJSEngine::convertV2(value, type, ptr);
-}
-
template<typename T>
T qjsvalue_cast(const QJSValue &value)
{
T t;
const int id = qMetaTypeId<T>();
- if (qjsvalue_cast_helper(value, id, &t))
+ if (QJSEngine::convertV2(value, id, &t))
return t;
else if (value.isVariant())
return qvariant_cast<T>(value.toVariant());
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
index 7866a5bdda..0aff6595b6 100644
--- a/src/qml/jsapi/qjsengine_p.h
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -53,6 +53,7 @@
#include <QtCore/private/qobject_p.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qproperty.h>
#include "qjsengine.h"
#include "private/qtqmlglobal_p.h"
#include <private/qqmlmetatype_p.h>
@@ -107,11 +108,11 @@ public:
// Shared by QQmlEngine
mutable QRecursiveMutex mutex;
- QString uiLanguage;
+ QProperty<QString> uiLanguage;
// These methods may be called from the QML loader thread
- inline QQmlPropertyCache *cache(QObject *obj, int minorVersion = -1);
- inline QQmlPropertyCache *cache(const QMetaObject *, int minorVersion = -1);
+ inline QQmlPropertyCache *cache(QObject *obj, QTypeRevision version = QTypeRevision());
+ inline QQmlPropertyCache *cache(const QMetaObject *obj, QTypeRevision version = QTypeRevision());
};
QJSEnginePrivate::Locker::Locker(const QJSEngine *e)
@@ -161,14 +162,14 @@ and deleted before the loader thread has a chance to use or reference it. This
can't currently happen as the cache holds a reference to the
QQmlPropertyCache until the QQmlEngine is destroyed.
*/
-QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, int minorVersion)
+QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, QTypeRevision version)
{
if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
return nullptr;
Locker locker(this);
const QMetaObject *mo = obj->metaObject();
- return QQmlMetaType::propertyCache(mo, minorVersion);
+ return QQmlMetaType::propertyCache(mo, version);
}
/*!
@@ -180,12 +181,12 @@ exist for the lifetime of the QQmlEngine.
The returned cache is not referenced, so if it is to be stored, call addref().
*/
-QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, int minorVersion)
+QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, QTypeRevision version)
{
Q_ASSERT(metaObject);
Locker locker(this);
- return QQmlMetaType::propertyCache(metaObject, minorVersion);
+ return QQmlMetaType::propertyCache(metaObject, version);
}
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index b40bc1f18b..1122700334 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -191,41 +191,29 @@ using namespace QV4;
/*!
Constructs a new QJSValue with a boolean \a value.
*/
-QJSValue::QJSValue(bool value)
+QJSValue::QJSValue(bool value) : d(QV4::Encode(value))
{
- QJSValuePrivate::setVariant(this, QVariant(value));
-}
-
-/*!
- \internal
-*/
-QJSValue::QJSValue(ExecutionEngine *e, quint64 val)
-{
- QJSValuePrivate::setValue(this, e, val);
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(int value)
+QJSValue::QJSValue(int value) : d(QV4::Encode(value))
{
- QJSValuePrivate::setVariant(this, QVariant(value));
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(uint value)
+QJSValue::QJSValue(uint value) : d(QV4::Encode(value))
{
- QJSValuePrivate::setVariant(this, QVariant((double)value));
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(double value)
+QJSValue::QJSValue(double value) : d(QV4::Encode(value))
{
- QJSValuePrivate::setVariant(this, QVariant(value));
}
/*!
@@ -233,17 +221,14 @@ QJSValue::QJSValue(double value)
*/
QJSValue::QJSValue(const QString& value)
{
- QJSValuePrivate::setVariant(this, QVariant(value));
+ QJSValuePrivate::setString(this, QString(value));
}
/*!
Constructs a new QJSValue with a special \a value.
*/
-QJSValue::QJSValue(SpecialValue value)
- : d(0)
+QJSValue::QJSValue(SpecialValue value) : d(value == NullValue ? QV4::Encode::null() : 0)
{
- if (value == NullValue)
- QJSValuePrivate::setVariant(this, QVariant::fromValue(nullptr));
}
/*!
@@ -251,7 +236,7 @@ QJSValue::QJSValue(SpecialValue value)
*/
QJSValue::QJSValue(const QLatin1String &value)
{
- QJSValuePrivate::setVariant(this, QVariant(value));
+ QJSValuePrivate::setString(this, QString(value));
}
/*!
@@ -260,7 +245,7 @@ QJSValue::QJSValue(const QLatin1String &value)
#ifndef QT_NO_CAST_FROM_ASCII
QJSValue::QJSValue(const char *value)
{
- QJSValuePrivate::setVariant(this, QVariant(QString::fromUtf8(value)));
+ QJSValuePrivate::setString(this, QString(QString::fromUtf8(value)));
}
#endif
@@ -271,15 +256,12 @@ QJSValue::QJSValue(const char *value)
true), then only a reference to the underlying object is copied into
the new script value (i.e., the object itself is not copied).
*/
-QJSValue::QJSValue(const QJSValue& other)
- : d(0)
+QJSValue::QJSValue(const QJSValue &other) : d(0)
{
- QV4::Value *v = QJSValuePrivate::getValue(&other);
- if (v) {
- QJSValuePrivate::setValue(this, QJSValuePrivate::engine(&other), *v);
- } else if (QVariant *v = QJSValuePrivate::getVariant(&other)) {
- QJSValuePrivate::setVariant(this, *v);
- }
+ if (const QString *string = QJSValuePrivate::asQString(&other))
+ QJSValuePrivate::setString(this, *string);
+ else
+ QJSValuePrivate::setValue(this, QJSValuePrivate::asReturnedValue(&other));
}
/*!
@@ -310,11 +292,7 @@ QJSValue::~QJSValue()
*/
bool QJSValue::isBool() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val)
- return val->isBoolean();
- QVariant *variant = QJSValuePrivate::getVariant(this);
- return variant && variant->userType() == QMetaType::Bool;
+ return QV4::Value::fromReturnedValue(d).isBoolean();
}
/*!
@@ -325,27 +303,7 @@ bool QJSValue::isBool() const
*/
bool QJSValue::isNumber() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val)
- return val->isNumber();
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (!variant)
- return false;
-
- switch (variant->userType()) {
- case QMetaType::Double:
- case QMetaType::Int:
- case QMetaType::UInt:
- case QMetaType::Long:
- case QMetaType::ULong:
- case QMetaType::Short:
- case QMetaType::UShort:
- case QMetaType::LongLong:
- case QMetaType::ULongLong:
- return true;
- default:
- return false;
- }
+ return QV4::Value::fromReturnedValue(d).isNumber();
}
/*!
@@ -354,14 +312,7 @@ bool QJSValue::isNumber() const
*/
bool QJSValue::isNull() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val)
- return val->isNull();
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (!variant)
- return false;
- const int type = variant->userType();
- return type == QMetaType::Nullptr || type == QMetaType::VoidStar;
+ return QV4::Value::fromReturnedValue(d).isNull();
}
/*!
@@ -372,24 +323,27 @@ bool QJSValue::isNull() const
*/
bool QJSValue::isString() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val)
- return val->isString();
- QVariant *variant = QJSValuePrivate::getVariant(this);
- return variant && variant->userType() == QMetaType::QString;
+ if (QJSValuePrivate::asQString(this))
+ return true;
+
+ // String is managed
+ return QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this)).isString();
}
/*!
- Returns true if this QJSValue is of the primitive type Undefined;
- otherwise returns false.
+ Returns true if this QJSValue is of the primitive type Undefined or if the managed value
+ has been cleared (by deleting the engine). Otherwise returns false.
*/
bool QJSValue::isUndefined() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val)
- return val->isUndefined();
- QVariant *variant = QJSValuePrivate::getVariant(this);
- return !variant || variant->userType() == QMetaType::UnknownType || variant->userType() == QMetaType::Void;
+ if (QJSValuePrivate::asQString(this))
+ return false;
+ QV4::Value v = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this));
+ if (v.isUndefined())
+ return true;
+ if (!v.isManaged())
+ return false;
+ return v.managed() == nullptr;
}
/*!
@@ -400,10 +354,7 @@ bool QJSValue::isUndefined() const
*/
bool QJSValue::isError() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return false;
- return val->as<ErrorObject>();
+ return QJSValuePrivate::asManagedType<ErrorObject>(this);
}
/*!
@@ -415,10 +366,7 @@ bool QJSValue::isError() const
*/
QJSValue::ErrorType QJSValue::errorType() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return NoError;
- QV4::ErrorObject *error = val->as<ErrorObject>();
+ const QV4::ErrorObject *error = QJSValuePrivate::asManagedType<ErrorObject>(this);
if (!error)
return NoError;
switch (error->d()->errorType) {
@@ -449,10 +397,7 @@ QJSValue::ErrorType QJSValue::errorType() const
*/
bool QJSValue::isArray() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return false;
- return val->as<ArrayObject>();
+ return QJSValuePrivate::asManagedType<ArrayObject>(this);
}
/*!
@@ -466,10 +411,7 @@ bool QJSValue::isArray() const
*/
bool QJSValue::isObject() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return false;
- return val->as<QV4::Object>();
+ return QJSValuePrivate::asManagedType<QV4::Object>(this);
}
/*!
@@ -480,10 +422,7 @@ bool QJSValue::isObject() const
*/
bool QJSValue::isCallable() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return false;
- return val->as<FunctionObject>();
+ return QJSValuePrivate::asManagedType<FunctionObject>(this);
}
/*!
@@ -494,10 +433,7 @@ bool QJSValue::isCallable() const
*/
bool QJSValue::isVariant() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return false;
- return val->as<QV4::VariantObject>();
+ return QJSValuePrivate::asManagedType<QV4::VariantObject>(this);
}
/*!
@@ -514,27 +450,22 @@ bool QJSValue::isVariant() const
*/
QString QJSValue::toString() const
{
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- Q_ASSERT(variant);
- if (variant->userType() == QMetaType::QVariantMap)
- return QStringLiteral("[object Object]");
- else if (variant->userType() == QMetaType::QVariantList) {
- const QVariantList list = variant->toList();
- QString result;
- for (int i = 0; i < list.count(); ++i) {
- if (i > 0)
- result.append(QLatin1Char(','));
- result.append(list.at(i).toString());
- }
- return result;
- }
- return variant->toString();
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return *string;
+
+ return QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this)).toQStringNoThrow();
+}
+
+template<typename T>
+T caughtResult(const QJSValue *v, T (QV4::Value::*convert)() const)
+{
+ const T result = (QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(v)).*convert)();
+ QV4::ExecutionEngine *engine = QJSValuePrivate::engine(v);
+ if (engine && engine->hasException) {
+ engine->catchException();
+ return T();
}
- return val->toQStringNoThrow();
+ return result;
}
/*!
@@ -551,28 +482,10 @@ QString QJSValue::toString() const
*/
double QJSValue::toNumber() const
{
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- Q_ASSERT(variant);
-
- if (variant->userType() == QMetaType::QString)
- return RuntimeHelpers::stringToNumber(variant->toString());
- else if (variant->canConvert<double>())
- return variant->value<double>();
- else
- return std::numeric_limits<double>::quiet_NaN();
- }
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return RuntimeHelpers::stringToNumber(*string);
- double dbl = val->toNumber();
- QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
- if (engine && engine->hasException) {
- engine->catchException();
- return 0;
- }
- return dbl;
+ return caughtResult<double>(this, &QV4::Value::toNumber);
}
/*!
@@ -589,24 +502,10 @@ double QJSValue::toNumber() const
*/
bool QJSValue::toBool() const
{
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (variant->userType() == QMetaType::QString)
- return variant->toString().length() > 0;
- else
- return variant->toBool();
- }
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return string->length() > 0;
- bool b = val->toBoolean();
- QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
- if (engine && engine->hasException) {
- engine->catchException();
- return false;
- }
- return b;
+ return caughtResult<bool>(this, &QV4::Value::toBoolean);
}
/*!
@@ -623,24 +522,10 @@ bool QJSValue::toBool() const
*/
qint32 QJSValue::toInt() const
{
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (variant->userType() == QMetaType::QString)
- return QV4::Value::toInt32(RuntimeHelpers::stringToNumber(variant->toString()));
- else
- return variant->toInt();
- }
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return QV4::Value::toInt32(RuntimeHelpers::stringToNumber(*string));
- qint32 i = val->toInt32();
- QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
- if (engine && engine->hasException) {
- engine->catchException();
- return 0;
- }
- return i;
+ return caughtResult<qint32>(this, &QV4::Value::toInt32);
}
/*!
@@ -657,24 +542,10 @@ qint32 QJSValue::toInt() const
*/
quint32 QJSValue::toUInt() const
{
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
-
- if (!val) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (variant->userType() == QMetaType::QString)
- return QV4::Value::toUInt32(RuntimeHelpers::stringToNumber(variant->toString()));
- else
- return variant->toUInt();
- }
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return QV4::Value::toUInt32(RuntimeHelpers::stringToNumber(*string));
- quint32 u = val->toUInt32();
- QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
- if (engine && engine->hasException) {
- engine->catchException();
- return 0;
- }
- return u;
+ return caughtResult<quint32>(this, &QV4::Value::toUInt32);
}
/*!
@@ -701,29 +572,29 @@ quint32 QJSValue::toUInt() const
*/
QVariant QJSValue::toVariant() const
{
- QVariant *variant = QJSValuePrivate::getVariant(this);
- if (variant)
- return *variant;
-
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
- Q_ASSERT(val);
-
- if (QV4::Object *o = val->as<QV4::Object>())
- return o->engine()->toVariant(*val, /*typeHint*/ -1, /*createJSValueForObjects*/ false);
-
- if (String *s = val->stringValue())
- return QVariant(s->toQString());
- if (val->isBoolean())
- return QVariant(val->booleanValue());
- if (val->isNumber()) {
- if (val->isInt32())
- return QVariant(val->integerValue());
- return QVariant(val->asDouble());
- }
- if (val->isNull())
+ if (const QString *string = QJSValuePrivate::asQString(this))
+ return QVariant(*string);
+
+ QV4::Value val = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this));
+ if (val.isUndefined())
+ return QVariant();
+ if (val.isNull())
return QVariant(QMetaType::Nullptr, nullptr);
- Q_ASSERT(val->isUndefined());
+ if (val.isBoolean())
+ return QVariant(val.booleanValue());
+ if (val.isInt32()) // Includes doubles that can be losslessly casted to int
+ return QVariant(val.integerValue());
+ if (val.isNumber())
+ return QVariant(val.doubleValue());
+
+ Q_ASSERT(val.isManaged());
+
+ if (val.isString())
+ return QVariant(val.toQString());
+ if (QV4::Managed *m = val.as<QV4::Managed>())
+ return m->engine()->toVariant(val, /*typeHint*/ -1, /*createJSValueForObjects*/ false);
+
+ Q_ASSERT(false);
return QVariant();
}
@@ -742,13 +613,9 @@ QVariant QJSValue::toVariant() const
\sa isCallable(), callWithInstance(), callAsConstructor()
*/
-QJSValue QJSValue::call(const QJSValueList &args)
+QJSValue QJSValue::call(const QJSValueList &args) const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return QJSValue();
-
- FunctionObject *f = val->as<FunctionObject>();
+ const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(this);
if (!f)
return QJSValue();
@@ -763,7 +630,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
}
ScopedValue result(scope, f->call(jsCallData));
@@ -772,7 +639,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
if (engine->isInterrupted.loadAcquire())
result = engine->newErrorObject(QStringLiteral("Interrupted"));
- return QJSValue(engine, result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -795,13 +662,9 @@ QJSValue QJSValue::call(const QJSValueList &args)
\sa call()
*/
-QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args)
+QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args) const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return QJSValue();
-
- FunctionObject *f = val->as<FunctionObject>();
+ const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(this);
if (!f)
return QJSValue();
@@ -815,13 +678,13 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
}
JSCallData jsCallData(scope, args.size());
- *jsCallData->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
+ *jsCallData->thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance);
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
}
ScopedValue result(scope, f->call(jsCallData));
@@ -830,7 +693,7 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
if (engine->isInterrupted.loadAcquire())
result = engine->newErrorObject(QStringLiteral("Interrupted"));
- return QJSValue(engine, result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -851,13 +714,9 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
\sa call(), QJSEngine::newObject()
*/
-QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
+QJSValue QJSValue::callAsConstructor(const QJSValueList &args) const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (!val)
- return QJSValue();
-
- FunctionObject *f = val->as<FunctionObject>();
+ const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(this);
if (!f)
return QJSValue();
@@ -871,7 +730,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
return QJSValue();
}
- jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
}
ScopedValue result(scope, f->callAsConstructor(jsCallData));
@@ -880,7 +739,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
if (engine->isInterrupted.loadAcquire())
result = engine->newErrorObject(QStringLiteral("Interrupted"));
- return QJSValue(engine, result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
#ifdef QT_DEPRECATED
@@ -915,13 +774,13 @@ QJSValue QJSValue::prototype() const
if (!engine)
return QJSValue();
QV4::Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<QV4::Object>());
+ ScopedObject o(scope, QJSValuePrivate::asManagedType<QV4::Object>(this));
if (!o)
return QJSValue();
ScopedObject p(scope, o->getPrototypeOf());
if (!p)
return QJSValue(NullValue);
- return QJSValue(o->internalClass()->engine, p.asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(p.asReturnedValue());
}
/*!
@@ -942,14 +801,11 @@ void QJSValue::setPrototype(const QJSValue& prototype)
if (!engine)
return;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return;
- QV4::Value scratch;
- QV4::Value *val = QJSValuePrivate::valueForData(&prototype, &scratch);
- if (!val)
- return;
- if (val->isNull()) {
+ QV4::Value val = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&prototype));
+ if (val.isNull()) {
o->setPrototypeOf(nullptr);
return;
}
@@ -980,12 +836,11 @@ QJSValue& QJSValue::operator=(const QJSValue& other)
QJSValuePrivate::free(this);
d = 0;
- QV4::Value *v = QJSValuePrivate::getValue(&other);
- if (v) {
- QJSValuePrivate::setValue(this, QJSValuePrivate::engine(&other), *v);
- } else if (QVariant *v = QJSValuePrivate::getVariant(&other)) {
- QJSValuePrivate::setVariant(this, *v);
- }
+ if (const QString *string = QJSValuePrivate::asQString(&other))
+ QJSValuePrivate::setString(this, *string);
+ else
+ QJSValuePrivate::setValue(this, QJSValuePrivate::asReturnedValue(&other));
+
return *this;
}
@@ -1031,23 +886,17 @@ static bool js_equal(const QString &string, const QV4::Value &value)
*/
bool QJSValue::equals(const QJSValue& other) const
{
- QV4::Value s1, s2;
- QV4::Value *v = QJSValuePrivate::valueForData(this, &s1);
- QV4::Value *ov = QJSValuePrivate::valueForData(&other, &s2);
-
- if (!v) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- Q_ASSERT(variant);
- if (!ov)
- return *variant == *QJSValuePrivate::getVariant(&other);
- if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
- return false;
- return js_equal(variant->toString(), *ov);
- }
- if (!ov)
- return other.equals(*this);
+ if (const QString *string = QJSValuePrivate::asQString(this)) {
+ if (const QString *otherString = QJSValuePrivate::asQString(&other))
+ return *string == *otherString;
+ return js_equal(*string, QJSValuePrivate::asReturnedValue(&other));
+ }
+
+ if (const QString *otherString = QJSValuePrivate::asQString(&other))
+ return js_equal(*otherString, QJSValuePrivate::asReturnedValue(this));
- return Runtime::CompareEqual::call(*v, *ov);
+ return Runtime::CompareEqual::call(QJSValuePrivate::asReturnedValue(this),
+ QJSValuePrivate::asReturnedValue(&other));
}
/*!
@@ -1074,25 +923,22 @@ bool QJSValue::equals(const QJSValue& other) const
*/
bool QJSValue::strictlyEquals(const QJSValue& other) const
{
- QV4::Value s1, s2;
- QV4::Value *v = QJSValuePrivate::valueForData(this, &s1);
- QV4::Value *ov = QJSValuePrivate::valueForData(&other, &s2);
-
- if (!v) {
- QVariant *variant = QJSValuePrivate::getVariant(this);
- Q_ASSERT(variant);
- if (!ov)
- return *variant == *QJSValuePrivate::getVariant(&other);
- if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
- return false;
- if (String *s = ov->stringValue())
- return variant->toString() == s->toQString();
+ if (const QString *string = QJSValuePrivate::asQString(this)) {
+ if (const QString *otherString = QJSValuePrivate::asQString(&other))
+ return *string == *otherString;
+ if (const String *s = QJSValuePrivate::asManagedType<String>(&other))
+ return *string == s->toQString();
return false;
}
- if (!ov)
- return other.strictlyEquals(*this);
- return RuntimeHelpers::strictEqual(*v, *ov);
+ if (const QString *otherString = QJSValuePrivate::asQString(&other)) {
+ if (const String *s = QJSValuePrivate::asManagedType<String>(this))
+ return *otherString == s->toQString();
+ return false;
+ }
+
+ return RuntimeHelpers::strictEqual(QJSValuePrivate::asReturnedValue(this),
+ QJSValuePrivate::asReturnedValue(&other));
}
/*!
@@ -1119,7 +965,7 @@ QJSValue QJSValue::property(const QString& name) const
return QJSValue();
QV4::Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return QJSValue();
@@ -1128,7 +974,7 @@ QJSValue QJSValue::property(const QString& name) const
if (engine->hasException)
result = engine->catchException();
- return QJSValue(engine, result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -1167,14 +1013,14 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
return QJSValue();
QV4::Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return QJSValue();
QV4::ScopedValue result(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax()) : o->get(arrayIndex));
if (engine->hasException)
engine->catchException();
- return QJSValue(engine, result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -1199,7 +1045,7 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
return;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return;
@@ -1209,7 +1055,7 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
}
ScopedString s(scope, engine->newString(name));
- QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
+ QV4::ScopedValue v(scope, QJSValuePrivate::convertToReturnedValue(engine, value));
o->put(s->toPropertyKey(), v);
if (engine->hasException)
engine->catchException();
@@ -1253,7 +1099,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
return;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return;
@@ -1262,7 +1108,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
return;
}
- QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
+ QV4::ScopedValue v(scope, QJSValuePrivate::convertToReturnedValue(engine, value));
PropertyKey id = arrayIndex != UINT_MAX ? PropertyKey::fromArrayIndex(arrayIndex) : engine->id_uintMax()->propertyKey();
o->put(id, v);
if (engine->hasException)
@@ -1296,7 +1142,7 @@ bool QJSValue::deleteProperty(const QString &name)
return false;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return false;
@@ -1317,7 +1163,7 @@ bool QJSValue::hasProperty(const QString &name) const
return false;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return false;
@@ -1338,7 +1184,7 @@ bool QJSValue::hasOwnProperty(const QString &name) const
return false;
Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this));
+ ScopedObject o(scope, QJSValuePrivate::asReturnedValue(this));
if (!o)
return false;
@@ -1362,7 +1208,7 @@ QObject *QJSValue::toQObject() const
if (!engine)
return nullptr;
QV4::Scope scope(engine);
- QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
+ QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, QJSValuePrivate::asReturnedValue(this));
if (!wrapper)
return nullptr;
@@ -1383,7 +1229,7 @@ const QMetaObject *QJSValue::toQMetaObject() const
if (!engine)
return nullptr;
QV4::Scope scope(engine);
- QV4::Scoped<QV4::QMetaObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
+ QV4::Scoped<QV4::QMetaObjectWrapper> wrapper(scope, QJSValuePrivate::asReturnedValue(this));
if (!wrapper)
return nullptr;
@@ -1400,12 +1246,8 @@ const QMetaObject *QJSValue::toQMetaObject() const
*/
QDateTime QJSValue::toDateTime() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- if (val) {
- QV4::DateObject *date = val->as<DateObject>();
- if (date)
- return date->toQDateTime();
- }
+ if (const QV4::DateObject *date = QJSValuePrivate::asManagedType<DateObject>(this))
+ return date->toQDateTime();
return QDateTime();
}
@@ -1415,8 +1257,7 @@ QDateTime QJSValue::toDateTime() const
*/
bool QJSValue::isDate() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<DateObject>();
+ return QJSValuePrivate::asManagedType<DateObject>(this);
}
/*!
@@ -1425,8 +1266,7 @@ bool QJSValue::isDate() const
*/
bool QJSValue::isRegExp() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<RegExpObject>();
+ return QJSValuePrivate::asManagedType<RegExpObject>(this);
}
/*!
@@ -1440,8 +1280,7 @@ bool QJSValue::isRegExp() const
*/
bool QJSValue::isQObject() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<QV4::QObjectWrapper>() != nullptr;
+ return QJSValuePrivate::asManagedType<QV4::QObjectWrapper>(this);
}
/*!
@@ -1454,8 +1293,7 @@ bool QJSValue::isQObject() const
*/
bool QJSValue::isQMetaObject() const
{
- QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<QV4::QMetaObjectWrapper>() != nullptr;
+ return QJSValuePrivate::asManagedType<QV4::QMetaObjectWrapper>(this);
}
QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h
index 2f95e0ff31..091f353291 100644
--- a/src/qml/jsapi/qjsvalue.h
+++ b/src/qml/jsapi/qjsvalue.h
@@ -144,22 +144,21 @@ public:
bool deleteProperty(const QString &name);
bool isCallable() const;
- QJSValue call(const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
- QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
- QJSValue callAsConstructor(const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
+ QJSValue call(const QJSValueList &args = QJSValueList()) const;
+ QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList()) const;
+ QJSValue callAsConstructor(const QJSValueList &args = QJSValueList()) const;
ErrorType errorType() const;
#ifdef QT_DEPRECATED
QT_DEPRECATED QJSEngine *engine() const;
#endif
- QJSValue(QV4::ExecutionEngine *e, quint64 val);
private:
friend class QJSValuePrivate;
// force compile error, prevent QJSValue(bool) to be called
QJSValue(void *) Q_DECL_EQ_DELETE;
- mutable quintptr d;
+ quint64 d;
};
QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index 2faffffbae..5533682144 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -64,132 +64,181 @@
QT_BEGIN_NAMESPACE
+// QJSValue::d is a QV4::ReturnedValue, but we don't want to expose that in the public header.
+// We use the lower bits of the managed pointer to hide a QString* or a QV4::Value* in there.
+Q_STATIC_ASSERT(sizeof(QV4::ReturnedValue) == sizeof(quint64));
+Q_STATIC_ASSERT(alignof(QV4::Value) >= 4);
+Q_STATIC_ASSERT(alignof(QString) >= 4);
+
+enum PointerMask: quintptr {
+ IsV4Value = 0x0,
+ IsString = 0x1
+};
+
class Q_AUTOTEST_EXPORT QJSValuePrivate
{
+ static const QV4::Value *managedValue(const QV4::Value &v)
+ {
+ const quintptr m = quintptr(v.m());
+ return (m & IsString) ? nullptr : reinterpret_cast<QV4::Value *>(m);
+ }
+
+ static const QString *qstring(const QV4::Value &v)
+ {
+ const quintptr m = quintptr(v.m());
+ return (m & IsString) ? reinterpret_cast<QString *>(m & ~IsString) : nullptr;
+ }
+
+ static QV4::ReturnedValue encode(const QString &string)
+ {
+ const quintptr m = quintptr(new QString(string)) | IsString;
+ return encodeRawValue(m);
+ }
+
+ static QV4::ReturnedValue encode(const QV4::Value &managedValue)
+ {
+ QV4::Value *m = managedValue.as<QV4::Managed>()->engine()
+ ->memoryManager->m_persistentValues->allocate();
+ *m = managedValue;
+ return encodeRawValue(quintptr(m));
+ }
+
+ static QV4::ReturnedValue encodeRawValue(quintptr m)
+ {
+ return QV4::Value::fromHeapObject(reinterpret_cast<QV4::Heap::Base *>(m)).asReturnedValue();
+ }
+
+protected:
+ // Only for the test. You're not supposed to subclass QJSValuePrivate otherwise.
+ static void setRawValue(QJSValue *jsval, QV4::Value *m)
+ {
+ jsval->d = encodeRawValue(quintptr(m));
+ }
+
public:
- static inline QV4::Value *getValue(const QJSValue *jsval)
+ static QJSValue fromReturnedValue(QV4::ReturnedValue d)
{
- if (jsval->d & 3)
- return nullptr;
- return reinterpret_cast<QV4::Value *>(jsval->d);
+ QJSValue result;
+ setValue(&result, d);
+ return result;
}
- static inline QVariant *getVariant(const QJSValue *jsval)
+ template<typename T>
+ static const T *asManagedType(const QJSValue *jsval)
{
- if (jsval->d & 1)
- return reinterpret_cast<QVariant *>(jsval->d & ~3);
+ const QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ if (!v.isManaged())
+ return nullptr;
+ if (const QV4::Value *value = managedValue(v))
+ return value->as<T>();
return nullptr;
}
- static inline void setRawValue(QJSValue *jsval, QV4::Value *v)
+ static QV4::ReturnedValue asPrimitiveType(const QJSValue *jsval)
{
- jsval->d = reinterpret_cast<quintptr>(v);
+ const QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ return v.isManaged() ? QV4::Encode::undefined() : v.asReturnedValue();
}
- static inline void setVariant(QJSValue *jsval, const QVariant &v) {
- QVariant *val = new QVariant(v);
- jsval->d = reinterpret_cast<quintptr>(val) | 1;
+ // Beware: This only returns a non-null string if the QJSValue actually holds one.
+ // QV4::Strings are kept as managed values. Retrieve those with getValue().
+ static const QString *asQString(const QJSValue *jsval)
+ {
+ const QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ return v.isManaged() ? qstring(v) : nullptr;
}
- static inline void setValue(QJSValue *jsval, QV4::ExecutionEngine *engine, const QV4::Value &v) {
- QV4::Value *value = engine->memoryManager->m_persistentValues->allocate();
- *value = v;
- jsval->d = reinterpret_cast<quintptr>(value);
+ static QV4::ReturnedValue asReturnedValue(const QJSValue *jsval)
+ {
+ const QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ if (!v.isManaged())
+ return v.asReturnedValue();
+
+ if (const QV4::Value *value = managedValue(v))
+ return value->asReturnedValue();
+
+ return QV4::Encode::undefined();
}
- static inline void setValue(QJSValue *jsval, QV4::ExecutionEngine *engine, QV4::ReturnedValue v) {
- QV4::Value *value = engine->memoryManager->m_persistentValues->allocate();
- *value = v;
- jsval->d = reinterpret_cast<quintptr>(value);
+ static void setString(QJSValue *jsval, const QString &s)
+ {
+ jsval->d = encode(s);
}
- static QV4::ReturnedValue convertedToValue(QV4::ExecutionEngine *e, const QJSValue &jsval)
+ static void setValue(QJSValue *jsval, const QV4::Value &v)
{
- QV4::Value *v = getValue(&jsval);
- if (!v) {
- QVariant *variant = getVariant(&jsval);
- v = e->memoryManager->m_persistentValues->allocate();
- *v = variant ? e->fromVariant(*variant) : QV4::Encode::undefined();
- jsval.d = reinterpret_cast<quintptr>(v);
- delete variant;
+ jsval->d = v.isManaged() ? encode(v) : v.asReturnedValue();
+ }
+
+ // Moves any QString onto the V4 heap, changing the value to reflect that.
+ static void manageStringOnV4Heap(QV4::ExecutionEngine *e, QJSValue *jsval)
+ {
+ if (const QString *string = asQString(jsval)) {
+ jsval->d = encode(e->newString(*string)->asReturnedValue());
+ delete string;
}
+ }
+
+ // Converts any QString on the fly, involving an allocation.
+ // Does not change the value.
+ static QV4::ReturnedValue convertToReturnedValue(QV4::ExecutionEngine *e,
+ const QJSValue &jsval)
+ {
+ if (const QString *string = asQString(&jsval))
+ return e->newString(*string)->asReturnedValue();
+ if (const QV4::Value *val = asManagedType<QV4::Managed>(&jsval)) {
+ if (QV4::PersistentValueStorage::getEngine(val) == e)
+ return val->asReturnedValue();
- if (QV4::PersistentValueStorage::getEngine(v) != e) {
qWarning("JSValue can't be reassigned to another engine.");
return QV4::Encode::undefined();
}
-
- return v->asReturnedValue();
+ return jsval.d;
}
- static QV4::Value *valueForData(const QJSValue *jsval, QV4::Value *scratch)
+ static QV4::ExecutionEngine *engine(const QJSValue *jsval)
{
- QV4::Value *v = getValue(jsval);
- if (v)
- return v;
- v = scratch;
- QVariant *variant = getVariant(jsval);
- if (!variant) {
- *v = QV4::Encode::undefined();
- return v;
- }
-
- switch (variant->userType()) {
- case QMetaType::UnknownType:
- case QMetaType::Void:
- *v = QV4::Encode::undefined();
- break;
- case QMetaType::Nullptr:
- case QMetaType::VoidStar:
- *v = QV4::Encode::null();
- break;
- case QMetaType::Bool:
- *v = QV4::Encode(variant->toBool());
- break;
- case QMetaType::Double:
- *v = QV4::Encode(variant->toDouble());
- break;
- case QMetaType::Int:
- case QMetaType::Short:
- case QMetaType::UShort:
- case QMetaType::Char:
- case QMetaType::UChar:
- *v = QV4::Encode(variant->toInt());
- break;
- case QMetaType::UInt:
- *v = QV4::Encode(variant->toUInt());
- break;
- default:
+ const QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ if (!v.isManaged())
return nullptr;
- }
- return v;
- }
- static QV4::ExecutionEngine *engine(const QJSValue *jsval) {
- QV4::Value *v = getValue(jsval);
- return v ? QV4::PersistentValueStorage::getEngine(v) : nullptr;
+ if (const QV4::Value *m = managedValue(v))
+ return QV4::PersistentValueStorage::getEngine(m);
+
+ return nullptr;
}
- static inline bool checkEngine(QV4::ExecutionEngine *e, const QJSValue &jsval) {
+ static bool checkEngine(QV4::ExecutionEngine *e, const QJSValue &jsval)
+ {
QV4::ExecutionEngine *v4 = engine(&jsval);
return !v4 || v4 == e;
}
- static inline void free(QJSValue *jsval) {
- if (QV4::Value *v = QJSValuePrivate::getValue(jsval)) {
- if (QV4::ExecutionEngine *e = engine(jsval)) {
- if (QJSEngine *jsEngine = e->jsEngine()) {
- if (jsEngine->thread() != QThread::currentThread()) {
- QMetaObject::invokeMethod(
- jsEngine, [v](){ QV4::PersistentValueStorage::free(v); });
- return;
- }
+ static void free(QJSValue *jsval)
+ {
+ QV4::Value v = QV4::Value::fromReturnedValue(jsval->d);
+ if (!v.isManaged())
+ return;
+
+ if (const QString *m = qstring(v)) {
+ delete m;
+ return;
+ }
+
+ // We need a mutable value for free(). It needs to write to the actual memory.
+ Q_ASSERT(!(quintptr(v.m()) & IsString));
+ QV4::Value *m = reinterpret_cast<QV4::Value *>(v.m());
+ Q_ASSERT(m); // Otherwise it would have been undefined, that is !v.isManaged() above.
+ if (QV4::ExecutionEngine *e = QV4::PersistentValueStorage::getEngine(m)) {
+ if (QJSEngine *jsEngine = e->jsEngine()) {
+ if (jsEngine->thread() != QThread::currentThread()) {
+ QMetaObject::invokeMethod(
+ jsEngine, [m](){ QV4::PersistentValueStorage::free(m); });
+ return;
}
}
- QV4::PersistentValueStorage::free(v);
- } else if (QVariant *v = QJSValuePrivate::getVariant(jsval)) {
- delete v;
}
+ QV4::PersistentValueStorage::free(m);
}
};
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
index 076b90c5f2..360a39aea3 100644
--- a/src/qml/jsapi/qjsvalueiterator.cpp
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -58,12 +58,12 @@ void QJSValueIteratorPrivate::init(const QJSValue &v)
QV4::ExecutionEngine *e = QJSValuePrivate::engine(&v);
if (!e)
return;
- QV4::Object *o = QJSValuePrivate::getValue(&v)->objectValue();
+ const QV4::Object *o = QJSValuePrivate::asManagedType<QV4::Object>(&v);
if (!o)
return;
engine = e;
- object = o;
+ object.set(e, o->asReturnedValue());
iterator.reset(o->ownPropertyKeys(object.valueRef()));
next();
}
@@ -209,7 +209,7 @@ QJSValue QJSValueIterator::value() const
scope.engine->catchException();
return QJSValue();
}
- return QJSValue(scope.engine, val->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(val->asReturnedValue());
}
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 32acc6affc..00127e1ca8 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -6,7 +6,7 @@ SOURCES += \
$$PWD/qv4context.cpp \
$$PWD/qv4persistent.cpp \
$$PWD/qv4lookup.cpp \
- $$PWD/qv4identifier.cpp \
+ $$PWD/qv4identifierhash.cpp \
$$PWD/qv4identifiertable.cpp \
$$PWD/qv4managed.cpp \
$$PWD/qv4internalclass.cpp \
@@ -59,10 +59,12 @@ SOURCES += \
$$PWD/qv4module.cpp \
$$PWD/qv4promiseobject.cpp \
$$PWD/qv4runtime.cpp \
+ $$PWD/qv4urlobject.cpp \
$$PWD/qv4value.cpp \
$$PWD/qv4compilationunitmapper.cpp \
$$PWD/qv4executablecompilationunit.cpp \
- $$PWD/qv4executableallocator.cpp
+ $$PWD/qv4executableallocator.cpp \
+ $$PWD/qv4resolvedtypereference.cpp
qtConfig(qml-debug): SOURCES += $$PWD/qv4profiling.cpp
@@ -75,7 +77,8 @@ HEADERS += \
$$PWD/qv4persistent_p.h \
$$PWD/qv4debugging_p.h \
$$PWD/qv4lookup_p.h \
- $$PWD/qv4identifier_p.h \
+ $$PWD/qv4identifierhashdata_p.h \
+ $$PWD/qv4identifierhash_p.h \
$$PWD/qv4identifiertable_p.h \
$$PWD/qv4managed_p.h \
$$PWD/qv4internalclass_p.h \
@@ -134,11 +137,13 @@ HEADERS += \
$$PWD/qv4module_p.h \
$$PWD/qv4promiseobject_p.h \
$$PWD/qv4runtime_p.h \
+ $$PWD/qv4urlobject_p.h \
$$PWD/qv4value_p.h \
$$PWD/qv4compilationunitmapper_p.h \
$$PWD/qv4executablecompilationunit_p.h \
$$PWD/qv4functiontable_p.h \
- $$PWD/qv4runtimeapi_p.h
+ $$PWD/qv4runtimeapi_p.h \
+ $$PWD/qv4resolvedtypereference_p.h
qtConfig(qml-sequence-object) {
HEADERS += \
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index a99ec16943..a2fac21b29 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -127,13 +127,17 @@ ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value
void Heap::SharedArrayBuffer::init(size_t length)
{
Object::init();
+ QPair<QTypedArrayData<char> *, char *> pair;
if (length < UINT_MAX)
- data = QTypedArrayData<char>::allocate(length + 1);
- if (!data) {
+ pair = QTypedArrayData<char>::allocate(length + 1);
+ if (!pair.first) {
+ new (&d) QArrayDataPointer<char>();
internalClass->engine->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
return;
}
- data->size = int(length);
+ auto data = new (&d) QArrayDataPointer<char>{ pair.first, pair.second, uint(length) };
+
+ // can't use appendInitialize() because we want to set the terminating '\0'
memset(data->data(), 0, length + 1);
isShared = true;
}
@@ -141,41 +145,24 @@ void Heap::SharedArrayBuffer::init(size_t length)
void Heap::SharedArrayBuffer::init(const QByteArray& array)
{
Object::init();
- data = const_cast<QByteArray&>(array).data_ptr();
- data->ref.ref();
+ new (&d) QArrayDataPointer<char>(*const_cast<QByteArray &>(array).data_ptr());
isShared = true;
}
void Heap::SharedArrayBuffer::destroy()
{
- if (data && !data->ref.deref())
- QTypedArrayData<char>::deallocate(data);
+ data().~QArrayDataPointer();
Object::destroy();
}
QByteArray ArrayBuffer::asByteArray() const
{
- QByteArrayDataPtr ba = { d()->data };
- ba.ptr->ref.ref();
- return QByteArray(ba);
+ return QByteArray(d()->data());
}
-void ArrayBuffer::detach() {
- if (!d()->data->ref.isShared())
- return;
-
- QTypedArrayData<char> *oldData = d()->data;
-
- d()->data = QTypedArrayData<char>::allocate(oldData->size + 1);
- if (!d()->data) {
- engine()->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
- return;
- }
-
- memcpy(d()->data->data(), oldData->data(), oldData->size + 1);
-
- if (!oldData->ref.deref())
- QTypedArrayData<char>::deallocate(oldData);
+void ArrayBuffer::detach()
+{
+ d()->data().detach();
}
@@ -200,7 +187,7 @@ ReturnedValue SharedArrayBufferPrototype::method_get_byteLength(const FunctionOb
if (!a || a->isDetachedBuffer() || !a->isSharedArrayBuffer())
return b->engine()->throwTypeError();
- return Encode(a->d()->data->size);
+ return Encode(a->d()->data()->size);
}
ReturnedValue SharedArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
@@ -217,12 +204,12 @@ ReturnedValue SharedArrayBufferPrototype::slice(const FunctionObject *b, const V
double start = argc > 0 ? argv[0].toInteger() : 0;
double end = (argc < 2 || argv[1].isUndefined()) ?
- a->d()->data->size : argv[1].toInteger();
+ a->d()->data()->size : argv[1].toInteger();
if (scope.hasException())
return QV4::Encode::undefined();
- double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size);
- double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
+ double first = (start < 0) ? qMax(a->d()->data()->size + start, 0.) : qMin(start, (double)a->d()->data()->size);
+ double final = (end < 0) ? qMax(a->d()->data()->size + end, 0.) : qMin(end, (double)a->d()->data()->size);
const FunctionObject *constructor = a->speciesConstructor(scope, shared ? scope.engine->sharedArrayBufferCtor() : scope.engine->arrayBufferCtor());
if (!constructor)
@@ -231,13 +218,13 @@ ReturnedValue SharedArrayBufferPrototype::slice(const FunctionObject *b, const V
double newLen = qMax(final - first, 0.);
ScopedValue argument(scope, QV4::Encode(newLen));
QV4::Scoped<SharedArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1));
- if (!newBuffer || newBuffer->d()->data->size < (int)newLen ||
+ if (!newBuffer || newBuffer->d()->data()->size < newLen ||
newBuffer->isDetachedBuffer() || (newBuffer->isSharedArrayBuffer() != shared) ||
newBuffer->sameValue(*a) ||
a->isDetachedBuffer())
return scope.engine->throwTypeError();
- memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
+ memcpy(newBuffer->d()->data()->data(), a->d()->data()->data() + (uint)first, newLen);
return newBuffer->asReturnedValue();
}
@@ -265,7 +252,7 @@ ReturnedValue ArrayBufferPrototype::method_get_byteLength(const FunctionObject *
if (!a || a->isDetachedBuffer() || a->isSharedArrayBuffer())
return f->engine()->throwTypeError();
- return Encode(a->d()->data->size);
+ return Encode(a->d()->data()->size);
}
ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index 8344fa2554..1873c41261 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -52,6 +52,7 @@
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
+#include <QtCore/qarraydatapointer.h>
QT_BEGIN_NAMESPACE
@@ -71,12 +72,14 @@ struct Q_QML_PRIVATE_EXPORT SharedArrayBuffer : Object {
void init(size_t length);
void init(const QByteArray& array);
void destroy();
- QTypedArrayData<char> *data;
+ std::aligned_storage_t<sizeof(QArrayDataPointer<char>), alignof(QArrayDataPointer<char>)> d;
+ const QArrayDataPointer<char> &data() const { return *reinterpret_cast<const QArrayDataPointer<char> *>(&d); }
+ QArrayDataPointer<char> &data() { return *reinterpret_cast<QArrayDataPointer<char> *>(&d); }
bool isShared;
- uint byteLength() const { return data ? data->size : 0; }
+ uint byteLength() const { return data().size; }
- bool isDetachedBuffer() const { return !data; }
+ bool isDetachedBuffer() const { return data().isNull(); }
bool isSharedArrayBuffer() const { return isShared; }
};
@@ -90,9 +93,7 @@ struct Q_QML_PRIVATE_EXPORT ArrayBuffer : SharedArrayBuffer {
isShared = false;
}
void detachArrayBuffer() {
- if (data && !data->ref.deref())
- QTypedArrayData<char>::deallocate(data);
- data = nullptr;
+ data().clear();
}
};
@@ -124,11 +125,11 @@ struct Q_QML_PRIVATE_EXPORT SharedArrayBuffer : Object
QByteArray asByteArray() const;
uint byteLength() const { return d()->byteLength(); }
- char *data() { Q_ASSERT(d()->data); return d()->data->data(); }
- const char *constData() { Q_ASSERT(d()->data); return d()->data->data(); }
+ char *data() { return d()->data()->data(); }
+ const char *constData() { return d()->data()->data(); }
- bool isShared() { return d()->data->ref.isShared(); }
- bool isDetachedBuffer() const { return !d()->data; }
+ bool isShared() { return d()->data()->isShared(); }
+ bool isDetachedBuffer() const { return d()->data().isNull(); }
bool isSharedArrayBuffer() const { return d()->isShared; }
};
@@ -140,11 +141,11 @@ struct Q_QML_PRIVATE_EXPORT ArrayBuffer : SharedArrayBuffer
QByteArray asByteArray() const;
uint byteLength() const { return d()->byteLength(); }
- char *data() { detach(); return d()->data ? d()->data->data() : nullptr; }
+ char *data() { if (d()->data().needsDetach()) detach(); return d()->data().data(); }
// ### is that detach needed?
- const char *constData() { detach(); return d()->data ? d()->data->data() : nullptr; }
+ const char *constData() const { return d()->data().data(); }
- bool isShared() { return d()->data && d()->data->ref.isShared(); }
+ bool isShared() { return d()->data()->isShared(); }
void detach();
void detachArrayBuffer() { d()->detachArrayBuffer(); }
};
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 1c587d2367..0eea3345c5 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -654,6 +654,8 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const
jsCallData->args[0] = v1;
jsCallData->args[1] = v2;
result = o->call(jsCallData);
+ if (scope.hasException())
+ return false;
return result->toNumber() < 0;
}
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index da1b91e69a..264057e162 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -85,7 +85,7 @@ ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, co
if (buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- uint bufferLength = buffer->d()->data->size;
+ uint bufferLength = buffer->d()->data()->size;
if (offset > bufferLength)
return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
@@ -197,7 +197,7 @@ ReturnedValue DataViewPrototype::method_getChar(const FunctionObject *b, const V
return e->throwRangeError(QStringLiteral("index out of range"));
idx += v->d()->byteOffset;
- T t = T(v->d()->buffer->data->data()[idx]);
+ T t = T(v->d()->buffer->data()->data()[idx]);
return Encode((int)t);
}
@@ -221,8 +221,8 @@ ReturnedValue DataViewPrototype::method_get(const FunctionObject *b, const Value
bool littleEndian = argc < 2 ? false : argv[1].toBoolean();
T t = littleEndian
- ? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx)
- : qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx);
+ ? qFromLittleEndian<T>((uchar *)v->d()->buffer->data()->data() + idx)
+ : qFromBigEndian<T>((uchar *)v->d()->buffer->data()->data() + idx);
return Encode(t);
}
@@ -252,8 +252,8 @@ ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const
float f;
} u;
u.i = littleEndian
- ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx)
- : qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx);
+ ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data()->data() + idx)
+ : qFromBigEndian<uint>((uchar *)v->d()->buffer->data()->data() + idx);
return Encode(u.f);
} else {
Q_ASSERT(sizeof(T) == 8);
@@ -262,8 +262,8 @@ ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const
double d;
} u;
u.i = littleEndian
- ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx)
- : qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx);
+ ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data()->data() + idx)
+ : qFromBigEndian<quint64>((uchar *)v->d()->buffer->data()->data() + idx);
return Encode(u.d);
}
}
@@ -288,7 +288,7 @@ ReturnedValue DataViewPrototype::method_setChar(const FunctionObject *b, const V
return e->throwRangeError(QStringLiteral("index out of range"));
idx += v->d()->byteOffset;
- v->d()->buffer->data->data()[idx] = (char)val;
+ v->d()->buffer->data()->data()[idx] = (char)val;
RETURN_UNDEFINED();
}
@@ -316,9 +316,9 @@ ReturnedValue DataViewPrototype::method_set(const FunctionObject *b, const Value
if (littleEndian)
- qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
+ qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data()->data() + idx);
else
- qToBigEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
+ qToBigEndian<T>(val, (uchar *)v->d()->buffer->data()->data() + idx);
RETURN_UNDEFINED();
}
@@ -352,9 +352,9 @@ ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const
} u;
u.f = val;
if (littleEndian)
- qToLittleEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
+ qToLittleEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx);
else
- qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
+ qToBigEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx);
} else {
Q_ASSERT(sizeof(T) == 8);
union {
@@ -363,9 +363,9 @@ ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const
} u;
u.d = val;
if (littleEndian)
- qToLittleEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
+ qToLittleEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx);
else
- qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
+ qToBigEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx);
}
RETURN_UNDEFINED();
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 680ccc02a8..6a583bf395 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -91,6 +91,7 @@
#include "qv4proxy_p.h"
#include "qv4stackframe_p.h"
#include "qv4atomics_p.h"
+#include "qv4urlobject_p.h"
#if QT_CONFIG(qml_sequence_object)
#include "qv4sequenceobject_p.h"
@@ -165,8 +166,23 @@ static void saveJSValue(QDataStream &stream, const void *data)
if (jsv->isUndefined())
isNullOrUndefined |= 0x2;
stream << isNullOrUndefined;
- if (!isNullOrUndefined)
- reinterpret_cast<const QJSValue*>(data)->toVariant().save(stream);
+ if (!isNullOrUndefined) {
+ const QVariant v = reinterpret_cast<const QJSValue*>(data)->toVariant();
+ switch (v.userType()) {
+ case QMetaType::Bool:
+ case QMetaType::Double:
+ case QMetaType::Int:
+ case QMetaType::QString:
+ v.save(stream);
+ break;
+ default:
+ qWarning() << "QDataStream::operator<< was to save a non-trivial QJSValue."
+ << "This is not supported anymore, please stream a QVariant instead.";
+ QVariant().save(stream);
+ break;
+ }
+
+ }
}
static void restoreJSValue(QDataStream &stream, void *data)
@@ -183,7 +199,25 @@ static void restoreJSValue(QDataStream &stream, void *data)
} else {
QVariant v;
v.load(stream);
- QJSValuePrivate::setVariant(jsv, v);
+
+ switch (v.userType()) {
+ case QMetaType::Bool:
+ *jsv = QJSValue(v.toBool());
+ break;
+ case QMetaType::Double:
+ *jsv = QJSValue(v.toDouble());
+ break;
+ case QMetaType::Int:
+ *jsv = QJSValue(v.toInt());
+ break;
+ case QMetaType::QString:
+ *jsv = QJSValue(v.toString());
+ break;
+ default:
+ qWarning() << "QDataStream::operator>> to restore a non-trivial QJSValue."
+ << "This is not supported anymore, please stream a QVariant instead.";
+ break;
+ }
}
}
@@ -617,6 +651,15 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
ic = newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype());
jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(ic);
+ //
+ // url
+ //
+
+ jsObjects[Url_Ctor] = memoryManager->allocate<UrlCtor>(global);
+ jsObjects[UrlProto] = memoryManager->allocate<UrlPrototype>();
+ jsObjects[UrlSearchParams_Ctor] = memoryManager->allocate<UrlSearchParamsCtor>(global);
+ jsObjects[UrlSearchParamsProto] = memoryManager->allocate<UrlSearchParamsPrototype>();
+
str = newString(QStringLiteral("get [Symbol.species]"));
jsObjects[GetSymbolSpecies] = FunctionObject::createBuiltinFunction(this, str, ArrayPrototype::method_get_species, 0);
@@ -638,6 +681,8 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(this, syntaxErrorCtor());
static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(this, typeErrorCtor());
static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor());
+ static_cast<UrlPrototype *>(urlPrototype())->init(this, urlCtor());
+ static_cast<UrlSearchParamsPrototype *>(urlSearchParamsPrototype())->init(this, urlSearchParamsCtor());
static_cast<IteratorPrototype *>(iteratorPrototype())->init(this);
static_cast<ForInIteratorPrototype *>(forInIteratorPrototype())->init(this);
@@ -727,6 +772,8 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
globalObject->defineDefaultProperty(QStringLiteral("TypeError"), *typeErrorCtor());
globalObject->defineDefaultProperty(QStringLiteral("URIError"), *uRIErrorCtor());
globalObject->defineDefaultProperty(QStringLiteral("Promise"), *promiseCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("URL"), *urlCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("URLSearchParams"), *urlSearchParamsCtor());
globalObject->defineDefaultProperty(QStringLiteral("SharedArrayBuffer"), *sharedArrayBufferCtor());
globalObject->defineDefaultProperty(QStringLiteral("ArrayBuffer"), *arrayBufferCtor());
@@ -1009,11 +1056,6 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(RegExp *re)
return memoryManager->allocate<RegExpObject>(re);
}
-Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
-{
- return memoryManager->allocate<RegExpObject>(re);
-}
-
#if QT_CONFIG(regularexpression)
Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegularExpression &re)
{
@@ -1021,6 +1063,16 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegularExpression &r
}
#endif
+Heap::UrlObject *ExecutionEngine::newUrlObject()
+{
+ return memoryManager->allocate<UrlObject>();
+}
+
+Heap::UrlSearchParamsObject *ExecutionEngine::newUrlSearchParamsObject()
+{
+ return memoryManager->allocate<UrlSearchParamsObject>();
+}
+
Heap::Object *ExecutionEngine::newErrorObject(const Value &value)
{
return ErrorObject::create<ErrorObject>(this, value, errorCtor());
@@ -1165,13 +1217,13 @@ QObject *ExecutionEngine::qmlScopeObject() const
return ctx->qml()->scopeObject;
}
-QQmlContextData *ExecutionEngine::callingQmlContext() const
+QQmlRefPointer<QQmlContextData> ExecutionEngine::callingQmlContext() const
{
Heap::QmlContext *ctx = qmlContext();
if (!ctx)
return nullptr;
- return ctx->qml()->context->contextData();
+ return ctx->qml()->context;
}
StackTrace ExecutionEngine::stackTrace(int frameLimit) const
@@ -1428,11 +1480,9 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError()
typedef QSet<QV4::Heap::Object *> V4ObjectSet;
static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects);
-static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &value);
+static QObject *qtObjectFromJS(const QV4::Value &value);
static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr);
-static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &value,
- const QByteArray &targetType,
- void **result);
+static bool convertToNativeQObject(const QV4::Value &value, const QByteArray &targetType, void **result);
static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst);
static QV4::ReturnedValue sequentialIterableToJS(QV4::ExecutionEngine *v4, const QSequentialIterable &lst);
static QV4::ReturnedValue variantMapToJS(QV4::ExecutionEngine *v4, const QVariantMap &vmap);
@@ -1463,7 +1513,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
if (typeHint == qMetaTypeId<QJSValue>())
- return QVariant::fromValue(QJSValue(e, value.asReturnedValue()));
+ return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(value.asReturnedValue()));
if (value.as<QV4::Object>()) {
QV4::ScopedObject object(scope, value);
@@ -1574,16 +1624,13 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
QV4::ScopedObject o(scope, value);
Q_ASSERT(o);
- if (QV4::RegExpObject *re = o->as<QV4::RegExpObject>()) {
#if QT_CONFIG(regularexpression)
- if (typeHint != QMetaType::QRegExp)
- return re->toQRegularExpression();
+ if (QV4::RegExpObject *re = o->as<QV4::RegExpObject>())
+ return re->toQRegularExpression();
#endif
- return re->toQRegExp();
- }
if (createJSValueForObjects)
- return QVariant::fromValue(QJSValue(scope.engine, o->asReturnedValue()));
+ return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue()));
return objectToVariant(e, o, visitedObjects);
}
@@ -1689,8 +1736,6 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return QV4::Encode(newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr), QTime(0, 0, 0), Qt::UTC)));
case QMetaType::QTime:
return QV4::Encode(newDateObjectFromTime(*reinterpret_cast<const QTime *>(ptr)));
- case QMetaType::QRegExp:
- return QV4::Encode(newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
#if QT_CONFIG(regularexpression)
case QMetaType::QRegularExpression:
return QV4::Encode(newRegExpObject(*reinterpret_cast<const QRegularExpression *>(ptr)));
@@ -1743,8 +1788,8 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return QV4::Encode::null();
}
} else if (type == qMetaTypeId<QJSValue>()) {
- const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
- return QJSValuePrivate::convertedToValue(this, *value);
+ return QJSValuePrivate::convertToReturnedValue(
+ this, *reinterpret_cast<const QJSValue *>(ptr));
} else if (type == qMetaTypeId<QList<QObject *> >()) {
// XXX Can this be made more by using Array as a prototype and implementing
// directly against QList<QObject*>?
@@ -1882,9 +1927,9 @@ ReturnedValue ExecutionEngine::global()
QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule(const QUrl &url)
{
QQmlMetaType::CachedUnitLookupError cacheError = QQmlMetaType::CachedUnitLookupError::NoError;
- if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url, &cacheError)) {
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url, &cacheError)) {
return ExecutableCompilationUnit::create(
- QV4::CompiledData::CompilationUnit(cachedUnit, url.fileName(), url.toString()));
+ QV4::CompiledData::CompilationUnit(cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, url.fileName(), url.toString()));
}
QFile f(QQmlFile::urlToLocalFileOrQrc(url));
@@ -2093,94 +2138,93 @@ void ExecutionEngine::setExtensionData(int index, Deletable *data)
// Converts a JS value to a meta-type.
// data must point to a place that can store a value of the given type.
// Returns true if conversion succeeded, false otherwise.
-bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
+bool ExecutionEngine::metaTypeFromJS(const Value &value, int type, void *data)
{
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::Bool:
- *reinterpret_cast<bool*>(data) = value->toBoolean();
+ *reinterpret_cast<bool*>(data) = value.toBoolean();
return true;
case QMetaType::Int:
- *reinterpret_cast<int*>(data) = value->toInt32();
+ *reinterpret_cast<int*>(data) = value.toInt32();
return true;
case QMetaType::UInt:
- *reinterpret_cast<uint*>(data) = value->toUInt32();
+ *reinterpret_cast<uint*>(data) = value.toUInt32();
return true;
case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(data) = qlonglong(value->toInteger());
+ *reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
return true;
case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(data) = qulonglong(value->toInteger());
+ *reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
return true;
case QMetaType::Double:
- *reinterpret_cast<double*>(data) = value->toNumber();
+ *reinterpret_cast<double*>(data) = value.toNumber();
return true;
case QMetaType::QString:
- if (value->isUndefined() || value->isNull())
+ if (value.isUndefined() || value.isNull())
*reinterpret_cast<QString*>(data) = QString();
else
- *reinterpret_cast<QString*>(data) = value->toQString();
+ *reinterpret_cast<QString*>(data) = value.toQString();
return true;
case QMetaType::QByteArray:
- if (const ArrayBuffer *ab = value->as<ArrayBuffer>())
+ if (const ArrayBuffer *ab = value.as<ArrayBuffer>())
*reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
else
*reinterpret_cast<QByteArray*>(data) = QByteArray();
return true;
case QMetaType::Float:
- *reinterpret_cast<float*>(data) = value->toNumber();
+ *reinterpret_cast<float*>(data) = value.toNumber();
return true;
case QMetaType::Short:
- *reinterpret_cast<short*>(data) = short(value->toInt32());
+ *reinterpret_cast<short*>(data) = short(value.toInt32());
return true;
case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(data) = value->toUInt16();
+ *reinterpret_cast<unsigned short*>(data) = value.toUInt16();
return true;
case QMetaType::Char:
- *reinterpret_cast<char*>(data) = char(value->toInt32());
+ *reinterpret_cast<char*>(data) = char(value.toInt32());
return true;
case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->toInt32());
+ *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value.toInt32());
return true;
case QMetaType::QChar:
- if (String *s = value->stringValue()) {
+ if (String *s = value.stringValue()) {
QString str = s->toQString();
*reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
} else {
- *reinterpret_cast<QChar*>(data) = QChar(ushort(value->toUInt16()));
+ *reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
}
return true;
case QMetaType::QDateTime:
- if (const QV4::DateObject *d = value->as<DateObject>()) {
+ if (const QV4::DateObject *d = value.as<DateObject>()) {
*reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
return true;
} break;
case QMetaType::QDate:
- if (const QV4::DateObject *d = value->as<DateObject>()) {
+ if (const QV4::DateObject *d = value.as<DateObject>()) {
*reinterpret_cast<QDate *>(data) = d->toQDateTime().date();
return true;
} break;
- case QMetaType::QRegExp:
- if (const QV4::RegExpObject *r = value->as<QV4::RegExpObject>()) {
- *reinterpret_cast<QRegExp *>(data) = r->toQRegExp();
- return true;
- } break;
#if QT_CONFIG(regularexpression)
case QMetaType::QRegularExpression:
- if (const QV4::RegExpObject *r = value->as<QV4::RegExpObject>()) {
+ if (const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
*reinterpret_cast<QRegularExpression *>(data) = r->toQRegularExpression();
return true;
} break;
#endif
case QMetaType::QObjectStar: {
- const QV4::QObjectWrapper *qobjectWrapper = value->as<QV4::QObjectWrapper>();
- if (qobjectWrapper || value->isNull()) {
- *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(this, *value);
+ if (value.isNull()) {
+ *reinterpret_cast<QObject* *>(data) = nullptr;
return true;
- } break;
+ }
+ if (value.as<QV4::QObjectWrapper>()) {
+ *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
+ return true;
+ }
+ break;
}
case QMetaType::QStringList: {
- const QV4::ArrayObject *a = value->as<QV4::ArrayObject>();
+ const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
if (a) {
*reinterpret_cast<QStringList *>(data) = a->toQStringList();
return true;
@@ -2188,33 +2232,45 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
break;
}
case QMetaType::QVariantList: {
- const QV4::ArrayObject *a = value->as<QV4::ArrayObject>();
+ const QV4::ArrayObject *a = value.as<QV4::ArrayObject>();
if (a) {
- *reinterpret_cast<QVariantList *>(data) = toVariant(*a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList();
+ *reinterpret_cast<QVariantList *>(data) = a->engine()->toVariant(
+ *a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList();
return true;
}
break;
}
case QMetaType::QVariantMap: {
- const QV4::Object *o = value->as<QV4::Object>();
+ const QV4::Object *o = value.as<QV4::Object>();
if (o) {
- *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(o);
+ *reinterpret_cast<QVariantMap *>(data) = o->engine()->variantMapFromJS(o);
return true;
}
break;
}
case QMetaType::QVariant:
- *reinterpret_cast<QVariant*>(data) = toVariant(*value, /*typeHint*/-1, /*createJSValueForObjects*/false);
+ if (const QV4::Managed *m = value.as<QV4::Managed>())
+ *reinterpret_cast<QVariant*>(data) = m->engine()->toVariant(value, /*typeHint*/-1, /*createJSValueForObjects*/false);
+ else if (value.isNull())
+ *reinterpret_cast<QVariant*>(data) = QVariant::fromValue(nullptr);
+ else if (value.isUndefined())
+ *reinterpret_cast<QVariant*>(data) = QVariant();
+ else if (value.isBoolean())
+ *reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue());
+ else if (value.isInteger())
+ *reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue());
+ else if (value.isDouble())
+ *reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue());
return true;
case QMetaType::QJsonValue:
- *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(*value);
+ *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
return true;
case QMetaType::QJsonObject: {
- *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value->as<Object>());
+ *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.as<Object>());
return true;
}
case QMetaType::QJsonArray: {
- const QV4::ArrayObject *a = value->as<ArrayObject>();
+ const QV4::ArrayObject *a = value.as<ArrayObject>();
if (a) {
*reinterpret_cast<QJsonArray *>(data) = JsonObject::toJsonArray(a);
return true;
@@ -2226,7 +2282,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
}
{
- const QQmlValueTypeWrapper *vtw = value->as<QQmlValueTypeWrapper>();
+ const QQmlValueTypeWrapper *vtw = value.as<QQmlValueTypeWrapper>();
if (vtw && vtw->typeId() == type) {
return vtw->toGadget(data);
}
@@ -2254,18 +2310,18 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
// Try to use magic; for compatibility with qjsvalue_cast.
QByteArray name = QMetaType::typeName(type);
- if (convertToNativeQObject(this, *value, name, reinterpret_cast<void* *>(data)))
+ if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(data)))
return true;
- if (value->as<QV4::VariantObject>() && name.endsWith('*')) {
+ if (value.as<QV4::VariantObject>() && name.endsWith('*')) {
int valueType = QMetaType::type(name.left(name.size()-1));
- QVariant &var = value->as<QV4::VariantObject>()->d()->data();
+ QVariant &var = value.as<QV4::VariantObject>()->d()->data();
if (valueType == var.userType()) {
// We have T t, T* is requested, so return &t.
*reinterpret_cast<void* *>(data) = var.data();
return true;
- } else if (Object *o = value->objectValue()) {
+ } else if (Object *o = value.objectValue()) {
// Look in the prototype chain.
- QV4::Scope scope(this);
+ QV4::Scope scope(o->engine());
QV4::ScopedObject proto(scope, o->getPrototypeOf());
while (proto) {
bool canCast = false;
@@ -2276,7 +2332,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
else if (proto->as<QV4::QObjectWrapper>()) {
QByteArray className = name.left(name.size()-1);
QV4::ScopedObject p(scope, proto.getPointer());
- if (QObject *qobject = qtObjectFromJS(this, p))
+ if (QObject *qobject = qtObjectFromJS(p))
canCast = qobject->qt_metacast(className) != nullptr;
}
if (canCast) {
@@ -2290,22 +2346,22 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
proto = proto->getPrototypeOf();
}
}
- } else if (value->isNull() && name.endsWith('*')) {
+ } else if (value.isNull() && name.endsWith('*')) {
*reinterpret_cast<void* *>(data) = nullptr;
return true;
} else if (type == qMetaTypeId<QJSValue>()) {
- *reinterpret_cast<QJSValue*>(data) = QJSValue(this, value->asReturnedValue());
+ QJSValuePrivate::setValue(reinterpret_cast<QJSValue*>(data), value.asReturnedValue());
return true;
}
return false;
}
-static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &value, const QByteArray &targetType, void **result)
+static bool convertToNativeQObject(const QV4::Value &value, const QByteArray &targetType, void **result)
{
if (!targetType.endsWith('*'))
return false;
- if (QObject *qobject = qtObjectFromJS(e, value)) {
+ if (QObject *qobject = qtObjectFromJS(value)) {
int start = targetType.startsWith("const ") ? 6 : 0;
QByteArray className = targetType.mid(start, targetType.size()-start-1);
if (void *instance = qobject->qt_metacast(className)) {
@@ -2316,12 +2372,12 @@ static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &va
return false;
}
-static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &value)
+static QObject *qtObjectFromJS(const QV4::Value &value)
{
if (!value.isObject())
return nullptr;
- QV4::Scope scope(engine);
+ QV4::Scope scope(value.as<QV4::Managed>()->engine());
QV4::Scoped<QV4::VariantObject> v(scope, value);
if (v) {
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index efe44a324c..c555730838 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -240,6 +240,8 @@ public:
MapIteratorProto,
ArrayIteratorProto,
StringIteratorProto,
+ UrlProto,
+ UrlSearchParamsProto,
Object_Ctor,
String_Ctor,
@@ -267,6 +269,8 @@ public:
WeakMap_Ctor,
Map_Ctor,
IntrinsicTypedArray_Ctor,
+ Url_Ctor,
+ UrlSearchParams_Ctor,
GetSymbolSpecies,
@@ -307,6 +311,14 @@ public:
FunctionObject *weakMapCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + WeakMap_Ctor); }
FunctionObject *mapCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Map_Ctor); }
FunctionObject *intrinsicTypedArrayCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + IntrinsicTypedArray_Ctor); }
+ FunctionObject *urlCtor() const
+ {
+ return reinterpret_cast<FunctionObject *>(jsObjects + Url_Ctor);
+ }
+ FunctionObject *urlSearchParamsCtor() const
+ {
+ return reinterpret_cast<FunctionObject *>(jsObjects + UrlSearchParams_Ctor);
+ }
FunctionObject *typedArrayCtors;
FunctionObject *getSymbolSpecies() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetSymbolSpecies); }
@@ -354,6 +366,8 @@ public:
Object *mapIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + MapIteratorProto); }
Object *arrayIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayIteratorProto); }
Object *stringIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + StringIteratorProto); }
+ Object *urlPrototype() const { return reinterpret_cast<Object *>(jsObjects + UrlProto); }
+ Object *urlSearchParamsPrototype() const { return reinterpret_cast<Object *>(jsObjects + UrlSearchParamsProto); }
EvalFunction *evalFunction() const { return reinterpret_cast<EvalFunction *>(jsObjects + Eval_Function); }
FunctionObject *getStackFunction() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetStack_Function); }
@@ -579,11 +593,13 @@ public:
Heap::RegExpObject *newRegExpObject(const QString &pattern, int flags);
Heap::RegExpObject *newRegExpObject(RegExp *re);
- Heap::RegExpObject *newRegExpObject(const QRegExp &re);
#if QT_CONFIG(regularexpression)
Heap::RegExpObject *newRegExpObject(const QRegularExpression &re);
#endif
+ Heap::UrlObject *newUrlObject();
+ Heap::UrlSearchParamsObject *newUrlSearchParamsObject();
+
Heap::Object *newErrorObject(const Value &value);
Heap::Object *newErrorObject(const QString &message);
Heap::Object *newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column);
@@ -609,7 +625,7 @@ public:
Heap::QmlContext *qmlContext() const;
QObject *qmlScopeObject() const;
- QQmlContextData *callingQmlContext() const;
+ QQmlRefPointer<QQmlContextData> callingQmlContext() const;
StackTrace stackTrace(int frameLimit = -1) const;
@@ -648,7 +664,7 @@ public:
QVariantMap variantMapFromJS(const QV4::Object *o);
- bool metaTypeFromJS(const Value *value, int type, void *data);
+ static bool metaTypeFromJS(const Value &value, int type, void *data);
QV4::ReturnedValue metaTypeToJS(int type, const void *data);
int maxJSStackSize() const;
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 29e1c6dbf7..4b0fe0f5f6 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -37,7 +37,10 @@
**
****************************************************************************/
+#include "qml/qqmlprivate.h"
+#include "qv4engine_p.h"
#include "qv4executablecompilationunit_p.h"
+#include "qv4stackframe_p.h"
#include <private/qv4engine_p.h>
#include <private/qv4regexp_p.h>
@@ -54,6 +57,7 @@
#include <private/qml_compile_hash_p.h>
#include <private/qqmltypewrapper_p.h>
#include <private/inlinecomponentutils_p.h>
+#include <private/qv4resolvedtypereference_p.h>
#include <QtQml/qqmlfile.h>
#include <QtQml/qqmlpropertymap.h>
@@ -207,9 +211,18 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine)
}
runtimeFunctions.resize(data->functionTableSize);
+ const QQmlPrivate::AOTCompiledFunction *aotFunction = aotCompiledFunctions;
for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
- runtimeFunctions[i] = QV4::Function::create(engine, this, compiledFunction);
+ runtimeFunctions[i] = QV4::Function::create(engine, this, compiledFunction, aotFunction);
+ if (aotFunction) {
+ if (aotFunction->functionPtr) {
+ if (aotFunction->index == i)
+ ++aotFunction;
+ } else {
+ aotFunction = nullptr;
+ }
+ }
}
Scope scope(engine);
@@ -410,8 +423,9 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
metaTypeId = compilationUnit->metaTypeId;
listMetaTypeId = compilationUnit->listMetaTypeId;
} else {
- metaTypeId = typeRef->type.typeId();
- listMetaTypeId = typeRef->type.qListTypeId();
+ const auto type = typeRef->type();
+ metaTypeId = type.typeId();
+ listMetaTypeId = type.qListTypeId();
}
}
@@ -449,7 +463,8 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ const auto type = typeRef->type();
+ if (type.isValid() && type.parserStatusCast() != -1)
++inlineComponentData[lastICRoot].totalParserStatusCount;
++inlineComponentData[lastICRoot].totalObjectCount;
@@ -457,9 +472,8 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
// if the type is an inline component type, we have to extract the information from it
// This requires that inline components are visited in the correct order
auto icRoot = compilationUnit->icRoot;
- if (typeRef->type.isInlineComponentType()) {
- icRoot = typeRef->type.inlineComponendId();
- }
+ if (type.isInlineComponentType())
+ icRoot = type.inlineComponentId();
QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
inlineComponentData[lastICRoot].totalBindingCount += compilationUnit->totalBindingsCount();
inlineComponentData[lastICRoot].totalParserStatusCount += compilationUnit->totalParserStatusCount();
@@ -478,14 +492,14 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
}
bindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ const auto type = typeRef->type();
+ if (type.isValid() && type.parserStatusCast() != -1)
++parserStatusCount;
++objectCount;
if (const auto compilationUnit = typeRef->compilationUnit()) {
auto icRoot = compilationUnit->icRoot;
- if (typeRef->type.isInlineComponentType()) {
- icRoot = typeRef->type.inlineComponendId();
- }
+ if (type.isInlineComponentType())
+ icRoot = type.inlineComponentId();
QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
bindingCount += compilationUnit->totalBindingsCount();
parserStatusCount += compilationUnit->totalParserStatusCount();
@@ -798,69 +812,6 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt
});
}
-/*!
-Returns the property cache, if one alread exists. The cache is not referenced.
-*/
-QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::propertyCache() const
-{
- if (type.isValid())
- return typePropertyCache;
- else
- return m_compilationUnit->rootPropertyCache();
-}
-
-/*!
-Returns the property cache, creating one if it doesn't already exist. The cache is not referenced.
-*/
-QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQmlEngine *engine)
-{
- if (typePropertyCache) {
- return typePropertyCache;
- } else if (type.isValid()) {
- typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), minorVersion);
- return typePropertyCache;
- } else {
- Q_ASSERT(m_compilationUnit);
- return m_compilationUnit->rootPropertyCache();
- }
-}
-
-bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine)
-{
- if (type.isValid() && !type.isInlineComponentType()) {
- bool ok = false;
- hash->addData(createPropertyCache(engine)->checksum(&ok));
- return ok;
- }
- if (!m_compilationUnit)
- return false;
- hash->addData(m_compilationUnit->data->md5Checksum,
- sizeof(m_compilationUnit->data->md5Checksum));
- return true;
-}
-
-template <typename T>
-bool qtTypeInherits(const QMetaObject *mo) {
- while (mo) {
- if (mo == &T::staticMetaObject)
- return true;
- mo = mo->superClass();
- }
- return false;
-}
-
-void ResolvedTypeReference::doDynamicTypeCheck()
-{
- const QMetaObject *mo = nullptr;
- if (typePropertyCache)
- mo = typePropertyCache->firstCppMetaObject();
- else if (type.isValid())
- mo = type.metaObject();
- else if (m_compilationUnit)
- mo = m_compilationUnit->rootPropertyCache()->firstCppMetaObject();
- isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo);
-}
-
bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *engine) const
{
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
@@ -874,24 +825,8 @@ bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *e
QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Binding *binding) const
{
using namespace CompiledData;
+#if QT_CONFIG(translation)
switch (binding->type) {
- case Binding::Type_Script:
- case Binding::Type_String:
- return stringAt(binding->stringIndex);
- case Binding::Type_Null:
- return QStringLiteral("null");
- case Binding::Type_Boolean:
- return binding->value.b ? QStringLiteral("true") : QStringLiteral("false");
- case Binding::Type_Number:
- return QString::number(bindingValueAsNumber(binding), 'g', QLocale::FloatingPointShortest);
- case Binding::Type_Invalid:
- return QString();
-#if !QT_CONFIG(translation)
- case Binding::Type_TranslationById:
- case Binding::Type_Translation:
- return stringAt(
- data->translations()[binding->value.translationDataIndex].stringIndex);
-#else
case Binding::Type_TranslationById: {
const TranslationData &translation
= data->translations()[binding->value.translationDataIndex];
@@ -912,19 +847,11 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind
return QCoreApplication::translate(contextUtf8.constData(), text.constData(),
comment.constData(), translation.number);
}
-#endif
default:
break;
}
- return QString();
-}
-
-QString ExecutableCompilationUnit::bindingValueAsScriptString(
- const CompiledData::Binding *binding) const
-{
- return (binding->type == CompiledData::Binding::Type_String)
- ? CompiledData::Binding::escapedString(stringAt(binding->stringIndex))
- : bindingValueAsString(binding);
+#endif
+ return CompilationUnit::bindingValueAsString(binding);
}
bool ExecutableCompilationUnit::verifyHeader(
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index 7bfb68da9d..1af5824074 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -52,7 +52,7 @@
//
#include <private/qv4compileddata_p.h>
-#include <private/qv4identifier_p.h>
+#include <private/qv4identifierhash_p.h>
#include <private/qqmlrefcount_p.h>
#include <private/qintrusivelist_p.h>
#include <private/qqmlpropertycachevector_p.h>
@@ -90,7 +90,7 @@ namespace QV4 {
typedef QVector<QQmlPropertyData*> BindingPropertyData;
class CompilationUnitMapper;
-struct ResolvedTypeReference;
+class ResolvedTypeReference;
// map from name index
// While this could be a hash, a map is chosen here to provide a stable
// order, which is used to calculating a check-sum on dependent meta-objects.
@@ -182,8 +182,8 @@ public:
CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
- int metaTypeId = -1;
- int listMetaTypeId = -1;
+ QMetaType metaTypeId;
+ QMetaType listMetaTypeId;
bool isRegisteredWithEngine = false;
QHash<int, InlineComponentData> inlineComponentData;
@@ -279,17 +279,9 @@ public:
bool saveToDisk(const QUrl &unitUrl, QString *errorString);
QString bindingValueAsString(const CompiledData::Binding *binding) const;
- QString bindingValueAsScriptString(const CompiledData::Binding *binding) const;
- double bindingValueAsNumber(const CompiledData::Binding *binding) const
- {
- if (binding->type != CompiledData::Binding::Type_Number)
- return 0.0;
- return constants[binding->value.constantValueIndex].doubleValue();
- }
static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp,
QString *errorString);
-
protected:
quint32 totalStringCount() const
{ return data->stringTableSize; }
@@ -323,77 +315,6 @@ private:
bool includeDefaultExport = true) const;
};
-struct ResolvedTypeReference
-{
-public:
- ResolvedTypeReference()
- : m_compilationUnit(nullptr)
- , m_stronglyReferencesCompilationUnit(true)
- , majorVersion(0)
- , minorVersion(0)
- , isFullyDynamicType(false)
- {}
-
- ~ResolvedTypeReference()
- {
- if (m_stronglyReferencesCompilationUnit && m_compilationUnit)
- m_compilationUnit->release();
- }
-
- QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() { return m_compilationUnit; }
- void setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit> unit)
- {
- if (m_compilationUnit == unit.data())
- return;
- if (m_stronglyReferencesCompilationUnit) {
- if (m_compilationUnit)
- m_compilationUnit->release();
- m_compilationUnit = unit.take();
- } else {
- m_compilationUnit = unit.data();
- }
- }
-
- bool referencesCompilationUnit() const { return m_stronglyReferencesCompilationUnit; }
- void setReferencesCompilationUnit(bool doReference)
- {
- if (doReference == m_stronglyReferencesCompilationUnit)
- return;
- m_stronglyReferencesCompilationUnit = doReference;
- if (!m_compilationUnit)
- return;
- if (doReference) {
- m_compilationUnit->addref();
- } else if (m_compilationUnit->count() == 1) {
- m_compilationUnit->release();
- m_compilationUnit = nullptr;
- } else {
- m_compilationUnit->release();
- }
- }
-
- QQmlRefPointer<QQmlPropertyCache> propertyCache() const;
- QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *);
- bool addToHash(QCryptographicHash *hash, QQmlEngine *engine);
-
- void doDynamicTypeCheck();
-
- QQmlType type;
- QQmlRefPointer<QQmlPropertyCache> typePropertyCache;
-private:
- Q_DISABLE_COPY_MOVE(ResolvedTypeReference)
-
- QV4::ExecutableCompilationUnit *m_compilationUnit;
- bool m_stronglyReferencesCompilationUnit;
-
-public:
- int majorVersion;
- int minorVersion;
- // Types such as QQmlPropertyMap can add properties dynamically at run-time and
- // therefore cannot have a property cache installed when instantiated.
- bool isFullyDynamicType;
-};
-
IdentifierHash ExecutableCompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
{
auto it = namedObjectsPerComponentCache.find(componentObjectIndex);
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index aeb4835c40..76eda5dcde 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include "qml/qqmlprivate.h"
#include "qv4function_p.h"
#include "qv4functionobject_p.h"
#include "qv4managed_p.h"
@@ -74,9 +75,10 @@ ReturnedValue Function::call(const Value *thisObject, const Value *argv, int arg
}
Function *Function::create(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
- const CompiledData::Function *function)
+ const CompiledData::Function *function,
+ const QQmlPrivate::AOTCompiledFunction *aotFunction)
{
- return new Function(engine, unit, function);
+ return new Function(engine, unit, function, aotFunction);
}
void Function::destroy()
@@ -85,12 +87,14 @@ void Function::destroy()
}
Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
- const CompiledData::Function *function)
+ const CompiledData::Function *function,
+ const QQmlPrivate::AOTCompiledFunction *aotFunction)
: FunctionData(unit)
, compiledFunction(function)
, codeData(function->code())
, jittedCode(nullptr)
, codeRef(nullptr)
+ , aotFunction(aotFunction)
{
Scope scope(engine);
Scoped<InternalClass> ic(scope, engine->internalClasses(EngineBase::Class_CallContext));
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 51960863c4..ce9151c225 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -50,6 +50,7 @@
// We mean it.
//
+#include <qqmlprivate.h>
#include "qv4global_p.h"
#include <private/qv4executablecompilationunit_p.h>
#include <private/qv4context_p.h>
@@ -82,7 +83,7 @@ Q_STATIC_ASSERT(std::is_standard_layout< FunctionData >::value);
struct Q_QML_EXPORT Function : public FunctionData {
private:
Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
- const CompiledData::Function *function);
+ const CompiledData::Function *function, const QQmlPrivate::AOTCompiledFunction *aotFunction);
~Function();
public:
@@ -106,6 +107,7 @@ public:
typedef ReturnedValue (*JittedCode)(CppStackFrame *, ExecutionEngine *);
JittedCode jittedCode;
JSC::MacroAssemblerCodeRef *codeRef;
+ const QQmlPrivate::AOTCompiledFunction *aotFunction = nullptr;
// first nArguments names in internalClass are the actual arguments
Heap::InternalClass *internalClass;
@@ -114,7 +116,8 @@ public:
bool isEval = false;
static Function *create(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
- const CompiledData::Function *function);
+ const CompiledData::Function *function,
+ const QQmlPrivate::AOTCompiledFunction *aotFunction);
void destroy();
// used when dynamically assigning signal handlers (QQmlConnection)
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index c6a737b467..ace070c683 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -141,6 +141,8 @@ namespace Heap {
struct ArgumentsObject;
struct QObjectWrapper;
struct RegExpObject;
+ struct UrlObject;
+ struct UrlSearchParamsObject;
struct RegExp;
struct EvalFunction;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index bb81fb52d4..1b47620572 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -372,12 +372,12 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc,
if (function->isStrict() || isStrict) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
ScopedValue thisObject(scope, directCall ? scope.engine->currentStackFrame->thisObject() : scope.engine->globalObject->asReturnedValue());
- return e->call(thisObject, nullptr, 0);
+ return checkedResult(v4, e->call(thisObject, nullptr, 0));
}
ScopedValue thisObject(scope, scope.engine->currentStackFrame->thisObject());
- return function->call(thisObject, nullptr, 0, ctx);
+ return checkedResult(v4, function->call(thisObject, nullptr, 0, ctx));
}
diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h
deleted file mode 100644
index 32de8b7c8d..0000000000
--- a/src/qml/jsruntime/qv4identifier_p.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml 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 QV4IDENTIFIER_H
-#define QV4IDENTIFIER_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 <qstring.h>
-#include <private/qv4global_p.h>
-#include <private/qv4propertykey_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-struct IdentifierHashEntry {
- PropertyKey identifier;
- int value;
-};
-
-struct IdentifierHashData
-{
- IdentifierHashData(IdentifierTable *table, int numBits);
- explicit IdentifierHashData(IdentifierHashData *other);
- ~IdentifierHashData();
- void markObjects(MarkStack *markStack) const;
-
- QBasicAtomicInt refCount;
- int alloc;
- int size;
- int numBits;
- IdentifierTable *identifierTable;
- IdentifierHashEntry *entries;
-};
-
-struct IdentifierHash
-{
-
- IdentifierHashData *d = nullptr;
-
- IdentifierHash() {}
- IdentifierHash(ExecutionEngine *engine);
- inline IdentifierHash(const IdentifierHash &other);
- inline ~IdentifierHash();
- inline IdentifierHash &operator=(const IdentifierHash &other);
-
- bool isEmpty() const { return !d; }
-
- inline int count() const;
-
- void detach();
-
- void add(const QString &str, int value);
- void add(Heap::String *str, int value);
-
- inline int value(const QString &str) const;
- inline int value(String *str) const;
- QString findId(int value) const;
-
-protected:
- IdentifierHashEntry *addEntry(PropertyKey i);
- const IdentifierHashEntry *lookup(PropertyKey identifier) const;
- const IdentifierHashEntry *lookup(const QString &str) const;
- const IdentifierHashEntry *lookup(String *str) const;
- const PropertyKey toIdentifier(const QString &str) const;
- const PropertyKey toIdentifier(Heap::String *str) const;
-};
-
-
-inline IdentifierHash::IdentifierHash(const IdentifierHash &other)
-{
- d = other.d;
- if (d)
- d->refCount.ref();
-}
-
-inline IdentifierHash::~IdentifierHash()
-{
- if (d && !d->refCount.deref())
- delete d;
-}
-
-IdentifierHash &IdentifierHash::operator=(const IdentifierHash &other)
-{
- if (other.d)
- other.d->refCount.ref();
- if (d && !d->refCount.deref())
- delete d;
- d = other.d;
- return *this;
-}
-
-inline int IdentifierHash::count() const
-{
- return d ? d->size : 0;
-}
-
-inline
-void IdentifierHash::add(const QString &str, int value)
-{
- IdentifierHashEntry *e = addEntry(toIdentifier(str));
- e->value = value;
-}
-
-inline
-void IdentifierHash::add(Heap::String *str, int value)
-{
- IdentifierHashEntry *e = addEntry(toIdentifier(str));
- e->value = value;
-}
-
-inline int IdentifierHash::value(const QString &str) const
-{
- const IdentifierHashEntry *e = lookup(str);
- return e ? e->value : -1;
-}
-
-inline int IdentifierHash::value(String *str) const
-{
- const IdentifierHashEntry *e = lookup(str);
- return e ? e->value : -1;
-}
-
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifierhash.cpp
index c3d7165f71..7d2d3143b2 100644
--- a/src/qml/jsruntime/qv4identifier.cpp
+++ b/src/qml/jsruntime/qv4identifierhash.cpp
@@ -36,45 +36,17 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "qv4identifier_p.h"
-#include "qv4identifiertable_p.h"
-#include "qv4string_p.h"
+
+#include <private/qv4identifierhash_p.h>
+#include <private/qv4identifiertable_p.h>
+#include <private/qv4string_p.h>
+#include <private/qv4identifierhashdata_p.h>
#include <private/qprimefornumbits_p.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
-IdentifierHashData::IdentifierHashData(IdentifierTable *table, int numBits)
- : size(0)
- , numBits(numBits)
- , identifierTable(table)
-{
- refCount.storeRelaxed(1);
- alloc = qPrimeForNumBits(numBits);
- entries = (IdentifierHashEntry *)malloc(alloc*sizeof(IdentifierHashEntry));
- memset(entries, 0, alloc*sizeof(IdentifierHashEntry));
- identifierTable->addIdentifierHash(this);
-}
-
-IdentifierHashData::IdentifierHashData(IdentifierHashData *other)
- : size(other->size)
- , numBits(other->numBits)
- , identifierTable(other->identifierTable)
-{
- refCount.storeRelaxed(1);
- alloc = other->alloc;
- entries = (IdentifierHashEntry *)malloc(alloc*sizeof(IdentifierHashEntry));
- memcpy(entries, other->entries, alloc*sizeof(IdentifierHashEntry));
- identifierTable->addIdentifierHash(this);
-}
-
-IdentifierHashData::~IdentifierHashData() {
- free(entries);
- if (identifierTable)
- identifierTable->removeIdentifierHash(this);
-}
-
IdentifierHash::IdentifierHash(ExecutionEngine *engine)
{
d = new IdentifierHashData(engine->identifierTable, 3);
@@ -90,7 +62,7 @@ void IdentifierHash::detach()
d = newData;
}
-
+inline
IdentifierHashEntry *IdentifierHash::addEntry(PropertyKey identifier)
{
Q_ASSERT(identifier.isStringOrSymbol());
@@ -130,6 +102,7 @@ IdentifierHashEntry *IdentifierHash::addEntry(PropertyKey identifier)
return d->entries + idx;
}
+inline
const IdentifierHashEntry *IdentifierHash::lookup(PropertyKey identifier) const
{
if (!d || !identifier.isStringOrSymbol())
@@ -147,6 +120,7 @@ const IdentifierHashEntry *IdentifierHash::lookup(PropertyKey identifier) const
}
}
+inline
const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const
{
if (!d)
@@ -156,6 +130,7 @@ const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const
return lookup(id);
}
+inline
const IdentifierHashEntry *IdentifierHash::lookup(String *str) const
{
if (!d)
@@ -166,12 +141,14 @@ const IdentifierHashEntry *IdentifierHash::lookup(String *str) const
return lookup(str->toQString());
}
+inline
const PropertyKey IdentifierHash::toIdentifier(const QString &str) const
{
Q_ASSERT(d);
return d->identifierTable->asPropertyKey(str);
}
+inline
const PropertyKey IdentifierHash::toIdentifier(Heap::String *str) const
{
Q_ASSERT(d);
@@ -190,15 +167,56 @@ QString QV4::IdentifierHash::findId(int value) const
return QString();
}
-void IdentifierHashData::markObjects(MarkStack *markStack) const
+QV4::IdentifierHash::IdentifierHash(const IdentifierHash &other)
{
- IdentifierHashEntry *e = entries;
- IdentifierHashEntry *end = e + alloc;
- while (e < end) {
- if (Heap::Base *o = e->identifier.asStringOrSymbol())
- o->mark(markStack);
- ++e;
- }
+ d = other.d;
+ if (d)
+ d->refCount.ref();
+}
+
+QV4::IdentifierHash::~IdentifierHash()
+{
+ if (d && !d->refCount.deref())
+ delete d;
+}
+
+IdentifierHash &QV4::IdentifierHash::operator=(const IdentifierHash &other)
+{
+ if (other.d)
+ other.d->refCount.ref();
+ if (d && !d->refCount.deref())
+ delete d;
+ d = other.d;
+ return *this;
+}
+
+int QV4::IdentifierHash::count() const
+{
+ return d ? d->size : 0;
+}
+
+void QV4::IdentifierHash::add(const QString &str, int value)
+{
+ IdentifierHashEntry *e = addEntry(toIdentifier(str));
+ e->value = value;
+}
+
+void QV4::IdentifierHash::add(Heap::String *str, int value)
+{
+ IdentifierHashEntry *e = addEntry(toIdentifier(str));
+ e->value = value;
+}
+
+int QV4::IdentifierHash::value(const QString &str) const
+{
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
+}
+
+int QV4::IdentifierHash::value(String *str) const
+{
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
}
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h b/src/qml/jsruntime/qv4identifierhash_p.h
index 26284740ee..06b813b843 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h
+++ b/src/qml/jsruntime/qv4identifierhash_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQuick module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -36,9 +36,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#ifndef QSGD3D12INTERNALIMAGENODE_P_H
-#define QSGD3D12INTERNALIMAGENODE_P_H
+#ifndef QV4IDENTIFIERHASH_P_H
+#define QV4IDENTIFIERHASH_P_H
//
// W A R N I N G
@@ -51,32 +50,50 @@
// We mean it.
//
-#include <private/qsgbasicinternalimagenode_p.h>
-#include "qsgd3d12builtinmaterials_p.h"
+#include <qstring.h>
+#include <private/qv4global_p.h>
+#include <private/qv4propertykey_p.h>
QT_BEGIN_NAMESPACE
-class QSGD3D12InternalImageNode : public QSGBasicInternalImageNode
+namespace QV4 {
+
+struct IdentifierHashEntry;
+struct IdentifierHashData;
+struct Q_QML_PRIVATE_EXPORT IdentifierHash
{
-public:
- QSGD3D12InternalImageNode();
+ IdentifierHash() = default;
+ IdentifierHash(ExecutionEngine *engine);
+ IdentifierHash(const IdentifierHash &other);
+ ~IdentifierHash();
+ IdentifierHash &operator=(const IdentifierHash &other);
+
+ bool isEmpty() const { return !d; }
+
+ int count() const;
- void setMipmapFiltering(QSGTexture::Filtering filtering) override;
- void setFiltering(QSGTexture::Filtering filtering) override;
- void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override;
- void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override;
+ void detach();
- void updateMaterialAntialiasing() override;
- void setMaterialTexture(QSGTexture *texture) override;
- QSGTexture *materialTexture() const override;
- bool updateMaterialBlending() override;
- bool supportsWrap(const QSize &size) const override;
+ void add(const QString &str, int value);
+ void add(Heap::String *str, int value);
+
+ int value(const QString &str) const;
+ int value(String *str) const;
+ QString findId(int value) const;
private:
- QSGD3D12TextureMaterial m_material;
- QSGD3D12SmoothTextureMaterial m_smoothMaterial;
+ inline IdentifierHashEntry *addEntry(PropertyKey i);
+ inline const IdentifierHashEntry *lookup(PropertyKey identifier) const;
+ inline const IdentifierHashEntry *lookup(const QString &str) const;
+ inline const IdentifierHashEntry *lookup(String *str) const;
+ inline const PropertyKey toIdentifier(const QString &str) const;
+ inline const PropertyKey toIdentifier(Heap::String *str) const;
+
+ IdentifierHashData *d = nullptr;
};
+} // namespace QV4
+
QT_END_NAMESPACE
-#endif // QSGD3D12INTERNALIMAGENODE_P_H
+#endif // QV4_IDENTIFIERHASH_P_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h b/src/qml/jsruntime/qv4identifierhashdata_p.h
index 7f4842b3a6..a4ea40c524 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h
+++ b/src/qml/jsruntime/qv4identifierhashdata_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQuick module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -36,9 +36,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#ifndef QSGD3D12PAINTERNODE_P_H
-#define QSGD3D12PAINTERNODE_P_H
+#ifndef QV4IDENTIFIERHASHDATA_H
+#define QV4IDENTIFIERHASHDATA_H
//
// W A R N I N G
@@ -51,70 +50,73 @@
// We mean it.
//
-#include <private/qsgadaptationlayer_p.h>
-#include "qsgd3d12texture_p.h"
-#include "qsgd3d12builtinmaterials_p.h"
+#include <private/qv4global_p.h>
+#include <private/qv4propertykey_p.h>
+#include <private/qv4identifiertable_p.h>
+#include <QtCore/qatomic.h>
QT_BEGIN_NAMESPACE
-class QSGD3D12Engine;
-
-class QSGD3D12PainterTexture : public QSGD3D12Texture
-{
-public:
- QSGD3D12PainterTexture(QSGD3D12Engine *engine);
-
- void bind() override;
- bool hasAlphaChannel() const override { return true; }
-
- QImage *image() { return &m_image; }
-
- QRect dirty;
+namespace QV4 {
-private:
- QSize lastSize;
+struct IdentifierHashEntry {
+ PropertyKey identifier;
+ int value;
};
-class QSGD3D12PainterNode : public QSGPainterNode
+struct IdentifierHashData
{
-public:
- QSGD3D12PainterNode(QQuickPaintedItem *item);
- ~QSGD3D12PainterNode();
-
- void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) override;
- void setSize(const QSize &size) override;
- void setDirty(const QRect &dirtyRect = QRect()) override;
- void setOpaquePainting(bool opaque) override;
- void setLinearFiltering(bool linearFiltering) override;
- void setMipmapping(bool mipmapping) override;
- void setSmoothPainting(bool s) override;
- void setFillColor(const QColor &c) override;
- void setContentsScale(qreal s) override;
- void setFastFBOResizing(bool dynamic) override;
- void setTextureSize(const QSize &size) override;
-
- QImage toImage() const override;
- void update() override;
- QSGTexture *texture() const override;
-
-private:
- QQuickPaintedItem *m_item;
- QSGD3D12Engine *m_engine;
- QSGD3D12PainterTexture *m_texture;
- QSize m_size;
- QSize m_textureSize;
- float m_contentsScale = 1;
- bool m_smoothPainting = false;
- QColor m_fillColor = Qt::transparent;
- QRect m_dirtyRect;
-
- QSGGeometry m_geometry;
- QSGD3D12TextureMaterial m_material;
-
- uint m_dirtyGeometry : 1;
- uint m_dirtyContents : 1;
+ IdentifierHashData(IdentifierTable *table, int numBits)
+ : size(0)
+ , numBits(numBits)
+ , identifierTable(table)
+ {
+ refCount.storeRelaxed(1);
+ alloc = qPrimeForNumBits(numBits);
+ entries = (IdentifierHashEntry *)malloc(alloc*sizeof(IdentifierHashEntry));
+ memset(entries, 0, alloc*sizeof(IdentifierHashEntry));
+ identifierTable->addIdentifierHash(this);
+ }
+
+ explicit IdentifierHashData(IdentifierHashData *other)
+ : size(other->size)
+ , numBits(other->numBits)
+ , identifierTable(other->identifierTable)
+ {
+ refCount.storeRelaxed(1);
+ alloc = other->alloc;
+ entries = (IdentifierHashEntry *)malloc(alloc*sizeof(IdentifierHashEntry));
+ memcpy(entries, other->entries, alloc*sizeof(IdentifierHashEntry));
+ identifierTable->addIdentifierHash(this);
+ }
+
+ ~IdentifierHashData() {
+ free(entries);
+ if (identifierTable)
+ identifierTable->removeIdentifierHash(this);
+ }
+
+ void markObjects(MarkStack *markStack) const
+ {
+ IdentifierHashEntry *e = entries;
+ IdentifierHashEntry *end = e + alloc;
+ while (e < end) {
+ if (Heap::Base *o = e->identifier.asStringOrSymbol())
+ o->mark(markStack);
+ ++e;
+ }
+ }
+
+ QBasicAtomicInt refCount;
+ int alloc;
+ int size;
+ int numBits;
+ IdentifierTable *identifierTable;
+ IdentifierHashEntry *entries;
};
+} // namespace QV4
+
QT_END_NAMESPACE
-#endif // QSGD3D12PAINTERNODE_P_H
+#endif // QV4IDENTIFIERHASHDATA_P_H
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 21b47c3909..c4ce837360 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qv4identifiertable_p.h"
#include "qv4symbol_p.h"
+#include <private/qv4identifierhashdata_p.h>
#include <private/qprimefornumbits_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index 78e2b6620e..6553ad6103 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -50,7 +50,7 @@
// We mean it.
//
-#include "qv4identifier_p.h"
+#include "qv4identifierhash_p.h"
#include "qv4string_p.h"
#include "qv4engine_p.h"
#include <qset.h>
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 92face6f94..17512cf4ff 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -208,9 +208,9 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, cons
if (!argc)
RETURN_UNDEFINED();
- QQmlContextData *context = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
- if ((!context || !context->isJSContext) && scope.engine->qmlEngine())
+ if ((!context || !context->isJSContext()) && scope.engine->qmlEngine())
RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Value::undefinedValue());
@@ -218,8 +218,8 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, cons
callbackFunction = argv[1];
QUrl url(scope.engine->resolvedUrl(argv[0].toQStringNoThrow()));
- if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
- url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
+ if (const QQmlEngine *qmlEngine = scope.engine->qmlEngine())
+ url = qmlEngine->interceptUrl(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 70ccfbf223..9d0a17a5cc 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -53,11 +53,11 @@
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
-
-#include <private/qqmlcontext_p.h>
+#include <QtCore/qpointer.h>
#include <private/qv4value_p.h>
#include <private/qv4context_p.h>
+#include <private/qv4persistent_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 70849775cb..4287563c94 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -40,7 +40,7 @@
#include <qv4internalclass_p.h>
#include <qv4string_p.h>
#include <qv4engine_p.h>
-#include <qv4identifier_p.h>
+#include <qv4identifierhash_p.h>
#include "qv4object_p.h"
#include "qv4identifiertable_p.h"
#include "qv4value_p.h"
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 7d9f204910..7b225fb1b6 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -77,7 +77,7 @@ struct ObjectItem {
inline bool operator ==(const ObjectItem &a, const ObjectItem &b)
{ return a.o->d() == b.o->d(); }
-inline int qHash(const ObjectItem &i, uint seed = 0)
+inline size_t qHash(const ObjectItem &i, uint seed = 0)
{ return ::qHash((void *)i.o->d(), seed); }
struct JsonObject : Object {
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index d51b03d90b..f090afe649 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -105,6 +105,12 @@ QString Managed::className() const
case Type_MathObject:
s = "Math";
break;
+ case Type_UrlObject:
+ s = "URL";
+ break;
+ case Type_UrlSearchParamsObject:
+ s = "URLSearchParams";
+ break;
case Type_ExecutionContext:
s = "__ExecutionContext";
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 4f22dc7330..96c47a9c41 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -144,6 +144,8 @@ public:
Type_JsonObject,
Type_MathObject,
Type_ProxyObject,
+ Type_UrlObject,
+ Type_UrlSearchParamsObject,
Type_ExecutionContext,
Type_InternalClass,
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 13f6912371..0044e0bc68 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -196,7 +196,7 @@ ReturnedValue NumberPrototype::method_isSafeInteger(const FunctionObject *, cons
return Encode(false);
double iv = v.toInteger();
- return Encode(dv == iv && std::fabs(iv) <= (2^53)-1);
+ return Encode(dv == iv && std::fabs(iv) <= (1LL << 53) - 1);
}
ReturnedValue NumberPrototype::method_isNaN(const FunctionObject *, const Value *, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index b723141caa..11e2efb64c 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -46,7 +46,7 @@
#include "qv4scopedvalue_p.h"
#include "qv4memberdata_p.h"
#include "qv4objectiterator_p.h"
-#include "qv4identifier_p.h"
+#include "qv4identifierhash_p.h"
#include "qv4string_p.h"
#include "qv4identifiertable_p.h"
#include "qv4jscall_p.h"
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index 65f6fa8b12..1711a4228c 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -39,7 +39,7 @@
#include "qv4objectiterator_p.h"
#include "qv4object_p.h"
#include "qv4stringobject_p.h"
-#include "qv4identifier_p.h"
+#include "qv4identifierhash_p.h"
#include "qv4argumentsobject_p.h"
#include "qv4string_p.h"
#include "qv4iterator_p.h"
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index f4901e3e4d..dea3019ef4 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -64,7 +64,7 @@ struct Page {
Value values[1]; // Really kEntriesPerPage, but keep the compiler happy
};
-Page *getPage(Value *val) {
+Page *getPage(const Value *val) {
return reinterpret_cast<Page *>(reinterpret_cast<quintptr>(val) & ~((quintptr)(WTF::pageSize() - 1)));
}
@@ -245,7 +245,7 @@ void PersistentValueStorage::mark(MarkStack *markStack)
}
}
-ExecutionEngine *PersistentValueStorage::getEngine(Value *v)
+ExecutionEngine *PersistentValueStorage::getEngine(const Value *v)
{
return getPage(v)->header.engine;
}
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index 55e8eefcb7..79e8e50790 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -83,7 +83,7 @@ struct Q_QML_EXPORT PersistentValueStorage
Iterator begin() { return Iterator(firstPage, 0); }
Iterator end() { return Iterator(nullptr, 0); }
- static ExecutionEngine *getEngine(Value *v);
+ static ExecutionEngine *getEngine(const Value *v);
ExecutionEngine *engine;
void *firstPage;
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index e2d3b98ff6..9863edead0 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -64,23 +64,25 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QQmlContextWrapper);
DEFINE_MANAGED_VTABLE(QmlContext);
-void Heap::QQmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject)
+void Heap::QQmlContextWrapper::init(QQmlRefPointer<QQmlContextData> context, QObject *scopeObject)
{
Object::init();
- this->context = new QQmlContextDataRef(context);
+ this->context = context.take();
this->scopeObject.init(scopeObject);
}
void Heap::QQmlContextWrapper::destroy()
{
- delete context;
+ context->release();
+ context = nullptr;
scopeObject.destroy();
Object::destroy();
}
-static OptionalReturnedValue searchContextProperties(QV4::ExecutionEngine *v4, QQmlContextData *context, String *name,
- bool *hasProperty, Value *base, QV4::Lookup *lookup,
- QV4::Lookup *originalLookup, QQmlEnginePrivate *ep)
+static OptionalReturnedValue searchContextProperties(
+ QV4::ExecutionEngine *v4, const QQmlRefPointer<QQmlContextData> &context, String *name,
+ bool *hasProperty, Value *base, QV4::Lookup *lookup, QV4::Lookup *originalLookup,
+ QQmlEnginePrivate *ep)
{
const QV4::IdentifierHash &properties = context->propertyNames();
if (properties.count() == 0)
@@ -91,7 +93,7 @@ static OptionalReturnedValue searchContextProperties(QV4::ExecutionEngine *v4, Q
if (propertyIdx == -1)
return OptionalReturnedValue();
- if (propertyIdx < context->idValueCount) {
+ if (propertyIdx < context->numIdValues()) {
if (hasProperty)
*hasProperty = true;
@@ -104,16 +106,16 @@ static OptionalReturnedValue searchContextProperties(QV4::ExecutionEngine *v4, Q
}
if (ep->propertyCapture)
- ep->propertyCapture->captureProperty(&context->idValues[propertyIdx].bindings);
- return OptionalReturnedValue(QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]));
+ ep->propertyCapture->captureProperty(context->idValueBindings(propertyIdx));
+ return OptionalReturnedValue(QV4::QObjectWrapper::wrap(v4, context->idValue(propertyIdx)));
}
QQmlContextPrivate *cp = context->asQQmlContextPrivate();
if (ep->propertyCapture)
- ep->propertyCapture->captureProperty(context->asQQmlContext(), -1, propertyIdx + cp->notifyIndex);
+ ep->propertyCapture->captureProperty(context->asQQmlContext(), -1, propertyIdx + cp->notifyIndex());
- const QVariant &value = cp->propertyValues.at(propertyIdx);
+ const QVariant &value = cp->propertyValue(propertyIdx);
if (hasProperty)
*hasProperty = true;
if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
@@ -122,7 +124,7 @@ static OptionalReturnedValue searchContextProperties(QV4::ExecutionEngine *v4, Q
QQmlContextPrivate::context_at);
return OptionalReturnedValue(QmlListWrapper::create(v4, prop, qMetaTypeId<QQmlListProperty<QObject> >()));
}
- return OptionalReturnedValue(v4->fromVariant(cp->propertyValues.at(propertyIdx)));
+ return OptionalReturnedValue(v4->fromVariant(cp->propertyValue(propertyIdx)));
}
ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *resource, PropertyKey id, const Value *receiver, bool *hasProperty, Value *base, Lookup *lookup)
@@ -133,7 +135,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
- if (v4->callingQmlContext() != *resource->d()->context) {
+ if (v4->callingQmlContext().data() != resource->d()->context) {
if (resource->d()->module) {
Scoped<Module> module(scope, resource->d()->module);
bool hasProp = false;
@@ -158,8 +160,8 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
// It's possible we could delay the calculation of the "actual" context (in the case
// of sub contexts) until it is definitely needed.
- QQmlContextData *context = resource->getContext();
- QQmlContextData *expressionContext = context;
+ QQmlRefPointer<QQmlContextData> context = resource->getContext();
+ QQmlRefPointer<QQmlContextData> expressionContext = context;
if (!context) {
if (hasProperty)
@@ -211,9 +213,9 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
return result->asReturnedValue();
}
- if (context->imports && name->startsWithUpper()) {
+ if (context->imports() && name->startsWithUpper()) {
// Search for attached properties, enums and imported scripts
- QQmlTypeNameCache::Result r = context->imports->query(name, QQmlImport::AllowRecursion);
+ QQmlTypeNameCache::Result r = context->imports()->query(name, QQmlImport::AllowRecursion);
if (r.isValid()) {
if (hasProperty)
@@ -224,7 +226,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupScript;
return lookup->qmlContextPropertyGetter(lookup, v4, base);
}
- QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
+ QV4::ScopedObject scripts(scope, context->importedScripts().valueRef());
if (scripts)
return scripts->get(r.scriptIndex);
return QV4::Encode::null();
@@ -241,7 +243,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
).heapObject());
} else {
QJSValue singleton = e->singletonInstance<QJSValue>(r.type);
- QV4::ScopedObject o(scope, QJSValuePrivate::convertedToValue(v4, singleton));
+ QV4::ScopedObject o(scope, QJSValuePrivate::asReturnedValue(&singleton));
lookup->qmlContextSingletonLookup.singleton = o->d();
}
lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupSingleton;
@@ -250,7 +252,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
}
result = QQmlTypeWrapper::create(v4, scopeObject, r.type);
} else if (r.importNamespace) {
- result = QQmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace);
+ result = QQmlTypeWrapper::create(v4, scopeObject, context->imports(), r.importNamespace);
}
if (lookup) {
lookup->qmlTypeLookup.qmlTypeWrapper = static_cast<Heap::Object*>(result->heapObject());
@@ -268,7 +270,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
decltype(lookup->qmlContextPropertyGetter) contextGetterFunction = QQmlContextWrapper::lookupContextObjectProperty;
// minor optimization so we don't potentially try two property lookups on the same object
- if (scopeObject == context->contextObject) {
+ if (scopeObject == context->contextObject()) {
scopeObject = nullptr;
contextGetterFunction = QQmlContextWrapper::lookupScopeObjectProperty;
}
@@ -310,22 +312,24 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
// Search context object
- if (context->contextObject) {
+ if (QObject *contextObject = context->contextObject()) {
bool hasProp = false;
QQmlPropertyData *propertyData = nullptr;
- result = QV4::QObjectWrapper::getQmlProperty(v4, context, context->contextObject,
- name, QV4::QObjectWrapper::CheckRevision, &hasProp, &propertyData);
+ result = QV4::QObjectWrapper::getQmlProperty(v4, context, contextObject,
+ name, QV4::QObjectWrapper::CheckRevision,
+ &hasProp, &propertyData);
if (hasProp) {
if (hasProperty)
*hasProperty = true;
if (base)
- *base = QV4::QObjectWrapper::wrap(v4, context->contextObject);
+ *base = QV4::QObjectWrapper::wrap(v4, contextObject);
if (propertyData) {
if (lookup) {
- QQmlData *ddata = QQmlData::get(context->contextObject, false);
+ QQmlData *ddata = QQmlData::get(contextObject, false);
if (ddata && ddata->propertyCache) {
- ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, context->contextObject)));
+ ScopedValue val(scope, base ? *base
+ : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, contextObject)));
const QObjectWrapper *That = static_cast<const QObjectWrapper *>(val->objectValue());
lookup->qobjectLookup.ic = That->internalClass();
lookup->qobjectLookup.propertyCache = ddata->propertyCache;
@@ -342,7 +346,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
}
}
- context = context->parent;
+ context = context->parent();
// As the hierarchy of contexts is not stable, we can't do accelerated lookups beyond
// the immediate QML context (of the .qml file).
@@ -370,7 +374,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
return result->asReturnedValue();
}
- expressionContext->unresolvedNames = true;
+ expressionContext->setUnresolvedNames(true);
return Encode::undefined();
}
@@ -402,8 +406,8 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val
// It's possible we could delay the calculation of the "actual" context (in the case
// of sub contexts) until it is definitely needed.
- QQmlContextData *context = wrapper->getContext();
- QQmlContextData *expressionContext = context;
+ QQmlRefPointer<QQmlContextData> context = wrapper->getContext();
+ QQmlRefPointer<QQmlContextData> expressionContext = context;
if (!context)
return false;
@@ -419,7 +423,7 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val
if (properties.count()) {
const int propertyIndex = properties.value(name);
if (propertyIndex != -1) {
- if (propertyIndex < context->idValueCount) {
+ if (propertyIndex < context->numIdValues()) {
v4->throwError(QLatin1String("left-hand side of assignment operator is not an lvalue"));
return false;
}
@@ -434,14 +438,15 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val
scopeObject = nullptr;
// Search context object
- if (context->contextObject &&
- QV4::QObjectWrapper::setQmlProperty(v4, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, value))
+ if (context->contextObject() &&
+ QV4::QObjectWrapper::setQmlProperty(v4, context, context->contextObject(), name,
+ QV4::QObjectWrapper::CheckRevision, value))
return true;
- context = context->parent;
+ context = context->parent();
}
- expressionContext->unresolvedNames = true;
+ expressionContext->setUnresolvedNames(true);
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
@@ -502,11 +507,11 @@ ReturnedValue QQmlContextWrapper::lookupScript(Lookup *l, ExecutionEngine *engin
if (!qmlContext)
return QV4::Encode::null();
- QQmlContextData *context = qmlContext->qmlContext();
+ QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
if (!context)
return QV4::Encode::null();
- QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
+ QV4::ScopedObject scripts(scope, context->importedScripts().valueRef());
if (!scripts)
return QV4::Encode::null();
return scripts->get(l->qmlContextScriptLookup.scriptIndex);
@@ -527,7 +532,7 @@ ReturnedValue QQmlContextWrapper::lookupIdObject(Lookup *l, ExecutionEngine *eng
if (!qmlContext)
return QV4::Encode::null();
- QQmlContextData *context = qmlContext->qmlContext();
+ QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
if (!context)
return QV4::Encode::null();
@@ -535,9 +540,9 @@ ReturnedValue QQmlContextWrapper::lookupIdObject(Lookup *l, ExecutionEngine *eng
const int objectId = l->qmlContextIdObjectLookup.objectId;
if (qmlEngine->propertyCapture)
- qmlEngine->propertyCapture->captureProperty(&context->idValues[objectId].bindings);
+ qmlEngine->propertyCapture->captureProperty(context->idValueBindings(objectId));
- return QV4::QObjectWrapper::wrap(engine, context->idValues[objectId]);
+ return QV4::QObjectWrapper::wrap(engine, context->idValue(objectId));
}
ReturnedValue QQmlContextWrapper::lookupScopeObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base)
@@ -576,11 +581,11 @@ ReturnedValue QQmlContextWrapper::lookupContextObjectProperty(Lookup *l, Executi
if (!qmlContext)
return QV4::Encode::undefined();
- QQmlContextData *context = qmlContext->qmlContext();
+ QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
if (!context)
return QV4::Encode::undefined();
- QObject *contextObject = context->contextObject;
+ QObject *contextObject = context->contextObject();
if (!contextObject)
return QV4::Encode::undefined();
@@ -621,11 +626,11 @@ ReturnedValue QQmlContextWrapper::lookupInParentContextHierarchy(Lookup *l, Exec
if (!qmlContext)
return QV4::Encode::undefined();
- QQmlContextData *context = qmlContext->qmlContext();
+ QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
if (!context)
return QV4::Encode::undefined();
- QQmlContextData *expressionContext = context;
+ QQmlRefPointer<QQmlContextData> expressionContext = context;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->qmlEngine());
@@ -635,18 +640,19 @@ ReturnedValue QQmlContextWrapper::lookupInParentContextHierarchy(Lookup *l, Exec
ScopedValue result(scope);
- for (context = context->parent; context; context = context->parent) {
+ for (context = context->parent(); context; context = context->parent()) {
if (auto property = searchContextProperties(engine, context, name, nullptr, base, nullptr, nullptr, ep))
return *property;
// Search context object
- if (context->contextObject) {
+ if (QObject *contextObject = context->contextObject()) {
bool hasProp = false;
- result = QV4::QObjectWrapper::getQmlProperty(engine, context, context->contextObject,
- name, QV4::QObjectWrapper::CheckRevision, &hasProp);
+ result = QV4::QObjectWrapper::getQmlProperty(
+ engine, context, contextObject, name,
+ QV4::QObjectWrapper::CheckRevision, &hasProp);
if (hasProp) {
if (base)
- *base = QV4::QObjectWrapper::wrap(engine, context->contextObject);
+ *base = QV4::QObjectWrapper::wrap(engine, contextObject);
return result->asReturnedValue();
}
@@ -658,7 +664,7 @@ ReturnedValue QQmlContextWrapper::lookupInParentContextHierarchy(Lookup *l, Exec
if (hasProp)
return result->asReturnedValue();
- expressionContext->unresolvedNames = true;
+ expressionContext->setUnresolvedNames(true);
return Encode::undefined();
}
@@ -692,11 +698,15 @@ void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContex
this->activation.set(internalClass->engine, qml->d());
}
-Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject)
+Heap::QmlContext *QmlContext::create(
+ ExecutionContext *parent, QQmlRefPointer<QQmlContextData> context,
+ QObject *scopeObject)
{
Scope scope(parent);
- Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocate<QQmlContextWrapper>(context, scopeObject));
+ Scoped<QQmlContextWrapper> qml(
+ scope, scope.engine->memoryManager->allocate<QQmlContextWrapper>(
+ std::move(context), scopeObject));
Heap::QmlContext *c = scope.engine->memoryManager->alloc<QmlContext>(parent, qml);
Q_ASSERT(c->vtable() == staticVTable());
return c;
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index e3e7239fe5..ba7c5da146 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -56,7 +56,7 @@
#include <private/qv4object_p.h>
#include <private/qv4context_p.h>
-#include <private/qqmlcontext_p.h>
+#include <private/qqmlcontextdata_p.h>
QT_BEGIN_NAMESPACE
@@ -72,10 +72,11 @@ namespace Heap {
DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
DECLARE_MARKOBJECTS(QQmlContextWrapper);
- void init(QQmlContextData *context, QObject *scopeObject);
+ void init(QQmlRefPointer<QQmlContextData> context, QObject *scopeObject);
void destroy();
- QQmlContextDataRef *context;
+ // This has to be a plain pointer because object needs to be a POD type.
+ QQmlContextData *context;
QQmlQPointer<QObject> scopeObject;
};
@@ -97,7 +98,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
V4_INTERNALCLASS(QmlContextWrapper)
inline QObject *getScopeObject() const { return d()->scopeObject; }
- inline QQmlContextData *getContext() const { return *d()->context; }
+ inline QQmlRefPointer<QQmlContextData> getContext() const { return d()->context; }
static ReturnedValue getPropertyAndBase(const QQmlContextWrapper *resource, PropertyKey id, const Value *receiver,
bool *hasProperty, Value *base, Lookup *lookup = nullptr);
@@ -120,13 +121,16 @@ struct Q_QML_EXPORT QmlContext : public ExecutionContext
V4_MANAGED(QmlContext, ExecutionContext)
V4_INTERNALCLASS(QmlContext)
- static Heap::QmlContext *create(QV4::ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject);
+ static Heap::QmlContext *create(
+ QV4::ExecutionContext *parent, QQmlRefPointer<QQmlContextData> context,
+ QObject *scopeObject);
QObject *qmlScope() const {
return d()->qml()->scopeObject;
}
- QQmlContextData *qmlContext() const {
- return *d()->qml()->context;
+
+ QQmlRefPointer<QQmlContextData> qmlContext() const {
+ return d()->qml()->context;
}
};
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 66b79aa0e8..4366a6932d 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -170,7 +170,7 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
} else if (property.propType() == qMetaTypeId<QJSValue>()) {
QJSValue v;
property.readProperty(object, &v);
- return QJSValuePrivate::convertedToValue(v4, v);
+ return QJSValuePrivate::convertToReturnedValue(v4, v);
} else if (property.isQVariant()) {
QVariant v;
property.readProperty(object, &v);
@@ -212,13 +212,17 @@ void QObjectWrapper::initializeBindings(ExecutionEngine *engine)
engine->functionPrototype()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect);
}
-QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const
+QQmlPropertyData *QObjectWrapper::findProperty(
+ ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext, String *name,
+ RevisionMode revisionMode, QQmlPropertyData *local) const
{
QObject *o = d()->object();
return findProperty(engine, o, qmlContext, name, revisionMode, local);
}
-QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local)
+QQmlPropertyData *QObjectWrapper::findProperty(
+ ExecutionEngine *engine, QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ String *name, RevisionMode revisionMode, QQmlPropertyData *local)
{
Q_UNUSED(revisionMode);
@@ -285,13 +289,14 @@ static OptionalReturnedValue getDestroyOrToStringMethod(ExecutionEngine *v4, Str
return OptionalReturnedValue(QV4::QObjectMethod::create(global, qobj, index));
}
-static OptionalReturnedValue getPropertyFromImports(ExecutionEngine *v4, String *name, QQmlContextData *qmlContext, QObject *qobj,
- bool *hasProperty = nullptr)
+static OptionalReturnedValue getPropertyFromImports(
+ ExecutionEngine *v4, String *name, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ QObject *qobj, bool *hasProperty = nullptr)
{
- if (!qmlContext || !qmlContext->imports)
+ if (!qmlContext || !qmlContext->imports())
return OptionalReturnedValue();
- QQmlTypeNameCache::Result r = qmlContext->imports->query(name);
+ QQmlTypeNameCache::Result r = qmlContext->imports()->query(name);
if (hasProperty)
*hasProperty = true;
@@ -304,15 +309,17 @@ static OptionalReturnedValue getPropertyFromImports(ExecutionEngine *v4, String
} else if (r.type.isValid()) {
return OptionalReturnedValue(QQmlTypeWrapper::create(v4, qobj,r.type, Heap::QQmlTypeWrapper::ExcludeEnums));
} else if (r.importNamespace) {
- return OptionalReturnedValue(QQmlTypeWrapper::create(v4, qobj, qmlContext->imports, r.importNamespace,
- Heap::QQmlTypeWrapper::ExcludeEnums));
+ return OptionalReturnedValue(QQmlTypeWrapper::create(
+ v4, qobj, qmlContext->imports(), r.importNamespace,
+ Heap::QQmlTypeWrapper::ExcludeEnums));
}
Q_UNREACHABLE();
return OptionalReturnedValue();
}
-ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode,
- bool *hasProperty, bool includeImports) const
+ReturnedValue QObjectWrapper::getQmlProperty(
+ const QQmlRefPointer<QQmlContextData> &qmlContext, String *name,
+ QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports) const
{
// Keep this code in sync with ::virtualResolveLookupGetter
@@ -355,7 +362,10 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
return getProperty(v4, d()->object(), result);
}
-ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, QQmlPropertyData **property)
+ReturnedValue QObjectWrapper::getQmlProperty(
+ QV4::ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty,
+ QQmlPropertyData **property)
{
if (QQmlData::wasDeleted(object)) {
if (hasProperty)
@@ -415,8 +425,9 @@ ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlC
}
-bool QObjectWrapper::setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name,
- QObjectWrapper::RevisionMode revisionMode, const Value &value)
+bool QObjectWrapper::setQmlProperty(
+ ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext, QObject *object,
+ String *name, QObjectWrapper::RevisionMode revisionMode, const Value &value)
{
if (QQmlData::wasDeleted(object))
return false;
@@ -462,7 +473,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
}
} else {
// binding assignment.
- QQmlContextData *callingQmlContext = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> callingQmlContext = scope.engine->callingQmlContext();
QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f);
@@ -519,7 +530,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
} else if (value.isUndefined() && property->propType() == QMetaType::QJsonValue) {
PROPERTY_STORE(QJsonValue, QJsonValue(QJsonValue::Undefined));
} else if (!newBinding && property->propType() == qMetaTypeId<QJSValue>()) {
- PROPERTY_STORE(QJSValue, QJSValue(scope.engine, value.asReturnedValue()));
+ PROPERTY_STORE(QJSValue, QJSValuePrivate::fromReturnedValue(value.asReturnedValue()));
} else if (value.isUndefined() && property->propType() != qMetaTypeId<QQmlScriptString>()) {
QString error = QLatin1String("Cannot assign [undefined] to ");
if (!QMetaType::typeName(property->propType()))
@@ -561,7 +572,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
else
v = scope.engine->toVariant(value, property->propType());
- QQmlContextData *callingQmlContext = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> callingQmlContext = scope.engine->callingQmlContext();
if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
const char *valueType = (v.userType() == QMetaType::UnknownType)
? "an unknown type"
@@ -702,7 +713,7 @@ QV4::ReturnedValue QObjectWrapper::virtualGet(const Managed *m, PropertyKey id,
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
Scope scope(that);
ScopedString n(scope, id.asStringOrSymbol());
- QQmlContextData *qmlContext = that->engine()->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> qmlContext = that->engine()->callingQmlContext();
return that->getQmlProperty(qmlContext, n, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
@@ -718,7 +729,7 @@ bool QObjectWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value,
if (scope.engine->hasException || QQmlData::wasDeleted(that->d()->object()))
return false;
- QQmlContextData *qmlContext = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> qmlContext = scope.engine->callingQmlContext();
if (!setQmlProperty(scope.engine, qmlContext, that->d()->object(), name, QV4::QObjectWrapper::IgnoreRevision, value)) {
QQmlData *ddata = QQmlData::get(that->d()->object());
// Types created by QML are not extensible at run-time, but for other QObjects we can store them
@@ -744,7 +755,7 @@ PropertyAttributes QObjectWrapper::virtualGetOwnProperty(const Managed *m, Prope
if (!QQmlData::wasDeleted(thatObject)) {
Scope scope(m);
ScopedString n(scope, id.asStringOrSymbol());
- QQmlContextData *qmlContext = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> qmlContext = scope.engine->callingQmlContext();
QQmlPropertyData local;
if (that->findProperty(scope.engine, qmlContext, n, IgnoreRevision, &local)
|| n->equals(scope.engine->id_destroy()) || n->equals(scope.engine->id_toString())) {
@@ -848,7 +859,7 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E
const QObjectWrapper *This = static_cast<const QObjectWrapper *>(object);
ScopedString name(scope, id.asStringOrSymbol());
- QQmlContextData *qmlContext = engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> qmlContext = engine->callingQmlContext();
QObject * const qobj = This->d()->object();
@@ -1168,7 +1179,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
if (ddata) {
if (!h->object()->parent() && !ddata->indestructible) {
if (ddata && ddata->ownContext) {
- Q_ASSERT(ddata->ownContext == ddata->context);
+ Q_ASSERT(ddata->ownContext.data() == ddata->context);
ddata->ownContext->emitDestruction();
ddata->ownContext = nullptr;
ddata->context = nullptr;
@@ -1287,11 +1298,16 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index
: QString());
}
- qWarning() << QLatin1String("Passing incompatible arguments to C++ functions from "
- "JavaScript is dangerous and deprecated.");
- qWarning() << QLatin1String("This will throw a JavaScript TypeError in future "
- "releases of Qt!");
+ const bool is_signal =
+ object.metaObject()->method(index).methodType() == QMetaMethod::Signal;
+ if (is_signal) {
+ qWarning() << "Passing incomatible arguments to signals is not supported.";
+ } else {
+ return engine->throwTypeError(
+ QLatin1String("Passing incompatible arguments to C++ functions from "
+ "JavaScript is not allowed."));
+ }
}
}
QVarLengthArray<void *, 9> argData(args.count());
@@ -1388,11 +1404,10 @@ static int MatchScore(const QV4::Value &actual, int conversionType)
}
} else if (actual.as<QV4::RegExpObject>()) {
switch (conversionType) {
- case QMetaType::QRegExp:
#if QT_CONFIG(regularexpression)
case QMetaType::QRegularExpression:
-#endif
return 0;
+#endif
default:
return 10;
}
@@ -1563,6 +1578,18 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
return engine->throwError(error);
}
+ if (args[0] < callArgs->argc()) {
+ Q_ASSERT(!engine->stackTrace().isEmpty());
+
+ const StackFrame frame = engine->stackTrace().first();
+ qWarning().noquote() << frame.function + QLatin1Char('@') + frame.source
+ + (frame.line > 0 ? (QLatin1Char(':') + QString::number(frame.line))
+ : QString());
+
+ qWarning().noquote() << QStringLiteral("Too many arguments, ignoring %1")
+ .arg(callArgs->argc() - args[0]);
+ }
+
return CallMethod(object, data.coreIndex(), returnType, args[0], args + 1, engine, callArgs, callType);
} else {
@@ -1775,7 +1802,8 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
bool queryEngine = false;
if (callType == qMetaTypeId<QJSValue>()) {
- qjsValuePtr = new (&allocData) QJSValue(scope.engine, value.asReturnedValue());
+ qjsValuePtr = new (&allocData) QJSValue;
+ QJSValuePrivate::setValue(qjsValuePtr, value.asReturnedValue());
type = qMetaTypeId<QJSValue>();
} else if (callType == QMetaType::Int) {
intValue = quint32(value.toInt32());
@@ -1932,7 +1960,9 @@ QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine)
QV4::Scope scope(engine);
if (type == qMetaTypeId<QJSValue>()) {
- return QJSValuePrivate::convertedToValue(scope.engine, *qjsValuePtr);
+ // The QJSValue can be passed around via dataPtr()
+ QJSValuePrivate::manageStringOnV4Heap(engine, qjsValuePtr);
+ return QJSValuePrivate::asReturnedValue(qjsValuePtr);
} else if (type == QMetaType::Int) {
return QV4::Encode(int(intValue));
} else if (type == QMetaType::UInt) {
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index ac9cad2bdb..6d12271eb8 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -165,10 +165,19 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
QObject *object() const { return d()->object(); }
- ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr, bool includeImports = false) const;
- static ReturnedValue getQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr, QQmlPropertyData **property = nullptr);
-
- static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
+ ReturnedValue getQmlProperty(
+ const QQmlRefPointer<QQmlContextData> &qmlContext, String *name,
+ RevisionMode revisionMode, bool *hasProperty = nullptr,
+ bool includeImports = false) const;
+ \
+ static ReturnedValue getQmlProperty(
+ ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr,
+ QQmlPropertyData **property = nullptr);
+
+ static bool setQmlProperty(
+ ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ QObject *object, String *name, RevisionMode revisionMode, const Value &value);
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
static void markWrapper(QObject *object, MarkStack *markStack);
@@ -193,8 +202,13 @@ protected:
static bool virtualIsEqualTo(Managed *that, Managed *o);
static ReturnedValue create(ExecutionEngine *engine, QObject *object);
- static QQmlPropertyData *findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local);
- QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
+ static QQmlPropertyData *findProperty(
+ ExecutionEngine *engine, QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ String *name, RevisionMode revisionMode, QQmlPropertyData *local);
+
+ QQmlPropertyData *findProperty(
+ ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext,
+ String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index 6afb10ea95..9e78ed4175 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -164,7 +164,7 @@ inline RegExpCacheKey::RegExpCacheKey(const RegExp::Data *re)
, flags(re->flags)
{}
-inline uint qHash(const RegExpCacheKey& key, uint seed = 0) Q_DECL_NOTHROW
+inline size_t qHash(const RegExpCacheKey& key, uint seed = 0) Q_DECL_NOTHROW
{ return qHash(key.pattern, seed); }
class RegExpCache : public QHash<RegExpCacheKey, WeakValue>
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index a8a37cda37..73122fbf75 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -49,7 +49,6 @@
#include "private/qlocale_tools_p.h"
#include <QtCore/QDebug>
-#include <QtCore/qregexp.h>
#if QT_CONFIG(regularexpression)
#include <QtCore/qregularexpression.h>
#endif
@@ -60,8 +59,6 @@
QT_BEGIN_NAMESPACE
-Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
-
using namespace QV4;
DEFINE_OBJECT_VTABLE(RegExpObject);
@@ -84,57 +81,40 @@ void Heap::RegExpObject::init(QV4::RegExp *value)
o->initProperties();
}
-// Converts a QRegExp to a JS RegExp.
-// The conversion is not 100% exact since ECMA regexp and QRegExp
-// have different semantics/flags, but we try to do our best.
-void Heap::RegExpObject::init(const QRegExp &re)
-{
- Object::init();
-
- // Convert the pattern to a ECMAScript pattern.
- QString pattern = QT_PREPEND_NAMESPACE(qt_regexp_toCanonical)(re.pattern(), re.patternSyntax());
- if (re.isMinimal()) {
- QString ecmaPattern;
- int len = pattern.length();
- ecmaPattern.reserve(len);
- int i = 0;
- const QChar *wc = pattern.unicode();
- bool inBracket = false;
- while (i < len) {
- QChar c = wc[i++];
- ecmaPattern += c;
- switch (c.unicode()) {
- case '?':
- case '+':
- case '*':
- case '}':
- if (!inBracket)
- ecmaPattern += QLatin1Char('?');
- break;
- case '\\':
- if (i < len)
- ecmaPattern += wc[i++];
- break;
- case '[':
- inBracket = true;
- break;
- case ']':
- inBracket = false;
- break;
- default:
- break;
- }
+static QString minimalPattern(const QString &pattern)
+{
+ QString ecmaPattern;
+ int len = pattern.length();
+ ecmaPattern.reserve(len);
+ int i = 0;
+ const QChar *wc = pattern.unicode();
+ bool inBracket = false;
+ while (i < len) {
+ QChar c = wc[i++];
+ ecmaPattern += c;
+ switch (c.unicode()) {
+ case '?':
+ case '+':
+ case '*':
+ case '}':
+ if (!inBracket)
+ ecmaPattern += QLatin1Char('?');
+ break;
+ case '\\':
+ if (i < len)
+ ecmaPattern += wc[i++];
+ break;
+ case '[':
+ inBracket = true;
+ break;
+ case ']':
+ inBracket = false;
+ break;
+ default:
+ break;
}
- pattern = ecmaPattern;
}
-
- Scope scope(internalClass->engine);
- Scoped<QV4::RegExpObject> o(scope, this);
-
- uint flags = (re.caseSensitivity() == Qt::CaseInsensitive ? CompiledData::RegExp::RegExp_IgnoreCase : CompiledData::RegExp::RegExp_NoFlags);
- o->d()->value.set(scope.engine, QV4::RegExp::create(scope.engine, pattern, flags));
-
- o->initProperties();
+ return ecmaPattern;
}
#if QT_CONFIG(regularexpression)
@@ -148,10 +128,16 @@ void Heap::RegExpObject::init(const QRegularExpression &re)
Scope scope(internalClass->engine);
Scoped<QV4::RegExpObject> o(scope, this);
- const uint flags = (re.patternOptions() & QRegularExpression::CaseInsensitiveOption)
- ? CompiledData::RegExp::RegExp_IgnoreCase
- : CompiledData::RegExp::RegExp_NoFlags;
- o->d()->value.set(scope.engine, QV4::RegExp::create(scope.engine, re.pattern(), flags));
+ QRegularExpression::PatternOptions options = re.patternOptions();
+ uint flags = (options & QRegularExpression::CaseInsensitiveOption)
+ ? CompiledData::RegExp::RegExp_IgnoreCase
+ : CompiledData::RegExp::RegExp_NoFlags;
+ if (options & QRegularExpression::MultilineOption)
+ flags |= CompiledData::RegExp::RegExp_Multiline;
+ QString pattern = re.pattern();
+ if (options & QRegularExpression::InvertedGreedinessOption)
+ pattern = minimalPattern(pattern);
+ o->d()->value.set(scope.engine, QV4::RegExp::create(scope.engine, pattern, flags));
o->initProperties();
}
#endif
@@ -163,26 +149,18 @@ void RegExpObject::initProperties()
Q_ASSERT(value());
}
-// Converts a JS RegExp to a QRegExp.
-// The conversion is not 100% exact since ECMA regexp and QRegExp
-// have different semantics/flags, but we try to do our best.
-QRegExp RegExpObject::toQRegExp() const
-{
- Qt::CaseSensitivity caseSensitivity = (value()->flags & CompiledData::RegExp::RegExp_IgnoreCase) ? Qt::CaseInsensitive : Qt::CaseSensitive;
- return QRegExp(*value()->pattern, caseSensitivity, QRegExp::RegExp2);
-}
-
#if QT_CONFIG(regularexpression)
// Converts a JS RegExp to a QRegularExpression.
// The conversion is not 100% exact since ECMA regexp and QRegularExpression
// have different semantics/flags, but we try to do our best.
QRegularExpression RegExpObject::toQRegularExpression() const
{
- QRegularExpression::PatternOptions caseSensitivity
- = (value()->flags & CompiledData::RegExp::RegExp_IgnoreCase)
- ? QRegularExpression::CaseInsensitiveOption
- : QRegularExpression::NoPatternOption;
- return QRegularExpression(*value()->pattern, caseSensitivity);
+ QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
+ if (value()->flags & CompiledData::RegExp::RegExp_IgnoreCase)
+ options |= QRegularExpression::CaseInsensitiveOption;
+ if (value()->flags & CompiledData::RegExp::RegExp_Multiline)
+ options |= QRegularExpression::MultilineOption;
+ return QRegularExpression(*value()->pattern, options);
}
#endif
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index b94889e9f0..8b26d06579 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -80,7 +80,6 @@ DECLARE_HEAP_OBJECT(RegExpObject, Object) {
void init();
void init(QV4::RegExp *value);
- void init(const QRegExp &re);
#if QT_CONFIG(regularexpression)
void init(const QRegularExpression &re);
#endif
@@ -140,7 +139,6 @@ struct Q_QML_PRIVATE_EXPORT RegExpObject: Object {
return setProperty(Index_LastIndex, Value::fromInt32(index));
}
- QRegExp toQRegExp() const;
#if QT_CONFIG(regularexpression)
QRegularExpression toQRegularExpression() const;
#endif
diff --git a/src/qml/jsruntime/qv4resolvedtypereference.cpp b/src/qml/jsruntime/qv4resolvedtypereference.cpp
new file mode 100644
index 0000000000..d81f512391
--- /dev/null
+++ b/src/qml/jsruntime/qv4resolvedtypereference.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications 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 "qv4resolvedtypereference_p.h"
+
+#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/qqmlpropertymap.h>
+#include <QtCore/qcryptographichash.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+template <typename T>
+bool qtTypeInherits(const QMetaObject *mo) {
+ while (mo) {
+ if (mo == &T::staticMetaObject)
+ return true;
+ mo = mo->superClass();
+ }
+ return false;
+}
+
+void ResolvedTypeReference::doDynamicTypeCheck()
+{
+ const QMetaObject *mo = nullptr;
+ if (m_typePropertyCache)
+ mo = m_typePropertyCache->firstCppMetaObject();
+ else if (m_type.isValid())
+ mo = m_type.metaObject();
+ else if (m_compilationUnit)
+ mo = m_compilationUnit->rootPropertyCache()->firstCppMetaObject();
+ m_isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo);
+}
+
+/*!
+Returns the property cache, if one alread exists. The cache is not referenced.
+*/
+QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::propertyCache() const
+{
+ if (m_type.isValid())
+ return m_typePropertyCache;
+ else
+ return m_compilationUnit->rootPropertyCache();
+}
+
+/*!
+Returns the property cache, creating one if it doesn't already exist. The cache is not referenced.
+*/
+QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQmlEngine *engine)
+{
+ if (m_typePropertyCache) {
+ return m_typePropertyCache;
+ } else if (m_type.isValid()) {
+ m_typePropertyCache = QQmlEnginePrivate::get(engine)->cache(m_type.metaObject(), m_version);
+ return m_typePropertyCache;
+ } else {
+ Q_ASSERT(m_compilationUnit);
+ return m_compilationUnit->rootPropertyCache();
+ }
+}
+
+bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine)
+{
+ if (m_type.isValid() && !m_type.isInlineComponentType()) {
+ bool ok = false;
+ hash->addData(createPropertyCache(engine)->checksum(&ok));
+ return ok;
+ }
+ if (!m_compilationUnit)
+ return false;
+ hash->addData(m_compilationUnit->data->md5Checksum,
+ sizeof(m_compilationUnit->data->md5Checksum));
+ return true;
+}
+
+} // namespace QV4
+
+QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4resolvedtypereference_p.h b/src/qml/jsruntime/qv4resolvedtypereference_p.h
new file mode 100644
index 0000000000..7e8bedad62
--- /dev/null
+++ b/src/qml/jsruntime/qv4resolvedtypereference_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications 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 QV4RESOLVEDTYPEREFERNCE_P_H
+#define QV4RESOLVEDTYPEREFERNCE_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 <QtQml/private/qtqmlglobal_p.h>
+#include <QtQml/private/qqmlrefcount_p.h>
+#include <QtQml/private/qqmlpropertycache_p.h>
+#include <QtQml/private/qqmltype_p.h>
+#include <QtQml/private/qv4executablecompilationunit_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCryptographicHash;
+namespace QV4 {
+
+class ResolvedTypeReference
+{
+ Q_DISABLE_COPY_MOVE(ResolvedTypeReference)
+public:
+ ResolvedTypeReference() = default;
+ ~ResolvedTypeReference()
+ {
+ if (m_stronglyReferencesCompilationUnit && m_compilationUnit)
+ m_compilationUnit->release();
+ }
+
+ QQmlRefPointer<QQmlPropertyCache> propertyCache() const;
+ QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *);
+ bool addToHash(QCryptographicHash *hash, QQmlEngine *engine);
+
+ void doDynamicTypeCheck();
+
+ QQmlType type() const { return m_type; }
+ void setType(QQmlType type) { m_type = std::move(type); }
+
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() { return m_compilationUnit; }
+ void setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit> unit)
+ {
+ if (m_compilationUnit == unit.data())
+ return;
+ if (m_stronglyReferencesCompilationUnit) {
+ if (m_compilationUnit)
+ m_compilationUnit->release();
+ m_compilationUnit = unit.take();
+ } else {
+ m_compilationUnit = unit.data();
+ }
+ }
+
+ bool referencesCompilationUnit() const { return m_stronglyReferencesCompilationUnit; }
+ void setReferencesCompilationUnit(bool doReference)
+ {
+ if (doReference == m_stronglyReferencesCompilationUnit)
+ return;
+ m_stronglyReferencesCompilationUnit = doReference;
+ if (!m_compilationUnit)
+ return;
+ if (doReference) {
+ m_compilationUnit->addref();
+ } else if (m_compilationUnit->count() == 1) {
+ m_compilationUnit->release();
+ m_compilationUnit = nullptr;
+ } else {
+ m_compilationUnit->release();
+ }
+ }
+
+ QQmlRefPointer<QQmlPropertyCache> typePropertyCache() const { return m_typePropertyCache; }
+ void setTypePropertyCache(QQmlRefPointer<QQmlPropertyCache> cache)
+ {
+ m_typePropertyCache = std::move(cache);
+ }
+
+ QTypeRevision version() const { return m_version; }
+ void setVersion(QTypeRevision version) { m_version = version; }
+
+ bool isFullyDynamicType() const { return m_isFullyDynamicType; }
+ void setFullyDynamicType(bool fullyDynamic) { m_isFullyDynamicType = fullyDynamic; }
+
+private:
+ QQmlType m_type;
+ QQmlRefPointer<QQmlPropertyCache> m_typePropertyCache;
+ QV4::ExecutableCompilationUnit *m_compilationUnit = nullptr;
+
+ QTypeRevision m_version = QTypeRevision::zero();
+ // Types such as QQmlPropertyMap can add properties dynamically at run-time and
+ // therefore cannot have a property cache installed when instantiated.
+ bool m_isFullyDynamicType = false;
+ bool m_stronglyReferencesCompilationUnit = true;
+};
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif // QV4RESOLVEDTYPEREFERNCE_P_H
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 2add1222ea..7fa3544e5a 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -227,10 +227,10 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo
error->clear();
QQmlMetaType::CachedUnitLookupError cacheError = QQmlMetaType::CachedUnitLookupError::NoError;
- if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl, &cacheError)) {
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl, &cacheError)) {
QQmlRefPointer<QV4::ExecutableCompilationUnit> jsUnit
= QV4::ExecutableCompilationUnit::create(
- QV4::CompiledData::CompilationUnit(cachedUnit));
+ QV4::CompiledData::CompilationUnit(cachedUnit->qmlData, cachedUnit->aotCompiledFunctions));
return new QV4::Script(engine, qmlContext, jsUnit);
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 5a1b27fda6..9e5bb7cc2f 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -80,7 +80,6 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
#if QT_CONFIG(qml_itemmodel)
#define FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F) \
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \
- F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \
F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \
F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange())
#else
@@ -88,9 +87,6 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
#endif
#define FOREACH_QML_SEQUENCE_TYPE(F) \
- F(int, IntVector, QVector<int>, 0) \
- F(qreal, RealVector, QVector<qreal>, 0.0) \
- F(bool, BoolVector, QVector<bool>, false) \
F(int, IntStdVector, std::vector<int>, 0) \
F(qreal, RealStdVector, std::vector<qreal>, 0.0) \
F(bool, BoolStdVector, std::vector<bool>, false) \
@@ -99,10 +95,8 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
F(bool, Bool, QList<bool>, false) \
F(QString, String, QList<QString>, QString()) \
F(QString, QString, QStringList, QString()) \
- F(QString, StringVector, QVector<QString>, QString()) \
F(QString, StringStdVector, std::vector<QString>, QString()) \
F(QUrl, Url, QList<QUrl>, QUrl()) \
- F(QUrl, UrlVector, QVector<QUrl>, QUrl()) \
F(QUrl, UrlStdVector, std::vector<QUrl>, QUrl()) \
FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F)
@@ -377,24 +371,8 @@ public:
++arrayIndex;
if (attrs)
*attrs = QV4::Attr_Data;
-
- // TODO: Replace the container->at() below with operator[] in Qt6!
- // TODO: But _not_ in Qt5!
- //
- // gcc 5.3.1 as shipped on RHEL 7.6 includes a copy of basic_string<char>
- // into QtQml, when it sees a std::vector::at(). The basic_string symbols
- // are publicly visible and preferred over the ones from libstdc++ when
- // building user code. Therefore, removing this at() breaks binary
- // compatibility. We _do_ want to remove it in Qt6, though.
- //
- // The exact mechanism is that at() checks its argument and can throw an
- // out_of_range exception. The construction of this exception then triggers
- // some string manipulation that uses the std::basic_string symbols. Clearly,
- // this is a compiler bug. And clearly, we don't want the check as we can't
- // catch the exception anyway.
-
if (pd)
- pd->value = convertElementToValue(s->engine(), s->d()->container->at(index));
+ pd->value = convertElementToValue(s->engine(), (*s->d()->container)[index]);
return PropertyKey::fromArrayIndex(index);
}
@@ -473,6 +451,8 @@ public:
argv[0] = convertElementToValue(m_v4, lhs);
argv[1] = convertElementToValue(m_v4, rhs);
QV4::ScopedValue result(scope, compare->call(m_v4->globalObject, argv, 2));
+ if (scope.engine->hasException)
+ return false;
return result->toNumber() < 0;
}
@@ -672,12 +652,6 @@ void Heap::QQmlSequence<Container>::init(QObject *object, int propertyIndex, boo
namespace QV4 {
-typedef QQmlSequence<QVector<int> > QQmlIntVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntVectorList);
-typedef QQmlSequence<QVector<qreal> > QQmlRealVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealVectorList);
-typedef QQmlSequence<QVector<bool> > QQmlBoolVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolVectorList);
typedef QQmlSequence<std::vector<int> > QQmlIntStdVectorList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntStdVectorList);
typedef QQmlSequence<std::vector<qreal> > QQmlRealStdVectorList;
@@ -688,23 +662,17 @@ typedef QQmlSequence<QStringList> QQmlQStringList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQStringList);
typedef QQmlSequence<QList<QString> > QQmlStringList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringList);
-typedef QQmlSequence<QVector<QString> > QQmlStringVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringVectorList);
typedef QQmlSequence<std::vector<QString> > QQmlStringStdVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList);
typedef QQmlSequence<QList<int> > QQmlIntList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList);
typedef QQmlSequence<QList<QUrl> > QQmlUrlList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlList);
-typedef QQmlSequence<QVector<QUrl> > QQmlUrlVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlVectorList);
typedef QQmlSequence<std::vector<QUrl> > QQmlUrlStdVectorList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlStdVectorList);
#if QT_CONFIG(qml_itemmodel)
typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList);
-typedef QQmlSequence<QVector<QModelIndex> > QQmlQModelIndexVectorList;
-DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexVectorList);
typedef QQmlSequence<std::vector<QModelIndex> > QQmlQModelIndexStdVectorList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexStdVectorList);
typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList;
diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp
index 8930c9a94d..7457e724e2 100644
--- a/src/qml/jsruntime/qv4sparsearray.cpp
+++ b/src/qml/jsruntime/qv4sparsearray.cpp
@@ -359,7 +359,7 @@ static inline void qMapDeallocate(SparseArrayNode *node, int alignment)
SparseArrayNode *SparseArray::createNode(uint sl, SparseArrayNode *parent, bool left)
{
- SparseArrayNode *node = static_cast<SparseArrayNode *>(qMapAllocate(sizeof(SparseArrayNode), Q_ALIGNOF(SparseArrayNode)));
+ SparseArrayNode *node = static_cast<SparseArrayNode *>(qMapAllocate(sizeof(SparseArrayNode), alignof(SparseArrayNode)));
Q_CHECK_PTR(node);
node->p = (quintptr)parent;
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index c1e50c8dcf..248fcdb02f 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -147,7 +147,7 @@ struct Q_QML_EXPORT SparseArray
SparseArray();
~SparseArray() {
if (root())
- freeTree(header.left, Q_ALIGNOF(SparseArrayNode));
+ freeTree(header.left, alignof(SparseArrayNode));
}
SparseArray(const SparseArray &other);
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 223f4a4769..fc004a2ce0 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -91,18 +91,14 @@ bool String::virtualIsEqualTo(Managed *t, Managed *o)
void Heap::String::init(const QString &t)
{
- Base::init();
-
+ QString mutableText(t);
+ StringOrSymbol::init(mutableText.data_ptr());
subtype = String::StringType_Unknown;
-
- text = const_cast<QString &>(t).data_ptr();
- text->ref.ref();
}
void Heap::ComplexString::init(String *l, String *r)
{
- Base::init();
-
+ StringOrSymbol::init();
subtype = String::StringType_AddedString;
left = l;
@@ -125,7 +121,7 @@ void Heap::ComplexString::init(String *l, String *r)
void Heap::ComplexString::init(Heap::String *ref, int from, int len)
{
Q_ASSERT(ref->length() >= from + len);
- Base::init();
+ StringOrSymbol::init();
subtype = String::StringType_SubString;
@@ -136,11 +132,11 @@ void Heap::ComplexString::init(Heap::String *ref, int from, int len)
void Heap::StringOrSymbol::destroy()
{
- if (text) {
- internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
- if (!text->ref.deref())
- QStringData::deallocate(text);
+ if (subtype < Heap::String::StringType_AddedString) {
+ internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(
+ qptrdiff(-text()->size) * qptrdiff(sizeof(QChar)));
}
+ text().~QStringPrivate();
Base::destroy();
}
@@ -164,27 +160,27 @@ uint String::toUInt(bool *ok) const
void String::createPropertyKeyImpl() const
{
- if (!d()->text)
+ if (d()->subtype >= Heap::String::StringType_AddedString)
d()->simplifyString();
- Q_ASSERT(d()->text);
+ Q_ASSERT(d()->subtype < Heap::String::StringType_AddedString);
engine()->identifierTable->asPropertyKey(this);
}
void Heap::String::simplifyString() const
{
- Q_ASSERT(!text);
+ Q_ASSERT(subtype >= StringType_AddedString);
int l = length();
QString result(l, Qt::Uninitialized);
QChar *ch = const_cast<QChar *>(result.constData());
append(this, ch);
- text = result.data_ptr();
- text->ref.ref();
+ text() = result.data_ptr();
const ComplexString *cs = static_cast<const ComplexString *>(this);
identifier = PropertyKey::invalid();
cs->left = cs->right = nullptr;
- internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
+ internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(
+ qptrdiff(text().size) * qptrdiff(sizeof(QChar)));
subtype = StringType_Unknown;
}
@@ -206,7 +202,7 @@ bool Heap::String::startsWithUpper() const
offset = cs->from;
}
Q_ASSERT(str->subtype < Heap::String::StringType_Complex);
- return str->text->size > offset && QChar::isUpper(str->text->data()[offset]);
+ return str->text().size > offset && QChar::isUpper(str->text().data()[offset]);
}
void Heap::String::append(const String *data, QChar *ch)
@@ -228,21 +224,21 @@ void Heap::String::append(const String *data, QChar *ch)
memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar));
ch += cs->len;
} else {
- memcpy(static_cast<void *>(ch), static_cast<const void *>(item->text->data()), item->text->size * sizeof(QChar));
- ch += item->text->size;
+ memcpy(static_cast<void *>(ch), item->text().data(), item->text().size * sizeof(QChar));
+ ch += item->text().size;
}
}
}
void Heap::StringOrSymbol::createHashValue() const
{
- if (!text) {
+ if (subtype >= StringType_AddedString) {
Q_ASSERT(internalClass->vtable->isString);
static_cast<const Heap::String *>(this)->simplifyString();
}
- Q_ASSERT(text);
- const QChar *ch = reinterpret_cast<const QChar *>(text->data());
- const QChar *end = ch + text->size;
+ Q_ASSERT(subtype < StringType_AddedString);
+ const QChar *ch = reinterpret_cast<const QChar *>(text().data());
+ const QChar *end = ch + text().size;
stringHash = QV4::String::calculateHashValue(ch, end, &subtype);
}
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 52fe09cd72..d5d11ef660 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -77,7 +77,18 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : Base
StringType_Complex = StringType_AddedString
};
- mutable QStringData *text;
+ void init() {
+ Base::init();
+ new (&textStorage) QStringPrivate;
+ }
+
+ void init(QStringPrivate text)
+ {
+ Base::init();
+ new (&textStorage) QStringPrivate(std::move(text));
+ }
+
+ mutable std::aligned_storage<sizeof(QStringPrivate), alignof(QStringPrivate)>::type textStorage;
mutable PropertyKey identifier;
mutable uint subtype;
mutable uint stringHash;
@@ -85,12 +96,11 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : Base
static void markObjects(Heap::Base *that, MarkStack *markStack);
void destroy();
+ QStringPrivate &text() const { return *reinterpret_cast<QStringPrivate *>(&textStorage); }
+
inline QString toQString() const {
- if (!text)
- return QString();
- QStringDataPtr ptr = { text };
- text->ref.ref();
- return QString(ptr);
+ QStringPrivate dd = text();
+ return QString(std::move(dd));
}
void createHashValue() const;
inline unsigned hashValue() const {
@@ -113,14 +123,12 @@ struct Q_QML_PRIVATE_EXPORT String : StringOrSymbol {
void simplifyString() const;
int length() const;
std::size_t retainedTextSize() const {
- return subtype >= StringType_Complex ? 0 : (std::size_t(text->size) * sizeof(QChar));
+ return subtype >= StringType_Complex ? 0 : (std::size_t(text().size) * sizeof(QChar));
}
inline QString toQString() const {
if (subtype >= StringType_Complex)
simplifyString();
- QStringDataPtr ptr = { text };
- text->ref.ref();
- return QString(ptr);
+ return StringOrSymbol::toQString();
}
inline bool isEqualTo(const String *other) const {
if (this == other)
@@ -158,7 +166,7 @@ Q_STATIC_ASSERT(std::is_trivial< ComplexString >::value);
inline
int String::length() const {
- return text ? text->size : static_cast<const ComplexString *>(this)->len;
+ return subtype < StringType_AddedString ? text().size : static_cast<const ComplexString *>(this)->len;
}
}
@@ -252,7 +260,7 @@ public:
}
if (subtype)
- *subtype = (charToUInt(ch) == '@') ? Heap::StringOrSymbol::StringType_Symbol : Heap::StringOrSymbol::StringType_Regular;
+ *subtype = (ch != end && charToUInt(ch) == '@') ? Heap::StringOrSymbol::StringType_Symbol : Heap::StringOrSymbol::StringType_Regular;
return h;
}
};
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 209a1b4e76..bf098fef26 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -571,7 +571,7 @@ ReturnedValue StringPrototype::method_match(const FunctionObject *b, const Value
ScopedFunctionObject fo(scope, f);
if (!fo)
return scope.engine->throwTypeError();
- return fo->call(r, thisObject, 1);
+ return checkedResult(scope.engine, fo->call(r, thisObject, 1));
}
}
@@ -862,6 +862,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
Value that = Value::undefinedValue();
replacement = searchCallback->call(&that, arguments, numCaptures + 2);
+ CHECK_EXCEPTION();
result += string.midRef(lastEnd, matchStart - lastEnd);
result += replacement->toQString();
lastEnd = matchEnd;
diff --git a/src/qml/jsruntime/qv4symbol.cpp b/src/qml/jsruntime/qv4symbol.cpp
index 004a9938e2..be6d821c14 100644
--- a/src/qml/jsruntime/qv4symbol.cpp
+++ b/src/qml/jsruntime/qv4symbol.cpp
@@ -50,10 +50,9 @@ DEFINE_OBJECT_VTABLE(SymbolObject);
void Heap::Symbol::init(const QString &s)
{
Q_ASSERT(s.at(0) == QLatin1Char('@'));
- identifier = PropertyKey::fromStringOrSymbol(this);
QString desc(s);
- text = desc.data_ptr();
- text->ref.ref();
+ StringOrSymbol::init(desc.data_ptr());
+ identifier = PropertyKey::fromStringOrSymbol(this);
}
void Heap::SymbolCtor::init(QV4::ExecutionContext *scope)
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index d03b67aa27..f425c6c87f 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -338,8 +338,8 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
array->d()->byteLength = destByteLength;
array->d()->byteOffset = 0;
- const char *src = buffer->d()->data->data() + typedArray->d()->byteOffset;
- char *dest = newBuffer->d()->data->data();
+ const char *src = buffer->d()->data()->data() + typedArray->d()->byteOffset;
+ char *dest = newBuffer->d()->data()->data();
// check if src and new type have the same size. In that case we can simply memcpy the data
if (srcElementSize == destElementSize) {
@@ -420,7 +420,7 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
array->d()->byteOffset = 0;
uint idx = 0;
- char *b = newBuffer->d()->data->data();
+ char *b = newBuffer->d()->data()->data();
ScopedValue val(scope);
while (idx < l) {
val = o->get(idx);
@@ -480,7 +480,7 @@ ReturnedValue TypedArray::virtualGet(const Managed *m, PropertyKey id, const Val
if (hasProperty)
*hasProperty = true;
- return a->d()->type->read(a->d()->buffer->data->data() + byteOffset);
+ return a->d()->type->read(a->d()->buffer->data()->data() + byteOffset);
}
bool TypedArray::virtualHasProperty(const Managed *m, PropertyKey id)
@@ -538,7 +538,7 @@ bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Valu
Value v = Value::fromReturnedValue(value.convertedToNumber());
if (scope.hasException() || a->d()->buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- a->d()->type->write(a->d()->buffer->data->data() + byteOffset, v);
+ a->d()->type->write(a->d()->buffer->data()->data() + byteOffset, v);
return true;
}
@@ -569,7 +569,7 @@ bool TypedArray::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Prop
uint bytesPerElement = a->d()->type->bytesPerElement;
uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
Q_ASSERT(byteOffset + bytesPerElement <= (uint)a->d()->buffer->byteLength());
- a->d()->type->write(a->d()->buffer->data->data() + byteOffset, v);
+ a->d()->type->write(a->d()->buffer->data()->data() + byteOffset, v);
}
return true;
}
@@ -713,7 +713,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_copyWithin(const FunctionObje
if (from != to) {
int elementSize = O->d()->type->bytesPerElement;
- char *data = O->d()->buffer->data->data() + O->d()->byteOffset;
+ char *data = O->d()->buffer->data()->data() + O->d()->byteOffset;
memmove(data + to*elementSize, data + from*elementSize, count*elementSize);
}
@@ -749,7 +749,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_every(const FunctionObject *b
ScopedValue r(scope);
Value *arguments = scope.alloc(3);
- const char *data = v->d()->buffer->data->data();
+ const char *data = v->d()->buffer->data()->data();
uint bytesPerElement = v->d()->type->bytesPerElement;
uint byteOffset = v->d()->byteOffset;
@@ -803,7 +803,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b,
if (scope.hasException() || v->d()->buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- char *data = v->d()->buffer->data->data();
+ char *data = v->d()->buffer->data()->data();
uint bytesPerElement = v->d()->type->bytesPerElement;
uint byteOffset = v->d()->byteOffset;
@@ -1422,7 +1422,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
uint idx = 0;
if (buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
+ char *b = buffer->d()->data()->data() + a->d()->byteOffset + offset*elementSize;
ScopedValue val(scope);
while (idx < l) {
val = o->get(idx);
@@ -1451,8 +1451,8 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
if (offset > aLength || l > aLength - offset)
RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
- char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
- const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset;
+ char *dest = buffer->d()->data()->data() + a->d()->byteOffset + offset*elementSize;
+ const char *src = srcBuffer->d()->data()->data() + srcTypedArray->d()->byteOffset;
if (srcTypedArray->d()->type == a->d()->type) {
// same type of typed arrays, use memmove (as srcbuffer and buffer could be the same)
memmove(dest, src, srcTypedArray->d()->byteLength);
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 65656e3389..e590083bc3 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -156,8 +156,8 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
return d()->byteLength/d()->type->bytesPerElement;
}
- QTypedArrayData<char> *arrayData() {
- return d()->buffer->data;
+ QArrayDataPointer<char> *arrayData() {
+ return &d()->buffer->data();
}
Heap::TypedArray::Type arrayType() const {
diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp
new file mode 100644
index 0000000000..73b1510d2e
--- /dev/null
+++ b/src/qml/jsruntime/qv4urlobject.cpp
@@ -0,0 +1,1449 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 "qv4arrayiterator_p.h"
+#include "qv4urlobject_p.h"
+#include "qv4stringobject_p.h"
+
+#include <QtCore/QUrl>
+
+#include <qv4jscall_p.h>
+#include <qv4objectiterator_p.h>
+
+using namespace QV4;
+
+DEFINE_OBJECT_VTABLE(UrlObject);
+DEFINE_OBJECT_VTABLE(UrlCtor);
+
+DEFINE_OBJECT_VTABLE(UrlSearchParamsObject);
+DEFINE_OBJECT_VTABLE(UrlSearchParamsCtor);
+
+
+void Heap::UrlCtor::init(QV4::ExecutionContext *scope)
+{
+ Heap::FunctionObject::init(scope, QLatin1String("URL"));
+}
+
+void UrlPrototype::init(ExecutionEngine *engine, Object *ctor)
+{
+ Q_UNUSED(ctor)
+
+ Scope scope(engine);
+ ScopedObject o(scope);
+
+ defineDefaultProperty(QLatin1String("toString"), method_getHref);
+ defineDefaultProperty(QLatin1String("toJSON"), method_getHref);
+
+ defineAccessorProperty(QLatin1String("hash"), method_getHash, method_setHash);
+ defineAccessorProperty(QLatin1String("host"), method_getHost, method_setHost);
+ defineAccessorProperty(QLatin1String("hostname"), method_getHostname, method_setHostname);
+ defineAccessorProperty(QLatin1String("href"), method_getHref, method_setHref);
+ defineAccessorProperty(QLatin1String("origin"), method_getOrigin, nullptr);
+ defineAccessorProperty(QLatin1String("password"), method_getPassword, method_setPassword);
+ defineAccessorProperty(QLatin1String("pathname"), method_getPathname, method_setPathname);
+ defineAccessorProperty(QLatin1String("port"), method_getPort, method_setPort);
+ defineAccessorProperty(QLatin1String("protocol"), method_getProtocol, method_setProtocol);
+ defineAccessorProperty(QLatin1String("search"), method_getSearch, method_setSearch);
+ defineAccessorProperty(QLatin1String("searchParams"), method_getSearchParams, nullptr);
+ defineAccessorProperty(QLatin1String("username"), method_getUsername, method_setUsername);
+}
+
+bool UrlObject::setHash(QString hash)
+{
+ if (hash.startsWith(QLatin1Char('#')))
+ hash = hash.mid(1);
+
+ QUrl url = toQUrl();
+ url.setFragment(hash);
+
+ if (!url.isValid())
+ return false;
+
+ d()->hash.set(engine(), engine()->newString(url.fragment()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ return true;
+}
+
+bool UrlObject::setHostname(QString host)
+{
+ QUrl url = toQUrl();
+ url.setHost(host);
+
+ if (!url.isValid())
+ return false;
+
+ d()->hostname.set(engine(), engine()->newString(url.host()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ updateOrigin();
+ updateHost();
+
+ return true;
+}
+
+bool UrlObject::setHost(QString hostname)
+{
+ int port = -1;
+
+ if (hostname.contains(QLatin1Char(':'))) {
+ const QStringList list = hostname.split(QLatin1Char(':'));
+ hostname = list[0];
+ port = list[1].toInt();
+ }
+
+ QUrl url = toQUrl();
+ url.setHost(hostname);
+ url.setPort(port);
+
+ if (!url.isValid())
+ return false;
+
+ if (url.port() != -1)
+ d()->port.set(engine(), engine()->newString(QString::number(url.port())));
+
+ d()->hostname.set(engine(), engine()->newString(url.host()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ updateOrigin();
+ updateHost();
+
+ return true;
+}
+
+bool UrlObject::setHref(QString href)
+{
+ QUrl url(href);
+
+ if (!url.isValid() || url.isRelative())
+ return false;
+
+ d()->hash.set(engine(), engine()->newString(url.fragment()));
+ d()->hostname.set(engine(), engine()->newString(url.host()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+ d()->password.set(engine(), engine()->newString(url.password()));
+ d()->pathname.set(engine(), engine()->newString(url.path()));
+ d()->port.set(engine(),
+ engine()->newString(url.port() == -1 ? QLatin1String("")
+ : QString::number(url.port())));
+ d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->search.set(engine(), engine()->newString(url.query()));
+ d()->username.set(engine(), engine()->newString(url.userName()));
+
+ updateOrigin();
+ updateHost();
+
+ return true;
+}
+
+bool UrlObject::setPassword(QString password)
+{
+ QUrl url = toQUrl();
+ url.setPassword(password);
+
+ if (!url.isValid())
+ return false;
+
+ d()->password.set(engine(), engine()->newString(url.password()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ return true;
+}
+
+bool UrlObject::setPathname(QString pathname)
+{
+ QUrl url = toQUrl();
+ url.setPath(pathname);
+
+ if (!url.isValid())
+ return false;
+
+ d()->pathname.set(engine(), engine()->newString(url.path()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ return true;
+}
+
+bool UrlObject::setPort(QString port)
+{
+ QUrl url = toQUrl();
+ url.setPort(port.isEmpty() ? -1 : port.toInt());
+
+ if (!url.isValid())
+ return false;
+
+ d()->port.set(engine(),
+ engine()->newString(url.port() == -1 ? QLatin1String("")
+ : QString::number(url.port())));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ updateOrigin();
+ updateHost();
+
+ return true;
+}
+
+bool UrlObject::setProtocol(QString protocol)
+{
+ QUrl url = toQUrl();
+ url.setScheme(protocol);
+
+ if (!url.isValid())
+ return false;
+
+ d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ updateOrigin();
+ updateHost();
+
+ return true;
+}
+
+bool UrlObject::setSearch(QString search)
+{
+ QUrl url = toQUrl();
+
+ if (search.startsWith(QLatin1Char('?')))
+ search = search.mid(1);
+
+ url.setQuery(search);
+
+ if (!url.isValid())
+ return false;
+
+ d()->search.set(engine(), engine()->newString(url.query()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ return true;
+}
+
+bool UrlObject::setUsername(QString username)
+{
+ QUrl url = toQUrl();
+ url.setUserName(username);
+
+ if (!url.isValid())
+ return false;
+
+ d()->username.set(engine(), engine()->newString(url.userName()));
+ d()->href.set(engine(), engine()->newString(url.toString()));
+
+ return true;
+}
+
+QUrl UrlObject::toQUrl() const
+{
+ return QUrl(href());
+}
+
+void UrlObject::updateOrigin()
+{
+ QUrl url = toQUrl();
+
+ QString proto = url.scheme();
+
+ // A blob's origin is the origin of the URL that it points to
+ if (proto == QLatin1String("blob")) {
+ url = QUrl(url.path());
+ proto = url.scheme();
+ }
+
+ QString origin;
+ if (proto == QLatin1String("http") || proto == QLatin1String("https")
+ || proto == QLatin1String("ftp")) {
+ origin = QLatin1String("%1://%2").arg(url.scheme(), url.host());
+
+ if (url.port() != -1)
+ origin.append(QLatin1String(":") + QString::number(url.port()));
+ }
+
+ d()->origin.set(engine(), engine()->newString(origin));
+}
+
+void UrlObject::updateHost()
+{
+ QUrl url = toQUrl();
+
+ QString host = url.host();
+
+ if (url.port() != -1)
+ host.append(QLatin1String(":") + QString::number(url.port()));
+
+ d()->host.set(engine(), engine()->newString(host));
+}
+
+ReturnedValue UrlPrototype::method_getHash(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->hash()));
+}
+
+ReturnedValue UrlPrototype::method_setHash(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setHash(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getHost(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->host()));
+}
+
+ReturnedValue UrlPrototype::method_setHost(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ QString host = stringValue->toQString();
+ if (!r->setHost(host))
+ return v4->throwTypeError(QLatin1String("Invalid host: %1").arg(host));
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getHostname(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->hostname()));
+}
+
+ReturnedValue UrlPrototype::method_setHostname(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ QString hostname = stringValue->toQString();
+ if (!r->setHostname(hostname))
+ return v4->throwTypeError(QLatin1String("Invalid hostname: %1").arg(hostname));
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getHref(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->href()));
+}
+
+ReturnedValue UrlPrototype::method_setHref(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ QString href = stringValue->toQString();
+ if (!r->setHref(href))
+ return v4->throwTypeError(QLatin1String("Invalid URL: %1").arg(href));
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getOrigin(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->origin()));
+}
+
+ReturnedValue UrlPrototype::method_getPassword(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->password()));
+}
+
+ReturnedValue UrlPrototype::method_setPassword(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setPassword(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getPathname(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->pathname()));
+}
+
+ReturnedValue UrlPrototype::method_setPathname(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setPathname(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getPort(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->port()));
+}
+
+ReturnedValue UrlPrototype::method_setPort(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ QString port;
+
+ if (stringValue != nullptr)
+ port = stringValue->toQString();
+ else if (arg->isInt32())
+ port = QString::number(arg->toInt32());
+ else
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ if (!r->setPort(port))
+ return v4->throwTypeError(QLatin1String("Invalid port: %1").arg(port));
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getProtocol(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->protocol()));
+}
+
+ReturnedValue UrlPrototype::method_setProtocol(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setProtocol(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getSearch(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->search()));
+}
+
+ReturnedValue UrlPrototype::method_setSearch(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setSearch(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getUsername(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ return Encode(v4->newString(r->username()));
+}
+
+ReturnedValue UrlPrototype::method_setUsername(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ String *stringValue = arg->stringValue();
+
+ if (stringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ r->setUsername(stringValue->toQString());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlPrototype::method_getSearchParams(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ Scoped<UrlSearchParamsObject> usp(scope, v4->newUrlSearchParamsObject());
+
+ usp->initializeParams(r->search());
+
+ return usp->asReturnedValue();
+}
+
+ReturnedValue UrlCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
+ int argc, const Value *newTarget)
+{
+ ExecutionEngine *v4 = that->engine();
+
+ if (argc < 1 || argc > 2)
+ return v4->throwError(QLatin1String("Invalid amount of arguments"));
+
+ Scope scope(v4);
+
+ ScopedValue arg1(scope, argv[0]);
+ String *arg1StringValue = arg1->stringValue();
+
+ if (arg1StringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ QString arg1String = arg1StringValue->toQString();
+ QString urlString;
+
+ if (argc == 2) {
+ ScopedValue arg2(scope, argv[1]);
+ String *arg2StringValue = arg2->stringValue();
+
+ if (arg2StringValue == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
+
+ QUrl url = QUrl(arg2StringValue->toQString());
+ QUrl relativeUrl = QUrl(arg1String);
+
+ QString baseUrlPath = url.path();
+ QString relativePath = relativeUrl.path();
+
+ // If the base URL contains a path the last section of it is discarded
+ int lastSlash = baseUrlPath.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ baseUrlPath.truncate(lastSlash);
+
+ if (!relativePath.startsWith(QLatin1Char('/')))
+ relativePath = relativePath.prepend(QLatin1Char('/'));
+
+ url.setPath(baseUrlPath + relativePath);
+ url.setFragment(relativeUrl.fragment());
+ url.setQuery(relativeUrl.query());
+
+ urlString = url.toString();
+ } else {
+ urlString = arg1String;
+ }
+
+ ReturnedValue o = Encode(v4->newUrlObject());
+
+ if (!newTarget)
+ return o;
+
+ ScopedObject obj(scope, o);
+ obj->setProtoFromNewTarget(newTarget);
+
+ UrlObject *urlObject = obj->as<UrlObject>();
+
+ if (!urlObject->setHref(urlString))
+ return v4->throwTypeError(QLatin1String("Invalid URL: %1").arg(urlString));
+
+ return obj->asReturnedValue();
+}
+
+
+void Heap::UrlSearchParamsCtor::init(QV4::ExecutionContext *scope)
+{
+ Heap::FunctionObject::init(scope, QLatin1String("URLSearchParams"));
+}
+
+void UrlSearchParamsPrototype::init(ExecutionEngine *engine, Object *ctor)
+{
+ Q_UNUSED(ctor)
+
+ Scope scope(engine);
+ ScopedObject o(scope);
+
+ defineDefaultProperty(QLatin1String("toString"), method_toString);
+ defineDefaultProperty(QLatin1String("sort"), method_sort);
+ defineDefaultProperty(QLatin1String("append"), method_append);
+ defineDefaultProperty(QLatin1String("delete"), method_delete);
+ defineDefaultProperty(QLatin1String("has"), method_has);
+ defineDefaultProperty(QLatin1String("set"), method_set);
+ defineDefaultProperty(QLatin1String("get"), method_get);
+ defineDefaultProperty(QLatin1String("getAll"), method_getAll);
+ defineDefaultProperty(QLatin1String("forEach"), method_forEach);
+ defineDefaultProperty(QLatin1String("entries"), method_entries);
+ defineDefaultProperty(QLatin1String("keys"), method_keys);
+ defineDefaultProperty(QLatin1String("values"), method_values);
+}
+
+ReturnedValue UrlSearchParamsCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
+ int argc, const Value *newTarget)
+{
+ ExecutionEngine *v4 = that->engine();
+
+ if (argc > 1)
+ return v4->throwError(QLatin1String("Invalid amount of arguments"));
+
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ ArrayObject *argArrayObject = arg->as<ArrayObject>();
+ Object *argObject = arg->as<Object>();
+
+ ReturnedValue o = Encode(v4->newUrlSearchParamsObject());
+
+ if (!newTarget)
+ return o;
+
+ ScopedObject obj(scope, o);
+ obj->setProtoFromNewTarget(newTarget);
+
+ UrlSearchParamsObject *urlSearchParamsObject = obj->as<UrlSearchParamsObject>();
+
+ if (argArrayObject != nullptr) {
+ ScopedArrayObject argArray(scope, argArrayObject);
+
+ uint len = argArray->getLength();
+
+ for (uint i = 0; i < len; i++) {
+ QV4::Value pair = argArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ if (pairArrayObject == nullptr) {
+ return v4->throwTypeError(
+ QLatin1String("element %1 is not a pair").arg(QString::number(i)));
+ }
+
+
+ ScopedArrayObject pairArray(scope, pairArrayObject);
+
+
+ uint pairLen = pairArray->getLength();
+
+
+ if (pairLen != 2) {
+ return v4->throwTypeError(QLatin1String("pair %1 has %2 elements instead of 2")
+ .arg(QString::number(i))
+ .arg(QString::number(pairLen)));
+ }
+ }
+
+ urlSearchParamsObject->initializeParams(argArray);
+ } else if (argObject != nullptr) {
+ ScopedObject scopedObject(scope, argObject);
+ urlSearchParamsObject->initializeParams(scopedObject);
+ } else {
+ QString value = argc > 0 ? arg->toQString() : QLatin1String("");
+ urlSearchParamsObject->initializeParams(value);
+ }
+
+ return obj->asReturnedValue();
+}
+
+void UrlSearchParamsObject::initializeParams()
+{
+ auto *arrayObject = engine()->newArrayObject(0);
+ auto *keys = engine()->newArrayObject(0);
+ auto *values = engine()->newArrayObject(0);
+
+ d()->params.set(engine(), arrayObject);
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::initializeParams(QString value)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ initializeParams();
+
+ if (value.startsWith(QLatin1Char('?')))
+ value = value.mid(1);
+
+ const QStringList params = value.split(QLatin1Char('&'));
+
+ for (const QString& param : params) {
+ if (param.isEmpty())
+ continue;
+
+ QString key, value;
+
+ int equalsIndex = param.indexOf(QLatin1Char('='));
+ if (equalsIndex != -1) {
+ key = param.left(equalsIndex);
+ value = param.mid(equalsIndex+1);
+ } else {
+ key = param;
+ }
+
+ append(engine()->newString(key), engine()->newString(value));
+ }
+}
+
+void UrlSearchParamsObject::initializeParams(ScopedArrayObject& params)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ Scope scope(engine());
+
+ uint len = params->getLength();
+ auto *keys = engine()->newArrayObject(len);
+ auto *values = engine()->newArrayObject(len);
+
+ ScopedArrayObject scopedKeys(scope, keys);
+ ScopedArrayObject scopedValues(scope, values);
+
+ for (uint i = 0; i < len; i++)
+ {
+ QV4::Value pair = params->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+ QV4::Value value = pairArrayObject->get(uint(1));
+
+ scopedKeys->put(i, key);
+ scopedValues->put(i, value);
+ }
+
+
+ d()->params.set(engine(), params->d());
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::initializeParams(ScopedObject& params)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ initializeParams();
+
+ Scope scope(engine());
+ ObjectIterator it(scope, params, ObjectIterator::EnumerableOnly);
+
+ ScopedValue name(scope);
+ ScopedValue val(scope);
+
+ while (true) {
+ name = it.nextPropertyNameAsString(val);
+ if (name->isNull())
+ break;
+
+ Heap::String *nameStr = name->as<String>()->d();
+ Heap::String *valStr = val->toString(engine());
+
+ append(nameStr, valStr);
+ }
+}
+
+void UrlSearchParamsObject::setParams(QList<QStringList> params)
+{
+ auto *arrayObject = engine()->newArrayObject(0);
+ auto *keys = engine()->newArrayObject(0);
+ auto *values = engine()->newArrayObject(0);
+
+ Scope scope(engine());
+
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ ScopedArrayObject scopedKeys(scope, keys);
+ ScopedArrayObject scopedValues(scope, values);
+
+ uint len = 0;
+
+ for (const QStringList& param : params) {
+
+ auto *valuePair = engine()->newArrayObject(2);
+
+ ScopedArrayObject valuePairObject(scope, valuePair);
+
+ ScopedValue key(scope, Value::fromHeapObject(engine()->newString(param[0])));
+ ScopedValue value(scope, Value::fromHeapObject(engine()->newString(param[1])));
+ valuePairObject->put(uint(0), key);
+ valuePairObject->put(uint(1), value);
+
+ scopedKeys->put(len, key);
+ scopedValues->put(len, value);
+
+ scopedArray->put(len, valuePairObject);
+ len++;
+ }
+
+ d()->params.set(engine(), arrayObject);
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::append(Heap::String *name, Heap::String *value)
+{
+ Scope scope(engine());
+
+ ScopedArrayObject scopedArray(scope, d()->params);
+ ScopedArrayObject scopedKeys(scope, d()->keys);
+ ScopedArrayObject scopedValues(scope, d()->values);
+
+ auto *valuePair = engine()->newArrayObject(2);
+
+ ScopedArrayObject valuePairObject(scope, valuePair);
+
+ ScopedValue keyScoped(scope, Value::fromHeapObject(name));
+ ScopedValue valueScoped(scope, Value::fromHeapObject(value));
+ valuePairObject->put(uint(0), keyScoped);
+ valuePairObject->put(uint(1), valueScoped);
+
+ uint len = scopedArray->getLength();
+
+ scopedKeys->put(len, keyScoped);
+ scopedValues->put(len, valueScoped);
+
+ scopedArray->put(len, valuePairObject);
+}
+
+QList<QStringList> UrlSearchParamsObject::params() const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ QList<QStringList> result;
+
+ uint len = scopedArray->getLength();
+
+ for (uint i = 0; i < len; i++) {
+ QV4::Value pair = scopedArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+ QV4::Value value = pairArrayObject->get(uint(1));
+
+ result << QStringList { key.toQString(), value.toQString() };
+ }
+
+ return result;
+}
+
+int UrlSearchParamsObject::length() const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ return scopedArray->getLength();
+}
+
+int UrlSearchParamsObject::indexOf(QString name, int last) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ int len = scopedArray->getLength();
+
+ for (int i = last + 1; i < len; i++) {
+ QV4::Value pair = scopedArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+
+ if (key.toQString() == name)
+ return i;
+ }
+
+ return -1;
+}
+
+QString UrlSearchParamsObject::stringAt(int index, int pairIndex) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ if (index >= scopedArray->getLength())
+ return {};
+
+ QV4::Value pair = scopedArray->get(index);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value value = pairArrayObject->get(pairIndex);
+
+ return value.toQString();
+}
+
+QV4::Heap::String * UrlSearchParamsObject::stringAtRaw(int index, int pairIndex) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ if (index >= scopedArray->getLength())
+ return nullptr;
+
+ QV4::Value pair = scopedArray->get(index);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value value = pairArrayObject->get(pairIndex);
+
+ return value.as<String>()->d();
+}
+
+QString UrlSearchParamsObject::nameAt(int index) const
+{
+ return stringAt(index, 0);
+}
+
+QV4::Heap::String * UrlSearchParamsObject::nameAtRaw(int index) const
+{
+ return stringAtRaw(index, 0);
+}
+
+
+QString UrlSearchParamsObject::valueAt(int index) const
+{
+ return stringAt(index, 1);
+}
+
+QV4::Heap::String * UrlSearchParamsObject::valueAtRaw(int index) const
+{
+ return stringAtRaw(index, 1);
+}
+
+
+struct UrlSearchParamsObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
+{
+ ~UrlSearchParamsObjectOwnPropertyKeyIterator() override = default;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr,
+ PropertyAttributes *attrs = nullptr) override;
+};
+
+PropertyKey UrlSearchParamsObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd,
+ PropertyAttributes *attrs)
+{
+ const UrlSearchParamsObject *usp = static_cast<const UrlSearchParamsObject *>(o);
+
+ Scope scope(usp);
+
+ uint len = usp->length();
+ if (arrayIndex < len) {
+ uint index = arrayIndex;
+ ++arrayIndex;
+ if (attrs)
+ *attrs = Attr_NotConfigurable | Attr_NotWritable;
+ if (pd)
+ pd->value = usp->engine()->newString(usp->nameAt(index));
+ return PropertyKey::fromArrayIndex(index);
+ }
+
+ return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
+}
+
+OwnPropertyKeyIterator *UrlSearchParamsObject::virtualOwnPropertyKeys(const Object *m,
+ Value *target)
+{
+ *target = *m;
+ return new UrlSearchParamsObjectOwnPropertyKeyIterator;
+}
+
+PropertyAttributes UrlSearchParamsObject::virtualGetOwnProperty(const Managed *m, PropertyKey id,
+ Property *p)
+{
+ PropertyAttributes attributes = Object::virtualGetOwnProperty(m, id, p);
+ if (attributes != Attr_Invalid)
+ return attributes;
+
+ if (id.isArrayIndex()) {
+ const int index = id.asArrayIndex();
+ const auto usp = static_cast<const UrlSearchParamsObject *>(m);
+ if (index < usp->length()) {
+ if (p)
+ p->value = usp->engine()->newString(usp->nameAt(index));
+ return Attr_NotConfigurable | Attr_NotWritable;
+ }
+ }
+
+ return Object::virtualGetOwnProperty(m, id, p);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_toString(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ auto params = o->params();
+
+ QString value;
+
+ for (const QStringList &pair : params)
+ value += QLatin1String("%1=%2&").arg(QString::fromUtf8(QUrl::toPercentEncoding(pair[0])),
+ QString::fromUtf8(QUrl::toPercentEncoding(pair[1])));
+
+ value.chop(1);
+
+ return Encode(v4->newString(value));
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_sort(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QList<QStringList> params = o->params();
+ std::stable_sort(params.begin(), params.end(), [](QStringList a, QStringList b) { return a[0] < b[0]; });
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_append(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 2)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+ ScopedValue argValue(scope, argv[1]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ ScopedString name(scope, argName->as<String>());
+ ScopedString value(scope, argValue->toString(v4));
+
+
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ o->append(name->d(), value->d());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_delete(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ QString name = argNameString->toQString();
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QList<QStringList> params = o->params();
+
+ auto to_remove = std::remove_if(params.begin(), params.end(), [&name](QStringList pair) {
+ return pair[0] == name;
+ });
+
+ params.erase(to_remove, params.end());
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_has(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ return Encode(o->indexOf(name) != -1);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_set(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 2)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+ ScopedValue argValue(scope, argv[1]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+ QString value = argValue->toQString();
+
+ auto params = o->params();
+
+ bool matched = false;
+
+ for (auto *it = params.begin(); it != params.end();) {
+ QStringList &param = *it;
+ if (param[0] == name) {
+ if (!matched) {
+ param[1] = value;
+ matched = true;
+ } else {
+ it = params.erase(it);
+ continue;
+ }
+ }
+ it++;
+ }
+
+ if (!matched)
+ params << QStringList { name, value };
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_get(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ int index = o->indexOf(name);
+
+ if (index == -1)
+ return Encode::null();
+
+ return Encode(o->valueAtRaw(index));
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_getAll(const FunctionObject *b,
+ const Value *thisObject, const Value *argv,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ auto *arrayObject = v4->newArrayObject(0);
+ ScopedArrayObject result(scope, arrayObject);
+
+ int i = 0;
+ for (int index = o->indexOf(name); index != -1; index = o->indexOf(name, index)) {
+ ScopedValue value(scope, Value::fromHeapObject(o->valueAtRaw(index)));
+ result->put(i++, value);
+ }
+
+ return Encode(arrayObject);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_forEach(const FunctionObject *b,
+ const Value *thisObject, const Value *argv,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argFunc(scope, argv[0]);
+
+ FunctionObject *func = argFunc->as<FunctionObject>();
+
+ if (func == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument: must be a function"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ for (int i = 0; i < o->length(); i++) {
+ Scoped<String> name(scope, o->nameAtRaw(i));
+ Scoped<String> value(scope, o->valueAtRaw(i));
+
+ QV4::JSCallData calldata(scope, 2);
+
+ calldata->args[0] = value;
+ calldata->args[1] = name;
+
+ func->call(calldata);
+ }
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_entries(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject params(scope, o->d()->params.get());
+
+ Scoped<ArrayIteratorObject> paramsIterator(scope, v4->newArrayIteratorObject(params));
+ paramsIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return paramsIterator->asReturnedValue();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_keys(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject keys(scope, o->d()->keys.get());
+
+ Scoped<ArrayIteratorObject> keysIterator(scope, v4->newArrayIteratorObject(keys));
+ keysIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return keysIterator->asReturnedValue();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_values(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject values(scope, o->d()->values.get());
+
+ Scoped<ArrayIteratorObject> valuesIterator(scope, v4->newArrayIteratorObject(values));
+ valuesIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return valuesIterator->asReturnedValue();
+}
diff --git a/src/qml/jsruntime/qv4urlobject_p.h b/src/qml/jsruntime/qv4urlobject_p.h
new file mode 100644
index 0000000000..aa0e7a062f
--- /dev/null
+++ b/src/qml/jsruntime/qv4urlobject_p.h
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 QV4URLOBJECT_P_H
+#define QV4URLOBJECT_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 "qv4object_p.h"
+#include "qv4functionobject_p.h"
+
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+namespace Heap {
+// clang-format off
+#define UrlObjectMembers(class, Member) \
+ Member(class, Pointer, String *, hash) \
+ Member(class, Pointer, String *, host) \
+ Member(class, Pointer, String *, hostname) \
+ Member(class, Pointer, String *, href) \
+ Member(class, Pointer, String *, origin) \
+ Member(class, Pointer, String *, password) \
+ Member(class, Pointer, String *, pathname) \
+ Member(class, Pointer, String *, port) \
+ Member(class, Pointer, String *, protocol) \
+ Member(class, Pointer, String *, search) \
+ Member(class, Pointer, String *, username)
+// clang-format on
+
+DECLARE_HEAP_OBJECT(UrlObject, Object)
+{
+ DECLARE_MARKOBJECTS(UrlObject);
+ void init() { Object::init(); }
+};
+
+struct UrlCtor : FunctionObject
+{
+ void init(QV4::ExecutionContext *scope);
+};
+
+// clang-format on
+#define UrlSearchParamsObjectMembers(class, Member) \
+ Member(class, Pointer, ArrayObject *, params) \
+ Member(class, Pointer, ArrayObject *, keys) \
+ Member(class, Pointer, ArrayObject *, values)
+// clang-format off
+
+DECLARE_HEAP_OBJECT(UrlSearchParamsObject, Object)
+{
+ DECLARE_MARKOBJECTS(UrlSearchParamsObject);
+ void init() { Object::init(); }
+};
+
+struct UrlSearchParamsCtor : FunctionObject
+{
+ void init(QV4::ExecutionContext *scope);
+};
+}
+
+struct UrlObject : Object
+{
+ V4_OBJECT2(UrlObject, Object)
+ Q_MANAGED_TYPE(UrlObject)
+ V4_PROTOTYPE(urlPrototype)
+
+ QString hash() const { return QLatin1String("#") + d()->hash->toQString(); }
+ bool setHash(QString hash);
+
+ QString host() const { return d()->host->toQString(); }
+ bool setHost(QString host);
+
+ QString hostname() const { return d()->hostname->toQString(); }
+ bool setHostname(QString hostname);
+
+ QString href() const { return d()->href->toQString(); }
+ bool setHref(QString href);
+
+ QString origin() const { return d()->origin->toQString(); }
+
+ QString password() const { return d()->password->toQString(); }
+ bool setPassword(QString password);
+
+ QString pathname() const { return d()->pathname->toQString(); }
+ bool setPathname(QString pathname);
+
+ QString port() const { return d()->port->toQString(); }
+ bool setPort(QString port);
+
+ QString protocol() const { return d()->protocol->toQString(); }
+ bool setProtocol(QString protocol);
+
+ QString search() const { return QLatin1String("?") + d()->search->toQString(); }
+ bool setSearch(QString search);
+
+ QString username() const { return d()->username->toQString(); }
+ bool setUsername(QString username);
+
+private:
+ QUrl toQUrl() const;
+ void updateOrigin();
+ void updateHost();
+};
+
+template<>
+inline const UrlObject *Value::as() const
+{
+ return isManaged() && m()->internalClass->vtable->type == Managed::Type_UrlObject
+ ? static_cast<const UrlObject *>(this)
+ : nullptr;
+}
+
+struct UrlCtor : FunctionObject
+{
+ V4_OBJECT2(UrlCtor, FunctionObject)
+
+ static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv,
+ int argc, const Value *);
+};
+
+struct UrlPrototype : Object
+{
+ V4_PROTOTYPE(objectPrototype)
+
+ void init(ExecutionEngine *engine, Object *ctor);
+
+ static ReturnedValue method_getHash(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setHash(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getHost(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setHost(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getHostname(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setHostname(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getHref(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setHref(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getOrigin(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getPassword(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setPassword(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getPathname(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setPathname(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getPort(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setPort(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getProtocol(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setProtocol(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getSearch(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setSearch(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getUsername(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_setUsername(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+ static ReturnedValue method_getSearchParams(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+};
+
+struct UrlSearchParamsObject : Object
+{
+ V4_OBJECT2(UrlSearchParamsObject, Object)
+ Q_MANAGED_TYPE(UrlSearchParamsObject)
+ V4_PROTOTYPE(urlSearchParamsPrototype)
+
+ void initializeParams();
+ void initializeParams(QString params);
+ void initializeParams(ScopedArrayObject& params);
+ void initializeParams(ScopedObject& params);
+
+ QList<QStringList> params() const;
+ void setParams(QList<QStringList> params);
+
+ QString nameAt(int index) const;
+ Heap::String * nameAtRaw(int index) const;
+ QString valueAt(int index) const;
+ Heap::String * valueAtRaw(int index) const;
+
+ void append(Heap::String *name, Heap::String *value);
+
+ int indexOf(QString name, int last = -1) const;
+ int length() const;
+
+ using Object::getOwnProperty;
+protected:
+ static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
+ static PropertyAttributes virtualGetOwnProperty(const Managed *m, PropertyKey id, Property *p);
+private:
+ QString stringAt(int index, int pairIndex) const;
+ Heap::String * stringAtRaw(int index, int pairIndex) const;
+};
+
+template<>
+inline const UrlSearchParamsObject *Value::as() const
+{
+ return isManaged() && m()->internalClass->vtable->type == Managed::Type_UrlSearchParamsObject
+ ? static_cast<const UrlSearchParamsObject *>(this)
+ : nullptr;
+}
+
+struct UrlSearchParamsCtor : FunctionObject
+{
+ V4_OBJECT2(UrlSearchParamsCtor, FunctionObject)
+
+ static ReturnedValue virtualCallAsConstructor(const FunctionObject *, const Value *argv,
+ int argc, const Value *);
+};
+
+struct UrlSearchParamsPrototype : Object
+{
+ V4_PROTOTYPE(objectPrototype)
+
+ void init(ExecutionEngine *engine, Object *ctor);
+
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_append(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_delete(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_has(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_set(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_get(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_getAll(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_forEach(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_entries(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_keys(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+ static ReturnedValue method_values(const FunctionObject *, const Value *thisObject,
+ const Value *argv, int argc);
+
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QV4URLOBJECT_P_H
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index fb103d492d..7772b34c82 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -58,6 +58,7 @@
#include <private/qv4generatorobject_p.h>
#include <private/qv4alloca_p.h>
#include <private/qqmljavascriptexpression_p.h>
+#include <private/qv4qmlcontext_p.h>
#include <iostream>
#if QT_CONFIG(qml_jit)
@@ -458,6 +459,13 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine)
ReturnedValue result;
if (function->jittedCode != nullptr && debugger == nullptr) {
result = function->jittedCode(frame, engine);
+ } else if (function->aotFunction) {
+ Scope scope(engine);
+ Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
+
+ QVariant resultVariant(function->aotFunction->returnType.id(), nullptr);
+ function->aotFunction->functionPtr(qmlContext->qmlContext()->asQQmlContext(), qmlContext->qmlScope(), resultVariant.data());
+ result = engine->fromVariant(resultVariant);
} else {
// interpreter
result = interpret(frame, engine, function->codeData);
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 6dfdd81cb2..74a760d093 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -212,46 +212,46 @@ public:
}
template <typename ManagedType, typename Arg1>
- typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
+ typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 &&arg1)
{
typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
o->internalClass.set(engine, ManagedType::defaultInternalClass(engine));
Q_ASSERT(o->internalClass && o->internalClass->vtable);
- o->init(arg1);
+ o->init(std::forward<Arg1>(arg1));
return o;
}
template <typename ObjectType, typename... Args>
- typename ObjectType::Data *allocObject(Heap::InternalClass *ic, Args... args)
+ typename ObjectType::Data *allocObject(Heap::InternalClass *ic, Args&&... args)
{
typename ObjectType::Data *d = allocateObject<ObjectType>(ic);
- d->init(args...);
+ d->init(std::forward<Args>(args)...);
return d;
}
template <typename ObjectType, typename... Args>
- typename ObjectType::Data *allocObject(InternalClass *ic, Args... args)
+ typename ObjectType::Data *allocObject(InternalClass *ic, Args&&... args)
{
typename ObjectType::Data *d = allocateObject<ObjectType>(ic);
- d->init(args...);
+ d->init(std::forward<Args>(args)...);
return d;
}
template <typename ObjectType, typename... Args>
- typename ObjectType::Data *allocate(Args... args)
+ typename ObjectType::Data *allocate(Args&&... args)
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(args...);
+ t->d_unchecked()->init(std::forward<Args>(args)...);
return t->d();
}
template <typename ManagedType, typename... Args>
- typename ManagedType::Data *alloc(Args... args)
+ typename ManagedType::Data *alloc(Args&&... args)
{
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(args...);
+ t->d_unchecked()->init(std::forward<Args>(args)...);
return t->d();
}
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index e4b7198b30..67f9cc7581 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -835,7 +835,15 @@ UiImport: UiImportHead Semicolon;
UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
/.
case $rule_number: {
- auto version = new (pool) AST::UiVersionSpecifier(sym(1).dval, sym(3).dval);
+ const int major = sym(1).dval;
+ const int minor = sym(3).dval;
+ if (!QTypeRevision::isValidSegment(major) || !QTypeRevision::isValidSegment(minor)) {
+ diagnostic_messages.append(
+ compileError(loc(1),
+ QLatin1String("Invalid version. Version numbers must be >= 0 and < 255.")));
+ return false;
+ }
+ auto version = new (pool) AST::UiVersionSpecifier(major, minor);
version->majorToken = loc(1);
version->minorToken = loc(3);
sym(1).UiVersionSpecifier = version;
@@ -846,7 +854,14 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
UiVersionSpecifier: T_VERSION_NUMBER;
/.
case $rule_number: {
- auto version = new (pool) AST::UiVersionSpecifier(sym(1).dval, 0);
+ const int major = sym(1).dval;
+ if (!QTypeRevision::isValidSegment(major)) {
+ diagnostic_messages.append(
+ compileError(loc(1),
+ QLatin1String("Invalid major version. Version numbers must be >= 0 and < 255.")));
+ return false;
+ }
+ auto version = new (pool) AST::UiVersionSpecifier(sym(1).dval);
version->majorToken = loc(1);
sym(1).UiVersionSpecifier = version;
} break;
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 9eba432e69..8c1d8a2510 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -57,6 +57,7 @@
#include <private/qqmljsmemorypool_p.h>
#include <QtCore/qstring.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -646,7 +647,15 @@ class QML_PARSER_EXPORT UiVersionSpecifier : public Node
public:
QQMLJS_DECLARE_AST_NODE(UiVersionSpecifier)
- UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum) { kind = K; }
+ UiVersionSpecifier(int majorum) : version(QTypeRevision::fromMajorVersion(majorum))
+ {
+ kind = K;
+ }
+
+ UiVersionSpecifier(int majorum, int minorum) : version(QTypeRevision::fromVersion(majorum, minorum))
+ {
+ kind = K;
+ }
void accept0(BaseVisitor *visitor) override;
@@ -658,8 +667,7 @@ public:
}
// attributes:
- int majorVersion;
- int minorVersion;
+ QTypeRevision version;
SourceLocation majorToken;
SourceLocation minorToken;
};
diff --git a/src/qml/parser/qqmljsglobal_p.h b/src/qml/parser/qqmljsglobal_p.h
index bf8155c6ec..e7937ebc3b 100644
--- a/src/qml/parser/qqmljsglobal_p.h
+++ b/src/qml/parser/qqmljsglobal_p.h
@@ -52,29 +52,17 @@
#include <QtCore/qglobal.h>
-#ifdef QT_CREATOR
-
-# ifdef QDECLARATIVEJS_BUILD_DIR
-# define QML_PARSER_EXPORT Q_DECL_EXPORT
-# elif QML_BUILD_STATIC_LIB
+#ifndef QT_STATIC
+# if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
+ // QmlDevTools is a static library
# define QML_PARSER_EXPORT
+# elif defined(QT_BUILD_QML_LIB)
+# define QML_PARSER_EXPORT Q_DECL_EXPORT
# else
# define QML_PARSER_EXPORT Q_DECL_IMPORT
-# endif // QQMLJS_BUILD_DIR
-
-#else // !QT_CREATOR
-# ifndef QT_STATIC
-# if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
- // QmlDevTools is a static library
-# define QML_PARSER_EXPORT
-# elif defined(QT_BUILD_QML_LIB)
-# define QML_PARSER_EXPORT Q_DECL_EXPORT
-# else
-# define QML_PARSER_EXPORT Q_DECL_IMPORT
-# endif
-# else
-# define QML_PARSER_EXPORT
# endif
-#endif // QT_CREATOR
+#else
+# define QML_PARSER_EXPORT
+#endif
#endif // QQMLJSGLOBAL_P_H
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 243fc5bd30..95ad9a0670 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -893,8 +893,10 @@ int Lexer::scanString(ScanStringMode mode)
if (_engine) {
while (_codePtr <= _endPtr) {
if (isLineTerminator()) {
- if ((quote == QLatin1Char('`') || qmlMode()))
+ if ((quote == QLatin1Char('`') || qmlMode())) {
+ --_currentLineNumber; // will be read again in scanChar()
break;
+ }
_errorCode = IllegalCharacter;
_errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal");
return T_ERROR;
@@ -925,6 +927,7 @@ int Lexer::scanString(ScanStringMode mode)
// rewind by one char, so things gets scanned correctly
--_codePtr;
+ --_currentColumnNumber;
_validTokenText = true;
_tokenText = QString(startCode, _codePtr - startCode);
@@ -1538,9 +1541,10 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
setError(QCoreApplication::translate("QQmlParser","Imported file must be a script"));
return false;
}
+ lex();
} else if (_tokenKind == T_IDENTIFIER) {
- // .import T_IDENTIFIER (. T_IDENTIFIER)* T_VERSION_NUMBER . T_VERSION_NUMBER as T_IDENTIFIER
+ // .import T_IDENTIFIER (. T_IDENTIFIER)* (T_VERSION_NUMBER (. T_VERSION_NUMBER)?)? as T_IDENTIFIER
while (true) {
if (!isUriToken(_tokenKind)) {
setError(QCoreApplication::translate("QQmlParser","Invalid module URI"));
@@ -1566,31 +1570,27 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
}
}
- if (_tokenKind != T_VERSION_NUMBER) {
- setError(QCoreApplication::translate("QQmlParser","Module import requires a version"));
- return false; // expected the module version number
- }
-
- version = tokenText();
- lex();
- if (_tokenKind != T_DOT) {
- setError(QCoreApplication::translate( "QQmlParser", "Module import requires a minor version (missing dot)"));
- return false; // expected the module version number
- }
- version += QLatin1Char('.');
-
- lex();
- if (_tokenKind != T_VERSION_NUMBER) {
- setError(QCoreApplication::translate( "QQmlParser", "Module import requires a minor version (missing number)"));
- return false; // expected the module version number
+ if (_tokenKind == T_VERSION_NUMBER) {
+ version = tokenText();
+ lex();
+ if (_tokenKind == T_DOT) {
+ version += QLatin1Char('.');
+ lex();
+ if (_tokenKind != T_VERSION_NUMBER) {
+ setError(QCoreApplication::translate(
+ "QQmlParser", "Incomplete version number (dot but no minor)"));
+ return false; // expected the module version number
+ }
+ version += tokenText();
+ lex();
+ }
}
- version += tokenText();
}
//
// recognize the mandatory `as' followed by the module name
//
- if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
+ if (! (_tokenKind == T_AS && tokenStartLine() == lineNumber)) {
if (fileImport)
setError(QCoreApplication::translate("QQmlParser", "File import requires a qualifier"));
else
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index e39a8319b6..14b46307aa 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -7,6 +7,9 @@ qtConfig(qml-network): \
TRACEPOINT_PROVIDER = $$PWD/qtqml.tracepoints
CONFIG += qt_tracepoints
+!qtConfig(qml-python): \
+ error(Python is required to build QtQml.)
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
@@ -63,7 +66,6 @@ qtConfig(qml-animation) {
}
include(types/types.pri)
include(../3rdparty/masm/masm-defs.pri)
-include(../3rdparty/masm/masm.pri)
MODULE_PLUGIN_TYPES = \
qmltooling
@@ -71,7 +73,9 @@ MODULE_PLUGIN_TYPES = \
QMLTYPES_FILENAME = plugins.qmltypes
QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml
QML_IMPORT_NAME = QtQml
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
load(qt_module)
+
+include(../3rdparty/masm/masm.pri)
diff --git a/src/qml/qml/ftw/qfieldlist_p.h b/src/qml/qml/ftw/qfieldlist_p.h
index 2bf07fb20d..66602daab2 100644
--- a/src/qml/qml/ftw/qfieldlist_p.h
+++ b/src/qml/qml/ftw/qfieldlist_p.h
@@ -52,11 +52,12 @@
//
#include <QtCore/qglobal.h>
+#include <QtCore/qtaggedpointer.h>
#include <private/qflagpointer_p.h>
// QForwardFieldList is a super simple linked list that can only prepend
-template<class N, N *N::*nextMember>
+template<class N, N *N::*nextMember, typename Tag = QtPrivate::TagInfo<N>>
class QForwardFieldList
{
public:
@@ -72,17 +73,10 @@ public:
static inline N *next(N *v);
- inline bool flag() const;
- inline void setFlag();
- inline void clearFlag();
- inline void setFlagValue(bool);
-
- inline bool flag2() const;
- inline void setFlag2();
- inline void clearFlag2();
- inline void setFlag2Value(bool);
+ inline Tag tag() const;
+ inline void setTag(Tag t);
private:
- QFlagPointer<N> _first;
+ QTaggedPointer<N, Tag> _first;
};
// QFieldList is a simple linked list, that can append and prepend and also
@@ -108,8 +102,10 @@ public:
inline void insertAfter(N *, QFieldList<N, nextMember> &);
inline void copyAndClear(QFieldList<N, nextMember> &);
- inline void copyAndClearAppend(QForwardFieldList<N, nextMember> &);
- inline void copyAndClearPrepend(QForwardFieldList<N, nextMember> &);
+ template <typename Tag>
+ inline void copyAndClearAppend(QForwardFieldList<N, nextMember, Tag> &);
+ template <typename Tag>
+ inline void copyAndClearPrepend(QForwardFieldList<N, nextMember, Tag> &);
static inline N *next(N *v);
@@ -124,21 +120,21 @@ private:
quint32 _count:31;
};
-template<class N, N *N::*nextMember>
-QForwardFieldList<N, nextMember>::QForwardFieldList()
+template<class N, N *N::*nextMember, typename Tag>
+QForwardFieldList<N, nextMember, Tag>::QForwardFieldList()
{
}
-template<class N, N *N::*nextMember>
-N *QForwardFieldList<N, nextMember>::first() const
+template<class N, N *N::*nextMember, typename Tag>
+N *QForwardFieldList<N, nextMember, Tag>::first() const
{
- return *_first;
+ return _first.data();
}
-template<class N, N *N::*nextMember>
-N *QForwardFieldList<N, nextMember>::takeFirst()
+template<class N, N *N::*nextMember, typename Tag>
+N *QForwardFieldList<N, nextMember, Tag>::takeFirst()
{
- N *value = *_first;
+ N *value = _first.data();
if (value) {
_first = next(value);
value->*nextMember = nullptr;
@@ -146,85 +142,49 @@ N *QForwardFieldList<N, nextMember>::takeFirst()
return value;
}
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::prepend(N *v)
+template<class N, N *N::*nextMember, typename Tag>
+void QForwardFieldList<N, nextMember, Tag>::prepend(N *v)
{
Q_ASSERT(v->*nextMember == nullptr);
- v->*nextMember = *_first;
+ v->*nextMember = _first.data();
_first = v;
}
-template<class N, N *N::*nextMember>
-bool QForwardFieldList<N, nextMember>::isEmpty() const
+template<class N, N *N::*nextMember, typename Tag>
+bool QForwardFieldList<N, nextMember, Tag>::isEmpty() const
{
return _first.isNull();
}
-template<class N, N *N::*nextMember>
-bool QForwardFieldList<N, nextMember>::isOne() const
+template<class N, N *N::*nextMember, typename Tag>
+bool QForwardFieldList<N, nextMember, Tag>::isOne() const
{
- return *_first && _first->*nextMember == 0;
+ return _first.data() && _first->*nextMember == 0;
}
-template<class N, N *N::*nextMember>
-bool QForwardFieldList<N, nextMember>::isMany() const
+template<class N, N *N::*nextMember, typename Tag>
+bool QForwardFieldList<N, nextMember, Tag>::isMany() const
{
- return *_first && _first->*nextMember != 0;
+ return _first.data() && _first->*nextMember != 0;
}
-template<class N, N *N::*nextMember>
-N *QForwardFieldList<N, nextMember>::next(N *v)
+template<class N, N *N::*nextMember, typename Tag>
+N *QForwardFieldList<N, nextMember, Tag>::next(N *v)
{
Q_ASSERT(v);
return v->*nextMember;
}
-template<class N, N *N::*nextMember>
-bool QForwardFieldList<N, nextMember>::flag() const
-{
- return _first.flag();
-}
-
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::setFlag()
-{
- _first.setFlag();
-}
-
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::clearFlag()
-{
- _first.clearFlag();
-}
-
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::setFlagValue(bool v)
-{
- _first.setFlagValue(v);
-}
-
-template<class N, N *N::*nextMember>
-bool QForwardFieldList<N, nextMember>::flag2() const
-{
- return _first.flag2();
-}
-
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::setFlag2()
+template<class N, N *N::*nextMember, typename Tag>
+Tag QForwardFieldList<N, nextMember, Tag>::tag() const
{
- _first.setFlag2();
+ return _first.tag();
}
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::clearFlag2()
-{
- _first.clearFlag2();
-}
-
-template<class N, N *N::*nextMember>
-void QForwardFieldList<N, nextMember>::setFlag2Value(bool v)
+template<class N, N *N::*nextMember, typename Tag>
+void QForwardFieldList<N, nextMember, Tag>::setTag(Tag t)
{
- _first.setFlag2Value(v);
+ _first.setTag(t);
}
template<class N, N *N::*nextMember>
@@ -380,7 +340,8 @@ void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
}
template<class N, N *N::*nextMember>
-void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMember> &o)
+template <typename Tag>
+void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMember, Tag> &o)
{
_first = 0;
_last = 0;
@@ -389,7 +350,8 @@ void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMemb
}
template<class N, N *N::*nextMember>
-void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember> &o)
+template <typename Tag>
+void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember, Tag> &o)
{
_first = nullptr;
_last = nullptr;
diff --git a/src/qml/qml/ftw/qflagpointer_p.h b/src/qml/qml/ftw/qflagpointer_p.h
index a10e57aeca..5cdf973352 100644
--- a/src/qml/qml/ftw/qflagpointer_p.h
+++ b/src/qml/qml/ftw/qflagpointer_p.h
@@ -66,43 +66,6 @@ template <> struct QFlagPointerAlignment<void>
};
}
-template<typename T>
-class QFlagPointer {
-public:
- inline QFlagPointer();
- inline QFlagPointer(T *);
- inline QFlagPointer(const QFlagPointer<T> &o);
-
- inline bool isNull() const;
-
- inline bool flag() const;
- inline void setFlag();
- inline void clearFlag();
- inline void setFlagValue(bool);
-
- inline bool flag2() const;
- inline void setFlag2();
- inline void clearFlag2();
- inline void setFlag2Value(bool);
-
- inline QFlagPointer<T> &operator=(const QFlagPointer &o);
- inline QFlagPointer<T> &operator=(T *);
-
- inline T *operator->() const;
- inline T *operator*() const;
-
- inline T *data() const;
-
- inline explicit operator bool() const;
-
-private:
- quintptr ptr_value = 0;
-
- static const quintptr FlagBit = 0x1;
- static const quintptr Flag2Bit = 0x2;
- static const quintptr FlagsMask = FlagBit | Flag2Bit;
-};
-
template<typename T, typename T2>
class QBiPointer {
public:
@@ -135,121 +98,6 @@ private:
static const quintptr FlagsMask = FlagBit | Flag2Bit;
};
-template<typename T>
-QFlagPointer<T>::QFlagPointer()
-{
-}
-
-template<typename T>
-QFlagPointer<T>::QFlagPointer(T *v)
-: ptr_value(quintptr(v))
-{
- Q_STATIC_ASSERT_X(Q_ALIGNOF(T) >= 4, "Type T does not have sufficient alignment");
- Q_ASSERT((ptr_value & FlagsMask) == 0);
-}
-
-template<typename T>
-QFlagPointer<T>::QFlagPointer(const QFlagPointer<T> &o)
-: ptr_value(o.ptr_value)
-{
-}
-
-template<typename T>
-bool QFlagPointer<T>::isNull() const
-{
- return 0 == (ptr_value & (~FlagsMask));
-}
-
-template<typename T>
-bool QFlagPointer<T>::flag() const
-{
- return ptr_value & FlagBit;
-}
-
-template<typename T>
-void QFlagPointer<T>::setFlag()
-{
- ptr_value |= FlagBit;
-}
-
-template<typename T>
-void QFlagPointer<T>::clearFlag()
-{
- ptr_value &= ~FlagBit;
-}
-
-template<typename T>
-void QFlagPointer<T>::setFlagValue(bool v)
-{
- if (v) setFlag();
- else clearFlag();
-}
-
-template<typename T>
-bool QFlagPointer<T>::flag2() const
-{
- return ptr_value & Flag2Bit;
-}
-
-template<typename T>
-void QFlagPointer<T>::setFlag2()
-{
- ptr_value|= Flag2Bit;
-}
-
-template<typename T>
-void QFlagPointer<T>::clearFlag2()
-{
- ptr_value &= ~Flag2Bit;
-}
-
-template<typename T>
-void QFlagPointer<T>::setFlag2Value(bool v)
-{
- if (v) setFlag2();
- else clearFlag2();
-}
-
-template<typename T>
-QFlagPointer<T> &QFlagPointer<T>::operator=(const QFlagPointer &o)
-{
- ptr_value = o.ptr_value;
- return *this;
-}
-
-template<typename T>
-QFlagPointer<T> &QFlagPointer<T>::operator=(T *o)
-{
- Q_ASSERT((quintptr(o) & FlagsMask) == 0);
-
- ptr_value = quintptr(o) | (ptr_value & FlagsMask);
- return *this;
-}
-
-template<typename T>
-T *QFlagPointer<T>::operator->() const
-{
- return (T *)(ptr_value & ~FlagsMask);
-}
-
-template<typename T>
-T *QFlagPointer<T>::operator*() const
-{
- return (T *)(ptr_value & ~FlagsMask);
-}
-
-template<typename T>
-T *QFlagPointer<T>::data() const
-{
- return (T *)(ptr_value & ~FlagsMask);
-}
-
-template<typename T>
-QFlagPointer<T>::operator bool() const
-{
- return data() != nullptr;
-}
-
template<typename T, typename T2>
QBiPointer<T, T2>::QBiPointer()
{
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 6c58ab87f4..4553fa9359 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
// Copy of QString's qMemCompare
bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
{
- Q_ASSERT(lhs && rhs);
+ Q_ASSERT((lhs && rhs) || !length);
const quint16 *a = (const quint16 *)lhs;
const quint16 *b = (const quint16 *)rhs;
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index a2e10ff143..08f019b4bd 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -172,12 +172,12 @@ private:
mutable quint32 m_hash = 0;
};
-inline uint qHash(const QHashedString &string)
+inline size_t qHash(const QHashedString &string)
{
return uint(string.hash());
}
-inline uint qHash(const QHashedStringRef &string)
+inline size_t qHash(const QHashedStringRef &string)
{
return uint(string.hash());
}
diff --git a/src/qml/qml/ftw/qlazilyallocated_p.h b/src/qml/qml/ftw/qlazilyallocated_p.h
index 9073e41558..2bac84afb3 100644
--- a/src/qml/qml/ftw/qlazilyallocated_p.h
+++ b/src/qml/qml/ftw/qlazilyallocated_p.h
@@ -52,12 +52,11 @@
//
#include <QtCore/qglobal.h>
-
-#include <private/qflagpointer_p.h>
+#include <QtCore/qtaggedpointer.h>
QT_BEGIN_NAMESPACE
-template<typename T>
+template<typename T, typename Tag = typename QtPrivate::TagInfo<T>::TagType>
class QLazilyAllocated {
public:
inline QLazilyAllocated();
@@ -70,73 +69,59 @@ public:
inline T &value();
inline const T &value() const;
- inline bool flag() const;
- inline void setFlag();
- inline void clearFlag();
- inline void setFlagValue(bool);
+ inline Tag tag() const;
+ inline void setTag(Tag t);
private:
- mutable QFlagPointer<T> d;
+ mutable QTaggedPointer<T, Tag> d;
};
-template<typename T>
-QLazilyAllocated<T>::QLazilyAllocated()
+template<typename T, typename Tag>
+QLazilyAllocated<T, Tag>::QLazilyAllocated()
{
}
-template<typename T>
-QLazilyAllocated<T>::~QLazilyAllocated()
+template<typename T, typename Tag>
+QLazilyAllocated<T, Tag>::~QLazilyAllocated()
{
- delete *d;
+ delete d.data();
}
-template<typename T>
-bool QLazilyAllocated<T>::isAllocated() const
+template<typename T, typename Tag>
+bool QLazilyAllocated<T, Tag>::isAllocated() const
{
return !d.isNull();
}
-template<typename T>
-T &QLazilyAllocated<T>::value()
+template<typename T, typename Tag>
+T &QLazilyAllocated<T, Tag>::value()
{
if (d.isNull()) d = new T;
- return *(*d);
+ return *d;
}
-template<typename T>
-const T &QLazilyAllocated<T>::value() const
+template<typename T, typename Tag>
+const T &QLazilyAllocated<T, Tag>::value() const
{
if (d.isNull()) d = new T;
- return *(*d);
-}
-
-template<typename T>
-T *QLazilyAllocated<T>::operator->() const
-{
return *d;
}
-template<typename T>
-bool QLazilyAllocated<T>::flag() const
-{
- return d.flag();
-}
-
-template<typename T>
-void QLazilyAllocated<T>::setFlag()
+template<typename T, typename Tag>
+T *QLazilyAllocated<T, Tag>::operator->() const
{
- d.setFlag();
+ return d.data();
}
-template<typename T>
-void QLazilyAllocated<T>::clearFlag()
+template<typename T, typename Tag>
+Tag QLazilyAllocated<T, Tag>::tag() const
{
- d.clearFlag();
+ return d.tag();
}
-template<typename T>
-void QLazilyAllocated<T>::setFlagValue(bool v)
+template<typename T, typename Tag>
+void QLazilyAllocated<T, Tag>::setTag(Tag t)
{
- d.setFlagValue(v);
+ d.setTag(t);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/ftw/qlinkedstringhash_p.h b/src/qml/qml/ftw/qlinkedstringhash_p.h
index 67ced7fbbf..495d78ea2f 100644
--- a/src/qml/qml/ftw/qlinkedstringhash_p.h
+++ b/src/qml/qml/ftw/qlinkedstringhash_p.h
@@ -223,7 +223,7 @@ public:
{
if (auto *node = iter.node()) {
QHashedString key(node->key());
- while ((node = static_cast<typename QLinkedStringHash<T>::Node *>(*node->next))) {
+ while ((node = static_cast<typename QLinkedStringHash<T>::Node *>(node->next.data()))) {
if (node->equals(key))
return QLinkedStringHash<T>::iterator(node);
}
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index 7d2ad354d6..0f7726ef65 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -188,13 +188,7 @@ void QQmlThreadPrivate::threadEvent()
lock();
for (;;) {
- if (m_shutdown) {
- quit();
- wakeOne();
- unlock();
-
- return;
- } else if (!threadList.isEmpty()) {
+ if (!threadList.isEmpty()) {
m_threadProcessing = true;
QQmlThread::Message *message = threadList.first();
@@ -206,6 +200,12 @@ void QQmlThreadPrivate::threadEvent()
lock();
delete threadList.takeFirst();
+ } else if (m_shutdown) {
+ quit();
+ wakeOne();
+ unlock();
+
+ return;
} else {
wakeOne();
@@ -242,6 +242,7 @@ void QQmlThread::shutdown()
d->lock();
Q_ASSERT(!d->m_shutdown);
+ d->m_shutdown = true;
for (;;) {
if (d->mainSync || !d->mainList.isEmpty()) {
d->unlock();
@@ -254,13 +255,10 @@ void QQmlThread::shutdown()
}
}
- d->m_shutdown = true;
- if (QCoreApplication::closingDown()) {
+ if (QCoreApplication::closingDown())
d->quit();
- } else {
+ else
d->triggerThreadEvent();
- d->wait();
- }
d->unlock();
d->QThread::wait();
diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h
index f9435b4919..125e160500 100644
--- a/src/qml/qml/ftw/qstringhash_p.h
+++ b/src/qml/qml/ftw/qstringhash_p.h
@@ -54,25 +54,32 @@
#include <private/qhashedstring_p.h>
#include <private/qprimefornumbits_p.h>
-#include <QtCore/qglobal.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtaggedpointer.h>
QT_BEGIN_NAMESPACE
+static inline QString::DataPointer &mutableStringData(const QHashedString &key)
+{
+ return const_cast<QHashedString &>(key).data_ptr();
+}
+
class QStringHashData;
class QStringHashNode
{
public:
QStringHashNode()
- : ckey(nullptr)
{
}
QStringHashNode(const QHashedString &key)
: length(key.length()), hash(key.hash()), symbolId(0)
+ , arrayData(mutableStringData(key).d_ptr())
+ , strData(mutableStringData(key).data())
{
- strData = const_cast<QHashedString &>(key).data_ptr();
+ arrayData->ref();
setQString(true);
- strData->ref.ref();
}
QStringHashNode(const QHashedCStringRef &key)
@@ -81,49 +88,61 @@ public:
}
QStringHashNode(const QStringHashNode &o)
- : length(o.length), hash(o.hash), symbolId(o.symbolId), ckey(o.ckey)
+ : length(o.length), hash(o.hash), symbolId(o.symbolId), arrayData(o.arrayData)
{
setQString(o.isQString());
- if (isQString()) { strData->ref.ref(); }
+ if (isQString()) {
+ strData = o.strData;
+ arrayData->ref();
+ } else {
+ ckey = o.ckey;
+ }
}
~QStringHashNode()
{
- if (isQString()) { if (!strData->ref.deref()) free(strData); }
+ if (isQString() && !arrayData->deref())
+ QTypedArrayData<ushort>::deallocate(arrayData);
}
- QFlagPointer<QStringHashNode> next;
+ enum Tag {
+ NodeIsCString,
+ NodeIsQString
+ };
+
+ QTaggedPointer<QStringHashNode, Tag> next;
qint32 length = 0;
quint32 hash = 0;
quint32 symbolId = 0;
+ QTypedArrayData<ushort> *arrayData = nullptr;
union {
- const char *ckey;
- QStringData *strData;
+ const char *ckey = nullptr;
+ ushort *strData;
};
inline QHashedString key() const
{
- if (isQString())
- return QHashedString(QString((QChar *)strData->data(), length), hash);
+ if (isQString()) {
+ arrayData->ref();
+ return QHashedString(QString(QStringPrivate(arrayData, strData, length)), hash);
+ }
return QHashedString(QString::fromLatin1(ckey, length), hash);
}
- bool isQString() const { return next.flag(); }
- void setQString(bool v) { if (v) next.setFlag(); else next.clearFlag(); }
+ bool isQString() const { return next.tag() == NodeIsQString; }
+ void setQString(bool v) { if (v) next.setTag(NodeIsQString); else next.setTag(NodeIsCString); }
- inline char *cStrData() const { return (char *)ckey; }
- inline quint16 *utf16Data() const { return (quint16 *)strData->data(); }
+ inline qsizetype size() const { return length; }
+ inline const char *cStrData() const { return ckey; }
+ inline const quint16 *utf16Data() const { return strData; }
inline bool equals(const QV4::Value &string) const {
QString s = string.toQStringNoThrow();
if (isQString()) {
- QStringDataPtr dd;
- dd.ptr = strData;
- strData->ref.ref();
- return QString(dd) == s;
+ return QStringView(utf16Data(), length) == s;
} else {
return QLatin1String(cStrData(), length) == s;
}
@@ -133,10 +152,7 @@ public:
if (length != string->d()->length() || hash != string->hashValue())
return false;
if (isQString()) {
- QStringDataPtr dd;
- dd.ptr = strData;
- strData->ref.ref();
- return QString(dd) == string->toQString();
+ return QStringView(utf16Data(), length) == string->toQString();
} else {
return QLatin1String(cStrData(), length) == string->toQString();
}
@@ -510,8 +526,9 @@ void QStringHash<T>::initializeNode(Node *node, const QHashedString &key)
{
node->length = key.length();
node->hash = key.hash();
- node->strData = const_cast<QHashedString &>(key).data_ptr();
- node->strData->ref.ref();
+ node->arrayData = mutableStringData(key).d_ptr();
+ node->strData = mutableStringData(key).data();
+ node->arrayData->ref();
node->setQString(true);
}
@@ -547,10 +564,11 @@ typename QStringHash<T>::Node *QStringHash<T>::takeNode(const Node &o)
Node *rv = nodePool->nodes + nodePool->used++;
rv->length = o.length;
rv->hash = o.hash;
+ rv->arrayData = o.arrayData;
if (o.isQString()) {
rv->strData = o.strData;
- rv->strData->ref.ref();
rv->setQString(true);
+ rv->arrayData->ref();
} else {
rv->ckey = o.ckey;
}
@@ -700,7 +718,7 @@ typename QStringHash<T>::Node *QStringHash<T>::findNode(const K &key) const
typename HashedForm<K>::Type hashedKey(hashedString(key));
while (node && !node->equals(hashedKey))
- node = (*node->next);
+ node = node->next.data();
return (Node *)node;
}
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index a16f3d4167..6cca897e08 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -17,6 +17,7 @@ SOURCES += \
$$PWD/qqmlcomponent.cpp \
$$PWD/qqmlincubator.cpp \
$$PWD/qqmlcontext.cpp \
+ $$PWD/qqmlcontextdata.cpp \
$$PWD/qqmlcustomparser.cpp \
$$PWD/qqmlpropertyvaluesource.cpp \
$$PWD/qqmlpropertyvalueinterceptor.cpp \
@@ -53,6 +54,7 @@ SOURCES += \
$$PWD/qqmlfile.cpp \
$$PWD/qqmlplatform.cpp \
$$PWD/qqmlbinding.cpp \
+ $$PWD/qqmlpropertybinding.cpp \
$$PWD/qqmlabstracturlinterceptor.cpp \
$$PWD/qqmlapplicationengine.cpp \
$$PWD/qqmllistwrapper.cpp \
@@ -112,6 +114,8 @@ HEADERS += \
$$PWD/qqmlinfo.h \
$$PWD/qqmlproperty_p.h \
$$PWD/qqmlcontext_p.h \
+ $$PWD/qqmlcontextdata_p.h \
+ $$PWD/qqmlguardedcontextdata_p.h \
$$PWD/qqmltypeloader_p.h \
$$PWD/qqmllist.h \
$$PWD/qqmllist_p.h \
@@ -145,6 +149,7 @@ HEADERS += \
$$PWD/qqmlfile.h \
$$PWD/qqmlplatform_p.h \
$$PWD/qqmlbinding_p.h \
+ $$PWD/qqmlpropertybinding_p.h \
$$PWD/qqmlextensionplugin_p.h \
$$PWD/qqmlabstracturlinterceptor.h \
$$PWD/qqmlapplicationengine_p.h \
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index fe4e2f4e55..a57daf78d2 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -62,23 +62,24 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
//From qqml.h
bool qmlProtectModule(const char *uri, int majVersion)
{
- return QQmlMetaType::protectModule(QString::fromUtf8(uri), majVersion);
+ return QQmlMetaType::protectModule(QString::fromUtf8(uri),
+ QTypeRevision::fromMajorVersion(majVersion));
}
//From qqml.h
void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor)
{
- QQmlMetaType::registerModule(uri, versionMajor, versionMinor);
+ QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor));
}
//From qqml.h
int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
- return QQmlMetaType::typeId(uri, versionMajor, versionMinor, qmlName);
+ return QQmlMetaType::typeId(uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName);
}
// From qqmlprivate.h
-QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
+QObject *QQmlPrivate::SingletonFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
{
if (!m_object) {
QQmlError error;
@@ -104,9 +105,9 @@ QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJS
return m_object;
};
-static QVector<int> availableRevisions(const QMetaObject *metaObject)
+static QVector<QTypeRevision> availableRevisions(const QMetaObject *metaObject)
{
- QVector<int> revisions;
+ QVector<QTypeRevision> revisions;
if (!metaObject)
return revisions;
const int propertyOffset = metaObject->propertyOffset();
@@ -115,7 +116,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject)
propertyIndex < propertyEnd; ++propertyIndex) {
const QMetaProperty property = metaObject->property(propertyIndex);
if (int revision = property.revision())
- revisions.append(revision);
+ revisions.append(QTypeRevision::fromEncodedVersion(revision));
}
const int methodOffset = metaObject->methodOffset();
const int methodCount = metaObject->methodCount();
@@ -123,7 +124,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject)
methodIndex < methodEnd; ++methodIndex) {
const QMetaMethod method = metaObject->method(methodIndex);
if (int revision = method.revision())
- revisions.append(revision);
+ revisions.append(QTypeRevision::fromEncodedVersion(revision));
}
// Need to also check parent meta objects, as their revisions are inherited.
@@ -133,6 +134,54 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject)
return revisions;
}
+template<typename Registration>
+void assignVersions(Registration *registration, QTypeRevision revision,
+ QTypeRevision defaultVersion)
+{
+ const quint8 majorVersion = revision.hasMajorVersion() ? revision.majorVersion()
+ : defaultVersion.majorVersion();
+ registration->version = revision.hasMinorVersion()
+ ? QTypeRevision::fromVersion(majorVersion, revision.minorVersion())
+ : QTypeRevision::fromMajorVersion(majorVersion);
+ registration->revision = revision;
+}
+
+static QVector<QTypeRevision> prepareRevisions(const QMetaObject *metaObject, QTypeRevision added)
+{
+ auto revisions = availableRevisions(metaObject);
+ revisions.append(added);
+ return revisions;
+}
+
+static void uniqueRevisions(QVector<QTypeRevision> *revisions, QTypeRevision defaultVersion,
+ QTypeRevision added)
+{
+ bool revisionsHaveMajorVersions = false;
+ for (QTypeRevision revision : QVector<QTypeRevision>(*revisions)) { // yes, copy
+ // allow any minor version for each explicitly specified past major one
+ if (revision.hasMajorVersion()) {
+ revisionsHaveMajorVersions = true;
+ if (revision.majorVersion() < defaultVersion.majorVersion())
+ revisions->append(QTypeRevision::fromVersion(revision.majorVersion(), 254));
+ }
+ }
+
+ if (revisionsHaveMajorVersions) {
+ if (!added.hasMajorVersion()) {
+ // If added in unspecified major version, assume default one.
+ revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(),
+ added.minorVersion()));
+ } else if (added.majorVersion() < defaultVersion.majorVersion()) {
+ // If added in past major version, add .0 of default version.
+ revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), 0));
+ }
+ }
+
+ std::sort(revisions->begin(), revisions->end());
+ const auto it = std::unique(revisions->begin(), revisions->end());
+ revisions->erase(it, revisions->end());
+}
+
/*
This method is "over generalized" to allow us to (potentially) register more types of things in
the future without adding exported symbols.
@@ -153,19 +202,23 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
const bool creatable = (elementName != nullptr)
&& boolClassInfo(type.classInfoMetaObject, "QML.Creatable", true);
- const QString noCreateReason = creatable
- ? QString()
- : QString::fromUtf8(classInfo(type.classInfoMetaObject, "QML.UncreatableReason"));
+ QString noCreateReason;
+
+ if (!creatable) {
+ noCreateReason = QString::fromUtf8(classInfo(type.classInfoMetaObject, "QML.UncreatableReason"));
+ if (noCreateReason.isEmpty())
+ noCreateReason = QLatin1String("Type cannot be created in QML.");
+ }
+
RegisterType revisionRegistration = {
- 1,
+ 0,
type.typeId,
type.listId,
creatable ? type.objectSize : 0,
nullptr,
noCreateReason,
type.uri,
- type.versionMajor,
- -1,
+ type.version,
nullptr,
type.metaObject,
type.attachedPropertiesFunction,
@@ -176,28 +229,26 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
type.extensionObjectCreate,
type.extensionMetaObject,
nullptr,
- -1
+ QTypeRevision()
};
- const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0);
- const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1);
+ const QTypeRevision added = revisionClassInfo(
+ type.classInfoMetaObject, "QML.AddedInVersion",
+ QTypeRevision::fromMinorVersion(0));
+ const QTypeRevision removed = revisionClassInfo(
+ type.classInfoMetaObject, "QML.RemovedInVersion");
- auto revisions = availableRevisions(type.metaObject);
- revisions.append(qMax(added, 0));
+ auto revisions = prepareRevisions(type.metaObject, added);
if (type.attachedPropertiesMetaObject)
revisions += availableRevisions(type.attachedPropertiesMetaObject);
+ uniqueRevisions(&revisions, type.version, added);
- std::sort(revisions.begin(), revisions.end());
- const auto it = std::unique(revisions.begin(), revisions.end());
- revisions.erase(it, revisions.end());
-
- const bool typeWasRemoved = removed >= added;
- for (int revision : revisions) {
+ for (QTypeRevision revision : revisions) {
if (revision < added)
continue;
// When removed, we still add revisions, but anonymous ones
- if (typeWasRemoved && revision >= removed) {
+ if (removed.isValid() && !(revision < removed)) {
revisionRegistration.elementName = nullptr;
revisionRegistration.create = nullptr;
} else {
@@ -205,12 +256,11 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
revisionRegistration.create = creatable ? type.create : nullptr;
}
- // Equivalent of qmlRegisterRevision<T, revision>(...)
- revisionRegistration.versionMinor = revision;
- revisionRegistration.revision = revision;
+ assignVersions(&revisionRegistration, revision, type.version);
revisionRegistration.customParser = type.customParserFactory();
-
- qmlregister(TypeRegistration, &revisionRegistration);
+ const int id = qmlregister(TypeRegistration, &revisionRegistration);
+ if (type.qmlTypeIds)
+ type.qmlTypeIds->append(id);
}
break;
}
@@ -219,52 +269,43 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
= *reinterpret_cast<RegisterSingletonTypeAndRevisions *>(data);
const char *elementName = classElementName(type.classInfoMetaObject);
RegisterSingletonType revisionRegistration = {
- QmlCurrentSingletonTypeRegistrationVersion,
+ 0,
type.uri,
- type.versionMajor,
- -1,
+ type.version,
elementName,
-
- type.scriptApi,
nullptr,
+ type.qObjectApi,
type.instanceMetaObject,
type.typeId,
- -1,
-
- type.generalizedQobjectApi
+ QTypeRevision()
};
- const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0);
- const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1);
+ const QTypeRevision added = revisionClassInfo(
+ type.classInfoMetaObject, "QML.AddedInVersion",
+ QTypeRevision::fromMinorVersion(0));
+ const QTypeRevision removed = revisionClassInfo(
+ type.classInfoMetaObject, "QML.RemovedInVersion");
- auto revisions = availableRevisions(type.instanceMetaObject);
- revisions.append(qMax(added, 0));
+ auto revisions = prepareRevisions(type.instanceMetaObject, added);
+ uniqueRevisions(&revisions, type.version, added);
- std::sort(revisions.begin(), revisions.end());
- const auto it = std::unique(revisions.begin(), revisions.end());
- revisions.erase(it, revisions.end());
-
- const bool typeWasRemoved = removed >= added;
- for (int revision : qAsConst(revisions)) {
+ for (QTypeRevision revision : qAsConst(revisions)) {
if (revision < added)
continue;
// When removed, we still add revisions, but anonymous ones
- if (typeWasRemoved && revision >= removed) {
+ if (removed.isValid() && !(revision < removed)) {
revisionRegistration.typeName = nullptr;
- revisionRegistration.scriptApi = nullptr;
- revisionRegistration.generalizedQobjectApi = nullptr;
+ revisionRegistration.qObjectApi = nullptr;
} else {
revisionRegistration.typeName = elementName;
- revisionRegistration.scriptApi = type.scriptApi;
- revisionRegistration.generalizedQobjectApi = type.generalizedQobjectApi;
+ revisionRegistration.qObjectApi = type.qObjectApi;
}
- // Equivalent of qmlRegisterRevision<T, revision>(...)
- revisionRegistration.versionMinor = revision;
- revisionRegistration.revision = revision;
-
- qmlregister(SingletonRegistration, &revisionRegistration);
+ assignVersions(&revisionRegistration, revision, type.version);
+ const int id = qmlregister(SingletonRegistration, &revisionRegistration);
+ if (type.qmlTypeIds)
+ type.qmlTypeIds->append(id);
}
break;
}
@@ -325,21 +366,20 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
namespace QQmlPrivate {
template<>
void qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
- const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject)
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds)
{
using T = QQmlTypeNotAvailable;
- QML_GETTYPENAMES
-
RegisterTypeAndRevisions type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T>>(),
0,
nullptr,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
&QQmlTypeNotAvailable::staticMetaObject,
classInfoMetaObject,
@@ -351,7 +391,7 @@ namespace QQmlPrivate {
StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
- nullptr, nullptr, qmlCreateCustomParser<T>
+ nullptr, nullptr, qmlCreateCustomParser<T>, qmlTypeIds
};
qmlregister(TypeAndRevisionsRegistration, &type);
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 5ea1d17478..9c896e6322 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -44,6 +44,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qversionnumber.h>
#define QML_VERSION 0x020000
#define QML_VERSION_STR "2.0"
@@ -76,6 +77,10 @@
#define QML_NAMED_ELEMENT(NAME) \
Q_CLASSINFO("QML.Element", #NAME)
+#define QML_VALUE_TYPE(NAME) \
+ Q_CLASSINFO("QML.Element", #NAME) \
+ QML_UNCREATABLE("Value types cannot be created.")
+
#define QML_UNCREATABLE(REASON) \
Q_CLASSINFO("QML.Creatable", "false") \
Q_CLASSINFO("QML.UncreatableReason", REASON)
@@ -85,13 +90,19 @@
enum class QmlIsSingleton {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
template<typename T, typename... Args> \
- friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QVector<int> *);
#define QML_ADDED_IN_MINOR_VERSION(VERSION) \
- Q_CLASSINFO("QML.AddedInMinorVersion", #VERSION)
+ Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION))
+
+#define QML_ADDED_IN_VERSION(MAJOR, MINOR) \
+ Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_REMOVED_IN_MINOR_VERSION(VERSION) \
- Q_CLASSINFO("QML.RemovedInMinorVersion", #VERSION)
+ Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(VERSION))
+
+#define QML_REMOVED_IN_VERSION(MAJOR, MINOR) \
+ Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(MAJOR, MINOR))
#define QML_ATTACHED(ATTACHED_TYPE) \
Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \
@@ -104,21 +115,21 @@
using QmlExtendedType = EXTENDED_TYPE; \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtended; \
template<typename T, typename... Args> \
- friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QVector<int> *);
#define QML_FOREIGN(FOREIGN_TYPE) \
Q_CLASSINFO("QML.Foreign", #FOREIGN_TYPE) \
using QmlForeignType = FOREIGN_TYPE; \
template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlResolved; \
template<typename T, typename... Args> \
- friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QVector<int> *);
#define QML_INTERFACE \
Q_CLASSINFO("QML.Element", "anonymous") \
enum class QmlIsInterface {yes = true}; \
template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
template<typename T, typename... Args> \
- friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QVector<int> *);
#define QML_UNAVAILABLE \
QML_FOREIGN(QQmlTypeNotAvailable)
@@ -149,18 +160,16 @@ QQmlCustomParser *qmlCreateCustomParser();
template<typename T>
int qmlRegisterAnonymousType(const char *uri, int versionMajor)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
0,
nullptr,
QString(),
- uri, versionMajor, 0, nullptr, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -172,7 +181,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor)
nullptr, nullptr,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -192,18 +201,16 @@ int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor,
template<typename T>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T>>(),
0,
nullptr,
reason,
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -215,7 +222,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
nullptr, nullptr,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -224,18 +231,16 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
template<typename T, int metaObjectRevision>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
0,
nullptr,
reason,
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -247,7 +252,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
nullptr, nullptr,
nullptr,
- metaObjectRevision
+ QTypeRevision::fromMinorVersion(metaObjectRevision)
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -256,8 +261,6 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
template<typename T, typename E>
int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
{
- QML_GETTYPENAMES
-
QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
if (!attached) {
@@ -268,13 +271,13 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
0,
nullptr,
reason,
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
attached,
attachedMetaObject,
@@ -286,7 +289,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::createParent<E>, &E::staticMetaObject,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -295,8 +298,6 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
template<typename T, typename E, int metaObjectRevision>
int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
{
- QML_GETTYPENAMES
-
QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
if (!attached) {
@@ -305,15 +306,15 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
}
QQmlPrivate::RegisterType type = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
0,
nullptr,
reason,
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
attached,
attachedMetaObject,
@@ -325,7 +326,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::createParent<E>, &E::staticMetaObject,
nullptr,
- metaObjectRevision
+ QTypeRevision::fromMinorVersion(metaObjectRevision)
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -336,17 +337,15 @@ Q_QML_EXPORT int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaO
template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -358,7 +357,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
nullptr, nullptr,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -367,17 +366,15 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
template<typename T, int metaObjectRevision>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -389,7 +386,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
nullptr, nullptr,
nullptr,
- metaObjectRevision
+ QTypeRevision::fromMinorVersion(metaObjectRevision)
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -398,17 +395,15 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
template<typename T, int metaObjectRevision>
int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -420,7 +415,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
nullptr, nullptr,
nullptr,
- metaObjectRevision
+ QTypeRevision::fromMinorVersion(metaObjectRevision)
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -429,18 +424,16 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
template<typename T, typename E>
int qmlRegisterExtendedType(const char *uri, int versionMajor)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
0,
nullptr,
QString(),
- uri, versionMajor, 0, nullptr, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -452,7 +445,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor)
QQmlPrivate::createParent<E>, &E::staticMetaObject,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -471,8 +464,6 @@ template<typename T, typename E>
int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName)
{
- QML_GETTYPENAMES
-
QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
if (!attached) {
@@ -483,12 +474,12 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
attached,
attachedMetaObject,
@@ -500,7 +491,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::createParent<E>, &E::staticMetaObject,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -517,14 +508,14 @@ int qmlRegisterInterface(const char *typeName)
QByteArray listName("QQmlListProperty<" + name + '>');
QQmlPrivate::RegisterInterface qmlInterface = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
qobject_interface_iid<T *>(),
"",
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
@@ -534,16 +525,14 @@ int qmlRegisterInterface(const char *typeName)
template<typename T>
int qmlRegisterInterface(const char *uri, int versionMajor)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterInterface qmlInterface = {
- 1,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T>>(listName.constData()),
+ 0,
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
qobject_interface_iid<T *>(),
uri,
- versionMajor
+ QTypeRevision::fromVersion(versionMajor, 0)
};
return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
@@ -553,17 +542,15 @@ template<typename T>
int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName, QQmlCustomParser *parser)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -575,7 +562,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
nullptr, nullptr,
parser,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -585,17 +572,15 @@ template<typename T, int metaObjectRevision>
int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName, QQmlCustomParser *parser)
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterType type = {
- 1,
+ 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -607,7 +592,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
nullptr, nullptr,
parser,
- metaObjectRevision
+ QTypeRevision::fromMinorVersion(metaObjectRevision)
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -617,8 +602,6 @@ template<typename T, typename E>
int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName, QQmlCustomParser *parser)
{
- QML_GETTYPENAMES
-
QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
if (!attached) {
@@ -629,12 +612,12 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T *>(),
+ QMetaType::fromType<QQmlListProperty<T> >(),
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
attached,
attachedMetaObject,
@@ -646,7 +629,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version
QQmlPrivate::createParent<E>, &E::staticMetaObject,
parser,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -709,27 +692,29 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
QQmlPrivate::RegisterSingletonType api = {
0,
- uri, versionMajor, versionMinor, typeName,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName,
- callback, nullptr, nullptr, 0, 0, {}
+ callback, nullptr, nullptr, QMetaType(), QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
}
-enum { QmlCurrentSingletonTypeRegistrationVersion = 3 };
template <typename T>
-inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
- QObject *(*callback)(QQmlEngine *, QJSEngine *))
+inline int qmlRegisterSingletonType(
+ const char *uri, int versionMajor, int versionMinor, const char *typeName,
+ QObject *(*callback)(QQmlEngine *, QJSEngine *))
{
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterSingletonType api = {
- QmlCurrentSingletonTypeRegistrationVersion,
-
- uri, versionMajor, versionMinor, typeName,
-
- nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
+ 0,
+ uri,
+ QTypeRevision::fromVersion(versionMajor, versionMinor),
+ typeName,
+ nullptr,
+ callback,
+ &T::staticMetaObject,
+ QMetaType::fromType<T *>(),
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
@@ -745,15 +730,16 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
F&& callback)
#endif
{
-
- QML_GETTYPENAMES
-
QQmlPrivate::RegisterSingletonType api = {
- QmlCurrentSingletonTypeRegistrationVersion,
-
- uri, versionMajor, versionMinor, typeName,
-
- nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
+ 0,
+ uri,
+ QTypeRevision::fromVersion(versionMajor, versionMinor),
+ typeName,
+ nullptr,
+ callback,
+ &T::staticMetaObject,
+ QMetaType::fromType<T *>(),
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
@@ -767,7 +753,7 @@ inline auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int
const char *typeName, T *cppObject) -> typename std::enable_if<std::is_base_of<QObject, T>::value, int>::type
#endif
{
- QQmlPrivate::RegisterSingletonFunctor registrationFunctor;
+ QQmlPrivate::SingletonFunctor registrationFunctor;
registrationFunctor.m_object = cppObject;
return qmlRegisterSingletonType<T>(uri, versionMajor, versionMinor, typeName, registrationFunctor);
}
@@ -781,10 +767,10 @@ inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versio
}
QQmlPrivate::RegisterCompositeSingletonType type = {
+ 0,
url,
uri,
- versionMajor,
- versionMinor,
+ QTypeRevision::fromVersion(versionMajor, versionMinor),
qmlName
};
@@ -800,10 +786,10 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i
}
QQmlPrivate::RegisterCompositeType type = {
+ 0,
url,
uri,
- versionMajor,
- versionMinor,
+ QTypeRevision::fromVersion(versionMajor, versionMinor),
qmlName
};
@@ -815,60 +801,67 @@ struct QmlTypeAndRevisionsRegistration;
template<class T, class Resolved, class Extended>
struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
- static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ static void registerTypeAndRevisions(const char *uri, int versionMajor,
+ QVector<int> *qmlTypeIds)
{
QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
- uri, versionMajor, &T::staticMetaObject);
+ uri, versionMajor, &T::staticMetaObject, qmlTypeIds);
}
};
template<class T, class Resolved>
struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true, false> {
- static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ static void registerTypeAndRevisions(const char *uri, int versionMajor,
+ QVector<int> *qmlTypeIds)
{
QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved>(
- uri, versionMajor, &T::staticMetaObject);
+ uri, versionMajor, &T::staticMetaObject, qmlTypeIds);
}
};
template<class T, class Resolved>
struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> {
- static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ static void registerTypeAndRevisions(const char *uri, int versionMajor,
+ QVector<int> *qmlTypeIds)
{
- qmlRegisterInterface<Resolved>(uri, versionMajor);
+ const int id = qmlRegisterInterface<Resolved>(uri, versionMajor);
+ if (qmlTypeIds)
+ qmlTypeIds->append(id);
}
};
template<typename T = void, typename... Args>
-void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor);
+void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor,
+ QVector<int> *qmlTypeIds = nullptr);
template<typename T, typename... Args>
-void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor)
+void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QVector<int> *qmlTypeIds)
{
QmlTypeAndRevisionsRegistration<
T, typename QQmlPrivate::QmlResolved<T>::Type,
typename QQmlPrivate::QmlExtended<T>::Type,
QQmlPrivate::QmlSingleton<T>::Value,
QQmlPrivate::QmlInterface<T>::Value>
- ::registerTypeAndRevisions(uri, versionMajor);
- qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor);
+ ::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds);
+ qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor, qmlTypeIds);
}
template<>
-inline void qmlRegisterTypesAndRevisions<>(const char *, int) {}
+inline void qmlRegisterTypesAndRevisions<>(const char *, int, QVector<int> *) {}
inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
- const char *uri, int versionMajor)
+ const char *uri, int versionMajor,
+ QVector<int> *qmlTypeIds = nullptr)
{
QQmlPrivate::RegisterTypeAndRevisions type = {
0,
- 0,
- 0,
+ QMetaType(),
+ QMetaType(),
0,
nullptr,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
metaObject,
metaObject,
@@ -883,7 +876,8 @@ inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
nullptr,
nullptr,
- &qmlCreateCustomParser<void>
+ &qmlCreateCustomParser<void>,
+ qmlTypeIds
};
qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type);
@@ -893,7 +887,4 @@ int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor,
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QObject)
-Q_DECLARE_METATYPE(QVariant)
-
#endif // QQML_H
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h
index fc53be3e7b..96bb0da269 100644
--- a/src/qml/qml/qqmlabstractbinding_p.h
+++ b/src/qml/qml/qqmlabstractbinding_p.h
@@ -92,7 +92,7 @@ public:
inline QQmlAbstractBinding *nextBinding() const;
inline bool canUseAccessor() const
- { return m_nextBinding.flag2(); }
+ { return m_nextBinding.tag().testFlag(CanUseAccessor); }
struct RefCount {
RefCount() {}
@@ -103,6 +103,20 @@ public:
};
RefCount ref;
+ enum TargetTag {
+ NoTargetTag = 0x0,
+ UpdatingBinding = 0x1,
+ BindingEnabled = 0x2
+ };
+ Q_DECLARE_FLAGS(TargetTags, TargetTag)
+
+ enum NextBindingTag {
+ NoBindingTag = 0x0,
+ AddedToObject = 0x1,
+ CanUseAccessor = 0x2
+ };
+ Q_DECLARE_FLAGS(NextBindingTags, NextBindingTag)
+
protected:
friend class QQmlData;
friend class QQmlValueTypeProxyBinding;
@@ -116,24 +130,23 @@ protected:
QQmlPropertyIndex m_targetIndex;
// Pointer is the target object to which the binding binds
- // flag1 is the updating flag
- // flag2 is the enabled flag
- QFlagPointer<QObject> m_target;
+ QTaggedPointer<QObject, TargetTags> m_target;
// Pointer to the next binding in the linked list of bindings.
- // flag1 is used for addedToObject
- // flag2 indicates if an accessor is can be used (i.e. there is no interceptor on the target)
- QFlagPointer<QQmlAbstractBinding> m_nextBinding;
+ QTaggedPointer<QQmlAbstractBinding, NextBindingTags> m_nextBinding;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::TargetTags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::NextBindingTags)
+
void QQmlAbstractBinding::setAddedToObject(bool v)
{
- m_nextBinding.setFlagValue(v);
+ m_nextBinding.setTag(m_nextBinding.tag().setFlag(AddedToObject, v));
}
bool QQmlAbstractBinding::isAddedToObject() const
{
- return m_nextBinding.flag();
+ return m_nextBinding.tag().testFlag(AddedToObject);
}
QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 6ee03b39e5..01670b91d3 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -81,7 +81,8 @@ void QQmlApplicationEnginePrivate::init()
else
delete qtTranslator;
#endif
- new QQmlFileSelector(q,q);
+ auto *selector = new QQmlFileSelector(q,q);
+ selector->setExtraSelectors(extraFileSelectors);
QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
}
@@ -94,7 +95,7 @@ void QQmlApplicationEnginePrivate::_q_loadTranslations()
Q_Q(QQmlApplicationEngine);
QScopedPointer<QTranslator> translator(new QTranslator);
- if (!uiLanguage.isEmpty()) {
+ if (!uiLanguage.value().isEmpty()) {
QLocale locale(uiLanguage);
if (translator->load(locale, QLatin1String("qml"), QLatin1String("_"), translationsDirectory, QLatin1String(".qm"))) {
if (activeTranslator)
@@ -113,6 +114,11 @@ void QQmlApplicationEnginePrivate::startLoad(const QUrl &url, const QByteArray &
{
Q_Q(QQmlApplicationEngine);
+ if (!isInitialized) {
+ init();
+ isInitialized = true;
+ }
+
if (url.scheme() == QLatin1String("file") || url.scheme() == QLatin1String("qrc")) {
QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(url));
translationsDirectory = fi.path() + QLatin1String("/i18n");
@@ -225,8 +231,6 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent)
: QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent)
{
- Q_D(QQmlApplicationEngine);
- d->init();
QJSEnginePrivate::addToDebugServer(this);
}
@@ -297,6 +301,17 @@ void QQmlApplicationEngine::load(const QString &filePath)
Sets the \a initialProperties with which the QML component gets initialized after
it gets loaded.
+ \code
+ QQmlApplicationEngine engine;
+
+ EventDatabase eventDatabase;
+ EventMonitor eventMonitor;
+
+ engine.setInitialProperties({
+ { "eventDatabase", QVariant::fromValue(&eventDatabase) },
+ { "eventMonitor", QVariant::fromValue(&eventMonitor) }
+ });
+ \endcode
\sa QQmlComponent::setInitialProperties
\sa QQmlApplicationEngine::load
@@ -310,6 +325,26 @@ void QQmlApplicationEngine::setInitialProperties(const QVariantMap &initialPrope
}
/*!
+ Sets the \a extraFileSelectors to be passed to the internal QQmlFileSelector
+ used for resolving URLs to local files. The \a extraFileSelectors are applied
+ when the first QML file is loaded. Setting them afterwards has no effect.
+
+ \sa QQmlFileSelector
+ \sa QFileSelector::setExtraSelectors
+ \since 6.0
+*/
+void QQmlApplicationEngine::setExtraFileSelectors(const QStringList &extraFileSelectors)
+{
+ Q_D(QQmlApplicationEngine);
+ if (d->isInitialized) {
+ qWarning() << "QQmlApplicationEngine::setExtraFileSelectors()"
+ << "called after loading QML files. This has no effect.";
+ } else {
+ d->extraFileSelectors = extraFileSelectors;
+ }
+}
+
+/*!
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 37f75d5068..7faa51892e 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -67,6 +67,7 @@ public Q_SLOTS:
void load(const QUrl &url);
void load(const QString &filePath);
void setInitialProperties(const QVariantMap &initialProperties);
+ void setExtraFileSelectors(const QStringList &extraFileSelectors);
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 86f492510f..4568f7cfbb 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -74,9 +74,11 @@ public:
void finishLoad(QQmlComponent *component);
QList<QObject *> objects;
QVariantMap initialProperties;
+ QStringList extraFileSelectors;
QString translationsDirectory;
#if QT_CONFIG(translation)
QScopedPointer<QTranslator> activeTranslator;
+ bool isInitialized = false;
#endif
};
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index b9566d5862..7de94fe3d5 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -57,6 +57,7 @@
#include <private/qv4qobjectwrapper_p.h>
#include <private/qv4variantobject_p.h>
#include <private/qv4jscall_p.h>
+#include <private/qjsvalue_p.h>
#include <qtqml_tracepoints_p.h>
@@ -80,19 +81,19 @@ QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QQmlScr
QString url;
QV4::Function *runtimeFunction = nullptr;
- QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
+ QQmlRefPointer<QQmlContextData> ctxtdata = QQmlContextData::get(scriptPrivate->context);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
- if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit) {
+ if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit()) {
url = ctxtdata->urlString();
if (scriptPrivate->bindingId != QQmlBinding::Invalid)
- runtimeFunction = ctxtdata->typeCompilationUnit->runtimeFunctions.at(scriptPrivate->bindingId);
+ runtimeFunction = ctxtdata->typeCompilationUnit()->runtimeFunctions.at(scriptPrivate->bindingId);
}
b->setNotifyOnValueChanged(true);
b->QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
b->setScopeObject(obj ? obj : scriptPrivate->scope);
- QV4::ExecutionEngine *v4 = b->context()->engine->handle();
+ QV4::ExecutionEngine *v4 = b->engine()->handle();
if (runtimeFunction) {
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxtdata, b->scopeObject()));
@@ -120,8 +121,9 @@ void QQmlBinding::setSourceLocation(const QQmlSourceLocation &location)
}
-QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QString &str, QObject *obj,
- QQmlContextData *ctxt, const QString &url, quint16 lineNumber)
+QQmlBinding *QQmlBinding::create(
+ const QQmlPropertyData *property, const QString &str, QObject *obj,
+ const QQmlRefPointer<QQmlContextData> &ctxt, const QString &url, quint16 lineNumber)
{
QQmlBinding *b = newBinding(QQmlEnginePrivate::get(ctxt), property);
@@ -134,8 +136,9 @@ QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QString
return b;
}
-QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, QV4::Function *function,
- QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope)
+QQmlBinding *QQmlBinding::create(
+ const QQmlPropertyData *property, QV4::Function *function, QObject *obj,
+ const QQmlRefPointer<QQmlContextData> &ctxt, QV4::ExecutionContext *scope)
{
QQmlBinding *b = newBinding(QQmlEnginePrivate::get(ctxt), property);
@@ -154,14 +157,9 @@ QQmlBinding::~QQmlBinding()
delete m_sourceLocation;
}
-void QQmlBinding::setNotifyOnValueChanged(bool v)
-{
- QQmlJavaScriptExpression::setNotifyOnValueChanged(v);
-}
-
void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
{
- if (!enabledFlag() || !context() || !context()->isValid())
+ if (!enabledFlag() || !hasValidContext())
return;
// Check that the target has not been deleted
@@ -182,15 +180,15 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
DeleteWatcher watcher(this);
- QQmlEngine *engine = context()->engine;
- QV4::Scope scope(engine->handle());
+ QQmlEngine *qmlEngine = engine();
+ QV4::Scope scope(qmlEngine->handle());
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
Q_TRACE_SCOPE(QQmlBinding, engine, function() ? function()->name()->toQString() : QString(),
sourceLocation().sourceFile, sourceLocation().line, sourceLocation().column);
- QQmlBindingProfiler prof(QQmlEnginePrivate::get(engine)->profiler, function());
+ QQmlBindingProfiler prof(QQmlEnginePrivate::get(qmlEngine)->profiler, function());
doUpdate(watcher, flags, scope);
if (!watcher.wasDeleted())
@@ -199,7 +197,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
QV4::ReturnedValue QQmlBinding::evaluate(bool *isUndefined)
{
- QV4::ExecutionEngine *v4 = context()->engine->handle();
+ QV4::ExecutionEngine *v4 = engine()->handle();
int argc = 0;
const QV4::Value *argv = nullptr;
const QV4::Value *thisObject = nullptr;
@@ -234,7 +232,7 @@ protected:
QQmlPropertyData *pd = nullptr;
getPropertyData(&pd, nullptr);
QQmlBinding *thisPtr = this;
- pd->writeProperty(*m_target, &thisPtr, flags);
+ pd->writeProperty(m_target.data(), &thisPtr, flags);
}
};
@@ -265,7 +263,7 @@ protected:
}
if (hasError()) {
- if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
+ if (!delayedError()->addError(ep)) ep->warning(this->error(engine()));
} else {
clearError();
}
@@ -388,7 +386,10 @@ private:
const QV4::CompiledData::Binding *m_binding;
};
-QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt)
+QQmlBinding *QQmlBinding::createTranslationBinding(
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
+ const QV4::CompiledData::Binding *binding, QObject *obj,
+ const QQmlRefPointer<QQmlContextData> &ctxt)
{
QQmlTranslationBinding *b = new QQmlTranslationBinding(unit, binding);
@@ -409,8 +410,8 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
const QV4::Value &result,
bool isUndefined, QQmlPropertyData::WriteFlags flags)
{
- QQmlEngine *engine = context()->engine;
- QV4::ExecutionEngine *v4engine = engine->handle();
+ QQmlEngine *qmlEngine = engine();
+ QV4::ExecutionEngine *v4engine = qmlEngine->handle();
int type = valueTypeData.isValid() ? valueTypeData.propType() : core.propType();
@@ -455,9 +456,10 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
return false;
}
- QQmlPropertyPrivate::writeValueProperty(m_target.data(), core, valueTypeData, QVariant::fromValue(
- QJSValue(v4engine, result.asReturnedValue())),
- context(), flags);
+ QQmlPropertyPrivate::writeValueProperty(
+ m_target.data(), core, valueTypeData,
+ QVariant::fromValue(QJSValuePrivate::fromReturnedValue(result.asReturnedValue())),
+ context(), flags);
} else if (isUndefined) {
const QLatin1String typeName(QMetaType::typeName(type)
? QMetaType::typeName(type)
@@ -484,7 +486,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (QObject *o = *(QObject *const *)value.constData()) {
valueType = o->metaObject()->className();
- QQmlMetaObject propertyMetaObject = QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate::get(engine), type);
+ QQmlMetaObject propertyMetaObject = QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate::get(qmlEngine), type);
if (!propertyMetaObject.isNull())
propertyType = propertyMetaObject.className();
}
@@ -514,13 +516,13 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
QVariant QQmlBinding::evaluate()
{
- QQmlEngine *engine = context()->engine;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ QQmlEngine *qmlEngine = engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine);
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::Scope scope(engine->handle());
+ QV4::Scope scope(qmlEngine->handle());
QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
ep->dereferenceScarceResources();
@@ -528,18 +530,6 @@ QVariant QQmlBinding::evaluate()
return scope.engine->toVariant(result, qMetaTypeId<QList<QObject*> >());
}
-QString QQmlBinding::expressionIdentifier() const
-{
- if (auto f = function()) {
- QString url = f->sourceFile();
- uint lineNumber = f->compiledFunction->location.line;
- uint columnNumber = f->compiledFunction->location.column;
- return url + QString::asprintf(":%u:%u", lineNumber, columnNumber);
- }
-
- return QStringLiteral("[native code]");
-}
-
void QQmlBinding::expressionChanged()
{
update();
@@ -556,10 +546,10 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags)
setEnabledFlag(e);
setNotifyOnValueChanged(e);
- m_nextBinding.setFlag2(); // Always use accessors, only not when:
+ m_nextBinding.setTag(m_nextBinding.tag().setFlag(CanUseAccessor)); // Always use accessors, only not when:
if (auto interceptorMetaObject = QQmlInterceptorMetaObject::get(targetObject())) {
if (!m_targetIndex.isValid() || interceptorMetaObject->intercepts(m_targetIndex))
- m_nextBinding.clearFlag2();
+ m_nextBinding.setTag(m_nextBinding.tag().setFlag(CanUseAccessor, false));
}
if (e && !wasEnabled)
@@ -616,9 +606,9 @@ bool QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
}
m_targetIndex = QQmlPropertyIndex(coreIndex, valueTypeIndex);
- QQmlData *data = QQmlData::get(*m_target, true);
+ QQmlData *data = QQmlData::get(m_target.data(), true);
if (!data->propertyCache) {
- data->propertyCache = QQmlEnginePrivate::get(context()->engine)->cache(m_target->metaObject());
+ data->propertyCache = QQmlEnginePrivate::get(engine())->cache(m_target->metaObject());
data->propertyCache->addref();
}
@@ -629,11 +619,11 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD
{
Q_ASSERT(propertyData);
- QQmlData *data = QQmlData::get(*m_target, false);
+ QQmlData *data = QQmlData::get(m_target.data(), false);
Q_ASSERT(data);
if (Q_UNLIKELY(!data->propertyCache)) {
- data->propertyCache = QQmlEnginePrivate::get(context()->engine)->cache(m_target->metaObject());
+ data->propertyCache = QQmlEnginePrivate::get(engine())->cache(m_target->metaObject());
data->propertyCache->addref();
}
@@ -720,8 +710,9 @@ protected:
}
} else if (auto variant = result.as<QV4::VariantObject>()) {
QVariant value = variant->d()->data();
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context());
- resultMo = QQmlPropertyPrivate::rawMetaObjectForType(ep, value.userType());
+ QQmlEngine *qmlEngine = engine();
+ resultMo = QQmlPropertyPrivate::rawMetaObjectForType(
+ qmlEngine ? QQmlEnginePrivate::get(qmlEngine) : nullptr, value.userType());
if (resultMo.isNull())
return slowWrite(*pd, vtpd, result, isUndefined, flags);
resultObject = *static_cast<QObject *const *>(value.constData());
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 7f96b4df9f..bf73c24c9e 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -76,19 +76,26 @@ public:
typedef QExplicitlySharedDataPointer<QQmlBinding> Ptr;
static QQmlBinding *create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *);
- static QQmlBinding *create(const QQmlPropertyData *, const QString &, QObject *, QQmlContextData *,
- const QString &url = QString(), quint16 lineNumber = 0);
- static QQmlBinding *create(const QQmlPropertyData *property, QV4::Function *function,
- QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope);
- static QQmlBinding *createTranslationBinding(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, const QV4::CompiledData::Binding *binding,
- QObject *obj, QQmlContextData *ctxt);
+
+ static QQmlBinding *create(
+ const QQmlPropertyData *, const QString &, QObject *,
+ const QQmlRefPointer<QQmlContextData> &, const QString &url = QString(),
+ quint16 lineNumber = 0);
+
+ static QQmlBinding *create(
+ const QQmlPropertyData *property, QV4::Function *function, QObject *obj,
+ const QQmlRefPointer<QQmlContextData> &ctxt, QV4::ExecutionContext *scope);
+
+ static QQmlBinding *createTranslationBinding(
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
+ const QV4::CompiledData::Binding *binding, QObject *obj,
+ const QQmlRefPointer<QQmlContextData> &ctxt);
+
~QQmlBinding() override;
void setTarget(const QQmlProperty &);
bool setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
- void setNotifyOnValueChanged(bool);
-
void refresh() override;
void setEnabled(bool, QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding) override;
@@ -102,7 +109,6 @@ public:
QVariant evaluate();
- QString expressionIdentifier() const override;
void expressionChanged() override;
QQmlSourceLocation sourceLocation() const override;
@@ -147,22 +153,22 @@ private:
bool QQmlBinding::updatingFlag() const
{
- return m_target.flag();
+ return m_target.tag().testFlag(UpdatingBinding);
}
void QQmlBinding::setUpdatingFlag(bool v)
{
- m_target.setFlagValue(v);
+ m_target.setTag(m_target.tag().setFlag(UpdatingBinding, v));
}
bool QQmlBinding::enabledFlag() const
{
- return m_target.flag2();
+ return m_target.tag().testFlag(BindingEnabled);
}
void QQmlBinding::setEnabledFlag(bool v)
{
- m_target.setFlag2Value(v);
+ m_target.setTag(m_target.tag().setFlag(BindingEnabled, v));
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index b347bb3829..e87f691203 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -64,11 +64,10 @@
QT_BEGIN_NAMESPACE
-QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
- QQmlContextData *ctxt, QObject *scope, const QString &expression,
- const QString &fileName, quint16 line, quint16 column,
- const QString &handlerName,
- const QString &parameterString)
+QQmlBoundSignalExpression::QQmlBoundSignalExpression(
+ QObject *target, int index, const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope,
+ const QString &expression, const QString &fileName, quint16 line, quint16 column,
+ const QString &handlerName, const QString &parameterString)
: QQmlJavaScriptExpression(),
m_index(index),
m_target(target)
@@ -105,8 +104,9 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
setupFunction(context, f->function());
}
-QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scopeObject,
- QV4::Function *function, QV4::ExecutionContext *scope)
+QQmlBoundSignalExpression::QQmlBoundSignalExpression(
+ QObject *target, int index, const QQmlRefPointer<QQmlContextData> &ctxt,
+ QObject *scopeObject, QV4::Function *function, QV4::ExecutionContext *scope)
: QQmlJavaScriptExpression(),
m_index(index),
m_target(target)
@@ -114,7 +114,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
// It's important to call init first, because m_index gets remapped in case of cloned signals.
init(ctxt, scopeObject);
- QV4::ExecutionEngine *engine = ctxt->engine->handle();
+ QV4::ExecutionEngine *engine = ctxt->engine()->handle();
// If the function is marked as having a nested function, then the user wrote:
// onSomeSignal: function() { /*....*/ }
@@ -141,7 +141,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
setupFunction(qmlContext, function);
}
-void QQmlBoundSignalExpression::init(QQmlContextData *ctxt, QObject *scope)
+void QQmlBoundSignalExpression::init(const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope)
{
setNotifyOnValueChanged(false);
setContext(ctxt);
@@ -177,7 +177,7 @@ QString QQmlBoundSignalExpression::expression() const
// Changes made here may need to be made there and vice versa.
void QQmlBoundSignalExpression::evaluate(void **a)
{
- Q_ASSERT (context() && engine());
+ Q_ASSERT (engine());
if (!expressionFunctionValid())
return;
@@ -202,10 +202,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == qMetaTypeId<QJSValue>()) {
- if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &jsCall->args[ii]))
- jsCall->args[ii] = *v4Value;
- else
- jsCall->args[ii] = QV4::Encode::undefined();
+ jsCall->args[ii] = QJSValuePrivate::asReturnedValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
} else if (type == QMetaType::QVariant) {
jsCall->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
@@ -228,7 +225,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
{
- Q_ASSERT (context() && engine());
+ Q_ASSERT (engine());
if (!expressionFunctionValid())
return;
@@ -411,4 +408,13 @@ QQmlBoundSignalExpressionPointer &QQmlBoundSignalExpressionPointer::take(QQmlBou
return *this;
}
+QQmlPropertyObserver::QQmlPropertyObserver(QQmlBoundSignalExpression *expr)
+ : QPropertyObserver([](QPropertyObserver *self, void *) {
+ auto This = static_cast<QQmlPropertyObserver*>(self);
+ This->expression->evaluate(QList<QVariant>());
+ })
+{
+ expression.take(expr);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index d1ec67210e..71a3e90b7f 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -66,15 +66,14 @@ QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QQmlBoundSignalExpression : public QQmlJavaScriptExpression, public QQmlRefCount
{
public:
- QQmlBoundSignalExpression(QObject *target, int index,
- QQmlContextData *ctxt, QObject *scope, const QString &expression,
- const QString &fileName, quint16 line, quint16 column,
- const QString &handlerName = QString(),
- const QString &parameterString = QString());
+ QQmlBoundSignalExpression(
+ QObject *target, int index, const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope,
+ const QString &expression, const QString &fileName, quint16 line, quint16 column,
+ const QString &handlerName = QString(), const QString &parameterString = QString());
- QQmlBoundSignalExpression(QObject *target, int index,
- QQmlContextData *ctxt, QObject *scopeObject, QV4::Function *function,
- QV4::ExecutionContext *scope = nullptr);
+ QQmlBoundSignalExpression(
+ QObject *target, int index, const QQmlRefPointer<QQmlContextData> &ctxt,
+ QObject *scopeObject, QV4::Function *function, QV4::ExecutionContext *scope = nullptr);
// inherited from QQmlJavaScriptExpression.
QString expressionIdentifier() const override;
@@ -87,12 +86,10 @@ public:
QString expression() const;
QObject *target() const { return m_target; }
- QQmlEngine *engine() const { return context() ? context()->engine : nullptr; }
-
private:
~QQmlBoundSignalExpression() override;
- void init(QQmlContextData *ctxt, QObject *scope);
+ void init(const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope);
bool expressionFunctionValid() const { return function() != nullptr; }
@@ -129,6 +126,15 @@ private:
QQmlBoundSignalExpressionPointer m_expression;
};
+class QQmlPropertyObserver : public QPropertyObserver
+{
+public:
+ QQmlPropertyObserver(QQmlBoundSignalExpression *expr);
+
+private:
+ QQmlBoundSignalExpressionPointer expression;
+};
+
QT_END_NAMESPACE
#endif // QQMLBOUNDSIGNAL_P_H
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 9ee4fdbe41..64e2c9a90e 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -521,6 +521,10 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, QObject *parent)
{
Q_D(QQmlComponent);
d->engine = engine;
+ QObject::connect(engine, &QObject::destroyed, this, [d]() {
+ d->state.creator.reset();
+ d->engine = nullptr;
+ });
}
/*!
@@ -635,7 +639,7 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url)
QQmlContext *QQmlComponent::creationContext() const
{
Q_D(const QQmlComponent);
- if(d->creationContext)
+ if (!d->creationContext.isNull())
return d->creationContext->asQQmlContext();
return qmlContext(this);
@@ -879,15 +883,11 @@ QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialPr
QObject *QQmlComponent::beginCreate(QQmlContext *publicContext)
{
Q_D(QQmlComponent);
-
Q_ASSERT(publicContext);
- QQmlContextData *context = QQmlContextData::get(publicContext);
-
- return d->beginCreate(context);
+ return d->beginCreate(QQmlContextData::get(publicContext));
}
-QObject *
-QQmlComponentPrivate::beginCreate(QQmlContextData *context)
+QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> context)
{
Q_Q(QQmlComponent);
if (!context) {
@@ -900,7 +900,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
return nullptr;
}
- if (context->engine != engine) {
+ if (context->engine() != engine) {
qWarning("QQmlComponent: Must create component in context from the same QQmlEngine");
return nullptr;
}
@@ -930,7 +930,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
enginePriv->referenceScarceResources();
QObject *rv = nullptr;
- state.creator.reset(new QQmlObjectCreator(context, compilationUnit, creationContext));
+ state.creator.reset(new QQmlObjectCreator(std::move(context), compilationUnit, creationContext));
rv = state.creator->create(start);
if (!rv)
state.errors = state.creator->errors;
@@ -963,8 +963,9 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
ConstructionState *state = new ConstructionState;
state->completePending = true;
- QQmlContextData *creationContext = nullptr;
- state->creator.reset(new QQmlObjectCreator(deferredData->context->parent, deferredData->compilationUnit, creationContext));
+ state->creator.reset(new QQmlObjectCreator(
+ deferredData->context->parent(), deferredData->compilationUnit,
+ QQmlRefPointer<QQmlContextData>()));
if (!state->creator->populateDeferredProperties(object, deferredData))
state->errors << state->creator->errors;
@@ -1082,16 +1083,16 @@ void QQmlComponentPrivate::completeCreate()
}
QQmlComponentAttached::QQmlComponentAttached(QObject *parent)
-: QObject(parent), prev(nullptr), next(nullptr)
+: QObject(parent), m_prev(nullptr), m_next(nullptr)
{
}
QQmlComponentAttached::~QQmlComponentAttached()
{
- if (prev) *prev = next;
- if (next) next->prev = prev;
- prev = nullptr;
- next = nullptr;
+ if (m_prev) *m_prev = m_next;
+ if (m_next) m_next->m_prev = m_prev;
+ m_prev = nullptr;
+ m_next = nullptr;
}
/*!
@@ -1107,12 +1108,12 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj)
QQmlEnginePrivate *p = QQmlEnginePrivate::get(engine);
if (p->activeObjectCreator) { // XXX should only be allowed during begin
- a->add(p->activeObjectCreator->componentAttachment());
+ a->insertIntoList(p->activeObjectCreator->componentAttachment());
} else {
QQmlData *d = QQmlData::get(obj);
Q_ASSERT(d);
Q_ASSERT(d->context);
- a->add(&d->context->componentAttached);
+ d->context->addComponentAttached(a);
}
return a;
@@ -1138,24 +1139,23 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj)
\sa QQmlIncubator
*/
-void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
- QQmlContext *forContext)
+void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, QQmlContext *forContext)
{
Q_D(QQmlComponent);
if (!context)
context = d->engine->rootContext();
- QQmlContextData *contextData = QQmlContextData::get(context);
- QQmlContextData *forContextData = contextData;
- if (forContext) forContextData = QQmlContextData::get(forContext);
+ QQmlRefPointer<QQmlContextData> contextData = QQmlContextData::get(context);
+ QQmlRefPointer<QQmlContextData> forContextData =
+ forContext ? QQmlContextData::get(forContext) : contextData;
if (!contextData->isValid()) {
qWarning("QQmlComponent: Cannot create a component in an invalid context");
return;
}
- if (contextData->engine != d->engine) {
+ if (contextData->engine() != d->engine) {
qWarning("QQmlComponent: Must create component in context from the same QQmlEngine");
return;
}
@@ -1209,8 +1209,8 @@ void QQmlComponentPrivate::incubateObject(
QQmlIncubator *incubationTask,
QQmlComponent *component,
QQmlEngine *engine,
- QQmlContextData *context,
- QQmlContextData *forContext)
+ const QQmlRefPointer<QQmlContextData> &context,
+ const QQmlRefPointer<QQmlContextData> &forContext)
{
QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask);
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index cb5d5a787c..9a4ea711f3 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -71,6 +71,7 @@ class Q_QML_EXPORT QQmlComponent : public QObject
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QUrl url READ url CONSTANT)
QML_NAMED_ELEMENT(Component)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQmlComponentAttached)
Q_CLASSINFO("QML.Builtin", "QML")
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index a919eb45c0..cc938371a1 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -61,6 +61,7 @@
#include "qqml.h"
#include <private/qqmlobjectcreator_p.h>
#include <private/qqmltypedata_p.h>
+#include <private/qqmlguardedcontextdata_p.h>
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -84,7 +85,7 @@ public:
void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous);
- QObject *beginCreate(QQmlContextData *);
+ QObject *beginCreate(QQmlRefPointer<QQmlContextData>);
void completeCreate();
void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate, RequiredProperties &requiredProperties);
static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent);
@@ -94,8 +95,8 @@ public:
QQmlIncubator *incubationTask,
QQmlComponent *component,
QQmlEngine *engine,
- QQmlContextData *context,
- QQmlContextData *forContext);
+ const QQmlRefPointer<QQmlContextData> &context,
+ const QQmlRefPointer<QQmlContextData> &forContext);
QQmlRefPointer<QQmlTypeData> typeData;
void typeDataReady(QQmlTypeData *) override;
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index 8ecd9da17d..b94d474d1f 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -66,28 +66,38 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject
// when registering QQmlComponent, but we cannot #include it from qqmlcomponent.h. Therefore we
// force an anonymous type registration here.
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlComponentAttached(QObject *parent = nullptr);
~QQmlComponentAttached();
- void add(QQmlComponentAttached **a) {
- prev = a; next = *a; *a = this;
- if (next) next->prev = &next;
+ void insertIntoList(QQmlComponentAttached **listHead)
+ {
+ m_prev = listHead;
+ m_next = *listHead;
+ *listHead = this;
+ if (m_next)
+ m_next->m_prev = &m_next;
}
- void rem() {
- if (next) next->prev = prev;
- *prev = next;
- next = nullptr; prev = nullptr;
+
+ void removeFromList()
+ {
+ *m_prev = m_next;
+ if (m_next)
+ m_next->m_prev = m_prev;
+ m_next = nullptr;
+ m_prev = nullptr;
}
- QQmlComponentAttached **prev;
- QQmlComponentAttached *next;
+
+ QQmlComponentAttached *next() const { return m_next; }
Q_SIGNALS:
void completed();
void destruction();
private:
- friend class QQmlContextData;
+ QQmlComponentAttached **m_prev;
+ QQmlComponentAttached *m_next;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 9157bb95c3..a67eeeecc9 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -55,11 +55,6 @@
QT_BEGIN_NAMESPACE
-QQmlContextPrivate::QQmlContextPrivate()
-: data(nullptr), notifyIndex(-1)
-{
-}
-
/*!
\class QQmlContext
\brief The QQmlContext class defines a context within a QML engine.
@@ -157,13 +152,8 @@ QQmlContextPrivate::QQmlContextPrivate()
/*! \internal */
QQmlContext::QQmlContext(QQmlEngine *e, bool)
-: QObject(*(new QQmlContextPrivate))
+ : QObject(*(new QQmlContextPrivate(this, nullptr, e)))
{
- Q_D(QQmlContext);
- d->data = new QQmlContextData(this);
- ++d->data->refCount;
-
- d->data->engine = e;
}
/*!
@@ -171,13 +161,10 @@ QQmlContext::QQmlContext(QQmlEngine *e, bool)
QObject \a parent.
*/
QQmlContext::QQmlContext(QQmlEngine *engine, QObject *parent)
-: QObject(*(new QQmlContextPrivate), parent)
+ : QObject(*(new QQmlContextPrivate(
+ this, engine ? QQmlContextData::get(engine->rootContext()).data() : nullptr)),
+ parent)
{
- Q_D(QQmlContext);
- d->data = new QQmlContextData(this);
- ++d->data->refCount;
-
- d->data->setParent(engine?QQmlContextData::get(engine->rootContext()):nullptr);
}
/*!
@@ -185,24 +172,18 @@ QQmlContext::QQmlContext(QQmlEngine *engine, QObject *parent)
QObject \a parent.
*/
QQmlContext::QQmlContext(QQmlContext *parentContext, QObject *parent)
-: QObject(*(new QQmlContextPrivate), parent)
+ : QObject(*(new QQmlContextPrivate(
+ this, parentContext ? QQmlContextData::get(parentContext).data() : nullptr)),
+ parent)
{
- Q_D(QQmlContext);
- d->data = new QQmlContextData(this);
- ++d->data->refCount;
-
- d->data->setParent(parentContext?QQmlContextData::get(parentContext):nullptr);
}
/*!
\internal
*/
-QQmlContext::QQmlContext(QQmlContextData *data)
-: QObject(*(new QQmlContextPrivate), nullptr)
+QQmlContext::QQmlContext(QQmlContextPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
{
- Q_D(QQmlContext);
- d->data = data;
- // don't add a refcount here, as the data owns this context
}
/*!
@@ -215,10 +196,7 @@ QQmlContext::QQmlContext(QQmlContextData *data)
QQmlContext::~QQmlContext()
{
Q_D(QQmlContext);
-
- d->data->publicContext = nullptr;
- if (!--d->data->refCount)
- d->data->destroy();
+ d->m_data->clearPublicContext();
}
/*!
@@ -230,7 +208,7 @@ QQmlContext::~QQmlContext()
bool QQmlContext::isValid() const
{
Q_D(const QQmlContext);
- return d->data && d->data->isValid();
+ return d->m_data->isValid();
}
/*!
@@ -240,7 +218,7 @@ bool QQmlContext::isValid() const
QQmlEngine *QQmlContext::engine() const
{
Q_D(const QQmlContext);
- return d->data->engine;
+ return d->m_data->engine();
}
/*!
@@ -250,7 +228,10 @@ QQmlEngine *QQmlContext::engine() const
QQmlContext *QQmlContext::parentContext() const
{
Q_D(const QQmlContext);
- return d->data->parent?d->data->parent->asQQmlContext():nullptr;
+
+ if (QQmlRefPointer<QQmlContextData> parent = d->m_data->parent())
+ return parent->asQQmlContext();
+ return nullptr;
}
/*!
@@ -259,7 +240,7 @@ QQmlContext *QQmlContext::parentContext() const
QObject *QQmlContext::contextObject() const
{
Q_D(const QQmlContext);
- return d->data->contextObject;
+ return d->m_data->contextObject();
}
/*!
@@ -269,19 +250,19 @@ void QQmlContext::setContextObject(QObject *object)
{
Q_D(QQmlContext);
- QQmlContextData *data = d->data;
+ QQmlRefPointer<QQmlContextData> data = d->m_data;
- if (data->isInternal) {
+ if (data->isInternal()) {
qWarning("QQmlContext: Cannot set context object for internal context.");
return;
}
- if (!isValid()) {
+ if (!data->isValid()) {
qWarning("QQmlContext: Cannot set context object on invalid context.");
return;
}
- data->contextObject = object;
+ data->setContextObject(object);
data->refreshExpressions();
}
@@ -291,31 +272,30 @@ void QQmlContext::setContextObject(QObject *object)
void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
{
Q_D(QQmlContext);
- if (d->notifyIndex == -1)
- d->notifyIndex = QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject);
+ if (d->notifyIndex() == -1)
+ d->setNotifyIndex(QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject));
- QQmlContextData *data = d->data;
+ QQmlRefPointer<QQmlContextData> data = d->m_data;
- if (data->isInternal) {
+ if (data->isInternal()) {
qWarning("QQmlContext: Cannot set property on internal context.");
return;
}
- if (!isValid()) {
+ if (!data->isValid()) {
qWarning("QQmlContext: Cannot set property on invalid context.");
return;
}
- QV4::IdentifierHash &properties = data->detachedPropertyNames();
- int idx = properties.value(name);
+ QV4::IdentifierHash *properties = data->detachedPropertyNames();
+ int idx = properties->value(name);
if (idx == -1) {
- properties.add(name, data->idValueCount + d->propertyValues.count());
- d->propertyValues.append(value);
-
+ properties->add(name, data->numIdValues() + d->numPropertyValues());
+ d->appendPropertyValue(value);
data->refreshExpressions();
} else {
- d->propertyValues[idx] = value;
- QMetaObject::activate(this, d->notifyIndex, idx, nullptr);
+ d->setPropertyValue(idx, value);
+ QMetaObject::activate(this, d->notifyIndex(), idx, nullptr);
}
if (auto *obj = qvariant_cast<QObject *>(value)) {
@@ -350,20 +330,15 @@ void QQmlContext::setContextProperties(const QVector<PropertyPair> &properties)
{
Q_D(const QQmlContext);
- QQmlContextData *data = d->data;
-
- QQmlJavaScriptExpression *expressions = data->expressions;
- QQmlContextData *childContexts = data->childContexts;
-
- data->expressions = nullptr;
- data->childContexts = nullptr;
+ QQmlRefPointer<QQmlContextData> data = d->m_data;
+ QQmlJavaScriptExpression *expressions = data->takeExpressions();
+ QQmlRefPointer<QQmlContextData> childContexts = data->takeChildContexts();
for (const auto &property : properties)
setContextProperty(property.name, property.value);
- data->expressions = expressions;
- data->childContexts = childContexts;
-
+ data->setExpressions(expressions);
+ data->setChildContexts(childContexts);
data->refreshExpressions();
}
@@ -389,28 +364,27 @@ QVariant QQmlContext::contextProperty(const QString &name) const
QVariant value;
int idx = -1;
- QQmlContextData *data = d->data;
+ QQmlRefPointer<QQmlContextData> data = d->m_data;
- const QV4::IdentifierHash &properties = data->propertyNames();
+ const QV4::IdentifierHash properties = data->propertyNames();
if (properties.count())
idx = properties.value(name);
if (idx == -1) {
- if (data->contextObject) {
- QObject *obj = data->contextObject;
+ if (QObject *obj = data->contextObject()) {
QQmlPropertyData local;
QQmlPropertyData *property =
- QQmlPropertyCache::property(data->engine, obj, name, data, local);
+ QQmlPropertyCache::property(data->engine(), obj, name, data, local);
if (property) value = obj->metaObject()->property(property->coreIndex()).read(obj);
}
if (!value.isValid() && parentContext())
value = parentContext()->contextProperty(name);
} else {
- if (idx >= d->propertyValues.count())
- value = QVariant::fromValue(data->idValues[idx - d->propertyValues.count()].data());
+ if (idx >= d->numPropertyValues())
+ value = QVariant::fromValue(data->idValue(idx - d->numPropertyValues()));
else
- value = d->propertyValues[idx];
+ value = d->propertyValue(idx);
}
return value;
@@ -427,7 +401,7 @@ QString QQmlContext::nameForObject(QObject *object) const
{
Q_D(const QQmlContext);
- return d->data->findObjectId(object);
+ return d->m_data->findObjectId(object);
}
/*!
@@ -439,38 +413,9 @@ QString QQmlContext::nameForObject(QObject *object) const
QUrl QQmlContext::resolvedUrl(const QUrl &src)
{
Q_D(QQmlContext);
- return d->data->resolvedUrl(src);
-}
-
-QUrl QQmlContextData::resolvedUrl(const QUrl &src)
-{
- QUrl resolved;
- if (src.isRelative() && !src.isEmpty()) {
- QQmlContextData *ctxt = this;
- do {
- if (ctxt->url().isValid())
- break;
- else
- ctxt = ctxt->parent;
- } while (ctxt);
-
- if (ctxt)
- resolved = ctxt->url().resolved(src);
- else if (engine)
- resolved = engine->baseUrl().resolved(src);
- } else {
- resolved = src;
- }
-
- if (resolved.isEmpty()) //relative but no ctxt
- return resolved;
-
- if (engine && engine->urlInterceptor())
- resolved = engine->urlInterceptor()->intercept(resolved, QQmlAbstractUrlInterceptor::UrlString);
- return resolved;
+ return d->m_data->resolvedUrl(src);
}
-
/*!
Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl.
@@ -482,9 +427,8 @@ QUrl QQmlContextData::resolvedUrl(const QUrl &src)
void QQmlContext::setBaseUrl(const QUrl &baseUrl)
{
Q_D(QQmlContext);
-
- d->data->baseUrl = baseUrl;
- d->data->baseUrlString = baseUrl.toString();
+ d->m_data->setBaseUrl(baseUrl);
+ d->m_data->setBaseUrlString(baseUrl.toString());
}
/*!
@@ -494,14 +438,7 @@ void QQmlContext::setBaseUrl(const QUrl &baseUrl)
QUrl QQmlContext::baseUrl() const
{
Q_D(const QQmlContext);
- const QQmlContextData* data = d->data;
- while (data && data->url().isEmpty())
- data = data->parent;
-
- if (data)
- return data->url();
- else
- return QUrl();
+ return d->m_data->baseUrl();
}
int QQmlContextPrivate::context_count(QQmlListProperty<QObject> *prop)
@@ -510,11 +447,10 @@ int QQmlContextPrivate::context_count(QQmlListProperty<QObject> *prop)
QQmlContextPrivate *d = QQmlContextPrivate::get(context);
int contextProperty = (int)(quintptr)prop->data;
- if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
+ if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
return 0;
- } else {
- return ((const QList<QObject> *)d->propertyValues.at(contextProperty).constData())->count();
- }
+ else
+ return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->count();
}
QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int index)
@@ -523,384 +459,40 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind
QQmlContextPrivate *d = QQmlContextPrivate::get(context);
int contextProperty = (int)(quintptr)prop->data;
- if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
+ if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
return nullptr;
- } else {
- return ((const QList<QObject*> *)d->propertyValues.at(contextProperty).constData())->at(index);
- }
+ else
+ return ((const QList<QObject*> *)d->propertyValue(contextProperty).constData())->at(index);
}
void QQmlContextPrivate::dropDestroyedQObject(const QString &name, QObject *destroyed)
{
- if (!data->isValid())
+ if (!m_data->isValid())
return;
- const int idx = data->propertyNames().value(name);
+ const int idx = m_data->propertyNames().value(name);
Q_ASSERT(idx >= 0);
- if (qvariant_cast<QObject *>(propertyValues[idx]) != destroyed)
+ if (qvariant_cast<QObject *>(propertyValue(idx)) != destroyed)
return;
- propertyValues[idx] = QVariant::fromValue<QObject *>(nullptr);
- QMetaObject::activate(q_func(), notifyIndex, idx, nullptr);
-}
-
-
-QQmlContextData::QQmlContextData()
- : QQmlContextData(nullptr)
-{
-}
-
-QQmlContextData::QQmlContextData(QQmlContext *ctxt)
- : engine(nullptr), isInternal(false), isJSContext(false),
- isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- stronglyReferencedByParent(false), hasExtraObject(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
- contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
- expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
- componentAttached(nullptr)
-{
-}
-
-void QQmlContextData::emitDestruction()
-{
- if (!hasEmittedDestruction) {
- hasEmittedDestruction = true;
-
- // Emit the destruction signal - must be emitted before invalidate so that the
- // context is still valid if bindings or resultant expression evaluation requires it
- if (engine) {
- while (componentAttached) {
- QQmlComponentAttached *a = componentAttached;
- componentAttached = a->next;
- if (componentAttached) componentAttached->prev = &componentAttached;
-
- a->next = nullptr;
- a->prev = nullptr;
-
- emit a->destruction();
- }
-
- QQmlContextData * child = childContexts;
- while (child) {
- child->emitDestruction();
- child = child->nextChild;
- }
- }
- }
-}
-
-void QQmlContextData::invalidate()
-{
- emitDestruction();
-
- while (childContexts) {
- Q_ASSERT(childContexts != this);
- if (childContexts->stronglyReferencedByParent && !--childContexts->refCount)
- childContexts->destroy();
- else
- childContexts->invalidate();
- }
-
- if (prevChild) {
- *prevChild = nextChild;
- if (nextChild) nextChild->prevChild = prevChild;
- nextChild = nullptr;
- prevChild = nullptr;
- }
-
- importedScripts.clear();
-
- engine = nullptr;
- parent = nullptr;
-}
-
-void QQmlContextData::clearContextRecursively()
-{
- clearContext();
-
- for (auto ctxIt = childContexts; ctxIt; ctxIt = ctxIt->nextChild)
- ctxIt->clearContextRecursively();
-}
-
-void QQmlContextData::clearContext()
-{
- emitDestruction();
-
- QQmlJavaScriptExpression *expression = expressions;
- while (expression) {
- QQmlJavaScriptExpression *nextExpression = expression->m_nextExpression;
-
- expression->m_prevExpression = nullptr;
- expression->m_nextExpression = nullptr;
-
- expression->setContext(nullptr);
-
- expression = nextExpression;
- }
- expressions = nullptr;
-}
-
-void QQmlContextData::destroy()
-{
- Q_ASSERT(refCount == 0);
- linkedContext = nullptr;
-
- // avoid recursion
- ++refCount;
- if (engine)
- invalidate();
-
- Q_ASSERT(refCount == 1);
- clearContext();
- Q_ASSERT(refCount == 1);
-
- while (contextObjects) {
- QQmlData *co = contextObjects;
- contextObjects = contextObjects->nextContextObject;
-
- if (co->context == this)
- co->context = nullptr;
- co->outerContext = nullptr;
- co->nextContextObject = nullptr;
- co->prevContextObject = nullptr;
- }
- Q_ASSERT(refCount == 1);
-
- QQmlGuardedContextData *contextGuard = contextGuards;
- while (contextGuard) {
- QQmlGuardedContextData *next = contextGuard->m_next;
- contextGuard->m_next = nullptr;
- contextGuard->m_prev = nullptr;
- contextGuard->m_contextData = nullptr;
- contextGuard = next;
- }
- contextGuards = nullptr;
- Q_ASSERT(refCount == 1);
-
- delete [] idValues;
- idValues = nullptr;
-
- Q_ASSERT(refCount == 1);
- if (publicContext) {
- // the QQmlContext destructor will remove one ref again
- ++refCount;
- delete publicContext;
- }
-
- Q_ASSERT(refCount == 1);
- --refCount;
- Q_ASSERT(refCount == 0);
-
- delete this;
-}
-
-void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent)
-{
- if (p == parent)
- return;
- if (p) {
- Q_ASSERT(!parent);
- parent = p;
- this->stronglyReferencedByParent = stronglyReferencedByParent;
- if (stronglyReferencedByParent)
- ++refCount; // balanced in QQmlContextData::invalidate()
- engine = p->engine;
- nextChild = p->childContexts;
- if (nextChild) nextChild->prevChild = &nextChild;
- prevChild = &p->childContexts;
- p->childContexts = this;
- }
-}
-
-void QQmlContextData::refreshExpressionsRecursive(QQmlJavaScriptExpression *expression)
-{
- QQmlJavaScriptExpression::DeleteWatcher w(expression);
-
- if (expression->m_nextExpression)
- refreshExpressionsRecursive(expression->m_nextExpression);
-
- if (!w.wasDeleted())
- expression->refresh();
-}
-
-QQmlContextData::~QQmlContextData()
-{
-}
-
-static inline bool expressions_to_run(QQmlContextData *ctxt, bool isGlobalRefresh)
-{
- return ctxt->expressions && (!isGlobalRefresh || ctxt->unresolvedNames);
-}
-
-void QQmlContextData::refreshExpressionsRecursive(bool isGlobal)
-{
- // For efficiency, we try and minimize the number of guards we have to create
- if (expressions_to_run(this, isGlobal) && (nextChild || childContexts)) {
- QQmlGuardedContextData guard(this);
-
- if (childContexts)
- childContexts->refreshExpressionsRecursive(isGlobal);
-
- if (guard.isNull()) return;
-
- if (nextChild)
- nextChild->refreshExpressionsRecursive(isGlobal);
-
- if (guard.isNull()) return;
-
- if (expressions_to_run(this, isGlobal))
- refreshExpressionsRecursive(expressions);
-
- } else if (expressions_to_run(this, isGlobal)) {
-
- refreshExpressionsRecursive(expressions);
-
- } else if (nextChild && childContexts) {
-
- QQmlGuardedContextData guard(this);
-
- childContexts->refreshExpressionsRecursive(isGlobal);
-
- if (!guard.isNull() && nextChild)
- nextChild->refreshExpressionsRecursive(isGlobal);
-
- } else if (nextChild) {
-
- nextChild->refreshExpressionsRecursive(isGlobal);
-
- } else if (childContexts) {
-
- childContexts->refreshExpressionsRecursive(isGlobal);
-
- }
-}
-
-// Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
-// context-tree dependent caches in the expressions, and should occur every time the context tree
-// *structure* (not values) changes.
-void QQmlContextData::refreshExpressions()
-{
- bool isGlobal = (parent == nullptr);
-
- // For efficiency, we try and minimize the number of guards we have to create
- if (expressions_to_run(this, isGlobal) && childContexts) {
- QQmlGuardedContextData guard(this);
-
- childContexts->refreshExpressionsRecursive(isGlobal);
-
- if (!guard.isNull() && expressions_to_run(this, isGlobal))
- refreshExpressionsRecursive(expressions);
-
- } else if (expressions_to_run(this, isGlobal)) {
-
- refreshExpressionsRecursive(expressions);
-
- } else if (childContexts) {
-
- childContexts->refreshExpressionsRecursive(isGlobal);
-
- }
-}
-
-void QQmlContextData::addObject(QQmlData *data)
-{
- if (data->outerContext) {
- if (data->nextContextObject)
- data->nextContextObject->prevContextObject = data->prevContextObject;
- if (data->prevContextObject)
- *data->prevContextObject = data->nextContextObject;
- else if (data->outerContext->contextObjects == data)
- data->outerContext->contextObjects = data->nextContextObject;
- }
-
- data->outerContext = this;
-
- data->nextContextObject = contextObjects;
- if (data->nextContextObject)
- data->nextContextObject->prevContextObject = &data->nextContextObject;
- data->prevContextObject = &contextObjects;
- contextObjects = data;
-}
-
-void QQmlContextData::setIdProperty(int idx, QObject *obj)
-{
- idValues[idx] = obj;
- idValues[idx].context = this;
-}
-
-QString QQmlContextData::findObjectId(const QObject *obj) const
-{
- const QV4::IdentifierHash &properties = propertyNames();
- if (propertyNameCache.isEmpty())
- return QString();
-
- for (int ii = 0; ii < idValueCount; ii++) {
- if (idValues[ii] == obj)
- return properties.findId(ii);
- }
-
- if (publicContext) {
- QQmlContextPrivate *p = QQmlContextPrivate::get(publicContext);
- for (int ii = 0; ii < p->propertyValues.count(); ++ii)
- if (p->propertyValues.at(ii) == QVariant::fromValue(const_cast<QObject *>(obj)))
- return properties.findId(ii);
- }
-
- if (linkedContext)
- return linkedContext->findObjectId(obj);
- return QString();
-}
-
-QQmlContext *QQmlContextData::asQQmlContext()
-{
- if (!publicContext)
- publicContext = new QQmlContext(this);
- return publicContext;
-}
-
-QQmlContextPrivate *QQmlContextData::asQQmlContextPrivate()
-{
- return QQmlContextPrivate::get(asQQmlContext());
-}
-
-void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, int subComponentIndex)
-{
- typeCompilationUnit = unit;
- componentObjectIndex = subComponentIndex == -1 ? /*root object*/0 : subComponentIndex;
- Q_ASSERT(!idValues);
- idValueCount = typeCompilationUnit->objectAt(componentObjectIndex)->nNamedObjectsInComponent;
- idValues = new ContextGuard[idValueCount];
-}
-
-const QV4::IdentifierHash &QQmlContextData::propertyNames() const
-{
- if (propertyNameCache.isEmpty()) {
- if (typeCompilationUnit)
- propertyNameCache = typeCompilationUnit->namedObjectsPerComponent(componentObjectIndex);
- else
- propertyNameCache = QV4::IdentifierHash(engine->handle());
- }
- return propertyNameCache;
-}
-
-QV4::IdentifierHash &QQmlContextData::detachedPropertyNames()
-{
- propertyNames();
- propertyNameCache.detach();
- return propertyNameCache;
+ setPropertyValue(idx, QVariant::fromValue<QObject *>(nullptr));
+ QMetaObject::activate(q_func(), notifyIndex(), idx, nullptr);
}
-QUrl QQmlContextData::url() const
+void QQmlContextPrivate::emitDestruction()
{
- if (typeCompilationUnit)
- return typeCompilationUnit->finalUrl();
- return baseUrl;
+ m_data->emitDestruction();
}
-QString QQmlContextData::urlString() const
+// m_data is owned by the public context. When the public context is reset to nullptr, it will be
+// deref'd. It's OK to pass a half-created publicContext here. We will not dereference it during
+// construction.
+QQmlContextPrivate::QQmlContextPrivate(
+ QQmlContext *publicContext, QQmlContextData *parent, QQmlEngine *engine) :
+ m_data(new QQmlContextData(QQmlContextData::OwnedByPublicContext, publicContext,
+ parent, engine))
{
- if (typeCompilationUnit)
- return typeCompilationUnit->finalUrlString();
- return baseUrlString;
+ Q_ASSERT(publicContext != nullptr);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index 7ed70c7619..f12a94ef9d 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -100,7 +100,7 @@ private:
friend class QQmlComponentPrivate;
friend class QQmlScriptPrivate;
friend class QQmlContextData;
- QQmlContext(QQmlContextData *);
+ QQmlContext(QQmlContextPrivate &dd, QObject *parent = nullptr);
QQmlContext(QQmlEngine *, bool);
Q_DISABLE_COPY(QQmlContext)
};
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index f93393a11b..e1b2e9d41d 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -51,342 +51,74 @@
// We mean it.
//
-#include "qqmlcontext.h"
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qpointer.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmllist.h>
-#include "qqmldata_p.h"
-#include "qqmltypenamecache_p.h"
-#include "qqmlnotifier_p.h"
-#include "qqmllist.h"
-
-#include <QtCore/qhash.h>
-#include <QtQml/qjsvalue.h>
-#include <QtCore/qset.h>
-
-#include <private/qobject_p.h>
-#include <private/qflagpointer_p.h>
-#include <private/qqmlguard_p.h>
-
-#include <private/qv4executablecompilationunit_p.h>
-#include <private/qv4identifier_p.h>
+#include <QtCore/private/qobject_p.h>
+#include <QtCore/qtaggedpointer.h>
+#include <QtQml/private/qqmlrefcount_p.h>
QT_BEGIN_NAMESPACE
-class QQmlContext;
-class QQmlExpression;
-class QQmlEngine;
-class QQmlExpression;
-class QQmlExpressionPrivate;
-class QQmlJavaScriptExpression;
class QQmlContextData;
-class QQmlGuardedContextData;
-class QQmlIncubatorPrivate;
class QQmlContextPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQmlContext)
public:
- QQmlContextPrivate();
-
- QQmlContextData *data;
-
- QList<QVariant> propertyValues;
- int notifyIndex;
-
static QQmlContextPrivate *get(QQmlContext *context) {
return static_cast<QQmlContextPrivate *>(QObjectPrivate::get(context));
}
+
static QQmlContext *get(QQmlContextPrivate *context) {
return static_cast<QQmlContext *>(context->q_func());
}
- // Only used for debugging
- QList<QPointer<QObject> > instances;
-
static int context_count(QQmlListProperty<QObject> *);
static QObject *context_at(QQmlListProperty<QObject> *, int);
void dropDestroyedQObject(const QString &name, QObject *destroyed);
-};
-
-class QQmlComponentAttached;
-
-class Q_QML_PRIVATE_EXPORT QQmlContextData
-{
-public:
- QQmlContextData();
- QQmlContextData(QQmlContext *);
- void emitDestruction();
- void clearContext();
- void clearContextRecursively();
- void invalidate();
-
- inline bool isValid() const {
- return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
- }
-
- // My parent context and engine
- QQmlContextData *parent = nullptr;
- QQmlEngine *engine;
-
- void setParent(QQmlContextData *, bool stronglyReferencedByParent = false);
- void refreshExpressions();
-
- void addObject(QQmlData *data);
-
- QUrl resolvedUrl(const QUrl &);
-
- // My containing QQmlContext. If isInternal is true this owns publicContext.
- // If internal is false publicContext owns this.
- QQmlContext *asQQmlContext();
- QQmlContextPrivate *asQQmlContextPrivate();
- quint32 refCount = 0;
- quint32 isInternal:1;
- quint32 isJSContext:1;
- quint32 isPragmaLibraryContext:1;
- quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
- quint32 hasEmittedDestruction:1;
- quint32 isRootObjectInCreation:1;
- quint32 stronglyReferencedByParent:1;
- quint32 hasExtraObject:1; // used in QQmlDelegateModelItem::dataForObject to find the corresponding QQmlDelegateModelItem of an object
- quint32 dummy:24;
- QQmlContext *publicContext;
- union {
- // The incubator that is constructing this context if any
- QQmlIncubatorPrivate *incubator;
- // a pointer to extra data, currently only used in QQmlDelegateModel
- QObject *extraObject;
- };
+ int notifyIndex() const { return m_notifyIndex; }
+ void setNotifyIndex(int notifyIndex) { m_notifyIndex = notifyIndex; }
- // Compilation unit for contexts that belong to a compiled type.
- QQmlRefPointer<QV4::ExecutableCompilationUnit> typeCompilationUnit;
+ int numPropertyValues() const { return m_propertyValues.count(); }
+ void appendPropertyValue(const QVariant &value) { m_propertyValues.append(value); }
+ void setPropertyValue(int index, const QVariant &value) { m_propertyValues[index] = value; }
+ QVariant propertyValue(int index) const { return m_propertyValues[index]; }
- // object index in CompiledData::Unit to component that created this context
- int componentObjectIndex;
-
- void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, int subComponentIndex);
-
- // flag indicates whether the context owns the cache (after mutation) or not.
- mutable QV4::IdentifierHash propertyNameCache;
- const QV4::IdentifierHash &propertyNames() const;
- QV4::IdentifierHash &detachedPropertyNames();
-
- // Context object
- QObject *contextObject;
-
- // Any script blocks that exist on this context
- QV4::PersistentValue importedScripts; // This is a JS Array
-
- QUrl baseUrl;
- QString baseUrlString;
-
- QUrl url() const;
- QString urlString() const;
-
- // List of imports that apply to this context
- QQmlRefPointer<QQmlTypeNameCache> imports;
-
- // My children
- QQmlContextData *childContexts = nullptr;
-
- // My peers in parent's childContexts list
- QQmlContextData *nextChild;
- QQmlContextData **prevChild;
-
- // Expressions that use this context
- QQmlJavaScriptExpression *expressions;
-
- // Doubly-linked list of objects that are owned by this context
- QQmlData *contextObjects;
-
- // Doubly-linked list of context guards (XXX merge with contextObjects)
- QQmlGuardedContextData *contextGuards = nullptr;
-
- // id guards
- struct ContextGuard : public QQmlGuard<QObject>
+ QList<QPointer<QObject>> instances() const { return m_instances; }
+ void appendInstance(QObject *instance) { m_instances.append(instance); }
+ void cleanInstances()
{
- inline ContextGuard();
- inline ContextGuard &operator=(QObject *obj);
- inline void objectDestroyed(QObject *) override;
-
- inline bool wasSet() const;
-
- QFlagPointer<QQmlContextData> context;
- QQmlNotifier bindings;
- };
- ContextGuard *idValues;
- int idValueCount;
- void setIdProperty(int, QObject *);
-
- // Linked contexts. this owns linkedContext.
- QQmlContextDataRef linkedContext;
-
- // Linked list of uses of the Component attached property in this
- // context
- QQmlComponentAttached *componentAttached;
-
- // Return the outermost id for obj, if any.
- QString findObjectId(const QObject *obj) const;
-
- static QQmlContextData *get(QQmlContext *context) {
- return QQmlContextPrivate::get(context)->data;
+ for (auto it = m_instances.begin(); it != m_instances.end();
+ it->isNull() ? (it = m_instances.erase(it)) : ++it) {}
}
-private:
- friend class QQmlContextDataRef;
- friend class QQmlContext; // needs to do manual refcounting :/
- void refreshExpressionsRecursive(bool isGlobal);
- void refreshExpressionsRecursive(QQmlJavaScriptExpression *);
- ~QQmlContextData();
- void destroy();
-};
-
-
-class QQmlGuardedContextData
-{
-public:
- inline QQmlGuardedContextData() = default;
- inline QQmlGuardedContextData(QQmlContextData *data)
- { setContextData(data); }
- inline ~QQmlGuardedContextData()
- { clear(); }
-
- inline QQmlContextData *contextData() const
- { return m_contextData; }
- inline void setContextData(QQmlContextData *);
-
- inline bool isNull() const { return !m_contextData; }
-
- inline operator QQmlContextData*() const { return m_contextData; }
- inline QQmlContextData* operator->() const { return m_contextData; }
- inline QQmlGuardedContextData &operator=(QQmlContextData *d) {
- setContextData(d); return *this;
- }
+ void emitDestruction();
private:
- QQmlGuardedContextData &operator=(const QQmlGuardedContextData &) = delete;
- QQmlGuardedContextData(const QQmlGuardedContextData &) = delete;
friend class QQmlContextData;
- inline void clear();
-
- QQmlContextData *m_contextData = nullptr;
- QQmlGuardedContextData *m_next = nullptr;
- QQmlGuardedContextData **m_prev = nullptr;
-};
-
-
-void QQmlGuardedContextData::setContextData(QQmlContextData *contextData)
- {
- if (m_contextData == contextData)
- return;
- clear();
-
- if (contextData) {
- m_contextData = contextData;
- m_next = contextData->contextGuards;
- if (m_next) m_next->m_prev = &m_next;
- m_prev = &contextData->contextGuards;
- contextData->contextGuards = this;
- }
-}
-
-void QQmlGuardedContextData::clear()
-{
- if (m_prev) {
- *m_prev = m_next;
- if (m_next) m_next->m_prev = m_prev;
- m_contextData = nullptr;
- m_next = nullptr;
- m_prev = nullptr;
- }
-}
-
-QQmlContextDataRef::QQmlContextDataRef()
- : m_contextData(nullptr)
-{
-}
-
-QQmlContextDataRef::QQmlContextDataRef(const QQmlContextDataRef &other)
- : m_contextData(other.m_contextData)
-{
- if (m_contextData)
- ++m_contextData->refCount;
-}
-
-QQmlContextDataRef::QQmlContextDataRef(QQmlContextData *data)
- : m_contextData(data)
-{
- if (m_contextData)
- ++m_contextData->refCount;
-}
-
-QQmlContextDataRef::~QQmlContextDataRef()
-{
- clear();
-}
-
-void QQmlContextDataRef::setContextData(QQmlContextData *contextData)
-{
- if (m_contextData == contextData)
- return;
- clear();
-
- if (contextData) {
- m_contextData = contextData;
- ++m_contextData->refCount;
- }
-}
-
-QQmlContextData *QQmlContextDataRef::contextData() const
-{
- return m_contextData;
-}
-
-void QQmlContextDataRef::clear()
-{
- if (m_contextData && !--m_contextData->refCount)
- m_contextData->destroy();
- m_contextData = nullptr;
-}
+ QQmlContextPrivate(QQmlContextData *data) : m_data(data) {}
+ QQmlContextPrivate(QQmlContext *publicContext, QQmlContextData *parent,
+ QQmlEngine *engine = nullptr);
-QQmlContextDataRef &
-QQmlContextDataRef::operator=(QQmlContextData *d)
-{
- setContextData(d);
- return *this;
-}
-
-QQmlContextDataRef &
-QQmlContextDataRef::operator=(const QQmlContextDataRef &other)
-{
- setContextData(other.m_contextData);
- return *this;
-}
+ // Intentionally a bare pointer. QQmlContextData knows whether it owns QQmlContext or vice
+ // versa. If QQmlContext is the owner, QQmlContextData keeps an extra ref for its publicContext.
+ // The publicContext ref is released when doing QQmlContextData::setPublicContext(nullptr).
+ QQmlContextData *m_data;
-QQmlContextData::ContextGuard::ContextGuard()
-: context(nullptr)
-{
-}
-
-QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj)
-{
- QQmlGuard<QObject>::operator=(obj);
- context.setFlag();
- bindings.notify(); // For alias connections
- return *this;
-}
+ QList<QVariant> m_propertyValues;
+ int m_notifyIndex = -1;
-void QQmlContextData::ContextGuard::objectDestroyed(QObject *)
-{
- if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted)
- bindings.notify();
-}
-
-bool QQmlContextData::ContextGuard::wasSet() const
-{
- return context.flag();
-}
+ // Only used for debugging
+ QList<QPointer<QObject>> m_instances;
+};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontextdata.cpp b/src/qml/qml/qqmlcontextdata.cpp
new file mode 100644
index 0000000000..33be23b14d
--- /dev/null
+++ b/src/qml/qml/qqmlcontextdata.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 "qqmlcontextdata_p.h"
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/private/qqmlcomponentattached_p.h>
+#include <QtQml/private/qqmljavascriptexpression_p.h>
+#include <QtQml/private/qqmlguardedcontextdata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QUrl QQmlContextData::resolvedUrl(const QUrl &src)
+{
+ QUrl resolved;
+ if (src.isRelative() && !src.isEmpty()) {
+ QQmlRefPointer<QQmlContextData> ctxt = this;
+ do {
+ if (ctxt->url().isValid())
+ break;
+ else
+ ctxt = ctxt->parent();
+ } while (ctxt);
+
+ if (ctxt)
+ resolved = ctxt->url().resolved(src);
+ else if (m_engine)
+ resolved = m_engine->baseUrl().resolved(src);
+ } else {
+ resolved = src;
+ }
+
+ if (resolved.isEmpty()) //relative but no ctxt
+ return resolved;
+
+ return m_engine ? m_engine->interceptUrl(resolved, QQmlAbstractUrlInterceptor::UrlString)
+ : resolved;
+}
+
+void QQmlContextData::emitDestruction()
+{
+ if (!m_hasEmittedDestruction) {
+ m_hasEmittedDestruction = true;
+
+ // Emit the destruction signal - must be emitted before invalidate so that the
+ // context is still valid if bindings or resultant expression evaluation requires it
+ if (m_engine) {
+ while (m_componentAttacheds) {
+ QQmlComponentAttached *attached = m_componentAttacheds;
+ attached->removeFromList();
+ emit attached->destruction();
+ }
+
+ for (QQmlContextData *child = m_childContexts; child; child = child->m_nextChild)
+ child->emitDestruction();
+ }
+ }
+}
+
+void QQmlContextData::invalidate()
+{
+ emitDestruction();
+
+ while (m_childContexts) {
+ Q_ASSERT(m_childContexts != this);
+ m_childContexts->invalidate();
+ }
+
+ if (m_prevChild) {
+ *m_prevChild = m_nextChild;
+ if (m_nextChild) m_nextChild->m_prevChild = m_prevChild;
+ m_nextChild = nullptr;
+ m_prevChild = nullptr;
+ }
+
+ m_importedScripts.clear();
+
+ m_engine = nullptr;
+ clearParent();
+}
+
+void QQmlContextData::clearContextRecursively()
+{
+ clearContext();
+
+ for (auto ctxIt = m_childContexts; ctxIt; ctxIt = ctxIt->m_nextChild)
+ ctxIt->clearContextRecursively();
+}
+
+void QQmlContextData::clearContext()
+{
+ emitDestruction();
+
+ QQmlJavaScriptExpression *expression = m_expressions;
+ while (expression) {
+ QQmlJavaScriptExpression *nextExpression = expression->m_nextExpression;
+
+ expression->m_prevExpression = nullptr;
+ expression->m_nextExpression = nullptr;
+
+ expression->setContext(nullptr);
+
+ expression = nextExpression;
+ }
+ m_expressions = nullptr;
+}
+
+QQmlContextData::~QQmlContextData()
+{
+ Q_ASSERT(refCount() == 0);
+ m_linkedContext = nullptr;
+
+ // avoid recursion
+ addref();
+ if (m_engine)
+ invalidate();
+
+ Q_ASSERT(refCount() == 1);
+ clearContext();
+ Q_ASSERT(refCount() == 1);
+
+ while (m_ownedObjects) {
+ QQmlData *co = m_ownedObjects;
+ m_ownedObjects = m_ownedObjects->nextContextObject;
+
+ if (co->context == this)
+ co->context = nullptr;
+ co->outerContext = nullptr;
+ co->nextContextObject = nullptr;
+ co->prevContextObject = nullptr;
+ }
+ Q_ASSERT(refCount() == 1);
+
+ QQmlGuardedContextData *contextGuard = m_contextGuards;
+ while (contextGuard) {
+ QQmlGuardedContextData *next = contextGuard->next();
+ next->reset();
+ contextGuard = next;
+ }
+ m_contextGuards = nullptr;
+ Q_ASSERT(refCount() == 1);
+
+ delete [] m_idValues;
+ m_idValues = nullptr;
+
+ Q_ASSERT(refCount() == 1);
+ if (m_publicContext)
+ delete m_publicContext;
+
+ Q_ASSERT(refCount() == 1);
+}
+
+void QQmlContextData::refreshExpressionsRecursive(QQmlJavaScriptExpression *expression)
+{
+ QQmlJavaScriptExpression::DeleteWatcher w(expression);
+
+ if (expression->m_nextExpression)
+ refreshExpressionsRecursive(expression->m_nextExpression);
+
+ if (!w.wasDeleted())
+ expression->refresh();
+}
+
+void QQmlContextData::refreshExpressionsRecursive(bool isGlobal)
+{
+ // For efficiency, we try and minimize the number of guards we have to create
+ if (hasExpressionsToRun(isGlobal) && (m_nextChild || m_childContexts)) {
+ QQmlGuardedContextData guard(this);
+
+ if (m_childContexts)
+ m_childContexts->refreshExpressionsRecursive(isGlobal);
+
+ if (guard.isNull()) return;
+
+ if (m_nextChild)
+ m_nextChild->refreshExpressionsRecursive(isGlobal);
+
+ if (guard.isNull()) return;
+
+ if (hasExpressionsToRun(isGlobal))
+ refreshExpressionsRecursive(m_expressions);
+
+ } else if (hasExpressionsToRun(isGlobal)) {
+ refreshExpressionsRecursive(m_expressions);
+ } else if (m_nextChild && m_childContexts) {
+ QQmlGuardedContextData guard(this);
+ m_childContexts->refreshExpressionsRecursive(isGlobal);
+ if (!guard.isNull() && m_nextChild)
+ m_nextChild->refreshExpressionsRecursive(isGlobal);
+ } else if (m_nextChild) {
+ m_nextChild->refreshExpressionsRecursive(isGlobal);
+ } else if (m_childContexts) {
+ m_childContexts->refreshExpressionsRecursive(isGlobal);
+ }
+}
+
+// Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
+// context-tree dependent caches in the expressions, and should occur every time the context tree
+// *structure* (not values) changes.
+void QQmlContextData::refreshExpressions()
+{
+ bool isGlobal = (m_parent == nullptr);
+
+ // For efficiency, we try and minimize the number of guards we have to create
+ if (hasExpressionsToRun(isGlobal) && m_childContexts) {
+ QQmlGuardedContextData guard(this);
+ m_childContexts->refreshExpressionsRecursive(isGlobal);
+ if (!guard.isNull() && hasExpressionsToRun(isGlobal))
+ refreshExpressionsRecursive(m_expressions);
+ } else if (hasExpressionsToRun(isGlobal)) {
+ refreshExpressionsRecursive(m_expressions);
+ } else if (m_childContexts) {
+ m_childContexts->refreshExpressionsRecursive(isGlobal);
+ }
+}
+
+void QQmlContextData::addOwnedObject(QQmlData *data)
+{
+ if (data->outerContext) {
+ if (data->nextContextObject)
+ data->nextContextObject->prevContextObject = data->prevContextObject;
+ if (data->prevContextObject)
+ *data->prevContextObject = data->nextContextObject;
+ else if (data->outerContext->m_ownedObjects == data)
+ data->outerContext->m_ownedObjects = data->nextContextObject;
+ }
+
+ data->outerContext = this;
+
+ data->nextContextObject = m_ownedObjects;
+ if (data->nextContextObject)
+ data->nextContextObject->prevContextObject = &data->nextContextObject;
+ data->prevContextObject = &m_ownedObjects;
+ m_ownedObjects = data;
+}
+
+void QQmlContextData::setIdValue(int idx, QObject *obj)
+{
+ m_idValues[idx] = obj;
+ m_idValues[idx].setContext(this);
+}
+
+QString QQmlContextData::findObjectId(const QObject *obj) const
+{
+ const QV4::IdentifierHash &properties = propertyNames();
+ if (m_propertyNameCache.isEmpty())
+ return QString();
+
+ for (int ii = 0; ii < m_idValueCount; ii++) {
+ if (m_idValues[ii] == obj)
+ return properties.findId(ii);
+ }
+
+ if (m_publicContext) {
+ QQmlContextPrivate *p = QQmlContextPrivate::get(m_publicContext);
+ for (int ii = 0; ii < p->numPropertyValues(); ++ii)
+ if (p->propertyValue(ii) == QVariant::fromValue(const_cast<QObject *>(obj)))
+ return properties.findId(ii);
+ }
+
+ if (m_linkedContext)
+ return m_linkedContext->findObjectId(obj);
+ return QString();
+}
+
+QQmlContext *QQmlContextData::asQQmlContext()
+{
+ if (!m_publicContext)
+ m_publicContext = new QQmlContext(*new QQmlContextPrivate(this));
+ return m_publicContext;
+}
+
+QQmlContextPrivate *QQmlContextData::asQQmlContextPrivate()
+{
+ return QQmlContextPrivate::get(asQQmlContext());
+}
+
+void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, int subComponentIndex)
+{
+ m_typeCompilationUnit = unit;
+ m_componentObjectIndex = subComponentIndex == -1 ? /*root object*/0 : subComponentIndex;
+ Q_ASSERT(!m_idValues);
+ m_idValueCount = m_typeCompilationUnit->objectAt(m_componentObjectIndex)
+ ->nNamedObjectsInComponent;
+ m_idValues = new ContextGuard[m_idValueCount];
+}
+
+void QQmlContextData::addComponentAttached(QQmlComponentAttached *attached)
+{
+ attached->insertIntoList(&m_componentAttacheds);
+}
+
+void QQmlContextData::addExpression(QQmlJavaScriptExpression *expression)
+{
+ expression->insertIntoList(&m_expressions);
+}
+
+QV4::IdentifierHash QQmlContextData::propertyNames() const
+{
+ if (m_propertyNameCache.isEmpty()) {
+ if (m_typeCompilationUnit)
+ m_propertyNameCache = m_typeCompilationUnit->namedObjectsPerComponent(m_componentObjectIndex);
+ else
+ m_propertyNameCache = QV4::IdentifierHash(m_engine->handle());
+ }
+ return m_propertyNameCache;
+}
+
+QV4::IdentifierHash *QQmlContextData::detachedPropertyNames()
+{
+ propertyNames();
+ m_propertyNameCache.detach();
+ return &m_propertyNameCache;
+}
+
+QUrl QQmlContextData::url() const
+{
+ if (m_typeCompilationUnit)
+ return m_typeCompilationUnit->finalUrl();
+ return m_baseUrl;
+}
+
+QString QQmlContextData::urlString() const
+{
+ if (m_typeCompilationUnit)
+ return m_typeCompilationUnit->finalUrlString();
+ return m_baseUrlString;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontextdata_p.h b/src/qml/qml/qqmlcontextdata_p.h
new file mode 100644
index 0000000000..ea0b010d21
--- /dev/null
+++ b/src/qml/qml/qqmlcontextdata_p.h
@@ -0,0 +1,432 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 QQMLCONTEXTDATA_P_H
+#define QQMLCONTEXTDATA_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 <QtQml/private/qqmlglobal_p.h>
+#include <QtQml/private/qqmlcontext_p.h>
+#include <QtQml/private/qqmlguard_p.h>
+#include <QtQml/private/qqmltypenamecache_p.h>
+#include <QtQml/private/qv4identifierhash_p.h>
+#include <QtQml/private/qv4executablecompilationunit_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlComponentAttached;
+class QQmlGuardedContextData;
+class QQmlJavaScriptExpression;
+class QQmlIncubatorPrivate;
+
+class Q_QML_PRIVATE_EXPORT QQmlContextData
+{
+public:
+ static QQmlRefPointer<QQmlContextData> createRefCounted(
+ const QQmlRefPointer<QQmlContextData> &parent)
+ {
+ return QQmlRefPointer<QQmlContextData>(new QQmlContextData(RefCounted, nullptr, parent),
+ QQmlRefPointer<QQmlContextData>::Adopt);
+ }
+
+ // Owned by the parent. When the parent is reset to nullptr, it will be deref'd.
+ static QQmlRefPointer<QQmlContextData> createChild(
+ const QQmlRefPointer<QQmlContextData> &parent)
+ {
+ Q_ASSERT(!parent.isNull());
+ return QQmlRefPointer<QQmlContextData>(new QQmlContextData(OwnedByParent, nullptr, parent));
+ }
+
+ void addref() const { ++m_refCount; }
+ void release() const { if (--m_refCount == 0) delete this; }
+ int count() const { return m_refCount; }
+ int refCount() const { return m_refCount; }
+
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> typeCompilationUnit() const
+ {
+ return m_typeCompilationUnit;
+ }
+ void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit,
+ int subComponentIndex);
+
+ static QQmlRefPointer<QQmlContextData> get(QQmlContext *context) {
+ return QQmlContextPrivate::get(context)->m_data;
+ }
+
+ void emitDestruction();
+ void clearContext();
+ void clearContextRecursively();
+ void invalidate();
+
+ bool isValid() const
+ {
+ return m_engine && (!m_isInternal || !m_contextObject
+ || !QObjectPrivate::get(m_contextObject)->wasDeleted);
+ }
+
+ bool isInternal() const { return m_isInternal; }
+ void setInternal(bool isInternal) { m_isInternal = isInternal; }
+
+ bool isJSContext() const { return m_isJSContext; }
+ void setJSContext(bool isJSContext) { m_isJSContext = isJSContext; }
+
+ bool isPragmaLibraryContext() const { return m_isPragmaLibraryContext; }
+ void setPragmaLibraryContext(bool library) { m_isPragmaLibraryContext = library; }
+
+ QQmlRefPointer<QQmlContextData> parent() const { return m_parent; }
+ void clearParent()
+ {
+ if (!m_parent)
+ return;
+
+ m_parent = nullptr;
+ if (m_ownedByParent) {
+ m_ownedByParent = false;
+ release();
+ }
+ }
+
+ void refreshExpressions();
+
+ void addOwnedObject(QQmlData *ownedObject);
+ QQmlData *ownedObjects() const { return m_ownedObjects; }
+ void setOwnedObjects(QQmlData *ownedObjects) { m_ownedObjects = ownedObjects; }
+
+ QUrl resolvedUrl(const QUrl &);
+
+ // My containing QQmlContext. If isInternal is true this owns publicContext.
+ // If internal is false publicContext owns this.
+ QQmlContext *asQQmlContext();
+ QQmlContextPrivate *asQQmlContextPrivate();
+
+ QObject *contextObject() const { return m_contextObject; }
+ void setContextObject(QObject *contextObject) { m_contextObject = contextObject; }
+
+ QQmlEngine *engine() const { return m_engine; }
+ void setEngine(QQmlEngine *engine) { m_engine = engine; }
+
+ QQmlContext *publicContext() const { return m_publicContext; }
+ void clearPublicContext()
+ {
+ if (!m_publicContext)
+ return;
+
+ m_publicContext = nullptr;
+ if (m_ownedByPublicContext) {
+ m_ownedByPublicContext = false;
+ release();
+ }
+ }
+
+ QV4::IdentifierHash propertyNames() const;
+ QV4::IdentifierHash *detachedPropertyNames();
+
+ void setExpressions(QQmlJavaScriptExpression *expressions) { m_expressions = expressions; }
+ QQmlJavaScriptExpression *takeExpressions()
+ {
+ QQmlJavaScriptExpression *expressions = m_expressions;
+ m_expressions = nullptr;
+ return expressions;
+ }
+
+ void setChildContexts(const QQmlRefPointer<QQmlContextData> &childContexts)
+ {
+ m_childContexts = childContexts.data();
+ }
+ QQmlRefPointer<QQmlContextData> childContexts() const { return m_childContexts; }
+ QQmlRefPointer<QQmlContextData> takeChildContexts()
+ {
+ QQmlRefPointer<QQmlContextData> childContexts = m_childContexts;
+ m_childContexts = nullptr;
+ return childContexts;
+ }
+ QQmlRefPointer<QQmlContextData> nextChild() const { return m_nextChild; }
+
+ int numIdValues() const { return m_idValueCount; }
+ void setIdValue(int index, QObject *idValue);
+ bool isIdValueSet(int index) const { return m_idValues[index].wasSet(); }
+ QQmlNotifier *idValueBindings(int index) const { return m_idValues[index].bindings(); }
+ QObject *idValue(int index) const { return m_idValues[index].data(); }
+
+ // Return the outermost id for obj, if any.
+ QString findObjectId(const QObject *obj) const;
+
+ // url() and urlString() prefer the CU's URL over explicitly set baseUrls. They
+ // don't search the context hierarchy.
+ // baseUrl() and baseUrlString() search the context hierarchy and prefer explicit
+ // base URLs over CU Urls.
+
+ QUrl url() const;
+ QString urlString() const;
+
+ void setBaseUrlString(const QString &baseUrlString) { m_baseUrlString = baseUrlString; }
+ QString baseUrlString() const
+ {
+ for (const QQmlContextData *data = this; data; data = data->m_parent) {
+ if (!data->m_baseUrlString.isEmpty())
+ return data->m_baseUrlString;
+ if (data->m_typeCompilationUnit)
+ return data->m_typeCompilationUnit->finalUrlString();
+ }
+ return QString();
+ }
+
+ void setBaseUrl(const QUrl &baseUrl) { m_baseUrl = baseUrl; }
+ QUrl baseUrl() const
+ {
+ for (const QQmlContextData *data = this; data; data = data->m_parent) {
+ if (!data->m_baseUrl.isEmpty())
+ return data->m_baseUrl;
+ if (data->m_typeCompilationUnit)
+ return data->m_typeCompilationUnit->finalUrl();
+ }
+ return QUrl();
+ }
+
+ QQmlRefPointer<QQmlTypeNameCache> imports() const { return m_imports; }
+ void setImports(const QQmlRefPointer<QQmlTypeNameCache> &imports) { m_imports = imports; }
+
+ QQmlIncubatorPrivate *incubator() const { return m_hasExtraObject ? nullptr : m_incubator; }
+ void setIncubator(QQmlIncubatorPrivate *incubator)
+ {
+ Q_ASSERT(!m_hasExtraObject || m_extraObject == nullptr);
+ m_hasExtraObject = false;
+ m_incubator = incubator;
+ }
+
+ QObject *extraObject() const { return m_hasExtraObject ? m_extraObject : nullptr; }
+ void setExtraObject(QObject *extraObject)
+ {
+ Q_ASSERT(m_hasExtraObject || m_incubator == nullptr);
+ m_hasExtraObject = true;
+ m_extraObject = extraObject;
+ }
+
+ bool isRootObjectInCreation() const { return m_isRootObjectInCreation; }
+ void setRootObjectInCreation(bool rootInCreation) { m_isRootObjectInCreation = rootInCreation; }
+
+ QV4::PersistentValue importedScripts() const { return m_importedScripts; }
+ void setImportedScripts(const QV4::PersistentValue &scripts) { m_importedScripts = scripts; }
+
+ QQmlRefPointer<QQmlContextData> linkedContext() const { return m_linkedContext; }
+ void setLinkedContext(const QQmlRefPointer<QQmlContextData> &context) { m_linkedContext = context; }
+
+ bool hasUnresolvedNames() const { return m_unresolvedNames; }
+ void setUnresolvedNames(bool hasUnresolvedNames) { m_unresolvedNames = hasUnresolvedNames; }
+
+ QQmlComponentAttached *componentAttacheds() const { return m_componentAttacheds; }
+ void addComponentAttached(QQmlComponentAttached *attached);
+
+ void addExpression(QQmlJavaScriptExpression *expression);
+
+private:
+ friend class QQmlGuardedContextData;
+ friend class QQmlContextPrivate;
+
+ enum Ownership {
+ RefCounted,
+ OwnedByParent,
+ OwnedByPublicContext
+ };
+
+ // id guards
+ struct ContextGuard : public QQmlGuard<QObject>
+ {
+ enum Tag {
+ NoTag,
+ ObjectWasSet
+ };
+
+ inline ContextGuard() : m_context(nullptr) {}
+ inline ContextGuard &operator=(QObject *obj);
+ inline void objectDestroyed(QObject *) override;
+
+ inline bool wasSet() const;
+
+ QQmlNotifier *bindings() { return &m_bindings; }
+ void setContext(const QQmlRefPointer<QQmlContextData> &context)
+ {
+ m_context = context.data();
+ }
+
+ private:
+ // Not refcounted, as it always belongs to the QQmlContextData.
+ QTaggedPointer<QQmlContextData, Tag> m_context;
+ QQmlNotifier m_bindings;
+ };
+
+ // It's OK to pass a half-created publicContext here. We will not dereference it during
+ // construction.
+ QQmlContextData(
+ Ownership ownership, QQmlContext *publicContext,
+ const QQmlRefPointer<QQmlContextData> &parent, QQmlEngine *engine = nullptr)
+ : m_parent(parent.data()),
+ m_engine(engine ? engine : (parent.isNull() ? nullptr : parent->engine())),
+ m_isInternal(false), m_isJSContext(false), m_isPragmaLibraryContext(false),
+ m_unresolvedNames(false), m_hasEmittedDestruction(false), m_isRootObjectInCreation(false),
+ m_ownedByParent(ownership == OwnedByParent),
+ m_ownedByPublicContext(ownership == OwnedByPublicContext), m_hasExtraObject(false),
+ m_dummy(0), m_publicContext(publicContext), m_incubator(nullptr)
+ {
+ Q_ASSERT(!m_ownedByParent || !m_ownedByPublicContext);
+ if (!m_parent)
+ return;
+
+ m_nextChild = m_parent->m_childContexts;
+ if (m_nextChild)
+ m_nextChild->m_prevChild = &m_nextChild;
+ m_prevChild = &m_parent->m_childContexts;
+ m_parent->m_childContexts = this;
+ }
+
+ ~QQmlContextData();
+
+ bool hasExpressionsToRun(bool isGlobalRefresh) const
+ {
+ return m_expressions && (!isGlobalRefresh || m_unresolvedNames);
+ }
+
+ void refreshExpressionsRecursive(bool isGlobal);
+ void refreshExpressionsRecursive(QQmlJavaScriptExpression *);
+
+ // My parent context and engine
+ QQmlContextData *m_parent = nullptr;
+ QQmlEngine *m_engine = nullptr;
+
+ mutable quint32 m_refCount = 1;
+ quint32 m_isInternal:1;
+ quint32 m_isJSContext:1;
+ quint32 m_isPragmaLibraryContext:1;
+ quint32 m_unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
+ quint32 m_hasEmittedDestruction:1;
+ quint32 m_isRootObjectInCreation:1;
+ quint32 m_ownedByParent:1;
+ quint32 m_ownedByPublicContext:1;
+ quint32 m_hasExtraObject:1; // used in QQmlDelegateModelItem::dataForObject to find the corresponding QQmlDelegateModelItem of an object
+ quint32 m_dummy:23;
+ QQmlContext *m_publicContext = nullptr;
+
+ union {
+ // The incubator that is constructing this context if any
+ QQmlIncubatorPrivate *m_incubator;
+ // a pointer to extra data, currently only used in QQmlDelegateModel
+ QObject *m_extraObject;
+ };
+
+ // Compilation unit for contexts that belong to a compiled type.
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> m_typeCompilationUnit;
+
+ // object index in CompiledData::Unit to component that created this context
+ int m_componentObjectIndex = -1;
+
+ // flag indicates whether the context owns the cache (after mutation) or not.
+ mutable QV4::IdentifierHash m_propertyNameCache;
+
+ // Context object
+ QObject *m_contextObject = nullptr;
+
+ // Any script blocks that exist on this context
+ QV4::PersistentValue m_importedScripts; // This is a JS Array
+
+ QUrl m_baseUrl;
+ QString m_baseUrlString;
+
+ // List of imports that apply to this context
+ QQmlRefPointer<QQmlTypeNameCache> m_imports;
+
+ // My children, not refcounted as that would create cyclic references
+ QQmlContextData *m_childContexts = nullptr;
+
+ // My peers in parent's childContexts list; not refcounted
+ QQmlContextData *m_nextChild = nullptr;
+ QQmlContextData **m_prevChild = nullptr;
+
+ // Expressions that use this context
+ QQmlJavaScriptExpression *m_expressions = nullptr;
+
+ // Doubly-linked list of objects that are owned by this context
+ QQmlData *m_ownedObjects = nullptr;
+
+ // Doubly-linked list of context guards (XXX merge with contextObjects)
+ QQmlGuardedContextData *m_contextGuards = nullptr;
+
+ ContextGuard *m_idValues = nullptr;
+ int m_idValueCount = 0;
+
+ // Linked contexts. this owns linkedContext.
+ QQmlRefPointer<QQmlContextData> m_linkedContext;
+
+ // Linked list of uses of the Component attached property in this context
+ QQmlComponentAttached *m_componentAttacheds = nullptr;
+};
+
+QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj)
+{
+ QQmlGuard<QObject>::operator=(obj);
+ m_context.setTag(ObjectWasSet);
+ m_bindings.notify(); // For alias connections
+ return *this;
+}
+
+void QQmlContextData::ContextGuard::objectDestroyed(QObject *)
+{
+ if (QObject *contextObject = m_context->contextObject()) {
+ if (!QObjectPrivate::get(contextObject)->wasDeleted)
+ m_bindings.notify();
+ }
+}
+
+bool QQmlContextData::ContextGuard::wasSet() const
+{
+ return m_context.tag() == ObjectWasSet;
+}
+
+QT_END_NAMESPACE
+
+#endif // QQMLCONTEXTDATA_P_H
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 5e6e1187e2..b0df4f26dc 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -109,12 +109,6 @@ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const
exceptions << error;
}
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
/*!
If \a script is a simple enumeration expression (eg. Text.AlignLeft),
returns the integer equivalent (eg. 1), and sets \a ok to true.
@@ -150,12 +144,12 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
if (imports.isT1()) {
QQmlImportNamespace *ns = nullptr;
- if (!imports.asT1()->resolveType(scope, &type, nullptr, nullptr, &ns))
+ if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns))
return -1;
if (!type.isValid() && ns != nullptr) {
dot = nextDot(dot);
if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)),
- &type, nullptr, nullptr, nullptr)) {
+ &type, nullptr, nullptr)) {
return -1;
}
}
@@ -184,7 +178,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
}
QByteArray enumValue = script.mid(dot + 1);
- const QMetaObject *mo = StaticQtMetaObject::get();
+ const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
while (i--) {
int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index ee31cb38d9..f850746d92 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -74,6 +74,7 @@ class QQmlContextData;
class QQmlNotifier;
class QQmlDataExtended;
class QQmlNotifierEndpoint;
+class QQmlPropertyObserver;
namespace QV4 {
class ExecutableCompilationUnit;
@@ -82,34 +83,6 @@ struct Binding;
}
}
-// This is declared here because QQmlData below needs it and this file
-// in turn is included from qqmlcontext_p.h.
-class QQmlContextData;
-class Q_QML_PRIVATE_EXPORT QQmlContextDataRef
-{
-public:
- inline QQmlContextDataRef();
- inline QQmlContextDataRef(QQmlContextData *);
- inline QQmlContextDataRef(const QQmlContextDataRef &);
- inline ~QQmlContextDataRef();
-
- inline QQmlContextData *contextData() const;
- inline void setContextData(QQmlContextData *);
-
- inline bool isNull() const { return !m_contextData; }
-
- inline operator QQmlContextData*() const { return m_contextData; }
- inline QQmlContextData* operator->() const { return m_contextData; }
- inline QQmlContextDataRef &operator=(QQmlContextData *d);
- inline QQmlContextDataRef &operator=(const QQmlContextDataRef &other);
-
-private:
-
- inline void clear();
-
- QQmlContextData *m_contextData;
-};
-
// This class is structured in such a way, that simply zero'ing it is the
// default state for elemental object allocations. This is crucial in the
// workings of the QQmlInstruction::CreateSimpleObject instruction.
@@ -195,14 +168,15 @@ public:
bool signalHasEndpoint(int index) const;
void disconnectNotifiers();
- // The context that created the C++ object
+ // The context that created the C++ object; not refcounted to prevent cycles
QQmlContextData *context = nullptr;
- // The outermost context in which this object lives
+ // The outermost context in which this object lives; not refcounted to prevent cycles
QQmlContextData *outerContext = nullptr;
- QQmlContextDataRef ownContext;
+ QQmlRefPointer<QQmlContextData> ownContext;
QQmlAbstractBinding *bindings;
QQmlBoundSignal *signalHandlers;
+ std::vector<QQmlPropertyObserver> propertyObservers;
// Linked list for QQmlContext::contextObjects
QQmlData *nextContextObject;
@@ -226,14 +200,19 @@ public:
~DeferredData();
unsigned int deferredIdx;
QMultiHash<int, const QV4::CompiledData::Binding *> bindings;
- QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;//Not always the same as the other compilation unit
- QQmlContextData *context;//Could be either context or outerContext
+
+ // Not always the same as the other compilation unit
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
+
+ // Could be either context or outerContext
+ QQmlRefPointer<QQmlContextData> context;
Q_DISABLE_COPY(DeferredData);
};
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
QVector<DeferredData *> deferredData;
- void deferData(int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, QQmlContextData *);
+ void deferData(int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &,
+ const QQmlRefPointer<QQmlContextData> &);
void releaseDeferredData();
QV4::WeakValue jsWrapper;
diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp
index b22e46b69c..fb8bd63bf1 100644
--- a/src/qml/qml/qqmldatablob.cpp
+++ b/src/qml/qml/qqmldatablob.cpp
@@ -105,9 +105,8 @@ QQmlDataBlob::QQmlDataBlob(const QUrl &url, Type type, QQmlTypeLoader *manager)
m_inCallback(false), m_isDone(false)
{
//Set here because we need to get the engine from the manager
- if (m_typeLoader->engine() && m_typeLoader->engine()->urlInterceptor())
- m_url = m_typeLoader->engine()->urlInterceptor()->intercept(m_url,
- (QQmlAbstractUrlInterceptor::DataType)m_type);
+ if (const QQmlEngine *qmlEngine = m_typeLoader->engine())
+ m_url = qmlEngine->interceptUrl(m_url, (QQmlAbstractUrlInterceptor::DataType)m_type);
}
/*! \internal */
@@ -290,7 +289,18 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
Q_ASSERT(status() != Error);
Q_ASSERT(m_errors.isEmpty());
- m_errors = errors; // Must be set before the m_data fence
+ // m_errors must be set before the m_data fence
+ m_errors.reserve(errors.count());
+ for (const QQmlError &error : errors) {
+ if (error.url().isEmpty()) {
+ QQmlError mutableError = error;
+ mutableError.setUrl(url());
+ m_errors.append(mutableError);
+ } else {
+ m_errors.append(error);
+ }
+ }
+
m_data.setStatus(Error);
if (dumpErrors()) {
@@ -314,18 +324,6 @@ void QQmlDataBlob::setError(const QQmlJS::DiagnosticMessage &error)
setError(e);
}
-void QQmlDataBlob::setError(const QVector<QQmlError> &errors)
-{
- QList<QQmlError> finalErrors;
- finalErrors.reserve(errors.count());
- for (const auto &error : errors) {
- QQmlError e = error;
- e.setUrl(url());
- finalErrors << e;
- }
- setError(finalErrors);
-}
-
void QQmlDataBlob::setError(const QString &description)
{
QQmlError e;
diff --git a/src/qml/qml/qqmldatablob_p.h b/src/qml/qml/qqmldatablob_p.h
index cc066d29a1..87e31a38f9 100644
--- a/src/qml/qml/qqmldatablob_p.h
+++ b/src/qml/qml/qqmldatablob_p.h
@@ -59,8 +59,10 @@
#include <QtNetwork/qnetworkreply.h>
#endif
+#include <QtQml/qqmlprivate.h>
#include <QtQml/qqmlerror.h>
#include <QtQml/qqmlabstracturlinterceptor.h>
+#include <QtQml/qqmlprivate.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qfileinfo.h>
@@ -132,13 +134,12 @@ protected:
void setError(const QQmlError &);
void setError(const QList<QQmlError> &errors);
void setError(const QQmlJS::DiagnosticMessage &error);
- void setError(const QVector<QQmlError> &errors);
void setError(const QString &description);
void addDependency(QQmlDataBlob *);
// Callbacks made in load thread
virtual void dataReceived(const SourceCodeData &) = 0;
- virtual void initializeFromCachedUnit(const QV4::CompiledData::Unit*) = 0;
+ virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) = 0;
virtual void done();
#if QT_CONFIG(qml_network)
virtual void networkError(QNetworkReply::NetworkError);
diff --git a/src/qml/qml/qqmldirdata.cpp b/src/qml/qml/qqmldirdata.cpp
index de74dfdf9b..9c42cbec13 100644
--- a/src/qml/qml/qqmldirdata.cpp
+++ b/src/qml/qml/qqmldirdata.cpp
@@ -87,7 +87,7 @@ void QQmlQmldirData::dataReceived(const SourceCodeData &data)
}
}
-void QQmlQmldirData::initializeFromCachedUnit(const QV4::CompiledData::Unit *)
+void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *)
{
Q_UNIMPLEMENTED();
}
diff --git a/src/qml/qml/qqmldirdata_p.h b/src/qml/qml/qqmldirdata_p.h
index 34f1ff1678..d8ca7886e6 100644
--- a/src/qml/qml/qqmldirdata_p.h
+++ b/src/qml/qml/qqmldirdata_p.h
@@ -73,7 +73,7 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QV4::CompiledData::Unit *) override;
+ void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) override;
private:
QString m_content;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 872a448bfd..fec4f2ba65 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -62,7 +62,6 @@
#include <private/qqmlboundsignal_p.h>
#include <private/qqmljsdiagnosticmessage_p.h>
#include <QtCore/qstandardpaths.h>
-#include <QtCore/qsettings.h>
#include <QtCore/qmetaobject.h>
#include <QDebug>
#include <QtCore/qcoreapplication.h>
@@ -75,7 +74,6 @@
#if QT_CONFIG(qml_network)
#include "qqmlnetworkaccessmanagerfactory.h"
#include <QNetworkAccessManager>
-#include <QtNetwork/qnetworkconfigmanager.h>
#endif
#include <private/qobject_p.h>
@@ -113,13 +111,13 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
QQmlPrivate::RegisterType type = {
0,
- 0,
- 0,
+ QMetaType(),
+ QMetaType(),
0,
nullptr,
reason,
- uri, versionMajor, versionMinor, qmlName, &staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject,
QQmlAttachedPropertiesFunc(),
nullptr,
@@ -131,7 +129,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
nullptr, nullptr,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
@@ -196,35 +194,6 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
bool QQmlEnginePrivate::qml_debugging_enabled = false;
bool QQmlEnginePrivate::s_designerMode = false;
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-void QQmlEnginePrivate::registerQuickTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
- // Also, don't use qmlRegisterTypesAndRevisions as that will auto-add future revisions.
-
- const char uri[] = "QtQuick";
-
- qmlRegisterType<QQmlComponent>(uri, 2, 0, "Component");
- qmlRegisterType<QObject>(uri, 2, 0, "QtObject");
- qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding");
- qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding");
- qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
-
- // Connections revision 3 was added in QtQml 2.3, but only in QtQuick 2.7.
- qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 7, "Connections", new QQmlConnectionsParser);
-
-#if QT_CONFIG(qml_animation)
- qmlRegisterType<QQmlTimer>(uri, 2, 0,"Timer");
-#endif
- qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory");
- qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory");
-#if QT_CONFIG(qml_locale)
- // Locale was added in QtQuick 2.0 and in QtQml 2.2
- qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
-#endif
-}
-#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
bool QQmlEnginePrivate::designerMode()
{
return s_designerMode;
@@ -657,7 +626,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
#if QT_CONFIG(qml_network)
networkAccessManager(nullptr), networkAccessManagerFactory(nullptr),
#endif
- urlInterceptor(nullptr), scarceResourcesRefCount(0), importDatabase(e), typeLoader(e),
+ scarceResourcesRefCount(0), importDatabase(e), typeLoader(e),
uniqueId(1), incubatorCount(0), incubationController(nullptr)
{
}
@@ -696,20 +665,21 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
{
if (QQmlData *d = QQmlData::get(o)) {
if (d->ownContext) {
- for (QQmlContextData *lc = d->ownContext->linkedContext; lc; lc = lc->linkedContext) {
+ for (QQmlRefPointer<QQmlContextData> lc = d->ownContext->linkedContext().data(); lc;
+ lc = lc->linkedContext()) {
lc->invalidate();
- if (lc->contextObject == o)
- lc->contextObject = nullptr;
+ if (lc->contextObject() == o)
+ lc->setContextObject(nullptr);
}
d->ownContext->invalidate();
- if (d->ownContext->contextObject == o)
- d->ownContext->contextObject = nullptr;
+ if (d->ownContext->contextObject() == o)
+ d->ownContext->setContextObject(nullptr);
d->ownContext = nullptr;
d->context = nullptr;
}
- if (d->outerContext && d->outerContext->contextObject == o)
- d->outerContext->contextObject = nullptr;
+ if (d->outerContext && d->outerContext->contextObject() == o)
+ d->outerContext->setContextObject(nullptr);
// Mark this object as in the process of deletion to
// prevent it resolving in bindings
@@ -880,10 +850,10 @@ void QQmlData::setQueuedForDeletion(QObject *object)
if (object) {
if (QQmlData *ddata = QQmlData::get(object)) {
if (ddata->ownContext) {
- Q_ASSERT(ddata->ownContext == ddata->context);
+ Q_ASSERT(ddata->ownContext.data() == ddata->context);
ddata->context->emitDestruction();
- if (ddata->ownContext->contextObject == object)
- ddata->ownContext->contextObject = nullptr;
+ if (ddata->ownContext->contextObject() == object)
+ ddata->ownContext->setContextObject(nullptr);
ddata->ownContext = nullptr;
ddata->context = nullptr;
}
@@ -1013,7 +983,7 @@ QQmlEngine::~QQmlEngine()
// Emit onDestruction signals for the root context before
// we destroy the contexts, engine, Singleton Types etc. that
// may be required to handle the destruction signal.
- QQmlContextData::get(rootContext())->emitDestruction();
+ QQmlContextPrivate::get(rootContext())->emitDestruction();
// clean up all singleton type instances which we own.
// we do this here and not in the private dtor since otherwise a crash can
@@ -1108,32 +1078,62 @@ QQmlContext *QQmlEngine::rootContext() const
return d->rootContext;
}
+#if QT_DEPRECATED_SINCE(6, 0)
/*!
\internal
+ \deprecated
This API is private for 5.1
- Sets the \a urlInterceptor to be used when resolving URLs in QML.
+ Returns the last QQmlAbstractUrlInterceptor. It must not be modified outside
+ the GUI thread.
+*/
+QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const
+{
+ Q_D(const QQmlEngine);
+ return d->urlInterceptors.last();
+}
+#endif
+
+/*!
+ Adds a \a urlInterceptor to be used when resolving URLs in QML.
This also applies to URLs used for loading script files and QML types.
- This should not be modifed while the engine is loading files, or URL
- selection may be inconsistent.
+ The URL interceptors should not be modifed while the engine is loading files,
+ or URL selection may be inconsistent. Multiple URL interceptors, when given,
+ will be called in the order they were added for each URL.
+
+ QQmlEngine does not take ownership of the interceptor and won't delete it.
*/
-void QQmlEngine::setUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
+void QQmlEngine::addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
{
Q_D(QQmlEngine);
- d->urlInterceptor = urlInterceptor;
+ d->urlInterceptors.append(urlInterceptor);
}
/*!
- \internal
- This API is private for 5.1
+ Remove a \a urlInterceptor that was previously added using
+ \l addUrlInterceptor. The URL interceptors should not be modifed while the
+ engine is loading files, or URL selection may be inconsistent.
- Returns the current QQmlAbstractUrlInterceptor. It must not be modified outside
- the GUI thread.
+ This does not delete the interceptor, but merely removes it from the engine.
+ You can re-use it on the same or a different engine afterwards.
*/
-QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const
+void QQmlEngine::removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
+{
+ Q_D(QQmlEngine);
+ d->urlInterceptors.removeOne(urlInterceptor);
+}
+
+/*!
+ Run the current URL interceptors on the given \a url of the given \a type and
+ return the result.
+ */
+QUrl QQmlEngine::interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const
{
Q_D(const QQmlEngine);
- return d->urlInterceptor;
+ QUrl result = url;
+ for (QQmlAbstractUrlInterceptor *interceptor : d->urlInterceptors)
+ result = interceptor->intercept(result, type);
+ return result;
}
void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
@@ -1361,7 +1361,7 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
QObject* example:
\code
class MySingleton : public QObject {
- Q_OBJECT
+ \Q_OBJECT
// Register as default constructed singleton.
QML_ELEMENT
@@ -1423,10 +1423,10 @@ QJSValue QQmlEngine::singletonInstance<QJSValue>(int qmlTypeId)
void QQmlEngine::retranslate()
{
Q_D(QQmlEngine);
- QQmlContextData *context = QQmlContextData::get(d->rootContext)->childContexts;
- while (context) {
+ for (QQmlRefPointer<QQmlContextData> context
+ = QQmlContextData::get(d->rootContext)->childContexts();
+ context; context = context->nextChild()) {
context->refreshExpressions();
- context = context->nextChild;
}
}
@@ -1470,78 +1470,10 @@ void QQmlEngine::setContextForObject(QObject *object, QQmlContext *context)
return;
}
- QQmlContextData *contextData = QQmlContextData::get(context);
+ QQmlRefPointer<QQmlContextData> contextData = QQmlContextData::get(context);
Q_ASSERT(data->context == nullptr);
- data->context = contextData;
- contextData->addObject(data);
-}
-
-/*!
- \enum QQmlEngine::ObjectOwnership
-
- ObjectOwnership controls whether or not QML automatically destroys the
- QObject when the corresponding JavaScript object is garbage collected by the
- engine. The two ownership options are:
-
- \value CppOwnership The object is owned by C++ code and QML will never delete
- it. The JavaScript destroy() method cannot be used on these objects. This
- option is similar to QScriptEngine::QtOwnership.
-
- \value JavaScriptOwnership The object is owned by JavaScript. When the object
- is returned to QML as the return value of a method call, QML will track it
- and delete it if there are no remaining JavaScript references to it and
- it has no QObject::parent(). An object tracked by one QQmlEngine will be
- deleted during that QQmlEngine's destructor. Thus, JavaScript references
- between objects with JavaScriptOwnership from two different engines will
- not be valid if one of these engines is deleted. This option is similar to
- QScriptEngine::ScriptOwnership.
-
- Generally an application doesn't need to set an object's ownership
- explicitly. QML uses a heuristic to set the default ownership. By default, an
- object that is created by QML has JavaScriptOwnership. The exception to this
- are the root objects created by calling QQmlComponent::create() or
- QQmlComponent::beginCreate(), which have CppOwnership by default. The
- ownership of these root-level objects is considered to have been transferred
- to the C++ caller.
-
- Objects not-created by QML have CppOwnership by default. The exception to this
- are objects returned from C++ method calls; their ownership will be set to
- JavaScriptOwnership. This applies only to explicit invocations of Q_INVOKABLE
- methods or slots, but not to property getter invocations.
-
- Calling setObjectOwnership() overrides the default ownership heuristic used by
- QML.
-*/
-
-/*!
- Sets the \a ownership of \a object.
-*/
-void QQmlEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
-{
- if (!object)
- return;
-
- QQmlData *ddata = QQmlData::get(object, true);
- if (!ddata)
- return;
-
- ddata->indestructible = (ownership == CppOwnership)?true:false;
- ddata->explicitIndestructibleSet = true;
-}
-
-/*!
- Returns the ownership of \a object.
-*/
-QQmlEngine::ObjectOwnership QQmlEngine::objectOwnership(QObject *object)
-{
- if (!object)
- return CppOwnership;
-
- QQmlData *ddata = QQmlData::get(object, false);
- if (!ddata)
- return CppOwnership;
- else
- return ddata->indestructible?CppOwnership:JavaScriptOwnership;
+ data->context = contextData.data();
+ contextData->addOwnedObject(data);
}
/*!
@@ -1577,7 +1509,7 @@ void qmlExecuteDeferred(QObject *object)
QQmlData *data = QQmlData::get(object);
if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object)) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine());
QQmlComponentPrivate::DeferredState state;
QQmlComponentPrivate::beginDeferred(ep, object, &state);
@@ -1599,7 +1531,7 @@ QQmlEngine *qmlEngine(const QObject *obj)
QQmlData *data = QQmlData::get(obj, false);
if (!data || !data->context)
return nullptr;
- return data->context->engine;
+ return data->context->engine();
}
static QObject *resolveAttachedProperties(QQmlAttachedPropertiesFunc pf, QQmlData *data,
@@ -1787,7 +1719,9 @@ void QQmlData::NotifyList::layout()
todo = nullptr;
}
-void QQmlData::deferData(int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlContextData *context)
+void QQmlData::deferData(
+ int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ const QQmlRefPointer<QQmlContextData> &context)
{
QQmlData::DeferredData *deferData = new QQmlData::DeferredData;
deferData->deferredIdx = objectIndex;
@@ -1881,8 +1815,8 @@ void QQmlData::destroyed(QObject *object)
nextContextObject->prevContextObject = prevContextObject;
if (prevContextObject)
*prevContextObject = nextContextObject;
- else if (outerContext && outerContext->contextObjects == this)
- outerContext->contextObjects = nextContextObject;
+ else if (outerContext && outerContext->ownedObjects() == this)
+ outerContext->setOwnedObjects(nextContextObject);
QQmlAbstractBinding *binding = bindings;
while (binding) {
@@ -2230,7 +2164,6 @@ void QQmlEngine::addPluginPath(const QString& path)
d->importDatabase.addPluginPath(path);
}
-
/*!
Returns the list of directories where the engine searches for
native plugins for imported modules (referenced in the \c qmldir file).
@@ -2274,7 +2207,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
{
Q_D(QQmlEngine);
- return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), -1, errors);
+ return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), QTypeRevision(), errors);
}
#endif
@@ -2331,17 +2264,6 @@ QString QQmlEngine::offlineStorageDatabaseFilePath(const QString &databaseName)
return d->offlineStorageDatabaseDirectory() + QLatin1String(md5.result().toHex());
}
-// #### Qt 6: Remove this function, it exists only for binary compatibility.
-/*!
- * \internal
- */
-bool QQmlEngine::addNamedBundle(const QString &name, const QString &fileName)
-{
- Q_UNUSED(name)
- Q_UNUSED(fileName)
- return false;
-}
-
QString QQmlEnginePrivate::offlineStorageDatabaseDirectory() const
{
Q_Q(const QQmlEngine);
@@ -2386,67 +2308,100 @@ int QQmlEnginePrivate::listType(int t) const
static QQmlPropertyCache *propertyCacheForPotentialInlineComponentType(int t, const QHash<int, QV4::ExecutableCompilationUnit *>::const_iterator &iter) {
- if (t != (*iter)->metaTypeId) {
+ if (t != (*iter)->metaTypeId.id()) {
// this is an inline component, and what we have in the iterator is currently the parent compilation unit
for (auto &&icDatum: (*iter)->inlineComponentData)
- if (icDatum.typeIds.id == t)
+ if (icDatum.typeIds.id.id() == t)
return (*iter)->propertyCaches.at(icDatum.objectIndex);
}
return (*iter)->rootPropertyCache().data();
}
+/*!
+ * \internal
+ *
+ * Look up by type's baseMetaObject.
+ */
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
{
- Locker locker(this);
- auto iter = m_compositeTypes.constFind(t);
- if (iter != m_compositeTypes.cend()) {
- return propertyCacheForPotentialInlineComponentType(t, iter);
- } else {
- QQmlType type = QQmlMetaType::qmlType(t);
- return QQmlMetaObject(type.baseMetaObject());
- }
+ if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t))
+ return QQmlMetaObject(composite);
+
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return QQmlMetaObject(type.baseMetaObject());
}
+/*!
+ * \internal
+ *
+ * Look up by type's metaObject.
+ */
QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
{
- Locker locker(this);
- auto iter = m_compositeTypes.constFind(t);
- if (iter != m_compositeTypes.cend()) {
- return propertyCacheForPotentialInlineComponentType(t, iter);
- } else {
- QQmlType type = QQmlMetaType::qmlType(t);
- return QQmlMetaObject(type.metaObject());
- }
+ if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t))
+ return QQmlMetaObject(composite);
+
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return QQmlMetaObject(type.metaObject());
}
+/*!
+ * \internal
+ *
+ * Look up by type's metaObject and version.
+ */
QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
{
- Locker locker(this);
- auto iter = m_compositeTypes.constFind(t);
- if (iter != m_compositeTypes.cend()) {
- return propertyCacheForPotentialInlineComponentType(t, iter);
- } else {
- QQmlType type = QQmlMetaType::qmlType(t);
- locker.unlock();
- return type.isValid() ? cache(type.metaObject()) : nullptr;
- }
+ if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t))
+ return composite;
+
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return type.isValid() ? cache(type.metaObject(), type.version()) : nullptr;
+}
+
+/*!
+ * \internal
+ *
+ * Look up by type's baseMetaObject and unspecified/any version.
+ * TODO: Is this correct? Passing a plain QTypeRevision() rather than QTypeRevision::zero() or
+ * the actual type's version seems strange. The behavior has been in place for a while.
+ */
+QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
+{
+ if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t))
+ return composite;
+
+ QQmlType type = QQmlMetaType::qmlType(t);
+ return type.isValid() ? cache(type.baseMetaObject(), QTypeRevision()) : nullptr;
}
-QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion)
+/*!
+ * \internal
+ *
+ * Look up by QQmlType and version. We only fall back to lookup by metaobject if the type
+ * has no revisiononed attributes here. Unspecified versions are interpreted as "any".
+ */
+QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, QTypeRevision version)
+{
+ if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t))
+ return composite;
+
+ QQmlType type = QQmlMetaType::qmlType(t);
+ if (!type.isValid())
+ return nullptr;
+
+ return type.containsRevisionedAttributes()
+ ? QQmlMetaType::propertyCache(type, version)
+ : cache(type.metaObject(), version);
+}
+
+QQmlPropertyCache *QQmlEnginePrivate::findPropertyCacheInCompositeTypes(int t) const
{
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
- if (iter != m_compositeTypes.cend()) {
- return propertyCacheForPotentialInlineComponentType(t, iter);
- } else {
- QQmlType type = QQmlMetaType::qmlType(t);
- locker.unlock();
-
- if (minorVersion >= 0)
- return type.isValid() ? cache(type, minorVersion) : nullptr;
- else
- return type.isValid() ? cache(type.baseMetaObject()) : nullptr;
- }
+ return (iter == m_compositeTypes.constEnd())
+ ? nullptr
+ : propertyCacheForPotentialInlineComponentType(t, iter);
}
void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
@@ -2456,10 +2411,9 @@ void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilation
Locker locker(this);
// The QQmlCompiledData is not referenced here, but it is removed from this
// hash in the QQmlCompiledData destructor
- m_compositeTypes.insert(compilationUnit->metaTypeId, compilationUnit);
- for (auto &&data: compilationUnit->inlineComponentData) {
- m_compositeTypes.insert(data.typeIds.id, compilationUnit);
- }
+ m_compositeTypes.insert(compilationUnit->metaTypeId.id(), compilationUnit);
+ for (auto &&data: compilationUnit->inlineComponentData)
+ m_compositeTypes.insert(data.typeIds.id.id(), compilationUnit);
}
void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
@@ -2467,9 +2421,9 @@ void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilati
compilationUnit->isRegisteredWithEngine = false;
Locker locker(this);
- m_compositeTypes.remove(compilationUnit->metaTypeId);
+ m_compositeTypes.remove(compilationUnit->metaTypeId.id());
for (auto&& icDatum: compilationUnit->inlineComponentData)
- m_compositeTypes.remove(icDatum.typeIds.id);
+ m_compositeTypes.remove(icDatum.typeIds.id.id());
}
QV4::ExecutableCompilationUnit *QQmlEnginePrivate::obtainExecutableCompilationUnit(int typeId)
@@ -2499,7 +2453,7 @@ QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type)
// should behave identically to QML singleton types.
q->setContextForObject(o, new QQmlContext(q->rootContext(), q));
}
- singletonInstances.insert(type, value);
+ singletonInstances.convertAndInsert(v4engine(), type, &value);
} else if (siinfo->qobjectCallback) {
QObject *o = siinfo->qobjectCallback(q, q);
@@ -2517,12 +2471,12 @@ QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type)
// should behave identically to QML singleton types.
q->setContextForObject(o, new QQmlContext(q->rootContext(), q));
value = q->newQObject(o);
- singletonInstances.insert(type, value);
+ singletonInstances.convertAndInsert(v4engine(), type, &value);
} else if (!siinfo->url.isEmpty()) {
QQmlComponent component(q, siinfo->url, QQmlComponent::PreferSynchronous);
QObject *o = component.beginCreate(q->rootContext());
value = q->newQObject(o);
- singletonInstances.insert(type, value);
+ singletonInstances.convertAndInsert(v4engine(), type, &value);
component.completeCreate();
}
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 31fe3a1849..aeb5756712 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -46,11 +46,10 @@
#include <QtQml/qjsengine.h>
#include <QtQml/qqml.h>
#include <QtQml/qqmlerror.h>
+#include <QtQml/qqmlabstracturlinterceptor.h>
QT_BEGIN_NAMESPACE
-class QQmlAbstractUrlInterceptor;
-
class Q_QML_EXPORT QQmlImageProviderBase
{
public:
@@ -112,7 +111,9 @@ public:
void setPluginPathList(const QStringList &paths);
void addPluginPath(const QString& dir);
- bool addNamedBundle(const QString &name, const QString &fileName);
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED bool addNamedBundle(const QString &, const QString &) { return false; }
+#endif
#if QT_CONFIG(library)
bool importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors);
@@ -125,8 +126,17 @@ public:
QNetworkAccessManager *networkAccessManager() const;
#endif
- void setUrlInterceptor(QQmlAbstractUrlInterceptor* urlInterceptor);
- QQmlAbstractUrlInterceptor* urlInterceptor() const;
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED void setUrlInterceptor(QQmlAbstractUrlInterceptor* urlInterceptor)
+ {
+ addUrlInterceptor(urlInterceptor);
+ }
+ QT_DEPRECATED QQmlAbstractUrlInterceptor *urlInterceptor() const;
+#endif
+
+ void addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor);
+ void removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor);
+ QUrl interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const;
void addImageProvider(const QString &id, QQmlImageProviderBase *);
QQmlImageProviderBase *imageProvider(const QString &id) const;
@@ -155,9 +165,6 @@ public:
static QQmlContext *contextForObject(const QObject *);
static void setContextForObject(QObject *, QQmlContext *);
- enum ObjectOwnership { CppOwnership, JavaScriptOwnership };
- static void setObjectOwnership(QObject *, ObjectOwnership);
- static ObjectOwnership objectOwnership(QObject *);
protected:
QQmlEngine(QQmlEnginePrivate &dd, QObject *p);
bool event(QEvent *) override;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 263c69e2d8..f8b8b187a5 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -59,7 +59,7 @@
#include "qqml.h"
#include "qqmlvaluetype_p.h"
#include "qqmlcontext.h"
-#include "qqmlcontext_p.h"
+#include "qqmlcontextdata_p.h"
#include "qqmlexpression.h"
#include "qqmlproperty_p.h"
#include "qqmlmetatype_p.h"
@@ -67,6 +67,7 @@
#include <private/qrecyclepool_p.h>
#include <private/qfieldlist_p.h>
#include <private/qv4engine_p.h>
+#include <private/qjsvalue_p.h>
#include <QtCore/qlist.h>
#include <QtCore/qpair.h>
@@ -105,6 +106,7 @@ struct QObjectForeign {
Q_GADGET
QML_FOREIGN(QObject)
QML_NAMED_ELEMENT(QtObject)
+ QML_ADDED_IN_VERSION(2, 0)
Q_CLASSINFO("QML.Root", "QML")
};
@@ -177,8 +179,7 @@ public:
QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders;
QSharedPointer<QQmlImageProviderBase> imageProvider(const QString &providerId) const;
-
- QQmlAbstractUrlInterceptor* urlInterceptor;
+ QList<QQmlAbstractUrlInterceptor *> urlInterceptors;
int scarceResourcesRefCount;
void referenceScarceResources();
@@ -204,7 +205,7 @@ public:
QIntrusiveList<Incubator, &Incubator::next> incubatorList;
unsigned int incubatorCount;
QQmlIncubationController *incubationController;
- void incubate(QQmlIncubator &, QQmlContextData *);
+ void incubate(QQmlIncubator &, const QQmlRefPointer<QQmlContextData> &);
// These methods may be called from any thread
inline bool isEngineThread() const;
@@ -216,7 +217,7 @@ public:
QString offlineStorageDatabaseDirectory() const;
// These methods may be called from the loader thread
- inline QQmlPropertyCache *cache(const QQmlType &, int);
+ inline QQmlPropertyCache *cache(const QQmlType &, QTypeRevision version);
using QJSEnginePrivate::cache;
// These methods may be called from the loader thread
@@ -228,7 +229,8 @@ public:
QQmlMetaObject rawMetaObjectForType(int) const;
QQmlMetaObject metaObjectForType(int) const;
QQmlPropertyCache *propertyCacheForType(int);
- QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1);
+ QQmlPropertyCache *rawPropertyCacheForType(int);
+ QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version);
void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId);
@@ -253,16 +255,13 @@ public:
inline static QQmlEnginePrivate *get(QQmlEngine *e);
inline static const QQmlEnginePrivate *get(const QQmlEngine *e);
inline static QQmlEnginePrivate *get(QQmlContext *c);
- inline static QQmlEnginePrivate *get(QQmlContextData *c);
+ inline static QQmlEnginePrivate *get(const QQmlRefPointer<QQmlContextData> &c);
inline static QQmlEngine *get(QQmlEnginePrivate *p);
inline static QQmlEnginePrivate *get(QV4::ExecutionEngine *e);
static QList<QQmlError> qmlErrorFromDiagnostics(const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages);
static void defineModule();
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- static void registerQuickTypes();
-#endif
static bool designerMode();
static void activateDesignerMode();
@@ -287,7 +286,20 @@ public:
}
private:
- QHash<QQmlType, QJSValue> singletonInstances;
+ class SingletonInstances : private QHash<QQmlType, QJSValue>
+ {
+ public:
+ void convertAndInsert(QV4::ExecutionEngine *engine, const QQmlType &type, QJSValue *value)
+ {
+ QJSValuePrivate::manageStringOnV4Heap(engine, value);
+ insert(type, *value);
+ }
+
+ using QHash<QQmlType, QJSValue>::value;
+ using QHash<QQmlType, QJSValue>::take;
+ };
+
+ SingletonInstances singletonInstances;
QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
// These members must be protected by a QQmlEnginePrivate::Locker as they are required by
@@ -301,6 +313,7 @@ private:
void doDeleteInEngineThread();
void cleanupScarceResources();
+ QQmlPropertyCache *findPropertyCacheInCompositeTypes(int t) const;
};
/*
@@ -399,15 +412,13 @@ Returns a QQmlPropertyCache for \a type with \a minorVersion.
The returned cache is not referenced, so if it is to be stored, call addref().
*/
-QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersion)
+QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, QTypeRevision version)
{
Q_ASSERT(type.isValid());
-
- if (minorVersion == -1 || !type.containsRevisionedAttributes())
- return cache(type.metaObject(), minorVersion);
+ Q_ASSERT(type.containsRevisionedAttributes());
Locker locker(this);
- return QQmlMetaType::propertyCache(type, minorVersion);
+ return QQmlMetaType::propertyCache(type, version);
}
QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e)
@@ -431,14 +442,24 @@ const QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlEngine *e)
return e ? e->d_func() : nullptr;
}
+template<typename Context>
+QQmlEnginePrivate *contextEngine(const Context &context)
+{
+ if (!context)
+ return nullptr;
+ if (QQmlEngine *engine = context->engine())
+ return QQmlEnginePrivate::get(engine);
+ return nullptr;
+}
+
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContext *c)
{
- return (c && c->engine()) ? QQmlEnginePrivate::get(c->engine()) : nullptr;
+ return contextEngine(c);
}
-QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContextData *c)
+QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlRefPointer<QQmlContextData> &c)
{
- return (c && c->engine) ? QQmlEnginePrivate::get(c->engine) : nullptr;
+ return contextEngine(c);
}
QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index f6a5afb891..5864c3245c 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -63,7 +63,8 @@ QQmlExpressionPrivate::~QQmlExpressionPrivate()
{
}
-void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QObject *me)
+void QQmlExpressionPrivate::init(const QQmlRefPointer<QQmlContextData> &ctxt, const QString &expr,
+ QObject *me)
{
expression = expr;
@@ -72,10 +73,11 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb
expressionFunctionValid = false;
}
-void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFunction, QObject *me)
+void QQmlExpressionPrivate::init(const QQmlRefPointer<QQmlContextData> &ctxt,
+ QV4::Function *runtimeFunction, QObject *me)
{
expressionFunctionValid = true;
- QV4::ExecutionEngine *engine = ctxt->engine->handle();
+ QV4::ExecutionEngine *engine = ctxt->engine()->handle();
QV4::Scope scope(engine);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(engine->rootContext(), ctxt, me));
setupFunction(qmlContext, runtimeFunction);
@@ -144,20 +146,24 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid()))
return;
- QQmlContextData *evalCtxtData = QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context);
+ QQmlRefPointer<QQmlContextData> evalCtxtData
+ = QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context);
QObject *scopeObject = scope ? scope : scriptPrivate->scope;
QV4::Function *runtimeFunction = nullptr;
if (scriptPrivate->context) {
- QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
+ QQmlRefPointer<QQmlContextData> ctxtdata = QQmlContextData::get(scriptPrivate->context);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
- if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit) {
+ if (engine
+ && ctxtdata
+ && !ctxtdata->urlString().isEmpty()
+ && ctxtdata->typeCompilationUnit()) {
d->url = ctxtdata->urlString();
d->line = scriptPrivate->lineNumber;
d->column = scriptPrivate->columnNumber;
if (scriptPrivate->bindingId != QQmlBinding::Invalid)
- runtimeFunction = ctxtdata->typeCompilationUnit->runtimeFunctions.at(scriptPrivate->bindingId);
+ runtimeFunction = ctxtdata->typeCompilationUnit()->runtimeFunctions.at(scriptPrivate->bindingId);
}
}
@@ -175,10 +181,8 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
If specified, the \a scope object's properties will also be in scope during
the expression's execution.
*/
-QQmlExpression::QQmlExpression(QQmlContext *ctxt,
- QObject *scope,
- const QString &expression,
- QObject *parent)
+QQmlExpression::QQmlExpression(QQmlContext *ctxt, QObject *scope, const QString &expression,
+ QObject *parent)
: QObject(*new QQmlExpressionPrivate, parent)
{
Q_D(QQmlExpression);
@@ -188,12 +192,10 @@ QQmlExpression::QQmlExpression(QQmlContext *ctxt,
/*!
\internal
*/
-QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope,
- const QString &expression)
-: QObject(*new QQmlExpressionPrivate, nullptr)
+QQmlExpression::QQmlExpression(QQmlExpressionPrivate &dd, QObject *parent) : QObject(dd, parent)
{
- Q_D(QQmlExpression);
- d->init(ctxt, expression, scope);
+// Q_D(QQmlExpression);
+// d->init(QQmlContextData::get(ctxt), expression, scope);
}
/*!
@@ -210,7 +212,7 @@ QQmlExpression::~QQmlExpression()
QQmlEngine *QQmlExpression::engine() const
{
Q_D(const QQmlExpression);
- return d->context()?d->context()->engine:nullptr;
+ return d->engine();
}
/*!
@@ -220,8 +222,7 @@ QQmlEngine *QQmlExpression::engine() const
QQmlContext *QQmlExpression::context() const
{
Q_D(const QQmlExpression);
- QQmlContextData *data = d->context();
- return data?data->asQQmlContext():nullptr;
+ return d->publicContext();
}
/*!
@@ -265,7 +266,7 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
{
Q_Q(QQmlExpression);
- if (!context() || !context()->isValid()) {
+ if (!hasValidContext()) {
qWarning("QQmlExpression: Attempted to evaluate an expression in an invalid context");
return QVariant();
}
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index 0eceeb12e1..c9719aec52 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -90,7 +90,7 @@ Q_SIGNALS:
void valueChanged();
private:
- QQmlExpression(QQmlContextData *, QObject *, const QString &);
+ QQmlExpression(QQmlExpressionPrivate &dd, QObject *parent);
Q_DISABLE_COPY(QQmlExpression)
Q_DECLARE_PRIVATE(QQmlExpression)
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index da10b31b2c..3df839a6a2 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -70,8 +70,8 @@ public:
QQmlExpressionPrivate();
~QQmlExpressionPrivate() override;
- void init(QQmlContextData *, const QString &, QObject *);
- void init(QQmlContextData *, QV4::Function *runtimeFunction, QObject *);
+ void init(const QQmlRefPointer<QQmlContextData> &, const QString &, QObject *);
+ void init(const QQmlRefPointer<QQmlContextData> &, QV4::Function *runtimeFunction, QObject *);
QVariant value(bool *isUndefined = nullptr);
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 7a62c967e7..f779199b74 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -117,6 +117,16 @@ QUrl QQmlExtensionPlugin::baseUrl() const
}
/*!
+ \since 6.0
+
+ Override this method to unregister types manually registered in registerTypes.
+*/
+void QQmlExtensionPlugin::unregisterTypes()
+{
+
+}
+
+/*!
\internal
*/
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index ef7ff422cd..78371106bd 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -64,6 +64,7 @@ public:
QUrl baseUrl() const;
void registerTypes(const char *uri) override = 0;
+ virtual void unregisterTypes();
void initializeEngine(QQmlEngine *engine, const char *uri) override;
private:
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
index 32dce8b4bc..aaddfa628c 100644
--- a/src/qml/qml/qqmlfileselector.cpp
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -39,15 +39,16 @@
#include <QtCore/QFileSelector>
#include <QtQml/QQmlAbstractUrlInterceptor>
+#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/private/qqmlapplicationengine_p.h>
#include <qobjectdefs.h>
#include "qqmlfileselector.h"
#include "qqmlfileselector_p.h"
+#include "qqmlengine_p.h"
#include <QDebug>
QT_BEGIN_NAMESPACE
-typedef QHash<QQmlAbstractUrlInterceptor*, QQmlFileSelector*> interceptorSelectorMap;
-Q_GLOBAL_STATIC(interceptorSelectorMap, interceptorInstances);
/*!
\class QQmlFileSelector
\since 5.2
@@ -104,8 +105,7 @@ QQmlFileSelector::QQmlFileSelector(QQmlEngine* engine, QObject* parent)
{
Q_D(QQmlFileSelector);
d->engine = engine;
- interceptorInstances()->insert(d->myInstance.data(), this);
- d->engine->setUrlInterceptor(d->myInstance.data());
+ d->engine->addUrlInterceptor(d->myInstance.data());
}
/*!
@@ -114,11 +114,10 @@ QQmlFileSelector::QQmlFileSelector(QQmlEngine* engine, QObject* parent)
QQmlFileSelector::~QQmlFileSelector()
{
Q_D(QQmlFileSelector);
- if (d->engine && QQmlFileSelector::get(d->engine) == this) {
- d->engine->setUrlInterceptor(nullptr);
+ if (d->engine) {
+ d->engine->removeUrlInterceptor(d->myInstance.data());
d->engine = nullptr;
}
- interceptorInstances()->remove(d->myInstance.data());
}
/*!
@@ -173,35 +172,50 @@ void QQmlFileSelector::setSelector(QFileSelector *selector)
Use this when extra selectors are all you need to avoid having to create your own
QFileSelector instance.
*/
-void QQmlFileSelector::setExtraSelectors(QStringList &strings)
-{
- Q_D(QQmlFileSelector);
- d->selector->setExtraSelectors(strings);
-}
-
-
-/*!
- Adds extra selectors contained in \a strings to the current QFileSelector being used.
- Use this when extra selectors are all you need to avoid having to create your own
- QFileSelector instance.
-*/
void QQmlFileSelector::setExtraSelectors(const QStringList &strings)
{
Q_D(QQmlFileSelector);
d->selector->setExtraSelectors(strings);
}
+#if QT_DEPRECATED_SINCE(6, 0)
/*!
+ \deprecated
Gets the QQmlFileSelector currently active on the target \a engine.
+
+ This method is deprecated. You should not retrieve the files selector from an
+ engine after setting it. It may be in use.
+
+ If the \a engine passed here is a QQmlApplicationEngine that hasn't loaded any
+ QML files, yet, it will be initialized. Any later calls to
+ QQmlApplicationEngine::setExtraFileSelectors() will have no effect.
+
+ \sa QQmlApplicationEngine
*/
QQmlFileSelector* QQmlFileSelector::get(QQmlEngine* engine)
{
- //Since I think we still can't use dynamic_cast inside Qt...
- QQmlAbstractUrlInterceptor* current = engine->urlInterceptor();
- if (current && interceptorInstances()->contains(current))
- return interceptorInstances()->value(current);
+ QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
+
+ if (qobject_cast<QQmlApplicationEngine *>(engine)) {
+ auto *appEnginePrivate = static_cast<QQmlApplicationEnginePrivate *>(enginePrivate);
+ if (!appEnginePrivate->isInitialized) {
+ appEnginePrivate->init();
+ appEnginePrivate->isInitialized = true;
+ }
+ }
+
+ const QUrl nonEmptyInvalid(QLatin1String(":"));
+ for (QQmlAbstractUrlInterceptor *interceptor : enginePrivate->urlInterceptors) {
+ const QUrl result = interceptor->intercept(
+ nonEmptyInvalid, QQmlAbstractUrlInterceptor::UrlString);
+ if (result.scheme() == QLatin1String("type")
+ && result.path() == QLatin1String("fileselector")) {
+ return static_cast<QQmlFileSelectorInterceptor *>(interceptor)->d->q_func();
+ }
+ }
return nullptr;
}
+#endif
/*!
\internal
@@ -216,9 +230,12 @@ QQmlFileSelectorInterceptor::QQmlFileSelectorInterceptor(QQmlFileSelectorPrivate
*/
QUrl QQmlFileSelectorInterceptor::intercept(const QUrl &path, DataType type)
{
- if ( type == QQmlAbstractUrlInterceptor::QmldirFile ) //Don't intercept qmldir files, to prevent double interception
- return path;
- return d->selector->select(path);
+ if (!path.isEmpty() && !path.isValid())
+ return QUrl(QLatin1String("type:fileselector"));
+
+ return type == QQmlAbstractUrlInterceptor::QmldirFile
+ ? path // Don't intercept qmldir files, to prevent double interception
+ : d->selector->select(path);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
index 9b70e3936d..0aeea6775f 100644
--- a/src/qml/qml/qqmlfileselector.h
+++ b/src/qml/qml/qqmlfileselector.h
@@ -58,9 +58,11 @@ public:
~QQmlFileSelector() override;
QFileSelector *selector() const Q_DECL_NOTHROW;
void setSelector(QFileSelector *selector);
- void setExtraSelectors(QStringList &strings); // TODO Qt6: remove
void setExtraSelectors(const QStringList &strings);
- static QQmlFileSelector* get(QQmlEngine*);
+
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED static QQmlFileSelector *get(QQmlEngine*);
+#endif
private:
Q_DISABLE_COPY(QQmlFileSelector)
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index acebb6bac3..b6a1075c67 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -283,6 +283,10 @@ QVariant QQmlColorProvider::fromHslF(double, double, double, double) { return QV
QVariant QQmlColorProvider::fromHsvF(double, double, double, double) { return QVariant(); }
QVariant QQmlColorProvider::lighter(const QVariant &, qreal) { return QVariant(); }
QVariant QQmlColorProvider::darker(const QVariant &, qreal) { return QVariant(); }
+QVariant QQmlColorProvider::alpha(const QVariant &, qreal)
+{
+ return QVariant();
+}
QVariant QQmlColorProvider::tint(const QVariant &, const QVariant &) { return QVariant(); }
static QQmlColorProvider *colorProvider = nullptr;
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 3c540a6124..b0f239e398 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -278,6 +278,7 @@ public:
virtual QVariant fromHsvF(double, double, double, double);
virtual QVariant lighter(const QVariant &, qreal);
virtual QVariant darker(const QVariant &, qreal);
+ virtual QVariant alpha(const QVariant &, qreal);
virtual QVariant tint(const QVariant &, const QVariant &);
};
diff --git a/src/qml/qml/qqmlguardedcontextdata_p.h b/src/qml/qml/qqmlguardedcontextdata_p.h
new file mode 100644
index 0000000000..0b24c04305
--- /dev/null
+++ b/src/qml/qml/qqmlguardedcontextdata_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 QQMLGUARDEDCONTEXTDATA_P_H
+#define QQMLGUARDEDCONTEXTDATA_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 <QtQml/private/qqmlglobal_p.h>
+#include <QtQml/private/qqmlcontextdata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlGuardedContextData
+{
+ Q_DISABLE_COPY(QQmlGuardedContextData);
+public:
+ QQmlGuardedContextData() = default;
+ ~QQmlGuardedContextData() { unlink(); }
+
+ QQmlGuardedContextData(QQmlGuardedContextData &&) = default;
+ QQmlGuardedContextData &operator=(QQmlGuardedContextData &&) = default;
+
+ QQmlGuardedContextData(QQmlRefPointer<QQmlContextData> data)
+ {
+ setContextData(std::move(data));
+ }
+
+ QQmlGuardedContextData &operator=(QQmlRefPointer<QQmlContextData> d)
+ {
+ setContextData(std::move(d));
+ return *this;
+ }
+
+ QQmlRefPointer<QQmlContextData> contextData() const { return m_contextData; }
+ void setContextData(QQmlRefPointer<QQmlContextData> contextData)
+ {
+ if (m_contextData.data() == contextData.data())
+ return;
+ unlink();
+
+ if (contextData) {
+ m_contextData = std::move(contextData);
+ m_next = m_contextData->m_contextGuards;
+ if (m_next)
+ m_next->m_prev = &m_next;
+
+ m_contextData->m_contextGuards = this;
+ m_prev = &m_contextData->m_contextGuards;
+ }
+ }
+
+ bool isNull() const { return !m_contextData; }
+
+ operator const QQmlRefPointer<QQmlContextData> &() const { return m_contextData; }
+ QQmlContextData &operator*() const { return m_contextData.operator*(); }
+ QQmlContextData *operator->() const { return m_contextData.operator->(); }
+
+ QQmlGuardedContextData *next() const { return m_next; }
+
+ void reset()
+ {
+ m_contextData = nullptr;
+ m_next = nullptr;
+ m_prev = nullptr;
+ }
+
+private:
+ void unlink()
+ {
+ if (m_prev) {
+ *m_prev = m_next;
+ if (m_next)
+ m_next->m_prev = m_prev;
+ reset();
+ }
+ }
+
+ QQmlRefPointer<QQmlContextData> m_contextData;
+ QQmlGuardedContextData *m_next = nullptr;
+ QQmlGuardedContextData **m_prev = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLGUARDEDCONTEXTDATA_P_H
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index c3f6a9057d..08e43c1341 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -161,9 +161,17 @@ void qmlClearEnginePlugins()
#if QT_CONFIG(library)
for (auto &plugin : qAsConst(*plugins)) {
QPluginLoader* loader = plugin.loader;
- if (loader && !loader->unload())
- qWarning("Unloading %s failed: %s", qPrintable(plugin.uri), qPrintable(loader->errorString()));
- delete loader;
+ if (loader) {
+ auto extensionPlugin = qobject_cast<QQmlExtensionPlugin *>(loader->instance());
+ if (extensionPlugin) {
+ extensionPlugin->unregisterTypes();
+ }
+#ifndef Q_OS_MACOS
+ if (!loader->unload())
+ qWarning("Unloading %s failed: %s", qPrintable(plugin.uri), qPrintable(loader->errorString()));
+ delete loader;
+#endif
+ }
}
#endif
plugins->clear();
@@ -213,12 +221,12 @@ public:
QQmlImportNamespace *importNamespace(const QString &prefix) const;
bool addLibraryImport(const QString& uri, const QString &prefix,
- int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete,
+ QTypeRevision version, const QString &qmldirIdentifier,
+ const QString &qmldirUrl, bool incomplete,
QQmlImportDatabase *database,
QList<QQmlError> *errors);
- bool addFileImport(const QString &uri, const QString &prefix,
- int vmaj, int vmin,
+ bool addFileImport(const QString &uri, const QString &prefix, QTypeRevision version,
bool isImplicitImport, bool incomplete, QQmlImportDatabase *database,
QList<QQmlError> *errors);
@@ -227,7 +235,7 @@ public:
QQmlImportDatabase *database,
QList<QQmlError> *errors);
- bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
+ bool resolveType(const QHashedStringRef &type, QTypeRevision *version_return,
QQmlType *type_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
bool *typeRecursionDetected = nullptr);
@@ -247,14 +255,13 @@ public:
QQmlTypeLoader *typeLoader;
static QQmlImports::LocalQmldirResult locateLocalQmldir(
- const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ const QString &uri, QTypeRevision version, QQmlImportDatabase *database,
QString *outQmldirFilePath, QString *outUrl);
- static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
- QList<QQmlError> *errors);
+ static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri,
+ QTypeRevision version, QList<QQmlError> *errors);
- bool importExtension(const QString &absoluteFilePath, const QString &uri,
- int vmaj, int vmin,
+ bool importExtension(const QString &absoluteFilePath, const QString &uri, QTypeRevision version,
QQmlImportDatabase *database,
const QQmlTypeLoaderQmldirContent &qmldir,
QList<QQmlError> *errors);
@@ -264,10 +271,10 @@ public:
QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database);
- QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace,
- const QString &uri, const QString &url,
- int vmaj, int vmin, QV4::CompiledData::Import::ImportType type,
- QList<QQmlError> *errors, bool lowPrecedence = false);
+ QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri,
+ const QString &url, QTypeRevision version,
+ QV4::CompiledData::Import::ImportType type,
+ QList<QQmlError> *errors, bool lowPrecedence = false);
bool populatePluginPairVector(QVector<StaticPluginPair> &result, const QString &uri, const QStringList &versionUris,
const QString &qmldirPath, QList<QQmlError> *errors);
@@ -344,9 +351,9 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
- QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion);
+ QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
- cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->minversion));
+ cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->version));
}
}
@@ -360,10 +367,10 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
- QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion);
+ QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
QQmlImportRef &typeimport = cache->m_namedImports[set.prefix];
- typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion));
+ typeimport.modules.append(QQmlTypeModuleVersion(module, import->version));
}
}
}
@@ -395,36 +402,35 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports::
const QQmlDirComponents &components = import->qmlDirComponents;
- const int importMajorVersion = import->majversion;
- const int importMinorVersion = import->minversion;
- auto shouldSkipSingleton = [importMajorVersion, importMinorVersion](int singletonMajorVersion, int singletonMinorVersion) -> bool {
- return importMajorVersion != -1 &&
- (singletonMajorVersion > importMajorVersion || (singletonMajorVersion == importMajorVersion && singletonMinorVersion > importMinorVersion));
+ const QTypeRevision importVersion = import->version;
+ auto shouldSkipSingleton = [importVersion](QTypeRevision singletonVersion) -> bool {
+ return importVersion.hasMajorVersion() &&
+ (singletonVersion.majorVersion() > importVersion.majorVersion()
+ || (singletonVersion.majorVersion() == importVersion.majorVersion()
+ && singletonVersion.minorVersion() > importVersion.minorVersion()));
};
ConstIterator cend = components.constEnd();
for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) {
if (cit->singleton && excludeBaseUrl(import->url, cit->fileName, baseUrl.toString())) {
- if (shouldSkipSingleton(cit->majorVersion, cit->minorVersion))
+ if (shouldSkipSingleton(cit->version))
continue;
QQmlImports::CompositeSingletonReference ref;
ref.typeName = cit->typeName;
ref.prefix = set.prefix;
- ref.majorVersion = cit->majorVersion;
- ref.minorVersion = cit->minorVersion;
+ ref.version = cit->version;
resultList.append(ref);
}
}
- if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) {
+ if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version)) {
module->walkCompositeSingletons([&resultList, &set, &shouldSkipSingleton](const QQmlType &singleton) {
- if (shouldSkipSingleton(singleton.majorVersion(), singleton.minorVersion()))
+ if (shouldSkipSingleton(singleton.version()))
return;
QQmlImports::CompositeSingletonReference ref;
ref.typeName = singleton.elementName();
ref.prefix = set.prefix;
- ref.majorVersion = singleton.majorVersion();
- ref.minorVersion = singleton.minorVersion();
+ ref.version = singleton.version();
resultList.append(ref);
});
}
@@ -461,9 +467,9 @@ QList<QQmlImports::CompositeSingletonReference> QQmlImports::resolvedCompositeSi
if (lhs.typeName != rhs.typeName)
return lhs.typeName < rhs.typeName;
- return lhs.majorVersion != rhs.majorVersion
- ? lhs.majorVersion < rhs.majorVersion
- : lhs.minorVersion < rhs.minorVersion;
+ return lhs.version.majorVersion() != rhs.version.majorVersion()
+ ? lhs.version.majorVersion() < rhs.version.majorVersion()
+ : lhs.version.minorVersion() < rhs.version.minorVersion();
});
return compositeSingletons;
@@ -532,7 +538,8 @@ static QString joinStringRefs(const QVector<QStringRef> &refs, const QChar &sep)
- base/QtQml.2/Models/qmldir
- base/QtQml/Models/qmldir
*/
-QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin)
+QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths,
+ QTypeRevision version)
{
const QVector<QStringRef> parts = uri.splitRef(Dot, Qt::SkipEmptyParts);
@@ -540,8 +547,21 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi
// fully & partially versioned parts + 1 unversioned for each base path
qmlDirPathsPaths.reserve(basePaths.count() * (2 * parts.count() + 1));
- for (int version = FullyVersioned; version <= Unversioned; ++version) {
- const QString ver = versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version));
+ for (int versionMode = FullyVersioned; versionMode <= Unversioned; ++versionMode) {
+ switch (versionMode) {
+ case FullyVersioned:
+ if (!version.hasMinorVersion())
+ continue;
+ break;
+ case PartiallyVersioned:
+ if (!version.hasMajorVersion())
+ continue;
+ break;
+ default:
+ break;
+ }
+
+ const QString ver = versionString(version, QQmlImports::ImportVersion(versionMode));
for (const QString &path : basePaths) {
QString dir = path;
@@ -551,7 +571,7 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi
// append to the end
qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver + Slash_qmldir;
- if (version != Unversioned) {
+ if (versionMode != Unversioned) {
// insert in the middle
for (int index = parts.count() - 2; index >= 0; --index) {
qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash)
@@ -565,14 +585,14 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi
return qmlDirPathsPaths;
}
-QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version)
+QString QQmlImports::versionString(QTypeRevision version, ImportVersion versionMode)
{
- if (version == QQmlImports::FullyVersioned) {
+ if (versionMode == QQmlImports::FullyVersioned) {
// extension with fully encoded version number (eg. MyModule.3.2)
- return QString::asprintf(".%d.%d", vmaj, vmin);
- } else if (version == QQmlImports::PartiallyVersioned) {
+ return QString::asprintf(".%d.%d", version.majorVersion(), version.minorVersion());
+ } else if (versionMode == QQmlImports::PartiallyVersioned) {
// extension with encoded version major (eg. MyModule.3)
- return QString::asprintf(".%d", vmaj);
+ return QString::asprintf(".%d", version.majorVersion());
} // else extension without version number (eg. MyModule)
return QString();
}
@@ -591,7 +611,7 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version)
\sa addFileImport(), addLibraryImport
*/
bool QQmlImports::resolveType(const QHashedStringRef &type,
- QQmlType *type_return, int *vmaj, int *vmin,
+ QQmlType *type_return, QTypeRevision *version_return,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
bool *typeRecursionDetected) const
@@ -603,7 +623,7 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
return true;
}
if (type_return) {
- if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType,
+ if (d->resolveType(type, version_return, type_return, errors, registrationType,
typeRecursionDetected)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
@@ -627,7 +647,9 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
return false;
}
-bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors)
+bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl,
+ const QQmlTypeLoaderQmldirContent &qmldir,
+ QQmlImportNamespace *nameSpace, QList<QQmlError> *errors)
{
Q_ASSERT(resolvedUrl.endsWith(Slash));
url = resolvedUrl;
@@ -648,24 +670,27 @@ bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQml
}
}
- qmlDirScripts = getVersionedScripts(scripts, majversion, minversion);
+ qmlDirScripts = getVersionedScripts(scripts, version);
}
return true;
}
-QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin)
+QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts,
+ QTypeRevision version)
{
QMap<QString, QQmlDirParser::Script> versioned;
for (QList<QQmlDirParser::Script>::const_iterator sit = qmldirscripts.constBegin();
sit != qmldirscripts.constEnd(); ++sit) {
// Only include scripts that match our requested version
- if (((vmaj == -1) || (sit->majorVersion == vmaj)) &&
- ((vmin == -1) || (sit->minorVersion <= vmin))) {
+ if ((!version.hasMajorVersion() || (sit->version.majorVersion() == version.majorVersion()))
+ && (!version.hasMinorVersion()
+ || (sit->version.minorVersion() <= version.minorVersion()))) {
// Load the highest version that matches
QMap<QString, QQmlDirParser::Script>::iterator vit = versioned.find(sit->nameSpace);
- if (vit == versioned.end() || (vit->minorVersion < sit->minorVersion)) {
+ if (vit == versioned.end()
+ || (vit->version.minorVersion() < sit->version.minorVersion())) {
versioned.insert(sit->nameSpace, *sit);
}
}
@@ -685,30 +710,27 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml
If the return pointer is 0, the corresponding search is not done.
*/
bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type,
- QQmlType *type_return, int *vmaj, int *vmin,
+ QQmlType *type_return, QTypeRevision *version_return,
QQmlType::RegistrationType registrationType) const
{
- return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return, nullptr, nullptr, registrationType);
+ return ns->resolveType(d->typeLoader, type, version_return, type_return, nullptr, nullptr,
+ registrationType);
}
bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor, QQmlType *type_return, QString *base,
- bool *typeRecursionDetected,
+ QTypeRevision *version_return, QQmlType *type_return,
+ QString *base, bool *typeRecursionDetected,
QQmlType::RegistrationType registrationType,
QQmlImport::RecursionRestriction recursionRestriction,
QList<QQmlError> *errors) const
{
- if (majversion >= 0 && minversion >= 0) {
- QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
- if (t.isValid()) {
- if (vmajor)
- *vmajor = majversion;
- if (vminor)
- *vminor = minversion;
- if (type_return)
- *type_return = t;
- return true;
- }
+ QQmlType t = QQmlMetaType::qmlType(type, uri, version);
+ if (t.isValid()) {
+ if (version_return)
+ *version_return = version;
+ if (type_return)
+ *type_return = t;
+ return true;
}
const QString typeStr = type.toString();
@@ -764,14 +786,16 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
break;
}
- // importing version -1 means import ALL versions
- if ((majversion == -1) ||
- (implicitlyImported && c.internal) || // allow the implicit import of internal types
- (c.majorVersion == majversion && c.minorVersion <= minversion)) {
+ // importing invalid version means import ALL versions
+ if (!version.hasMajorVersion() || (implicitlyImported && c.internal)
+ // allow the implicit import of internal types
+ || (c.version.majorVersion() == version.majorVersion()
+ && c.version.minorVersion() <= version.minorVersion())) {
// Is this better than the previous candidate?
- if ((candidate == end) ||
- (c.majorVersion > candidate->majorVersion) ||
- ((c.majorVersion == candidate->majorVersion) && (c.minorVersion > candidate->minorVersion))) {
+ if ((candidate == end)
+ || (c.version.majorVersion() > candidate->version.majorVersion())
+ || ((c.version.majorVersion() == candidate->version.majorVersion())
+ && (c.version.minorVersion() > candidate->version.minorVersion()))) {
if (base) {
componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName);
if (c.internal) {
@@ -799,12 +823,9 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
if (!base) // ensure we have a componentUrl
componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName);
QQmlType returnType = QQmlMetaType::typeForUrl(componentUrl, type, isCompositeSingleton,
- nullptr, candidate->majorVersion,
- candidate->minorVersion);
- if (vmajor)
- *vmajor = candidate->majorVersion;
- if (vminor)
- *vminor = candidate->minorVersion;
+ nullptr, candidate->version);
+ if (version_return)
+ *version_return = candidate->version;
if (type_return)
*type_return = returnType;
return returnType.isValid();
@@ -856,14 +877,14 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
return false;
}
-bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
+bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision *version_return,
QQmlType *type_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
bool *typeRecursionDetected)
{
const QVector<QHashedStringRef> splitName = type.split(Dot);
auto resolveTypeInNamespace = [&](QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) -> bool {
- if (nameSpace->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors,
+ if (nameSpace->resolveType(typeLoader, unqualifiedtype, version_return, type_return, &base, errors,
registrationType, typeRecursionDetected))
return true;
if (nameSpace->imports.count() == 1 && !nameSpace->imports.at(0)->isLibrary && type_return && nameSpace != &unqualifiedset) {
@@ -976,7 +997,7 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const
}
bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor, QQmlType *type_return,
+ QTypeRevision *version_return, QQmlType *type_return,
QString *base, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
bool *typeRecursionDetected)
@@ -996,13 +1017,13 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
}
for (int i=0; i<imports.count(); ++i) {
const QQmlImportInstance *import = imports.at(i);
- if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base,
+ if (import->resolveType(typeLoader, type, version_return, type_return, base,
typeRecursionDetected, registrationType, recursionRestriction, errors)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<imports.count(); ++j) {
const QQmlImportInstance *import2 = imports.at(j);
- if (import2->resolveType(typeLoader, type, vmajor, vminor, nullptr, base,
+ if (import2->resolveType(typeLoader, type, version_return, nullptr, base,
nullptr, registrationType)) {
if (errors) {
QString u1 = import->url;
@@ -1029,9 +1050,11 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2));
} else {
error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
- .arg(u1)
- .arg(import->majversion).arg(import->minversion)
- .arg(import2->majversion).arg(import2->minversion));
+ .arg(u1)
+ .arg(import->version.majorVersion())
+ .arg(import->version.minorVersion())
+ .arg(import2->version.majorVersion())
+ .arg(import2->version.minorVersion()));
}
errors->prepend(error);
}
@@ -1088,18 +1111,19 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr
QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following:
[QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models]
*/
-static QStringList versionUriList(const QString &uri, int vmaj, int vmin)
+static QStringList versionUriList(const QString &uri, QTypeRevision version)
{
QStringList result;
- for (int version = QQmlImports::FullyVersioned; version <= QQmlImports::Unversioned; ++version) {
+ for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) {
int index = uri.length();
do {
QString versionUri = uri;
- versionUri.insert(index, QQmlImports::versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version)));
+ versionUri.insert(index, QQmlImports::versionString(
+ version, QQmlImports::ImportVersion(mode)));
result += versionUri;
index = uri.lastIndexOf(Dot, index - 1);
- } while (index > 0 && version != QQmlImports::Unversioned);
+ } while (index > 0 && mode != QQmlImports::Unversioned);
}
return result;
}
@@ -1164,8 +1188,7 @@ Import an extension defined by a qmldir file.
\a qmldirFilePath is a raw file path.
*/
bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
- const QString &uri,
- int vmaj, int vmin,
+ const QString &uri, QTypeRevision version,
QQmlImportDatabase *database,
const QQmlTypeLoaderQmldirContent &qmldir,
QList<QQmlError> *errors)
@@ -1190,13 +1213,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (qmldirPluginCount == 0)
return true;
- if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
- if ((vmaj >= 0 && vmin >= 0)
- ? !QQmlMetaType::isModule(uri, vmaj, vmin)
- : !QQmlMetaType::isAnyModule(uri)) {
- QQmlMetaType::qmlRegisterModuleTypes(uri, vmaj);
- }
- } else {
+ if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
// First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue
// searching static plugins that has correct metadata uri. Note that since we only know the uri
// for a static plugin, and not the filename, we cannot know which static plugin belongs to which
@@ -1218,7 +1235,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name);
if (!resolvedFilePath.isEmpty()) {
dynamicPluginsFound++;
- if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, vmaj, errors)) {
+ if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, version, errors)) {
if (errors) {
// XXX TODO: should we leave the import plugin error alone?
// Here, we pop it off the top and coalesce it into this error's message.
@@ -1243,7 +1260,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
// versioned to unversioned, we need to compare with differnt version strings. If a module
// has several plugins, they must all have the same version. Start by populating pluginPairs
// with relevant plugins to cut the list short early on:
- const QStringList versionUris = versionUriList(uri, vmaj, vmin);
+ const QStringList versionUris = versionUriList(uri, version);
QVector<StaticPluginPair> pluginPairs;
if (!populatePluginPairVector(pluginPairs, uri, versionUris, qmldirFilePath, errors))
return false;
@@ -1255,7 +1272,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (versionUri == metaTagUri.toString()) {
staticPluginsFound++;
QObject *instance = pair.first.instance();
- if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, vmaj, errors)) {
+ if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, version, errors)) {
if (errors) {
QQmlError poppedError = errors->takeFirst();
QQmlError error;
@@ -1358,11 +1375,9 @@ and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise return
false.
*/
QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
- const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ const QString &uri, QTypeRevision version, QQmlImportDatabase *database,
QString *outQmldirFilePath, QString *outQmldirPathUrl)
{
- Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
-
// Check cache first
QQmlImportDatabase::QmldirCache *cacheHead = nullptr;
@@ -1372,7 +1387,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
cacheHead = *cachePtr;
QQmlImportDatabase::QmldirCache *cache = cacheHead;
while (cache) {
- if (cache->versionMajor == vmaj && cache->versionMinor == vmin) {
+ if (cache->version == version) {
*outQmldirFilePath = cache->qmldirFilePath;
*outQmldirPathUrl = cache->qmldirPathUrl;
return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound
@@ -1383,20 +1398,21 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
}
}
- QQmlTypeLoader &typeLoader = QQmlEnginePrivate::get(database->engine)->typeLoader;
+ QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(database->engine);
+ QQmlTypeLoader &typeLoader = enginePrivate->typeLoader;
+ const bool hasInterceptors = !enginePrivate->urlInterceptors.isEmpty();
// Interceptor might redirect remote files to local ones.
- QQmlAbstractUrlInterceptor *interceptor = typeLoader.engine()->urlInterceptor();
QStringList localImportPaths = database->importPathList(
- interceptor ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local);
+ hasInterceptors ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local);
// Search local import paths for a matching version
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
- uri, localImportPaths, vmaj, vmin);
+ uri, localImportPaths, version);
bool pathTurnedRemote = false;
for (QString qmldirPath : qmlDirPaths) {
- if (interceptor) {
- const QUrl intercepted = interceptor->intercept(
+ if (hasInterceptors) {
+ const QUrl intercepted = database->engine->interceptUrl(
QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
QQmlAbstractUrlInterceptor::QmldirFile);
qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted);
@@ -1414,8 +1430,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
url = QUrl::fromLocalFile(absolutePath.toString()).toString();
QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
- cache->versionMajor = vmaj;
- cache->versionMinor = vmin;
+ cache->version = version;
cache->qmldirFilePath = absoluteFilePath;
cache->qmldirPathUrl = url;
cache->next = cacheHead;
@@ -1429,19 +1444,19 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
}
QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
- cache->versionMajor = vmaj;
- cache->versionMinor = vmin;
+ cache->version = version;
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound;
}
-bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
+bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir,
+ const QString &uri, QTypeRevision version,
QList<QQmlError> *errors)
{
- int lowest_min = INT_MAX;
- int highest_min = INT_MIN;
+ quint8 lowest_min = std::numeric_limits<quint8>::max();
+ quint8 highest_min = 0;
typedef QQmlDirComponents::const_iterator ConstIterator;
const QQmlDirComponents &components = qmldir.components();
@@ -1449,21 +1464,20 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent
ConstIterator cend = components.constEnd();
for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) {
for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) {
- if ((cit2->typeName == cit->typeName) &&
- (cit2->majorVersion == cit->majorVersion) &&
- (cit2->minorVersion == cit->minorVersion)) {
+ if (cit2->typeName == cit->typeName && cit2->version == cit->version) {
// This entry clashes with a predecessor
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"")
- .arg(cit->typeName).arg(cit->majorVersion).arg(cit->minorVersion).arg(uri));
+ .arg(cit->typeName).arg(cit->version.majorVersion())
+ .arg(cit->version.minorVersion()).arg(uri));
errors->prepend(error);
return false;
}
}
- if (cit->majorVersion == vmaj) {
- lowest_min = qMin(lowest_min, cit->minorVersion);
- highest_min = qMax(highest_min, cit->minorVersion);
+ if (cit->version.majorVersion() == version.majorVersion()) {
+ lowest_min = qMin(lowest_min, cit->version.minorVersion());
+ highest_min = qMax(highest_min, cit->version.minorVersion());
}
}
@@ -1473,27 +1487,27 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent
SConstIterator send = scripts.constEnd();
for (SConstIterator sit = scripts.constBegin(); sit != send; ++sit) {
for (SConstIterator sit2 = scripts.constBegin(); sit2 != sit; ++sit2) {
- if ((sit2->nameSpace == sit->nameSpace) &&
- (sit2->majorVersion == sit->majorVersion) &&
- (sit2->minorVersion == sit->minorVersion)) {
+ if (sit2->nameSpace == sit->nameSpace && sit2->version == sit->version) {
// This entry clashes with a predecessor
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"")
- .arg(sit->nameSpace).arg(sit->majorVersion).arg(sit->minorVersion).arg(uri));
+ .arg(sit->nameSpace).arg(sit->version.majorVersion())
+ .arg(sit->version.minorVersion()).arg(uri));
errors->prepend(error);
return false;
}
}
- if (sit->majorVersion == vmaj) {
- lowest_min = qMin(lowest_min, sit->minorVersion);
- highest_min = qMax(highest_min, sit->minorVersion);
+ if (sit->version.majorVersion() == version.majorVersion()) {
+ lowest_min = qMin(lowest_min, sit->version.minorVersion());
+ highest_min = qMax(highest_min, sit->version.minorVersion());
}
}
- if (lowest_min > vmin || highest_min < vmin) {
+ if (lowest_min > version.minorVersion() || highest_min < version.minorVersion()) {
QQmlError error;
- error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin));
+ error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed")
+ .arg(uri).arg(version.majorVersion()).arg(version.minorVersion()));
errors->prepend(error);
return false;
}
@@ -1520,10 +1534,9 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix)
return nameSpace;
}
-QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace,
- const QString &uri, const QString &url, int vmaj, int vmin,
- QV4::CompiledData::Import::ImportType type,
- QList<QQmlError> *errors, bool lowPrecedence)
+QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(
+ QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, QTypeRevision version,
+ QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, bool lowPrecedence)
{
Q_ASSERT(nameSpace);
Q_ASSERT(errors);
@@ -1534,8 +1547,7 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace
import->uri = uri;
import->url = url;
import->localDirectoryPath = QQmlFile::urlToLocalFileOrQrc(url);
- import->majversion = vmaj;
- import->minversion = vmin;
+ import->version = version;
import->isLibrary = (type == QV4::CompiledData::Import::ImportLibrary);
if (lowPrecedence)
@@ -1546,10 +1558,10 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace
return import;
}
-bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &prefix,
- int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete,
- QQmlImportDatabase *database,
- QList<QQmlError> *errors)
+bool QQmlImportsPrivate::addLibraryImport(
+ const QString& uri, const QString &prefix, QTypeRevision version,
+ const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete,
+ QQmlImportDatabase *database, QList<QQmlError> *errors)
{
Q_ASSERT(database);
Q_ASSERT(errors);
@@ -1557,7 +1569,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
QQmlImportNamespace *nameSpace = importNamespace(prefix);
Q_ASSERT(nameSpace);
- QQmlImportInstance *inserted = addImportToNamespace(nameSpace, uri, qmldirUrl, vmaj, vmin, QV4::CompiledData::Import::ImportLibrary, errors);
+ QQmlImportInstance *inserted = addImportToNamespace(
+ nameSpace, uri, qmldirUrl, version,
+ QV4::CompiledData::Import::ImportLibrary, errors);
Q_ASSERT(inserted);
if (!incomplete) {
@@ -1568,7 +1582,7 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
return false;
if (qmldir.hasContent()) {
- if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors))
+ if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors))
return false;
if (!inserted->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors))
@@ -1577,18 +1591,26 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
}
// Ensure that we are actually providing something
- if ((vmaj < 0) || (vmin < 0) || !QQmlMetaType::isModule(uri, vmaj, vmin)) {
+ if (!QQmlMetaType::isModule(uri, version)) {
if (inserted->qmlDirComponents.isEmpty() && inserted->qmlDirScripts.isEmpty()) {
QQmlError error;
- if (QQmlMetaType::isAnyModule(uri))
- error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin));
- else
- error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri));
+ if (QQmlMetaType::isAnyModule(uri)) {
+ error.setDescription(QQmlImportDatabase::tr(
+ "module \"%1\" version %2.%3 is not installed")
+ .arg(uri).arg(version.majorVersion())
+ .arg(version.hasMinorVersion()
+ ? QString::number(version.minorVersion())
+ : QLatin1String("x")));
+ } else {
+ error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed")
+ .arg(uri));
+ }
errors->prepend(error);
return false;
- } else if ((vmaj >= 0) && (vmin >= 0) && qmldir.hasContent()) {
+ } else if (version.hasMajorVersion() && version.hasMinorVersion()
+ && qmldir.hasContent()) {
// Verify that the qmldir content is valid for this version
- if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors))
+ if (!validateQmldirVersion(qmldir, uri, version, errors))
return false;
}
}
@@ -1597,10 +1619,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
return true;
}
-bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix,
- int vmaj, int vmin,
- bool isImplicitImport, bool incomplete, QQmlImportDatabase *database,
- QList<QQmlError> *errors)
+bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix, QTypeRevision version,
+ bool isImplicitImport, bool incomplete,
+ QQmlImportDatabase *database, QList<QQmlError> *errors)
{
Q_ASSERT(errors);
@@ -1613,10 +1634,8 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
QString qmldirUrl = resolveLocalUrl(base, importUri + (importUri.endsWith(Slash)
? String_qmldir
: Slash_qmldir));
- if (QQmlAbstractUrlInterceptor *interceptor = typeLoader->engine()->urlInterceptor()) {
- qmldirUrl = interceptor->intercept(QUrl(qmldirUrl),
- QQmlAbstractUrlInterceptor::QmldirFile).toString();
- }
+ qmldirUrl = typeLoader->engine()->interceptUrl(
+ QUrl(qmldirUrl), QQmlAbstractUrlInterceptor::QmldirFile).toString();
QString qmldirIdentifier;
if (QQmlFile::isLocalFile(qmldirUrl)) {
@@ -1676,7 +1695,9 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
}
}
- QQmlImportInstance *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport);
+ QQmlImportInstance *inserted = addImportToNamespace(
+ nameSpace, importUri, url, version, QV4::CompiledData::Import::ImportFile,
+ errors, isImplicitImport);
Q_ASSERT(inserted);
if (!incomplete && !qmldirIdentifier.isEmpty()) {
@@ -1685,7 +1706,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
return false;
if (qmldir.hasContent()) {
- if (!importExtension(qmldir.pluginLocation(), importUri, vmaj, vmin, database, qmldir, errors))
+ if (!importExtension(qmldir.pluginLocation(), importUri, version, database, qmldir, errors))
return false;
if (!inserted->setQmldirContent(url, qmldir, nameSpace, errors))
@@ -1709,26 +1730,27 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString &
return false;
if (qmldir.hasContent()) {
- int vmaj = import->majversion;
- int vmin = import->minversion;
- if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors))
+ QTypeRevision version = import->version;
+ if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors))
return false;
if (import->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) {
if (import->qmlDirComponents.isEmpty() && import->qmlDirScripts.isEmpty()) {
// The implicit import qmldir can be empty, and plugins have no extra versions
- if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, vmaj, vmin)) {
+ if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, version)) {
QQmlError error;
- if (QQmlMetaType::isAnyModule(uri))
- error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin));
- else
+ if (QQmlMetaType::isAnyModule(uri)) {
+ error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed")
+ .arg(uri).arg(version.majorVersion()).arg(version.minorVersion()));
+ } else {
error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri));
+ }
errors->prepend(error);
return false;
}
- } else if ((vmaj >= 0) && (vmin >= 0)) {
+ } else if (version.hasMajorVersion() && version.hasMinorVersion()) {
// Verify that the qmldir content is valid for this version
- if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors))
+ if (!validateQmldirVersion(qmldir, uri, version, errors))
return false;
}
return true;
@@ -1762,7 +1784,8 @@ bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlErro
<< ")::addImplicitImport";
bool incomplete = !isLocal(baseUrl());
- return d->addFileImport(QLatin1String("."), QString(), -1, -1, true, incomplete, importDb, errors);
+ return d->addFileImport(QLatin1String("."), QString(), QTypeRevision(), true, incomplete,
+ importDb, errors);
}
/*!
@@ -1773,8 +1796,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta
importInstance->url = importUrl.toString();
importInstance->uri = name;
importInstance->isInlineComponent = true;
- importInstance->majversion = 0;
- importInstance->minversion = 0;
+ importInstance->version = QTypeRevision::zero();
importInstance->containingType = containingType;
d->unqualifiedset.imports.push_back(importInstance);
d->unqualifiedset.setNeedsSorting(true);
@@ -1803,7 +1825,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta
filled appropriately.
*/
bool QQmlImports::addFileImport(QQmlImportDatabase *importDb,
- const QString& uri, const QString& prefix, int vmaj, int vmin,
+ const QString& uri, const QString& prefix, QTypeRevision version,
bool incomplete, QList<QQmlError> *errors)
{
Q_ASSERT(importDb);
@@ -1811,13 +1833,13 @@ bool QQmlImports::addFileImport(QQmlImportDatabase *importDb,
if (qmlImportTrace())
qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addFileImport: "
- << uri << ' ' << vmaj << '.' << vmin << " as " << prefix;
+ << uri << ' ' << version << " as " << prefix;
- return d->addFileImport(uri, prefix, vmaj, vmin, false, incomplete, importDb, errors);
+ return d->addFileImport(uri, prefix, version, false, incomplete, importDb, errors);
}
bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb,
- const QString &uri, const QString &prefix, int vmaj, int vmin,
+ const QString &uri, const QString &prefix, QTypeRevision version,
const QString &qmldirIdentifier, const QString& qmldirUrl, bool incomplete, QList<QQmlError> *errors)
{
Q_ASSERT(importDb);
@@ -1825,9 +1847,9 @@ bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb,
if (qmlImportTrace())
qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addLibraryImport: "
- << uri << ' ' << vmaj << '.' << vmin << " as " << prefix;
+ << uri << ' ' << version << " as " << prefix;
- return d->addLibraryImport(uri, prefix, vmaj, vmin, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors);
+ return d->addLibraryImport(uri, prefix, version, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors);
}
bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb,
@@ -1845,10 +1867,10 @@ bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb,
}
QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir(
- QQmlImportDatabase *importDb, const QString &uri, int vmaj, int vmin,
+ QQmlImportDatabase *importDb, const QString &uri, QTypeRevision version,
QString *qmldirFilePath, QString *url)
{
- return d->locateLocalQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url);
+ return d->locateLocalQmldir(uri, version, importDb, qmldirFilePath, url);
}
bool QQmlImports::isLocal(const QString &url)
@@ -2157,19 +2179,21 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths)
\internal
*/
static bool registerPluginTypes(QObject *instance, const QString &basePath, const QString &uri,
- const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
+ const QString &typeNamespace, QTypeRevision version,
+ QList<QQmlError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QQmlImportDatabase::registerPluginTypes: " << uri << " from " << basePath;
- if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors))
+ if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors))
return false;
- if (vmaj >= 0 && !typeNamespace.isEmpty() && !QQmlMetaType::protectModule(uri, vmaj)) {
+ if (version.hasMajorVersion() && !typeNamespace.isEmpty()
+ && !QQmlMetaType::protectModule(uri, version)) {
QQmlError error;
error.setDescription(
QString::fromLatin1("Cannot protect module %1 %2 as it was never registered")
- .arg(uri).arg(vmaj));
+ .arg(uri).arg(version.majorVersion()));
errors->append(error);
return false;
}
@@ -2180,8 +2204,9 @@ static bool registerPluginTypes(QObject *instance, const QString &basePath, cons
/*!
\internal
*/
-bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
+bool QQmlImportDatabase::importStaticPlugin(
+ QObject *instance, const QString &basePath, const QString &uri,
+ const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
{
// Dynamic plugins are differentiated by their filepath. For static plugins we
// don't have that information so we use their address as key instead.
@@ -2204,7 +2229,7 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba
plugin.loader = nullptr;
plugins->insert(uniquePluginID, plugin);
- if (!registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors))
+ if (!registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors))
return false;
}
@@ -2224,8 +2249,9 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba
/*!
\internal
*/
-bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QString &uri,
- const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
+bool QQmlImportDatabase::importDynamicPlugin(
+ const QString &filePath, const QString &uri, const QString &typeNamespace,
+ QTypeRevision version, QList<QQmlError> *errors)
{
QFileInfo fileInfo(filePath);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
@@ -2279,7 +2305,7 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
plugins->insert(absoluteFilePath, plugin);
// Continue with shared code path for dynamic and static plugins:
- if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, vmaj, errors))
+ if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, version, errors))
return false;
}
}
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 594eae7bb4..f7f5c32bf4 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -81,8 +81,7 @@ struct QQmlImportInstance
QString url; // the base path of the import
QString localDirectoryPath; // the base path of the import if it's a local file
QQmlType containingType; // points to the containing type for inline components
- int majversion; // the major version imported
- int minversion; // the minor version imported
+ QTypeRevision version; // the version imported
bool isLibrary; // true means that this is not a file import
bool implicitlyImported = false;
bool isInlineComponent = false;
@@ -92,10 +91,11 @@ struct QQmlImportInstance
bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir,
QQmlImportNamespace *nameSpace, QList<QQmlError> *errors);
- static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin);
+ static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts,
+ QTypeRevision version);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor, QQmlType* type_return,
+ QTypeRevision *version_return, QQmlType* type_return,
QString *base = nullptr, bool *typeRecursionDetected = nullptr,
QQmlType::RegistrationType = QQmlType::AnyRegistrationType,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion,
@@ -113,7 +113,7 @@ public:
QQmlImportInstance *findImport(const QString &uri) const;
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor, QQmlType* type_return,
+ QTypeRevision *version_return, QQmlType* type_return,
QString *base = nullptr, QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
bool *typeRecursionDeteced = nullptr);
@@ -145,14 +145,14 @@ public:
bool resolveType(const QHashedStringRef &type,
QQmlType *type_return,
- int *version_major, int *version_minor,
+ QTypeRevision *version_return,
QQmlImportNamespace **ns_return,
QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
bool *typeRecursionDetected = nullptr) const;
bool resolveType(QQmlImportNamespace *,
const QHashedStringRef& type,
- QQmlType *type_return, int *version_major, int *version_minor,
+ QQmlType *type_return, QTypeRevision *version_return,
QQmlType::RegistrationType registrationType
= QQmlType::AnyRegistrationType) const;
@@ -161,11 +161,11 @@ public:
bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType);
bool addFileImport(QQmlImportDatabase *,
- const QString& uri, const QString& prefix, int vmaj, int vmin, bool incomplete,
- QList<QQmlError> *errors);
+ const QString& uri, const QString& prefix, QTypeRevision version,
+ bool incomplete, QList<QQmlError> *errors);
bool addLibraryImport(QQmlImportDatabase *importDb,
- const QString &uri, const QString &prefix, int vmaj, int vmin,
+ const QString &uri, const QString &prefix, QTypeRevision version,
const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, QList<QQmlError> *errors);
bool updateQmldirContent(QQmlImportDatabase *importDb,
@@ -179,7 +179,7 @@ public:
};
LocalQmldirResult locateLocalQmldir(
- QQmlImportDatabase *, const QString &uri, int vmaj, int vmin,
+ QQmlImportDatabase *, const QString &uri, QTypeRevision version,
QString *qmldirFilePath, QString *url);
void populateCache(QQmlTypeNameCache *cache) const;
@@ -197,14 +197,14 @@ public:
{
QString typeName;
QString prefix;
- int majorVersion;
- int minorVersion;
+ QTypeRevision version;
};
QList<CompositeSingletonReference> resolvedCompositeSingletons() const;
- static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin);
- static QString versionString(int vmaj, int vmin, ImportVersion version);
+ static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths,
+ QTypeRevision version);
+ static QString versionString(QTypeRevision version, ImportVersion importVersion);
static bool isLocal(const QString &url);
static bool isLocal(const QUrl &url);
@@ -227,7 +227,9 @@ public:
~QQmlImportDatabase();
#if QT_CONFIG(library)
- bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors);
+ bool importDynamicPlugin(const QString &filePath, const QString &uri,
+ const QString &importNamespace, QTypeRevision version,
+ QList<QQmlError> *errors);
bool removeDynamicPlugin(const QString &filePath);
QStringList dynamicPlugins() const;
#endif
@@ -250,13 +252,13 @@ private:
const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName);
bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri,
- const QString &typeNamespace, int vmaj, QList<QQmlError> *errors);
+ const QString &typeNamespace, QTypeRevision version,
+ QList<QQmlError> *errors);
void clearDirCache();
void finalizePlugin(QObject *instance, const QString &path, const QString &uri);
struct QmldirCache {
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
QString qmldirFilePath;
QString qmldirPathUrl;
QmldirCache *next;
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 0ad013e90b..1f41934c3c 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -45,7 +45,8 @@
#include "qqmlobjectcreator_p.h"
#include <private/qqmlcomponent_p.h>
-void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
+void QQmlEnginePrivate::incubate(
+ QQmlIncubator &i, const QQmlRefPointer<QQmlContextData> &forContext)
{
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> p(i.d);
@@ -59,13 +60,13 @@ void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
// Need to find the first constructing context and see if it is asynchronous
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> parentIncubator;
- QQmlContextData *cctxt = forContext;
+ QQmlRefPointer<QQmlContextData> cctxt = forContext;
while (cctxt) {
- if (!cctxt->hasExtraObject && cctxt->incubator) {
- parentIncubator = cctxt->incubator;
+ if (QQmlIncubatorPrivate *incubator = cctxt->incubator()) {
+ parentIncubator = incubator;
break;
}
- cctxt = cctxt->parent;
+ cctxt = cctxt->parent();
}
if (parentIncubator && parentIncubator->isAsynchronous) {
@@ -149,8 +150,8 @@ void QQmlIncubatorPrivate::clear()
}
enginePriv = nullptr;
if (!rootContext.isNull()) {
- if (!rootContext->hasExtraObject)
- rootContext->incubator = nullptr;
+ if (rootContext->incubator())
+ rootContext->setIncubator(nullptr);
rootContext = nullptr;
}
@@ -360,10 +361,8 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
if (watcher.hasRecursed())
return;
- QQmlContextData *ctxt = nullptr;
- ctxt = creator->finalize(i);
- if (ctxt) {
- rootContext = ctxt;
+ if (creator->finalize(i)) {
+ rootContext = creator->rootContext();
progress = QQmlIncubatorPrivate::Completed;
goto finishIncubate;
}
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index a674ff274f..b178c6aa29 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -46,7 +46,7 @@
#include <private/qqmlvme_p.h>
#include <private/qrecursionwatcher_p.h>
#include <private/qqmlengine_p.h>
-#include <private/qqmlcontext_p.h>
+#include <private/qqmlguardedcontextdata_p.h>
//
// W A R N I N G
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 6a9ef06159..0f83baa893 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -115,9 +115,21 @@ QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
m_scopeObject.asT2()->_s = nullptr;
}
+QString QQmlJavaScriptExpression::expressionIdentifier() const
+{
+ if (auto f = function()) {
+ QString url = f->sourceFile();
+ uint lineNumber = f->compiledFunction->location.line;
+ uint columnNumber = f->compiledFunction->location.column;
+ return url + QString::asprintf(":%u:%u", lineNumber, columnNumber);
+ }
+
+ return QStringLiteral("[native code]");
+}
+
void QQmlJavaScriptExpression::setNotifyOnValueChanged(bool v)
{
- activeGuards.setFlagValue(v);
+ activeGuards.setTag(v ? NotifyOnValueChanged : NoGuardTag);
if (!v)
clearActiveGuards();
}
@@ -134,7 +146,7 @@ QQmlSourceLocation QQmlJavaScriptExpression::sourceLocation() const
return QQmlSourceLocation();
}
-void QQmlJavaScriptExpression::setContext(QQmlContextData *context)
+void QQmlJavaScriptExpression::setContext(const QQmlRefPointer<QQmlContextData> &context)
{
if (m_prevExpression) {
*m_prevExpression = m_nextExpression;
@@ -144,15 +156,10 @@ void QQmlJavaScriptExpression::setContext(QQmlContextData *context)
m_nextExpression = nullptr;
}
- m_context = context;
+ m_context = context.data();
- if (context) {
- m_nextExpression = context->expressions;
- if (m_nextExpression)
- m_nextExpression->m_prevExpression = &m_nextExpression;
- m_prevExpression = &context->expressions;
- context->expressions = this;
- }
+ if (context)
+ context->addExpression(this);
}
QV4::Function *QQmlJavaScriptExpression::function() const
@@ -166,7 +173,7 @@ void QQmlJavaScriptExpression::refresh()
QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
{
- QV4::ExecutionEngine *v4 = m_context->engine->handle();
+ QV4::ExecutionEngine *v4 = m_context->engine()->handle();
QV4::Scope scope(v4);
QV4::JSCallData jsCall(scope);
@@ -175,7 +182,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined)
{
- Q_ASSERT(m_context && m_context->engine);
+ Q_ASSERT(m_context && m_context->engine());
QV4::Function *v4Function = function();
if (!v4Function) {
@@ -184,14 +191,14 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
return QV4::Encode::undefined();
}
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_context->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_context->engine());
// All code that follows must check with watcher before it accesses data members
// incase we have been deleted.
DeleteWatcher watcher(this);
Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty());
- QQmlPropertyCapture capture(m_context->engine, this, &watcher);
+ QQmlPropertyCapture capture(m_context->engine(), this, &watcher);
QQmlPropertyCapture *lastPropertyCapture = ep->propertyCapture;
ep->propertyCapture = notifyOnValueChanged() ? &capture : nullptr;
@@ -200,7 +207,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
if (notifyOnValueChanged())
capture.guards.copyAndClearPrepend(activeGuards);
- QV4::ExecutionEngine *v4 = m_context->engine->handle();
+ QV4::ExecutionEngine *v4 = m_context->engine()->handle();
callData->thisObject = v4->globalObject;
if (scopeObject()) {
QV4::ReturnedValue scope = QV4::QObjectWrapper::wrap(v4, scopeObject());
@@ -337,10 +344,11 @@ QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
}
QV4::ReturnedValue
-QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObject,
- const QString &code, const QString &filename, quint16 line)
+QQmlJavaScriptExpression::evalFunction(
+ const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scopeObject,
+ const QString &code, const QString &filename, quint16 line)
{
- QQmlEngine *engine = ctxt->engine;
+ QQmlEngine *engine = ctxt->engine();
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QV4::ExecutionEngine *v4 = engine->handle();
@@ -367,10 +375,11 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje
return result->asReturnedValue();
}
-void QQmlJavaScriptExpression::createQmlBinding(QQmlContextData *ctxt, QObject *qmlScope,
- const QString &code, const QString &filename, quint16 line)
+void QQmlJavaScriptExpression::createQmlBinding(
+ const QQmlRefPointer<QQmlContextData> &ctxt, QObject *qmlScope, const QString &code,
+ const QString &filename, quint16 line)
{
- QQmlEngine *engine = ctxt->engine;
+ QQmlEngine *engine = ctxt->engine();
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QV4::ExecutionEngine *v4 = engine->handle();
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index eecee08062..f90b399b0a 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/qglobal.h>
+#include <QtCore/qtaggedpointer.h>
#include <QtQml/qqmlerror.h>
#include <private/qqmlengine_p.h>
@@ -102,7 +103,7 @@ public:
QQmlJavaScriptExpression();
virtual ~QQmlJavaScriptExpression();
- virtual QString expressionIdentifier() const = 0;
+ virtual QString expressionIdentifier() const;
virtual void expressionChanged() = 0;
QV4::ReturnedValue evaluate(bool *isUndefined);
@@ -118,10 +119,21 @@ public:
virtual QQmlSourceLocation sourceLocation() const;
- bool isValid() const { return context() != nullptr; }
+ bool hasContext() const { return m_context != nullptr; }
+ bool hasValidContext() const { return m_context && m_context->isValid(); }
+ QQmlContext *publicContext() const { return m_context ? m_context->asQQmlContext() : nullptr; }
- QQmlContextData *context() const { return m_context; }
- void setContext(QQmlContextData *context);
+ QQmlRefPointer<QQmlContextData> context() const { return m_context; }
+ void setContext(const QQmlRefPointer<QQmlContextData> &context);
+
+ void insertIntoList(QQmlJavaScriptExpression **listHead)
+ {
+ m_nextExpression = *listHead;
+ if (m_nextExpression)
+ m_nextExpression->m_prevExpression = &m_nextExpression;
+ m_prevExpression = listHead;
+ *listHead = this;
+ }
QV4::Function *function() const;
@@ -146,11 +158,16 @@ public:
void clearActiveGuards();
QQmlDelayedError *delayedError();
- static QV4::ReturnedValue evalFunction(QQmlContextData *ctxt, QObject *scope,
- const QString &code, const QString &filename,
- quint16 line);
+ static QV4::ReturnedValue evalFunction(
+ const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope, const QString &code,
+ const QString &filename, quint16 line);
+
+ QQmlEngine *engine() const { return m_context ? m_context->engine() : nullptr; }
+ bool hasUnresolvedNames() const { return m_context && m_context->hasUnresolvedNames(); }
+
protected:
- void createQmlBinding(QQmlContextData *ctxt, QObject *scope, const QString &code, const QString &filename, quint16 line);
+ void createQmlBinding(const QQmlRefPointer<QQmlContextData> &ctxt, QObject *scope,
+ const QString &code, const QString &filename, quint16 line);
void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f);
void setCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit);
@@ -159,10 +176,16 @@ protected:
// activeGuards:flag1 - notifyOnValueChanged
// activeGuards:flag2 - useSharedContext
QBiPointer<QObject, DeleteWatcher> m_scopeObject;
- QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards;
- void setTranslationsCaptured(bool captured) { m_error.setFlagValue(captured); }
- bool translationsCaptured() const { return m_error.flag(); }
+ enum GuardTag {
+ NoGuardTag,
+ NotifyOnValueChanged
+ };
+
+ QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next, GuardTag> activeGuards;
+
+ void setTranslationsCaptured(bool captured) { if (captured) m_error.setTag(TranslationsCaptured); else m_error.setTag(NoTag); }
+ bool translationsCaptured() const { return m_error.tag() == TranslationsCaptured; }
private:
friend class QQmlContextData;
@@ -170,10 +193,17 @@ private:
friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
friend class QQmlTranslationBinding;
+ enum Tag {
+ NoTag,
+ TranslationsCaptured
+ };
+
// m_error:flag1 translationsCapturedDuringEvaluation
- QFlagPointer<QQmlDelayedError> m_error;
+ QTaggedPointer<QQmlDelayedError> m_error;
+ // Not refcounted as the context will clear the expressions when destructed.
QQmlContextData *m_context;
+
QQmlJavaScriptExpression **m_prevExpression;
QQmlJavaScriptExpression *m_nextExpression;
@@ -232,7 +262,7 @@ bool QQmlJavaScriptExpression::DeleteWatcher::wasDeleted() const
bool QQmlJavaScriptExpression::notifyOnValueChanged() const
{
- return activeGuards.flag();
+ return activeGuards.tag() == NotifyOnValueChanged;
}
QObject *QQmlJavaScriptExpression::scopeObject() const
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 7af6af276a..bc227ad713 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -835,7 +835,7 @@ QV4::ReturnedValue QQmlLocale::locale(ExecutionEngine *engine, const QString &lo
{
QLocale qlocale;
if (!localeName.isEmpty())
- qlocale = localeName;
+ qlocale = QLocale(localeName);
return wrap(engine, qlocale);
}
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 1d6fdb12a7..d7bff5a1b7 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -96,7 +96,7 @@ class Q_QML_PRIVATE_EXPORT QQmlLocale
Q_GADGET
QML_NAMED_ELEMENT(Locale)
QML_UNCREATABLE("Locale cannot be instantiated. Use Qt.locale().")
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
~QQmlLocale();
diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h
index c7377528b4..9cee029a9b 100644
--- a/src/qml/qml/qqmlloggingcategory_p.h
+++ b/src/qml/qml/qqmlloggingcategory_p.h
@@ -66,9 +66,9 @@ 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 12)
+ Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION(2, 12))
QML_NAMED_ELEMENT(LoggingCategory)
- QML_ADDED_IN_MINOR_VERSION(8)
+ QML_ADDED_IN_VERSION(2, 8)
public:
enum DefaultLogLevel {
diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp
index a967f46b12..a87865fd81 100644
--- a/src/qml/qml/qqmlmetaobject.cpp
+++ b/src/qml/qml/qqmlmetaobject.cpp
@@ -44,12 +44,6 @@
QT_BEGIN_NAMESPACE
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
static bool isNamedEnumeratorInScope(const QMetaObject *resolvedMetaObject, const QByteArray &scope,
const QByteArray &name)
{
@@ -74,7 +68,7 @@ static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scop
}
if (scope == "Qt")
- return isNamedEnumeratorInScope(StaticQtMetaObject::get(), scope, name);
+ return isNamedEnumeratorInScope(&Qt::staticMetaObject, scope, name);
if (isNamedEnumeratorInScope(metaObj, scope, name))
return true;
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index b2a769cab4..4587ac3cc8 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -92,13 +92,8 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data,
d->typeId = type.typeId;
d->listId = type.listId;
d->isSetup = true;
- d->version_min = 0;
- if (type.version > 0) {
- d->module = QString::fromUtf8(type.uri);
- d->version_maj = type.versionMajor;
- } else {
- d->version_maj = 0;
- }
+ d->module = QString::fromUtf8(type.uri);
+ d->version = type.version;
data->registerType(d);
return d;
}
@@ -110,28 +105,20 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
data->registerType(d);
d->setName(QString::fromUtf8(type.uri), elementName);
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
-
- if (type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi)) {
- if (type.version >= 1) // static metaobject added in version 1
- d->baseMetaObject = type.instanceMetaObject;
- if (type.version >= 2) // typeId added in version 2
- d->typeId = type.typeId;
- if (type.version >= 2) // revisions added in version 2
- d->revision = type.revision;
+ d->version = type.version;
+
+ if (type.qObjectApi) {
+ d->baseMetaObject = type.instanceMetaObject;
+ d->typeId = type.typeId;
+ d->revision = type.revision;
}
d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
- if (type.version >= 3) {
- d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.generalizedQobjectApi;
- } else {
- d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
- }
+ d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qObjectApi;
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
d->extraData.sd->singletonInstanceInfo->instanceMetaObject
- = ((type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi) ) && type.version >= 1) ? type.instanceMetaObject : nullptr;
+ = type.qObjectApi ? type.instanceMetaObject : nullptr;
return d;
}
@@ -143,10 +130,8 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
data->registerType(d);
d->setName(QString::fromUtf8(type.uri), elementName);
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
- if (type.version >= 1) // revisions added in version 1
- d->revision = type.revision;
+ d->version = type.version;
+ d->revision = type.revision;
d->typeId = type.typeId;
d->listId = type.listId;
d->extraData.cd->allocationSize = type.objectSize;
@@ -181,8 +166,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
auto *d = new QQmlTypePrivate(QQmlType::CompositeType);
data->registerType(d);
d->setName(QString::fromUtf8(type.uri), elementName);
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
+ d->version = type.version;
d->extraData.fd->url = QQmlTypeLoader::normalize(type.url);
return d;
@@ -195,8 +179,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
data->registerType(d);
d->setName(QString::fromUtf8(type.uri), elementName);
- d->version_maj = type.versionMajor;
- d->version_min = type.versionMinor;
+ d->version = type.version;
d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url);
@@ -272,35 +255,32 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
}
}
-void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, int majorVersion,
- void (*registerFunction)())
+void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)())
{
- const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
QQmlMetaTypeDataPtr data;
- if (data->moduleTypeRegistrationFunctions.contains(versionedUri))
- qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ if (data->moduleTypeRegistrationFunctions.contains(uri))
+ qFatal("Cannot add multiple registrations for %s", qPrintable(uri));
else
- data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction);
+ data->moduleTypeRegistrationFunctions.insert(uri, registerFunction);
}
-void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, int majorVersion)
+void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri)
{
- const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
QQmlMetaTypeDataPtr data;
if (!data.isValid())
return; // shutdown/deletion race. Not a problem.
- if (!data->moduleTypeRegistrationFunctions.contains(versionedUri))
- qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ if (!data->moduleTypeRegistrationFunctions.contains(uri))
+ qFatal("Cannot remove multiple registrations for %s", qPrintable(uri));
else
- data->moduleTypeRegistrationFunctions.remove(versionedUri);
+ data->moduleTypeRegistrationFunctions.remove(uri);
}
-bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, int majorVersion)
+bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri)
{
QQmlMetaTypeDataPtr data;
- return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, majorVersion));
+ return data->registerModuleTypes(uri);
}
/*!
@@ -333,11 +313,14 @@ void QQmlMetaType::clearTypeRegistrations()
data->undeletableTypes.clear();
}
-int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent)
+int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &function)
{
+ if (function.structVersion > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+
QQmlMetaTypeDataPtr data;
- data->parentFunctions.append(autoparent.function);
+ data->parentFunctions.append(function.function);
return data->parentFunctions.count() - 1;
}
@@ -350,22 +333,19 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun
QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type)
{
- if (type.version > 1)
+ if (type.structVersion > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
QQmlTypePrivate *priv = createQQmlType(data, type);
Q_ASSERT(priv);
- data->idToType.insert(priv->typeId, priv);
- data->idToType.insert(priv->listId, priv);
- if (data->interfaces.size() <= type.typeId)
- data->interfaces.resize(type.typeId + 16);
- if (data->lists.size() <= type.listId)
- data->lists.resize(type.listId + 16);
- data->interfaces.setBit(type.typeId, true);
- data->lists.setBit(type.listId, true);
+ data->idToType.insert(priv->typeId.id(), priv);
+ data->idToType.insert(priv->listId.id(), priv);
+
+ data->interfaces.insert(type.typeId.id());
+ data->lists.insert(type.listId.id());
return QQmlType(priv);
}
@@ -386,10 +366,12 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
// NOTE: caller must hold a QMutexLocker on "data"
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
- const char *uri, const QString &typeName, int majorVersion)
+ const char *uri, const QString &typeName, QTypeRevision version,
+ QMetaType::TypeFlags flags)
{
if (!typeName.isEmpty()) {
- if (typeName.at(0).isLower()) {
+ if (typeName.at(0).isLower()
+ && !(flags & (QMetaType::PointerToGadget | QMetaType::IsGadget))) {
QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName));
return false;
@@ -407,14 +389,14 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (uri && !typeName.isEmpty()) {
QString nameSpace = QString::fromUtf8(uri);
- QQmlMetaTypeData::VersionedUri versionedUri;
- versionedUri.uri = nameSpace;
- versionedUri.majorVersion = majorVersion;
+ QQmlMetaTypeData::VersionedUri versionedUri(nameSpace, version);
if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){
if (qqtm->isLocked()){
QString failure(QCoreApplication::translate("qmlRegisterType",
"Cannot install %1 '%2' into protected module '%3' version '%4'"));
- data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion));
+ data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType))
+ .arg(typeName).arg(nameSpace)
+ .arg(version.majorVersion()));
return false;
}
}
@@ -424,9 +406,9 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
}
// NOTE: caller must hold a QMutexLocker on "data"
-QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data)
+QQmlTypeModule *getTypeModule(const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
{
- QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
+ QQmlMetaTypeData::VersionedUri versionedUri(uri, version);
QQmlTypeModule *module = data->uriToModule.value(versionedUri);
if (!module) {
module = new QQmlTypeModule(versionedUri.uri, versionedUri.majorVersion);
@@ -446,24 +428,20 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
if (type->baseMetaObject)
data->metaObjectToType.insert(type->baseMetaObject, type);
- if (type->typeId) {
- data->idToType.insert(type->typeId, type);
- if (data->objects.size() <= type->typeId)
- data->objects.resize(type->typeId + 16);
- data->objects.setBit(type->typeId, true);
+ if (type->typeId.isValid()) {
+ data->idToType.insert(type->typeId.id(), type);
+ data->objects.insert(type->typeId.id());
}
- if (type->listId) {
- if (data->lists.size() <= type->listId)
- data->lists.resize(type->listId + 16);
- data->lists.setBit(type->listId, true);
- data->idToType.insert(type->listId, type);
+ if (type->listId.isValid()) {
+ data->idToType.insert(type->listId.id(), type);
+ data->lists.insert(type->listId.id());
}
if (!type->module.isEmpty()) {
const QHashedString &mod = type->module;
- QQmlTypeModule *module = getTypeModule(mod, type->version_maj, data);
+ QQmlTypeModule *module = getTypeModule(mod, type->version, data);
Q_ASSERT(module);
module->add(type);
}
@@ -471,28 +449,38 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
QQmlType QQmlMetaType::registerType(const QQmlPrivate::RegisterType &type)
{
+ if (type.structVersion > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+
QQmlMetaTypeDataPtr data;
QString elementName = QString::fromUtf8(type.elementName);
- if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
+ if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
+ QMetaType(type.typeId).flags())) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
addTypeToData(priv, data);
- if (!type.typeId)
- data->idToType.insert(priv->typeId, priv);
+ if (!type.typeId.isValid())
+ data->idToType.insert(priv->typeId.id(), priv);
return QQmlType(priv);
}
QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
{
+ if (type.structVersion > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+
QQmlMetaTypeDataPtr data;
QString typeName = QString::fromUtf8(type.typeName);
- if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
+ if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
+ QMetaType(type.typeId).flags())) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
@@ -503,6 +491,9 @@ QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingleto
QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
{
+ if (type.structVersion > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QQmlMetaTypeDataPtr data;
@@ -511,7 +502,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri,
- typeName, type.versionMajor)) {
+ typeName, type.version, {})) {
return QQmlType();
}
@@ -526,6 +517,9 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
{
+ if (type.structVersion > 0)
+ qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
+
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QQmlMetaTypeDataPtr data;
@@ -533,8 +527,10 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.versionMajor))
+ if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName,
+ type.version, {})) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
addTypeToData(priv, data);
@@ -545,26 +541,50 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
return QQmlType(priv);
}
+
+
+template <typename T>
+struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface
+{
+ const QByteArray name;
+ QQmlMetaTypeInterface(const QByteArray &name)
+ : QMetaTypeInterface {
+ /*.revision=*/ 0,
+ /*.size=*/ sizeof(T),
+ /*.alignment=*/ alignof(T),
+ /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<T>::Flags,
+ /*.metaObject=*/ nullptr,
+ /*.name=*/ name.constData(),
+ /*.typeId=*/ 0,
+ /*.ref=*/ { Q_BASIC_ATOMIC_INITIALIZER(0) },
+ /*.deleteSelf=*/ [](QMetaTypeInterface *self) {
+ delete static_cast<QQmlMetaTypeInterface *>(self);
+ },
+ /*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) { new (addr) T(); },
+ /*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) {
+ new (addr) T(*reinterpret_cast<const T *>(other));
+ },
+ /*.moveCtr=*/ [](const QMetaTypeInterface *, void *addr, void *other) {
+ new (addr) T(std::move(*reinterpret_cast<T *>(other)));
+ },
+ /*.dtor=*/ [](const QMetaTypeInterface *, void *addr) {
+ reinterpret_cast<T *>(addr)->~T();
+ },
+ /*.legacyRegisterOp=*/ nullptr
+ }
+ , name(name) { }
+};
+
CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArray &className)
{
QByteArray ptr = className + '*';
QByteArray lst = "QQmlListProperty<" + className + '>';
- int ptr_type = QMetaType::registerNormalizedType(ptr,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Construct,
- sizeof(QObject*),
- static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
- nullptr);
- int lst_type = QMetaType::registerNormalizedType(lst,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Construct,
- sizeof(QQmlListProperty<QObject>),
- static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
- static_cast<QMetaObject*>(nullptr));
+ QMetaType ptr_type(new QQmlMetaTypeInterface<QObject*>(ptr));
+ QMetaType lst_type(new QQmlMetaTypeInterface<QQmlListProperty<QObject>>(lst));
QQmlMetaTypeDataPtr data;
- data->qmlLists.insert(lst_type, ptr_type);
+ data->qmlLists.insert(lst_type.id(), ptr_type.id());
return {ptr_type, lst_type};
}
@@ -572,16 +592,13 @@ CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArra
void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds)
{
QQmlMetaTypeDataPtr data;
- data->qmlLists.remove(typeIds.listId);
-
- QMetaType::unregisterType(typeIds.id);
- QMetaType::unregisterType(typeIds.listId);
+ data->qmlLists.remove(typeIds.listId.id());
}
int QQmlMetaType::registerUnitCacheHook(
const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
{
- if (hookRegistration.version > 0)
+ if (hookRegistration.structVersion > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
@@ -589,40 +606,37 @@ int QQmlMetaType::registerUnitCacheHook(
return 0;
}
-bool QQmlMetaType::protectModule(const QString &uri, int majVersion)
+bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
- QQmlMetaTypeData::VersionedUri versionedUri;
- versionedUri.uri = uri;
- versionedUri.majorVersion = majVersion;
-
- if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) {
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(
+ QQmlMetaTypeData::VersionedUri(uri, version), nullptr)) {
qqtm->lock();
return true;
}
return false;
}
-void QQmlMetaType::registerModule(const char *uri, int versionMajor, int versionMinor)
+void QQmlMetaType::registerModule(const char *uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
- QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data);
+ QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
Q_ASSERT(module);
- module->addMinorVersion(versionMinor);
+ module->addMinorVersion(version.minorVersion());
}
-int QQmlMetaType::typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+int QQmlMetaType::typeId(const char *uri, QTypeRevision version, const char *qmlName)
{
QQmlMetaTypeDataPtr data;
- QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data);
+ QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
if (!module)
return -1;
- QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), versionMinor);
+ QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
if (!type.isValid())
return -1;
@@ -636,12 +650,12 @@ void QQmlMetaType::registerUndeletableType(const QQmlType &dtype)
}
static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const QString &uri,
- int majorVersion)
+ QTypeRevision version)
{
// Has any type previously been installed to this namespace?
QHashedString nameSpace(uri);
for (const QQmlType &type : data->types) {
- if (type.module() == nameSpace && type.majorVersion() == majorVersion)
+ if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
return true;
}
@@ -668,8 +682,8 @@ public:
bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace, int vmaj,
- QList<QQmlError> *errors)
+ const QString &uri, const QString &typeNamespace,
+ QTypeRevision version, QList<QQmlError> *errors)
{
if (!typeNamespace.isEmpty() && typeNamespace != uri) {
// This is an 'identified' module
@@ -690,7 +704,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
if (!typeNamespace.isEmpty()) {
// This is an 'identified' module
- if (namespaceContainsRegistrations(data, typeNamespace, vmaj)) {
+ if (namespaceContainsRegistrations(data, typeNamespace, version)) {
// Other modules have already installed to this namespace
if (errors) {
QQmlError error;
@@ -732,7 +746,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
iface->registerTypes(moduleId);
}
- data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, vmaj));
+ data->registerModuleTypes(uri);
if (!failures.isEmpty()) {
if (errors) {
@@ -763,7 +777,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
const QHashedStringRef &qualifiedType,
bool isCompositeSingleton, QList<QQmlError> *errors,
- int majorVersion, int minorVersion)
+ QTypeRevision version)
{
// ### unfortunate (costly) conversion
const QUrl url = QQmlTypeLoader::normalize(QUrl(urlString));
@@ -808,11 +822,10 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
const QQmlType::RegistrationType registrationType = isCompositeSingleton
? QQmlType::CompositeSingletonType
: QQmlType::CompositeType;
- if (checkRegistration(registrationType, data, nullptr, typeName, majorVersion)) {
+ if (checkRegistration(registrationType, data, nullptr, typeName, version, {})) {
auto *priv = new QQmlTypePrivate(registrationType);
priv->setName(QString(), typeName);
- priv->version_maj = majorVersion;
- priv->version_min = minorVersion;
+ priv->version = version;
if (isCompositeSingleton) {
priv->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
@@ -865,14 +878,12 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
/*
Returns true if a module \a uri of this version is installed and locked;
*/
-bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion)
+bool QQmlMetaType::isLockedModule(const QString &uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
- QQmlMetaTypeData::VersionedUri versionedUri;
- versionedUri.uri = uri;
- versionedUri.majorVersion = majVersion;
- if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0))
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(
+ QQmlMetaTypeData::VersionedUri(uri, version), nullptr))
return qqtm->isLocked();
return false;
}
@@ -884,24 +895,28 @@ bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion)
So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10.
*/
-bool QQmlMetaType::isModule(const QString &module, int versionMajor, int versionMinor)
+bool QQmlMetaType::isModule(const QString &module, QTypeRevision version)
{
- Q_ASSERT(versionMajor >= 0 && versionMinor >= 0);
+ if (!version.hasMajorVersion())
+ return isAnyModule(module);
+
QQmlMetaTypeDataPtr data;
// first, check Types
- QQmlTypeModule *tm =
- data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, versionMajor));
- if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor)
- return true;
+ if (QQmlTypeModule *tm
+ = data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, version))) {
+ return !version.hasMinorVersion()
+ || (tm->minimumMinorVersion() <= version.minorVersion()
+ && tm->maximumMinorVersion() >= version.minorVersion());
+ }
return false;
}
-QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, int majorVersion)
+QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
- return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, majorVersion));
+ return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, version));
}
QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
@@ -926,9 +941,8 @@ bool QQmlMetaType::isQObject(int userType)
{
if (userType == QMetaType::QObjectStar)
return true;
-
QQmlMetaTypeDataPtr data;
- return userType >= 0 && userType < data->objects.size() && data->objects.testBit(userType);
+ return data->objects.contains(userType);
}
/*
@@ -941,8 +955,8 @@ int QQmlMetaType::listType(int id)
if (iter != data->qmlLists.cend())
return *iter;
QQmlTypePrivate *type = data->idToType.value(id);
- if (type && type->listId == id)
- return type->typeId;
+ if (type && type->listId.id() == id)
+ return type->typeId.id();
else
return 0;
}
@@ -1042,9 +1056,9 @@ QQmlMetaType::TypeCategory QQmlMetaType::typeCategory(int userType)
QQmlMetaTypeDataPtr data;
if (data->qmlLists.contains(userType))
return List;
- else if (userType < data->objects.size() && data->objects.testBit(userType))
+ else if (data->objects.contains(userType))
return Object;
- else if (userType < data->lists.size() && data->lists.testBit(userType))
+ else if (data->lists.contains(userType))
return List;
else
return Unknown;
@@ -1056,7 +1070,7 @@ QQmlMetaType::TypeCategory QQmlMetaType::typeCategory(int userType)
bool QQmlMetaType::isInterface(int userType)
{
const QQmlMetaTypeDataPtr data;
- return userType >= 0 && userType < data->interfaces.size() && data->interfaces.testBit(userType);
+ return data->interfaces.contains(userType);
}
const char *QQmlMetaType::interfaceIId(int userType)
@@ -1069,7 +1083,7 @@ const char *QQmlMetaType::interfaceIId(int userType)
}
QQmlType type(typePrivate);
- if (type.isInterface() && type.typeId() == userType)
+ if (type.isInterface() && type.typeId().id() == userType)
return type.interfaceIId();
else
return nullptr;
@@ -1077,10 +1091,10 @@ const char *QQmlMetaType::interfaceIId(int userType)
bool QQmlMetaType::isList(int userType)
{
- const QQmlMetaTypeDataPtr data;
+ QQmlMetaTypeDataPtr data;
if (data->qmlLists.contains(userType))
return true;
- return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
+ return data->lists.contains(userType);
}
/*!
@@ -1120,7 +1134,7 @@ QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type)
Returns the type (if any) of URI-qualified named \a qualifiedName and version specified
by \a version_major and \a version_minor.
*/
-QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, QTypeRevision version)
{
int slash = qualifiedName.indexOf(QLatin1Char('/'));
if (slash <= 0)
@@ -1129,23 +1143,22 @@ QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major,
QHashedStringRef module(qualifiedName.constData(), slash);
QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
- return qmlType(name, module, version_major, version_minor);
+ return qmlType(name, module, version);
}
/*!
Returns the type (if any) of \a name in \a module and version specified
by \a version_major and \a version_minor.
*/
-QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module,
+ QTypeRevision version)
{
- Q_ASSERT(version_major >= 0 && version_minor >= 0);
const QQmlMetaTypeDataPtr data;
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
while (it != data->nameToType.cend() && it.key() == name) {
QQmlType t(*it);
- // XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
- if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor))
+ if (module.isEmpty() || t.availableInVersion(module, version))
return t;
++it;
}
@@ -1168,15 +1181,15 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject)
by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
type is registered.
*/
-QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
+QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module,
+ QTypeRevision version)
{
- Q_ASSERT(version_major >= 0 && version_minor >= 0);
const QQmlMetaTypeDataPtr data;
QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
while (it != data->metaObjectToType.cend() && it.key() == metaObject) {
QQmlType t(*it);
- if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor))
+ if (module.isEmpty() || t.availableInVersion(module, version))
return t;
++it;
}
@@ -1195,7 +1208,7 @@ QQmlType QQmlMetaType::qmlType(int typeId, TypeIdCategory category)
if (category == TypeIdCategory::MetaType) {
QQmlTypePrivate *type = data->idToType.value(typeId);
- if (type && type->typeId == typeId)
+ if (type && type->typeId.id() == typeId)
return QQmlType(type);
} else if (category == TypeIdCategory::QmlType) {
QQmlType type = data->types.value(typeId);
@@ -1226,16 +1239,16 @@ QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileI
return QQmlType();
}
-QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, int minorVersion)
+QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, QTypeRevision version)
{
QQmlMetaTypeDataPtr data; // not const: the cache is created on demand
- return data->propertyCache(metaObject, minorVersion);
+ return data->propertyCache(metaObject, version);
}
-QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVersion)
+QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, QTypeRevision version)
{
QQmlMetaTypeDataPtr data; // not const: the cache is created on demand
- return data->propertyCache(type, minorVersion);
+ return data->propertyCache(type, version);
}
void QQmlMetaType::unregisterType(int typeIndex)
@@ -1250,7 +1263,7 @@ void QQmlMetaType::unregisterType(int typeIndex)
removeQQmlTypePrivate(data->metaObjectToType, d);
for (auto & module : data->uriToModule)
module->remove(d);
- data->clearPropertyCachesForMinorVersion(typeIndex);
+ data->clearPropertyCachesForVersion(typeIndex);
data->types[typeIndex] = QQmlType();
data->undeletableTypes.remove(type);
}
@@ -1282,7 +1295,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
for (auto &module : data->uriToModule)
module->remove(d);
- data->clearPropertyCachesForMinorVersion(d->index);
+ data->clearPropertyCachesForVersion(d->index);
*it = QQmlType();
} else {
++it;
@@ -1367,7 +1380,7 @@ QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
return retn;
}
-const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri, CachedUnitLookupError *status)
+const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri, CachedUnitLookupError *status)
{
const QQmlMetaTypeDataPtr data;
@@ -1382,7 +1395,7 @@ const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUr
}
if (status)
*status = CachedUnitLookupError::NoError;
- return unit->qmlData;
+ return unit;
}
}
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 0c5bc043c4..0ac86e7d20 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -65,11 +65,9 @@ namespace QV4 { class ExecutableCompilationUnit; }
struct CompositeMetaTypeIds
{
- int id = -1;
- int listId = -1;
- CompositeMetaTypeIds() = default;
- CompositeMetaTypeIds(int id, int listId) : id(id), listId(listId) {}
- bool isValid() const { return id != -1 && listId != -1; }
+ QMetaType id;
+ QMetaType listId;
+ bool isValid() const { return id.isValid() && listId.isValid(); }
};
class Q_QML_PRIVATE_EXPORT QQmlMetaType
@@ -81,20 +79,20 @@ public:
static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type);
static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type);
static bool registerPluginTypes(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace, int vmaj,
- QList<QQmlError> *errors);
+ const QString &uri, const QString &typeNamespace,
+ QTypeRevision version, QList<QQmlError> *errors);
static QQmlType typeForUrl(const QString &urlString, const QHashedStringRef& typeName,
bool isCompositeSingleton, QList<QQmlError> *errors,
- int majorVersion = -1, int minorVersion = -1);
+ QTypeRevision version = QTypeRevision());
static void unregisterType(int type);
static CompositeMetaTypeIds registerInternalCompositeType(const QByteArray &className);
static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds);
- static void registerModule(const char *uri, int versionMajor, int versionMinor);
- static bool protectModule(const QString &uri, int majVersion);
+ static void registerModule(const char *uri, QTypeRevision version);
+ static bool protectModule(const QString &uri, QTypeRevision version);
- static int typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
+ static int typeId(const char *uri, QTypeRevision version, const char *qmlName);
static void registerUndeletableType(const QQmlType &dtype);
@@ -108,15 +106,16 @@ public:
QmlType
};
- static QQmlType qmlType(const QString &qualifiedName, int, int);
- static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int);
+ static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version);
+ static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version);
static QQmlType qmlType(const QMetaObject *);
- static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
+ static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version);
static QQmlType qmlType(int typeId, TypeIdCategory category = TypeIdCategory::MetaType);
static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false);
- static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion = -1);
- static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
+ static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject,
+ QTypeRevision version = QTypeRevision());
+ static QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version);
static void freeUnusedTypesAndCaches();
@@ -150,9 +149,9 @@ public:
static StringConverter customStringConverter(int);
static bool isAnyModule(const QString &uri);
- static bool isLockedModule(const QString &uri, int majorVersion);
- static bool isModule(const QString &module, int versionMajor, int versionMinor);
- static QQmlTypeModule *typeModule(const QString &uri, int majorVersion);
+ static bool isLockedModule(const QString &uri, QTypeRevision version);
+ static bool isModule(const QString &module, QTypeRevision version);
+ static QQmlTypeModule *typeModule(const QString &uri, QTypeRevision version);
static QList<QQmlPrivate::AutoParentFunction> parentFunctions();
@@ -162,7 +161,7 @@ public:
VersionMismatch
};
- static const QV4::CompiledData::Unit *findCachedCompilationUnit(const QUrl &uri, CachedUnitLookupError *status);
+ static const QQmlPrivate::CachedQmlUnit *findCachedCompilationUnit(const QUrl &uri, CachedUnitLookupError *status);
// used by tst_qqmlcachegen.cpp
static void prependCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler);
@@ -197,11 +196,10 @@ public:
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd);
- static void qmlInsertModuleRegistration(const QString &uri, int majorVersion,
- void (*registerFunction)());
- static void qmlRemoveModuleRegistration(const QString &uri, int majorVersion);
+ static void qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)());
+ static void qmlRemoveModuleRegistration(const QString &uri);
- static bool qmlRegisterModuleTypes(const QString &uri, int majorVersion);
+ static bool qmlRegisterModuleTypes(const QString &uri);
static int qmlRegisteredListTypeCount();
};
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index ed885eaa97..a34a0c1ae4 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -78,9 +78,9 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
priv->release();
}
-bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri &versionedUri)
+bool QQmlMetaTypeData::registerModuleTypes(const QString &uri)
{
- auto function = moduleTypeRegistrationFunctions.constFind(versionedUri);
+ auto function = moduleTypeRegistrationFunctions.constFind(uri);
if (function != moduleTypeRegistrationFunctions.constEnd()) {
(*function)();
return true;
@@ -88,28 +88,28 @@ bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri
return false;
}
-QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForMinorVersion(int index, int minorVersion) const
+QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForVersion(int index, QTypeRevision version) const
{
return (index < typePropertyCaches.length())
- ? typePropertyCaches.at(index).value(minorVersion).data()
+ ? typePropertyCaches.at(index).value(version).data()
: nullptr;
}
-void QQmlMetaTypeData::setPropertyCacheForMinorVersion(int index, int minorVersion,
- QQmlPropertyCache *cache)
+void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version,
+ QQmlPropertyCache *cache)
{
if (index >= typePropertyCaches.length())
typePropertyCaches.resize(index + 1);
- typePropertyCaches[index][minorVersion] = cache;
+ typePropertyCaches[index][version] = cache;
}
-void QQmlMetaTypeData::clearPropertyCachesForMinorVersion(int index)
+void QQmlMetaTypeData::clearPropertyCachesForVersion(int index)
{
if (index < typePropertyCaches.length())
typePropertyCaches[index].clear();
}
-QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, int minorVersion)
+QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, QTypeRevision version)
{
if (QQmlPropertyCache *rv = propertyCaches.value(metaObject))
return rv;
@@ -119,29 +119,36 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject
propertyCaches.insert(metaObject, rv);
return rv;
}
- QQmlPropertyCache *super = propertyCache(metaObject->superClass(), minorVersion);
- QQmlPropertyCache *rv = super->copyAndAppend(metaObject, minorVersion);
+ QQmlPropertyCache *super = propertyCache(metaObject->superClass(), version);
+ QQmlPropertyCache *rv = super->copyAndAppend(metaObject, version);
propertyCaches.insert(metaObject, rv);
return rv;
}
-QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int minorVersion)
+QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRevision version)
{
Q_ASSERT(type.isValid());
- if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), minorVersion))
+ if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), version))
return pc;
QVector<QQmlType> types;
- int maxMinorVersion = 0;
+ quint8 maxMinorVersion = 0;
const QMetaObject *metaObject = type.metaObject();
+ const QTypeRevision combinedVersion = version.hasMajorVersion()
+ ? version
+ : (version.hasMinorVersion()
+ ? QTypeRevision::fromVersion(type.version().majorVersion(),
+ version.minorVersion())
+ : type.version());
+
while (metaObject) {
- QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), type.majorVersion(), minorVersion);
+ QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), combinedVersion);
if (t.isValid()) {
- maxMinorVersion = qMax(maxMinorVersion, t.minorVersion());
+ maxMinorVersion = qMax(maxMinorVersion, t.version().minorVersion());
types << t;
} else {
types << QQmlType();
@@ -150,12 +157,14 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min
metaObject = metaObject->superClass();
}
- if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), maxMinorVersion)) {
- setPropertyCacheForMinorVersion(type.index(), minorVersion, pc);
+ const QTypeRevision maxVersion = QTypeRevision::fromVersion(combinedVersion.majorVersion(),
+ maxMinorVersion);
+ if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), maxVersion)) {
+ setPropertyCacheForVersion(type.index(), maxVersion, pc);
return pc;
}
- QQmlPropertyCache *raw = propertyCache(type.metaObject(), minorVersion);
+ QQmlPropertyCache *raw = propertyCache(type.metaObject(), combinedVersion);
bool hasCopied = false;
@@ -164,7 +173,7 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min
if (!currentType.isValid())
continue;
- int rev = currentType.metaObjectRevision();
+ QTypeRevision rev = currentType.metaObjectRevision();
int moIndex = types.count() - 1 - ii;
if (raw->allowedRevision(moIndex) != rev) {
@@ -222,13 +231,13 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min
}
#endif
- setPropertyCacheForMinorVersion(type.index(), minorVersion, raw);
+ setPropertyCacheForVersion(type.index(), version, raw);
if (hasCopied)
raw->release();
- if (minorVersion != maxMinorVersion)
- setPropertyCacheForMinorVersion(type.index(), maxMinorVersion, raw);
+ if (version != maxVersion)
+ setPropertyCacheForVersion(type.index(), maxVersion, raw);
return raw;
}
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index e51d4ca1a4..727e57a6de 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -57,7 +57,6 @@
#include <QtCore/qset.h>
#include <QtCore/qvector.h>
-#include <QtCore/qbitarray.h>
QT_BEGIN_NAMESPACE
@@ -83,29 +82,28 @@ struct QQmlMetaTypeData
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
- QVector<QHash<int, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches;
+ QVector<QHash<QTypeRevision, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches;
struct VersionedUri {
- VersionedUri()
- : majorVersion(0) {}
- VersionedUri(const QHashedString &uri, int majorVersion)
- : uri(uri), majorVersion(majorVersion) {}
+ VersionedUri() : majorVersion(0) {}
+ VersionedUri(const QHashedString &uri, QTypeRevision version)
+ : uri(uri), majorVersion(version.majorVersion()) {}
bool operator==(const VersionedUri &other) const {
return other.majorVersion == majorVersion && other.uri == uri;
}
QHashedString uri;
- int majorVersion;
+ quint8 majorVersion;
};
typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules;
TypeModules uriToModule;
- QHash<VersionedUri, void (*)()> moduleTypeRegistrationFunctions;
- bool registerModuleTypes(const VersionedUri &versionedUri);
+ QHash<QString, void (*)()> moduleTypeRegistrationFunctions;
+ bool registerModuleTypes(const QString &uri);
- QBitArray objects;
- QBitArray interfaces;
- QBitArray lists;
+ QSet<int> interfaces;
+ QSet<int> objects;
+ QSet<int> lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
QVector<QQmlPrivate::QmlUnitCacheLookupFunction> lookupCachedQmlUnit;
@@ -114,12 +112,12 @@ struct QQmlMetaTypeData
QHash<const QMetaObject *, QQmlPropertyCache *> propertyCaches;
- QQmlPropertyCache *propertyCacheForMinorVersion(int index, int minorVersion) const;
- void setPropertyCacheForMinorVersion(int index, int minorVersion, QQmlPropertyCache *cache);
- void clearPropertyCachesForMinorVersion(int index);
+ QQmlPropertyCache *propertyCacheForVersion(int index, QTypeRevision version) const;
+ void setPropertyCacheForVersion(int index, QTypeRevision version, QQmlPropertyCache *cache);
+ void clearPropertyCachesForVersion(int index);
- QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion);
- QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
+ QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, QTypeRevision version);
+ QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version);
void setTypeRegistrationFailures(QStringList *failures)
{
@@ -138,7 +136,7 @@ private:
QStringList *m_typeRegistrationFailures = nullptr;
};
-inline uint qHash(const QQmlMetaTypeData::VersionedUri &v)
+inline size_t qHash(const QQmlMetaTypeData::VersionedUri &v)
{
return v.uri.hash() ^ qHash(v.majorVersion);
}
diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp
index b7bc3555a6..422a5c0551 100644
--- a/src/qml/qml/qqmlmoduleregistration.cpp
+++ b/src/qml/qml/qqmlmoduleregistration.cpp
@@ -39,27 +39,33 @@
#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQml/qqmlmoduleregistration.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
struct QQmlModuleRegistrationPrivate
{
const QString uri;
- const int majorVersion;
};
+QQmlModuleRegistration::QQmlModuleRegistration(const char *uri, void (*registerFunction)()) :
+ d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri) })
+{
+ QQmlMetaType::qmlInsertModuleRegistration(d->uri, registerFunction);
+}
+
+#if QT_DEPRECATED_SINCE(6, 0)
QQmlModuleRegistration::QQmlModuleRegistration(
- const char *uri, int majorVersion,
- void (*registerFunction)()) :
- d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri), majorVersion })
+ const char *uri, int majorVersion, void (*registerFunction)()) :
+ QQmlModuleRegistration(uri, registerFunction)
{
- QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->majorVersion,
- registerFunction);
+ Q_UNUSED(majorVersion);
}
+#endif
QQmlModuleRegistration::~QQmlModuleRegistration()
{
- QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->majorVersion);
+ QQmlMetaType::qmlRemoveModuleRegistration(d->uri);
delete d;
}
diff --git a/src/qml/qml/qqmlmoduleregistration.h b/src/qml/qml/qqmlmoduleregistration.h
index 6f553a2823..3db535faa0 100644
--- a/src/qml/qml/qqmlmoduleregistration.h
+++ b/src/qml/qml/qqmlmoduleregistration.h
@@ -49,9 +49,14 @@ class Q_QML_EXPORT QQmlModuleRegistration
{
Q_DISABLE_COPY_MOVE(QQmlModuleRegistration)
public:
- QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)());
+ QQmlModuleRegistration(const char *uri, void (*registerFunction)());
~QQmlModuleRegistration();
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED_X("Use registration without major version")
+ QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)());
+#endif
+
private:
QQmlModuleRegistrationPrivate *d = nullptr;
};
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 3ca89924f9..cbf243b9c1 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -59,6 +59,8 @@
#include <private/qqmlsourcecoordinate_p.h>
#include <private/qjsvalue_p.h>
#include <private/qv4generatorobject_p.h>
+#include <private/qv4resolvedtypereference_p.h>
+#include <private/qqmlpropertybinding_p.h>
#include <QScopedValueRollback>
@@ -67,8 +69,11 @@
QT_USE_NAMESPACE
-QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlContextData *creationContext,
- QQmlIncubatorPrivate *incubator)
+QQmlObjectCreator::QQmlObjectCreator(
+ QQmlRefPointer<QQmlContextData> parentContext,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ const QQmlRefPointer<QQmlContextData> &creationContext,
+ QQmlIncubatorPrivate *incubator)
: phase(Startup)
, compilationUnit(compilationUnit)
, propertyCaches(&compilationUnit->propertyCaches)
@@ -76,7 +81,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
, topLevelCreator(true)
, incubator(incubator)
{
- init(parentContext);
+ init(std::move(parentContext));
sharedState->componentAttached = nullptr;
sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount());
@@ -95,7 +100,10 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
}
}
-QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState)
+QQmlObjectCreator::QQmlObjectCreator(
+ QQmlRefPointer<QQmlContextData> parentContext,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ QQmlObjectCreatorSharedState *inheritedSharedState)
: phase(Startup)
, compilationUnit(compilationUnit)
, propertyCaches(&compilationUnit->propertyCaches)
@@ -103,13 +111,13 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
, topLevelCreator(false)
, incubator(nullptr)
{
- init(parentContext);
+ init(std::move(parentContext));
}
-void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
+void QQmlObjectCreator::init(QQmlRefPointer<QQmlContextData> providedParentContext)
{
- parentContext = providedParentContext;
- engine = parentContext->engine;
+ parentContext = std::move(providedParentContext);
+ engine = parentContext->engine();
v4 = engine->handle();
if (compilationUnit && !compilationUnit->engine)
@@ -142,7 +150,7 @@ QQmlObjectCreator::~QQmlObjectCreator()
}
while (sharedState->componentAttached) {
QQmlComponentAttached *a = sharedState->componentAttached;
- a->rem();
+ a->removeFromList();
}
}
}
@@ -151,7 +159,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
{
if (phase == CreatingObjectsPhase2) {
phase = ObjectsCreated;
- return context->contextObject;
+ return context->contextObject();
}
Q_ASSERT(phase == Startup);
phase = CreatingObjects;
@@ -171,16 +179,15 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
}
}
- context = new QQmlContextData;
- context->isInternal = true;
- context->imports = compilationUnit->typeNameCache;
+ context = QQmlContextData::createRefCounted(parentContext);
+ context->setInternal(true);
+ context->setImports(compilationUnit->typeNameCache);
context->initFromTypeCompilationUnit(compilationUnit, subComponentIndex);
- context->setParent(parentContext);
if (!sharedState->rootContext) {
sharedState->rootContext = context;
- sharedState->rootContext->incubator = incubator;
- sharedState->rootContext->isRootObjectInCreation = true;
+ sharedState->rootContext->setIncubator(incubator);
+ sharedState->rootContext->setRootObjectInCreation(true);
}
QV4::Scope scope(v4);
@@ -191,14 +198,14 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (subComponentIndex == -1 && compilationUnit->dependentScripts.count()) {
QV4::ScopedObject scripts(scope, v4->newArrayObject(compilationUnit->dependentScripts.count()));
- context->importedScripts.set(v4, scripts);
+ context->setImportedScripts(QV4::PersistentValue(v4, scripts.asReturnedValue()));
QV4::ScopedValue v(scope);
for (int i = 0; i < compilationUnit->dependentScripts.count(); ++i) {
QQmlRefPointer<QQmlScriptData> s = compilationUnit->dependentScripts.at(i);
scripts->put(i, (v = s->scriptValueForContext(context)));
}
} else if (sharedState->creationContext) {
- context->importedScripts = sharedState->creationContext->importedScripts;
+ context->setImportedScripts(sharedState->creationContext->importedScripts());
}
QObject *instance = createInstance(objectToCreate, parent, /*isContextObject*/true);
@@ -221,18 +228,18 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (instance) {
if (QQmlEngineDebugService *service
= QQmlDebugConnector::service<QQmlEngineDebugService>()) {
- if (!parentContext->isInternal)
- parentContext->asQQmlContextPrivate()->instances.append(instance);
+ if (!parentContext->isInternal())
+ parentContext->asQQmlContextPrivate()->appendInstance(instance);
service->objectCreated(engine, instance);
- } else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) {
- parentContext->asQQmlContextPrivate()->instances.append(instance);
+ } else if (!parentContext->isInternal() && QQmlDebugConnector::service<QV4DebugService>()) {
+ parentContext->asQQmlContextPrivate()->appendInstance(instance);
}
}
return instance;
}
-void QQmlObjectCreator::beginPopulateDeferred(QQmlContextData *newContext)
+void QQmlObjectCreator::beginPopulateDeferred(const QQmlRefPointer<QQmlContextData> &newContext)
{
context = newContext;
sharedState->rootContext = newContext;
@@ -449,8 +456,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
QUrl value = string.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(string));
// Apply URL interceptor
- if (engine->urlInterceptor())
- value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString);
+ value = engine->interceptUrl(value, QQmlAbstractUrlInterceptor::UrlString);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
@@ -618,9 +624,6 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
- case QMetaType::QRegExp:
- assertOrNull(!"not possible");
- break;
default: {
// generate single literal value assignment to a list property if required
if (property->propType() == qMetaTypeId<QList<qreal> >()) {
@@ -742,7 +745,10 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
- QQmlPropertyData *property = binding->propertyNameIndex != 0 ? _propertyCache->property(stringAt(binding->propertyNameIndex), _qobject, context) : defaultProperty;
+ QQmlPropertyData *property = binding->propertyNameIndex != 0
+ ? _propertyCache->property(stringAt(binding->propertyNameIndex),
+ _qobject, context)
+ : defaultProperty;
if (property)
bindingSkipList |= (1 << property->coreIndex());
}
@@ -808,9 +814,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
Q_ASSERT(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex);
Q_ASSERT(tr);
- QQmlType attachedType = tr->type;
+ QQmlType attachedType = tr->type();
if (!attachedType.isValid()) {
- QQmlTypeNameCache::Result res = context->imports->query(stringAt(binding->propertyNameIndex));
+ QQmlTypeNameCache::Result res = context->imports()->query(
+ stringAt(binding->propertyNameIndex));
if (res.isValid())
attachedType = res.type;
else
@@ -899,14 +906,32 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()));
if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) {
- if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
+ || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver) {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex());
- QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
- QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(_bindingTarget, signalIndex,
- context, _scopeObject, runtimeFunction, currentQmlContext());
-
- bs->takeExpression(expr);
+ QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(
+ _bindingTarget, signalIndex, context,
+ _scopeObject, runtimeFunction, currentQmlContext());
+
+ if (bindingProperty->isQProperty()) {
+ auto &observer = QQmlData::get(_scopeObject)->propertyObservers.emplace_back(expr);
+ void *argv[] = { &observer };
+ _bindingTarget->qt_metacall(QMetaObject::RegisterQPropertyObserver, bindingProperty->coreIndex(), argv);
+ } else {
+ QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
+ bs->takeExpression(expr);
+ }
+ } else if (bindingProperty->isQProperty()) {
+ QUntypedPropertyBinding qmlBinding;
+ if (binding->isTranslationBinding()) {
+ qmlBinding = QQmlTranslationPropertyBinding::create(bindingProperty, compilationUnit, binding);
+ } else {
+ QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
+ qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext());
+ }
+ void *argv[] = { &qmlBinding };
+ _bindingTarget->qt_metacall(QMetaObject::SetQPropertyBinding, bindingProperty->coreIndex(), argv);
} else {
// When writing bindings to grouped properties implemented as value types,
// such as point.x: { someExpression; }, then the binding is installed on
@@ -921,10 +946,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
subprop = bindingProperty;
}
if (binding->isTranslationBinding()) {
- qmlBinding = QQmlBinding::createTranslationBinding(compilationUnit, binding, _scopeObject, context);
+ qmlBinding = QQmlBinding::createTranslationBinding(
+ compilationUnit, binding, _scopeObject, context);
} else {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
- qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject, context, currentQmlContext());
+ qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject,
+ context, currentQmlContext());
}
auto bindingTarget = _bindingTarget;
@@ -966,10 +993,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
QQmlPropertyValueSource *vs = reinterpret_cast<QQmlPropertyValueSource *>(reinterpret_cast<char *>(createdSubObject) + valueSourceCast);
QObject *target = createdSubObject->parent();
QQmlProperty prop;
- if (_valueTypeProperty)
- prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, bindingProperty, context);
- else
+ if (_valueTypeProperty) {
+ prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty,
+ bindingProperty, context);
+ } else {
prop = QQmlPropertyPrivate::restore(target, *bindingProperty, nullptr, context);
+ }
vs->setTarget(prop);
return true;
}
@@ -991,15 +1020,19 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
// we can't have aliasses on subproperties of value types, so:
QQmlPropertyData targetPropertyData = *data->propertyCache->property(propIndex.coreIndex());
- auto prop = QQmlPropertyPrivate::restore(target, targetPropertyData, nullptr, context);
+ auto prop = QQmlPropertyPrivate::restore(
+ target, targetPropertyData, nullptr, context);
vi->setTarget(prop);
propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
} else {
QQmlProperty prop;
- if (_valueTypeProperty)
- prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, bindingProperty, context);
- else
- prop = QQmlPropertyPrivate::restore(target, *bindingProperty, nullptr, context);
+ if (_valueTypeProperty) {
+ prop = QQmlPropertyPrivate::restore(
+ target, *_valueTypeProperty, bindingProperty, context);
+ } else {
+ prop = QQmlPropertyPrivate::restore(
+ target, *bindingProperty, nullptr, context);
+ }
vi->setTarget(prop);
propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
}
@@ -1069,7 +1102,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
_vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
} else {
QJSValue value;
- QJSValuePrivate::setValue(&value, v4, wrappedObject);
+ QJSValuePrivate::setValue(&value, wrappedObject);
argv[0] = &value;
QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
}
@@ -1145,12 +1178,7 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location,
void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const
{
if (object->id >= 0)
- context->setIdProperty(object->id, instance);
-}
-
-void QQmlObjectCreator::createQmlContext()
-{
- _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
+ context->setIdValue(object->id, instance);
}
QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
@@ -1180,8 +1208,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
} else {
QV4::ResolvedTypeReference *typeRef = resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
- installPropertyCache = !typeRef->isFullyDynamicType;
- QQmlType type = typeRef->type;
+ installPropertyCache = !typeRef->isFullyDynamicType();
+ const QQmlType type = typeRef->type();
if (type.isValid() && !type.isInlineComponentType()) {
typeName = type.qmlTypeName();
@@ -1206,10 +1234,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
customParser = type.customParser();
- if (sharedState->rootContext && sharedState->rootContext->isRootObjectInCreation) {
+ if (sharedState->rootContext && sharedState->rootContext->isRootObjectInCreation()) {
QQmlData *ddata = QQmlData::get(instance, /*create*/true);
ddata->rootObjectInCreation = true;
- sharedState->rootContext->isRootObjectInCreation = false;
+ sharedState->rootContext->setRootObjectInCreation(false);
}
sharedState->allCreatedObjects.push(instance);
@@ -1219,13 +1247,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
typeName = compilationUnit->fileName();
// compilation unit is shared between root type and its inline component types
// so isSingleton errorneously returns true for inline components
- if (compilationUnit->unitData()->isSingleton() && !type.isInlineComponentType())
- {
+ if (compilationUnit->unitData()->isSingleton() && !type.isInlineComponentType()) {
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
return nullptr;
}
-
if (!type.isInlineComponentType()) {
QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
instance = subCreator.create();
@@ -1234,7 +1260,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
return nullptr;
}
} else {
- int subObjectId = type.inlineComponendId();
+ int subObjectId = type.inlineComponentId();
QScopedValueRollback<int> rollback {compilationUnit->icRoot, subObjectId};
QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
instance = subCreator.create(subObjectId, nullptr, nullptr, CreationFlags::InlineComponent);
@@ -1271,21 +1297,22 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
const bool isInlineComponent = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot;
if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation || isInlineComponent) {
if (ddata->context) {
- Q_ASSERT(ddata->context != context);
+ Q_ASSERT(ddata->context != context.data());
Q_ASSERT(ddata->outerContext);
- Q_ASSERT(ddata->outerContext != context);
- QQmlContextData *c = ddata->context;
- while (c->linkedContext) c = c->linkedContext;
- c->linkedContext = context;
+ Q_ASSERT(ddata->outerContext != context.data());
+ QQmlRefPointer<QQmlContextData> c = ddata->context;
+ while (QQmlRefPointer<QQmlContextData> linked = c->linkedContext())
+ c = linked;
+ c->setLinkedContext(context);
} else {
- ddata->context = context;
+ ddata->context = context.data();
}
ddata->ownContext = ddata->context;
} else if (!ddata->context) {
- ddata->context = context;
+ ddata->context = context.data();
}
- context->addObject(ddata);
+ context->addOwnedObject(ddata);
if (parserStatus) {
parserStatus->classBegin();
@@ -1299,7 +1326,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
// Register the context object in the context early on in order for pending binding
// initialization to find it available.
if (isContextObject)
- context->contextObject = instance;
+ context->setContextObject(instance);
if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) {
customParser->engine = QQmlEnginePrivate::get(engine);
@@ -1374,7 +1401,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
return ok ? instance : nullptr;
}
-QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
+bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
{
Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
phase = Finalizing;
@@ -1396,12 +1423,13 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (!b->isValueTypeProxy()) {
QQmlBinding *binding = static_cast<QQmlBinding*>(b.data());
if (!binding->hasError() && !binding->hasDependencies()
- && binding->context() && !binding->context()->unresolvedNames)
+ && binding->hasContext() && !binding->hasUnresolvedNames()) {
b->removeFromObject();
+ }
}
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return nullptr;
+ return false;
}
if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later
@@ -1415,7 +1443,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
}
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return nullptr;
+ return false;
}
}
@@ -1427,27 +1455,27 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
}
if (watcher.hasRecursed())
- return nullptr;
+ return false;
}
sharedState->finalizeCallbacks.clear();
while (sharedState->componentAttached) {
QQmlComponentAttached *a = sharedState->componentAttached;
- a->rem();
+ a->removeFromList();
QQmlData *d = QQmlData::get(a->parent());
Q_ASSERT(d);
Q_ASSERT(d->context);
- a->add(&d->context->componentAttached);
+ d->context->addComponentAttached(a);
if (QQmlVME::componentCompleteEnabled())
emit a->completed();
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return nullptr;
+ return false;
}
phase = Done;
- return sharedState->rootContext;
+ return true;
}
void QQmlObjectCreator::clear()
@@ -1465,7 +1493,7 @@ void QQmlObjectCreator::clear()
while (sharedState->componentAttached) {
QQmlComponentAttached *a = sharedState->componentAttached;
- a->rem();
+ a->removeFromList();
}
phase = Done;
@@ -1560,9 +1588,9 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
while (alias->aliasToLocalAlias)
alias = _compiledObject->aliasesBegin() + alias->localAliasIndex;
Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
- if (!context->idValues->wasSet())
+ if (!context->isIdValueSet(0)) // TODO: Do we really want 0 here?
continue;
- QObject *target = context->idValues[alias->targetObjectId].data();
+ QObject *target = context->idValue(alias->targetObjectId);
if (!target)
continue;
QQmlData *targetDData = QQmlData::get(target, /*create*/false);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index bca450addb..0b14ec6603 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -57,6 +57,7 @@
#include <private/qrecursionwatcher_p.h>
#include <private/qqmlprofiler_p.h>
#include <private/qv4qmlcontext_p.h>
+#include <private/qqmlguardedcontextdata_p.h>
#include <qpointer.h>
@@ -90,8 +91,8 @@ class RequiredProperties : public QHash<QQmlPropertyData*, RequiredPropertyInfo>
struct QQmlObjectCreatorSharedState : public QSharedData
{
- QQmlContextData *rootContext;
- QQmlContextData *creationContext;
+ QQmlRefPointer<QQmlContextData> rootContext;
+ QQmlRefPointer<QQmlContextData> creationContext;
QFiniteStack<QQmlAbstractBinding::Ptr> allCreatedBindings;
QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
QFiniteStack<QPointer<QObject> > allCreatedObjects;
@@ -108,38 +109,48 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator
{
Q_DECLARE_TR_FUNCTIONS(QQmlObjectCreator)
public:
- QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr);
+ QQmlObjectCreator(QQmlRefPointer<QQmlContextData> parentContext,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ const QQmlRefPointer<QQmlContextData> &creationContext,
+ QQmlIncubatorPrivate *incubator = nullptr);
~QQmlObjectCreator();
enum CreationFlags { NormalObject = 1, InlineComponent = 2 };
- QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr, int flags = NormalObject);
+ QObject *create(int subComponentIndex = -1, QObject *parent = nullptr,
+ QQmlInstantiationInterrupt *interrupt = nullptr, int flags = NormalObject);
bool populateDeferredProperties(QObject *instance, const QQmlData::DeferredData *deferredData);
- void beginPopulateDeferred(QQmlContextData *context);
+ void beginPopulateDeferred(const QQmlRefPointer<QQmlContextData> &context);
void populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
const QV4::CompiledData::Binding *binding);
void finalizePopulateDeferred();
- QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
+ bool finalize(QQmlInstantiationInterrupt &interrupt);
void clear();
+ QQmlRefPointer<QQmlContextData> rootContext() const { return sharedState->rootContext; }
QQmlComponentAttached **componentAttachment() { return &sharedState->componentAttached; }
QList<QQmlEnginePrivate::FinalizeCallback> *finalizeCallbacks() { return &sharedState->finalizeCallbacks; }
QList<QQmlError> errors;
- QQmlContextData *parentContextData() const { return parentContext.contextData(); }
+ QQmlRefPointer<QQmlContextData> parentContextData() const
+ {
+ return parentContext.contextData();
+ }
QFiniteStack<QPointer<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
RequiredProperties &requiredProperties() {return sharedState->requiredProperties;}
bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;}
private:
- QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState);
+ QQmlObjectCreator(QQmlRefPointer<QQmlContextData> contextData,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ QQmlObjectCreatorSharedState *inheritedSharedState);
- void init(QQmlContextData *parentContext);
+ void init(QQmlRefPointer<QQmlContextData> parentContext);
QObject *createInstance(int index, QObject *parent = nullptr, bool isContextObject = false);
@@ -162,7 +173,6 @@ private:
void registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const;
inline QV4::QmlContext *currentQmlContext();
- Q_NEVER_INLINE void createQmlContext();
QV4::ResolvedTypeReference *resolvedType(int id) const
{
return compilationUnit->resolvedType(id);
@@ -182,7 +192,7 @@ private:
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
const QV4::CompiledData::Unit *qmlUnit;
QQmlGuardedContextData parentContext;
- QQmlContextData *context;
+ QQmlRefPointer<QQmlContextData> context;
const QQmlPropertyCacheVector *propertyCaches;
QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
bool topLevelCreator;
diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp
index b8f4bb8c19..cd45e6668b 100644
--- a/src/qml/qml/qqmlparserstatus.cpp
+++ b/src/qml/qml/qqmlparserstatus.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
\code
class MyObject : public QObject, public QQmlParserStatus
{
- Q_OBJECT
+ \Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
public:
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index d6a9e73763..c5c524c27a 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -63,27 +63,15 @@
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qversionnumber.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qdebug.h>
-#define QML_GETTYPENAMES \
- const char *className = T::staticMetaObject.className(); \
- const int nameLen = int(strlen(className)); \
- QVarLengthArray<char,48> pointerName(nameLen+2); \
- memcpy(pointerName.data(), className, size_t(nameLen)); \
- pointerName[nameLen] = '*'; \
- pointerName[nameLen+1] = '\0'; \
- const int listLen = int(strlen("QQmlListProperty<")); \
- QVarLengthArray<char,64> listName(listLen + nameLen + 2); \
- memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \
- memcpy(listName.data()+listLen, className, size_t(nameLen)); \
- listName[listLen+nameLen] = '>'; \
- listName[listLen+nameLen+1] = '\0';
-
QT_BEGIN_NAMESPACE
class QQmlPropertyValueInterceptor;
+class QQmlContext;
namespace QQmlPrivate {
struct CachedQmlUnit;
@@ -105,7 +93,7 @@ typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *)
using QQmlAttachedPropertiesFunc = QQmlPrivate::QQmlAttachedPropertiesFunc<QObject>;
-inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0)
+inline size_t qHash(QQmlAttachedPropertiesFunc func, uint seed = 0)
{
return qHash(quintptr(func), seed);
}
@@ -343,17 +331,16 @@ namespace QQmlPrivate
typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent);
struct RegisterType {
- int version;
+ int structVersion;
- int typeId;
- int listId;
+ QMetaType typeId;
+ QMetaType listId;
int objectSize;
void (*create)(void *);
QString noCreationReason;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *elementName;
const QMetaObject *metaObject;
@@ -369,20 +356,20 @@ namespace QQmlPrivate
QQmlCustomParser *customParser;
- int revision;
+ QTypeRevision revision;
// If this is extended ensure "version" is bumped!!!
};
struct RegisterTypeAndRevisions {
- int version;
+ int structVersion;
- int typeId;
- int listId;
+ QMetaType typeId;
+ QMetaType listId;
int objectSize;
void (*create)(void *);
const char *uri;
- int versionMajor;
+ QTypeRevision version;
const QMetaObject *metaObject;
const QMetaObject *classInfoMetaObject;
@@ -398,81 +385,87 @@ namespace QQmlPrivate
const QMetaObject *extensionMetaObject;
QQmlCustomParser *(*customParserFactory)();
+ QVector<int> *qmlTypeIds;
};
struct RegisterInterface {
- int version;
+ int structVersion;
- int typeId;
- int listId;
+ QMetaType typeId;
+ QMetaType listId;
const char *iid;
const char *uri;
- int versionMajor;
+ QTypeRevision version;
};
struct RegisterAutoParent {
- int version;
+ int structVersion;
AutoParentFunction function;
};
struct RegisterSingletonType {
- int version;
+ int structVersion;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
- QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *);
- const QMetaObject *instanceMetaObject; // new in version 1
- int typeId; // new in version 2
- int revision; // new in version 2
- std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
- // If this is extended ensure "version" is bumped!!!
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> qObjectApi;
+
+ const QMetaObject *instanceMetaObject;
+ QMetaType typeId;
+ QTypeRevision revision;
};
struct RegisterSingletonTypeAndRevisions {
- int version;
+ int structVersion;
const char *uri;
- int versionMajor;
+ QTypeRevision version;
+
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> qObjectApi;
- QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
const QMetaObject *instanceMetaObject;
const QMetaObject *classInfoMetaObject;
- int typeId;
- std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
+ QMetaType typeId;
+ QVector<int> *qmlTypeIds;
};
struct RegisterCompositeType {
+ int structVersion;
QUrl url;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
};
struct RegisterCompositeSingletonType {
+ int structVersion;
QUrl url;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
};
+ struct AOTCompiledFunction {
+ int index;
+ QMetaType returnType;
+ void (*functionPtr)(QQmlContext *context, QObject *scopeObject, void *resultPtr);
+ };
+
struct CachedQmlUnit {
const QV4::CompiledData::Unit *qmlData;
- void *unused1;
+ const AOTCompiledFunction *aotCompiledFunctions;
void *unused2;
};
typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
struct RegisterQmlUnitCacheHook {
- int version;
+ int structVersion;
QmlUnitCacheLookupFunction lookupCachedQmlUnit;
};
@@ -490,7 +483,7 @@ namespace QQmlPrivate
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr);
- struct Q_QML_EXPORT RegisterSingletonFunctor
+ struct Q_QML_EXPORT SingletonFunctor
{
QObject *operator()(QQmlEngine *, QJSEngine *);
@@ -516,11 +509,13 @@ namespace QQmlPrivate
return metaObject->classInfo(indexOfOwnClassInfo(metaObject, key)).value();
}
- inline int intClassInfo(const QMetaObject *metaObject, const char *key, int defaultValue = 0)
+ inline QTypeRevision revisionClassInfo(const QMetaObject *metaObject, const char *key,
+ QTypeRevision defaultValue = QTypeRevision())
{
const int index = indexOfOwnClassInfo(metaObject, key);
return (index == -1) ? defaultValue
- : QByteArray(metaObject->classInfo(index).value()).toInt();
+ : QTypeRevision::fromEncodedVersion(
+ QByteArray(metaObject->classInfo(index).value()).toInt());
}
inline bool boolClassInfo(const QMetaObject *metaObject, const char *key,
@@ -539,9 +534,9 @@ namespace QQmlPrivate
if (qstrcmp(elementName, "anonymous") == 0)
return nullptr;
- if (!elementName || elementName[0] < 'A' || elementName[0] > 'Z') {
- qWarning() << "Missing or unusable QML.Element class info \"" << elementName << "\""
- << "for" << metaObject->className();
+ if (!elementName) {
+ qWarning().nospace() << "Missing QML.Element class info \"" << elementName << "\""
+ << " for " << metaObject->className();
}
return elementName;
@@ -566,7 +561,7 @@ namespace QQmlPrivate
};
template<class T>
- struct QmlResolved<T, QmlVoidT<typename T::QmlForeignType>>
+ struct QmlResolved<T, QmlVoidT<decltype(T::QmlForeignType::staticMetaObject)>>
{
using Type = typename T::QmlForeignType;
};
@@ -597,23 +592,22 @@ namespace QQmlPrivate
template<typename T>
void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
- const QMetaObject *classInfoMetaObject)
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds)
{
- QML_GETTYPENAMES
-
RegisterSingletonTypeAndRevisions api = {
0,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
- nullptr,
+ Constructors<T>::createSingletonInstance,
&T::staticMetaObject,
classInfoMetaObject,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- Constructors<T>::createSingletonInstance
+ QMetaType::fromType<T *>(),
+ qmlTypeIds
};
qmlregister(SingletonAndRevisionsRegistration, &api);
@@ -621,19 +615,18 @@ namespace QQmlPrivate
template<typename T, typename E>
void qmlRegisterTypeAndRevisions(const char *uri, int versionMajor,
- const QMetaObject *classInfoMetaObject)
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds)
{
- QML_GETTYPENAMES
-
RegisterTypeAndRevisions type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ QMetaType::fromType<T*>(),
+ QMetaType::fromType<QQmlListProperty<T>>(),
int(sizeof(T)),
Constructors<T>::createInto,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
&T::staticMetaObject,
classInfoMetaObject,
@@ -648,7 +641,8 @@ namespace QQmlPrivate
ExtendedType<E>::createParent,
ExtendedType<E>::staticMetaObject,
- &qmlCreateCustomParser<T>
+ &qmlCreateCustomParser<T>,
+ qmlTypeIds
};
qmlregister(TypeAndRevisionsRegistration, &type);
@@ -656,7 +650,8 @@ namespace QQmlPrivate
template<>
void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
- const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject);
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds);
} // namespace QQmlPrivate
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 8521de6ab3..3824a7fb6d 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -163,7 +163,6 @@ QQmlProperty::QQmlProperty(QObject *obj, QQmlContext *ctxt)
QQmlProperty::QQmlProperty(QObject *obj, QQmlEngine *engine)
: d(new QQmlPropertyPrivate)
{
- d->context = nullptr;
d->engine = engine;
d->initDefault(obj);
}
@@ -205,7 +204,11 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt)
d->context = ctxt?QQmlContextData::get(ctxt):nullptr;
d->engine = ctxt?ctxt->engine():nullptr;
d->initProperty(obj, name);
- if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; }
+ if (!isValid()) {
+ d->object = nullptr;
+ d->context = nullptr;
+ d->engine = nullptr;
+ }
}
/*!
@@ -216,19 +219,23 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt)
QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlEngine *engine)
: d(new QQmlPropertyPrivate)
{
- d->context = nullptr;
d->engine = engine;
d->initProperty(obj, name);
- if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; }
+ if (!isValid()) {
+ d->object = nullptr;
+ d->context = nullptr;
+ d->engine = nullptr;
+ }
}
-QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propertyName, QQmlContextData *context)
+QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propertyName,
+ const QQmlRefPointer<QQmlContextData> &context)
{
QQmlProperty result;
auto d = new QQmlPropertyPrivate;
result.d = d;
d->context = context;
- d->engine = context ? context->engine : nullptr;
+ d->engine = context ? context->engine() : nullptr;
d->initProperty(target, propertyName);
if (!result.isValid()) {
d->object = nullptr;
@@ -238,23 +245,21 @@ QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propert
return result;
}
-QQmlPropertyPrivate::QQmlPropertyPrivate()
-: context(nullptr), engine(nullptr), object(nullptr), isNameCached(false)
+QQmlRefPointer<QQmlContextData> QQmlPropertyPrivate::effectiveContext() const
{
-}
-
-QQmlContextData *QQmlPropertyPrivate::effectiveContext() const
-{
- if (context) return context;
- else if (engine) return QQmlContextData::get(engine->rootContext());
- else return nullptr;
+ if (context)
+ return context;
+ else if (engine)
+ return QQmlContextData::get(engine->rootContext());
+ else
+ return nullptr;
}
void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
{
if (!obj) return;
- QQmlRefPointer<QQmlTypeNameCache> typeNameCache = context?context->imports:nullptr;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache = context ? context->imports() : nullptr;
QObject *currentObject = obj;
QVector<QStringRef> path;
@@ -974,7 +979,7 @@ void QQmlPropertyPrivate::takeSignalExpression(const QQmlProperty &that,
if (expr) {
int signalIndex = QQmlPropertyPrivate::get(that)->signalIndex();
QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, signalIndex, that.d->object,
- expr->context()->engine);
+ expr->engine());
signal->takeExpression(expr);
}
}
@@ -1097,7 +1102,8 @@ QVariant QQmlPropertyPrivate::readValueProperty()
}
// helper function to allow assignment / binding to QList<QUrl> properties.
-QVariant QQmlPropertyPrivate::resolvedUrlSequence(const QVariant &value, QQmlContextData *context)
+QVariant QQmlPropertyPrivate::resolvedUrlSequence(
+ const QVariant &value, const QQmlRefPointer<QQmlContextData> &context)
{
QList<QUrl> urls;
if (value.userType() == qMetaTypeId<QUrl>()) {
@@ -1186,7 +1192,8 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
const QQmlPropertyData &core,
const QQmlPropertyData &valueTypeData,
const QVariant &value,
- QQmlContextData *context,QQmlPropertyData::WriteFlags flags)
+ const QQmlRefPointer<QQmlContextData> &context,
+ QQmlPropertyData::WriteFlags flags)
{
// Remove any existing bindings on this property
if (!(flags & QQmlPropertyData::DontRemoveBinding) && object)
@@ -1201,7 +1208,7 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
};
QQmlGadgetPtrWrapper *wrapper = context
- ? QQmlGadgetPtrWrapper::instance(context->engine, core.propType())
+ ? QQmlGadgetPtrWrapper::instance(context->engine(), core.propType())
: nullptr;
if (wrapper) {
doWrite(wrapper);
@@ -1217,10 +1224,9 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
return rv;
}
-bool QQmlPropertyPrivate::write(QObject *object,
- const QQmlPropertyData &property,
- const QVariant &value, QQmlContextData *context,
- QQmlPropertyData::WriteFlags flags)
+bool QQmlPropertyPrivate::write(
+ QObject *object, const QQmlPropertyData &property, const QVariant &value,
+ const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData::WriteFlags flags)
{
const int propertyType = property.propType();
const int variantType = value.userType();
@@ -1647,14 +1653,15 @@ QQmlPropertyIndex QQmlPropertyPrivate::propertyIndex(const QQmlProperty &that)
QQmlProperty
QQmlPropertyPrivate::restore(QObject *object, const QQmlPropertyData &data,
- const QQmlPropertyData *valueTypeData, QQmlContextData *ctxt)
+ const QQmlPropertyData *valueTypeData,
+ const QQmlRefPointer<QQmlContextData> &ctxt)
{
QQmlProperty prop;
prop.d = new QQmlPropertyPrivate;
prop.d->object = object;
prop.d->context = ctxt;
- prop.d->engine = ctxt ? ctxt->engine : nullptr;
+ prop.d->engine = ctxt ? ctxt->engine() : nullptr;
prop.d->core = data;
if (valueTypeData)
diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h
index 34eab8208c..2fd14719c6 100644
--- a/src/qml/qml/qqmlproperty.h
+++ b/src/qml/qml/qqmlproperty.h
@@ -127,7 +127,7 @@ private:
};
typedef QList<QQmlProperty> QQmlProperties;
-inline uint qHash (const QQmlProperty &key)
+inline size_t qHash (const QQmlProperty &key)
{
return qHash(key.object()) + qHash(key.name());
}
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index 8abd83d7b4..5e357d77c0 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -57,9 +57,10 @@
#include <private/qobject_p.h>
#include <private/qtqmlglobal_p.h>
#include <private/qqmlrefcount_p.h>
-#include <private/qqmlcontext_p.h>
+#include <private/qqmlcontextdata_p.h>
#include <private/qqmlboundsignalexpressionpointer_p.h>
#include <private/qqmlpropertydata_p.h>
+#include <private/qqmlpropertyindex_p.h>
QT_BEGIN_NAMESPACE
@@ -67,11 +68,12 @@ class QQmlContext;
class QQmlEnginePrivate;
class QQmlJavaScriptExpression;
class QQmlMetaObject;
+class QQmlAbstractBinding;
class Q_QML_PRIVATE_EXPORT QQmlPropertyPrivate : public QQmlRefCount
{
public:
- QQmlContextData *context;
+ QQmlRefPointer<QQmlContextData> context;
QPointer<QQmlEngine> engine;
QPointer<QObject> object;
@@ -81,14 +83,14 @@ public:
bool isNameCached:1;
QString nameCache;
- QQmlPropertyPrivate();
+ QQmlPropertyPrivate() : isNameCached(false) {}
QQmlPropertyIndex encodedIndex() const
{ return encodedIndex(core, valueTypeData); }
static QQmlPropertyIndex encodedIndex(const QQmlPropertyData &core, const QQmlPropertyData &valueTypeData)
{ return QQmlPropertyIndex(core.coreIndex(), valueTypeData.coreIndex()); }
- inline QQmlContextData *effectiveContext() const;
+ QQmlRefPointer<QQmlContextData> effectiveContext() const;
void initProperty(QObject *obj, const QString &name);
void initDefault(QObject *obj);
@@ -106,10 +108,11 @@ public:
const QVariant &value, int flags);
static bool writeValueProperty(QObject *,
const QQmlPropertyData &, const QQmlPropertyData &valueTypeData,
- const QVariant &, QQmlContextData *,
+ const QVariant &, const QQmlRefPointer<QQmlContextData> &,
QQmlPropertyData::WriteFlags flags = {});
static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
- QQmlContextData *, QQmlPropertyData::WriteFlags flags = {});
+ const QQmlRefPointer<QQmlContextData> &,
+ QQmlPropertyData::WriteFlags flags = {});
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *);
enum BindingFlag {
@@ -126,7 +129,8 @@ public:
static void removeBinding(QQmlAbstractBinding *b);
static QQmlAbstractBinding *binding(QObject *, QQmlPropertyIndex index);
- static QQmlProperty restore(QObject *, const QQmlPropertyData &, const QQmlPropertyData *, QQmlContextData *);
+ static QQmlProperty restore(QObject *, const QQmlPropertyData &, const QQmlPropertyData *,
+ const QQmlRefPointer<QQmlContextData> &);
int signalIndex() const;
@@ -146,8 +150,11 @@ public:
int type = 0, int *types = nullptr);
static void flushSignal(const QObject *sender, int signal_index);
- static QVariant resolvedUrlSequence(const QVariant &value, QQmlContextData *context);
- static QQmlProperty create(QObject *target, const QString &propertyName, QQmlContextData *context);
+ static QVariant resolvedUrlSequence(
+ const QVariant &value, const QQmlRefPointer<QQmlContextData> &context);
+ static QQmlProperty create(
+ QObject *target, const QString &propertyName,
+ const QQmlRefPointer<QQmlContextData> &context);
};
diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp
new file mode 100644
index 0000000000..c7f620c88c
--- /dev/null
+++ b/src/qml/qml/qqmlpropertybinding.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml 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 "qqmlpropertybinding_p.h"
+
+#include <private/qpropertybinding_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QUntypedPropertyBinding QQmlPropertyBinding::create(const QQmlPropertyData *pd, QV4::Function *function,
+ QObject *obj, const QQmlRefPointer<QQmlContextData> &ctxt,
+ QV4::ExecutionContext *scope)
+{
+ if (auto aotFunction = function->aotFunction; aotFunction && aotFunction->returnType.id() == pd->propType()) {
+ return QUntypedPropertyBinding(aotFunction->returnType,
+ [
+ aotFunction,
+ unit = QQmlRefPointer<QV4::ExecutableCompilationUnit>(function->executableCompilationUnit()),
+ scopeObject = QPointer<QObject>(obj),
+ context = ctxt
+ ](const QMetaType &, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult {
+ Q_UNUSED(unit); // to keep refcount
+ aotFunction->functionPtr(context->asQQmlContext(), scopeObject.data(), dataPtr);
+ return QPropertyBindingError::NoError;
+ },
+ QPropertyBindingSourceLocation());
+ }
+
+ auto binding = new QQmlPropertyBinding(QMetaType(pd->propType()));
+ binding->setNotifyOnValueChanged(true);
+ binding->setContext(ctxt);
+ binding->setScopeObject(obj);
+ binding->setupFunction(scope, function);
+ return QUntypedPropertyBinding(QPropertyBindingPrivatePtr(binding).data());
+}
+
+void QQmlPropertyBinding::expressionChanged()
+{
+ markDirtyAndNotifyObservers();
+}
+
+QQmlPropertyBinding::QQmlPropertyBinding(const QMetaType &mt)
+ : QPropertyBindingPrivate(mt,
+ [this](const QMetaType &metaType, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult {
+ return evaluate(metaType, dataPtr);
+ }, QPropertyBindingSourceLocation())
+{
+}
+
+QUntypedPropertyBinding::BindingEvaluationResult QQmlPropertyBinding::evaluate(const QMetaType &metaType, void *dataPtr)
+{
+ QQmlEngine *engine = context()->engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ ep->referenceScarceResources();
+
+ bool isUndefined = false;
+
+ QV4::Scope scope(engine->handle());
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
+
+ ep->dereferenceScarceResources();
+
+ if (hasError()) {
+ QPropertyBindingError error(QPropertyBindingError::UnknownError);
+ error.setDescription(delayedError()->error().description());
+ return error;
+ }
+
+ QVariant resultVariant(scope.engine->toVariant(result, metaType.id()));
+ QMetaType::destruct(metaType.id(), dataPtr);
+ QMetaType::construct(metaType.id(), dataPtr, resultVariant.constData());
+ return QPropertyBindingError::NoError;
+}
+
+QUntypedPropertyBinding QQmlTranslationPropertyBinding::create(const QQmlPropertyData *pd, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding)
+{
+ auto translationBinding = [compilationUnit, binding](const QMetaType &metaType, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult {
+ // Create a dependency to the uiLanguage
+ QJSEnginePrivate::get(compilationUnit->engine)->uiLanguage.value();
+
+ QVariant resultVariant(compilationUnit->bindingValueAsString(binding));
+ if (metaType.id() != QMetaType::QString)
+ resultVariant.convert(metaType.id());
+
+ QMetaType::destruct(metaType.id(), dataPtr);
+ QMetaType::construct(metaType.id(), dataPtr, resultVariant.constData());
+ return QPropertyBindingError::NoError;
+ };
+
+ return QUntypedPropertyBinding(QMetaType(pd->propType()), translationBinding, QPropertyBindingSourceLocation());
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h b/src/qml/qml/qqmlpropertybinding_p.h
index b7748d12a0..086ab1615d 100644
--- a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h
+++ b/src/qml/qml/qqmlpropertybinding_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QQMLWORKERSCRIPTMODULE_P_H
-#define QQMLWORKERSCRIPTMODULE_P_H
+#ifndef QQMLPROPERTYBINDING_P_H
+#define QQMLPROPERTYBINDING_P_H
//
// W A R N I N G
@@ -51,18 +51,40 @@
// We mean it.
//
-#include <private/qtqmlworkerscriptglobal_p.h>
+#include <QtCore/qproperty.h>
+#include <private/qpropertybinding_p.h>
+
+#include "qqmlpropertydata_p.h"
+#include "qqmljavascriptexpression_p.h"
+
+#include <memory>
QT_BEGIN_NAMESPACE
-class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQmlWorkerScriptModule
+class QQmlPropertyBinding : public QQmlJavaScriptExpression,
+ public QPropertyBindingPrivate
+{
+public:
+ static QUntypedPropertyBinding create(const QQmlPropertyData *pd, QV4::Function *function,
+ QObject *obj, const QQmlRefPointer<QQmlContextData> &ctxt,
+ QV4::ExecutionContext *scope);
+
+ virtual void expressionChanged();
+
+private:
+ QQmlPropertyBinding(const QMetaType &metaType);
+
+ QUntypedPropertyBinding::BindingEvaluationResult evaluate(const QMetaType &metaType, void *dataPtr);
+};
+
+class QQmlTranslationPropertyBinding
{
public:
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- static void registerQuickTypes();
-#endif
+ static QUntypedPropertyBinding create(const QQmlPropertyData *pd,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ const QV4::CompiledData::Binding *binding);
};
QT_END_NAMESPACE
-#endif // QQMLWORKERSCRIPTMODULE_P_H
+#endif // QQMLPROPERTYBINDING_P_H
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 0e5534fc04..d1b040ee99 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -76,6 +76,7 @@ static QQmlPropertyData::Flags fastFlagsForProperty(const QMetaProperty &p)
flags.setIsResettable(p.isResettable());
flags.setIsFinal(p.isFinal());
flags.setIsRequired(p.isRequired());
+ flags.setIsQProperty(p.isQProperty());
if (p.isEnumType())
flags.type = QQmlPropertyData::Flags::EnumType;
@@ -83,13 +84,11 @@ static QQmlPropertyData::Flags fastFlagsForProperty(const QMetaProperty &p)
return flags;
}
-// Flags that do depend on the property's QMetaProperty::userType() and thus are slow to
-// load
-static void flagsForPropertyType(int propType, QQmlPropertyData::Flags &flags)
+// Flags that do depend on the property's QMetaType
+static void flagsForPropertyType(QMetaType metaType, QQmlPropertyData::Flags &flags)
{
- Q_ASSERT(propType != -1);
-
- if (propType == QMetaType::QObjectStar) {
+ int propType = metaType.id();
+ if (metaType.flags() & QMetaType::PointerToQObject) {
flags.type = QQmlPropertyData::Flags::QObjectDerivedType;
} else if (propType == QMetaType::QVariant) {
flags.type = QQmlPropertyData::Flags::QVariantType;
@@ -101,8 +100,7 @@ static void flagsForPropertyType(int propType, QQmlPropertyData::Flags &flags)
flags.type = QQmlPropertyData::Flags::QJSValueType;
} else {
QQmlMetaType::TypeCategory cat = QQmlMetaType::typeCategory(propType);
-
- if (cat == QQmlMetaType::Object || QMetaType::typeFlags(propType) & QMetaType::PointerToQObject)
+ if (cat == QQmlMetaType::Object)
flags.type = QQmlPropertyData::Flags::QObjectDerivedType;
else if (cat == QQmlMetaType::List)
flags.type = QQmlPropertyData::Flags::QListType;
@@ -121,17 +119,17 @@ QQmlPropertyData::Flags
QQmlPropertyData::flagsForProperty(const QMetaProperty &p)
{
auto flags = fastFlagsForProperty(p);
- flagsForPropertyType(p.userType(), flags);
+ flagsForPropertyType(p.metaType(), flags);
return flags;
}
static void populate(QQmlPropertyData *data, const QMetaProperty &p)
{
- Q_ASSERT(p.revision() <= Q_INT16_MAX);
+ Q_ASSERT(p.revision() <= std::numeric_limits<quint16>::max());
data->setCoreIndex(p.propertyIndex());
data->setNotifyIndex(QMetaObjectPrivate::signalIndex(p.notifySignal()));
data->setFlags(fastFlagsForProperty(p));
- data->setRevision(p.revision());
+ data->setRevision(QTypeRevision::fromEncodedVersion(p.revision()));
}
void QQmlPropertyData::lazyLoad(const QMetaProperty &p)
@@ -154,8 +152,9 @@ void QQmlPropertyData::lazyLoad(const QMetaProperty &p)
void QQmlPropertyData::load(const QMetaProperty &p)
{
populate(this, p);
- setPropType(p.userType());
- flagsForPropertyType(propType(), m_flags);
+ QMetaType type = p.metaType();
+ setPropType(type.id());
+ flagsForPropertyType(type, m_flags);
}
void QQmlPropertyData::load(const QMetaMethod &m)
@@ -183,8 +182,8 @@ void QQmlPropertyData::load(const QMetaMethod &m)
if (m.attributes() & QMetaMethod::Cloned)
m_flags.setIsCloned(true);
- Q_ASSERT(m.revision() <= Q_INT16_MAX);
- setRevision(m.revision());
+ Q_ASSERT(m.revision() <= std::numeric_limits<quint16>::max());
+ setRevision(QTypeRevision::fromEncodedVersion(m.revision()));
}
void QQmlPropertyData::lazyLoad(const QMetaMethod &m)
@@ -212,14 +211,14 @@ QQmlPropertyCache::QQmlPropertyCache()
/*!
Creates a new QQmlPropertyCache of \a metaObject.
*/
-QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, int metaObjectRevision)
+QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, QTypeRevision metaObjectRevision)
: QQmlPropertyCache()
{
Q_ASSERT(metaObject);
update(metaObject);
- if (metaObjectRevision > 0) {
+ if (metaObjectRevision.isValid() && metaObjectRevision != QTypeRevision::zero()) {
// Set the revision of the meta object that this cache describes to be
// 'metaObjectRevision'. This is useful when constructing a property cache
// from a type that was created directly in C++, and not through QML. For such
@@ -291,14 +290,15 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth
This is different from QMetaMethod::methodIndex().
*/
void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags,
- int coreIndex, int propType, int minorVersion, int notifyIndex)
+ int coreIndex, int propType, QTypeRevision version,
+ int notifyIndex)
{
QQmlPropertyData data;
data.setPropType(propType);
data.setCoreIndex(coreIndex);
data.setNotifyIndex(notifyIndex);
data.setFlags(flags);
- data.setTypeMinorVersion(minorVersion);
+ data.setTypeVersion(version);
QQmlPropertyData *old = findNamedProperty(name);
if (old)
@@ -433,12 +433,12 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject,
QQmlPropertyData::Flags methodFlags,
QQmlPropertyData::Flags signalFlags)
{
- return copyAndAppend(metaObject, -1, propertyFlags, methodFlags, signalFlags);
+ return copyAndAppend(metaObject, QTypeRevision(), propertyFlags, methodFlags, signalFlags);
}
QQmlPropertyCache *
QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject,
- int typeMinorVersion,
+ QTypeRevision typeVersion,
QQmlPropertyData::Flags propertyFlags,
QQmlPropertyData::Flags methodFlags,
QQmlPropertyData::Flags signalFlags)
@@ -452,13 +452,13 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject,
QMetaObjectPrivate::get(metaObject)->signalCount +
QMetaObjectPrivate::get(metaObject)->propertyCount);
- rv->append(metaObject, typeMinorVersion, propertyFlags, methodFlags, signalFlags);
+ rv->append(metaObject, typeVersion, propertyFlags, methodFlags, signalFlags);
return rv;
}
void QQmlPropertyCache::append(const QMetaObject *metaObject,
- int typeMinorVersion,
+ QTypeRevision typeVersion,
QQmlPropertyData::Flags propertyFlags,
QQmlPropertyData::Flags methodFlags,
QQmlPropertyData::Flags signalFlags)
@@ -467,7 +467,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
bool dynamicMetaObject = isDynamicMetaObject(metaObject);
- allowedRevisionCache.append(0);
+ allowedRevisionCache.append(QTypeRevision::zero());
int methodCount = metaObject->methodCount();
Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4);
@@ -496,7 +496,9 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
// These indices don't apply to gadgets, so don't block them.
- const bool preventDestruction = metaObject->superClass() || metaObject == &QObject::staticMetaObject;
+ // It is enough to check for QObject::staticMetaObject here because the loop below excludes
+ // methods of parent classes: It starts at metaObject->methodOffset()
+ const bool preventDestruction = (metaObject == &QObject::staticMetaObject);
int methodOffset = metaObject->methodOffset();
int signalOffset = signalCount - QMetaObjectPrivate::get(metaObject)->signalCount;
@@ -612,7 +614,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->setFlags(propertyFlags);
data->lazyLoad(p);
- data->setTypeMinorVersion(typeMinorVersion);
+ data->setTypeVersion(typeVersion);
data->m_flags.setIsDirect(!dynamicMetaObject);
@@ -662,7 +664,7 @@ void QQmlPropertyCache::resolve(QQmlPropertyData *data) const
data->setPropType(QMetaType::type(retTy));
} else {
auto metaProperty = mo->property(data->coreIndex());
- data->setPropType(QMetaType::type(metaProperty.typeName()));
+ data->setPropType(metaProperty.metaType().id());
}
if (!data->isFunction()) {
@@ -686,7 +688,7 @@ void QQmlPropertyCache::resolve(QQmlPropertyData *data) const
data->setPropType(registerResult == -1 ? QMetaType::UnknownType : registerResult);
}
}
- flagsForPropertyType(data->propType(), data->m_flags);
+ flagsForPropertyType(QMetaType(data->propType()), data->m_flags);
}
}
@@ -697,7 +699,7 @@ void QQmlPropertyCache::updateRecur(const QMetaObject *metaObject)
updateRecur(metaObject->superClass());
- append(metaObject, -1);
+ append(metaObject, QTypeRevision());
}
void QQmlPropertyCache::update(const QMetaObject *metaObject)
@@ -745,7 +747,7 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
methodIndexCacheStart = parent()->methodIndexCache.count() + parent()->methodIndexCacheStart;
signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.count() + parent()->signalHandlerIndexCacheStart;
stringCache.linkAndReserve(parent()->stringCache, reserve);
- append(metaObject, -1);
+ append(metaObject, QTypeRevision());
} else {
propertyIndexCacheStart = 0;
methodIndexCacheStart = 0;
@@ -754,7 +756,9 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
}
}
-QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, QObject *object, QQmlContextData *context) const
+QQmlPropertyData *QQmlPropertyCache::findProperty(
+ StringCache::ConstIterator it, QObject *object,
+ const QQmlRefPointer<QQmlContextData> &context) const
{
QQmlData *data = (object ? QQmlData::get(object) : nullptr);
const QQmlVMEMetaObject *vmemo = nullptr;
@@ -767,11 +771,11 @@ QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it,
namespace {
-inline bool contextHasNoExtensions(QQmlContextData *context)
+inline bool contextHasNoExtensions(const QQmlRefPointer<QQmlContextData> &context)
{
// This context has no extension if its parent is the engine's rootContext,
// which has children but no imports
- return (!context->parent || !context->parent->imports);
+ return (!context->parent() || !context->parent()->imports());
}
inline int maximumIndexForProperty(QQmlPropertyData *prop, const int methodCount, const int signalCount, const int propertyCount)
@@ -783,7 +787,9 @@ inline int maximumIndexForProperty(QQmlPropertyData *prop, const int methodCount
}
-QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *vmemo, QQmlContextData *context) const
+QQmlPropertyData *QQmlPropertyCache::findProperty(
+ StringCache::ConstIterator it, const QQmlVMEMetaObject *vmemo,
+ const QQmlRefPointer<QQmlContextData> &context) const
{
StringCache::ConstIterator end = stringCache.end();
@@ -797,7 +803,7 @@ QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it,
if (vmemo && context && !contextHasNoExtensions(context)) {
// Find the meta-object that corresponds to the supplied context
do {
- if (vmemo->ctxt == context)
+ if (vmemo->ctxt.contextData().data() == context.data())
break;
vmemo = vmemo->parentVMEMetaObject();
@@ -1008,7 +1014,7 @@ static inline QByteArray qQmlPropertyCacheToString(const QV4::String *string)
template<typename T>
QQmlPropertyData *
qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name,
- QQmlContextData *context, QQmlPropertyData &local)
+ const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData &local)
{
QQmlPropertyCache *cache = nullptr;
@@ -1041,21 +1047,21 @@ qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name,
QQmlPropertyData *
QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QV4::String *name,
- QQmlContextData *context, QQmlPropertyData &local)
+ const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData &local)
{
return qQmlPropertyCacheProperty<const QV4::String *>(engine, obj, name, context, local);
}
QQmlPropertyData *
QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QStringRef &name,
- QQmlContextData *context, QQmlPropertyData &local)
+ const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData &local)
{
return qQmlPropertyCacheProperty<const QStringRef &>(engine, obj, name, context, local);
}
QQmlPropertyData *
QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QLatin1String &name,
- QQmlContextData *context, QQmlPropertyData &local)
+ const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData &local)
{
return qQmlPropertyCacheProperty<const QLatin1String &>(engine, obj, name, context, local);
}
@@ -1066,13 +1072,10 @@ static inline const QMetaObjectPrivate *priv(const uint* data)
static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
- Q_ASSERT(priv(mo->d.data)->revision >= 7);
- const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
- Q_ASSERT(data.ptr->ref.isStatic());
- Q_ASSERT(data.ptr->alloc == 0);
- Q_ASSERT(data.ptr->capacityReserved == 0);
- Q_ASSERT(data.ptr->size >= 0);
- return data;
+ uint offset = mo->d.stringdata[2*index];
+ uint length = mo->d.stringdata[2*index + 1];
+ const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+ return QByteArray::fromRawData(string, length);
}
bool QQmlPropertyCache::isDynamicMetaObject(const QMetaObject *mo)
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index a5340cec37..43ffb0fb36 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -60,6 +60,7 @@
#include <private/qlinkedstringhash_p.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
+#include <QtCore/qversionnumber.h>
#include <private/qv4value_p.h>
#include <private/qqmlpropertydata_p.h>
@@ -80,7 +81,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount
{
public:
QQmlPropertyCache();
- QQmlPropertyCache(const QMetaObject *, int metaObjectRevision = 0);
+ QQmlPropertyCache(const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero());
~QQmlPropertyCache() override;
void update(const QMetaObject *);
@@ -92,7 +93,8 @@ public:
QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
- QQmlPropertyCache *copyAndAppend(const QMetaObject *, int typeMinorVersion,
+ QQmlPropertyCache *copyAndAppend(
+ const QMetaObject *, QTypeRevision typeVersion,
QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
@@ -100,7 +102,7 @@ public:
QQmlPropertyCache *copyAndReserve(int propertyCount,
int methodCount, int signalCount, int enumCount);
void appendProperty(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
- int propType, int revision, int notifyIndex);
+ int propType, QTypeRevision revision, int notifyIndex);
void appendSignal(const QString &, QQmlPropertyData::Flags, int coreIndex,
const int *types = nullptr, const QList<QByteArray> &names = QList<QByteArray>());
void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex, int returnType,
@@ -112,7 +114,8 @@ public:
const QMetaObject *firstCppMetaObject() const;
template<typename K>
- QQmlPropertyData *property(const K &key, QObject *object, QQmlContextData *context) const
+ QQmlPropertyData *property(const K &key, QObject *object,
+ const QQmlRefPointer<QQmlContextData> &context) const
{
return findProperty(stringCache.find(key), object, context);
}
@@ -134,14 +137,15 @@ public:
inline bool isAllowedInRevision(QQmlPropertyData *) const;
static QQmlPropertyData *property(QJSEngine *, QObject *, const QStringRef &,
- QQmlContextData *, QQmlPropertyData &);
+ const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *, QObject *, const QLatin1String &,
- QQmlContextData *, QQmlPropertyData &);
+ const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *, QObject *, const QV4::String *,
- QQmlContextData *, QQmlPropertyData &);
+ const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *engine, QObject *obj, const QString &name,
- QQmlContextData *context, QQmlPropertyData &local)
+ const QQmlRefPointer<QQmlContextData> &context,
+ QQmlPropertyData &local)
{
return property(engine, obj, QStringRef(&name), context, local);
}
@@ -174,8 +178,8 @@ public:
QByteArray checksum(bool *ok);
- int allowedRevision(int index) const { return allowedRevisionCache[index]; }
- void setAllowedRevision(int index, int allowed) { allowedRevisionCache[index] = allowed; }
+ QTypeRevision allowedRevision(int index) const { return allowedRevisionCache[index]; }
+ void setAllowedRevision(int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; }
private:
friend class QQmlEnginePrivate;
@@ -187,7 +191,7 @@ private:
inline QQmlPropertyCache *copy(int reserve);
- void append(const QMetaObject *, int typeMinorVersion,
+ void append(const QMetaObject *, QTypeRevision typeVersion,
QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
@@ -196,10 +200,12 @@ private:
typedef QVector<QQmlPropertyData> IndexCache;
typedef QLinkedStringMultiHash<QPair<int, QQmlPropertyData *> > StringCache;
- typedef QVector<int> AllowedRevisionCache;
+ typedef QVector<QTypeRevision> AllowedRevisionCache;
- QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *, QQmlContextData *) const;
- QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *, QQmlContextData *) const;
+ QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *,
+ const QQmlRefPointer<QQmlContextData> &) const;
+ QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *,
+ const QQmlRefPointer<QQmlContextData> &) const;
QQmlPropertyData *ensureResolved(QQmlPropertyData*) const;
@@ -352,8 +358,23 @@ QQmlPropertyCache::overrideData(QQmlPropertyData *data) const
bool QQmlPropertyCache::isAllowedInRevision(QQmlPropertyData *data) const
{
- return (data->metaObjectOffset() == -1 && data->revision() == 0) ||
- (allowedRevisionCache[data->metaObjectOffset()] >= data->revision());
+ const QTypeRevision requested = data->revision();
+ const int offset = data->metaObjectOffset();
+ if (offset == -1 && requested == QTypeRevision::zero())
+ return true;
+
+ Q_ASSERT(offset >= 0);
+ Q_ASSERT(offset < allowedRevisionCache.length());
+ const QTypeRevision allowed = allowedRevisionCache[data->metaObjectOffset()];
+
+ if (requested.hasMajorVersion()) {
+ if (requested.majorVersion() > allowed.majorVersion())
+ return false;
+ if (requested.majorVersion() < allowed.majorVersion())
+ return true;
+ }
+
+ return !requested.hasMinorVersion() || requested.minorVersion() <= allowed.minorVersion();
}
int QQmlPropertyCache::propertyCount() const
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index 36581bda4e..f132fb2d78 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -119,9 +119,12 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating
{
if (instantiatingProperty) {
if (instantiatingProperty->isQObject()) {
- return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), instantiatingProperty->typeMinorVersion());
+ // rawPropertyCacheForType assumes a given unspecified version means "any version".
+ // There is another overload that takes no version, which we shall not use here.
+ return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(),
+ instantiatingProperty->typeVersion());
} else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) {
- return enginePrivate->cache(vtmo, instantiatingProperty->typeMinorVersion());
+ return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion());
}
}
return QQmlRefPointer<QQmlPropertyCache>();
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 6b02d6fb98..b98ebebed3 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -197,7 +197,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
const auto &ic = allICs[nodeIt->index];
QV4::ResolvedTypeReference *typeRef = objectContainer->resolvedType(ic.nameIndex);
Q_ASSERT(propertyCaches->at(ic.objectIndex) == nullptr);
- Q_ASSERT(typeRef->typePropertyCache.isNull()); // not set yet
+ Q_ASSERT(typeRef->typePropertyCache().isNull()); // not set yet
QByteArray icTypeName { objectContainer->stringAt(ic.nameIndex).toUtf8() };
QScopedValueRollback<QByteArray> nameChange {typeClassName, icTypeName};
@@ -206,8 +206,8 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
if (diag.isValid()) {
return diag;
}
- typeRef->typePropertyCache = propertyCaches->at(ic.objectIndex);
- Q_ASSERT(!typeRef->typePropertyCache.isNull());
+ typeRef->setTypePropertyCache(propertyCaches->at(ic.objectIndex));
+ Q_ASSERT(!typeRef->typePropertyCache().isNull());
}
return buildMetaObjectRecursively(/*root object*/0, context, VMEMetaObjectIsRequired::Maybe);
@@ -226,7 +226,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecur
|| obj->signalCount() != 0 || obj->functionCount() != 0 || obj->enumCount() != 0
|| (((obj->flags & QV4::CompiledData::Object::IsComponent)
|| (objectIndex == 0 && isAddressable(objectContainer->url())))
- && !objectContainer->resolvedType(obj->inheritedTypeNameIndex)->isFullyDynamicType);
+ && !objectContainer->resolvedType(obj->inheritedTypeNameIndex)->isFullyDynamicType());
if (!needVMEMetaObject) {
auto binding = obj->bindingsBegin();
@@ -305,10 +305,9 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
return context.instantiatingPropertyCache(enginePrivate);
} else if (obj->inheritedTypeNameIndex != 0) {
auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
- QQmlType qmltype = typeRef->type;
Q_ASSERT(typeRef);
- if (typeRef->isFullyDynamicType) {
+ if (typeRef->isFullyDynamicType()) {
if (obj->propertyCount() > 0 || obj->aliasCount() > 0) {
*error = qQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully dynamic types cannot declare new properties."));
return nullptr;
@@ -328,7 +327,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
auto *typeRef = objectContainer->resolvedType(
context.instantiatingBinding->propertyNameIndex);
Q_ASSERT(typeRef);
- QQmlType qmltype = typeRef->type;
+ QQmlType qmltype = typeRef->type();
if (!qmltype.isValid()) {
imports->resolveType(stringAt(context.instantiatingBinding->propertyNameIndex),
&qmltype, nullptr, nullptr, nullptr);
@@ -368,16 +367,11 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
cache->_dynamicClassName = newClassName;
- int varPropCount = 0;
-
QQmlPropertyResolver resolver(baseTypeCache);
auto p = obj->propertiesBegin();
auto pend = obj->propertiesEnd();
for ( ; p != pend; ++p) {
- if (p->builtinType() == QV4::CompiledData::BuiltinType::Var)
- varPropCount++;
-
bool notInRevision = false;
QQmlPropertyData *d = resolver.property(stringAt(p->nameIndex), &notInRevision);
if (d && d->isFinal())
@@ -539,7 +533,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
pend = obj->propertiesEnd();
for ( ; p != pend; ++p, ++propertyIdx) {
int propertyType = 0;
- int propertTypeMinorVersion = 0;
+ QTypeRevision propertyTypeVersion = QTypeRevision::zero();
QQmlPropertyData::Flags propertyFlags;
const QV4::CompiledData::BuiltinType type = p->builtinType();
@@ -558,7 +552,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
QQmlType qmltype;
bool selfReference = false;
- if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr,
+ if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr,
nullptr, QQmlType::AnyRegistrationType, &selfReference)) {
return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
@@ -568,7 +562,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
if (qmltype.isComposite() || qmltype.isInlineComponentType()) {
CompositeMetaTypeIds typeIds;
if (qmltype.isInlineComponentType()) {
- auto objectId = qmltype.inlineComponendId();
+ auto objectId = qmltype.inlineComponentId();
auto containingType = qmltype.containingType();
if (containingType.isValid()) {
auto icType = containingType.lookupInlineComponentById(objectId);
@@ -591,16 +585,16 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
}
if (p->isList) {
- propertyType = typeIds.listId;
+ propertyType = typeIds.listId.id();
} else {
- propertyType = typeIds.id;
+ propertyType = typeIds.id.id();
}
} else {
if (p->isList) {
- propertyType = qmltype.qListTypeId();
+ propertyType = qmltype.qListTypeId().id();
} else {
- propertyType = qmltype.typeId();
- propertTypeMinorVersion = qmltype.minorVersion();
+ propertyType = qmltype.typeId().id();
+ propertyTypeVersion = qmltype.version();
}
}
@@ -618,7 +612,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int
if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias)
cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, propertTypeMinorVersion, effectiveSignalIndex);
+ propertyType, propertyTypeVersion, effectiveSignalIndex);
effectiveSignalIndex++;
}
@@ -642,15 +636,15 @@ inline int QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter(const
*customTypeName = typeName;
QQmlType qmltype;
bool selfReference = false;
- if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType,
- &selfReference))
+ if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr,
+ QQmlType::AnyRegistrationType, &selfReference))
return QMetaType::UnknownType;
if (!qmltype.isComposite())
- return qmltype.typeId();
+ return qmltype.typeId().id();
if (selfReference)
- return objectContainer->typeIdsForComponent().id;
+ return objectContainer->typeIdsForComponent().id.id();
QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
@@ -658,7 +652,7 @@ inline int QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter(const
auto compilationUnit = tdata->compilationUnit();
- return compilationUnit->metaTypeId;
+ return compilationUnit->metaTypeId.id();
}
template <typename ObjectContainer>
@@ -675,7 +669,7 @@ public:
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv);
- QQmlError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv);
+ QQmlError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -786,8 +780,10 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
}
template <typename ObjectContainer>
-inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
- QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv)
+inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
+ const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type,
+ QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags,
+ QQmlEnginePrivate *enginePriv)
{
*type = 0;
bool writable = false;
@@ -819,7 +815,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
lastAlias = targetAlias;
} while (lastAlias->aliasToLocalAlias);
- return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags, enginePriv);
+ return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv);
}
const int targetObjectIndex = objectForId(component, alias.targetObjectId);
@@ -837,12 +833,13 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
}
- if (typeRef->type.isValid())
- *type = typeRef->type.typeId();
+ const auto referencedType = typeRef->type();
+ if (referencedType.isValid())
+ *type = referencedType.typeId().id();
else
- *type = typeRef->compilationUnit()->metaTypeId;
+ *type = typeRef->compilationUnit()->metaTypeId.id();
- *minorVersion = typeRef->minorVersion;
+ *version = typeRef->version();
propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType;
} else {
@@ -921,9 +918,10 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo
Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
int type = 0;
- int minorVersion = 0;
+ QTypeRevision version = QTypeRevision::zero();
QQmlPropertyData::Flags propertyFlags;
- QQmlError error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv);
+ QQmlError error = propertyDataForAlias(component, *alias, &type, &version,
+ &propertyFlags, enginePriv);
if (error.isValid())
return error;
@@ -933,7 +931,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo
propertyCache->_defaultPropertyName = propertyName;
propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, minorVersion, effectiveSignalIndex++);
+ type, version, effectiveSignalIndex++);
}
return QQmlError();
diff --git a/src/qml/qml/qqmlpropertycachevector_p.h b/src/qml/qml/qqmlpropertycachevector_p.h
index 1dff7c61a6..2e09423206 100644
--- a/src/qml/qml/qqmlpropertycachevector_p.h
+++ b/src/qml/qml/qqmlpropertycachevector_p.h
@@ -54,16 +54,23 @@
#include <private/qflagpointer_p.h>
#include <private/qqmlpropertycache_p.h>
+#include <QtCore/qtaggedpointer.h>
+
QT_BEGIN_NAMESPACE
class QQmlPropertyCacheVector
{
public:
+ enum Tag {
+ NoTag,
+ CacheNeedsVMEMetaObject
+ };
+
QQmlPropertyCacheVector() {}
QQmlPropertyCacheVector(QQmlPropertyCacheVector &&other)
: data(std::move(other.data)) {}
QQmlPropertyCacheVector &operator=(QQmlPropertyCacheVector &&other) {
- QVector<QFlagPointer<QQmlPropertyCache>> moved(std::move(other.data));
+ QVector<QTaggedPointer<QQmlPropertyCache, Tag>> moved(std::move(other.data));
data.swap(moved);
return *this;
}
@@ -80,7 +87,7 @@ public:
data.clear();
}
- void append(QQmlPropertyCache *cache) { cache->addref(); data.append(cache); }
+ void append(QQmlPropertyCache *cache) { cache->addref(); data.append(QTaggedPointer<QQmlPropertyCache, Tag>(cache)); }
QQmlPropertyCache *at(int index) const { return data.at(index).data(); }
void set(int index, const QQmlRefPointer<QQmlPropertyCache> &replacement) {
if (QQmlPropertyCache *oldCache = data.at(index).data()) {
@@ -92,11 +99,11 @@ public:
replacement->addref();
}
- void setNeedsVMEMetaObject(int index) { data[index].setFlag(); }
- bool needsVMEMetaObject(int index) const { return data.at(index).flag(); }
+ void setNeedsVMEMetaObject(int index) { data[index].setTag(CacheNeedsVMEMetaObject); }
+ bool needsVMEMetaObject(int index) const { return data.at(index).tag() == CacheNeedsVMEMetaObject; }
private:
Q_DISABLE_COPY(QQmlPropertyCacheVector)
- QVector<QFlagPointer<QQmlPropertyCache>> data;
+ QVector<QTaggedPointer<QQmlPropertyCache, Tag>> data;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h
index 7f70c34854..517b865cbb 100644
--- a/src/qml/qml/qqmlpropertydata_p.h
+++ b/src/qml/qml/qqmlpropertydata_p.h
@@ -53,6 +53,7 @@
#include <private/qobject_p.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -96,7 +97,7 @@ public:
// b when type equals FunctionType. For that reason, the semantic meaning of the bit is
// overloaded, and the accessor functions are used to get the correct value
//
- // Moreover, isSignalHandler, isOverload and isCloned and isConstructor make only sense
+ // Moreover, isSignalHandler, isOverload and isCloned make only sense
// for functions, too (and could at a later point be reused for flags that only make sense
// for non-functions)
//
@@ -110,7 +111,7 @@ public:
unsigned isSignalHandler : 1; // Function is a signal handler
unsigned isOverload : 1; // Function is an overload of another function
unsigned isRequiredORisCloned : 1; // Has REQUIRED flag OR The function was marked as cloned
- unsigned isConstructor : 1; // The function was marked is a constructor
+ unsigned isConstructorORisQProperty : 1; // The function was marked is a constructor OR property is backed by QProperty<T>
unsigned isDirect : 1; // Exists on a C++ QMetaObject
unsigned isOverridden : 1; // Is overridden by a extension property
public:
@@ -155,6 +156,10 @@ public:
isOverridden = b;
}
+ void setIsQProperty(bool b) {
+ isConstructorORisQProperty = b;
+ }
+
void setIsDirect(bool b) {
isDirect = b;
}
@@ -203,7 +208,7 @@ public:
void setIsConstructor(bool b) {
Q_ASSERT(type == FunctionType);
- isConstructor = b;
+ isConstructorORisQProperty = b;
}
};
@@ -228,7 +233,7 @@ public:
bool isAlias() const { return !isFunction() && m_flags.isAliasORisVMESignal; }
bool isFinal() const { return !isFunction() && m_flags.isFinalORisV4Function; }
bool isOverridden() const { return m_flags.isOverridden; }
- bool isDirect() const { return m_flags.isOverload; }
+ bool isDirect() const { return m_flags.isDirect; }
bool isRequired() const { return !isFunction() && m_flags.isRequiredORisCloned; }
bool hasStaticMetaCallFunction() const { return staticMetaCallFunction() != nullptr; }
bool isFunction() const { return m_flags.type == Flags::FunctionType; }
@@ -248,10 +253,11 @@ public:
bool isOverload() const { return m_flags.isOverload; }
void setOverload(bool onoff) { m_flags.isOverload = onoff; }
bool isCloned() const { return isFunction() && m_flags.isRequiredORisCloned; }
- bool isConstructor() const { return m_flags.isConstructor; }
+ bool isConstructor() const { return m_flags.isConstructorORisQProperty; }
+ bool isQProperty() const { return m_flags.isConstructorORisQProperty; }
bool hasOverride() const { return overrideIndex() >= 0; }
- bool hasRevision() const { return revision() != 0; }
+ bool hasRevision() const { return revision() != QTypeRevision::zero(); }
bool isFullyResolved() const { return !m_flags.notFullyResolved; }
@@ -290,12 +296,8 @@ public:
m_coreIndex = qint16(idx);
}
- quint8 revision() const { return m_revision; }
- void setRevision(quint8 rev)
- {
- Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
- m_revision = quint8(rev);
- }
+ QTypeRevision revision() const { return m_revision; }
+ void setRevision(QTypeRevision revision) { m_revision = revision; }
/* If a property is a C++ type, then we store the minor
* version of this type.
@@ -315,12 +317,8 @@ public:
*
*/
- quint8 typeMinorVersion() const { return m_typeMinorVersion; }
- void setTypeMinorVersion(quint8 rev)
- {
- Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
- m_typeMinorVersion = quint8(rev);
- }
+ QTypeRevision typeVersion() const { return m_typeVersion; }
+ void setTypeVersion(QTypeRevision typeVersion) { m_typeVersion = typeVersion; }
QQmlPropertyCacheMethodArguments *arguments() const { return m_arguments; }
void setArguments(QQmlPropertyCacheMethodArguments *args) { m_arguments = args; }
@@ -412,22 +410,25 @@ private:
qint16 m_notifyIndex = -1;
qint16 m_overrideIndex = -1;
- quint8 m_revision = 0;
- quint8 m_typeMinorVersion = 0;
qint16 m_metaObjectOffset = -1;
+ quint16 m_reserved = 0;
+
+ QTypeRevision m_revision = QTypeRevision::zero();
+ QTypeRevision m_typeVersion = QTypeRevision::zero();
QQmlPropertyCacheMethodArguments *m_arguments = nullptr;
StaticMetaCallFunction m_staticMetaCallFunction = nullptr;
};
#if QT_POINTER_SIZE == 4
- Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 24);
+ Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 28);
#else // QT_POINTER_SIZE == 8
- Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 32);
+ Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 40);
#endif
bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const
{
+ Q_UNUSED(m_reserved)
return flags() == other.flags() &&
propType() == other.propType() &&
coreIndex() == other.coreIndex() &&
@@ -445,7 +446,8 @@ QQmlPropertyData::Flags::Flags()
, isSignalHandler(false)
, isOverload(false)
, isRequiredORisCloned(false)
- , isConstructor(false)
+ , isConstructorORisQProperty(false)
+ , isDirect(false)
, isOverridden(false)
, type(OtherType)
, notFullyResolved(false)
@@ -463,7 +465,7 @@ bool QQmlPropertyData::Flags::operator==(const QQmlPropertyData::Flags &other) c
isSignalHandler == other.isSignalHandler &&
isRequiredORisCloned == other.isRequiredORisCloned &&
type == other.type &&
- isConstructor == other.isConstructor &&
+ isConstructorORisQProperty == other.isConstructorORisQProperty &&
notFullyResolved == other.notFullyResolved &&
overrideIndexIsProperty == other.overrideIndexIsProperty;
}
diff --git a/src/qml/qml/qqmlpropertyresolver.cpp b/src/qml/qml/qqmlpropertyresolver.cpp
index 90eaca0b90..396f2876b9 100644
--- a/src/qml/qml/qqmlpropertyresolver.cpp
+++ b/src/qml/qml/qqmlpropertyresolver.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qqmlpropertyresolver_p.h"
+#include <private/qqmlcontextdata_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 3587609301..d7afffeaf9 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -117,8 +117,9 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject(
QQmlCustomParser *customParser = nullptr;
if (auto typeRef = resolvedType(obj->inheritedTypeNameIndex)) {
- if (typeRef->type.isValid())
- customParser = typeRef->type.customParser();
+ const auto type = typeRef->type();
+ if (type.isValid())
+ customParser = type.customParser();
}
QList<const QV4::CompiledData::Binding*> customBindings;
@@ -190,9 +191,16 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject(
if (notInRevision) {
QString typeName = stringAt(obj->inheritedTypeNameIndex);
- auto *objectType = resolvedType(obj->inheritedTypeNameIndex);
- if (objectType && objectType->type.isValid()) {
- return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type.module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
+ if (auto *objectType = resolvedType(obj->inheritedTypeNameIndex)) {
+ const auto type = objectType->type();
+ if (type.isValid()) {
+ const auto version = objectType->version();
+ return recordError(binding->location,
+ tr("\"%1.%2\" is not available in %3 %4.%5.")
+ .arg(typeName).arg(name).arg(type.module())
+ .arg(version.majorVersion())
+ .arg(version.minorVersion()));
+ }
} else {
return recordError(binding->location, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name));
}
@@ -212,7 +220,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject(
if (name.constData()->isUpper() && !binding->isAttachedProperty()) {
QQmlType type;
QQmlImportNamespace *typeNamespace = nullptr;
- imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, nullptr, &typeNamespace);
+ imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, &typeNamespace);
if (typeNamespace)
return recordError(binding->location, tr("Invalid use of namespace"));
return recordError(binding->location, tr("Invalid attached object assignment"));
@@ -588,7 +596,6 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope
}
}
break;
- case QMetaType::QRegExp:
case QMetaType::QRegularExpression:
return warnOrError(tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
default: {
@@ -744,8 +751,8 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert
// We want to use the raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
// effect the properties on the type, but don't effect assignability
- // Using -1 for the minor version ensures that we get the raw metaObject.
- QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType, -1);
+ // Not passing a version ensures that we get the raw metaObject.
+ QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType);
if (propertyMetaObject) {
// Will be true if the assigned type inherits propertyMetaObject
diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp
index dac21f7ee7..4ca506a926 100644
--- a/src/qml/qml/qqmlscriptblob.cpp
+++ b/src/qml/qml/qqmlscriptblob.cpp
@@ -42,6 +42,7 @@
#include <private/qqmlscriptblob_p.h>
#include <private/qqmlscriptdata_p.h>
#include <private/qqmlsourcecoordinate_p.h>
+#include <private/qqmlcontextdata_p.h>
#include <private/qv4runtimecodegen_p.h>
#include <private/qv4script_p.h>
@@ -149,10 +150,10 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
initializeFromCompilationUnit(executableUnit);
}
-void QQmlScriptBlob::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
+void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
{
initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create(
- QV4::CompiledData::CompilationUnit(unit, urlString(), finalUrlString())));
+ QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions, urlString(), finalUrlString())));
}
void QQmlScriptBlob::done()
diff --git a/src/qml/qml/qqmlscriptblob_p.h b/src/qml/qml/qqmlscriptblob_p.h
index 10c0437e7b..d8cdf5939d 100644
--- a/src/qml/qml/qqmlscriptblob_p.h
+++ b/src/qml/qml/qqmlscriptblob_p.h
@@ -78,7 +78,7 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
+ void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
void done() override;
QString stringAt(int index) const override;
diff --git a/src/qml/qml/qqmlscriptdata.cpp b/src/qml/qml/qqmlscriptdata.cpp
index ae268ca904..50ec0e20cd 100644
--- a/src/qml/qml/qqmlscriptdata.cpp
+++ b/src/qml/qml/qqmlscriptdata.cpp
@@ -55,78 +55,82 @@ QQmlScriptData::QQmlScriptData()
{
}
-QQmlContextData *QQmlScriptData::qmlContextDataForContext(QQmlContextData *parentQmlContextData)
+QQmlRefPointer<QQmlContextData> QQmlScriptData::qmlContextDataForContext(
+ const QQmlRefPointer<QQmlContextData> &parentQmlContextData)
{
- Q_ASSERT(parentQmlContextData && parentQmlContextData->engine);
+ Q_ASSERT(parentQmlContextData && parentQmlContextData->engine());
if (m_precompiledScript->isESModule())
return nullptr;
- auto qmlContextData = new QQmlContextData();
+ QQmlRefPointer<QQmlContextData> qmlContextData = m_precompiledScript->isSharedLibrary()
+ ? QQmlContextData::createRefCounted(QQmlRefPointer<QQmlContextData>())
+ : QQmlContextData::createRefCounted(parentQmlContextData);
- qmlContextData->isInternal = true;
- qmlContextData->isJSContext = true;
+ qmlContextData->setInternal(true);
+ qmlContextData->setJSContext(true);
if (m_precompiledScript->isSharedLibrary())
- qmlContextData->isPragmaLibraryContext = true;
+ qmlContextData->setPragmaLibraryContext(true);
else
- qmlContextData->isPragmaLibraryContext = parentQmlContextData->isPragmaLibraryContext;
- qmlContextData->baseUrl = url;
- qmlContextData->baseUrlString = urlString;
+ qmlContextData->setPragmaLibraryContext(parentQmlContextData->isPragmaLibraryContext());
+ qmlContextData->setBaseUrl(url);
+ qmlContextData->setBaseUrlString(urlString);
// For backward compatibility, if there are no imports, we need to use the
// imports from the parent context. See QTBUG-17518.
if (!typeNameCache->isEmpty()) {
- qmlContextData->imports = typeNameCache;
+ qmlContextData->setImports(typeNameCache);
} else if (!m_precompiledScript->isSharedLibrary()) {
- qmlContextData->imports = parentQmlContextData->imports;
- qmlContextData->importedScripts = parentQmlContextData->importedScripts;
+ qmlContextData->setImports(parentQmlContextData->imports());
+ qmlContextData->setImportedScripts(parentQmlContextData->importedScripts());
}
- if (!m_precompiledScript->isSharedLibrary()) {
- qmlContextData->setParent(parentQmlContextData);
- } else {
- qmlContextData->engine = parentQmlContextData->engine; // Fix for QTBUG-21620
- }
+ if (m_precompiledScript->isSharedLibrary())
+ qmlContextData->setEngine(parentQmlContextData->engine()); // Fix for QTBUG-21620
- QV4::ExecutionEngine *v4 = parentQmlContextData->engine->handle();
+ QV4::ExecutionEngine *v4 = parentQmlContextData->engine()->handle();
QV4::Scope scope(v4);
QV4::ScopedObject scriptsArray(scope);
- if (qmlContextData->importedScripts.isNullOrUndefined()) {
+ if (qmlContextData->importedScripts().isNullOrUndefined()) {
scriptsArray = v4->newArrayObject(scripts.count());
- qmlContextData->importedScripts.set(v4, scriptsArray);
+ qmlContextData->setImportedScripts(
+ QV4::PersistentValue(v4, scriptsArray.asReturnedValue()));
} else {
- scriptsArray = qmlContextData->importedScripts.valueRef();
+ scriptsArray = qmlContextData->importedScripts().valueRef();
}
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < scripts.count(); ++ii)
- scriptsArray->put(ii, (v = scripts.at(ii)->scriptData()->scriptValueForContext(qmlContextData)));
+ for (int ii = 0; ii < scripts.count(); ++ii) {
+ v = scripts.at(ii)->scriptData()->scriptValueForContext(qmlContextData.data());
+ scriptsArray->put(ii, v);
+ }
return qmlContextData;
}
-QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parentQmlContextData)
+QV4::ReturnedValue QQmlScriptData::scriptValueForContext(
+ const QQmlRefPointer<QQmlContextData> &parentQmlContextData)
{
if (m_loaded)
return m_value.value();
- Q_ASSERT(parentQmlContextData && parentQmlContextData->engine);
- QV4::ExecutionEngine *v4 = parentQmlContextData->engine->handle();
+ Q_ASSERT(parentQmlContextData && parentQmlContextData->engine());
+ QV4::ExecutionEngine *v4 = parentQmlContextData->engine()->handle();
QV4::Scope scope(v4);
if (!hasEngine()) {
- addToEngine(parentQmlContextData->engine);
+ addToEngine(parentQmlContextData->engine());
addref();
}
- QQmlContextDataRef qmlContextData = qmlContextDataForContext(parentQmlContextData);
QV4::Scoped<QV4::QmlContext> qmlExecutionContext(scope);
- if (qmlContextData)
- qmlExecutionContext =
- QV4::QmlContext::create(v4->rootContext(), qmlContextData, /* scopeObject: */ nullptr);
+ if (auto qmlContextData = qmlContextDataForContext(parentQmlContextData)) {
+ qmlExecutionContext = QV4::QmlContext::create(v4->rootContext(), std::move(qmlContextData),
+ /* scopeObject: */ nullptr);
+ }
QV4::Scoped<QV4::Module> module(scope, m_precompiledScript->instantiate(v4));
if (module) {
- if (qmlContextData) {
+ if (qmlExecutionContext) {
module->d()->scope->outer.set(v4, qmlExecutionContext->d());
qmlExecutionContext->d()->qml()->module.set(v4, module->d());
}
@@ -141,7 +145,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
}
QV4::ScopedValue value(scope);
- if (qmlContextData)
+ if (qmlExecutionContext)
value = qmlExecutionContext->d()->qml();
else if (module)
value = module->d();
diff --git a/src/qml/qml/qqmlscriptdata_p.h b/src/qml/qml/qqmlscriptdata_p.h
index 80b65b699c..abbafc33c2 100644
--- a/src/qml/qml/qqmlscriptdata_p.h
+++ b/src/qml/qml/qqmlscriptdata_p.h
@@ -85,7 +85,7 @@ public:
QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
QVector<QQmlRefPointer<QQmlScriptBlob>> scripts;
- QV4::ReturnedValue scriptValueForContext(QQmlContextData *parentCtxt);
+ QV4::ReturnedValue scriptValueForContext(const QQmlRefPointer<QQmlContextData> &parentCtxt);
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() const { return m_precompiledScript; }
@@ -96,7 +96,8 @@ private:
friend class QQmlScriptBlob;
void initialize(QQmlEngine *);
- QQmlContextData *qmlContextDataForContext(QQmlContextData *parentQmlContextData);
+ QQmlRefPointer<QQmlContextData> qmlContextDataForContext(
+ const QQmlRefPointer<QQmlContextData> &parentQmlContextData);
bool m_loaded;
QQmlRefPointer<QV4::ExecutableCompilationUnit> m_precompiledScript;
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 317d3c7ef5..0b21cc22ee 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -53,7 +53,7 @@
QT_BEGIN_NAMESPACE
QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
- : regType(type), iid(nullptr), typeId(0), listId(0), revision(0),
+ : regType(type), iid(nullptr), revision(QTypeRevision::zero()),
containsRevisionedAttributes(false), baseMetaObject(nullptr),
index(-1), isSetup(false), isEnumFromCacheSetup(false), isEnumFromBaseSetup(false),
haveSuperType(false)
@@ -132,34 +132,33 @@ QHashedString QQmlType::module() const
return d->module;
}
-int QQmlType::majorVersion() const
+QTypeRevision QQmlType::version() const
{
if (!d)
- return -1;
- return d->version_maj;
+ return QTypeRevision();
+ return d->version;
}
-int QQmlType::minorVersion() const
+bool QQmlType::availableInVersion(QTypeRevision version) const
{
if (!d)
- return -1;
- return d->version_min;
-}
+ return false;
-bool QQmlType::availableInVersion(int vmajor, int vminor) const
-{
- Q_ASSERT(vmajor >= 0 && vminor >= 0);
- if (!d)
+ if (!version.hasMajorVersion())
+ return true;
+
+ if (version.majorVersion() != d->version.majorVersion())
return false;
- return vmajor == d->version_maj && vminor >= d->version_min;
+
+ return !version.hasMinorVersion() || version.minorVersion() >= d->version.minorVersion();
}
-bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const
+bool QQmlType::availableInVersion(const QHashedStringRef &module, QTypeRevision version) const
{
- Q_ASSERT(vmajor >= 0 && vminor >= 0);
- if (!d)
+ if (!d || module != d->module)
return false;
- return module == d->module && vmajor == d->version_maj && vminor >= d->version_min;
+
+ return availableInVersion(version);
}
QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
@@ -592,14 +591,14 @@ bool QQmlType::isQJSValueSingleton() const
return d && d->regType == SingletonType && d->extraData.sd->singletonInstanceInfo->scriptCallback;
}
-int QQmlType::typeId() const
+QMetaType QQmlType::typeId() const
{
- return d ? d->typeId : -1;
+ return d ? d->typeId : QMetaType{};
}
-int QQmlType::qListTypeId() const
+QMetaType QQmlType::qListTypeId() const
{
- return d ? d->listId : -1;
+ return d ? d->listId : QMetaType{};
}
const QMetaObject *QQmlType::metaObject() const
@@ -629,9 +628,9 @@ bool QQmlType::containsRevisionedAttributes() const
return d->containsRevisionedAttributes;
}
-int QQmlType::metaObjectRevision() const
+QTypeRevision QQmlType::metaObjectRevision() const
{
- return d ? d->revision : -1;
+ return d ? d->revision : QTypeRevision();
}
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
@@ -699,7 +698,7 @@ bool QQmlType::isInlineComponentType() const {
return d ? d->regType == QQmlType::InlineComponentType : false;
}
-int QQmlType::inlineComponendId() const {
+int QQmlType::inlineComponentId() const {
bool ok = false;
if (d->regType == QQmlType::RegistrationType::InlineComponentType) {
Q_ASSERT(d->extraData.id->objectId != -1);
@@ -714,7 +713,7 @@ QUrl QQmlType::sourceUrl() const
auto url = d ? d->sourceUrl() : QUrl();
if (url.isValid() && d->regType == QQmlType::RegistrationType::InlineComponentType && d->extraData.id->objectId) {
Q_ASSERT(url.hasFragment());
- url.setFragment(QString::number(inlineComponendId()));
+ url.setFragment(QString::number(inlineComponentId()));
}
return url;
}
@@ -882,7 +881,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scope
return -1;
}
-int QQmlType::inlineComponentObjectId()
+int QQmlType::inlineComponentObjectId() const
{
if (!isInlineComponentType())
return -1;
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index 387baa74bb..eb3a773181 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -60,6 +60,7 @@
#include <QtQml/qjsvalue.h>
#include <QtCore/qobject.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -98,11 +99,10 @@ public:
QString elementName() const;
QHashedString module() const;
- int majorVersion() const;
- int minorVersion() const;
+ QTypeRevision version() const;
- bool availableInVersion(int vmajor, int vminor) const;
- bool availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const;
+ bool availableInVersion(QTypeRevision version) const;
+ bool availableInVersion(const QHashedStringRef &module, QTypeRevision version) const;
QObject *create() const;
void create(QObject **, void **, size_t) const;
@@ -124,12 +124,12 @@ public:
bool isQObjectSingleton() const;
bool isQJSValueSingleton() const;
- int typeId() const;
- int qListTypeId() const;
+ QMetaType typeId() const;
+ QMetaType qListTypeId() const;
const QMetaObject *metaObject() const;
const QMetaObject *baseMetaObject() const;
- int metaObjectRevision() const;
+ QTypeRevision metaObjectRevision() const;
bool containsRevisionedAttributes() const;
QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlEnginePrivate *engine) const;
@@ -146,7 +146,7 @@ public:
int index() const;
bool isInlineComponentType() const;
- int inlineComponendId() const;
+ int inlineComponentId() const;
struct Q_QML_PRIVATE_EXPORT SingletonInstanceInfo
{
@@ -170,7 +170,7 @@ public:
int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &, const QStringRef &, bool *ok) const;
- int inlineComponentObjectId();
+ int inlineComponentObjectId() const;
void setInlineComponentObjectId(int id) const; // TODO: const setters are BAD
const QQmlTypePrivate *priv() const { return d.data(); }
@@ -199,11 +199,11 @@ public:
private:
friend class QQmlTypePrivate;
- friend uint qHash(const QQmlType &t, uint seed);
+ friend size_t qHash(const QQmlType &t, uint seed);
QQmlRefPointer<const QQmlTypePrivate> d;
};
-inline uint qHash(const QQmlType &t, uint seed = 0)
+inline size_t qHash(const QQmlType &t, uint seed = 0)
{
return qHash(reinterpret_cast<quintptr>(t.d.data()), seed);
}
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index 43344827db..c94ac8c130 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -157,11 +157,10 @@ public:
QHashedString module;
QString name;
QString elementName;
- int version_maj;
- int version_min;
- int typeId;
- int listId;
- int revision;
+ QMetaType typeId;
+ QMetaType listId;
+ QTypeRevision version;
+ QTypeRevision revision;
mutable bool containsRevisionedAttributes;
mutable QQmlType superType;
const QMetaObject *baseMetaObject;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 058bf8848c..65b9213954 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -71,7 +71,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
for (auto it = resolvedTypes->constBegin(), end = resolvedTypes->constEnd();
it != end; ++it) {
- QQmlCustomParser *customParser = (*it)->type.customParser();
+ QQmlCustomParser *customParser = (*it)->type().customParser();
if (customParser)
customParsers.insert(it.key(), customParser);
}
@@ -264,7 +264,7 @@ QString QQmlTypeCompiler::bindingAsString(const QmlIR::Object *object, int scrip
return object->bindingAsString(document, scriptIndex);
}
-void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion)
+void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, QTypeRevision version)
{
const quint32 moduleIdx = registerString(module);
const quint32 qualifierIdx = registerString(qualifier);
@@ -279,8 +279,7 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier
auto pool = memoryPool();
QV4::CompiledData::Import *import = pool->New<QV4::CompiledData::Import>();
import->type = QV4::CompiledData::Import::ImportLibrary;
- import->majorVersion = majorVersion;
- import->minorVersion = minorVersion;
+ import->version = version;
import->uriIndex = moduleIdx;
import->qualifierIndex = qualifierIdx;
document->imports.append(import);
@@ -333,45 +332,55 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QHash<QString, QStringList> customSignals;
for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
- QString propertyName = stringAt(binding->propertyNameIndex);
+ const QString bindingPropertyName = stringAt(binding->propertyNameIndex);
// Attached property?
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex);
auto *typeRef = resolvedType(binding->propertyNameIndex);
- QQmlType type = typeRef ? typeRef->type : QQmlType();
+ QQmlType type = typeRef ? typeRef->type() : QQmlType();
if (!type.isValid())
- imports->resolveType(propertyName, &type, nullptr, nullptr, nullptr);
+ imports->resolveType(bindingPropertyName, &type, nullptr, nullptr, nullptr);
const QMetaObject *attachedType = type.attachedPropertiesType(enginePrivate);
if (!attachedType)
COMPILE_EXCEPTION(binding, tr("Non-existent attached object"));
QQmlPropertyCache *cache = compiler->enginePrivate()->cache(attachedType);
- if (!convertSignalHandlerExpressionsToFunctionDeclarations(attachedObj, propertyName, cache))
+ if (!convertSignalHandlerExpressionsToFunctionDeclarations(attachedObj, bindingPropertyName, cache))
return false;
continue;
}
- if (!QmlIR::IRBuilder::isSignalPropertyName(propertyName))
+ if (!QmlIR::IRBuilder::isSignalPropertyName(bindingPropertyName))
continue;
QQmlPropertyResolver resolver(propertyCache);
- Q_ASSERT(propertyName.startsWith(QLatin1String("on")));
- propertyName.remove(0, 2);
+ Q_ASSERT(bindingPropertyName.startsWith(QLatin1String("on")));
+ QString signalNameCandidate = bindingPropertyName;
+ signalNameCandidate.remove(0, 2);
// Note that the property name could start with any alpha or '_' or '$' character,
// so we need to do the lower-casing of the first alpha character.
- for (int firstAlphaIndex = 0; firstAlphaIndex < propertyName.size(); ++firstAlphaIndex) {
- if (propertyName.at(firstAlphaIndex).isUpper()) {
- propertyName[firstAlphaIndex] = propertyName.at(firstAlphaIndex).toLower();
+ for (int firstAlphaIndex = 0; firstAlphaIndex < signalNameCandidate.size(); ++firstAlphaIndex) {
+ if (signalNameCandidate.at(firstAlphaIndex).isUpper()) {
+ signalNameCandidate[firstAlphaIndex] = signalNameCandidate.at(firstAlphaIndex).toLower();
break;
}
}
+ QString qPropertyName;
+ if (signalNameCandidate.endsWith(QLatin1String("Changed")))
+ qPropertyName = signalNameCandidate.mid(0, signalNameCandidate.length() - static_cast<int>(strlen("Changed")));
+
QList<QString> parameters;
bool notInRevision = false;
- QQmlPropertyData *signal = resolver.signal(propertyName, &notInRevision);
+ QQmlPropertyData * const signal = resolver.signal(signalNameCandidate, &notInRevision);
+ QQmlPropertyData * const signalPropertyData = resolver.property(signalNameCandidate, /*notInRevision ptr*/nullptr);
+ QQmlPropertyData * const qPropertyData = !qPropertyName.isEmpty() ? resolver.property(qPropertyName) : nullptr;
+ QString finalSignalHandlerPropertyName = signalNameCandidate;
+ uint flags = QV4::CompiledData::Binding::IsSignalHandlerExpression;
+
if (signal) {
int sigIndex = propertyCache->methodIndexToSignalIndex(signal->coreIndex());
sigIndex = propertyCache->originalClone(sigIndex);
@@ -390,18 +399,24 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
}
parameters += param;
}
+ } else if (!signalPropertyData && qPropertyData && qPropertyData->isQProperty()) {
+ finalSignalHandlerPropertyName = qPropertyName;
+ flags = QV4::CompiledData::Binding::IsPropertyObserver;
} else {
if (notInRevision) {
// Try assinging it as a property later
- if (resolver.property(propertyName, /*notInRevision ptr*/nullptr))
+ if (signalPropertyData)
continue;
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
auto *typeRef = resolvedType(obj->inheritedTypeNameIndex);
- const QQmlType type = typeRef ? typeRef->type : QQmlType();
+ const QQmlType type = typeRef ? typeRef->type() : QQmlType();
if (type.isValid()) {
- COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type.module()).arg(type.majorVersion()).arg(type.minorVersion()));
+ COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.")
+ .arg(typeName).arg(originalPropertyName).arg(type.module())
+ .arg(type.version().majorVersion())
+ .arg(type.version().minorVersion()));
} else {
COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName));
}
@@ -422,11 +437,9 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
}
}
- QHash<QString, QStringList>::ConstIterator entry = customSignals.constFind(propertyName);
- if (entry == customSignals.constEnd() && propertyName.endsWith(QLatin1String("Changed"))) {
- QString alternateName = propertyName.mid(0, propertyName.length() - static_cast<int>(strlen("Changed")));
- entry = customSignals.constFind(alternateName);
- }
+ QHash<QString, QStringList>::ConstIterator entry = customSignals.constFind(signalNameCandidate);
+ if (entry == customSignals.constEnd() && !qPropertyName.isEmpty())
+ entry = customSignals.constFind(qPropertyName);
if (entry == customSignals.constEnd()) {
// Can't find even a custom signal, then just don't do anything and try
@@ -488,8 +501,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
functionDeclaration->rbraceToken = foe->node->lastSourceLocation();
}
foe->node = functionDeclaration;
- binding->propertyNameIndex = compiler->registerString(propertyName);
- binding->flags |= QV4::CompiledData::Binding::IsSignalHandlerExpression;
+ binding->propertyNameIndex = compiler->registerString(finalSignalHandlerPropertyName);
+ binding->flags |= flags;
}
return true;
}
@@ -514,7 +527,8 @@ bool QQmlEnumTypeResolver::resolveEnumBindings()
for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
- || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject
+ || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver)
continue;
if (binding->type != QV4::CompiledData::Binding::Type_Script)
@@ -537,12 +551,6 @@ bool QQmlEnumTypeResolver::resolveEnumBindings()
return true;
}
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, const QStringRef &enumName, int enumValue, bool isQtObject)
{
if (enumName.length() > 0 && enumName[0].isLower() && !isQtObject) {
@@ -611,7 +619,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
bool ok = false;
auto *tr = resolvedType(obj->inheritedTypeNameIndex);
- if (type.isValid() && tr && tr->type == type) {
+ if (type.isValid() && tr && tr->type() == type) {
// When these two match, we can short cut the search
QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex());
QMetaEnum menum = mprop.enumerator();
@@ -633,7 +641,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
} else {
QByteArray enumName = enumValue.toUtf8();
- const QMetaObject *metaObject = StaticQtMetaObject::get();
+ const QMetaObject *metaObject = &Qt::staticMetaObject;
for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
QMetaEnum e = metaObject->enumerator(ii);
value = e.keyToValue(enumName.constData(), &ok);
@@ -662,7 +670,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &e
return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
}
- const QMetaObject *mo = StaticQtMetaObject::get();
+ const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
const QByteArray ba = enumValue.toUtf8();
while (i--) {
@@ -811,8 +819,9 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
Q_ASSERT(tr);
const QMetaObject *firstMetaObject = nullptr;
- if (tr->type.isValid())
- firstMetaObject = tr->type.metaObject();
+ const auto type = tr->type();
+ if (type.isValid())
+ firstMetaObject = type.metaObject();
else if (const auto compilationUnit = tr->compilationUnit())
firstMetaObject = compilationUnit->rootPropertyCache()->firstCppMetaObject();
if (isUsableComponent(firstMetaObject))
@@ -829,7 +838,12 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!pd || !pd->isQObject())
continue;
- QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion());
+ // If the version is given, use it and look up by QQmlType.
+ // Otherwise, make sure we look up by metaobject.
+ // TODO: Is this correct?
+ QQmlPropertyCache *pc = pd->typeVersion().hasMinorVersion()
+ ? enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeVersion())
+ : enginePrivate->rawPropertyCacheForType(pd->propType());
const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr;
while (mo) {
if (mo == &QQmlComponent::staticMetaObject)
@@ -845,7 +859,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
Q_ASSERT(componentType.isValid());
const QString qualifier = QStringLiteral("QmlInternals");
- compiler->addImport(componentType.module(), qualifier, componentType.majorVersion(), componentType.minorVersion());
+ compiler->addImport(componentType.module(), qualifier, componentType.version());
QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>();
syntheticComponent->init(pool, compiler->registerString(qualifier + QLatin1Char('.') + componentType.elementName()), compiler->registerString(QString()));
@@ -854,9 +868,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!containsResolvedType(syntheticComponent->inheritedTypeNameIndex)) {
auto typeRef = new QV4::ResolvedTypeReference;
- typeRef->type = componentType;
- typeRef->majorVersion = componentType.majorVersion();
- typeRef->minorVersion = componentType.minorVersion();
+ typeRef->setType(componentType);
+ typeRef->setVersion(componentType.version());
insertResolvedType(syntheticComponent->inheritedTypeNameIndex, typeRef);
}
@@ -901,7 +914,7 @@ bool QQmlComponentAndAliasResolver::resolve()
if (obj->inheritedTypeNameIndex) {
auto *tref = resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(tref);
- if (tref->type.metaObject() == &QQmlComponent::staticMetaObject)
+ if (tref->type().metaObject() == &QQmlComponent::staticMetaObject)
isExplicitComponent = true;
}
if (!isExplicitComponent) {
@@ -1318,7 +1331,8 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex)
}
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
- || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject
+ || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver)
continue;
if (!pd) {
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index 057dd012c6..883fbf0d68 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -125,7 +125,7 @@ public:
QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const;
- void addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion);
+ void addImport(const QString &module, const QString &qualifier, QTypeRevision version);
QV4::ResolvedTypeReference *resolvedType(int id) const
{
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index fc1d0cfbcf..3b50027c4f 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -182,8 +182,8 @@ bool QQmlTypeData::tryLoadFromDiskCache()
const QV4::CompiledData::Import *import = m_compiledData->importAt(i);
if (m_compiledData->stringAt(import->uriIndex) == QLatin1String(".")
&& import->qualifierIndex == 0
- && import->majorVersion == -1
- && import->minorVersion == -1) {
+ && !import->version.hasMajorVersion()
+ && !import->version.hasMinorVersion()) {
QList<QQmlError> errors;
auto pendingImport = std::make_shared<PendingImport>(this, import);
if (!fetchQmldir(qmldirUrl, pendingImport, 1, &errors)) {
@@ -213,9 +213,9 @@ bool QQmlTypeData::tryLoadFromDiskCache()
QQmlType containingType;
auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first();
- int major = -1, minor = -1;
+ QTypeRevision version;
QQmlImportNamespace *ns = nullptr;
- m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns);
+ m_importCache.resolveType(containingTypeName, &containingType, &version, &ns);
for (auto&& ic: ics) {
QString const nameString = m_compiledData->stringAt(ic.nameIndex);
QByteArray const name = nameString.toUtf8();
@@ -601,14 +601,14 @@ void QQmlTypeData::dataReceived(const SourceCodeData &data)
continueLoadFromIR();
}
-void QQmlTypeData::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
+void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
{
m_document.reset(new QmlIR::Document(isDebugging()));
- QQmlIRLoader loader(unit, m_document.data());
+ QQmlIRLoader loader(unit->qmlData, m_document.data());
loader.load();
m_document->jsModule.fileName = urlString();
m_document->jsModule.finalUrl = finalUrlString();
- m_document->javaScriptCompilationUnit = QV4::CompiledData::CompilationUnit(unit);
+ m_document->javaScriptCompilationUnit = QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions);
continueLoadFromIR();
}
@@ -658,9 +658,9 @@ void QQmlTypeData::continueLoadFromIR()
{
QQmlType containingType;
auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first();
- int major = -1, minor = -1;
+ QTypeRevision version;
QQmlImportNamespace *ns = nullptr;
- m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns);
+ m_importCache.resolveType(containingTypeName, &containingType, &version, &ns);
for (auto const& object: m_document->objects) {
for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) {
QString const nameString = m_document->stringAt(it->nameIndex);
@@ -686,8 +686,7 @@ void QQmlTypeData::continueLoadFromIR()
// This qmldir is for the implicit import
auto implicitImport = std::make_shared<PendingImport>();
implicitImport->uri = QLatin1String(".");
- implicitImport->majorVersion = -1;
- implicitImport->minorVersion = -1;
+ implicitImport->version = QTypeRevision();
QList<QQmlError> errors;
if (!fetchQmldir(qmldirUrl, implicitImport, 1, &errors)) {
@@ -831,11 +830,8 @@ void QQmlTypeData::resolveTypes()
typeName = csRef.typeName;
}
- int majorVersion = csRef.majorVersion > -1 ? csRef.majorVersion : -1;
- int minorVersion = csRef.minorVersion > -1 ? csRef.minorVersion : -1;
-
- if (!resolveType(typeName, majorVersion, minorVersion, ref, -1, -1, true,
- QQmlType::CompositeSingletonType))
+ QTypeRevision version = csRef.version;
+ if (!resolveType(typeName, version, ref, -1, -1, true, QQmlType::CompositeSingletonType))
return;
if (ref.type.isCompositeSingleton()) {
@@ -859,14 +855,13 @@ void QQmlTypeData::resolveTypes()
const bool reportErrors = unresolvedRef->errorWhenNotFound;
- int majorVersion = -1;
- int minorVersion = -1;
+ QTypeRevision version;
const QString name = stringAt(unresolvedRef.key());
bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference;
- if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line,
+ if (!resolveType(name, version, ref, unresolvedRef->location.line,
unresolvedRef->location.column, reportErrors,
QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors)
return;
@@ -886,8 +881,7 @@ void QQmlTypeData::resolveTypes()
}
}
}
- ref.majorVersion = majorVersion;
- ref.minorVersion = minorVersion;
+ ref.version = version;
ref.location.line = unresolvedRef->location.line;
ref.location.column = unresolvedRef->location.column;
@@ -934,49 +928,47 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
objectId = qmlType.containingType().lookupInlineComponentIdByName(QString::fromUtf8(qmlType.typeName()));
qmlType.setInlineComponentObjectId(objectId);
} else {
- objectId = resolvedType->type.inlineComponendId();
+ objectId = resolvedType->type.inlineComponentId();
}
Q_ASSERT(objectId != -1);
- ref->typePropertyCache = resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId);
- ref->type = qmlType;
- Q_ASSERT(ref->type.isInlineComponentType());
+ ref->setTypePropertyCache(resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId));
+ ref->setType(qmlType);
+ Q_ASSERT(ref->type().isInlineComponentType());
}
} else if (resolvedType->type.isInlineComponentType()) {
// Inline component, defined in the file we are currently compiling
if (!m_inlineComponentToCompiledData.contains(resolvedType.key())) {
- ref->type = qmlType;
+ ref->setType(qmlType);
if (qmlType.isValid()) {
// this is required for inline components in singletons
- auto typeID = qmlType.lookupInlineComponentById(qmlType.inlineComponendId()).typeId();
+ auto type = qmlType.lookupInlineComponentById(qmlType.inlineComponentId()).typeId();
+ auto typeID = type.isValid() ? type.id() : -1;
auto exUnit = engine->obtainExecutableCompilationUnit(typeID);
if (exUnit) {
ref->setCompilationUnit(exUnit);
- ref->typePropertyCache = engine->propertyCacheForType(typeID);
+ ref->setTypePropertyCache(engine->propertyCacheForType(typeID));
}
}
} else {
ref->setCompilationUnit(m_inlineComponentToCompiledData[resolvedType.key()]);
- ref->typePropertyCache = m_inlineComponentToCompiledData[resolvedType.key()]->rootPropertyCache();
+ ref->setTypePropertyCache(m_inlineComponentToCompiledData[resolvedType.key()]->rootPropertyCache());
}
} else if (qmlType.isValid() && !resolvedType->selfReference) {
- ref->type = qmlType;
- Q_ASSERT(ref->type.isValid());
+ ref->setType(qmlType);
+ Q_ASSERT(ref->type().isValid());
- if (resolvedType->needsCreation && !ref->type.isCreatable()) {
- QString reason = ref->type.noCreationReason();
+ if (resolvedType->needsCreation && !qmlType.isCreatable()) {
+ QString reason = qmlType.noCreationReason();
if (reason.isEmpty())
reason = tr("Element is not creatable.");
return qQmlCompileError(resolvedType->location, reason);
}
- if (ref->type.containsRevisionedAttributes()) {
- ref->typePropertyCache = engine->cache(ref->type,
- resolvedType->minorVersion);
- }
+ if (qmlType.containsRevisionedAttributes())
+ ref->setTypePropertyCache(engine->cache(qmlType, resolvedType->version));
}
- ref->majorVersion = resolvedType->majorVersion;
- ref->minorVersion = resolvedType->minorVersion;
+ ref->setVersion(resolvedType->version);
ref->doDynamicTypeCheck();
resolvedTypeCache->insert(resolvedType.key(), ref.take());
}
@@ -984,7 +976,7 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
return noError;
}
-bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion,
+bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version,
TypeReference &ref, int lineNumber, int columnNumber,
bool reportErrors, QQmlType::RegistrationType registrationType,
bool *typeRecursionDetected)
@@ -992,7 +984,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
- bool typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion,
+ bool typeFound = m_importCache.resolveType(typeName, &ref.type, &version,
&typeNamespace, &errors, registrationType,
typeRecursionDetected);
if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
@@ -1000,7 +992,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
if (loadImplicitImport()) {
// Try again to find the type
errors.clear();
- typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion,
+ typeFound = m_importCache.resolveType(typeName, &ref.type, &version,
&typeNamespace, &errors, registrationType,
typeRecursionDetected);
} else {
diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h
index 906a0ee171..2c56ede9bd 100644
--- a/src/qml/qml/qqmltypedata_p.h
+++ b/src/qml/qml/qqmltypedata_p.h
@@ -62,12 +62,11 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob
public:
struct TypeReference
{
- TypeReference() : majorVersion(0), minorVersion(0), needsCreation(true) {}
+ TypeReference() : version(QTypeRevision::zero()), needsCreation(true) {}
QV4::CompiledData::Location location;
QQmlType type;
- int majorVersion;
- int minorVersion;
+ QTypeRevision version;
QQmlRefPointer<QQmlTypeData> typeData;
bool selfReference = false;
QString prefix; // used by CompositeSingleton types
@@ -113,7 +112,7 @@ protected:
void done() override;
void completed() override;
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
+ void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
void allDependenciesDone() override;
void downloadProgressChanged(qreal) override;
@@ -134,7 +133,7 @@ private:
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::ResolvedTypeReferenceMap &resolvedTypeCache);
- bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion,
+ bool resolveType(const QString &typeName, QTypeRevision &version,
TypeReference &ref, int lineNumber = -1, int columnNumber = -1,
bool reportErrors = true,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 1d66e756fa..49b3d7ad93 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -174,8 +174,8 @@ struct StaticLoader {
};
struct CachedLoader {
- const QV4::CompiledData::Unit *unit;
- CachedLoader(const QV4::CompiledData::Unit *unit) : unit(unit) {}
+ const QQmlPrivate::CachedQmlUnit *unit;
+ CachedLoader(const QQmlPrivate::CachedQmlUnit *unit) : unit(unit) {}
void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
{
@@ -247,7 +247,7 @@ void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da
doLoad(StaticLoader(data), blob, mode);
}
-void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode)
+void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode)
{
doLoad(CachedLoader(unit), blob, mode);
}
@@ -259,7 +259,7 @@ void QQmlTypeLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArr
setData(blob, data);
}
-void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
+void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
{
ASSERT_LOADTHREAD();
@@ -457,7 +457,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
blob->tryDone();
}
-void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
+void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
{
Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
@@ -488,8 +488,7 @@ QQmlTypeLoader::Blob::PendingImport::PendingImport(QQmlTypeLoader::Blob *blob, c
type = static_cast<QV4::CompiledData::Import::ImportType>(quint32(import->type));
uri = blob->stringAt(import->uriIndex);
qualifier = blob->stringAt(import->qualifierIndex);
- majorVersion = import->majorVersion;
- minorVersion = import->minorVersion;
+ version = import->version;
location = import->location;
}
@@ -579,12 +578,13 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
QString qmldirUrl;
const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir(
- importDatabase, import->uri, import->majorVersion, import->minorVersion,
+ importDatabase, import->uri, import->version,
&qmldirFilePath, &qmldirUrl);
if (qmldirResult == QQmlImports::QmldirFound) {
// This is a local library import
- if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
+ if (!m_importCache.addLibraryImport(
+ importDatabase, import->uri, import->qualifier,
+ import->version, qmldirFilePath, qmldirUrl, false, errors))
return false;
if (!loadImportDependencies(import, qmldirFilePath, errors))
@@ -606,44 +606,48 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
} else if (
// Major version of module already registered:
// We believe that the registration is complete.
- QQmlMetaType::typeModule(import->uri, import->majorVersion)
+ QQmlMetaType::typeModule(import->uri, import->version)
// Otherwise, try to register further module types.
|| (qmldirResult != QQmlImports::QmldirInterceptedToRemote
- && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->majorVersion))
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri))
// Otherwise, there is no way to register any further types.
// Try with any module of that name.
|| QQmlMetaType::isAnyModule(import->uri)) {
if (!m_importCache.addLibraryImport(
- importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), false, errors)) {
+ importDatabase, import->uri, import->qualifier, import->version,
+ QString(), QString(), false, errors)) {
return false;
}
} else {
// We haven't yet resolved this import
m_unresolvedImports << import;
- QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
+ const QQmlEngine *engine = typeLoader()->engine();
+ const bool hasInterceptors
+ = !(QQmlEnginePrivate::get(engine)->urlInterceptors.isEmpty());
// Query any network import paths for this library.
// Interceptor might redirect local paths.
QStringList remotePathList = importDatabase->importPathList(
- interceptor ? QQmlImportDatabase::LocalOrRemote
- : QQmlImportDatabase::Remote);
+ hasInterceptors ? QQmlImportDatabase::LocalOrRemote
+ : QQmlImportDatabase::Remote);
if (!remotePathList.isEmpty()) {
// Add this library and request the possible locations for it
- if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), true, errors))
+ if (!m_importCache.addLibraryImport(
+ importDatabase, import->uri, import->qualifier, import->version,
+ QString(), QString(), true, errors))
return false;
// Probe for all possible locations
int priority = 0;
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion);
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
+ import->uri, remotePathList, import->version);
for (const QString &qmldirPath : qmlDirPaths) {
- if (interceptor) {
- QUrl url = interceptor->intercept(
+ if (hasInterceptors) {
+ QUrl url = engine->interceptUrl(
QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
QQmlAbstractUrlInterceptor::QmldirFile);
if (!QQmlFile::isLocalFile(url)
@@ -672,8 +676,8 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
incomplete = true;
}
- if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, incomplete, errors))
+ if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier,
+ import->version, incomplete, errors))
return false;
if (incomplete) {
@@ -712,8 +716,7 @@ bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport
auto dependencyImport = std::make_shared<PendingImport>();
dependencyImport->uri = implicitImports;
dependencyImport->qualifier = currentImport->qualifier;
- dependencyImport->majorVersion = currentImport->majorVersion;
- dependencyImport->minorVersion = currentImport->minorVersion;
+ dependencyImport->version = currentImport->version;
if (!addImport(dependencyImport, errors))
return false;
}
@@ -818,7 +821,7 @@ QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &unNormalizedUrl
// TODO: if (compiledData == 0), is it safe to omit this insertion?
m_typeCache.insert(url, typeData);
QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
- if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url(), &error)) {
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url(), &error)) {
QQmlTypeLoader::loadWithCachedUnit(typeData, cachedUnit, mode);
} else {
typeData->setCachedUnitStatus(error);
@@ -877,7 +880,7 @@ QQmlRefPointer<QQmlScriptBlob> QQmlTypeLoader::getScript(const QUrl &unNormalize
m_scriptCache.insert(url, scriptBlob);
QQmlMetaType::CachedUnitLookupError error;
- if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url(), &error)) {
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url(), &error)) {
QQmlTypeLoader::loadWithCachedUnit(scriptBlob, cachedUnit);
} else {
scriptBlob->setCachedUnitStatus(error);
@@ -1186,8 +1189,8 @@ void QQmlTypeLoader::updateTypeCacheTrimThreshold()
void QQmlTypeLoader::trimCache()
{
while (true) {
- QList<TypeCache::Iterator> unneededTypes;
- for (TypeCache::Iterator iter = m_typeCache.begin(), end = m_typeCache.end(); iter != end; ++iter) {
+ bool deletedOneType = false;
+ for (TypeCache::Iterator iter = m_typeCache.begin(), end = m_typeCache.end(); iter != end;) {
QQmlTypeData *typeData = iter.value();
// typeData->m_compiledData may be set early on in the proccess of loading a file, so
@@ -1196,19 +1199,16 @@ void QQmlTypeLoader::trimCache()
if (typeData->count() == 1 && (typeData->isError() || typeData->isComplete())
&& (!typeData->m_compiledData || typeData->m_compiledData->count() == 1)) {
// There are no live objects of this type
- unneededTypes.append(iter);
+ iter.value()->release();
+ iter = m_typeCache.erase(iter);
+ deletedOneType = true;
+ } else {
+ ++iter;
}
}
- if (unneededTypes.isEmpty())
+ if (!deletedOneType)
break;
-
- while (!unneededTypes.isEmpty()) {
- TypeCache::Iterator iter = unneededTypes.takeLast();
-
- iter.value()->release();
- m_typeCache.erase(iter);
- }
}
updateTypeCacheTrimThreshold();
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index adecf61896..094360a51b 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -97,8 +97,7 @@ public:
QString uri;
QString qualifier;
- int majorVersion = -1;
- int minorVersion = -1;
+ QTypeRevision version;
QV4::CompiledData::Location location;
@@ -168,7 +167,7 @@ public:
void load(QQmlDataBlob *, Mode = PreferSynchronous);
void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
- void loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode = PreferSynchronous);
+ void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous);
QQmlEngine *engine() const;
void initializeEngine(QQmlEngineExtensionInterface *, const char *);
@@ -195,7 +194,7 @@ private:
void loadThread(QQmlDataBlob *);
void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
#if QT_CONFIG(qml_network)
void networkReplyFinished(QNetworkReply *);
void networkReplyProgress(QNetworkReply *, qint64, qint64);
@@ -206,7 +205,7 @@ private:
void setData(QQmlDataBlob *, const QByteArray &);
void setData(QQmlDataBlob *, const QString &fileName);
void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &);
- void setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
+ void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
template<typename T>
struct TypedCallback
diff --git a/src/qml/qml/qqmltypeloaderthread.cpp b/src/qml/qml/qqmltypeloaderthread.cpp
index 618bb09039..bb7a6aacb2 100644
--- a/src/qml/qml/qqmltypeloaderthread.cpp
+++ b/src/qml/qml/qqmltypeloaderthread.cpp
@@ -101,13 +101,13 @@ void QQmlTypeLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteA
postMethodToThread(&This::loadWithStaticDataThread, b, d);
}
-void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
{
b->addref();
callMethodInThread(&This::loadWithCachedUnitThread, b, unit);
}
-void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
{
b->addref();
postMethodToThread(&This::loadWithCachedUnitThread, b, unit);
@@ -169,7 +169,7 @@ void QQmlTypeLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByte
b->release();
}
-void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
{
m_loader->loadWithCachedUnitThread(b, unit);
b->release();
diff --git a/src/qml/qml/qqmltypeloaderthread_p.h b/src/qml/qml/qqmltypeloaderthread_p.h
index 9fb441e6e2..045d838528 100644
--- a/src/qml/qml/qqmltypeloaderthread_p.h
+++ b/src/qml/qml/qqmltypeloaderthread_p.h
@@ -82,8 +82,8 @@ public:
void loadAsync(QQmlDataBlob *b);
void loadWithStaticData(QQmlDataBlob *b, const QByteArray &);
void loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
- void loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
+ void loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
void callCompleted(QQmlDataBlob *b);
void callDownloadProgressChanged(QQmlDataBlob *b, qreal p);
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -95,7 +95,7 @@ protected:
private:
void loadThread(QQmlDataBlob *b);
void loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
void callCompletedMain(QQmlDataBlob *b);
void callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p);
void initializeExtensionMain(QQmlExtensionInterface *iface, const char *uri);
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 9d6f269030..e6bf796d74 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE
-QQmlTypeModule::QQmlTypeModule(const QString &module, int majorVersion)
+QQmlTypeModule::QQmlTypeModule(const QString &module, quint8 majorVersion)
: d(new QQmlTypeModulePrivate(module, majorVersion))
{
}
@@ -61,23 +61,23 @@ QString QQmlTypeModule::module() const
return d->module;
}
-int QQmlTypeModule::majorVersion() const
+quint8 QQmlTypeModule::majorVersion() const
{
// No need to lock. d->majorVersion is const
return d->majorVersion;
}
-int QQmlTypeModule::minimumMinorVersion() const
+quint8 QQmlTypeModule::minimumMinorVersion() const
{
return d->minMinorVersion.loadRelaxed();
}
-int QQmlTypeModule::maximumMinorVersion() const
+quint8 QQmlTypeModule::maximumMinorVersion() const
{
return d->maxMinorVersion.loadRelaxed();
}
-void QQmlTypeModule::addMinorVersion(int version)
+void QQmlTypeModule::addMinorVersion(quint8 version)
{
for (int oldVersion = d->minMinorVersion.loadRelaxed();
oldVersion > version && !d->minMinorVersion.testAndSetOrdered(oldVersion, version);
@@ -93,16 +93,16 @@ void QQmlTypeModule::addMinorVersion(int version)
void QQmlTypeModule::add(QQmlTypePrivate *type)
{
QMutexLocker lock(&d->mutex);
- addMinorVersion(type->version_min);
+ addMinorVersion(type->version.minorVersion());
QList<QQmlTypePrivate *> &list = d->typeHash[type->elementName];
for (int ii = 0; ii < list.count(); ++ii) {
QQmlTypePrivate *in_list = list.at(ii);
Q_ASSERT(in_list);
- if (in_list->version_min < type->version_min) {
+ if (in_list->version.minorVersion() < type->version.minorVersion()) {
list.insert(ii, type);
return;
- } else if (in_list->version_min == type->version_min) {
+ } else if (in_list->version.minorVersion() == type->version.minorVersion()) {
list[ii] = type;
return;
}
@@ -137,26 +137,26 @@ void QQmlTypeModule::lock()
d->locked.storeRelaxed(1);
}
-QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const
+QQmlType QQmlTypeModule::type(const QHashedStringRef &name, QTypeRevision version) const
{
QMutexLocker lock(&d->mutex);
QList<QQmlTypePrivate *> *types = d->typeHash.value(name);
if (types) {
for (int ii = 0; ii < types->count(); ++ii)
- if (types->at(ii)->version_min <= minor)
+ if (types->at(ii)->version.minorVersion() <= version.minorVersion())
return QQmlType(types->at(ii));
}
return QQmlType();
}
-QQmlType QQmlTypeModule::type(const QV4::String *name, int minor) const
+QQmlType QQmlTypeModule::type(const QV4::String *name, QTypeRevision version) const
{
QMutexLocker lock(&d->mutex);
QList<QQmlTypePrivate *> *types = d->typeHash.value(name);
if (types) {
for (int ii = 0; ii < types->count(); ++ii)
- if (types->at(ii)->version_min <= minor)
+ if (types->at(ii)->version.minorVersion() <= version.minorVersion())
return QQmlType(types->at(ii));
}
diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h
index b84a91b5db..d3149567a3 100644
--- a/src/qml/qml/qqmltypemodule_p.h
+++ b/src/qml/qml/qqmltypemodule_p.h
@@ -53,6 +53,7 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qstring.h>
+#include <QtCore/qversionnumber.h>
#include <functional>
@@ -72,7 +73,7 @@ class QQmlTypeModulePrivate;
class QQmlTypeModule
{
public:
- QQmlTypeModule(const QString &uri = QString(), int majorVersion = 0);
+ QQmlTypeModule(const QString &uri = QString(), quint8 majorVersion = 0);
~QQmlTypeModule();
void add(QQmlTypePrivate *);
@@ -82,14 +83,14 @@ public:
void lock();
QString module() const;
- int majorVersion() const;
+ quint8 majorVersion() const;
- void addMinorVersion(int minorVersion);
- int minimumMinorVersion() const;
- int maximumMinorVersion() const;
+ void addMinorVersion(quint8 minorVersion);
+ quint8 minimumMinorVersion() const;
+ quint8 maximumMinorVersion() const;
- QQmlType type(const QHashedStringRef &, int) const;
- QQmlType type(const QV4::String *, int) const;
+ QQmlType type(const QHashedStringRef &, QTypeRevision version) const;
+ QQmlType type(const QV4::String *, QTypeRevision version) const;
void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const;
diff --git a/src/qml/qml/qqmltypemodule_p_p.h b/src/qml/qml/qqmltypemodule_p_p.h
index b1dab1c4a0..5d4d2e458a 100644
--- a/src/qml/qml/qqmltypemodule_p_p.h
+++ b/src/qml/qml/qqmltypemodule_p_p.h
@@ -62,15 +62,15 @@ QT_BEGIN_NAMESPACE
class QQmlTypeModulePrivate
{
public:
- QQmlTypeModulePrivate(QString module, int majorVersion) :
+ QQmlTypeModulePrivate(QString module, quint8 majorVersion) :
module(std::move(module)), majorVersion(majorVersion)
{}
const QString module;
- const int majorVersion = 0;
+ const quint8 majorVersion = 0;
// Can only ever decrease
- QAtomicInt minMinorVersion = std::numeric_limits<int>::max();
+ QAtomicInt minMinorVersion = std::numeric_limits<quint8>::max();
// Can only ever increase
QAtomicInt maxMinorVersion = 0;
diff --git a/src/qml/qml/qqmltypemoduleversion.cpp b/src/qml/qml/qqmltypemoduleversion.cpp
index bbbfa1a7b6..932ff7f503 100644
--- a/src/qml/qml/qqmltypemoduleversion.cpp
+++ b/src/qml/qml/qqmltypemoduleversion.cpp
@@ -39,9 +39,6 @@
#include "qqmltypemoduleversion_p.h"
-#include <private/qqmltype_p.h>
-#include <private/qqmltypemodule_p.h>
-
QT_BEGIN_NAMESPACE
QQmlTypeModuleVersion::QQmlTypeModuleVersion()
@@ -49,11 +46,10 @@ QQmlTypeModuleVersion::QQmlTypeModuleVersion()
{
}
-QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, int minor)
- : m_module(module), m_minor(minor)
+QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, QTypeRevision version)
+ : m_module(module), m_minor(version.minorVersion())
{
Q_ASSERT(m_module);
- Q_ASSERT(m_minor >= 0);
}
QQmlTypeModuleVersion::QQmlTypeModuleVersion(const QQmlTypeModuleVersion &o)
@@ -68,28 +64,4 @@ QQmlTypeModuleVersion &QQmlTypeModuleVersion::operator=(const QQmlTypeModuleVers
return *this;
}
-QQmlTypeModule *QQmlTypeModuleVersion::module() const
-{
- return m_module;
-}
-
-int QQmlTypeModuleVersion::minorVersion() const
-{
- return m_minor;
-}
-
-QQmlType QQmlTypeModuleVersion::type(const QHashedStringRef &name) const
-{
- if (!m_module)
- return QQmlType();
- return m_module->type(name, m_minor);
-}
-
-QQmlType QQmlTypeModuleVersion::type(const QV4::String *name) const
-{
- if (!m_module)
- return QQmlType();
- return m_module->type(name, m_minor);
-}
-
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypemoduleversion_p.h b/src/qml/qml/qqmltypemoduleversion_p.h
index 20f4709ecb..c5379b2158 100644
--- a/src/qml/qml/qqmltypemoduleversion_p.h
+++ b/src/qml/qml/qqmltypemoduleversion_p.h
@@ -52,6 +52,9 @@
//
#include <QtQml/qtqmlglobal.h>
+#include <QtQml/private/qqmltype_p.h>
+#include <QtQml/private/qqmltypemodule_p.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -67,19 +70,23 @@ class QQmlTypeModuleVersion
{
public:
QQmlTypeModuleVersion();
- QQmlTypeModuleVersion(QQmlTypeModule *, int);
+ QQmlTypeModuleVersion(QQmlTypeModule *, QTypeRevision);
QQmlTypeModuleVersion(const QQmlTypeModuleVersion &);
QQmlTypeModuleVersion &operator=(const QQmlTypeModuleVersion &);
- QQmlTypeModule *module() const;
- int minorVersion() const;
-
- QQmlType type(const QHashedStringRef &) const;
- QQmlType type(const QV4::String *) const;
+ template<typename String>
+ QQmlType type(String name) const
+ {
+ if (!m_module)
+ return QQmlType();
+ return m_module->type(name, QTypeRevision::isValidSegment(m_minor)
+ ? QTypeRevision::fromMinorVersion(m_minor)
+ : QTypeRevision());
+ }
private:
QQmlTypeModule *m_module;
- int m_minor;
+ quint8 m_minor;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index 1015403226..45333668e3 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -101,7 +101,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(name, &t, nullptr, nullptr, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(name, &t, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
@@ -129,7 +129,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
@@ -155,7 +155,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml
QList<QQmlError> errors;
QQmlType t;
bool typeRecursionDetected = false;
- bool typeFound = m_imports.resolveType(typeName, &t, nullptr, nullptr, &typeNamespace, &errors,
+ bool typeFound = m_imports.resolveType(typeName, &t, nullptr, &typeNamespace, &errors,
QQmlType::AnyRegistrationType,
recursionRestriction == QQmlImport::AllowRecursion ? &typeRecursionDetected : nullptr);
if (typeFound) {
@@ -191,7 +191,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h
index d8427f2961..dbd37ace2a 100644
--- a/src/qml/qml/qqmltypenotavailable_p.h
+++ b/src/qml/qml/qqmltypenotavailable_p.h
@@ -58,8 +58,8 @@ QT_BEGIN_NAMESPACE
class QQmlTypeNotAvailable : public QObject {
Q_OBJECT
QML_NAMED_ELEMENT(TypeNotAvailable)
+ QML_ADDED_IN_VERSION(2, 15)
QML_UNCREATABLE("Type not available.")
- QML_ADDED_IN_MINOR_VERSION(15)
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index fa5d36503d..da76659ef4 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -183,7 +183,7 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons
if (hasProperty)
*hasProperty = true;
- QQmlContextData *context = v4->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = v4->callingQmlContext();
QObject *object = w->d()->object;
QQmlType type = w->d()->type();
@@ -233,7 +233,7 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons
QJSValue scriptSingleton = e->singletonInstance<QJSValue>(type);
if (!scriptSingleton.isUndefined()) {
// NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
- QV4::ScopedObject o(scope, QJSValuePrivate::convertedToValue(v4, scriptSingleton));
+ QV4::ScopedObject o(scope, QJSValuePrivate::asReturnedValue(&scriptSingleton));
if (!!o)
return o->get(name);
}
@@ -283,10 +283,10 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons
if (r.type.isValid()) {
return create(scope.engine, object, r.type, w->d()->mode);
} else if (r.scriptIndex != -1) {
- QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
+ QV4::ScopedObject scripts(scope, context->importedScripts().valueRef());
return scripts->get(r.scriptIndex);
} else if (r.importNamespace) {
- return create(scope.engine, object, context->imports, r.importNamespace);
+ return create(scope.engine, object, context->imports(), r.importNamespace);
}
return QV4::Encode::undefined();
@@ -329,7 +329,7 @@ bool QQmlTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value,
return false;
ScopedString name(scope, id.asStringOrSymbol());
- QQmlContextData *context = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
QQmlType type = w->d()->type();
if (type.isValid() && !type.isSingleton() && w->d()->object) {
@@ -349,7 +349,7 @@ bool QQmlTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value,
} else {
QJSValue scriptSingleton = e->singletonInstance<QJSValue>(type);
if (!scriptSingleton.isUndefined()) {
- QV4::ScopedObject apiprivate(scope, QJSValuePrivate::convertedToValue(scope.engine, scriptSingleton));
+ QV4::ScopedObject apiprivate(scope, QJSValuePrivate::asReturnedValue(&scriptSingleton));
if (!apiprivate) {
QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"');
scope.engine->throwError(error);
@@ -407,9 +407,9 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
if (!wrapperObject)
return engine->throwTypeError();
- const int myTypeId = typeWrapper->d()->type().typeId();
+ const QMetaType myTypeId = typeWrapper->d()->type().typeId();
QQmlMetaObject myQmlType;
- if (myTypeId == 0) {
+ if (!myTypeId.isValid()) {
// we're a composite type; a composite type cannot be equal to a
// non-composite object instance (Rectangle{} is never an instance of
// CustomRectangle)
@@ -420,9 +420,9 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
ExecutableCompilationUnit *cu = td->compilationUnit();
- myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+ myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId.id());
} else {
- myQmlType = qenginepriv->metaObjectForType(myTypeId);
+ myQmlType = qenginepriv->metaObjectForType(myTypeId.id());
}
const QMetaObject *theirType = wrapperObject->metaObject();
@@ -440,7 +440,7 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
const QQmlTypeWrapper *This = static_cast<const QQmlTypeWrapper *>(object);
ScopedString name(scope, id.asStringOrSymbol());
- QQmlContextData *qmlContext = engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> qmlContext = engine->callingQmlContext();
Scoped<QQmlTypeWrapper> w(scope, static_cast<const QQmlTypeWrapper *>(This));
QQmlType type = w->d()->type();
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index a86564a49a..254f1015e2 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -132,8 +132,10 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
return &QQmlRectValueType::staticMetaObject;
case QMetaType::QRectF:
return &QQmlRectFValueType::staticMetaObject;
+#if QT_CONFIG(easingcurve)
case QMetaType::QEasingCurve:
return &QQmlEasingValueType::staticMetaObject;
+#endif
#if QT_CONFIG(qml_itemmodel)
case QMetaType::QModelIndex:
return &QQmlModelIndexValueType::staticMetaObject;
@@ -214,7 +216,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)
@@ -527,6 +531,7 @@ int QQmlRectValueType::bottom() const
return v.bottom();
}
+#if QT_CONFIG(easingcurve)
QQmlEasingValueType::Type QQmlEasingValueType::type() const
{
return (QQmlEasingValueType::Type)v.type();
@@ -620,6 +625,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 29fa999725..056baf87d0 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -60,7 +60,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
@@ -131,6 +133,10 @@ struct QQmlPointFValueType
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_GADGET
+ QML_VALUE_TYPE(point)
+ QML_FOREIGN(QPointF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -145,6 +151,10 @@ struct QQmlPointValueType
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QPoint)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int x() const;
int y() const;
@@ -158,6 +168,10 @@ struct QQmlSizeFValueType
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
Q_GADGET
+ QML_VALUE_TYPE(size)
+ QML_FOREIGN(QSizeF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal width() const;
@@ -172,6 +186,10 @@ struct QQmlSizeValueType
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QSize)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int width() const;
int height() const;
@@ -191,6 +209,10 @@ struct QQmlRectFValueType
Q_PROPERTY(qreal top READ top DESIGNABLE false FINAL)
Q_PROPERTY(qreal bottom READ bottom DESIGNABLE false FINAL)
Q_GADGET
+ QML_VALUE_TYPE(rect)
+ QML_FOREIGN(QRectF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -221,6 +243,10 @@ struct QQmlRectValueType
Q_PROPERTY(int top READ top DESIGNABLE false FINAL)
Q_PROPERTY(int bottom READ bottom DESIGNABLE false FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QRect)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int x() const;
int y() const;
@@ -238,11 +264,13 @@ public:
int bottom() const;
};
+#if QT_CONFIG(easingcurve)
struct QQmlEasingValueType
{
QEasingCurve v;
Q_GADGET
QML_NAMED_ELEMENT(Easing)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Use the Type enum.")
Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL)
@@ -290,6 +318,7 @@ public:
void setBezierCurve(const QVariantList &);
QVariantList bezierCurve() const;
};
+#endif
struct QQmlPropertyValueType
{
@@ -297,6 +326,10 @@ struct QQmlPropertyValueType
Q_PROPERTY(QObject *object READ object CONSTANT FINAL)
Q_PROPERTY(QString name READ name CONSTANT FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QQmlProperty)
+ QML_ADDED_IN_VERSION(2, 15)
+
public:
QObject *object() const;
QString name() const;
@@ -305,18 +338,14 @@ public:
template<typename T>
int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
- QByteArray name(T::staticMetaObject.className());
-
- QByteArray pointerName(name + '*');
-
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, 0, nullptr,
+ QMetaType::fromType<T*>(), QMetaType(), 0, nullptr,
QString(),
- uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject,
nullptr, nullptr,
@@ -325,7 +354,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino
nullptr, nullptr,
nullptr,
- 0
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 110288faf7..d10fad191c 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -569,7 +569,7 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v
return false;
}
- QQmlContextData *context = v4->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = v4->callingQmlContext();
QQmlPropertyData cacheData;
cacheData.setWritable(true);
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 018769948d..38e9fad2b6 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -138,7 +138,7 @@ bool QQmlVMEGuard::isOK() const
return false;
for (int ii = 0; ii < m_contextCount; ++ii)
- if (m_contexts[ii].isNull() || !m_contexts[ii]->engine)
+ if (m_contexts[ii].isNull() || !m_contexts[ii]->engine())
return false;
return true;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 05a78a17fe..784df5d7ef 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -87,7 +87,7 @@ namespace QQmlVMETypes {
State() : flags(0), context(nullptr), instructionStream(nullptr) {}
quint32 flags;
- QQmlContextData *context;
+ QQmlRefPointer<QQmlContextData> context;
const char *instructionStream;
QBitField bindingSkipList;
};
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index aa9f4bc1bd..856dda1663 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -204,7 +204,12 @@ public:
QQmlVMEMetaObjectEndpoint();
void tryConnect();
- QFlagPointer<QQmlVMEMetaObject> metaObject;
+ enum Tag {
+ NoTag,
+ EndPointIsConnected
+ };
+
+ QTaggedPointer<QQmlVMEMetaObject, Tag> metaObject;
};
QQmlVMEMetaObjectEndpoint::QQmlVMEMetaObjectEndpoint()
@@ -223,15 +228,15 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
Q_ASSERT(metaObject->compiledObject);
int aliasId = this - metaObject->aliasEndpoints;
- if (metaObject.flag()) {
+ if (metaObject.tag() == EndPointIsConnected) {
// This is actually notify
int sigIdx = metaObject->methodOffset() + aliasId + metaObject->compiledObject->nProperties;
metaObject->activate(metaObject->object, sigIdx, nullptr);
} else {
const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId];
if (!aliasData->isObjectAlias()) {
- QQmlContextData *ctxt = metaObject->ctxt;
- QObject *target = ctxt->idValues[aliasData->targetObjectId].data();
+ QQmlRefPointer<QQmlContextData> ctxt = metaObject->ctxt;
+ QObject *target = ctxt->idValue(aliasData->targetObjectId);
if (!target)
return;
@@ -255,10 +260,10 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
return;
if (pd->notifyIndex() != -1)
- connect(target, pd->notifyIndex(), ctxt->engine);
+ connect(target, pd->notifyIndex(), ctxt->engine());
}
- metaObject.setFlag();
+ metaObject.setTag(EndPointIsConnected);
}
}
@@ -321,7 +326,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
if (type != QMetaType::UnknownType) {
if (valueIndex != -1) {
QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
- data->context->engine, type);
+ data->context->engine(), type);
Q_ASSERT(valueType);
//
@@ -694,7 +699,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
const QV4::CompiledData::BuiltinType t = property.builtinType();
// the context can be null if accessing var properties from cpp after re-parenting an item.
- QQmlEnginePrivate *ep = (ctxt == nullptr || ctxt->engine == nullptr) ? nullptr : QQmlEnginePrivate::get(ctxt->engine);
+ QQmlEnginePrivate *ep = (ctxt.isNull() || ctxt->engine() == nullptr)
+ ? nullptr
+ : QQmlEnginePrivate::get(ctxt->engine());
const int fallbackMetaType = QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(t);
@@ -891,15 +898,13 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if ((aliasData->flags & QV4::CompiledData::Alias::AliasPointsToPointerObject) && c == QMetaObject::ReadProperty)
*reinterpret_cast<void **>(a[0]) = nullptr;
- if (!ctxt) return -1;
+ if (ctxt.isNull())
+ return -1;
while (aliasData->aliasToLocalAlias)
aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
- QQmlContext *context = ctxt->asQQmlContext();
- QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(context);
-
- QObject *target = ctxtPriv->data->idValues[aliasData->targetObjectId].data();
+ QObject *target = ctxt->idValue(aliasData->targetObjectId);
if (!target)
return -1;
@@ -934,7 +939,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
// Value type property or deep alias
QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
- ctxt->engine, pd->propType());
+ ctxt->engine(), pd->propType());
if (valueType) {
valueType->read(target, coreIndex);
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
@@ -973,7 +978,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
id -= plainSignals;
if (id < methodCount) {
- QQmlEngine *engine = ctxt->engine;
+ QQmlEngine *engine = ctxt->engine();
if (!engine)
return -1; // We can't run the method
@@ -1050,7 +1055,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
QV4::ReturnedValue QQmlVMEMetaObject::method(int index) const
{
- if (!ctxt || !ctxt->isValid() || !compiledObject) {
+ if (ctxt.isNull() || !ctxt->isValid() || !compiledObject) {
qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context");
return QV4::Encode::undefined();
}
@@ -1255,14 +1260,14 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex,
*coreIndex = -1;
*valueTypeIndex = -1;
- if (!ctxt)
+ if (ctxt.isNull())
return false;
const int aliasId = index - propOffset() - compiledObject->nProperties;
const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId];
while (aliasData->aliasToLocalAlias)
aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
- *target = ctxt->idValues[aliasData->targetObjectId].data();
+ *target = ctxt->idValue(aliasData->targetObjectId);
if (!*target)
return false;
@@ -1290,7 +1295,7 @@ void QQmlVMEMetaObject::connectAlias(int aliasId)
}
endpoint->metaObject = this;
- endpoint->connect(&ctxt->idValues[aliasData->targetObjectId].bindings);
+ endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId));
endpoint->tryConnect();
}
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index e17701a968..10fa0d89a2 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -64,8 +64,8 @@
#include <private/qobject_p.h>
#include "qqmlguard_p.h"
-#include "qqmlcontext_p.h"
+#include <private/qqmlguardedcontextdata_p.h>
#include <private/qflagpointer_p.h>
#include <private/qv4object_p.h>
@@ -144,7 +144,10 @@ class QQmlVMEMetaObjectEndpoint;
class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject
{
public:
- QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &qmlCompilationUnit, int qmlObjectId);
+ QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj,
+ const QQmlRefPointer<QQmlPropertyCache> &cache,
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &qmlCompilationUnit,
+ int qmlObjectId);
~QQmlVMEMetaObject() override;
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 86e6282e53..416aca8667 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1020,7 +1020,8 @@ public:
QString replyStatusText() const;
ReturnedValue open(Object *thisObject, const QString &, const QUrl &, LoadType);
- ReturnedValue send(Object *thisObject, QQmlContextData *context, const QByteArray &);
+ ReturnedValue send(Object *thisObject, const QQmlRefPointer<QQmlContextData> &context,
+ const QByteArray &);
ReturnedValue abort(Object *thisObject);
void addHeader(const QString &, const QString &);
@@ -1068,7 +1069,7 @@ private:
void readEncoding();
PersistentValue m_thisObject;
- QQmlContextDataRef m_qmlContext;
+ QQmlRefPointer<QQmlContextData> m_qmlContext;
bool m_wasConstructedWithQmlContext = true;
void dispatchCallbackNow(Object *thisObj);
@@ -1095,7 +1096,7 @@ QQmlXMLHttpRequest::QQmlXMLHttpRequest(QNetworkAccessManager *manager, QV4::Exec
, m_responseType()
, m_parsedDocument()
{
- m_wasConstructedWithQmlContext = v4->callingQmlContext() != nullptr;
+ m_wasConstructedWithQmlContext = !v4->callingQmlContext().isNull();
}
QQmlXMLHttpRequest::~QQmlXMLHttpRequest()
@@ -1203,25 +1204,15 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
if (m_method == QLatin1String("PUT"))
{
if (!xhrFileWrite()) {
- if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_WRITE")) {
- qWarning("XMLHttpRequest: Tried to use PUT on a local file despite being disabled.");
- return;
- } else {
- qWarning("XMLHttpRequest: Using PUT on a local file is dangerous "
- "and will be disabled by default in a future Qt version."
- "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature.");
- }
+ qWarning("XMLHttpRequest: Using PUT on a local file is disabled by default.\n"
+ "Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature.");
+ return;
}
} else if (m_method == QLatin1String("GET")) {
if (!xhrFileRead()) {
- if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_READ")) {
- qWarning("XMLHttpRequest: Tried to use GET on a local file despite being disabled.");
- return;
- } else {
- qWarning("XMLHttpRequest: Using GET on a local file is dangerous "
- "and will be disabled by default in a future Qt version."
- "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature.");
- }
+ qWarning("XMLHttpRequest: Using GET on a local file is disabled by default.\n"
+ "Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.");
+ return;
}
} else {
qWarning("XMLHttpRequest: Unsupported method used on a local file");
@@ -1307,7 +1298,8 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
}
}
-ReturnedValue QQmlXMLHttpRequest::send(Object *thisObject, QQmlContextData *context, const QByteArray &data)
+ReturnedValue QQmlXMLHttpRequest::send(
+ Object *thisObject, const QQmlRefPointer<QQmlContextData> &context, const QByteArray &data)
{
m_errorFlag = false;
m_sendFlag = true;
@@ -1472,7 +1464,7 @@ void QQmlXMLHttpRequest::finished()
dispatchCallbackSafely();
m_thisObject.clear();
- m_qmlContext.setContextData(nullptr);
+ m_qmlContext = nullptr;
}
@@ -1625,12 +1617,13 @@ void QQmlXMLHttpRequest::dispatchCallbackNow(Object *thisObj, bool done, bool er
void QQmlXMLHttpRequest::dispatchCallbackSafely()
{
- if (m_wasConstructedWithQmlContext && !m_qmlContext.contextData())
+ if (m_wasConstructedWithQmlContext && m_qmlContext.isNull()) {
// if the calling context object is no longer valid, then it has been
// deleted explicitly (e.g., by a Loader deleting the itemContext when
// the source is changed). We do nothing in this case, as the evaluation
// cannot succeed.
return;
+ }
dispatchCallbackNow(m_thisObject.as<Object>());
}
@@ -1801,8 +1794,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(const FunctionObject *b, const
QUrl url = QUrl(argv[1].toQStringNoThrow());
if (url.isRelative()) {
- QQmlContextData *qmlContextData = scope.engine->callingQmlContext();
- if (qmlContextData)
+ if (QQmlRefPointer<QQmlContextData> qmlContextData = scope.engine->callingQmlContext())
url = qmlContextData->resolvedUrl(url);
else
url = scope.engine->resolvedUrl(url.url());
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 02628a9810..1123949cfa 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -93,12 +93,6 @@ DEFINE_OBJECT_VTABLE(QtObject);
return scope.engine->throwTypeError(QString::fromUtf8(msg)); \
} while (false)
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
void Heap::QtObject::init(QQmlEngine *qmlEngine)
{
Heap::Object::init();
@@ -116,6 +110,7 @@ void Heap::QtObject::init(QQmlEngine *qmlEngine)
o->defineDefaultProperty(QStringLiteral("include"), QV4Include::method_include);
o->defineDefaultProperty(QStringLiteral("isQtObject"), QV4::QtObject::method_isQtObject);
+ o->defineDefaultProperty(QStringLiteral("color"), QV4::QtObject::method_color);
o->defineDefaultProperty(QStringLiteral("rgba"), QV4::QtObject::method_rgba);
o->defineDefaultProperty(QStringLiteral("hsla"), QV4::QtObject::method_hsla);
o->defineDefaultProperty(QStringLiteral("hsva"), QV4::QtObject::method_hsva);
@@ -147,6 +142,7 @@ void Heap::QtObject::init(QQmlEngine *qmlEngine)
o->defineDefaultProperty(QStringLiteral("binding"), QV4::QtObject::method_binding);
if (qmlEngine) {
+ o->defineDefaultProperty(QStringLiteral("alpha"), QV4::QtObject::method_alpha);
o->defineDefaultProperty(QStringLiteral("lighter"), QV4::QtObject::method_lighter);
o->defineDefaultProperty(QStringLiteral("darker"), QV4::QtObject::method_darker);
o->defineDefaultProperty(QStringLiteral("tint"), QV4::QtObject::method_tint);
@@ -177,7 +173,7 @@ ReturnedValue QtObject::findAndAdd(const QString *name, bool &foundProperty) con
ScopedString key(scope);
ScopedValue value(scope);
- const QMetaObject *qtMetaObject = StaticQtMetaObject::get();
+ const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
for (int enumCount = qtMetaObject->enumeratorCount(); d()->enumeratorIterator < enumCount;
++d()->enumeratorIterator) {
QMetaEnum enumerator = qtMetaObject->enumerator(d()->enumeratorIterator);
@@ -243,6 +239,33 @@ ReturnedValue QtObject::method_isQtObject(const FunctionObject *, const Value *,
}
/*!
+ \qmlmethod color Qt::color(string name)
+
+ Returns the color corresponding to the given \a name (i.e. red or #ff0000).
+ If there is no such color, \c null is returned.
+*/
+ReturnedValue QtObject::method_color(const FunctionObject *f, const Value *, const Value *argv,
+ int argc)
+{
+ QV4::Scope scope(f);
+ if (argc != 1)
+ THROW_GENERIC_ERROR("Qt.color(): Qt.color takes exactly one argument");
+
+ QVariant v = scope.engine->toVariant(argv[0], -1);
+ if (v.userType() == QMetaType::QString) {
+ bool ok = false;
+ v = QQmlStringConverters::colorFromString(v.toString(), &ok);
+ if (!ok) {
+ return QV4::Encode::null();
+ }
+ } else {
+ THROW_GENERIC_ERROR("Qt.color(): Argument must be a string");
+ }
+
+ return scope.engine->fromVariant(v);
+}
+
+/*!
\qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
Returns a color with the specified \a red, \a green, \a blue, and \a alpha
@@ -670,6 +693,35 @@ ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, co
}
/*!
+ \qmlmethod color Qt::alpha(color baseColor, real value)
+
+ Returns \a baseColor with an alpha value of \a value.
+
+ \a value is a real ranging from 0 (completely transparent) to 1 (completely opaque).
+*/
+ReturnedValue QtObject::method_alpha(const FunctionObject *b, const Value *, const Value *argv,
+ int argc)
+{
+ QV4::Scope scope(b);
+ if (argc != 2)
+ THROW_GENERIC_ERROR("Qt.alpha(): Wrong number of arguments provided");
+
+ QVariant v = scope.engine->toVariant(argv[0], -1);
+ if (v.userType() == QMetaType::QString) {
+ bool ok = false;
+ v = QQmlStringConverters::colorFromString(v.toString(), &ok);
+ if (!ok)
+ return QV4::Encode::null();
+ } else if (v.userType() != QMetaType::QColor) {
+ return QV4::Encode::null();
+ }
+
+ qreal value = argv[1].toNumber();
+
+ return scope.engine->fromVariant(QQml_colorProvider()->alpha(v, value));
+}
+
+/*!
\qmlmethod color Qt::tint(color baseColor, color tintColor)
This function allows tinting one color (\a baseColor) with another (\a tintColor).
@@ -737,23 +789,10 @@ QString formatDateTimeObjectUsingDateFormat(T formatThis, Qt::DateFormat format)
case Qt::RFC2822Date:
case Qt::ISODateWithMs:
return formatThis.toString(format);
- // ### Qt 6: Remove all locale dependent cases
- QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
- case Qt::SystemLocaleDate:
- // case Qt::LocalDate: covered by SystemLocaleDate
- return QLocale::system().toString(formatThis);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toString(formatThis, QLocale::ShortFormat);
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(formatThis, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(formatThis, QLocale::LongFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toString(formatThis, QLocale::LongFormat);
+ default: // ### Qt 6: remove once qtbase has removed the rest of the enum !
+ break;
}
- QT_WARNING_POP
- Q_UNREACHABLE();
+ // Q_UNREACHABLE(); // ### Qt 6: restore once the default is gone
return QString();
}
@@ -1007,8 +1046,7 @@ ReturnedValue QtObject::method_resolvedUrl(const FunctionObject *b, const Value
QQmlEnginePrivate *p = nullptr;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
- QQmlContextData *ctxt = scope.engine->callingQmlContext();
- if (ctxt)
+ if (QQmlRefPointer<QQmlContextData> ctxt = scope.engine->callingQmlContext())
return Encode(scope.engine->newString(ctxt->resolvedUrl(url).toString()));
else
return Encode(scope.engine->newString(url.toString()));
@@ -1175,7 +1213,7 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
QQmlEngine *engine = scope.engine->qmlEngine();
- QQmlContextData *context = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
if (!context) {
QQmlEngine *qmlEngine = scope.engine->qmlEngine();
if (qmlEngine)
@@ -1183,7 +1221,7 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
}
Q_ASSERT(context);
QQmlContext *effectiveContext = nullptr;
- if (context->isPragmaLibraryContext)
+ if (context->isPragmaLibraryContext())
effectiveContext = engine->rootContext();
else
effectiveContext = context->asQQmlContext();
@@ -1307,16 +1345,15 @@ ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Va
QQmlEngine *engine = scope.engine->qmlEngine();
- QQmlContextData *context = scope.engine->callingQmlContext();
+ QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
if (!context) {
QQmlEngine *qmlEngine = scope.engine->qmlEngine();
if (qmlEngine)
context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
}
Q_ASSERT(context);
- QQmlContextData *effectiveContext = context;
- if (context->isPragmaLibraryContext)
- effectiveContext = nullptr;
+ QQmlRefPointer<QQmlContextData> effectiveContext
+ = context->isPragmaLibraryContext() ? nullptr : context;
QString arg = argv[0].toQStringNoThrow();
if (arg.isEmpty())
@@ -2063,7 +2100,7 @@ ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value
}
if (context.isEmpty()) {
- if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) {
+ if (QQmlRefPointer<QQmlContextData> ctxt = scope.engine->callingQmlContext()) {
QString path = ctxt->urlString();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
int lastDot = path.lastIndexOf(QLatin1Char('.'));
@@ -2251,4 +2288,3 @@ ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *t
}
QT_END_NAMESPACE
-
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index 5cbb52471d..8c64e5b1d8 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -97,6 +97,8 @@ struct QtObject : Object
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static ReturnedValue method_isQtObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_color(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc);
static ReturnedValue method_rgba(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_hsla(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_hsva(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
@@ -112,6 +114,8 @@ struct QtObject : Object
static ReturnedValue method_matrix4x4(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_lighter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_darker(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_alpha(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc);
static ReturnedValue method_tint(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_formatDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_formatTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp
index 152e840318..cb16d2e57a 100644
--- a/src/qml/qmldirparser/qqmldirparser.cpp
+++ b/src/qml/qmldirparser/qqmldirparser.cpp
@@ -60,17 +60,17 @@ static int parseInt(const QStringRef &str, bool *ok)
return number;
}
-static bool parseVersion(const QString &str, int *major, int *minor)
+static QTypeRevision parseVersion(const QString &str)
{
const int dotIndex = str.indexOf(QLatin1Char('.'));
if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) {
bool ok = false;
- *major = parseInt(QStringRef(&str, 0, dotIndex), &ok);
- if (ok)
- *minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok);
- return ok;
+ const int major = parseInt(QStringRef(&str, 0, dotIndex), &ok);
+ if (!ok) return QTypeRevision();
+ const int minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok);
+ return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision();
}
- return false;
+ return QTypeRevision();
}
void QQmlDirParser::clear()
@@ -203,7 +203,7 @@ bool QQmlDirParser::parse(const QString &source)
QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
- Component entry(sections[1], sections[2], -1, -1);
+ Component entry(sections[1], sections[2], QTypeRevision());
entry.internal = true;
_components.insert(entry.typeName, entry);
} else if (sections[0] == QLatin1String("singleton")) {
@@ -214,16 +214,16 @@ bool QQmlDirParser::parse(const QString &source)
} else if (sectionCount == 3) {
// handle qmldir directory listing case where singleton is defined in the following pattern:
// singleton TestSingletonType TestSingletonType.qml
- Component entry(sections[1], sections[2], -1, -1);
+ Component entry(sections[1], sections[2], QTypeRevision());
entry.singleton = true;
_components.insert(entry.typeName, entry);
} else {
// handle qmldir module listing case where singleton is defined in the following pattern:
// singleton TestSingletonType 2.0 TestSingletonType20.qml
- int major, minor;
- if (parseVersion(sections[2], &major, &minor)) {
+ const QTypeRevision version = parseVersion(sections[2]);
+ if (version.isValid()) {
const QString &fileName = sections[3];
- Component entry(sections[1], fileName, major, minor);
+ Component entry(sections[1], fileName, version);
entry.singleton = true;
_components.insert(entry.typeName, entry);
} else {
@@ -236,11 +236,8 @@ bool QQmlDirParser::parse(const QString &source)
QStringLiteral("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1));
continue;
}
-#ifdef QT_CREATOR
TypeInfo typeInfo(sections[1]);
_typeInfos.append(typeInfo);
-#endif
-
} else if (sections[0] == QLatin1String("designersupported")) {
if (sectionCount != 1)
reportError(lineNumber, 0, QStringLiteral("designersupported does not expect any argument"));
@@ -253,9 +250,9 @@ bool QQmlDirParser::parse(const QString &source)
continue;
}
- int major, minor;
- if (parseVersion(sections[2], &major, &minor)) {
- Component entry(sections[1], QString(), major, minor);
+ const QTypeRevision version = parseVersion(sections[2]);
+ if (version.isValid()) {
+ Component entry(sections[1], QString(), version);
entry.internal = true;
_dependencies.insert(entry.typeName, entry);
} else {
@@ -270,19 +267,19 @@ bool QQmlDirParser::parse(const QString &source)
_imports << sections[1];
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
- const Component entry(sections[0], sections[1], -1, -1);
+ const Component entry(sections[0], sections[1], QTypeRevision());
_components.insert(entry.typeName, entry);
} else if (sectionCount == 3) {
- int major, minor;
- if (parseVersion(sections[1], &major, &minor)) {
+ const QTypeRevision version = parseVersion(sections[1]);
+ if (version.isValid()) {
const QString &fileName = sections[2];
if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) {
// A 'js' extension indicates a namespaced script import
- const Script entry(sections[0], fileName, major, minor);
+ const Script entry(sections[0], fileName, version);
_scripts.append(entry);
} else {
- const Component entry(sections[0], fileName, major, minor);
+ const Component entry(sections[0], fileName, version);
_components.insert(entry.typeName, entry);
}
} else {
@@ -387,15 +384,17 @@ QString QQmlDirParser::className() const
QDebug &operator<< (QDebug &debug, const QQmlDirParser::Component &component)
{
- const QString output = QStringLiteral("{%1 %2.%3}").
- arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion);
+ const QString output = QStringLiteral("{%1 %2.%3}")
+ .arg(component.typeName).arg(component.version.majorVersion())
+ .arg(component.version.minorVersion());
return debug << qPrintable(output);
}
QDebug &operator<< (QDebug &debug, const QQmlDirParser::Script &script)
{
- const QString output = QStringLiteral("{%1 %2.%3}").
- arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion);
+ const QString output = QStringLiteral("{%1 %2.%3}")
+ .arg(script.nameSpace).arg(script.version.majorVersion())
+ .arg(script.version.minorVersion());
return debug << qPrintable(output);
}
diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h
index 3696a1aa12..ccdac8f484 100644
--- a/src/qml/qmldirparser/qqmldirparser_p.h
+++ b/src/qml/qmldirparser/qqmldirparser_p.h
@@ -54,6 +54,7 @@
#include <QtCore/QUrl>
#include <QtCore/QHash>
#include <QtCore/QDebug>
+#include <QtCore/QTypeRevision>
#include <private/qtqmlcompilerglobal_p.h>
#include <private/qqmljsengine_p.h>
#include <private/qqmljsdiagnosticmessage_p.h>
@@ -101,8 +102,8 @@ public:
{
Component() = default;
- Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
- : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
+ Component(const QString &typeName, const QString &fileName, QTypeRevision version)
+ : typeName(typeName), fileName(fileName), version(version),
internal(false), singleton(false)
{
checkNonRelative("Component", typeName, fileName);
@@ -110,8 +111,7 @@ public:
QString typeName;
QString fileName;
- int majorVersion = 0;
- int minorVersion = 0;
+ QTypeRevision version = QTypeRevision::zero();
bool internal = false;
bool singleton = false;
};
@@ -120,16 +120,15 @@ public:
{
Script() = default;
- Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
- : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion)
+ Script(const QString &nameSpace, const QString &fileName, QTypeRevision version)
+ : nameSpace(nameSpace), fileName(fileName), version(version)
{
checkNonRelative("Script", nameSpace, fileName);
}
QString nameSpace;
QString fileName;
- int majorVersion = 0;
- int minorVersion = 0;
+ QTypeRevision version = QTypeRevision::zero();
};
QMultiHash<QString,Component> components() const;
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 6d6553259e..6d762401d0 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -73,8 +73,7 @@ public:
, delayed(false)
, pendingEval(false)
, restoreBinding(true)
- , restoreValue(false)
- , restoreModeExplicit(false)
+ , restoreValue(true)
, writingProperty(false)
{}
~QQmlBindPrivate() { }
@@ -93,7 +92,6 @@ public:
bool pendingEval:1;
bool restoreBinding:1;
bool restoreValue:1;
- bool restoreModeExplicit:1;
bool writingProperty: 1;
void validate(QObject *binding) const;
@@ -196,13 +194,8 @@ QQmlBind::~QQmlBind()
}
\endcode
- When the binding becomes inactive again, any direct bindings that were previously
- set on the property will be restored.
-
- \note By default, a previously set literal value is not restored when the Binding becomes
- inactive. Rather, the last value set by the now inactive Binding is retained. You can customize
- the restoration behavior for literal values as well as bindings using the \l restoreMode
- property. The default will change in Qt 6.0.
+ By default, any binding or value that was set perviously is restored when the binding becomes
+ inactive. You can customize the restoration behavior using the \l restoreMode property.
\sa restoreMode
*/
@@ -371,8 +364,7 @@ void QQmlBind::setDelayed(bool delayed)
\li Binding.RestoreBindingOrValue The original value is always restored.
\endlist
- \warning The default value is Binding.RestoreBinding. This will change in
- Qt 6.0 to Binding.RestoreBindingOrValue.
+ The default value is \c Binding.RestoreBindingOrValue.
If you rely on any specific behavior regarding the restoration of plain
values when bindings get disabled you should migrate to explicitly set the
@@ -395,7 +387,6 @@ QQmlBind::RestorationMode QQmlBind::restoreMode() const
void QQmlBind::setRestoreMode(RestorationMode newMode)
{
Q_D(QQmlBind);
- d->restoreModeExplicit = true;
if (newMode != restoreMode()) {
d->restoreValue = (newMode & RestoreValue);
d->restoreBinding = (newMode & RestoreBinding);
@@ -482,27 +473,11 @@ void QQmlBind::eval()
Q_ASSERT(vmemo);
vmemo->setVMEProperty(propPriv->core.coreIndex(), *d->v4Value.valueRef());
d->clearPrev();
- } else if (!d->restoreModeExplicit) {
- qmlWarning(this)
- << "Not restoring previous value because restoreMode has not been set.\n"
- << "This behavior is deprecated.\n"
- << "You have to import QtQml 2.15 after any QtQuick imports and set\n"
- << "the restoreMode of the binding to fix this warning.\n"
- << "In Qt < 6.0 the default is Binding.RestoreBinding.\n"
- << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.";
}
} else if (d->prevIsVariant) {
if (d->restoreValue) {
d->prop.write(d->prevValue);
d->clearPrev();
- } else if (!d->restoreModeExplicit) {
- qmlWarning(this)
- << "Not restoring previous value because restoreMode has not been set.\n"
- << "This behavior is deprecated.\n"
- << "You have to import QtQml 2.15 after any QtQuick imports and set\n"
- << "the restoreMode of the binding to fix this warning.\n"
- << "In Qt < 6.0 the default is Binding.RestoreBinding.\n"
- << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.\n";
}
}
return;
diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h
index c709224c23..052af0d167 100644
--- a/src/qml/types/qqmlbind_p.h
+++ b/src/qml/types/qqmlbind_p.h
@@ -77,11 +77,12 @@ private:
Q_PROPERTY(QString property READ property WRITE setProperty)
Q_PROPERTY(QJSValue value READ value WRITE setValue)
Q_PROPERTY(bool when READ when WRITE setWhen)
- Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION 8)
+ Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION(2, 8))
Q_PROPERTY(RestorationMode restoreMode READ restoreMode WRITE setRestoreMode
- NOTIFY restoreModeChanged REVISION 14)
+ NOTIFY restoreModeChanged REVISION(2, 14))
Q_ENUM(RestorationMode)
QML_NAMED_ELEMENT(Binding)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlBind(QObject *parent=nullptr);
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 29ed62cd39..c913e2d11a 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -297,9 +297,9 @@ void QQmlConnections::connectSignalsToMethods()
if (!ddata)
return;
- QV4::ExecutionEngine *engine = ddata->context->engine->handle();
+ QV4::ExecutionEngine *engine = ddata->context->engine()->handle();
- QQmlContextData *ctxtdata = ddata->outerContext;
+ QQmlRefPointer<QQmlContextData> ctxtdata = ddata->outerContext;
for (int i = ddata->propertyCache->methodOffset(),
end = ddata->propertyCache->methodOffset() + ddata->propertyCache->methodCount();
i < end;
@@ -349,7 +349,7 @@ void QQmlConnections::connectSignalsToBindings()
Q_D(QQmlConnections);
QObject *target = this->target();
QQmlData *ddata = QQmlData::get(this);
- QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr;
+ QQmlRefPointer<QQmlContextData> ctxtdata = ddata ? ddata->outerContext : nullptr;
for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 7bf688cf75..8ed874d9fc 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -69,9 +69,10 @@ 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 3)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION(2, 3))
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
QML_NAMED_ELEMENT(Connections)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlConnections(QObject *parent=nullptr);
@@ -88,7 +89,7 @@ public:
Q_SIGNALS:
void targetChanged();
- Q_REVISION(3) void enabledChanged();
+ Q_REVISION(2, 3) void enabledChanged();
private:
void connectSignals();
diff --git a/src/qml/types/qqmlmodelindexvaluetype_p.h b/src/qml/types/qqmlmodelindexvaluetype_p.h
index f5b1699574..59c33bf5af 100644
--- a/src/qml/types/qqmlmodelindexvaluetype_p.h
+++ b/src/qml/types/qqmlmodelindexvaluetype_p.h
@@ -53,6 +53,7 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qitemselectionmodel.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -67,6 +68,9 @@ struct QQmlModelIndexValueType
Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT FINAL)
Q_PROPERTY(quint64 internalId READ internalId CONSTANT FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QModelIndex)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const
@@ -97,6 +101,9 @@ struct QQmlPersistentModelIndexValueType
Q_PROPERTY(QAbstractItemModel *model READ model FINAL)
Q_PROPERTY(quint64 internalId READ internalId FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QPersistentModelIndex)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const
@@ -130,6 +137,9 @@ struct QQmlItemSelectionRangeValueType
Q_PROPERTY(bool empty READ isEmpty FINAL)
Q_PROPERTY(QAbstractItemModel *model READ model FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QItemSelectionRange)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const;
diff --git a/src/qml/types/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h
index 0cd93e4659..a8236977c4 100644
--- a/src/qml/types/qqmltimer_p.h
+++ b/src/qml/types/qqmltimer_p.h
@@ -73,6 +73,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTimer : public QObject, public QQmlParserStatus
Q_PROPERTY(bool triggeredOnStart READ triggeredOnStart WRITE setTriggeredOnStart NOTIFY triggeredOnStartChanged)
Q_PROPERTY(QObject *parent READ parent CONSTANT)
QML_NAMED_ELEMENT(Timer)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlTimer(QObject *parent=nullptr);
diff --git a/src/qmldebug/CMakeLists.txt b/src/qmldebug/CMakeLists.txt
new file mode 100644
index 0000000000..da27e1da49
--- /dev/null
+++ b/src/qmldebug/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Generated from qmldebug.pro.
+
+#####################################################################
+## QmlDebug Module:
+#####################################################################
+
+qt_add_module(QmlDebug
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qqmldebugclient.cpp qqmldebugclient_p.h
+ qqmldebugclient_p_p.h
+ qqmldebugconnection.cpp qqmldebugconnection_p.h
+ qqmldebugmessageclient.cpp qqmldebugmessageclient_p.h
+ qqmldebugtranslationclient.cpp qqmldebugtranslationclient_p.h
+ qqmlenginecontrolclient.cpp qqmlenginecontrolclient_p.h
+ qqmlenginecontrolclient_p_p.h
+ qqmlenginedebugclient.cpp qqmlenginedebugclient_p.h
+ qqmlenginedebugclient_p_p.h
+ qqmlinspectorclient.cpp qqmlinspectorclient_p.h
+ qqmlinspectorclient_p_p.h
+ qqmlpreviewclient.cpp qqmlpreviewclient_p.h
+ qqmlpreviewclient_p_p.h
+ qqmlprofilerclient.cpp qqmlprofilerclient_p.h
+ qqmlprofilerclient_p_p.h
+ qqmlprofilerclientdefinitions_p.h
+ qqmlprofilerevent.cpp qqmlprofilerevent_p.h
+ qqmlprofilereventlocation.cpp qqmlprofilereventlocation_p.h
+ qqmlprofilereventreceiver_p.h
+ qqmlprofilereventtype.cpp qqmlprofilereventtype_p.h
+ qqmlprofilertypedevent.cpp qqmlprofilertypedevent_p.h
+ qv4debugclient.cpp qv4debugclient_p.h
+ qv4debugclient_p_p.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ Qt::PacketProtocolPrivate
+ Qt::QmlPrivate
+)
diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp
index b32ecc3d06..81b69d1216 100644
--- a/src/qmldebug/qqmldebugconnection.cpp
+++ b/src/qmldebug/qqmldebugconnection.cpp
@@ -205,14 +205,14 @@ void QQmlDebugConnection::protocolReadyRead()
QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin();
for (; iter != d->plugins.end(); ++iter) {
- const QString pluginName = iter.key();
- QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable;
+ const QString &pluginName = iter.key();
+ QQmlDebugClient::State newState = QQmlDebugClient::Unavailable;
if (d->serverPlugins.contains(pluginName))
- newSate = QQmlDebugClient::Enabled;
+ newState = QQmlDebugClient::Enabled;
if (oldServerPlugins.contains(pluginName)
!= d->serverPlugins.contains(pluginName)) {
- iter.value()->stateChanged(newSate);
+ iter.value()->stateChanged(newState);
}
}
} else {
@@ -223,9 +223,10 @@ void QQmlDebugConnection::protocolReadyRead()
if (iter == d->plugins.end()) {
// We can get more messages for plugins we have removed because it takes time to
// send the advertisement message but the removal is instant locally.
- if (!d->removedPlugins.contains(name))
+ if (!d->removedPlugins.contains(name)) {
qWarning() << "QQmlDebugConnection: Message received for missing plugin"
<< name;
+ }
} else {
QQmlDebugClient *client = *iter;
QByteArray message;
@@ -307,7 +308,7 @@ void QQmlDebugConnection::close()
bool QQmlDebugConnection::waitForConnected(int msecs)
{
Q_D(QQmlDebugConnection);
- QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
+ auto socket = qobject_cast<QAbstractSocket*>(d->device);
if (!socket) {
if (!d->server || (!d->server->hasPendingConnections() &&
!d->server->waitForNewConnection(msecs)))
@@ -324,7 +325,7 @@ bool QQmlDebugConnection::waitForConnected(int msecs)
QQmlDebugClient *QQmlDebugConnection::client(const QString &name) const
{
Q_D(const QQmlDebugConnection);
- return d->plugins.value(name, 0);
+ return d->plugins.value(name, nullptr);
}
bool QQmlDebugConnection::addClient(const QString &name, QQmlDebugClient *client)
@@ -371,9 +372,9 @@ bool QQmlDebugConnection::sendMessage(const QString &name, const QByteArray &mes
void QQmlDebugConnectionPrivate::flush()
{
- if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(device))
+ if (auto socket = qobject_cast<QAbstractSocket *>(device))
socket->flush();
- else if (QLocalSocket *socket = qobject_cast<QLocalSocket *>(device))
+ else if (auto socket = qobject_cast<QLocalSocket *>(device))
socket->flush();
}
@@ -382,7 +383,7 @@ void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
Q_D(QQmlDebugConnection);
if (d->gotHello)
close();
- QTcpSocket *socket = new QTcpSocket(this);
+ auto socket = new QTcpSocket(this);
d->device = socket;
d->createProtocol();
connect(socket, &QAbstractSocket::disconnected, this, &QQmlDebugConnection::socketDisconnected);
@@ -429,8 +430,8 @@ public:
}
signals:
- void socketError(QAbstractSocket::SocketError error);
- void socketStateChanged(QAbstractSocket::SocketState state);
+ void socketError(QAbstractSocket::SocketError);
+ void socketStateChanged(QAbstractSocket::SocketState);
};
void QQmlDebugConnection::newConnection()
@@ -442,7 +443,7 @@ void QQmlDebugConnection::newConnection()
d->device = socket;
d->createProtocol();
connect(socket, &QLocalSocket::disconnected, this, &QQmlDebugConnection::socketDisconnected);
- LocalSocketSignalTranslator *translator = new LocalSocketSignalTranslator(socket);
+ auto translator = new LocalSocketSignalTranslator(socket);
connect(translator, &LocalSocketSignalTranslator::socketError,
this, &QQmlDebugConnection::socketError);
diff --git a/src/qmldebug/qqmldebugconnection_p.h b/src/qmldebug/qqmldebugconnection_p.h
index ad9376886c..5abdd2943b 100644
--- a/src/qmldebug/qqmldebugconnection_p.h
+++ b/src/qmldebug/qqmldebugconnection_p.h
@@ -61,7 +61,6 @@ class QQmlDebugConnectionPrivate;
class QQmlDebugConnection : public QObject
{
Q_OBJECT
- Q_DISABLE_COPY(QQmlDebugConnection)
Q_DECLARE_PRIVATE(QQmlDebugConnection)
public:
QQmlDebugConnection(QObject *parent = nullptr);
diff --git a/src/qmldebug/qqmlprofilereventlocation_p.h b/src/qmldebug/qqmlprofilereventlocation_p.h
index 6f37eab14b..beec3a0eb0 100644
--- a/src/qmldebug/qqmlprofilereventlocation_p.h
+++ b/src/qmldebug/qqmlprofilereventlocation_p.h
@@ -103,7 +103,7 @@ inline bool operator!=(const QQmlProfilerEventLocation &location1,
return !(location1 == location2);
}
-inline uint qHash(const QQmlProfilerEventLocation &location)
+inline size_t qHash(const QQmlProfilerEventLocation &location)
{
return qHash(location.filename())
^ ((location.line() & 0xfff) // 12 bits of line number
diff --git a/src/qmldebug/qqmlprofilereventtype_p.h b/src/qmldebug/qqmlprofilereventtype_p.h
index 7189df53ef..c89115be83 100644
--- a/src/qmldebug/qqmlprofilereventtype_p.h
+++ b/src/qmldebug/qqmlprofilereventtype_p.h
@@ -97,7 +97,7 @@ private:
QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventType &type);
QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventType &type);
-inline uint qHash(const QQmlProfilerEventType &type)
+inline size_t qHash(const QQmlProfilerEventType &type)
{
return qHash(type.location())
^ (((type.message() << 12) & 0xf000) // 4 bits message
diff --git a/src/qmldevtools/.prev_CMakeLists.txt b/src/qmldevtools/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..a1f121d6d0
--- /dev/null
+++ b/src/qmldevtools/.prev_CMakeLists.txt
@@ -0,0 +1,90 @@
+# Generated from qmldevtools.pro.
+
+#####################################################################
+## QmlDevTools Module:
+#####################################################################
+
+qt_add_module(QmlDevTools
+ STATIC
+ INTERNAL_MODULE
+ NO_SYNC_QT
+ SOURCES
+ ../qml/common/qqmlapiversion_p.h
+ ../qml/common/qqmljsdiagnosticmessage_p.h
+ ../qml/common/qqmljsfixedpoolarray_p.h
+ ../qml/common/qqmljsmemorypool_p.h
+ ../qml/common/qqmljssourcelocation_p.h
+ ../qml/common/qv4alloca_p.h
+ ../qml/common/qv4calldata_p.h
+ ../qml/common/qv4compileddata_p.h
+ ../qml/common/qv4staticvalue_p.h
+ ../qml/common/qv4stringtoarrayindex_p.h
+ ../qml/compiler/qqmlirbuilder.cpp ../qml/compiler/qqmlirbuilder_p.h
+ ../qml/compiler/qv4bytecodegenerator.cpp ../qml/compiler/qv4bytecodegenerator_p.h
+ ../qml/compiler/qv4bytecodehandler.cpp ../qml/compiler/qv4bytecodehandler_p.h
+ ../qml/compiler/qv4codegen.cpp ../qml/compiler/qv4codegen_p.h
+ ../qml/compiler/qv4compiler.cpp ../qml/compiler/qv4compiler_p.h
+ ../qml/compiler/qv4compilercontext.cpp ../qml/compiler/qv4compilercontext_p.h
+ ../qml/compiler/qv4compilercontrolflow_p.h
+ ../qml/compiler/qv4compilerglobal_p.h
+ ../qml/compiler/qv4compilerscanfunctions.cpp ../qml/compiler/qv4compilerscanfunctions_p.h
+ ../qml/compiler/qv4instr_moth.cpp ../qml/compiler/qv4instr_moth_p.h
+ ../qml/compiler/qv4util_p.h
+ ../qml/parser/qqmljsast.cpp ../qml/parser/qqmljsast_p.h
+ ../qml/parser/qqmljsastfwd_p.h
+ ../qml/parser/qqmljsastvisitor.cpp ../qml/parser/qqmljsastvisitor_p.h
+ ../qml/parser/qqmljsengine_p.cpp ../qml/parser/qqmljsengine_p.h
+ ../qml/parser/qqmljsglobal_p.h
+ ../qml/parser/qqmljskeywords_p.h
+ ../qml/parser/qqmljslexer.cpp ../qml/parser/qqmljslexer_p.h
+ ../qml/qmldirparser/qqmldirparser.cpp ../qml/qmldirparser/qqmldirparser_p.h
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml/compiler
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml/qmldirparser
+ ../qml/compiler
+ ../qml/qmldirparser
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
+
+# QLALR Grammars:
+qt_process_qlalr(
+ QmlDevTools
+ ../qml/parser/qqmljs.g
+ ""
+)
+
+#### Keys ignored in scope 1:.:.:qmldevtools.pro:<TRUE>:
+# MODULE_INCNAME = "QtQml"
+# _OPTION = "host_build"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qmldevtools.pro:ICC:
+# WERROR = "-ww2415"
+
+#### Keys ignored in scope 3:.:.:qmldevtools.pro:CLANG AND ( (QT_CLANG_MAJOR_VERSION GREATER 3) OR (QT_CLANG_MINOR_VERSION GREATER 3) ):
+# WERROR = "-Wno-error=unused-const-variable"
+
+#### Keys ignored in scope 5:.:../qml/common:../qml/common/common.pri:NOT build_pass:
+# compile_hash_contents = "// Generated file, DO NOT EDIT" "$${LITERAL_HASH}define QML_COMPILE_HASH "$$QML_COMPILE_HASH"" "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
+# tag = <EMPTY>
+# tagFile = "$$PWD/../../.tag"
+
+#### Keys ignored in scope 6:.:../qml/common:../qml/common/common.pri:EXISTS _ss_tagFile:
+# QMAKE_INTERNAL_INCLUDED_FILES = "$$tagFile"
+# tag = "$$cat($$tagFile, singleline)"
+
+#### Keys ignored in scope 7:.:../qml/common:../qml/common/common.pri:NOT tag___equals____ss_{LITERAL_DOLLAR}Format AND %H_ss_{LITERAL_DOLLAR}:
+# QML_COMPILE_HASH = "$$tag"
+
+#### Keys ignored in scope 9:.:../qml/common:../qml/common/common.pri:EXISTS _ss_PWD/../../.git:
+# QML_COMPILE_HASH = "$$commit"
+# commit = "$$system(git rev-parse HEAD)"
+
+qt_extend_target(QmlDevTools CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5
+ COMPILE_OPTIONS
+ -fno-strict-aliasing
+)
diff --git a/src/qmldevtools/CMakeLists.txt b/src/qmldevtools/CMakeLists.txt
new file mode 100644
index 0000000000..4648c6854c
--- /dev/null
+++ b/src/qmldevtools/CMakeLists.txt
@@ -0,0 +1,137 @@
+# Generated from qmldevtools.pro.
+
+#####################################################################
+## QmlDevTools Module:
+#####################################################################
+
+qt_add_module(QmlDevTools
+ STATIC
+ INTERNAL_MODULE
+ NO_SYNC_QT
+ SOURCES
+ ../qml/common/qqmlapiversion_p.h
+ ../qml/common/qqmljsdiagnosticmessage_p.h
+ ../qml/common/qqmljsfixedpoolarray_p.h
+ ../qml/common/qqmljsmemorypool_p.h
+ ../qml/common/qqmljssourcelocation_p.h
+ ../qml/common/qv4alloca_p.h
+ ../qml/common/qv4calldata_p.h
+ ../qml/common/qv4compileddata_p.h
+ ../qml/common/qv4staticvalue_p.h
+ ../qml/common/qv4stringtoarrayindex_p.h
+ ../qml/compiler/qqmlirbuilder.cpp ../qml/compiler/qqmlirbuilder_p.h
+ ../qml/compiler/qv4bytecodegenerator.cpp ../qml/compiler/qv4bytecodegenerator_p.h
+ ../qml/compiler/qv4bytecodehandler.cpp ../qml/compiler/qv4bytecodehandler_p.h
+ ../qml/compiler/qv4codegen.cpp ../qml/compiler/qv4codegen_p.h
+ ../qml/compiler/qv4compiler.cpp ../qml/compiler/qv4compiler_p.h
+ ../qml/compiler/qv4compilercontext.cpp ../qml/compiler/qv4compilercontext_p.h
+ ../qml/compiler/qv4compilercontrolflow_p.h
+ ../qml/compiler/qv4compilerglobal_p.h
+ ../qml/compiler/qv4compilerscanfunctions.cpp ../qml/compiler/qv4compilerscanfunctions_p.h
+ ../qml/compiler/qv4instr_moth.cpp ../qml/compiler/qv4instr_moth_p.h
+ ../qml/compiler/qv4util_p.h
+ ../qml/parser/qqmljsast.cpp ../qml/parser/qqmljsast_p.h
+ ../qml/parser/qqmljsastfwd_p.h
+ ../qml/parser/qqmljsastvisitor.cpp ../qml/parser/qqmljsastvisitor_p.h
+ ../qml/parser/qqmljsengine_p.cpp ../qml/parser/qqmljsengine_p.h
+ ../qml/parser/qqmljsglobal_p.h
+ ../qml/parser/qqmljskeywords_p.h
+ ../qml/parser/qqmljslexer.cpp ../qml/parser/qqmljslexer_p.h
+ ../qml/qmldirparser/qqmldirparser.cpp ../qml/qmldirparser/qqmldirparser_p.h
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml/compiler
+ ${CMAKE_CURRENT_BINARY_DIR}/../qml/qmldirparser
+ ../qml/compiler
+ ../qml/qmldirparser
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
+
+# special case begin
+# Need to generate the parser files as in Qml module.
+set(_qt_qlalr_flags "--no-debug" "--qt")
+qt_process_qlalr(QmlDevTools "${CMAKE_CURRENT_SOURCE_DIR}/../qml/parser/qqmljs.g" "${_qt_qlalr_flags}")
+
+# Need to propagate some of the include directories from Qml via QmlDevToolsPrivate
+# for other tools, and also for the main QmlDevTools module,
+# until we fix the script to handle internal_module to create only one single Private module.
+qt_internal_module_info(qml_module "Qml")
+if(QT_FEATURE_framework)
+ get_target_property(_qml_fw_headers_dir Qt::Qml LIBRARY_OUTPUT_DIRECTORY)
+ string(APPEND _qml_fw_headers_dir /${qml_module}.framework/Versions/${PROJECT_VERSION_MAJOR}/Headers)
+ set(_qml_dev_tools_private_includes
+ $<BUILD_INTERFACE:${_qml_fw_headers_dir}>
+ $<BUILD_INTERFACE:${_qml_fw_headers_dir}/${PROJECT_VERSION}>
+ $<BUILD_INTERFACE:${_qml_fw_headers_dir}/${PROJECT_VERSION}/${qml_module}>
+ )
+else()
+ set(_qml_dev_tools_private_includes
+ $<BUILD_INTERFACE:${qml_module_include_dir}>
+ $<BUILD_INTERFACE:${qml_module_repo_include_dir}>
+ $<BUILD_INTERFACE:${qml_module_include_dir}/${PROJECT_VERSION}>
+ $<BUILD_INTERFACE:${qml_module_include_dir}/${PROJECT_VERSION}/${qml_module}>
+ )
+endif()
+target_include_directories(QmlDevTools PRIVATE ${_qml_dev_tools_private_includes})
+target_include_directories(QmlDevToolsPrivate INTERFACE ${_qml_dev_tools_private_includes})
+if(QT_FEATURE_framework)
+ set(_qml_fw_headers_dir lib/${qml_module}.framework/Headers)
+ set(_qml_dev_tools_public_includes
+ $<INSTALL_INTERFACE:${_qml_fw_headers_dir}>
+ $<INSTALL_INTERFACE:${_qml_fw_headers_dir}/${PROJECT_VERSION}>
+ $<INSTALL_INTERFACE:${_qml_fw_headers_dir}/${PROJECT_VERSION}/${qml_module}>
+ )
+else()
+ set(_qml_dev_tools_public_includes
+ $<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${qml_module}>
+ $<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${qml_module}/${PROJECT_VERSION}>
+ $<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${qml_module}/${PROJECT_VERSION}/${qml_module}>
+ )
+endif()
+target_include_directories(QmlDevTools PRIVATE ${_qml_dev_tools_public_includes})
+target_include_directories(QmlDevToolsPrivate INTERFACE ${_qml_dev_tools_public_includes})
+
+# We build the qlalr sources into qmldevtools, so there's no link-time
+# dependency to QtQml. However we also include files in QmlDevTools such
+# as qqmlirbuilder.cpp that include <private/qqmljsgrammar_p.h> that
+# originate from QtQml. That particular header was created at cmake time
+# via syncqt, but it's just a forwarding header that in turn includes
+# the generated file. That generated file is created when building
+# QtQml, so we must depend on it:
+add_dependencies(QmlDevTools Qml)
+# special case end
+
+#### Keys ignored in scope 1:.:.:qmldevtools.pro:<TRUE>:
+# MODULE_INCNAME = "QtQml"
+# _OPTION = "host_build"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qmldevtools.pro:ICC:
+# WERROR = "-ww2415"
+
+#### Keys ignored in scope 3:.:.:qmldevtools.pro:CLANG AND ( (QT_CLANG_MAJOR_VERSION GREATER 3) OR (QT_CLANG_MINOR_VERSION GREATER 3) ):
+# WERROR = "-Wno-error=unused-const-variable"
+
+#### Keys ignored in scope 5:.:../qml/common:../qml/common/common.pri:NOT build_pass:
+# compile_hash_contents = "// Generated file, DO NOT EDIT" "$${LITERAL_HASH}define QML_COMPILE_HASH "$$QML_COMPILE_HASH"" "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
+# tag = <EMPTY>
+# tagFile = "$$PWD/../../.tag"
+
+#### Keys ignored in scope 6:.:../qml/common:../qml/common/common.pri:EXISTS _ss_tagFile:
+# QMAKE_INTERNAL_INCLUDED_FILES = "$$tagFile"
+# tag = "$$cat($$tagFile, singleline)"
+
+#### Keys ignored in scope 7:.:../qml/common:../qml/common/common.pri:NOT tag___equals____ss_{LITERAL_DOLLAR}Format AND %H_ss_{LITERAL_DOLLAR}:
+# QML_COMPILE_HASH = "$$tag"
+
+#### Keys ignored in scope 9:.:../qml/common:../qml/common/common.pri:EXISTS _ss_PWD/../../.git:
+# QML_COMPILE_HASH = "$$commit"
+# commit = "$$system(git rev-parse HEAD)"
+
+qt_extend_target(QmlDevTools CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5
+ COMPILE_OPTIONS
+ -fno-strict-aliasing
+)
diff --git a/src/qmlmodels/CMakeLists.txt b/src/qmlmodels/CMakeLists.txt
new file mode 100644
index 0000000000..069ea4a01e
--- /dev/null
+++ b/src/qmlmodels/CMakeLists.txt
@@ -0,0 +1,78 @@
+# Generated from qmlmodels.pro.
+
+#####################################################################
+## QmlModels Module:
+#####################################################################
+
+qt_add_module(QmlModels
+ GENERATE_METATYPES
+ SOURCES
+ qqmlchangeset.cpp qqmlchangeset_p.h
+ qqmlmodelsmodule_p.h
+ qtqmlmodelsglobal.h qtqmlmodelsglobal_p.h
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Qml
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmlmodels.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQml/Models"
+# QML_IMPORT_NAME = "QtQml.Models"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QmlModels CONDITION QT_FEATURE_qml_object_model
+ SOURCES
+ qqmlinstantiator.cpp qqmlinstantiator_p.h
+ qqmlinstantiator_p_p.h
+ qqmlobjectmodel.cpp qqmlobjectmodel_p.h
+)
+
+qt_extend_target(QmlModels CONDITION QT_FEATURE_qml_table_model
+ SOURCES
+ qqmltableinstancemodel.cpp qqmltableinstancemodel_p.h
+)
+
+qt_extend_target(QmlModels CONDITION QT_FEATURE_qml_list_model
+ SOURCES
+ qqmllistmodel.cpp qqmllistmodel_p.h
+ qqmllistmodel_p_p.h
+ qqmllistmodelworkeragent.cpp qqmllistmodelworkeragent_p.h
+)
+
+qt_extend_target(QmlModels CONDITION QT_FEATURE_qml_delegate_model
+ SOURCES
+ qqmlabstractdelegatecomponent.cpp qqmlabstractdelegatecomponent_p.h
+ qqmladaptormodel.cpp qqmladaptormodel_p.h
+ qqmldelegatemodel.cpp qqmldelegatemodel_p.h
+ qqmldelegatemodel_p_p.h
+ qqmllistaccessor.cpp qqmllistaccessor_p.h
+ qqmllistcompositor.cpp qqmllistcompositor_p.h
+ qquickpackage.cpp qquickpackage_p.h
+)
+qt_add_docs(QmlModels
+ doc/qtqmlmodels.qdocconf
+)
+
+
+set_target_properties(QmlModels PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQml.Models
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQml/Models"
+)
+
+qt6_qml_type_registration(QmlModels)
diff --git a/src/qmlmodels/configure.cmake b/src/qmlmodels/configure.cmake
new file mode 100644
index 0000000000..44643c88a6
--- /dev/null
+++ b/src/qmlmodels/configure.cmake
@@ -0,0 +1,39 @@
+
+
+#### Inputs
+
+
+
+#### Libraries
+
+
+
+#### Tests
+
+
+
+#### Features
+
+qt_feature("qml-object-model" PRIVATE
+ SECTION "QML"
+ LABEL "QML object model"
+ PURPOSE "Provides the ObjectModel and Instantiator QML types."
+)
+qt_feature("qml-list-model" PRIVATE
+ SECTION "QML"
+ LABEL "QML list model"
+ PURPOSE "Provides the ListModel QML type."
+ CONDITION QT_FEATURE_qml_itemmodel
+)
+qt_feature("qml-delegate-model" PRIVATE
+ SECTION "QML"
+ LABEL "QML delegate model"
+ PURPOSE "Provides the DelegateModel QML type."
+ CONDITION QT_FEATURE_qml_object_model AND QT_FEATURE_qml_itemmodel
+)
+qt_feature("qml-table-model" PRIVATE
+ SECTION "QML"
+ LABEL "QML table model"
+ PURPOSE "Provides the TableModel QML type."
+ CONDITION QT_FEATURE_qml_itemmodel AND QT_FEATURE_qml_delegate_model
+)
diff --git a/src/qmlmodels/doc/qtqmlmodels.qdocconf b/src/qmlmodels/doc/qtqmlmodels.qdocconf
index 3364988559..4b7fe654ac 100644
--- a/src/qmlmodels/doc/qtqmlmodels.qdocconf
+++ b/src/qmlmodels/doc/qtqmlmodels.qdocconf
@@ -23,7 +23,7 @@ qhp.QtQmlModels.sortPages = true
tagfile = qtqmlmodels.tags
-depends += qtcore qtqml qtquick qtdoc qtqmlworkerscript qtquickcontrols qtxmlpatterns
+depends += qtcore qtqml qtquick qtdoc qtqmlworkerscript qtquickcontrols
headerdirs += .. \
../../imports/labsmodels
diff --git a/src/qmlmodels/qmlmodels.pro b/src/qmlmodels/qmlmodels.pro
index 4ac093556d..34380ee14e 100644
--- a/src/qmlmodels/qmlmodels.pro
+++ b/src/qmlmodels/qmlmodels.pro
@@ -12,8 +12,7 @@ HEADERS += \
$$PWD/qtqmlmodelsglobal.h
SOURCES += \
- $$PWD/qqmlchangeset.cpp \
- $$PWD/qqmlmodelsmodule.cpp
+ $$PWD/qqmlchangeset.cpp
qtConfig(qml-object-model) {
SOURCES += \
@@ -65,9 +64,9 @@ qtConfig(qml-delegate-model) {
}
QMLTYPES_FILENAME = plugins.qmltypes
-QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models.2
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models
QML_IMPORT_NAME = QtQml.Models
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
load(qt_module)
diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h
index 07cae6b092..853a7e8af8 100644
--- a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h
+++ b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h
@@ -65,6 +65,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComp
{
Q_OBJECT
QML_NAMED_ELEMENT(AbstractDelegateComponent)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Cannot create instance of abstract class AbstractDelegateComponent.")
public:
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 2126ad3dc5..8c8c37d237 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -1035,9 +1035,9 @@ int QQmlAdaptorModel::indexAt(int row, int column) const
return column * rowCount() + row;
}
-void QQmlAdaptorModel::useImportVersion(int minorVersion)
+void QQmlAdaptorModel::useImportVersion(QTypeRevision revision)
{
- modelItemRevision = minorVersion;
+ modelItemRevision = revision;
}
void QQmlAdaptorModel::objectDestroyed(QObject *)
diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h
index ba54c864c6..2c90ffc1d1 100644
--- a/src/qmlmodels/qqmladaptormodel_p.h
+++ b/src/qmlmodels/qqmladaptormodel_p.h
@@ -115,7 +115,7 @@ public:
QPersistentModelIndex rootIndex;
QQmlListAccessor list;
- int modelItemRevision = 0;
+ QTypeRevision modelItemRevision = QTypeRevision::zero();
QQmlAdaptorModel();
~QQmlAdaptorModel();
@@ -132,7 +132,7 @@ public:
int columnAt(int index) const;
int indexAt(int row, int column) const;
- void useImportVersion(int minorVersion);
+ void useImportVersion(QTypeRevision revision);
inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); }
inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
diff --git a/src/qmlmodels/qqmlchangeset_p.h b/src/qmlmodels/qqmlchangeset_p.h
index 5b44d2958c..203518cf90 100644
--- a/src/qmlmodels/qqmlchangeset_p.h
+++ b/src/qmlmodels/qqmlchangeset_p.h
@@ -149,7 +149,7 @@ private:
Q_DECLARE_TYPEINFO(QQmlChangeSet::Change, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QQmlChangeSet::MoveKey, Q_PRIMITIVE_TYPE);
-inline uint qHash(const QQmlChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
+inline size_t qHash(const QQmlChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
inline bool operator ==(const QQmlChangeSet::MoveKey &l, const QQmlChangeSet::MoveKey &r) {
return l.moveId == r.moveId && l.offset == r.offset; }
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index cee096035a..c94493dee8 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -48,6 +48,7 @@
#include <private/qqmlchangeset_p.h>
#include <private/qqmlengine_p.h>
#include <private/qqmlcomponent_p.h>
+#include <private/qjsvalue_p.h>
#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
@@ -266,7 +267,6 @@ QQmlDelegateModel::~QQmlDelegateModel()
cacheItem->object = nullptr;
cacheItem->contextData->invalidate();
- Q_ASSERT(cacheItem->contextData->refCount == 1);
cacheItem->contextData = nullptr;
cacheItem->scriptRef -= 1;
} else if (cacheItem->incubationTask) {
@@ -963,10 +963,8 @@ void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *mod
if (incubatorPriv->hadRequiredProperties()) {
QQmlData *d = QQmlData::get(object);
auto contextData = d ? d->context : nullptr;
- if (contextData) {
- contextData->hasExtraObject = true;
- contextData->extraObject = modelItemToIncubate;
- }
+ if (contextData)
+ contextData->setExtraObject(modelItemToIncubate);
if (incubatorPriv->requiredProperties().empty())
return;
@@ -1030,9 +1028,9 @@ void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *mod
}
}
} else {
- modelItemToIncubate->contextData->contextObject = modelItemToIncubate;
+ modelItemToIncubate->contextData->setContextObject(modelItemToIncubate);
if (proxiedObject)
- proxyContext->contextObject = proxiedObject;
+ proxyContext->setContextObject(proxiedObject);
}
}
@@ -1047,7 +1045,7 @@ void QQDMIncubationTask::statusChanged(Status status)
incubating->object = nullptr;
if (incubating->contextData) {
incubating->contextData->invalidate();
- Q_ASSERT(incubating->contextData->refCount == 1);
+ Q_ASSERT(incubating->contextData->refCount() == 1);
incubating->contextData = nullptr;
}
incubating->scriptRef = 0;
@@ -1182,7 +1180,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
cacheItem->scriptRef -= 1;
if (cacheItem->contextData) {
cacheItem->contextData->invalidate();
- Q_ASSERT(cacheItem->contextData->refCount == 1);
+ Q_ASSERT(cacheItem->contextData->refCount() == 1);
}
cacheItem->contextData = nullptr;
@@ -1277,15 +1275,14 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
for (int i = 1; i < m_groupCount; ++i)
cacheItem->incubationTask->index[i] = it.index[i];
- QQmlContextData *ctxt = new QQmlContextData;
- ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context.data()));
+ QQmlRefPointer<QQmlContextData> ctxt = QQmlContextData::createRefCounted(
+ QQmlContextData::get(creationContext ? creationContext : m_context.data()));
cacheItem->contextData = ctxt;
if (m_adaptorModel.hasProxyObject()) {
if (QQmlAdaptorModelProxyInterface *proxy
= qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) {
- ctxt = new QQmlContextData;
- ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true);
+ ctxt = QQmlContextData::createChild(cacheItem->contextData);
QObject *proxied = proxy->proxiedObject();
cacheItem->incubationTask->proxiedObject = proxied;
cacheItem->incubationTask->proxyContext = ctxt;
@@ -2260,9 +2257,10 @@ void QQmlDelegateModelItem::childContextObjectDestroyed(QObject *childContextObj
if (!contextData)
return;
- for (QQmlContextData *ctxt = contextData->childContexts; ctxt; ctxt = ctxt->nextChild) {
- if (ctxt->contextObject == childContextObject)
- ctxt->contextObject = nullptr;
+ for (QQmlRefPointer<QQmlContextData> ctxt = contextData->childContexts(); ctxt;
+ ctxt = ctxt->nextChild()) {
+ if (ctxt->contextObject() == childContextObject)
+ ctxt->setContextObject(nullptr);
}
}
@@ -2367,8 +2365,8 @@ void QQmlDelegateModelItem::destroyObject()
Q_ASSERT(data);
if (data->ownContext) {
data->ownContext->clearContext();
- if (data->ownContext->contextObject == object)
- data->ownContext->contextObject = nullptr;
+ if (data->ownContext->contextObject() == object)
+ data->ownContext->setContextObject(nullptr);
data->ownContext = nullptr;
data->context = nullptr;
}
@@ -2387,12 +2385,12 @@ void QQmlDelegateModelItem::destroyObject()
QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object)
{
QQmlData *d = QQmlData::get(object);
- QQmlContextData *context = d ? d->context : nullptr;
- if (context && context->hasExtraObject)
- return qobject_cast<QQmlDelegateModelItem *>(context->extraObject);
- for (context = context ? context->parent : nullptr; context; context = context->parent) {
+ QQmlRefPointer<QQmlContextData> context = d ? d->context : nullptr;
+ if (QObject *extraObject = context ? context->extraObject() : nullptr)
+ return qobject_cast<QQmlDelegateModelItem *>(extraObject);
+ for (context = context ? context->parent() : nullptr; context; context = context->parent()) {
if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>(
- context->contextObject)) {
+ context->contextObject())) {
return cacheItem;
}
}
@@ -2665,8 +2663,10 @@ void QQmlDelegateModelGroupPrivate::emitChanges(QV4::ExecutionEngine *v4)
{
Q_Q(QQmlDelegateModelGroup);
if (isChangedConnected() && !changeSet.isEmpty()) {
- emit q->changed(QJSValue(v4, engineData(v4)->array(v4, changeSet.removes())),
- QJSValue(v4, engineData(v4)->array(v4, changeSet.inserts())));
+ emit q->changed(QJSValuePrivate::fromReturnedValue(
+ engineData(v4)->array(v4, changeSet.removes())),
+ QJSValuePrivate::fromReturnedValue(
+ engineData(v4)->array(v4, changeSet.inserts())));
}
if (changeSet.difference() != 0)
emit q->countChanged();
@@ -2883,7 +2883,7 @@ QJSValue QQmlDelegateModelGroup::get(int index)
QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value());
o->setPrototypeOf(p);
- return QJSValue(v4, o->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(o->asReturnedValue());
}
bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index 8aab4badca..f4578e130e 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -86,7 +86,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p
Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
QML_NAMED_ELEMENT(DelegateModel)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
QML_ATTACHED(QQmlDelegateModelAttached)
Q_INTERFACES(QQmlParserStatus)
@@ -172,7 +172,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
QML_NAMED_ELEMENT(DelegateModelGroup)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
public:
QQmlDelegateModelGroup(QObject *parent = nullptr);
QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr);
diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h
index 2dc409b222..491e8025b8 100644
--- a/src/qmlmodels/qqmldelegatemodel_p_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p_p.h
@@ -100,8 +100,8 @@ class QQmlDelegateModelItem : public QObject
{
Q_OBJECT
Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
- Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION 12)
- Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12)
+ Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION(2, 12))
+ Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION(2, 12))
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
public:
QQmlDelegateModelItem(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
@@ -149,7 +149,7 @@ public:
QV4::ExecutionEngine *v4;
QQmlRefPointer<QQmlDelegateModelItemMetaType> const metaType;
- QQmlContextDataRef contextData;
+ QQmlRefPointer<QQmlContextData> contextData;
QPointer<QObject> object;
QPointer<QQmlDelegateModelAttached> attached;
QQDMIncubationTask *incubationTask;
@@ -162,8 +162,8 @@ public:
Q_SIGNALS:
void modelIndexChanged();
- Q_REVISION(12) void rowChanged();
- Q_REVISION(12) void columnChanged();
+ Q_REVISION(2, 12) void rowChanged();
+ Q_REVISION(2, 12) void columnChanged();
protected:
void objectDestroyed(QObject *);
@@ -222,7 +222,7 @@ public:
QQmlDelegateModelItem *incubating = nullptr;
QQmlDelegateModelPrivate *vdm = nullptr;
- QQmlContextData *proxyContext = nullptr;
+ QQmlRefPointer<QQmlContextData> proxyContext;
QPointer<QObject> proxiedObject = nullptr; // the proxied object might disapear, so we use a QPointer instead of a raw one
int index[QQmlListCompositor::MaximumGroupCount];
};
diff --git a/src/qmlmodels/qqmlinstantiator_p.h b/src/qmlmodels/qqmlinstantiator_p.h
index 60b611128d..fec5c3888a 100644
--- a/src/qmlmodels/qqmlinstantiator_p.h
+++ b/src/qmlmodels/qqmlinstantiator_p.h
@@ -73,7 +73,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlP
Q_PROPERTY(QObject *object READ object NOTIFY objectChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
QML_NAMED_ELEMENT(Instantiator)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 1)
public:
QQmlInstantiator(QObject *parent = nullptr);
diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp
index e07951cab3..0d45d03fa6 100644
--- a/src/qmlmodels/qqmllistmodel.cpp
+++ b/src/qmlmodels/qqmllistmodel.cpp
@@ -271,19 +271,6 @@ const ListLayout::Role *ListLayout::getExistingRole(QV4::String *key) const
return r;
}
-StringOrTranslation::StringOrTranslation(const QString &s)
-{
- d.setFlag();
- setString(s);
-}
-
-StringOrTranslation::StringOrTranslation(const QV4::CompiledData::Binding *binding)
-{
- d.setFlag();
- clear();
- d = binding;
-}
-
StringOrTranslation::~StringOrTranslation()
{
clear();
@@ -291,53 +278,48 @@ StringOrTranslation::~StringOrTranslation()
void StringOrTranslation::setString(const QString &s)
{
- d.setFlag();
clear();
- QStringData *stringData = const_cast<QString &>(s).data_ptr();
- d = stringData;
- if (stringData)
- stringData->ref.ref();
+ QString mutableString(s);
+ QString::DataPointer dataPointer = mutableString.data_ptr();
+ arrayData = dataPointer->d_ptr();
+ stringData = dataPointer->data();
+ stringSize = mutableString.length();
+ arrayData->ref();
}
void StringOrTranslation::setTranslation(const QV4::CompiledData::Binding *binding)
{
- d.setFlag();
clear();
- d = binding;
+ this->binding = binding;
}
QString StringOrTranslation::toString(const QQmlListModel *owner) const
{
- if (d.isNull())
- return QString();
- if (d.isT1()) {
- QStringDataPtr holder = { d.asT1() };
- holder.ptr->ref.ref();
- return QString(holder);
+ if (arrayData) {
+ arrayData->ref();
+ return QString(QStringPrivate(arrayData, stringData, stringSize));
}
if (!owner)
return QString();
- return owner->m_compilationUnit->bindingValueAsString(d.asT2());
+ return owner->m_compilationUnit->bindingValueAsString(binding);
}
QString StringOrTranslation::asString() const
{
- if (d.isNull())
+ if (!arrayData)
return QString();
- if (!d.isT1())
- return QString();
- QStringDataPtr holder = { d.asT1() };
- holder.ptr->ref.ref();
- return QString(holder);
+ arrayData->ref();
+ return QString(QStringPrivate(arrayData, stringData, stringSize));
}
void StringOrTranslation::clear()
{
- if (QStringData *strData = d.isT1() ? d.asT1() : nullptr) {
- if (!strData->ref.deref())
- QStringData::deallocate(strData);
- }
- d = static_cast<QStringData *>(nullptr);
+ if (arrayData && !arrayData->deref())
+ QTypedArrayData<ushort>::deallocate(arrayData);
+ arrayData = nullptr;
+ stringData = nullptr;
+ stringSize = 0;
+ binding = nullptr;
}
QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementIndex)
@@ -607,7 +589,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Function);
QV4::ScopedFunctionObject func(scope, f);
QJSValue jsv;
- QJSValuePrivate::setValue(&jsv, v4, func);
+ QJSValuePrivate::setValue(&jsv, func);
roleIndex = e->setFunctionProperty(r, jsv);
} else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
@@ -1150,7 +1132,7 @@ int ListElement::setTranslationProperty(const ListLayout::Role &role, const QV4:
void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s)
{
char *mem = getPropertyMemory(role);
- new (mem) StringOrTranslation(s);
+ reinterpret_cast<StringOrTranslation *>(mem)->setString(s);
}
void ListElement::setDoublePropertyFast(const ListLayout::Role &role, double d)
@@ -1452,7 +1434,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
} else if (d.as<QV4::FunctionObject>()) {
QV4::ScopedFunctionObject f(scope, d);
QJSValue jsv;
- QJSValuePrivate::setValue(&jsv, eng, f);
+ QJSValuePrivate::setValue(&jsv, f);
roleIndex = setFunctionProperty(role, jsv);
} else if (d.isObject()) {
QV4::ScopedObject o(scope, d);
@@ -1656,7 +1638,8 @@ PropertyKey ModelObjectOwnPropertyKeyIterator::next(const Object *o, Property *p
auto size = recursiveListModel->count();
auto array = ScopedArrayObject{scope, v4->newArrayObject(size)};
for (auto i = 0; i < size; i++) {
- array->arrayPut(i, QJSValuePrivate::convertedToValue(v4, recursiveListModel->get(i)));
+ array->arrayPut(i, QJSValuePrivate::convertToReturnedValue(
+ v4, recursiveListModel->get(i)));
}
pd->value = array;
} else {
@@ -2588,7 +2571,7 @@ QJSValue QQmlListModel::get(int index) const
}
}
- return QJSValue(engine(), result->asReturnedValue());
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
/*!
@@ -2610,7 +2593,7 @@ QJSValue QQmlListModel::get(int index) const
void QQmlListModel::set(int index, const QJSValue &value)
{
QV4::Scope scope(engine());
- QV4::ScopedObject object(scope, QJSValuePrivate::getValue(&value));
+ QV4::ScopedObject object(scope, QJSValuePrivate::asReturnedValue(&value));
if (!object) {
qmlWarning(this) << tr("set: value is not an object");
@@ -2809,7 +2792,7 @@ bool QQmlListModelParser::applyProperty(
if (v4->hasException)
v4->catchException();
else
- QJSValuePrivate::setValue(&v, v4, result->asReturnedValue());
+ QJSValuePrivate::setValue(&v, result->asReturnedValue());
value.setValue<QJSValue>(v);
} else {
QByteArray script = scriptStr.toUtf8();
diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h
index 9a4358ac6f..bf4279cd05 100644
--- a/src/qmlmodels/qqmllistmodel_p.h
+++ b/src/qmlmodels/qqmllistmodel_p.h
@@ -82,9 +82,9 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
- Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14))
+ Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(2, 14))
QML_NAMED_ELEMENT(ListModel)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlListModel(QObject *parent=nullptr);
@@ -175,7 +175,7 @@ class QQmlListElement : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(ListElement)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 0)
};
class QQmlListModelParser : public QQmlCustomParser
diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h
index 2ad5158050..f17004ed3b 100644
--- a/src/qmlmodels/qqmllistmodel_p_p.h
+++ b/src/qmlmodels/qqmllistmodel_p_p.h
@@ -252,18 +252,23 @@ private:
struct StringOrTranslation
{
- explicit StringOrTranslation(const QString &s);
- explicit StringOrTranslation(const QV4::CompiledData::Binding *binding);
~StringOrTranslation();
- bool isSet() const { return d.flag(); }
- bool isTranslation() const { return d.isT2(); }
+ bool isSet() const { return binding || arrayData; }
+ bool isTranslation() const { return binding && !arrayData; }
void setString(const QString &s);
void setTranslation(const QV4::CompiledData::Binding *binding);
QString toString(const QQmlListModel *owner) const;
QString asString() const;
private:
void clear();
- QBiPointer<QStringData, const QV4::CompiledData::Binding> d;
+
+ union {
+ ushort *stringData = nullptr;
+ const QV4::CompiledData::Binding *binding;
+ };
+
+ QTypedArrayData<ushort> *arrayData = nullptr;
+ uint stringSize = 0;
};
/*!
diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h
index f65909dcec..1700ff755f 100644
--- a/src/qmlmodels/qqmllistmodelworkeragent_p.h
+++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h
@@ -73,6 +73,7 @@ class QQmlListModelWorkerAgent : public QObject
Q_PROPERTY(int count READ count)
Q_PROPERTY(QV4::ExecutionEngine *engine READ engine WRITE setEngine NOTIFY engineChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQmlListModelWorkerAgent(QQmlListModel *);
diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp
deleted file mode 100644
index 155ded6c65..0000000000
--- a/src/qmlmodels/qqmlmodelsmodule.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml 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 "qqmlmodelsmodule_p.h"
-#include <private/qtqmlmodelsglobal_p.h>
-
-#if QT_CONFIG(qml_list_model)
-#include <private/qqmllistmodel_p.h>
-#include <private/qqmllistmodelworkeragent_p.h>
-#endif
-#if QT_CONFIG(qml_delegate_model)
-#include <private/qqmlabstractdelegatecomponent_p.h>
-#include <private/qqmldelegatemodel_p.h>
-#include <private/qquickpackage_p.h>
-#include <private/qqmlcomponentattached_p.h>
-#endif
-#if QT_CONFIG(qml_object_model)
-#include <private/qqmlobjectmodel_p.h>
-#include <private/qqmlinstantiator_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-void QQmlModelsModule::registerQmlTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
- // Don't convert these to qmlRegisterTypesAndRevisions!
- // -> the annotations in the headers are for the QtQml.Models module <-
-#if QT_CONFIG(qml_object_model)
- qmlRegisterType<QQmlInstantiator>("QtQml", 2, 1, "Instantiator"); // Only available in >= 2.1
- qmlRegisterAnonymousType<QQmlInstanceModel>("QtQml", 2);
-#endif
-}
-
-void QQmlModelsModule::registerQuickTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
- // Don't convert these to qmlRegisterTypesAndRevisions!
- // -> the annotations in the headers are for the QtQml.Models module <-
-
- const char uri[] = "QtQuick";
-
-#if QT_CONFIG(qml_object_model)
- qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator");
- qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2);
- qmlRegisterType<QQmlObjectModel>(uri, 2, 0, "VisualItemModel");
-#endif
-#if QT_CONFIG(qml_list_model)
- qmlRegisterType<QQmlListElement>(uri, 2, 0, "ListElement");
- qmlRegisterCustomType<QQmlListModel>(uri, 2, 0, "ListModel", new QQmlListModelParser);
-#endif
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterType<QQmlDelegateModel>(uri, 2, 0, "VisualDataModel");
- qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 0, "VisualDataGroup");
- qmlRegisterType<QQuickPackage>(uri, 2, 0, "Package");
-#endif
-}
-
-#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-QT_END_NAMESPACE
diff --git a/src/qmlmodels/qqmlmodelsmodule_p.h b/src/qmlmodels/qqmlmodelsmodule_p.h
index feed0f88fe..70268f53f2 100644
--- a/src/qmlmodels/qqmlmodelsmodule_p.h
+++ b/src/qmlmodels/qqmlmodelsmodule_p.h
@@ -61,22 +61,13 @@
QT_BEGIN_NAMESPACE
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlModelsModule
-{
-public:
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- static void registerQmlTypes();
- static void registerQuickTypes();
-#endif
-};
-
#if QT_CONFIG(itemmodel)
struct QItemSelectionModelForeign
{
Q_GADGET
QML_FOREIGN(QItemSelectionModel)
QML_NAMED_ELEMENT(ItemSelectionModel)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
};
#endif
diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp
index 90469d06c2..dac868a0a2 100644
--- a/src/qmlmodels/qqmlobjectmodel.cpp
+++ b/src/qmlmodels/qqmlobjectmodel.cpp
@@ -175,7 +175,8 @@ public:
void clear() {
Q_Q(QQmlObjectModel);
- for (const Item &child : qAsConst(children))
+ const auto copy = children;
+ for (const Item &child : copy)
emit q->destroyingItem(child.item);
remove(0, children.count());
}
@@ -191,6 +192,8 @@ public:
QList<Item> children;
};
+Q_DECLARE_TYPEINFO(QQmlObjectModelPrivate::Item, Q_PRIMITIVE_TYPE);
+
/*!
\qmltype ObjectModel
diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h
index 866d010cd3..761e9c73ec 100644
--- a/src/qmlmodels/qqmlobjectmodel_p.h
+++ b/src/qmlmodels/qqmlobjectmodel_p.h
@@ -70,6 +70,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstanceModel : public QObject
Q_PROPERTY(int count READ count NOTIFY countChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum ReusableFlag {
@@ -104,8 +105,8 @@ Q_SIGNALS:
void createdItem(int index, QObject *object);
void initItem(int index, QObject *object);
void destroyingItem(QObject *object);
- Q_REVISION(15) void itemPooled(int index, QObject *object);
- Q_REVISION(15) void itemReused(int index, QObject *object);
+ Q_REVISION(2, 15) void itemPooled(int index, QObject *object);
+ Q_REVISION(2, 15) void itemReused(int index, QObject *object);
protected:
QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
@@ -125,7 +126,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false)
Q_CLASSINFO("DefaultProperty", "children")
QML_NAMED_ELEMENT(ObjectModel)
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
QML_ATTACHED(QQmlObjectModelAttached)
public:
@@ -146,14 +147,14 @@ public:
static QQmlObjectModelAttached *qmlAttachedProperties(QObject *obj);
- Q_REVISION(3) Q_INVOKABLE QObject *get(int index) const;
- Q_REVISION(3) Q_INVOKABLE void append(QObject *object);
- Q_REVISION(3) Q_INVOKABLE void insert(int index, QObject *object);
- Q_REVISION(3) Q_INVOKABLE void move(int from, int to, int n = 1);
- Q_REVISION(3) Q_INVOKABLE void remove(int index, int n = 1);
+ Q_REVISION(2, 3) Q_INVOKABLE QObject *get(int index) const;
+ Q_REVISION(2, 3) Q_INVOKABLE void append(QObject *object);
+ Q_REVISION(2, 3) Q_INVOKABLE void insert(int index, QObject *object);
+ Q_REVISION(2, 3) Q_INVOKABLE void move(int from, int to, int n = 1);
+ Q_REVISION(2, 3) Q_INVOKABLE void remove(int index, int n = 1);
public Q_SLOTS:
- Q_REVISION(3) void clear();
+ Q_REVISION(2, 3) void clear();
Q_SIGNALS:
void childrenChanged();
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index 6e21f2f389..332a5447b1 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -68,7 +68,7 @@ void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelIt
if (modelItem->contextData) {
modelItem->contextData->invalidate();
- Q_ASSERT(modelItem->contextData->refCount == 1);
+ Q_ASSERT(modelItem->contextData->refCount() == 1);
modelItem->contextData = nullptr;
}
@@ -83,9 +83,9 @@ QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject
{
}
-void QQmlTableInstanceModel::useImportVersion(int minorVersion)
+void QQmlTableInstanceModel::useImportVersion(QTypeRevision version)
{
- m_adaptorModel.useImportVersion(minorVersion);
+ m_adaptorModel.useImportVersion(version);
}
QQmlTableInstanceModel::~QQmlTableInstanceModel()
@@ -330,10 +330,10 @@ void QQmlTableInstanceModel::incubateModelItem(QQmlDelegateModelItem *modelItem,
} else {
modelItem->incubationTask = new QQmlTableInstanceModelIncubationTask(this, modelItem, incubationMode);
- QQmlContextData *ctxt = new QQmlContextData;
QQmlContext *creationContext = modelItem->delegate->creationContext();
- ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
- ctxt->contextObject = modelItem;
+ QQmlRefPointer<QQmlContextData> ctxt = QQmlContextData::createRefCounted(
+ QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
+ ctxt->setContextObject(modelItem);
modelItem->contextData = ctxt;
QQmlComponentPrivate::get(modelItem->delegate)->incubateObject(
diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h
index 0d96d35a5e..defe513ef9 100644
--- a/src/qmlmodels/qqmltableinstancemodel_p.h
+++ b/src/qmlmodels/qqmltableinstancemodel_p.h
@@ -89,7 +89,7 @@ public:
QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr);
~QQmlTableInstanceModel() override;
- void useImportVersion(int minorVersion);
+ void useImportVersion(QTypeRevision version);
int count() const override { return m_adaptorModel.count(); }
int rows() const { return m_adaptorModel.rowCount(); }
diff --git a/src/qmlmodels/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h
index 97f3bab9bc..f40ffe552a 100644
--- a/src/qmlmodels/qquickpackage_p.h
+++ b/src/qmlmodels/qquickpackage_p.h
@@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject
Q_CLASSINFO("DefaultProperty", "data")
QML_NAMED_ELEMENT(Package)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQuickPackageAttached)
Q_PROPERTY(QQmlListProperty<QObject> data READ data)
diff --git a/src/qmltest/.prev_CMakeLists.txt b/src/qmltest/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..e6d8a49d22
--- /dev/null
+++ b/src/qmltest/.prev_CMakeLists.txt
@@ -0,0 +1,73 @@
+# Generated from qmltest.pro.
+
+#####################################################################
+## QuickTest Module:
+#####################################################################
+
+qt_add_module(QuickTest
+ GENERATE_METATYPES
+ QMAKE_MODULE_CONFIG $${QT.testlib.CONFIG}
+ SOURCES
+ qtestoptions_p.h
+ quicktest.cpp quicktest.h quicktest_p.h
+ quicktestglobal.h
+ quicktestresult.cpp quicktestresult_p.h
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_URL_CAST_FROM_STRING
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::QmlPrivate
+ Qt::Quick
+ Qt::QuickPrivate
+ Qt::TestPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Test
+ PRIVATE_MODULE_INTERFACE
+ Qt::TestPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmltest.pro:<TRUE>:
+# MODULE_CONFIG = "$${QT.testlib.CONFIG}"
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/Qt/test/qtestroot"
+# QML_IMPORT_NAME = "Qt.test.qtestroot"
+# QML_IMPORT_VERSION = "1.0"
+# qmldir.files = "$$PWD/qmldir"
+# qmldir.path = "$$QMLTYPES_INSTALL_DIR"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QuickTest CONDITION TARGET Qt::Widgets
+ DEFINES
+ QT_QMLTEST_WITH_WIDGETS
+ PUBLIC_LIBRARIES
+ Qt::Widgets
+)
+
+qt_extend_target(QuickTest CONDITION QT_FEATURE_qml_debug
+ DEFINES
+ QT_QML_DEBUG_NO_WARNING
+)
+
+#### Keys ignored in scope 4:.:.:qmltest.pro:prefix_build:
+# INSTALLS = "qmldir"
+
+#### Keys ignored in scope 5:.:.:qmltest.pro:else:
+# COPIES = "qmldir"
+qt_add_docs(QuickTest
+ doc/qtqmltest.qdocconf
+)
+
+
+set_target_properties(QuickTest PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION 1.0
+ QT_QML_MODULE_URI Qt.test.qtestroot
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/Qt/test/qtestroot"
+)
+
+qt6_qml_type_registration(QuickTest)
diff --git a/src/qmltest/CMakeLists.txt b/src/qmltest/CMakeLists.txt
new file mode 100644
index 0000000000..c75deac6ad
--- /dev/null
+++ b/src/qmltest/CMakeLists.txt
@@ -0,0 +1,82 @@
+# Generated from qmltest.pro.
+
+#####################################################################
+## QuickTest Module:
+#####################################################################
+
+qt_add_module(QuickTest
+ GENERATE_METATYPES
+ QMAKE_MODULE_CONFIG $${QT.testlib.CONFIG}
+ SOURCES
+ qtestoptions_p.h
+ quicktest.cpp quicktest.h quicktest_p.h
+ quicktestglobal.h
+ quicktestresult.cpp quicktestresult_p.h
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_URL_CAST_FROM_STRING
+ QT_BUILD_QMLTEST_LIB # special case
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::QmlPrivate
+ Qt::Quick
+ Qt::QuickPrivate
+ Qt::TestPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Test
+ PRIVATE_MODULE_INTERFACE
+ Qt::TestPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmltest.pro:<TRUE>:
+# MODULE_CONFIG = "$${QT.testlib.CONFIG}"
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/Qt/test/qtestroot"
+# QML_IMPORT_NAME = "Qt.test.qtestroot"
+# QML_IMPORT_VERSION = "1.0"
+# qmldir.files = "$$PWD/qmldir"
+# qmldir.path = "$$QMLTYPES_INSTALL_DIR"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QuickTest CONDITION TARGET Qt::Widgets
+ DEFINES
+ QT_QMLTEST_WITH_WIDGETS
+ PUBLIC_LIBRARIES
+ Qt::Widgets
+)
+
+qt_extend_target(QuickTest CONDITION QT_FEATURE_qml_debug
+ DEFINES
+ QT_QML_DEBUG_NO_WARNING
+)
+
+#### Keys ignored in scope 4:.:.:qmltest.pro:prefix_build:
+# INSTALLS = "qmldir"
+
+#### Keys ignored in scope 5:.:.:qmltest.pro:else:
+# COPIES = "qmldir"
+qt_add_docs(QuickTest
+ doc/qtqmltest.qdocconf
+)
+
+
+set_target_properties(QuickTest PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION 1.0
+ QT_QML_MODULE_URI Qt.test.qtestroot
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/Qt/test/qtestroot"
+)
+
+qt6_qml_type_registration(QuickTest)
+
+#special case begin
+if (QT_WILL_INSTALL)
+ install(FILES qmldir DESTINATION "${INSTALL_QMLDIR}/Qt/test/qtestroot")
+else()
+ file(COPY qmldir DESTINATION "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/Qt/test/qtestroot")
+endif()
+#special case end
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index cfc9221b20..63e51fa4ba 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -52,7 +52,7 @@
#include <QtQml/qqmlpropertymap.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/qquickitem.h>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QtCore/qurl.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
@@ -70,7 +70,7 @@
#include <QtQml/QQmlFileSelector>
#include <private/qqmlcomponent_p.h>
-#include <private/qv4executablecompilationunit_p.h>
+#include <private/qv4resolvedtypereference_p.h>
#ifdef QT_QMLTEST_WITH_WIDGETS
#include <QtWidgets/QApplication>
diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h
index 81b9d78830..7ebfb21186 100644
--- a/src/qmltest/quicktestresult_p.h
+++ b/src/qmltest/quicktestresult_p.h
@@ -158,10 +158,10 @@ public Q_SLOTS:
QObject *grabImage(QQuickItem *item);
- Q_REVISION(1) QObject *findChild(QObject *parent, const QString &objectName);
+ Q_REVISION(1, 1) QObject *findChild(QObject *parent, const QString &objectName);
- Q_REVISION(13) bool isPolishScheduled(QQuickItem *item) const;
- Q_REVISION(13) bool waitForItemPolished(QQuickItem *item, int timeout);
+ Q_REVISION(1, 13) bool isPolishScheduled(QQuickItem *item) const;
+ Q_REVISION(1, 13) bool waitForItemPolished(QQuickItem *item, int timeout);
public:
// Helper functions for the C++ main() shell.
diff --git a/src/qmltyperegistrar/.prev_CMakeLists.txt b/src/qmltyperegistrar/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..c82a0e5a99
--- /dev/null
+++ b/src/qmltyperegistrar/.prev_CMakeLists.txt
@@ -0,0 +1,38 @@
+# Generated from qmltyperegistrar.pro.
+
+#####################################################################
+## qmltyperegistrar Tool:
+#####################################################################
+
+qt_add_tool(qmltyperegistrar
+ SOURCES
+ ../../tools/shared/qmlstreamwriter.cpp ../../tools/shared/qmlstreamwriter.h
+ qmltyperegistrar.cpp
+ qmltypesclassdescription.cpp qmltypesclassdescription.h
+ qmltypescreator.cpp qmltypescreator.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ QT_NO_CAST_TO_ASCII
+ INCLUDE_DIRECTORIES
+ ../../tools/shared
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmltyperegistrar.pro:<TRUE>:
+# QMAKE_TARGET_DESCRIPTION = "QML" "Types" "Registrar"
+# _OPTION = "host_build"
+# build_integration.files = "qmltypes.prf"
+# build_integration.path = "$$[QT_HOST_DATA]/mkspecs/features"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qmltyperegistrar.pro:prefix_build:
+# COPIES = "qmltypes_to_builddir"
+# INSTALLS = "build_integration"
+# qmltypes_to_builddir.files = "qmltypes.prf"
+# qmltypes_to_builddir.path = "$$MODULE_BASE_OUTDIR/mkspecs/features"
+
+#### Keys ignored in scope 3:.:.:qmltyperegistrar.pro:else:
+# COPIES = "build_integration"
diff --git a/src/qmltyperegistrar/CMakeLists.txt b/src/qmltyperegistrar/CMakeLists.txt
new file mode 100644
index 0000000000..487c31d613
--- /dev/null
+++ b/src/qmltyperegistrar/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Generated from qmltyperegistrar.pro.
+
+#####################################################################
+## qmltyperegistrar Tool:
+#####################################################################
+
+qt_add_tool(qmltyperegistrar
+ TOOLS_TARGET Qml # special case
+ SOURCES
+ ../../tools/shared/qmlstreamwriter.cpp ../../tools/shared/qmlstreamwriter.h
+ qmltyperegistrar.cpp
+ qmltypesclassdescription.cpp qmltypesclassdescription.h
+ qmltypescreator.cpp qmltypescreator.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ QT_NO_CAST_TO_ASCII
+ INCLUDE_DIRECTORIES
+ ../../tools/shared
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmltyperegistrar.pro:<TRUE>:
+# QMAKE_TARGET_DESCRIPTION = "QML" "Types" "Registrar"
+# _OPTION = "host_build"
+# build_integration.files = "qmltypes.prf"
+# build_integration.path = "$$[QT_HOST_DATA]/mkspecs/features"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 2:.:.:qmltyperegistrar.pro:prefix_build:
+# COPIES = "qmltypes_to_builddir"
+# INSTALLS = "build_integration"
+# qmltypes_to_builddir.files = "qmltypes.prf"
+# qmltypes_to_builddir.path = "$$MODULE_BASE_OUTDIR/mkspecs/features"
+
+#### Keys ignored in scope 3:.:.:qmltyperegistrar.pro:else:
+# COPIES = "build_integration"
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp
index c3ab61e621..e6b0ee8cd9 100644
--- a/src/qmltyperegistrar/qmltyperegistrar.cpp
+++ b/src/qmltyperegistrar/qmltyperegistrar.cpp
@@ -75,6 +75,35 @@ static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef)
return NoRegistration;
}
+static bool argumentsFromCommandLineAndFile(QStringList &allArguments, const QStringList &arguments)
+{
+ allArguments.reserve(arguments.size());
+ for (const QString &argument : arguments) {
+ // "@file" doesn't start with a '-' so we can't use QCommandLineParser for it
+ if (argument.startsWith(QLatin1Char('@'))) {
+ QString optionsFile = argument;
+ optionsFile.remove(0, 1);
+ if (optionsFile.isEmpty()) {
+ fprintf(stderr, "The @ option requires an input file");
+ return false;
+ }
+ QFile f(optionsFile);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ fprintf(stderr, "Cannot open options file specified with @");
+ return false;
+ }
+ while (!f.atEnd()) {
+ QString line = QString::fromLocal8Bit(f.readLine().trimmed());
+ if (!line.isEmpty())
+ allArguments << line;
+ }
+ } else {
+ allArguments << argument;
+ }
+ }
+ return true;
+}
+
static QVector<QJsonObject> foreignRelatedTypes(const QVector<QJsonObject> &types,
const QVector<QJsonObject> &foreignTypes)
{
@@ -247,7 +276,11 @@ int main(int argc, char **argv)
parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
QStringLiteral("MOC generated json output."));
- parser.process(app);
+ QStringList arguments;
+ if (!argumentsFromCommandLineAndFile(arguments, app.arguments()))
+ return EXIT_FAILURE;
+
+ parser.process(arguments);
FILE *output = stdout;
QScopedPointer<FILE, ScopedPointerFileCloser> outputFile;
@@ -406,8 +439,8 @@ int main(int argc, char **argv)
qPrintable(module), qPrintable(majorVersion),
qPrintable(parser.value(minorVersionOption)));
fprintf(output, "\n}\n");
- fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s, %s);\n",
- qPrintable(module), qPrintable(majorVersion), qPrintable(functionName));
+ fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s);\n",
+ qPrintable(module), qPrintable(functionName));
if (!parser.isSet(pluginTypesOption))
return EXIT_SUCCESS;
@@ -456,7 +489,7 @@ int main(int argc, char **argv)
creator.setOwnTypes(std::move(types));
creator.setForeignTypes(std::move(foreignTypes));
creator.setModule(module);
- creator.setMajorVersion(parser.value(majorVersionOption).toInt());
+ creator.setVersion(QTypeRevision::fromVersion(parser.value(majorVersionOption).toInt(), 0));
creator.generate(parser.value(pluginTypesOption), parser.value(dependenciesOption));
return EXIT_SUCCESS;
diff --git a/src/qmltyperegistrar/qmltyperegistrar.pro b/src/qmltyperegistrar/qmltyperegistrar.pro
index dff8f00ca3..7ed3986dd7 100644
--- a/src/qmltyperegistrar/qmltyperegistrar.pro
+++ b/src/qmltyperegistrar/qmltyperegistrar.pro
@@ -8,11 +8,13 @@ QMAKE_TARGET_DESCRIPTION = QML Types Registrar
include(../../tools/shared/shared.pri)
SOURCES += \
+ $$QMLSTREAMWRITER_SOURCES \
qmltyperegistrar.cpp \
qmltypesclassdescription.cpp \
qmltypescreator.cpp
HEADERS += \
+ $$QMLSTREAMWRITER_HEADERS \
qmltypesclassdescription.h \
qmltypescreator.h
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp
index 9aadd75acc..2214758f38 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.cpp
+++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp
@@ -27,18 +27,19 @@
****************************************************************************/
#include "qmltypesclassdescription.h"
+#include "qmltypescreator.h"
#include <QtCore/qjsonarray.h>
static void collectExtraVersions(const QJsonObject *component, const QString &key,
- QList<int> &extraVersions)
+ QList<QTypeRevision> &extraVersions)
{
const QJsonArray &items = component->value(key).toArray();
for (const QJsonValue &item : items) {
const QJsonObject obj = item.toObject();
const auto revision = obj.find(QLatin1String("revision"));
if (revision != obj.end()) {
- const int extraVersion = revision.value().toInt();
+ const auto extraVersion = QTypeRevision::fromEncodedVersion(revision.value().toInt());
if (!extraVersions.contains(extraVersion))
extraVersions.append(extraVersion);
}
@@ -60,7 +61,7 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject>
void QmlTypesClassDescription::collect(const QJsonObject *classDef,
const QVector<QJsonObject> &types,
const QVector<QJsonObject> &foreign,
- CollectMode mode)
+ CollectMode mode, QTypeRevision defaultRevision)
{
const QJsonObject *origClassDef = classDef; // if we find QML.Foreign, classDef changes.
if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool())
@@ -74,12 +75,13 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
if (name == QLatin1String("DefaultProperty")) {
if (mode != AttachedType && defaultProp.isEmpty())
defaultProp = value;
- } else if (name == QLatin1String("QML.AddedInMinorVersion")) {
+ } else if (name == QLatin1String("QML.AddedInVersion")) {
+ const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt());
if (mode == TopLevel) {
- addedInRevision = value.toInt();
- revisions.append(value.toInt());
+ addedInRevision = revision;
+ revisions.append(revision);
} else if (!elementName.isEmpty()) {
- revisions.append(value.toInt());
+ revisions.append(revision);
}
}
@@ -92,12 +94,12 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
elementName = classDef->value(QLatin1String("className")).toString();
else if (value != QLatin1String("anonymous"))
elementName = value;
- } else if (name == QLatin1String("QML.RemovedInMinorVersion")) {
- removedInRevision = value.toInt();
+ } else if (name == QLatin1String("QML.RemovedInVersion")) {
+ removedInRevision = QTypeRevision::fromEncodedVersion(value.toInt());
} else if (name == QLatin1String("QML.Creatable")) {
isCreatable = (value != QLatin1String("false"));
} else if (name == QLatin1String("QML.Attached")) {
- collectAttached(value, types, foreign);
+ collectAttached(value, types, foreign, defaultRevision);
} else if (name == QLatin1String("QML.Singleton")) {
if (value == QLatin1String("true"))
isSingleton = true;
@@ -113,8 +115,11 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
if (defaultProp.isEmpty() && foreignName == QLatin1String("DefaultProperty"))
defaultProp = foreignValue;
else if (foreignName == QLatin1String("QML.Attached"))
- collectAttached(foreignValue, types, foreign);
+ collectAttached(foreignValue, types, foreign, defaultRevision);
}
+ } else {
+ // The foreign type does not have a meta object: We only override the name.
+ className = value;
}
} else if (name == QLatin1String("QML.Root")) {
isRootClass = true;
@@ -143,10 +148,11 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) {
const QString superName = superObject[QLatin1String("name")].toString();
+ const CollectMode superMode = (mode == TopLevel) ? SuperClass : AttachedType;
if (const QJsonObject *other = findType(types, superName))
- collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType);
+ collect(other, types, foreign, superMode, defaultRevision);
else if (const QJsonObject *other = findType(foreign, superName))
- collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType);
+ collect(other, types, foreign, superMode, defaultRevision);
else // If we cannot locate a type for it, there is no point in recording the superClass
continue;
@@ -158,17 +164,20 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
if (mode != TopLevel)
return;
- if (addedInRevision == -1) {
- revisions.append(0);
- addedInRevision = 0;
+ if (!addedInRevision.isValid()) {
+ revisions.append(defaultRevision);
+ addedInRevision = defaultRevision;
+ } else if (addedInRevision < defaultRevision) {
+ revisions.append(defaultRevision);
}
- std::sort(revisions.begin(), revisions.end(),
- [](int a, int b) { return QByteArray::number(a) < QByteArray::number(b); });
+ std::sort(revisions.begin(), revisions.end());
const auto end = std::unique(revisions.begin(), revisions.end());
revisions.erase(end, revisions.end());
resolvedClass = classDef;
+ if (className.isEmpty() && mode == TopLevel)
+ className = classDef->value(QLatin1String("qualifiedClassName")).toString();
// If it's not a QObject, it's not creatable
isCreatable = isCreatable && classDef->value(QLatin1String("object")).toBool();
@@ -176,11 +185,12 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
void QmlTypesClassDescription::collectAttached(const QString &attached,
const QVector<QJsonObject> &types,
- const QVector<QJsonObject> &foreign)
+ const QVector<QJsonObject> &foreign,
+ QTypeRevision defaultRevision)
{
attachedType = attached;
if (const QJsonObject *other = findType(types, attachedType))
- collect(other, types, foreign, AttachedType);
+ collect(other, types, foreign, AttachedType, defaultRevision);
else if (const QJsonObject *other = findType(foreign, attachedType))
- collect(other, types, foreign, AttachedType);
+ collect(other, types, foreign, AttachedType, defaultRevision);
}
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h
index 32313a490d..ed4ba49592 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.h
+++ b/src/qmltyperegistrar/qmltypesclassdescription.h
@@ -33,18 +33,20 @@
#include <QtCore/qjsonobject.h>
#include <QtCore/qvector.h>
#include <QtCore/qset.h>
+#include <QtCore/qversionnumber.h>
struct QmlTypesClassDescription
{
const QJsonObject *resolvedClass = nullptr;
QString file;
+ QString className;
QString elementName;
QString defaultProp;
QString superClass;
QString attachedType;
- QList<int> revisions;
- int addedInRevision = -1;
- int removedInRevision = -1;
+ QList<QTypeRevision> revisions;
+ QTypeRevision addedInRevision;
+ QTypeRevision removedInRevision;
bool isCreatable = true;
bool isSingleton = false;
bool isRootClass = false;
@@ -57,9 +59,10 @@ struct QmlTypesClassDescription
};
void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types,
- const QVector<QJsonObject> &foreign, CollectMode mode);
+ const QVector<QJsonObject> &foreign, CollectMode mode,
+ QTypeRevision defaultRevision);
void collectAttached(const QString &attached, const QVector<QJsonObject> &types,
- const QVector<QJsonObject> &foreign);
+ const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision);
static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name);
};
diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp
index e74550c6c2..a9885b03fa 100644
--- a/src/qmltyperegistrar/qmltypescreator.cpp
+++ b/src/qmltyperegistrar/qmltypescreator.cpp
@@ -35,6 +35,7 @@
#include <QtCore/qsavefile.h>
#include <QtCore/qfile.h>
#include <QtCore/qjsondocument.h>
+#include <QtCore/qversionnumber.h>
static QString enquote(const QString &string)
{
@@ -47,10 +48,7 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle
{
if (!collector.file.isEmpty())
m_qml.writeScriptBinding(QLatin1String("file"), enquote(collector.file));
- m_qml.writeScriptBinding(
- QLatin1String("name"),
- enquote(collector.resolvedClass->value(
- QLatin1String("qualifiedClassName")).toString()));
+ m_qml.writeScriptBinding(QLatin1String("name"), enquote(collector.className));
if (!collector.defaultProp.isEmpty())
m_qml.writeScriptBinding(QLatin1String("defaultProperty"), enquote(collector.defaultProp));
@@ -64,24 +62,24 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle
QStringList exports;
QStringList metaObjects;
+ if (collector.isBuiltin) {
+ exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName)));
+ metaObjects.append(QString::number(QTypeRevision::fromVersion(1, 0).toEncodedVersion<quint16>()));
+ }
+
for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) {
- const int revision = *it;
+ const QTypeRevision revision = *it;
if (revision < collector.addedInRevision)
continue;
- if (collector.removedInRevision > collector.addedInRevision
- && revision >= collector.removedInRevision) {
+ if (collector.removedInRevision.isValid() && !(revision < collector.removedInRevision))
break;
- }
-
- if (collector.isBuiltin) {
- exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName)));
- metaObjects.append(QLatin1String("0"));
- }
exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4")
- .arg(m_module).arg(collector.elementName)
- .arg(m_majorVersion).arg(revision)));
- metaObjects.append(QString::number(revision));
+ .arg(m_module).arg(collector.elementName)
+ .arg(revision.hasMajorVersion() ? revision.majorVersion()
+ : m_version.majorVersion())
+ .arg(revision.minorVersion())));
+ metaObjects.append(QString::number(revision.toEncodedVersion<quint16>()));
}
m_qml.writeArrayBinding(QLatin1String("exports"), exports);
@@ -267,7 +265,7 @@ void QmlTypesCreator::writeComponents()
QmlTypesClassDescription collector;
collector.collect(&component, m_ownTypes, m_foreignTypes,
- QmlTypesClassDescription::TopLevel);
+ QmlTypesClassDescription::TopLevel, m_version);
writeClassProperties(collector);
diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h
index 9207a64b7e..808c189323 100644
--- a/src/qmltyperegistrar/qmltypescreator.h
+++ b/src/qmltyperegistrar/qmltypescreator.h
@@ -45,7 +45,7 @@ public:
void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); }
void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); }
void setModule(QString module) { m_module = std::move(module); }
- void setMajorVersion(int majorVersion) { m_majorVersion = majorVersion; }
+ void setVersion(QTypeRevision version) { m_version = version; }
private:
void writeClassProperties(const QmlTypesClassDescription &collector);
@@ -62,7 +62,7 @@ private:
QVector<QJsonObject> m_ownTypes;
QVector<QJsonObject> m_foreignTypes;
QString m_module;
- int m_majorVersion = 0;
+ QTypeRevision m_version = QTypeRevision::zero();
};
#endif // QMLTYPESCREATOR_H
diff --git a/src/qmlworkerscript/.prev_CMakeLists.txt b/src/qmlworkerscript/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..ad1a578f14
--- /dev/null
+++ b/src/qmlworkerscript/.prev_CMakeLists.txt
@@ -0,0 +1,114 @@
+# Generated from qmlworkerscript.pro.
+
+#####################################################################
+## QmlWorkerScript Module:
+#####################################################################
+
+qt_add_module(QmlWorkerScript
+ GENERATE_METATYPES
+ SOURCES
+ qquickworkerscript.cpp qquickworkerscript_p.h
+ qtqmlworkerscriptglobal.h qtqmlworkerscriptglobal_p.h
+ qv4serialize.cpp qv4serialize_p.h
+ DEFINES
+ BUILDING_QT__
+ ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
+ ENABLE_DFG_JIT=0
+ ENABLE_DFG_JIT_UTILITY_METHODS=1
+ ENABLE_JIT_CONSTANT_BLINDING=0
+ ENABLE_LLINT=0
+ JS_EXPORT_PRIVATE=""
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ WTFInvokeCrashHook=qmlWTFInvokeCrashHook
+ WTFReportAssertionFailure=qmlWTFReportAssertionFailure
+ WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
+ WTFReportBacktrace=qmlWTFReportBacktrace
+ WTF_EXPORT_PRIVATE=""
+ INCLUDE_DIRECTORIES
+ ../3rdparty/masm
+ ../3rdparty/masm/assembler
+ ../3rdparty/masm/disassembler
+ ../3rdparty/masm/disassembler/udis86
+ ../3rdparty/masm/jit
+ ../3rdparty/masm/runtime
+ ../3rdparty/masm/stubs
+ ../3rdparty/masm/stubs/runtime
+ ../3rdparty/masm/stubs/wtf
+ ../3rdparty/masm/wtf
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Qml
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmlworkerscript.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQml/WorkerScript"
+# QML_IMPORT_NAME = "QtQml.WorkerScript"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QmlWorkerScript CONDITION WIN32
+ DEFINES
+ NOMINMAX
+)
+
+qt_extend_target(QmlWorkerScript CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64"))
+ DEFINES
+ WTF_USE_UDIS86=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler
+ DEFINES
+ WTF_USE_ARMV7_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler
+ DEFINES
+ WTF_USE_ARM64_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler
+ DEFINES
+ WTF_USE_MIPS32_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION NOT disassembler
+ DEFINES
+ WTF_USE_UDIS86=0
+)
+
+qt_extend_target(QmlWorkerScript CONDITION CMAKE_BUILD_TYPE STREQUAL Release
+ DEFINES
+ NDEBUG
+)
+
+qt_extend_target(QmlWorkerScript CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC
+ COMPILE_OPTIONS
+ -Wno-expansion-to-defined
+)
+
+#### Keys ignored in scope 12:.:../3rdparty/masm:../3rdparty/masm/masm-defs.pri:(QT_COMPILER_VERSION_MAJOR STRGREATER 6):
+# QMAKE_CXXFLAGS_WARN_ON = "-Wno-expansion-to-defined"
+qt_add_docs(QmlWorkerScript
+ doc/qtqmlworkerscript.qdocconf
+)
+
+
+set_target_properties(QmlWorkerScript PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQml.WorkerScript
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQml/WorkerScript"
+)
+
+qt6_qml_type_registration(QmlWorkerScript)
diff --git a/src/qmlworkerscript/CMakeLists.txt b/src/qmlworkerscript/CMakeLists.txt
new file mode 100644
index 0000000000..e85d1174e1
--- /dev/null
+++ b/src/qmlworkerscript/CMakeLists.txt
@@ -0,0 +1,114 @@
+# Generated from qmlworkerscript.pro.
+
+#####################################################################
+## QmlWorkerScript Module:
+#####################################################################
+
+qt_add_module(QmlWorkerScript
+ GENERATE_METATYPES
+ SOURCES
+ qquickworkerscript.cpp qquickworkerscript_p.h
+ qtqmlworkerscriptglobal.h qtqmlworkerscriptglobal_p.h
+ qv4serialize.cpp qv4serialize_p.h
+ DEFINES
+ BUILDING_QT__
+ ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
+ ENABLE_DFG_JIT=0
+ ENABLE_DFG_JIT_UTILITY_METHODS=1
+ ENABLE_JIT_CONSTANT_BLINDING=0
+ ENABLE_LLINT=0
+ JS_EXPORT_PRIVATE= # special case
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ WTFInvokeCrashHook=qmlWTFInvokeCrashHook
+ WTFReportAssertionFailure=qmlWTFReportAssertionFailure
+ WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
+ WTFReportBacktrace=qmlWTFReportBacktrace
+ WTF_EXPORT_PRIVATE= # special case
+ INCLUDE_DIRECTORIES
+ ../3rdparty/masm
+ ../3rdparty/masm/assembler
+ ../3rdparty/masm/disassembler
+ ../3rdparty/masm/disassembler/udis86
+ ../3rdparty/masm/jit
+ ../3rdparty/masm/runtime
+ ../3rdparty/masm/stubs
+ ../3rdparty/masm/stubs/runtime
+ ../3rdparty/masm/stubs/wtf
+ ../3rdparty/masm/wtf
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::QmlPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Qml
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::QmlPrivate
+)
+
+#### Keys ignored in scope 1:.:.:qmlworkerscript.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQml/WorkerScript"
+# QML_IMPORT_NAME = "QtQml.WorkerScript"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QmlWorkerScript CONDITION WIN32
+ DEFINES
+ NOMINMAX
+)
+
+qt_extend_target(QmlWorkerScript CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64"))
+ DEFINES
+ WTF_USE_UDIS86=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler
+ DEFINES
+ WTF_USE_ARMV7_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler
+ DEFINES
+ WTF_USE_ARM64_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler
+ DEFINES
+ WTF_USE_MIPS32_DISASSEMBLER=1
+)
+
+qt_extend_target(QmlWorkerScript CONDITION NOT disassembler
+ DEFINES
+ WTF_USE_UDIS86=0
+)
+
+qt_extend_target(QmlWorkerScript CONDITION CMAKE_BUILD_TYPE STREQUAL Release
+ DEFINES
+ NDEBUG
+)
+
+qt_extend_target(QmlWorkerScript CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC
+ COMPILE_OPTIONS
+ -Wno-expansion-to-defined
+)
+
+#### Keys ignored in scope 12:.:../3rdparty/masm:../3rdparty/masm/masm-defs.pri:(QT_COMPILER_VERSION_MAJOR STRGREATER 6):
+# QMAKE_CXXFLAGS_WARN_ON = "-Wno-expansion-to-defined"
+qt_add_docs(QmlWorkerScript
+ doc/qtqmlworkerscript.qdocconf
+)
+
+
+set_target_properties(QmlWorkerScript PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQml.WorkerScript
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQml/WorkerScript"
+)
+
+qt6_qml_type_registration(QmlWorkerScript)
diff --git a/src/qmlworkerscript/qmlworkerscript.pro b/src/qmlworkerscript/qmlworkerscript.pro
index 84466062e1..82b61ab12e 100644
--- a/src/qmlworkerscript/qmlworkerscript.pro
+++ b/src/qmlworkerscript/qmlworkerscript.pro
@@ -6,23 +6,21 @@ QMAKE_DOCS = $$PWD/doc/qtqmlworkerscript.qdocconf
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FOREACH
HEADERS += \
- qqmlworkerscriptmodule_p.h \
qquickworkerscript_p.h \
qtqmlworkerscriptglobal.h \
qtqmlworkerscriptglobal_p.h \
qv4serialize_p.h
SOURCES += \
- qqmlworkerscriptmodule.cpp \
qquickworkerscript.cpp \
qv4serialize.cpp
include(../3rdparty/masm/masm-defs.pri)
QMLTYPES_FILENAME = plugins.qmltypes
-QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript.2
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript
QML_IMPORT_NAME = QtQml.WorkerScript
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
load(qt_module)
diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp b/src/qmlworkerscript/qqmlworkerscriptmodule.cpp
deleted file mode 100644
index f6ad5b87e8..0000000000
--- a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml 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 "qqmlworkerscriptmodule_p.h"
-#include "qquickworkerscript_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-void QQmlWorkerScriptModule::registerQuickTypes()
-{
- // Don't add anything here. These are only for backwards compatibility.
- // Also, don't convert to qmlRegisterTypesAndRevisions as that will add future revisions.
- const char uri[] = "QtQuick";
- qmlRegisterType<QQuickWorkerScript>(uri, 2, 0, "WorkerScript");
-}
-
-#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-QT_END_NAMESPACE
diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp
index 20294d7ba7..705c6015a2 100644
--- a/src/qmlworkerscript/qquickworkerscript.cpp
+++ b/src/qmlworkerscript/qquickworkerscript.cpp
@@ -41,6 +41,7 @@
#include "qquickworkerscript_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlexpression_p.h>
+#include <private/qjsvalue_p.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
@@ -644,7 +645,8 @@ bool QQuickWorkerScript::event(QEvent *event)
if (QQmlEngine *engine = qmlEngine(this)) {
QV4::ExecutionEngine *v4 = engine->handle();
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
- emit message(QJSValue(v4, QV4::Serialize::deserialize(workerEvent->data(), v4)));
+ emit message(QJSValuePrivate::fromReturnedValue(
+ QV4::Serialize::deserialize(workerEvent->data(), v4)));
}
return true;
} else if (event->type() == (QEvent::Type)WorkerErrorEvent::WorkerError) {
diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h
index e56ce84b6d..d1ea34422a 100644
--- a/src/qmlworkerscript/qquickworkerscript_p.h
+++ b/src/qmlworkerscript/qquickworkerscript_p.h
@@ -88,9 +88,10 @@ class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserSt
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(bool ready READ ready NOTIFY readyChanged REVISION 15)
+ Q_PROPERTY(bool ready READ ready NOTIFY readyChanged REVISION(2, 15))
QML_NAMED_ELEMENT(WorkerScript);
+ QML_ADDED_IN_VERSION(2, 0)
Q_INTERFACES(QQmlParserStatus)
public:
@@ -107,7 +108,7 @@ public Q_SLOTS:
Q_SIGNALS:
void sourceChanged();
- Q_REVISION(15) void readyChanged();
+ Q_REVISION(2, 15) void readyChanged();
void message(const QJSValue &messageObject);
protected:
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
new file mode 100644
index 0000000000..0b0c3e0538
--- /dev/null
+++ b/src/quick/CMakeLists.txt
@@ -0,0 +1,622 @@
+# Generated from quick.pro.
+
+#####################################################################
+## Quick Module:
+#####################################################################
+
+qt_add_module(Quick
+ GENERATE_METATYPES
+ PLUGIN_TYPES scenegraph
+ SOURCES
+ handlers/qquickdragaxis.cpp handlers/qquickdragaxis_p.h
+ handlers/qquickdraghandler.cpp handlers/qquickdraghandler_p.h
+ handlers/qquickhandlerpoint.cpp handlers/qquickhandlerpoint_p.h
+ handlers/qquickhoverhandler.cpp handlers/qquickhoverhandler_p.h
+ handlers/qquickmultipointhandler.cpp handlers/qquickmultipointhandler_p.h
+ handlers/qquickmultipointhandler_p_p.h
+ handlers/qquickpinchhandler.cpp handlers/qquickpinchhandler_p.h
+ handlers/qquickpointerdevicehandler.cpp handlers/qquickpointerdevicehandler_p.h
+ handlers/qquickpointerdevicehandler_p_p.h
+ handlers/qquickpointerhandler.cpp handlers/qquickpointerhandler_p.h
+ handlers/qquickpointerhandler_p_p.h
+ handlers/qquickpointhandler.cpp handlers/qquickpointhandler_p.h
+ handlers/qquicksinglepointhandler.cpp handlers/qquicksinglepointhandler_p.h
+ handlers/qquicksinglepointhandler_p_p.h
+ handlers/qquicktaphandler.cpp handlers/qquicktaphandler_p.h
+ items/qquickabstractpaletteprovider_p.h
+ items/qquickaccessibleattached.cpp items/qquickaccessibleattached_p.h
+ items/qquickanchors.cpp items/qquickanchors_p.h
+ items/qquickanchors_p_p.h
+ items/qquickborderimage.cpp items/qquickborderimage_p.h
+ items/qquickborderimage_p_p.h
+ items/qquickclipnode.cpp items/qquickclipnode_p.h
+ items/qquickcolorgroup.cpp items/qquickcolorgroup_p.h
+ items/qquickevents.cpp
+ items/qquickevents_p_p.h
+ items/qquickflickable.cpp items/qquickflickable_p.h
+ items/qquickflickable_p_p.h
+ items/qquickflickablebehavior_p.h
+ items/qquickfocusscope.cpp items/qquickfocusscope_p.h
+ items/qquickgraphicsdevice.cpp items/qquickgraphicsdevice.h items/qquickgraphicsdevice_p.h
+ items/qquickgraphicsinfo.cpp items/qquickgraphicsinfo_p.h
+ items/qquickimage.cpp items/qquickimage_p.h
+ items/qquickimage_p_p.h
+ items/qquickimagebase.cpp items/qquickimagebase_p.h
+ items/qquickimagebase_p_p.h
+ items/qquickimplicitsizeitem.cpp items/qquickimplicitsizeitem_p.h
+ items/qquickimplicitsizeitem_p_p.h
+ items/qquickitem.cpp items/qquickitem.h items/qquickitem_p.h
+ items/qquickitemanimation.cpp items/qquickitemanimation_p.h
+ items/qquickitemanimation_p_p.h
+ items/qquickitemchangelistener_p.h
+ items/qquickitemgrabresult.cpp items/qquickitemgrabresult.h
+ items/qquickitemsmodule.cpp items/qquickitemsmodule_p.h
+ items/qquickloader.cpp items/qquickloader_p.h
+ items/qquickloader_p_p.h
+ items/qquickmousearea.cpp items/qquickmousearea_p.h
+ items/qquickmousearea_p_p.h
+ items/qquickmultipointtoucharea.cpp items/qquickmultipointtoucharea_p.h
+ items/qquickpainteditem.cpp items/qquickpainteditem.h items/qquickpainteditem_p.h
+ items/qquickpalette.cpp items/qquickpalette_p.h
+ items/qquickpalettecolorprovider.cpp items/qquickpalettecolorprovider_p.h
+ items/qquickpaletteproviderprivatebase_p.h
+ items/qquickpincharea.cpp items/qquickpincharea_p.h
+ items/qquickpincharea_p_p.h
+ items/qquickrectangle.cpp items/qquickrectangle_p.h
+ items/qquickrectangle_p_p.h
+ items/qquickrendercontrol.cpp items/qquickrendercontrol.h items/qquickrendercontrol_p.h
+ items/qquickrendertarget.cpp items/qquickrendertarget.h items/qquickrendertarget_p.h
+ items/qquickscalegrid.cpp
+ items/qquickscalegrid_p_p.h
+ items/qquickscreen.cpp items/qquickscreen_p.h
+ items/qquickstateoperations.cpp items/qquickstateoperations_p.h
+ items/qquicktext.cpp items/qquicktext_p.h
+ items/qquicktext_p_p.h
+ items/qquicktextcontrol.cpp items/qquicktextcontrol_p.h
+ items/qquicktextcontrol_p_p.h
+ items/qquicktextdocument.cpp items/qquicktextdocument.h items/qquicktextdocument_p.h
+ items/qquicktextedit.cpp items/qquicktextedit_p.h
+ items/qquicktextedit_p_p.h
+ items/qquicktextinput.cpp items/qquicktextinput_p.h
+ items/qquicktextinput_p_p.h
+ items/qquicktextnode.cpp items/qquicktextnode_p.h
+ items/qquicktextnodeengine.cpp items/qquicktextnodeengine_p.h
+ items/qquicktextutil.cpp items/qquicktextutil_p.h
+ items/qquicktranslate.cpp items/qquicktranslate_p.h
+ items/qquickview.cpp items/qquickview.h items/qquickview_p.h
+ items/qquickwindow.cpp items/qquickwindow.h items/qquickwindow_p.h
+ items/qquickwindowattached.cpp items/qquickwindowattached_p.h
+ items/qquickwindowmodule.cpp items/qquickwindowmodule_p.h
+ items/qquickwindowmodule_p_p.h
+ qtquick2.cpp qtquick2_p.h
+ qtquickglobal.h qtquickglobal_p.h
+ scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+ scenegraph/adaptations/software/qsgsoftwareadaptation.cpp scenegraph/adaptations/software/qsgsoftwareadaptation_p.h
+ scenegraph/adaptations/software/qsgsoftwarecontext.cpp scenegraph/adaptations/software/qsgsoftwarecontext_p.h
+ scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp scenegraph/adaptations/software/qsgsoftwareglyphnode_p.h
+ scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h
+ scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
+ scenegraph/adaptations/software/qsgsoftwarelayer.cpp scenegraph/adaptations/software/qsgsoftwarelayer_p.h
+ scenegraph/adaptations/software/qsgsoftwarepainternode.cpp scenegraph/adaptations/software/qsgsoftwarepainternode_p.h
+ scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h
+ scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h
+ scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
+ scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h
+ scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h
+ scenegraph/adaptations/software/qsgsoftwarerenderer.cpp scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
+ scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h
+ scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h
+ scenegraph/coreapi/qsgabstractrenderer.cpp scenegraph/coreapi/qsgabstractrenderer_p.h
+ scenegraph/coreapi/qsgabstractrenderer_p_p.h
+ scenegraph/coreapi/qsggeometry.cpp scenegraph/coreapi/qsggeometry.h scenegraph/coreapi/qsggeometry_p.h
+ scenegraph/coreapi/qsgmaterial.cpp scenegraph/coreapi/qsgmaterial.h
+ scenegraph/coreapi/qsgmaterialrhishader.cpp scenegraph/coreapi/qsgmaterialrhishader.h scenegraph/coreapi/qsgmaterialrhishader_p.h
+ scenegraph/coreapi/qsgmaterialshader.cpp scenegraph/coreapi/qsgmaterialshader.h scenegraph/coreapi/qsgmaterialshader_p.h
+ scenegraph/coreapi/qsgmaterialtype.h
+ scenegraph/coreapi/qsgnode.cpp scenegraph/coreapi/qsgnode.h scenegraph/coreapi/qsgnode_p.h
+ scenegraph/coreapi/qsgnodeupdater.cpp scenegraph/coreapi/qsgnodeupdater_p.h
+ scenegraph/coreapi/qsgrenderer.cpp scenegraph/coreapi/qsgrenderer_p.h
+ scenegraph/coreapi/qsgrendererinterface.cpp scenegraph/coreapi/qsgrendererinterface.h
+ scenegraph/coreapi/qsgrendernode.cpp scenegraph/coreapi/qsgrendernode.h scenegraph/coreapi/qsgrendernode_p.h
+ scenegraph/coreapi/qsgtexture.cpp scenegraph/coreapi/qsgtexture.h scenegraph/coreapi/qsgtexture_p.h
+ scenegraph/qsgadaptationlayer.cpp scenegraph/qsgadaptationlayer_p.h
+ scenegraph/qsgbasicglyphnode.cpp scenegraph/qsgbasicglyphnode_p.h
+ scenegraph/qsgbasicinternalimagenode.cpp scenegraph/qsgbasicinternalimagenode_p.h
+ scenegraph/qsgbasicinternalrectanglenode.cpp scenegraph/qsgbasicinternalrectanglenode_p.h
+ scenegraph/qsgcontext.cpp scenegraph/qsgcontext_p.h
+ scenegraph/qsgcontextplugin.cpp scenegraph/qsgcontextplugin_p.h
+ scenegraph/qsgrenderloop.cpp scenegraph/qsgrenderloop_p.h
+ scenegraph/qsgrhisupport.cpp scenegraph/qsgrhisupport_p.h
+ scenegraph/util/qsgareaallocator.cpp scenegraph/util/qsgareaallocator_p.h
+ scenegraph/util/qsgflatcolormaterial.cpp scenegraph/util/qsgflatcolormaterial.h
+ scenegraph/util/qsgimagenode.cpp scenegraph/util/qsgimagenode.h
+ scenegraph/util/qsgninepatchnode.cpp scenegraph/util/qsgninepatchnode.h
+ scenegraph/util/qsgplaintexture.cpp scenegraph/util/qsgplaintexture_p.h
+ scenegraph/util/qsgrectanglenode.cpp scenegraph/util/qsgrectanglenode.h
+ scenegraph/util/qsgsimplerectnode.cpp scenegraph/util/qsgsimplerectnode.h
+ scenegraph/util/qsgsimpletexturenode.cpp scenegraph/util/qsgsimpletexturenode.h
+ scenegraph/util/qsgtexturematerial.cpp scenegraph/util/qsgtexturematerial.h scenegraph/util/qsgtexturematerial_p.h
+ scenegraph/util/qsgtextureprovider.cpp scenegraph/util/qsgtextureprovider.h
+ scenegraph/util/qsgtexturereader.cpp scenegraph/util/qsgtexturereader_p.h
+ scenegraph/util/qsgvertexcolormaterial.cpp scenegraph/util/qsgvertexcolormaterial.h
+ util/qquickanimation.cpp util/qquickanimation_p.h
+ util/qquickanimation_p_p.h
+ util/qquickanimationcontroller.cpp util/qquickanimationcontroller_p.h
+ util/qquickanimator.cpp util/qquickanimator_p.h
+ util/qquickanimator_p_p.h
+ util/qquickanimatorcontroller.cpp util/qquickanimatorcontroller_p.h
+ util/qquickanimatorjob.cpp util/qquickanimatorjob_p.h
+ util/qquickapplication.cpp util/qquickapplication_p.h
+ util/qquickbehavior.cpp util/qquickbehavior_p.h
+ util/qquickfontloader.cpp util/qquickfontloader_p.h
+ util/qquickfontmetrics.cpp util/qquickfontmetrics_p.h
+ util/qquickforeignutils_p.h
+ util/qquickglobal.cpp
+ util/qquickimageprovider.cpp util/qquickimageprovider.h util/qquickimageprovider_p.h
+ util/qquickpixmapcache.cpp util/qquickpixmapcache_p.h
+ util/qquickprofiler_p.h
+ util/qquickpropertychanges.cpp util/qquickpropertychanges_p.h
+ util/qquicksmoothedanimation.cpp util/qquicksmoothedanimation_p.h
+ util/qquicksmoothedanimation_p_p.h
+ util/qquickspringanimation.cpp util/qquickspringanimation_p.h
+ util/qquickstate.cpp util/qquickstate_p.h
+ util/qquickstate_p_p.h
+ util/qquickstatechangescript.cpp util/qquickstatechangescript_p.h
+ util/qquickstategroup.cpp util/qquickstategroup_p.h
+ util/qquickstyledtext.cpp util/qquickstyledtext_p.h
+ util/qquicksvgparser.cpp util/qquicksvgparser_p.h
+ util/qquicksystempalette.cpp util/qquicksystempalette_p.h
+ util/qquicktextmetrics.cpp util/qquicktextmetrics_p.h
+ util/qquicktimeline.cpp
+ util/qquicktimeline_p_p.h
+ util/qquicktransition.cpp util/qquicktransition_p.h
+ util/qquicktransitionmanager.cpp
+ util/qquicktransitionmanager_p_p.h
+ util/qquickvalidator.cpp util/qquickvalidator_p.h
+ util/qquickvaluetypes.cpp util/qquickvaluetypes_p.h
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::QmlModels
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlModelsPrivate
+ Qt::QmlPrivate
+)
+
+# Resources:
+set(scenegraph_resource_files
+ "shaders/24bittextmask.frag"
+ "shaders/24bittextmask_core.frag"
+ "shaders/32bitcolortext.frag"
+ "shaders/32bitcolortext_core.frag"
+ "shaders/8bittextmask.frag"
+ "shaders/8bittextmask_core.frag"
+ "shaders/distancefieldoutlinetext.frag"
+ "shaders/distancefieldoutlinetext_core.frag"
+ "shaders/distancefieldshiftedtext.frag"
+ "shaders/distancefieldshiftedtext.vert"
+ "shaders/distancefieldshiftedtext_core.frag"
+ "shaders/distancefieldshiftedtext_core.vert"
+ "shaders/distancefieldtext.frag"
+ "shaders/distancefieldtext.vert"
+ "shaders/distancefieldtext_core.frag"
+ "shaders/distancefieldtext_core.vert"
+ "shaders/flatcolor.frag"
+ "shaders/flatcolor.vert"
+ "shaders/flatcolor_core.frag"
+ "shaders/flatcolor_core.vert"
+ "shaders/hiqsubpixeldistancefieldtext.frag"
+ "shaders/hiqsubpixeldistancefieldtext.vert"
+ "shaders/hiqsubpixeldistancefieldtext_core.frag"
+ "shaders/hiqsubpixeldistancefieldtext_core.vert"
+ "shaders/loqsubpixeldistancefieldtext.frag"
+ "shaders/loqsubpixeldistancefieldtext.vert"
+ "shaders/loqsubpixeldistancefieldtext_core.frag"
+ "shaders/loqsubpixeldistancefieldtext_core.vert"
+ "shaders/opaquetexture.frag"
+ "shaders/opaquetexture.vert"
+ "shaders/opaquetexture_core.frag"
+ "shaders/opaquetexture_core.vert"
+ "shaders/outlinedtext.frag"
+ "shaders/outlinedtext.vert"
+ "shaders/outlinedtext_core.frag"
+ "shaders/outlinedtext_core.vert"
+ "shaders/rendernode.frag"
+ "shaders/rendernode.vert"
+ "shaders/rendernode_core.frag"
+ "shaders/rendernode_core.vert"
+ "shaders/smoothcolor.frag"
+ "shaders/smoothcolor.vert"
+ "shaders/smoothcolor_core.frag"
+ "shaders/smoothcolor_core.vert"
+ "shaders/smoothtexture.frag"
+ "shaders/smoothtexture.vert"
+ "shaders/smoothtexture_core.frag"
+ "shaders/smoothtexture_core.vert"
+ "shaders/sprite.frag"
+ "shaders/sprite.vert"
+ "shaders/sprite_core.frag"
+ "shaders/sprite_core.vert"
+ "shaders/stencilclip.frag"
+ "shaders/stencilclip.vert"
+ "shaders/stencilclip_core.frag"
+ "shaders/stencilclip_core.vert"
+ "shaders/styledtext.frag"
+ "shaders/styledtext.vert"
+ "shaders/styledtext_core.frag"
+ "shaders/styledtext_core.vert"
+ "shaders/textmask.frag"
+ "shaders/textmask.vert"
+ "shaders/textmask_core.frag"
+ "shaders/textmask_core.vert"
+ "shaders/texture.frag"
+ "shaders/texture_core.frag"
+ "shaders/vertexcolor.frag"
+ "shaders/vertexcolor.vert"
+ "shaders/vertexcolor_core.frag"
+ "shaders/vertexcolor_core.vert"
+ "shaders/visualization.frag"
+ "shaders/visualization.vert"
+ "shaders_ng/24bittextmask.frag.qsb"
+ "shaders_ng/32bitcolortext.frag.qsb"
+ "shaders_ng/8bittextmask.frag.qsb"
+ "shaders_ng/8bittextmask_a.frag.qsb"
+ "shaders_ng/distancefieldoutlinetext.frag.qsb"
+ "shaders_ng/distancefieldoutlinetext.vert.qsb"
+ "shaders_ng/distancefieldoutlinetext_a.frag.qsb"
+ "shaders_ng/distancefieldshiftedtext.frag.qsb"
+ "shaders_ng/distancefieldshiftedtext.vert.qsb"
+ "shaders_ng/distancefieldshiftedtext_a.frag.qsb"
+ "shaders_ng/distancefieldtext.frag.qsb"
+ "shaders_ng/distancefieldtext.vert.qsb"
+ "shaders_ng/distancefieldtext_a.frag.qsb"
+ "shaders_ng/flatcolor.frag.qsb"
+ "shaders_ng/flatcolor.vert.qsb"
+ "shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb"
+ "shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb"
+ "shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb"
+ "shaders_ng/loqsubpixeldistancefieldtext.frag.qsb"
+ "shaders_ng/loqsubpixeldistancefieldtext.vert.qsb"
+ "shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb"
+ "shaders_ng/opaquetexture.frag.qsb"
+ "shaders_ng/opaquetexture.vert.qsb"
+ "shaders_ng/outlinedtext.frag.qsb"
+ "shaders_ng/outlinedtext.vert.qsb"
+ "shaders_ng/outlinedtext_a.frag.qsb"
+ "shaders_ng/shadereffect.frag.qsb"
+ "shaders_ng/shadereffect.vert.qsb"
+ "shaders_ng/smoothcolor.frag.qsb"
+ "shaders_ng/smoothcolor.vert.qsb"
+ "shaders_ng/smoothtexture.frag.qsb"
+ "shaders_ng/smoothtexture.vert.qsb"
+ "shaders_ng/sprite.frag.qsb"
+ "shaders_ng/sprite.vert.qsb"
+ "shaders_ng/stencilclip.frag.qsb"
+ "shaders_ng/stencilclip.vert.qsb"
+ "shaders_ng/styledtext.frag.qsb"
+ "shaders_ng/styledtext.vert.qsb"
+ "shaders_ng/styledtext_a.frag.qsb"
+ "shaders_ng/textmask.frag.qsb"
+ "shaders_ng/textmask.vert.qsb"
+ "shaders_ng/texture.frag.qsb"
+ "shaders_ng/texture.vert.qsb"
+ "shaders_ng/vertexcolor.frag.qsb"
+ "shaders_ng/vertexcolor.vert.qsb"
+ "shaders_ng/visualization.frag.qsb"
+ "shaders_ng/visualization.vert.qsb"
+)
+
+qt_add_resource(Quick "scenegraph"
+ PREFIX
+ "/qt-project.org/scenegraph"
+ BASE
+ "scenegraph"
+ FILES
+ ${scenegraph_resource_files}
+)
+set(items_resource_files
+ "shaders/shadereffect.frag"
+ "shaders/shadereffect.vert"
+ "shaders/shadereffect_core.frag"
+ "shaders/shadereffect_core.vert"
+ "shaders/shadereffectfallback.frag"
+ "shaders/shadereffectfallback.vert"
+ "shaders/shadereffectfallback_core.frag"
+ "shaders/shadereffectfallback_core.vert"
+)
+
+qt_add_resource(Quick "items"
+ PREFIX
+ "/qt-project.org/items"
+ BASE
+ "items"
+ FILES
+ ${items_resource_files}
+)
+
+
+if(ANDROID)
+ set_property(TARGET Quick APPEND PROPERTY QT_ANDROID_BUNDLED_FILES
+ qml
+ )
+endif()
+
+#### Keys ignored in scope 1:.:.:quick.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQuick"
+# QML_IMPORT_NAME = "QtQuick"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(Quick CONDITION QT_FEATURE_qml_network
+ LIBRARIES
+ Qt::Network
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_opengl
+ LIBRARIES
+ Qt::OpenGLPrivate
+ PUBLIC_LIBRARIES
+ Qt::OpenGL
+)
+
+qt_extend_target(Quick CONDITION MSVC
+ DEFINES
+ _CRT_SECURE_NO_WARNINGS
+)
+
+#### Keys ignored in scope 5:.:.:quick.pro:solaris-cc_x_:
+# QMAKE_CXXFLAGS_RELEASE = "--O2"
+
+qt_extend_target(Quick CONDITION WIN32 AND NOT WINRT
+ PUBLIC_LIBRARIES
+ user32
+)
+
+qt_extend_target(Quick CONDITION EXISTS "qqml_enable_gcov"
+ LIBRARIES
+ gcov
+ COMPILE_OPTIONS
+ -fno-elide-constructors
+ -fprofile-arcs
+ -ftest-coverage
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_designer
+ SOURCES
+ designer/qqmldesignermetaobject.cpp designer/qqmldesignermetaobject_p.h
+ designer/qquickdesignercustomobjectdata.cpp designer/qquickdesignercustomobjectdata_p.h
+ designer/qquickdesignercustomparserobject.cpp designer/qquickdesignercustomparserobject_p.h
+ designer/qquickdesignersupport.cpp designer/qquickdesignersupport_p.h
+ designer/qquickdesignersupportitems.cpp designer/qquickdesignersupportitems_p.h
+ designer/qquickdesignersupportmetainfo.cpp designer/qquickdesignersupportmetainfo_p.h
+ designer/qquickdesignersupportproperties.cpp designer/qquickdesignersupportproperties_p.h
+ designer/qquickdesignersupportpropertychanges.cpp designer/qquickdesignersupportpropertychanges_p.h
+ designer/qquickdesignersupportstates.cpp designer/qquickdesignersupportstates_p.h
+ designer/qquickdesignerwindowmanager.cpp designer/qquickdesignerwindowmanager_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_accessibility
+ SOURCES
+ accessible/qaccessiblequickitem.cpp accessible/qaccessiblequickitem_p.h
+ accessible/qaccessiblequickview.cpp accessible/qaccessiblequickview_p.h
+ accessible/qquickaccessiblefactory.cpp accessible/qquickaccessiblefactory_p.h
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_qml_debug
+ SOURCES
+ util/qquickprofiler.cpp
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_shortcut
+ SOURCES
+ util/qquickshortcut.cpp util/qquickshortcut_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_path
+ SOURCES
+ util/qquickpath.cpp util/qquickpath_p.h
+ util/qquickpath_p_p.h
+ util/qquickpathinterpolator.cpp util/qquickpathinterpolator_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3
+ SOURCES
+ items/qquickframebufferobject.cpp items/qquickframebufferobject.h
+ items/qquickopenglinfo.cpp items/qquickopenglinfo_p.h
+ scenegraph/compressedtexture/qsgcompressedatlastexture.cpp scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
+ scenegraph/compressedtexture/qsgcompressedtexture.cpp scenegraph/compressedtexture/qsgcompressedtexture_p.h
+ scenegraph/coreapi/qsgbatchrenderer.cpp scenegraph/coreapi/qsgbatchrenderer_p.h
+ scenegraph/coreapi/qsgopenglvisualizer.cpp scenegraph/coreapi/qsgopenglvisualizer_p.h
+ scenegraph/coreapi/qsgrhivisualizer.cpp scenegraph/coreapi/qsgrhivisualizer_p.h
+ scenegraph/coreapi/qsgshaderrewriter.cpp
+ scenegraph/qsgdefaultcontext.cpp scenegraph/qsgdefaultcontext_p.h
+ scenegraph/qsgdefaultglyphnode.cpp scenegraph/qsgdefaultglyphnode_p.cpp scenegraph/qsgdefaultglyphnode_p.h
+ scenegraph/qsgdefaultglyphnode_p_p.h
+ scenegraph/qsgdefaultinternalimagenode.cpp scenegraph/qsgdefaultinternalimagenode_p.h
+ scenegraph/qsgdefaultinternalrectanglenode.cpp scenegraph/qsgdefaultinternalrectanglenode_p.h
+ scenegraph/qsgdefaultrendercontext.cpp scenegraph/qsgdefaultrendercontext_p.h
+ scenegraph/qsgdistancefieldglyphnode.cpp scenegraph/qsgdistancefieldglyphnode_p.cpp scenegraph/qsgdistancefieldglyphnode_p.h
+ scenegraph/qsgdistancefieldglyphnode_p_p.h
+ scenegraph/qsgopengldistancefieldglyphcache.cpp scenegraph/qsgopengldistancefieldglyphcache_p.h
+ scenegraph/qsgopengllayer.cpp scenegraph/qsgopengllayer_p.h
+ scenegraph/qsgrhidistancefieldglyphcache.cpp scenegraph/qsgrhidistancefieldglyphcache_p.h
+ scenegraph/qsgrhilayer.cpp scenegraph/qsgrhilayer_p.h
+ scenegraph/qsgrhishadereffectnode.cpp scenegraph/qsgrhishadereffectnode_p.h
+ scenegraph/qsgrhitextureglyphcache.cpp scenegraph/qsgrhitextureglyphcache_p.h
+ scenegraph/util/qsgdefaultimagenode.cpp scenegraph/util/qsgdefaultimagenode_p.h
+ scenegraph/util/qsgdefaultninepatchnode.cpp scenegraph/util/qsgdefaultninepatchnode_p.h
+ scenegraph/util/qsgdefaultpainternode.cpp scenegraph/util/qsgdefaultpainternode_p.h
+ scenegraph/util/qsgdefaultrectanglenode.cpp scenegraph/util/qsgdefaultrectanglenode_p.h
+ scenegraph/util/qsgdepthstencilbuffer.cpp scenegraph/util/qsgdepthstencilbuffer_p.h
+ scenegraph/util/qsgopenglatlastexture.cpp scenegraph/util/qsgopenglatlastexture_p.h
+ scenegraph/util/qsgrhiatlastexture.cpp scenegraph/util/qsgrhiatlastexture_p.h
+ scenegraph/util/qsgshadersourcebuilder.cpp scenegraph/util/qsgshadersourcebuilder_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_thread AND (QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3)
+ SOURCES
+ scenegraph/qsgthreadedrenderloop.cpp scenegraph/qsgthreadedrenderloop_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_sprite AND (QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3)
+ SOURCES
+ scenegraph/qsgdefaultspritenode.cpp scenegraph/qsgdefaultspritenode_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_sprite
+ SOURCES
+ items/qquickanimatedsprite.cpp items/qquickanimatedsprite_p.h
+ items/qquickanimatedsprite_p_p.h
+ items/qquicksprite.cpp items/qquicksprite_p.h
+ items/qquickspriteengine.cpp items/qquickspriteengine_p.h
+ items/qquickspritesequence.cpp items/qquickspritesequence_p.h
+ items/qquickspritesequence_p_p.h
+ scenegraph/adaptations/software/qsgsoftwarespritenode.cpp scenegraph/adaptations/software/qsgsoftwarespritenode_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_thread
+ SOURCES
+ scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_draganddrop
+ SOURCES
+ items/qquickdrag.cpp items/qquickdrag_p.h
+ items/qquickdroparea.cpp items/qquickdroparea_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_animatedimage
+ SOURCES
+ items/qquickanimatedimage.cpp items/qquickanimatedimage_p.h
+ items/qquickanimatedimage_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_gridview
+ SOURCES
+ items/qquickgridview.cpp items/qquickgridview_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_itemview
+ SOURCES
+ items/qquickitemview.cpp items/qquickitemview_p.h
+ items/qquickitemview_p_p.h
+ items/qquickitemviewfxitem.cpp
+ items/qquickitemviewfxitem_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_viewtransitions
+ SOURCES
+ items/qquickitemviewtransition.cpp items/qquickitemviewtransition_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_listview
+ SOURCES
+ items/qquicklistview.cpp items/qquicklistview_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_tableview
+ SOURCES
+ items/qquicktableview.cpp items/qquicktableview_p.h
+ items/qquicktableview_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_pathview
+ SOURCES
+ items/qquickpathview.cpp items/qquickpathview_p.h
+ items/qquickpathview_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_positioners
+ SOURCES
+ items/qquickpositioners.cpp items/qquickpositioners_p.h
+ items/qquickpositioners_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_flipable
+ SOURCES
+ items/qquickflipable.cpp items/qquickflipable_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_repeater
+ SOURCES
+ items/qquickrepeater.cpp items/qquickrepeater_p.h
+ items/qquickrepeater_p_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_shadereffect
+ SOURCES
+ items/qquickgenericshadereffect.cpp items/qquickgenericshadereffect_p.h
+ items/qquickshadereffect.cpp items/qquickshadereffect_p.h
+ items/qquickshadereffectmesh.cpp items/qquickshadereffectmesh_p.h
+ items/qquickshadereffectsource.cpp items/qquickshadereffectsource_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_opengl AND QT_FEATURE_quick_shadereffect
+ SOURCES
+ items/qquickopenglshadereffect.cpp items/qquickopenglshadereffect_p.h
+ items/qquickopenglshadereffectnode.cpp items/qquickopenglshadereffectnode_p.h
+)
+
+#### Keys ignored in scope 41:.:items:items/items.pri:QT_FEATURE_opengl:
+# OTHER_FILES = "$$PWD/shaders/shadereffect.vert" "$$PWD/shaders/shadereffect.frag" "$$PWD/shaders/shadereffectfallback.vert" "$$PWD/shaders/shadereffectfallback.frag" "$$PWD/shaders/shadereffect_core.vert" "$$PWD/shaders/shadereffect_core.frag" "$$PWD/shaders/shadereffectfallback_core.vert" "$$PWD/shaders/shadereffectfallback_core.frag"
+
+qt_extend_target(Quick CONDITION QT_FEATURE_quick_canvas
+ SOURCES
+ items/context2d/qquickcanvascontext.cpp items/context2d/qquickcanvascontext_p.h
+ items/context2d/qquickcanvasitem.cpp items/context2d/qquickcanvasitem_p.h
+ items/context2d/qquickcontext2d.cpp items/context2d/qquickcontext2d_p.h
+ items/context2d/qquickcontext2dcommandbuffer.cpp items/context2d/qquickcontext2dcommandbuffer_p.h
+ items/context2d/qquickcontext2dtexture.cpp items/context2d/qquickcontext2dtexture_p.h
+ items/context2d/qquickcontext2dtile.cpp items/context2d/qquickcontext2dtile_p.h
+)
+
+qt_extend_target(Quick CONDITION QT_FEATURE_wheelevent
+ SOURCES
+ handlers/qquickwheelhandler.cpp handlers/qquickwheelhandler_p.h
+ handlers/qquickwheelhandler_p_p.h
+)
+
+
+qt_create_tracepoints(Quick qtquick.tracepoints)
+qt_add_docs(Quick
+ doc/qtquick.qdocconf
+)
+
+
+set_target_properties(Quick PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQuick
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQuick"
+)
+
+qt6_qml_type_registration(Quick)
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index b87203c3ef..5e1ae25c38 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -43,6 +43,7 @@
#include "QtQuick/private/qquickitem_p.h"
#include "QtQuick/private/qquicktext_p.h"
+#include "QtQuick/private/qquicktextinput_p.h"
#include "QtQuick/private/qquickaccessibleattached_p.h"
#include "QtQuick/qquicktextdocument.h"
QT_BEGIN_NAMESPACE
@@ -197,6 +198,9 @@ QAccessible::State QAccessibleQuickItem::state() const
state.focusable = true;
if (item()->hasActiveFocus())
state.focused = true;
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
return state;
}
diff --git a/src/quick/configure.cmake b/src/quick/configure.cmake
new file mode 100644
index 0000000000..1685ca63ef
--- /dev/null
+++ b/src/quick/configure.cmake
@@ -0,0 +1,109 @@
+
+
+#### Inputs
+
+
+
+#### Libraries
+
+
+
+#### Tests
+
+
+
+#### Features
+
+qt_feature("quick-animatedimage" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "AnimatedImage item"
+ PURPOSE "Provides the AnimatedImage item."
+ CONDITION TARGET Qt::Gui AND QT_FEATURE_movie
+)
+qt_feature("quick-canvas" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Canvas item"
+ PURPOSE "Provides the Canvas item."
+ CONDITION QT_FEATURE_quick_path
+)
+qt_feature("quick-designer" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Support for Qt Quick Designer"
+ PURPOSE "Provides support for the Qt Quick Designer in Qt Creator."
+)
+qt_feature("quick-flipable" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Flipable item"
+ PURPOSE "Provides the Flipable item."
+)
+qt_feature("quick-gridview" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "GridView item"
+ PURPOSE "Provides the GridView item."
+ CONDITION QT_FEATURE_qml_delegate_model
+)
+qt_feature("quick-itemview" PRIVATE
+ LABEL "ItemView item"
+ CONDITION QT_FEATURE_quick_gridview OR QT_FEATURE_quick_listview OR QT_FEATURE_quick_tableview
+)
+qt_feature("quick-viewtransitions" PRIVATE
+ LABEL "Transitions required for ItemViews and Positioners"
+ CONDITION QT_FEATURE_quick_itemview OR QT_FEATURE_quick_positioners
+)
+qt_feature("quick-listview" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "ListView item"
+ PURPOSE "Provides the ListView item."
+ CONDITION QT_FEATURE_qml_delegate_model
+)
+qt_feature("quick-tableview" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "TableView item"
+ PURPOSE "Provides the TableView item."
+ CONDITION QT_FEATURE_qml_table_model
+)
+qt_feature("quick-particles" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Particle support"
+ PURPOSE "Provides a particle system."
+ CONDITION TARGET Qt::Gui AND QT_FEATURE_quick_shadereffect AND QT_FEATURE_quick_sprite AND QT_FEATURE_opengl
+)
+qt_feature("quick-path" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Path support"
+ PURPOSE "Provides Path elements."
+ CONDITION QT_FEATURE_quick_shadereffect
+)
+qt_feature("quick-pathview" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "PathView item"
+ PURPOSE "Provides the PathView item."
+ CONDITION ( QT_FEATURE_qml_delegate_model ) AND ( QT_FEATURE_quick_path )
+)
+qt_feature("quick-positioners" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Positioner items"
+ PURPOSE "Provides Positioner items."
+)
+qt_feature("quick-repeater" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Repeater item"
+ PURPOSE "Provides the Repeater item."
+ CONDITION QT_FEATURE_qml_delegate_model
+)
+qt_feature("quick-shadereffect" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "ShaderEffect item"
+ PURPOSE "Provides Shader effects."
+)
+qt_feature("quick-sprite" PRIVATE
+ SECTION "Qt Quick"
+ LABEL "Sprite item"
+ PURPOSE "Provides the Sprite item."
+)
+qt_feature("quick-draganddrop" PUBLIC
+ SECTION "Qt Quick"
+ LABEL "Drag & Drop"
+ PURPOSE "Drag and drop support for Qt Quick"
+ CONDITION ( QT_FEATURE_draganddrop ) AND ( QT_FEATURE_regularexpression )
+)
diff --git a/src/quick/configure.json b/src/quick/configure.json
index 8d1ddaea7c..fbb70fe572 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -12,7 +12,6 @@
"commandline": {
"options": {
- "d3d12": "boolean",
"quick-animatedimage": "boolean",
"quick-canvas": "boolean",
"quick-designer": "boolean",
@@ -28,24 +27,7 @@
}
},
- "tests": {
- "d3d12": {
- "label": "Direct3D 12",
- "type": "compile",
- "test": "d3d12"
- }
- },
-
"features": {
- "d3d12": {
- "label": "Direct3D 12",
- "purpose": "Provides a Direct3D 12 backend for the scenegraph.",
- "section": "Qt Quick",
- "condition": "tests.d3d12",
- "output": [
- "publicFeature"
- ]
- },
"quick-animatedimage": {
"label": "AnimatedImage item",
"purpose": "Provides the AnimatedImage item.",
@@ -202,7 +184,6 @@
{
"section": "Qt Quick",
"entries": [
- "d3d12",
"quick-animatedimage",
"quick-canvas",
"quick-designer",
diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp
index 70b568800d..a2820fbba2 100644
--- a/src/quick/designer/qquickdesignersupport.cpp
+++ b/src/quick/designer/qquickdesignersupport.cpp
@@ -97,7 +97,7 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h
texture->setSize(itemSize.toSize());
texture->setRecursive(true);
#if QT_CONFIG(opengl)
-#ifndef QT_OPENGL_ES
+#if !QT_CONFIG(opengles2)
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL)
texture->setFormat(GL_RGBA8);
else
@@ -390,13 +390,13 @@ void QQuickDesignerSupport::emitComponentCompleteSignalForAttachedProperty(QObje
QQmlData *data = QQmlData::get(object);
if (data && data->context) {
- QQmlComponentAttached *componentAttached = data->context->componentAttached;
+ QQmlComponentAttached *componentAttached = data->context->componentAttacheds();
while (componentAttached) {
if (componentAttached->parent())
if (componentAttached->parent() == object)
emit componentAttached->completed();
- componentAttached = componentAttached->next;
+ componentAttached = componentAttached->next();
}
}
}
@@ -429,7 +429,7 @@ int QQuickDesignerSupport::borderWidth(QQuickItem *item)
void QQuickDesignerSupport::refreshExpressions(QQmlContext *context)
{
- QQmlContextPrivate::get(context)->data->refreshExpressions();
+ QQmlContextData::get(context)->refreshExpressions();
}
void QQuickDesignerSupport::setRootItem(QQuickView *view, QQuickItem *item)
diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp
index ed5fdf3a4a..4fd9158f4a 100644
--- a/src/quick/designer/qquickdesignersupportitems.cpp
+++ b/src/quick/designer/qquickdesignersupportitems.cpp
@@ -210,14 +210,14 @@ static bool isCrashingType(const QQmlType &type)
return false;
}
-QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context)
+QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context)
{
ComponentCompleteDisabler disableComponentComplete;
Q_UNUSED(disableComponentComplete)
QObject *object = nullptr;
- QQmlType type = QQmlMetaType::qmlType(typeName, majorNumber, minorNumber);
+ QQmlType type = QQmlMetaType::qmlType(typeName, version);
if (isCrashingType(type)) {
object = new QObject;
@@ -242,7 +242,8 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in
if (!object) {
qWarning() << "QuickDesigner: Cannot create an object of type"
- << QString::fromLatin1("%1 %2,%3").arg(typeName).arg(majorNumber).arg(minorNumber)
+ << QString::fromLatin1("%1 %2,%3").arg(typeName)
+ .arg(version.majorVersion()).arg(version.minorVersion())
<< "- type isn't known to declarative meta type system";
}
diff --git a/src/quick/designer/qquickdesignersupportitems_p.h b/src/quick/designer/qquickdesignersupportitems_p.h
index 8c5a44d9fe..93b4c529fa 100644
--- a/src/quick/designer/qquickdesignersupportitems_p.h
+++ b/src/quick/designer/qquickdesignersupportitems_p.h
@@ -58,6 +58,7 @@
#include <QVariant>
#include <QList>
#include <QByteArray>
+#include <QTypeRevision>
#include <QQmlContext>
#include <QQmlListReference>
@@ -66,7 +67,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_EXPORT QQuickDesignerSupportItems
{
public:
- static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context);
+ static QObject *createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context);
static QObject *createComponent(const QUrl &componentUrl, QQmlContext *context);
static void tweakObjects(QObject *object);
static bool objectWasDeleted(QObject *object);
diff --git a/src/quick/designer/qquickdesignerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp
index 9648a40a23..bca89f3e14 100644
--- a/src/quick/designer/qquickdesignerwindowmanager.cpp
+++ b/src/quick/designer/qquickdesignerwindowmanager.cpp
@@ -39,6 +39,7 @@
#include "qquickdesignerwindowmanager_p.h"
#include "private/qquickwindow_p.h"
+#include "private/qquickitem_p.h"
#include <QtQuick/QQuickWindow>
#if QT_CONFIG(opengl)
#include <private/qsgdefaultrendercontext_p.h>
diff --git a/src/quick/designer/qquickdesignerwindowmanager_p.h b/src/quick/designer/qquickdesignerwindowmanager_p.h
index 5e387ff5b9..ac9695953f 100644
--- a/src/quick/designer/qquickdesignerwindowmanager_p.h
+++ b/src/quick/designer/qquickdesignerwindowmanager_p.h
@@ -58,7 +58,7 @@
#include <private/qsgcontext_p.h>
#if QT_CONFIG(opengl)
-# include <QtGui/QOpenGLContext>
+# include <QOpenGLContext>
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/quick/doc/images/qml-xmllistmodel-example.png b/src/quick/doc/images/qml-xmllistmodel-example.png
deleted file mode 100644
index be2d15d342..0000000000
--- a/src/quick/doc/images/qml-xmllistmodel-example.png
+++ /dev/null
Binary files differ
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 0d46e3408d..4d51bf02c8 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -38,7 +38,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtquick/qtquick.tags
-depends += qtcore qtqml qtqmlmodels qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns
+depends += qtcore qtqml qtqmlmodels qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql
headerdirs += ..\
../../quick \
diff --git a/src/quick/doc/snippets/qml/regexp.qml b/src/quick/doc/snippets/qml/regexp.qml
deleted file mode 100644
index 10b451d60a..0000000000
--- a/src/quick/doc/snippets/qml/regexp.qml
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQuick 2.0
-//![0]
-TextInput {
- id: hexNumber
- validator: RegExpValidator { regExp: /[0-9A-F]+/ }
-}
-//![0]
diff --git a/src/quick/doc/src/concepts/input/textinput.qdoc b/src/quick/doc/src/concepts/input/textinput.qdoc
index 1ec18f2e65..c6d573e474 100644
--- a/src/quick/doc/src/concepts/input/textinput.qdoc
+++ b/src/quick/doc/src/concepts/input/textinput.qdoc
@@ -55,7 +55,7 @@ The regular expression in the snippet will only allow the inputted text to be
\c {fruit basket}.
Note that QML parses JavaScript regular expressions, while Qt's
-\l {QRegExp} class' regular expressions are based on Perl regular expressions.
+\l {QRegularExpression} class' regular expressions are based on Perl regular expressions.
*/
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index 88003b68d3..86292921a6 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -34,11 +34,10 @@
Originally, Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) to
parse the scene graph and render the results to a render target
-From Qt 5.8 onwards, Qt Quick also supports rendering in software, with OpenVG,
-and with Direct3D 12. This is realized by having additional scene graph
-adaptations, either in form of plugins (d3d12, openvg) or built-in to the Qt
-Quick library (software). The default adaptation continues to rely directly on
-OpenGL.
+From Qt 5.8 onwards, Qt Quick also supports rendering in software, and with
+OpenVG. This is realized by having additional scene graph adaptations, either
+in form of plugins (openvg) or built-in to the Qt Quick library
+(software). The default adaptation continues to rely directly on OpenGL.
From Qt 5.14 onwards, the default adaptation gains the option of rendering via
a graphics abstraction layer, the Qt Rendering Hardware Interface (RHI),
@@ -52,7 +51,7 @@ appropriate for the various graphics APIs.
\target Switching Between the Adaptation Used by the Application
\section1 Switch Between Adaptations in Your Application
-Unlike \c software or \c d3d12, the RHI-based renderer is not an additional
+Unlike \c software, the RHI-based renderer is not an additional
adaptation, and is always built-in. As of Qt 5.14 it can be enabled by setting
the environment variable \c{QSG_RHI} to a non-zero value before starting the
application, or via \l QQuickWindow::setSceneGraphBackend() in combination with
@@ -75,8 +74,6 @@ The following backends are supported:
different than the ones listed below.
\li Software - Request with the \c{"software"} string or the QSGRendererInterface::Software
enum value.
- \li Direct3D 12 - Request with the \c{"d3d12"} string or the QSGRendererInterface::Direct3D12
- enum value.
\li OpenVG - Request with the \c{"openvg"} string or the QSGRendererInterface::OpenVG enum
value.
\endlist
@@ -111,12 +108,6 @@ The Software adaptation is an alternative renderer for \l{Qt Quick} 2 that uses
engine to render the contents of the scene graph. For more details, see
\l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation}.
-\section1 Direct3D 12 (experimental)
-
-The Direct3D 12 adaptation is an alternative renderer for \l{Qt Quick} 2 when running on Windows
-10, both for Win32 and UWP applications. For more details, see
-\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation}.
-
\section1 OpenVG
The OpenVG adaptation is an alternative renderer for \l{Qt Quick} 2 that renders the contents of
@@ -172,235 +163,6 @@ behavior, which is only present in the default OpenGL adaptation.
/*!
-\title Qt Quick Direct3D 12 Adaptation
-\page qtquick-visualcanvas-adaptations-d3d12.html
-
-The Direct3D 12 adaptation for Windows 10, both in Win32 (\c windows platform plugin) and in UWP
-(\c winrt platform plugin), is shipped as a dynamically loaded plugin. This adaptation doesn't work
-on earlier Windows versions. Building this plugin is enabled automatically, whenever the necessary
-D3D and DXGI develpoment files are present. In practice, this currently means Visual Studio 2015
-and newer.
-
-The adaptation is available both in normal, OpenGL-enabled Qt builds, and also when Qt is
-configured with \c{-no-opengl}. However, it's never the default, meaning that the user or the
-application has to explicitly request it by setting the \c{QT_QUICK_BACKEND} environment variable
-to \c{d3d12} or by calling QQuickWindow::setSceneGraphBackend().
-
-\section2 Motivation
-
-This experimental adaptation is the first Qt Quick backend that focuses on a modern, lower-level
-graphics API in combination with a windowing system interface that's different from the traditional
-approaches used in combination with OpenGL.
-
-This adaptation also allows better integration with Windows, as Direct3D is the primary
-vendor-supported solution. Consequently, there are fewer problems anticipated with drivers,
-operations like window resizes, and special events like graphics device loss caused by device
-resets or graphics driver updates.
-
-Performance-wise, the general expectation is a somewhat lower CPU usage compared to OpenGL, due to
-lower driver overhead, and a higher GPU utilization with less idle time wastage. The backend
-doesn't heavily utilize threads yet, which means there are opportunities for further improvements
-in the future, for example to further optimize image loading.
-
-The D3D12 backend also introduces support for pre-compiled shaders. All the backend's own shaders
-(used by the built-in materials on which the Rectangle, Image, Text, and other QML types are built
-with) are compiled to D3D shader bytecode when you compile Qt. Applications using ShaderEffect
-items can choose to ship bytecode either in regular files, via the Qt resource system, or use
-High Level Shading Language for DirectX (HLSL) source strings. Unlike OpenGL, the compilation for
-HLSL is properly threaded, meaning shader compilation won't block the application and its user
-interface.
-
-\section2 Graphics Adapters
-
-The plugin does not necessarily require hardware acceleration. You can also use WARP, the Direct3D
-software rasterizer. By default, the first adapter providing hardware acceleration is chosen. To
-override this and use another graphics adapter or to force the use of the software rasterizer, set
-the \c{QT_D3D_ADAPTER_INDEX} environment variable to the index of the adapter. The adapters
-discovered are printed at startup when \c{QSG_INFO} or the \c{qt.scenegraph.general} logging
-category is enabled.
-
-\section2 Troubleshooting
-
-If you encounter issues, always set the \c{QSG_INFO} and \c{QT_D3D_DEBUG} environment variables
-to \c 1, to get debug and warning messages printed on the debug output. \c{QT_D3D_DEBUG} enables
-the Direct3D debug layer.
-
-\note The debug layer shouldn't be enabled in production use, since it can significantly impact
-performance (CPU load) due to increased API overhead.
-
-\section2 Render Loops
-
-By default, the D3D12 adaptation uses a single-threaded render loop similar to OpenGL's \c windows
-render loop. A threaded variant is also available, that you can request by setting the
-\c{QSG_RENDER_LOOP} environment variable to \c threaded. However, due to conceptual limitations in
-DXGI, the windowing system interface, the threaded loop is prone to deadlocks when multiple
-QQuickWindow or QQuickView instances are shown. Consequently, for the time being, the default is
-the single-threaded loop. This means that with the D3D12 backend, applications are expected to move
-their work from the main (GUI) thread out to worker threads, instead of expecting Qt to keep the
-GUI thread responsive and suitable for heavy, blocking operations.
-
-For more information see \l{qtquick-visualcanvas-scenegraph.html}{Qt Quick Scene Graph} for
-details on render loops and
-\l{https://docs.microsoft.com/en-us/windows/desktop/direct3darticles/dxgi-best-practices#multithreading-and-dxgi}{Multithreading and DXGI}
-regarding the issues with multithreading.
-
-\section2 Renderer
-
-The scene graph renderer in the D3D12 adaptation currently doesn't perform any batching. This is
-less of an issue, unlike OpenGL, because state changes don't present any problems in the first
-place. The simpler renderer logic can also lead to lower CPU overhead in some cases. The trade-offs
-between the various approaches are currently under research.
-
-\section2 Shader Effects
-
-The ShaderEffect QML type is fully functional with the D3D12 adaptation as well. However, the
-interpretation of the fragmentShader and vertexShader properties is different than with OpenGL.
-
-With D3D12, these strings can either be a URL for a local file, a file in the resource system,
-or an HLSL source string. Using a URL for a local file or a file in the resource system
-indicates that the file in question contains pre-compiled D3D shader bytecode generated by the
-\c fxc tool, or, alternatively, HLSL source code. The type of file is detected automatically.
-This means that the D3D12 backend supports all options from GraphicsInfo.shaderCompilationType
-and GraphicsInfo.shaderSourceType.
-
-Unlike OpenGL, whenever you open a file, there is a QFileSelector with the extra \c hlsl selector
-used. This provides easy creation of ShaderEffect items that are functional across both backends,
-for example by placing the GLSL source code into \c{shaders/effect.frag}, the HLSL source code or
-- preferably - pre-compiled bytecode into \c{shaders/+hlsl/effect.frag}, while simply writing
-\c{fragmentShader: "qrc:shaders/effect.frag"} in QML. For more details, see ShaderEffect.
-
-\section2 Multisample Render Targets
-
-The Direct3D 12 adaptation ignores the QSurfaceFormat set on the QQuickWindow or QQuickView, or
-set via QSurfaceFormat::setDefaultFormat(), with two exceptions: QSurfaceFormat::samples() and
-QSurfaceFormat::alphaBufferSize() are still taken into account. When the sample value is greater
-than 1, multisample offscreen render targets will be created with the specified sample count at
-the maximum supported quality level. The backend automatically performs resolving into the
-non-multisample swapchain buffers after each frame.
-
-\section2 Semi-transparent Windows
-
-When the alpha channel is enabled either via QQuickWindow::setDefaultAlphaBuffer() or by setting
-alphaBufferSize to a non-zero value in the window's QSurfaceFormat or in the global format managed
-by QSurfaceFormat::setDefaultFormat(), the D3D12 backend will create a swapchain for composition
-and go through DirectComposition. This is necessary, because the mandatory flip model swapchain
-wouldn't support transparency otherwise.
-
-Therefore, it's important not to unneccessarily request an alpha channel. When the alphaBufferSize
-is 0 or the default -1, all these extra steps can be avoided and the traditional window-based
-swapchain is sufficient.
-
-On WinRT, this isn't relevant because the backend there always uses a composition swapchain which
-is associated with the ISwapChainPanel that backs QWindow on that platform.
-
-\section2 Mipmaps
-
-Mipmap generation is supported and handled transparently to the applications via a built-in compute
-shader. However, at the moment, this feature is experimental and only supports power-of-two images.
-Textures of other size will work too, but this involves a QImage-based scaling on the CPU first.
-Therefore, avoid enabling mipmapping for Non-Power-Of-Two (NPOT) images whenever possible.
-
-\section2 Image Formats
-
-When creating textures via C++ scene graph APIs like QQuickWindow::createTextureFromImage(), 32-bit
-formats won't involve any conversion, they'll map directly to the corresponding \c{R8G8B8A8_UNORM}
-or \c{B8G8R8A8_UNORM} format. Everything else will trigger a QImage-based format conversion on the
-CPU first.
-
-\section2 Unsupported Features
-
-Particles and some other OpenGL-dependent utilities, like QQuickFramebufferObject, are currently
-not supported.
-
-Like with \l{qtquick-visualcanvas-adaptations-software.html}{Software adaptation}, text is always
-rendered using the native method. Distance field-based text rendering is currently not implemented.
-
-The shader sources in the \l {Qt Graphical Effects} module have not been ported to any format other
-than the OpenGL 2.0 compatible one, meaning that the QML types provided by that module are currently
-not functional with the D3D12 backend.
-
-Texture atlases are currently not in use.
-
-The renderer may lack support for certain minor features, such as drawing points and lines with a
-width other than 1.
-
-Custom Qt Quick items using custom scene graph nodes can be problematic because materials are
-inherently tied to the graphics API. Therefore, only items that use the utility rectangle and image
-nodes are functional across all adaptations.
-
-QQuickWidget and its underlying OpenGL-based compositing architecture is not supported. If you need
-to mix with QWidget-based user interfaces, use QWidget::createWindowContainer() to embed the native
-window of the QQuickWindow or QQuickView.
-
-Finally, rendering via QSGEngine and QSGAbstractRenderer is not feasible with the D3D12 adaptation
-at the moment.
-
-\section2 Related APIs
-
-To integrate custom Direct3D 12 rendering, use QSGRenderNode in combination with
-QSGRendererInterface. This approach doesn't rely on OpenGL contexts or API specifics like
-framebuffers, and allows exposing the graphics device and command buffer from the adaptation. It's
-not necessarily suitable for easy integration of all types of content, in particular true 3D, so
-it'll likely get complemented by an alternative to QQuickFramebufferObject in future releases.
-
-To perform runtime decisions based on the adaptation, use QSGRendererInterface from C++ and
-GraphicsInfo from QML. They can also be used to check the level of shader support: shading
-language, compilation approach, and so on.
-
-When creating custom items, use the new QSGRectangleNode and QSGImageNode classes. These replace
-the now deprecated QSGSimpleRectNode and QSGSimpleTextureNode. Unlike their predecessors, these new
-classes are interfaces, and implementations are created via the QQuickWindow::createRectangleNode()
-and QQuickWindow::createImageNode() factory functions.
-
-\section2 Advanced Configuration
-
-The D3D12 adaptation can keep multiple frames in flight, similar to modern game engines. This is
-somewhat different from the traditional "render - swap - wait for vsync" model and allows for
-better GPU utilization at the expense of higher resource use. This means that the renderer will
-be a number of frames ahead of what is displayed on the screen.
-
-For a discussion of flip model swap chains and the typical configuration parameters, refer to
-\l{https://software.intel.com/en-us/articles/sample-application-for-direct3d-12-flip-model-swap-chains}
-{Sample Application for Direct3D 12 Flip Model Swap Chains}.
-
-Vertical synchronization is always enabled, meaning Present() is invoked with an interval of 1.
-
-The configuration can be changed by setting the following environment variables:
-
-\table
- \header
- \li Environment variable
- \li Description
- \row
- \li \c{QT_D3D_BUFFER_COUNT}
- \li The number of swap chain buffers in range 2 - 4. The default value is 3.
- \row
- \li \c{QT_D3D_FRAME_COUNT}
- \li The number of frames prepared without blocking in range 1 - 4. The default value is 2.
- Present() starts blocking after queuing 3 frames (regardless of
- \c{QT_D3D_BUFFER_COUNT}), unless the waitable object is in use. Every additional frame
- increases GPU resource usage since geometry and constant buffer data needs to be
- duplicated, and involves more bookkeeping on the CPU side.
- \row
- \li \c{QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY}
- \li The frame latency in range 1 - 16. The default value is 0 (disabled).
- Changes the limit for Present() and triggers a wait for an available swap chain buffer
- when beginning each frame. For a detailed discussion, see the article linked above.
- \note Currently, this behavior is experimental.
- \row
- \li \c{QT_D3D_BLOCKING_PRESENT}
- \li The time the CPU should wait, a non-zero value, for the GPU to finish its work after
- each call to Present(). The default value is 0 (disabled). This behavior effectively
- kills all parallelism but makes the behavior resemble the traditional
- swap-blocks-for-vsync model, which can be useful in some special cases. However, this
- behavior is not the same as setting the frame count to 1 because that still avoids
- blocking after Present(), and may only block when starting to prepare the next frame
- (or may not block at all depending on the time gap between the frames).
-\endtable
-
-*/
-
-/*!
\title Qt Quick OpenVG Adaptation
\page qtquick-visualcanvas-adaptations-openvg.html
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index e09c430e43..f312bde552 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -179,17 +179,15 @@ render loop.
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
-single-threaded, while \c threaded performs scene graph rendering on a
-dedicated thread. Qt attempts to choose a suitable loop based on the
-platform and possibly the graphics drivers in use. When this is not
-satisfactory, or for testing purposes, the environment variable
-\c QSG_RENDER_LOOP can be used to force the usage of a given loop. To
-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 graphics API
+There are two render loop variants available: \c basic, and \c threaded.
+\c basic is single-threaded, while \c threaded performs scene graph rendering on a
+dedicated thread. Qt attempts to choose a suitable loop based on the platform
+and possibly the graphics drivers in use. When this is not satisfactory, or for
+testing purposes, the environment variable \c QSG_RENDER_LOOP can be used to
+force the usage of a given loop. To verify which render loop is in use, enable
+the \c qt.scenegraph.general \l {QLoggingCategory}{logging category}.
+
+\note The \c threaded render loop relies 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
@@ -280,15 +278,15 @@ 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")
+\section2 Non-threaded Render Loop ("basic")
-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.
+The non-threaded render loop is currently used by default on Windows with
+OpenGL when not using the system's standard opengl32.dll, \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 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
@@ -296,10 +294,6 @@ 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.
-
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.
diff --git a/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc
index 84741efa61..36c8eae4cb 100644
--- a/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc
@@ -72,7 +72,7 @@ so on.
\li \l{QML Profiler}
\endlist
-\section2 QmlLive, GammaRay, and Squish
+\section1 QmlLive, GammaRay, and Squish
QmlLive is a 3rd party tool that offers a QML runtime capable of rendering
changes to the code in realtime. It avoids the need to rebuild the
@@ -109,4 +109,28 @@ integrating 3rd party tools such as QmlLive and GammaRay.
\list
\li \l{Qt Creator Manual}
\endlist
+
+\section1 qmllint
+qmllint is a tool shipped with Qt, that verifies the syntatic validity of QML files.
+It also warns about some QML anti-patterns. If you want to disable a specific
+warning type, you can find the appropriate flag for doing so by passing \c{--help} on the command line.
+
+qmllint warns about
+\list
+ \li Unqualified accesses of properties.
+ \li Usage of signal handlers without a matching signal.
+ \li Usage of with statements in QML.
+\endlist
+
+In order for qmllint to work properly, it requires type information. That information
+is provided by qmltypes files. qmltypes files in the current directory, as well as
+those for Qt's built-in types, are discovered automatically. For qmltypes files from
+libraries that reside outside of the current directory, you can provide their path
+via the -I flag.
+
+\section2 Related Information
+\list
+ \li \l{qmltypes}
+\endlist
+
*/
diff --git a/src/quick/handlers/qquickdragaxis_p.h b/src/quick/handlers/qquickdragaxis_p.h
index ef74902122..b3db1be620 100644
--- a/src/quick/handlers/qquickdragaxis_p.h
+++ b/src/quick/handlers/qquickdragaxis_p.h
@@ -63,7 +63,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragAxis : public QObject
Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
QML_NAMED_ELEMENT(DragAxis)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
QML_UNCREATABLE("DragAxis is only available as a grouped property of DragHandler.")
public:
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index 22d51c78ec..1315f79114 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -62,9 +62,9 @@ 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 REVISION 14)
+ Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION(2, 14))
QML_NAMED_ELEMENT(DragHandler)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
enum SnapMode {
@@ -91,7 +91,7 @@ public:
Q_SIGNALS:
void translationChanged();
- Q_REVISION(14) void snapModeChanged();
+ Q_REVISION(2, 14) void snapModeChanged();
protected:
void onActiveChanged() override;
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index 313b87217c..4b9d0a9f39 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -63,7 +63,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandle
Q_OBJECT
Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged)
QML_NAMED_ELEMENT(HoverHandler)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
explicit QQuickHoverHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 5b30d08557..8413b8b721 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -153,49 +153,6 @@ void QQuickPinchHandler::setMaximumRotation(qreal maximumRotation)
emit maximumRotationChanged();
}
-#if QT_DEPRECATED_SINCE(5, 12)
-void QQuickPinchHandler::warnAboutMinMaxDeprecated() const
-{
- qmlWarning(this) << "min and max constraints are now part of the xAxis and yAxis properties";
-}
-
-void QQuickPinchHandler::setMinimumX(qreal minX)
-{
- warnAboutMinMaxDeprecated();
- if (qFuzzyCompare(m_minimumX, minX))
- return;
- m_minimumX = minX;
- emit minimumXChanged();
-}
-
-void QQuickPinchHandler::setMaximumX(qreal maxX)
-{
- warnAboutMinMaxDeprecated();
- if (qFuzzyCompare(m_maximumX, maxX))
- return;
- m_maximumX = maxX;
- emit maximumXChanged();
-}
-
-void QQuickPinchHandler::setMinimumY(qreal minY)
-{
- warnAboutMinMaxDeprecated();
- if (qFuzzyCompare(m_minimumY, minY))
- return;
- m_minimumY = minY;
- emit minimumYChanged();
-}
-
-void QQuickPinchHandler::setMaximumY(qreal maxY)
-{
- warnAboutMinMaxDeprecated();
- if (qFuzzyCompare(m_maximumY, maxY))
- return;
- m_maximumY = maxY;
- emit maximumYChanged();
-}
-#endif
-
bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
if (!QQuickMultiPointHandler::wantsPointerEvent(event))
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
index 708c836acf..b4e9fa0336 100644
--- a/src/quick/handlers/qquickpinchhandler_p.h
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -70,16 +70,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
Q_PROPERTY(qreal activeScale READ activeScale NOTIFY updated)
Q_PROPERTY(qreal rotation READ rotation NOTIFY updated)
Q_PROPERTY(QVector2D translation READ translation NOTIFY updated)
-#if QT_DEPRECATED_SINCE(5, 12)
- Q_PROPERTY(qreal minimumX READ minimumX WRITE setMinimumX NOTIFY minimumXChanged) // ### Qt 6: remove
- Q_PROPERTY(qreal maximumX READ maximumX WRITE setMaximumX NOTIFY maximumXChanged) // ### Qt 6: remove
- Q_PROPERTY(qreal minimumY READ minimumY WRITE setMinimumY NOTIFY minimumYChanged) // ### Qt 6: remove
- Q_PROPERTY(qreal maximumY READ maximumY WRITE setMaximumY NOTIFY maximumYChanged) // ### Qt 6: remove
-#endif
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
QML_NAMED_ELEMENT(PinchHandler)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
explicit QQuickPinchHandler(QQuickItem *parent = nullptr);
@@ -101,18 +95,6 @@ public:
qreal activeScale() const { return m_activeScale; }
qreal rotation() const { return m_activeRotation; }
-#if QT_DEPRECATED_SINCE(5, 12)
- void warnAboutMinMaxDeprecated() const;
- qreal minimumX() const { warnAboutMinMaxDeprecated(); return m_minimumX; }
- void setMinimumX(qreal minX);
- qreal maximumX() const { warnAboutMinMaxDeprecated(); return m_maximumX; }
- void setMaximumX(qreal maxX);
- qreal minimumY() const { warnAboutMinMaxDeprecated(); return m_minimumY; }
- void setMinimumY(qreal minY);
- qreal maximumY() const { warnAboutMinMaxDeprecated(); return m_maximumY; }
- void setMaximumY(qreal maxY);
-#endif
-
QQuickDragAxis *xAxis() { return &m_xAxis; }
QQuickDragAxis *yAxis() { return &m_yAxis; }
@@ -121,10 +103,6 @@ signals:
void maximumScaleChanged();
void minimumRotationChanged();
void maximumRotationChanged();
- void minimumXChanged();
- void maximumXChanged();
- void minimumYChanged();
- void maximumYChanged();
void updated();
protected:
@@ -145,10 +123,6 @@ private:
qreal m_minimumRotation = -qInf();
qreal m_maximumRotation = qInf();
- qreal m_minimumX = -qInf();
- qreal m_maximumX = qInf();
- qreal m_minimumY = -qInf();
- qreal m_maximumY = qInf();
QQuickDragAxis m_xAxis;
QQuickDragAxis m_yAxis;
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index 7262f4bcd3..3e7876b3d9 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -71,14 +71,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP
Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT)
Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged)
Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged)
- Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION 15)
+ Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION(2, 15))
#if QT_CONFIG(cursor)
- Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION 15)
+ Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION(2, 15))
#endif
QML_NAMED_ELEMENT(PointerHandler)
QML_UNCREATABLE("PointerHandler is an abstract base class.")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
explicit QQuickPointerHandler(QQuickItem *parent = nullptr);
@@ -134,12 +134,12 @@ Q_SIGNALS:
void activeChanged();
void targetChanged();
void marginChanged();
- Q_REVISION(15) void dragThresholdChanged();
+ Q_REVISION(2, 15) void dragThresholdChanged();
void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point);
void grabPermissionChanged();
void canceled(QQuickEventPoint *point);
#if QT_CONFIG(cursor)
- Q_REVISION(15) void cursorShapeChanged();
+ Q_REVISION(2, 15) void cursorShapeChanged();
#endif
protected:
diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h
index 42677540a7..cedbc1c539 100644
--- a/src/quick/handlers/qquickpointhandler_p.h
+++ b/src/quick/handlers/qquickpointhandler_p.h
@@ -60,7 +60,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointHandler : public QQuickSinglePointHandle
Q_OBJECT
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
QML_NAMED_ELEMENT(PointHandler)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
explicit QQuickPointHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h
index 07454bccb8..d5c16b071f 100644
--- a/src/quick/handlers/qquicktaphandler_p.h
+++ b/src/quick/handlers/qquicktaphandler_p.h
@@ -68,7 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler
Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged)
QML_NAMED_ELEMENT(TapHandler)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
enum GesturePolicy {
diff --git a/src/quick/handlers/qquickwheelhandler_p.h b/src/quick/handlers/qquickwheelhandler_p.h
index 26b052c5b3..021cd23679 100644
--- a/src/quick/handlers/qquickwheelhandler_p.h
+++ b/src/quick/handlers/qquickwheelhandler_p.h
@@ -73,7 +73,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWheelHandler : public QQuickSinglePointHandle
Q_PROPERTY(bool targetTransformAroundCursor READ isTargetTransformAroundCursor WRITE setTargetTransformAroundCursor NOTIFY targetTransformAroundCursorChanged)
QML_NAMED_ELEMENT(WheelHandler)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
public:
explicit QQuickWheelHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index bfee190baf..84f65d5241 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -59,6 +59,7 @@
#include <private/qv4scopedvalue_p.h>
#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qjsvalue_p.h>
QT_BEGIN_NAMESPACE
@@ -381,7 +382,7 @@ void QQuickCanvasItem::setContextType(const QString &contextType)
QJSValue QQuickCanvasItem::context() const
{
Q_D(const QQuickCanvasItem);
- return d->context ? QJSValue(d->context->v4Engine(), d->context->v4value()) : QJSValue();
+ return d->context ? QJSValuePrivate::fromReturnedValue(d->context->v4value()) : QJSValue();
}
/*!
@@ -593,11 +594,11 @@ void QQuickCanvasItem::sceneGraphInitialized()
QMetaObject::invokeMethod(this, "requestPaint", Qt::QueuedConnection);
}
-void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickCanvasItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickCanvasItem);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
// Due to indirect recursion, newGeometry may be outdated
// after this call, so we use width and height instead.
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index 6575caf806..1972a9a507 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -100,6 +100,7 @@ class QQuickCanvasItem : public QQuickItem
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
Q_PROPERTY(RenderStrategy renderStrategy READ renderStrategy WRITE setRenderStrategy NOTIFY renderStrategyChanged)
QML_NAMED_ELEMENT(Canvas)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum RenderTarget {
@@ -190,7 +191,7 @@ protected:
void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &) override;
void updatePolish() override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void releaseResources() override;
bool event(QEvent *event) override;
private:
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 14fa07099f..12a4ce32df 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -74,12 +74,12 @@
#include <QtCore/private/qnumeric_p.h>
#include <QtCore/QRunnable>
#include <QtGui/qguiapplication.h>
-#include <QtGui/qopenglframebufferobject.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#if QT_CONFIG(opengl)
-# include <private/qsgdefaultrendercontext_p.h>
+#include <qopenglframebufferobject.h>
+#include <private/qsgdefaultrendercontext_p.h>
#endif
#include <cmath>
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index 55ebbe907c..73b52d0c73 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -44,8 +44,8 @@
#include <QtQuick/qsgtexture.h>
#include <QtGui/QPaintEngine>
#if QT_CONFIG(opengl)
-# include <QtGui/QOpenGLContext>
-# include <QtGui/private/qopenglpaintengine_p.h>
+# include <QOpenGLContext>
+# include <private/qopenglpaintengine_p.h>
#endif
#define HAS_SHADOW(offsetX, offsetY, blur, color) (color.isValid() && color.alpha() && (blur || offsetX || offsetY))
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index 0ebd1a66c9..1cf3891488 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -43,12 +43,12 @@
#include <private/qquickitem_p.h>
#include <QtQuick/private/qsgplaintexture_p.h>
#include "qquickcontext2dcommandbuffer_p.h"
-#include <QOpenGLPaintDevice>
#if QT_CONFIG(opengl)
+#include <QOpenGLPaintDevice>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFramebufferObjectFormat>
#include <QOpenGLFunctions>
-#include <QtGui/private/qopenglextensions_p.h>
+#include <private/qopenglextensions_p.h>
#endif
#include <QtCore/QThread>
#include <QtGui/QGuiApplication>
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 6f2f9fbd8e..2d232a0b0a 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -1,4 +1,5 @@
HEADERS += \
+ $$PWD/qquickabstractpaletteprovider_p.h \
$$PWD/qquickevents_p_p.h \
$$PWD/qquickanchors_p.h \
$$PWD/qquickanchors_p_p.h \
@@ -56,10 +57,19 @@ HEADERS += \
$$PWD/qquickscreen_p.h \
$$PWD/qquickwindowattached_p.h \
$$PWD/qquickwindowmodule_p.h \
+ $$PWD/qquickwindowmodule_p_p.h \
$$PWD/qquickrendercontrol.h \
$$PWD/qquickrendercontrol_p.h \
$$PWD/qquickgraphicsinfo_p.h \
- $$PWD/qquickitemgrabresult.h
+ $$PWD/qquickitemgrabresult.h \
+ $$PWD/qquickpalette_p.h \
+ $$PWD/qquickcolorgroup_p.h \
+ $$PWD/qquickpalettecolorprovider_p.h \
+ $$PWD/qquickpaletteproviderprivatebase_p.h \
+ $$PWD/qquickrendertarget.h \
+ $$PWD/qquickrendertarget_p.h \
+ $$PWD/qquickgraphicsdevice.h \
+ $$PWD/qquickgraphicsdevice_p.h
SOURCES += \
$$PWD/qquickevents.cpp \
@@ -99,7 +109,12 @@ SOURCES += \
$$PWD/qquickwindowattached.cpp \
$$PWD/qquickrendercontrol.cpp \
$$PWD/qquickgraphicsinfo.cpp \
- $$PWD/qquickitemgrabresult.cpp
+ $$PWD/qquickitemgrabresult.cpp \
+ $$PWD/qquickpalettecolorprovider.cpp \
+ $$PWD/qquickcolorgroup.cpp \
+ $$PWD/qquickpalette.cpp \
+ $$PWD/qquickrendertarget.cpp \
+ $$PWD/qquickgraphicsdevice.cpp
qtConfig(quick-draganddrop) {
HEADERS += \
diff --git a/src/quick/items/qquickabstractpaletteprovider_p.h b/src/quick/items/qquickabstractpaletteprovider_p.h
new file mode 100644
index 0000000000..8336d88418
--- /dev/null
+++ b/src/quick/items/qquickabstractpaletteprovider_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKABSTRACTPALETTEPROVIDER_P_H
+#define QQUICKABSTRACTPALETTEPROVIDER_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 QQuickAbstractPaletteProvider
+{
+public:
+ virtual ~QQuickAbstractPaletteProvider() = default;
+ virtual QPalette defaultPalette() const = 0;
+ virtual QPalette parentPalette() const = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTPALETTEPROVIDER_P_H
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index c24bce7bda..c4ccbb5a10 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -91,6 +91,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject
Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL)
QML_NAMED_ELEMENT(Accessible)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Accessible is only available via attached properties.")
QML_ATTACHED(QQuickAccessibleAttached)
diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h
index e0276549e9..d243f6070f 100644
--- a/src/quick/items/qquickanchors_p.h
+++ b/src/quick/items/qquickanchors_p.h
@@ -85,6 +85,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnchors : public QObject
Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
Q_PROPERTY(bool alignWhenCentered READ alignWhenCentered WRITE setAlignWhenCentered NOTIFY centerAlignedChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnchors(QQuickItem *item, QObject *parent=nullptr);
diff --git a/src/quick/items/qquickanchors_p_p.h b/src/quick/items/qquickanchors_p_p.h
index 0a834276ae..9101b81b6c 100644
--- a/src/quick/items/qquickanchors_p_p.h
+++ b/src/quick/items/qquickanchors_p_p.h
@@ -57,8 +57,11 @@
QT_BEGIN_NAMESPACE
-class QQuickAnchorLine
+class Q_QUICK_PRIVATE_EXPORT QQuickAnchorLine
{
+ Q_GADGET
+ QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnchorLine() {}
QQuickAnchorLine(QQuickItem *i, QQuickAnchors::Anchor l) : item(i), anchorLine(l) {}
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 7f2199fd2a..6f7a7e45d5 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -70,11 +70,12 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged)
Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
- Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION 11)
+ Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION(2, 11))
// read-only for AnimatedImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
QML_NAMED_ELEMENT(AnimatedImage)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnimatedImage(QQuickItem *parent=nullptr);
@@ -104,7 +105,7 @@ Q_SIGNALS:
void frameChanged();
void currentFrameChanged();
void frameCountChanged();
- Q_REVISION(11) void speedChanged();
+ Q_REVISION(2, 11) void speedChanged();
private Q_SLOTS:
void movieUpdate();
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index b285fe56ed..8143f8117c 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -497,11 +497,19 @@ void QQuickAnimatedSprite::advance(int frames)
void QQuickAnimatedSprite::maybeUpdate()
{
QQuickItemPrivate *priv = QQuickItemPrivate::get(this);
- const QLazilyAllocated<QQuickItemPrivate::ExtraData> &extraData = priv->extra;
+ const auto &extraData = priv->extra;
if ((extraData.isAllocated() && extraData->effectRefCount > 0) || priv->effectiveVisible)
update();
}
+void QQuickAnimatedSprite::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_D(QQuickAnimatedSprite);
+ if (change == ItemVisibleHasChanged && d->m_running && !d->m_paused)
+ maybeUpdate();
+ QQuickItem::itemChange(change, value);
+}
+
/*!
\qmlmethod int QtQuick::AnimatedSprite::pause()
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index 546598a409..e231d2a10d 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -92,8 +92,9 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
- Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION 15)
+ Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION(2, 15))
QML_NAMED_ELEMENT(AnimatedSprite)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickAnimatedSprite(QQuickItem *parent = nullptr);
@@ -144,9 +145,9 @@ Q_SIGNALS:
void frameDurationChanged(int arg);
void loopsChanged(int arg);
void currentFrameChanged(int arg);
- Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg);
+ Q_REVISION(2, 15) void finishBehaviorChanged(FinishBehavior arg);
- Q_REVISION(12) void finished();
+ Q_REVISION(2, 12) void finished();
public Q_SLOTS:
void start();
@@ -183,6 +184,8 @@ protected Q_SLOTS:
protected:
void componentComplete() override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+ void itemChange(ItemChange, const ItemChangeData &) override;
+
private:
void maybeUpdate();
bool isCurrentFrameChangedConnected();
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 515edb33da..48922147ba 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase
// read-only for BorderImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
QML_NAMED_ELEMENT(BorderImage)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickBorderImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickcolorgroup.cpp b/src/quick/items/qquickcolorgroup.cpp
new file mode 100644
index 0000000000..5eedefea83
--- /dev/null
+++ b/src/quick/items/qquickcolorgroup.cpp
@@ -0,0 +1,571 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://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 "qquickcolorgroup_p.h"
+
+#include <QScopeGuard>
+
+#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
+#include <QtQuick/private/qquickpalette_p.h>
+#include <QtQuick/private/qquickpalettecolorprovider_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickColorGroup
+ \brief The QQuickColorGroup class represents a set of colors.
+ \inmodule QtQuick
+ \since 6.0
+
+ Used by QQuickPalette to provide different groups of colors by roles.
+
+ \sa QQuickPalette, QQuickAbstractPaletteProvider, QPalette::ColorRole
+ */
+
+/*!
+ \qmltype ColorGroup
+ \instantiates QQuickColorGroup
+ \inherits QtObject
+ \inqmlmodule QtQuick
+ \ingroup qtquick-visual
+ \brief The set of colors by roles.
+
+ The ColorGroup type is used to define a set of colors with certain roles. Although a ColorGroup
+ has no visual appearance, it defines colors used to customize rendered items.
+
+ Default values of colors are equal to active group colors of default-constructed \c QPalette.
+
+ The following code can be used to create a color group with some colors specified:
+
+ \code
+ ColorGroup {
+ alternateBase: "red"
+ base: "green"
+ }
+ \endcode
+ */
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::alternateBase
+
+ Used as the alternate background color in item views with alternating row colors.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::base
+
+ Used mostly as the background color for text editor controls and item views.
+ It is usually white or another light color.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::brightText
+
+ A text color that is very different from \c windowText, and contrasts
+ well with e.g. \c dark. Typically used for text that needs to be drawn
+ where \c text, \c windowText or \c buttonText would
+ give poor contrast, such as on highlighted buttons.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::button
+
+ The general button background color. This background can be different from
+ \c window as some styles require a different background color for buttons.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::buttonText
+
+ A foreground color used with the \c palette color.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::dark
+
+ A foreground color used with the \c palette color.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::highlight
+
+ A color to indicate a selected item or the current item.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::highlightedText
+
+ A text color that contrasts with \c highlight.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::light
+
+ Lighter than \c button.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::link
+
+ A text color used for hyperlinks.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::linkVisited
+
+ A text color used for already visited hyperlinks.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::mid
+
+ Between \c palette.button and \c dark.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::midlight
+
+ Between \c button and \c light.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::shadow
+
+ A very dark color.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::text
+
+ The foreground color used with \c base. This is usually the same as
+ the \c windowText, in which case it must provide good contrast with
+ \c window and \c base.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::toolTipBase
+
+ Used as the background color for tooltips.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::toolTipText
+
+ Used as the foreground color for tooltips.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::window
+
+ A general background color.
+*/
+
+/*!
+ \qmlproperty color QtQuick::ColorGroup::windowText
+
+ A general foreground color.
+*/
+
+/*!
+ \qmlsignal QtQuick::ColorGroup::changed
+
+ Additional signal indicates that the current state of this color group
+ has been changed. Usually it means that one of the colors is changed.
+
+ \sa QtQuick::Palette::changed
+*/
+
+/*!
+ Construct object in default state.
+ */
+QQuickColorGroup::QQuickColorGroup(QQuickPalette &parent)
+ : QObject(&parent)
+ , m_groupTag(defaultGroupTag())
+ , m_colorProvider(parent.colorProvider().shared_from_this())
+{
+}
+
+QPalette::ColorGroup QQuickColorGroup::currentColorGroup() const
+{
+ return groupTag();
+}
+
+QColor QQuickColorGroup::alternateBase() const
+{
+ return color(QPalette::AlternateBase);
+}
+
+void QQuickColorGroup::setAlternateBase(const QColor &color)
+{
+ setColor(QPalette::AlternateBase, color, &QQuickColorGroup::alternateBaseChanged);
+}
+
+void QQuickColorGroup::resetAlternateBase()
+{
+ resetColor(QPalette::AlternateBase, &QQuickColorGroup::alternateBaseChanged);
+}
+
+QColor QQuickColorGroup::base() const
+{
+ return color(QPalette::Base);
+}
+
+void QQuickColorGroup::setBase(const QColor &color)
+{
+ setColor(QPalette::Base, color, &QQuickColorGroup::baseChanged);
+}
+
+void QQuickColorGroup::resetBase()
+{
+ resetColor(QPalette::Base, &QQuickColorGroup::baseChanged);
+}
+
+QColor QQuickColorGroup::brightText() const
+{
+ return color(QPalette::BrightText);
+}
+
+void QQuickColorGroup::setBrightText(const QColor &color)
+{
+ setColor(QPalette::BrightText, color, &QQuickColorGroup::brightTextChanged);
+}
+
+void QQuickColorGroup::resetBrightText()
+{
+ resetColor(QPalette::BrightText, &QQuickColorGroup::brightTextChanged);
+}
+
+QColor QQuickColorGroup::button() const
+{
+ return color(QPalette::Button);
+}
+
+void QQuickColorGroup::setButton(const QColor &color)
+{
+ setColor(QPalette::Button, color, &QQuickColorGroup::buttonChanged);
+}
+
+void QQuickColorGroup::resetButton()
+{
+ resetColor(QPalette::Button, &QQuickColorGroup::buttonChanged);
+}
+
+QColor QQuickColorGroup::buttonText() const
+{
+ return color(QPalette::ButtonText);
+}
+
+void QQuickColorGroup::setButtonText(const QColor &color)
+{
+ setColor(QPalette::ButtonText, color, &QQuickColorGroup::buttonTextChanged);
+}
+
+void QQuickColorGroup::resetButtonText()
+{
+ resetColor(QPalette::ButtonText, &QQuickColorGroup::buttonTextChanged);
+}
+
+QColor QQuickColorGroup::dark() const
+{
+ return color(QPalette::Dark);
+}
+
+void QQuickColorGroup::setDark(const QColor &color)
+{
+ setColor(QPalette::Dark, color, &QQuickColorGroup::darkChanged);
+}
+
+void QQuickColorGroup::resetDark()
+{
+ resetColor(QPalette::Dark, &QQuickColorGroup::darkChanged);
+}
+
+QColor QQuickColorGroup::highlight() const
+{
+ return color(QPalette::Highlight);
+}
+
+void QQuickColorGroup::setHighlight(const QColor &color)
+{
+ setColor(QPalette::Highlight, color, &QQuickColorGroup::highlightChanged);
+}
+
+void QQuickColorGroup::resetHighlight()
+{
+ resetColor(QPalette::Highlight, &QQuickColorGroup::highlightChanged);
+}
+
+QColor QQuickColorGroup::highlightedText() const
+{
+ return color(QPalette::HighlightedText);
+}
+
+void QQuickColorGroup::setHighlightedText(const QColor &color)
+{
+ setColor(QPalette::HighlightedText, color, &QQuickColorGroup::highlightedTextChanged);
+}
+
+void QQuickColorGroup::resetHighlightedText()
+{
+ resetColor(QPalette::HighlightedText, &QQuickColorGroup::highlightedTextChanged);
+}
+
+QColor QQuickColorGroup::light() const
+{
+ return color(QPalette::Light);
+}
+
+void QQuickColorGroup::setLight(const QColor &color)
+{
+ setColor(QPalette::Light, color, &QQuickColorGroup::lightChanged);
+}
+
+void QQuickColorGroup::resetLight()
+{
+ resetColor(QPalette::Light, &QQuickColorGroup::lightChanged);
+}
+
+QColor QQuickColorGroup::link() const
+{
+ return color(QPalette::Link);
+}
+
+void QQuickColorGroup::setLink(const QColor &color)
+{
+ setColor(QPalette::Link, color, &QQuickColorGroup::linkChanged);
+}
+
+void QQuickColorGroup::resetLink()
+{
+ resetColor(QPalette::Link, &QQuickColorGroup::linkChanged);
+}
+
+QColor QQuickColorGroup::linkVisited() const
+{
+ return color(QPalette::LinkVisited);
+}
+
+void QQuickColorGroup::setLinkVisited(const QColor &color)
+{
+ setColor(QPalette::LinkVisited, color, &QQuickColorGroup::linkVisitedChanged);
+}
+
+void QQuickColorGroup::resetLinkVisited()
+{
+ resetColor(QPalette::LinkVisited, &QQuickColorGroup::linkVisitedChanged);
+}
+
+QColor QQuickColorGroup::mid() const
+{
+ return color(QPalette::Mid);
+}
+
+void QQuickColorGroup::setMid(const QColor &color)
+{
+ setColor(QPalette::Mid, color, &QQuickColorGroup::midChanged);
+}
+
+void QQuickColorGroup::resetMid()
+{
+ resetColor(QPalette::Mid, &QQuickColorGroup::midChanged);
+}
+
+QColor QQuickColorGroup::midlight() const
+{
+ return color(QPalette::Midlight);
+}
+
+void QQuickColorGroup::setMidlight(const QColor &color)
+{
+ setColor(QPalette::Midlight, color, &QQuickColorGroup::midlightChanged);
+}
+
+void QQuickColorGroup::resetMidlight()
+{
+ resetColor(QPalette::Midlight, &QQuickColorGroup::midlightChanged);
+}
+
+QColor QQuickColorGroup::shadow() const
+{
+ return color(QPalette::Shadow);
+}
+
+void QQuickColorGroup::setShadow(const QColor &color)
+{
+ setColor(QPalette::Shadow, color, &QQuickColorGroup::shadowChanged);
+}
+
+void QQuickColorGroup::resetShadow()
+{
+ resetColor(QPalette::Shadow, &QQuickColorGroup::shadowChanged);
+}
+
+QColor QQuickColorGroup::text() const
+{
+ return color(QPalette::Text);
+}
+
+void QQuickColorGroup::setText(const QColor &color)
+{
+ setColor(QPalette::Text, color, &QQuickColorGroup::textChanged);
+}
+
+void QQuickColorGroup::resetText()
+{
+ resetColor(QPalette::Text, &QQuickColorGroup::textChanged);
+}
+
+QColor QQuickColorGroup::toolTipBase() const
+{
+ return color(QPalette::ToolTipBase);
+}
+
+void QQuickColorGroup::setToolTipBase(const QColor &color)
+{
+ setColor(QPalette::ToolTipBase, color, &QQuickColorGroup::toolTipBaseChanged);
+}
+
+void QQuickColorGroup::resetToolTipBase()
+{
+ resetColor(QPalette::ToolTipBase, &QQuickColorGroup::toolTipBaseChanged);
+}
+
+QColor QQuickColorGroup::toolTipText() const
+{
+ return color(QPalette::ToolTipText);
+}
+
+void QQuickColorGroup::setToolTipText(const QColor &color)
+{
+ setColor(QPalette::ToolTipText, color, &QQuickColorGroup::toolTipTextChanged);
+}
+
+void QQuickColorGroup::resetToolTipText()
+{
+ resetColor(QPalette::ToolTipText, &QQuickColorGroup::toolTipTextChanged);
+}
+
+QColor QQuickColorGroup::window() const
+{
+ return color(QPalette::Window);
+}
+
+void QQuickColorGroup::setWindow(const QColor &color)
+{
+ setColor(QPalette::Window, color, &QQuickColorGroup::windowChanged);
+}
+
+void QQuickColorGroup::resetWindow()
+{
+ resetColor(QPalette::Window, &QQuickColorGroup::windowChanged);
+}
+
+QColor QQuickColorGroup::windowText() const
+{
+ return color(QPalette::WindowText);
+}
+
+void QQuickColorGroup::setWindowText(const QColor &color)
+{
+ setColor(QPalette::WindowText, color, &QQuickColorGroup::windowTextChanged);
+}
+
+void QQuickColorGroup::resetWindowText()
+{
+ resetColor(QPalette::WindowText, &QQuickColorGroup::windowTextChanged);
+}
+
+QPalette::ColorGroup QQuickColorGroup::groupTag() const
+{
+ return m_groupTag;
+}
+
+QQuickColorGroup::QQuickColorGroup(QObject *parent)
+ : QObject(parent)
+ , m_groupTag(defaultGroupTag())
+ , m_colorProvider(std::make_shared<QQuickPaletteColorProvider>())
+{
+}
+
+void QQuickColorGroup::setGroupTag(QPalette::ColorGroup tag)
+{
+ if (m_groupTag != tag) {
+ m_groupTag = tag;
+ Q_EMIT changed();
+ }
+}
+
+const QQuickPaletteColorProvider &QQuickColorGroup::colorProvider() const
+{
+ Q_ASSERT(m_colorProvider);
+ return *m_colorProvider;
+}
+
+QQuickPaletteColorProvider &QQuickColorGroup::colorProvider()
+{
+ return const_cast<QQuickPaletteColorProvider &>(
+ const_cast<const QQuickColorGroup*>(this)->colorProvider());
+}
+
+QQuickColorGroup *QQuickColorGroup::createWithParent(QQuickPalette &parent)
+{
+ return new QQuickColorGroup(parent);
+}
+
+QColor QQuickColorGroup::color(QPalette::ColorRole role) const
+{
+ return colorProvider().color(currentColorGroup(), role);
+}
+
+void QQuickColorGroup::setColor(QPalette::ColorRole role, QColor color, Notifier notifier)
+{
+ if (colorProvider().setColor(groupTag(), role, color)) {
+ Q_EMIT (this->*notifier)();
+ Q_EMIT changed();
+ }
+}
+
+void QQuickColorGroup::resetColor(QPalette::ColorRole role, Notifier notifier)
+{
+ if (colorProvider().resetColor(groupTag(), role)) {
+ Q_EMIT (this->*notifier)();
+ Q_EMIT changed();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickcolorgroup_p.h b/src/quick/items/qquickcolorgroup_p.h
new file mode 100644
index 0000000000..9d60c9aef2
--- /dev/null
+++ b/src/quick/items/qquickcolorgroup_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://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 QQUICKCOLORGROUP_H
+#define QQUICKCOLORGROUP_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QQuickColorGroup. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qpalette.h>
+
+#include <QtCore/private/qobject_p.h>
+
+#include <QtQuick/private/qtquickglobal_p.h>
+
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPalette;
+class QQuickPaletteColorProvider;
+
+class Q_QUICK_PRIVATE_EXPORT QQuickColorGroup : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QColor alternateBase READ alternateBase WRITE setAlternateBase RESET resetAlternateBase NOTIFY alternateBaseChanged FINAL)
+ Q_PROPERTY(QColor base READ base WRITE setBase RESET resetBase NOTIFY baseChanged FINAL)
+ Q_PROPERTY(QColor brightText READ brightText WRITE setBrightText RESET resetBrightText NOTIFY brightTextChanged FINAL)
+ Q_PROPERTY(QColor button READ button WRITE setButton RESET resetButton NOTIFY buttonChanged FINAL)
+ Q_PROPERTY(QColor buttonText READ buttonText WRITE setButtonText RESET resetButtonText NOTIFY buttonTextChanged FINAL)
+ Q_PROPERTY(QColor dark READ dark WRITE setDark RESET resetDark NOTIFY darkChanged FINAL)
+ Q_PROPERTY(QColor highlight READ highlight WRITE setHighlight RESET resetHighlight NOTIFY highlightChanged FINAL)
+ Q_PROPERTY(QColor highlightedText READ highlightedText WRITE setHighlightedText RESET resetHighlightedText NOTIFY highlightedTextChanged FINAL)
+ Q_PROPERTY(QColor light READ light WRITE setLight RESET resetLight NOTIFY lightChanged FINAL)
+ Q_PROPERTY(QColor link READ link WRITE setLink RESET resetLink NOTIFY linkChanged FINAL)
+ Q_PROPERTY(QColor linkVisited READ linkVisited WRITE setLinkVisited RESET resetLinkVisited NOTIFY linkVisitedChanged FINAL)
+ Q_PROPERTY(QColor mid READ mid WRITE setMid RESET resetMid NOTIFY midChanged FINAL)
+ Q_PROPERTY(QColor midlight READ midlight WRITE setMidlight RESET resetMidlight NOTIFY midlightChanged FINAL)
+ Q_PROPERTY(QColor shadow READ shadow WRITE setShadow RESET resetShadow NOTIFY shadowChanged FINAL)
+ Q_PROPERTY(QColor text READ text WRITE setText RESET resetText NOTIFY textChanged FINAL)
+ Q_PROPERTY(QColor toolTipBase READ toolTipBase WRITE setToolTipBase RESET resetToolTipBase NOTIFY toolTipBaseChanged FINAL)
+ Q_PROPERTY(QColor toolTipText READ toolTipText WRITE setToolTipText RESET resetToolTipText NOTIFY toolTipTextChanged FINAL)
+ Q_PROPERTY(QColor window READ window WRITE setWindow RESET resetWindow NOTIFY windowChanged FINAL)
+ Q_PROPERTY(QColor windowText READ windowText WRITE setWindowText RESET resetWindowText NOTIFY windowTextChanged FINAL)
+
+ QML_NAMED_ELEMENT(ColorGroup)
+ QML_ADDED_IN_VERSION(6, 0)
+
+public: // Types
+ using GroupPtr = QPointer<QQuickColorGroup>;
+
+public:
+ Q_DISABLE_COPY_MOVE(QQuickColorGroup)
+
+ explicit QQuickColorGroup(QObject *parent = nullptr);
+
+ QColor alternateBase() const;
+ void setAlternateBase(const QColor &color);
+ void resetAlternateBase();
+
+ QColor base() const;
+ void setBase(const QColor &color);
+ void resetBase();
+
+ QColor brightText() const;
+ void setBrightText(const QColor &color);
+ void resetBrightText();
+
+ QColor button() const;
+ void setButton(const QColor &color);
+ void resetButton();
+
+ QColor buttonText() const;
+ void setButtonText(const QColor &color);
+ void resetButtonText();
+
+ QColor dark() const;
+ void setDark(const QColor &color);
+ void resetDark();
+
+ QColor highlight() const;
+ void setHighlight(const QColor &color);
+ void resetHighlight();
+
+ QColor highlightedText() const;
+ void setHighlightedText(const QColor &color);
+ void resetHighlightedText();
+
+ QColor light() const;
+ void setLight(const QColor &color);
+ void resetLight();
+
+ QColor link() const;
+ void setLink(const QColor &color);
+ void resetLink();
+
+ QColor linkVisited() const;
+ void setLinkVisited(const QColor &color);
+ void resetLinkVisited();
+
+ QColor mid() const;
+ void setMid(const QColor &color);
+ void resetMid();
+
+ QColor midlight() const;
+ void setMidlight(const QColor &color);
+ void resetMidlight();
+
+ QColor shadow() const;
+ void setShadow(const QColor &color);
+ void resetShadow();
+
+ QColor text() const;
+ void setText(const QColor &color);
+ void resetText();
+
+ QColor toolTipBase() const;
+ void setToolTipBase(const QColor &color);
+ void resetToolTipBase();
+
+ QColor toolTipText() const;
+ void setToolTipText(const QColor &color);
+ void resetToolTipText();
+
+ QColor window() const;
+ void setWindow(const QColor &color);
+ void resetWindow();
+
+ QColor windowText() const;
+ void setWindowText(const QColor &color);
+ void resetWindowText();
+
+ QPalette::ColorGroup groupTag() const;
+ void setGroupTag(QPalette::ColorGroup tag);
+
+ const QQuickPaletteColorProvider &colorProvider() const;
+ QQuickPaletteColorProvider &colorProvider();
+
+ static QQuickColorGroup* createWithParent(QQuickPalette &parent);
+
+Q_SIGNALS:
+ void alternateBaseChanged();
+ void baseChanged();
+ void brightTextChanged();
+ void buttonChanged();
+ void buttonTextChanged();
+ void darkChanged();
+ void highlightChanged();
+ void highlightedTextChanged();
+ void lightChanged();
+ void linkChanged();
+ void linkVisitedChanged();
+ void midChanged();
+ void midlightChanged();
+ void shadowChanged();
+ void textChanged();
+ void toolTipBaseChanged();
+ void toolTipTextChanged();
+ void windowChanged();
+ void windowTextChanged();
+
+ void changed();
+
+protected:
+ explicit QQuickColorGroup(QQuickPalette &parent);
+
+ static constexpr QPalette::ColorGroup defaultGroupTag() { return QPalette::All; }
+
+ virtual QPalette::ColorGroup currentColorGroup() const;
+
+private:
+ using Notifier = void (QQuickColorGroup::* )();
+
+ QColor color(QPalette::ColorRole role) const;
+ void setColor(QPalette::ColorRole role, QColor color, Notifier notifier);
+ void resetColor(QPalette::ColorRole role, Notifier notifier);
+
+private:
+ QPalette::ColorGroup m_groupTag;
+ std::shared_ptr<QQuickPaletteColorProvider> m_colorProvider;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickColorGroup)
+
+#endif // QQUICKCOLORGROUP_H
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 32695e9245..3f32fc5243 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -61,6 +61,7 @@ class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChange
{
Q_DECLARE_PUBLIC(QQuickDragAttached)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
static QQuickDragAttachedPrivate *get(QQuickDragAttached *attached) {
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 9dbaac18f9..36b0a2bfd1 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -173,6 +173,7 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
//### consider drag and drop
QML_NAMED_ELEMENT(Drag)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Drag is only available via attached properties.")
QML_ATTACHED(QQuickDragAttached)
@@ -260,6 +261,7 @@ class QQuickDragAttached : public QObject
Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickDragAttached(QObject *parent);
diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h
index ee2deaa97a..b1d3d78a37 100644
--- a/src/quick/items/qquickdroparea_p.h
+++ b/src/quick/items/qquickdroparea_p.h
@@ -81,6 +81,7 @@ class QQuickDropEvent : public QObject
Q_PROPERTY(QList<QUrl> urls READ urls)
Q_PROPERTY(QStringList formats READ formats)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickDropEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {}
@@ -127,6 +128,7 @@ class QQuickDropAreaDrag : public QObject
Q_PROPERTY(qreal y READ y NOTIFY positionChanged)
Q_PROPERTY(QObject *source READ source NOTIFY sourceChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent = 0);
~QQuickDropAreaDrag();
@@ -154,6 +156,7 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem
Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
Q_PROPERTY(QQuickDropAreaDrag *drag READ drag CONSTANT)
QML_NAMED_ELEMENT(DropArea)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickDropArea(QQuickItem *parent=0);
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 950afaed52..e491369d44 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -580,8 +580,6 @@ Item {
\sa QTouchDevice::capabilities
*/
-typedef QHash<const QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
-Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)
struct ConstructableQQuickPointerDevice : public QQuickPointerDevice
{
@@ -591,14 +589,21 @@ struct ConstructableQQuickPointerDevice : public QQuickPointerDevice
: QQuickPointerDevice(devType, pType, caps, maxPoints, buttonCount, name, uniqueId) {}
};
+
+template<typename Key>
+struct PointerDeviceHash : public QHash<Key, ConstructableQQuickPointerDevice *>
+{
+ ~PointerDeviceHash() { qDeleteAll(*this); }
+};
+using PointerDeviceForTouchDeviceHash = PointerDeviceHash<const QTouchDevice *>;
+Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)
Q_GLOBAL_STATIC_WITH_ARGS(ConstructableQQuickPointerDevice, g_genericMouseDevice,
(QQuickPointerDevice::Mouse,
QQuickPointerDevice::GenericPointer,
QQuickPointerDevice::Position | QQuickPointerDevice::Scroll | QQuickPointerDevice::Hover,
1, 3, QLatin1String("core pointer"), 0))
-
#if QT_CONFIG(tabletevent)
-typedef QHash<qint64, QQuickPointerDevice *> PointerDeviceForDeviceIdHash;
+using PointerDeviceForDeviceIdHash = PointerDeviceHash<qint64>;
Q_GLOBAL_STATIC(PointerDeviceForDeviceIdHash, g_tabletDevices)
#endif
@@ -639,20 +644,28 @@ QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d)
qWarning() << "QQuickWindowPrivate::touchDevice: creating touch device from nullptr device in QTouchEvent";
}
- QQuickPointerDevice *dev = new QQuickPointerDevice(type, QQuickPointerDevice::Finger,
- caps, maximumTouchPoints, 0, name, 0);
+ ConstructableQQuickPointerDevice *dev = new ConstructableQQuickPointerDevice(
+ type, QQuickPointerDevice::Finger, caps, maximumTouchPoints, 0, name, 0);
g_touchDevices->insert(d, dev);
return dev;
}
const QTouchDevice *QQuickPointerDevice::qTouchDevice() const
{
- return g_touchDevices->key(const_cast<QQuickPointerDevice *>(this));
+ for (auto it = g_touchDevices->constBegin(), end = g_touchDevices->constEnd(); it != end; ++it) {
+ if (it.value() == this)
+ return it.key();
+ }
+ return nullptr;
}
QList<QQuickPointerDevice*> QQuickPointerDevice::touchDevices()
{
- return g_touchDevices->values();
+ QList<QQuickPointerDevice *> result;
+ result.reserve(g_touchDevices->size());
+ for (auto device : *g_touchDevices)
+ result.append(device);
+ return result;
}
QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
@@ -723,8 +736,10 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event
break;
}
- QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
- QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());
+ ConstructableQQuickPointerDevice *device = new ConstructableQQuickPointerDevice(
+ type, ptype, caps, 1, buttonCount,
+ QLatin1String("tablet tool ") + QString::number(event->uniqueId()),
+ event->uniqueId());
g_tabletDevices->insert(key, device);
return device;
@@ -2101,7 +2116,7 @@ const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int point
auto it = std::find_if(tps.constBegin(), tps.constEnd(),
[pointId](QTouchEvent::TouchPoint const& tp) { return tp.id() == pointId; } );
// return the pointer to the actual TP in QTouchEvent::_touchPoints
- return (it == tps.constEnd() ? nullptr : it.operator->());
+ return (it == tps.constEnd() ? nullptr : &*it);
}
/*!
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 7004b341de..b1d8b52372 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -56,12 +56,14 @@
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
-#include <QtGui/qvector2d.h>
#include <QtGui/qevent.h>
+#include <QtGui/qtouchdevice.h>
+#include <QtGui/qvector2d.h>
+#include <QtQuick/qquickitem.h>
+
#if QT_CONFIG(shortcut)
# include <QtGui/qkeysequence.h>
#endif
-#include <QtQuick/qquickitem.h>
QT_BEGIN_NAMESPACE
@@ -87,6 +89,7 @@ class QQuickKeyEvent : public QObject
Q_PROPERTY(quint32 nativeScanCode READ nativeScanCode CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickKeyEvent()
@@ -117,7 +120,7 @@ public:
void setAccepted(bool accepted) { event.setAccepted(accepted); }
#if QT_CONFIG(shortcut)
- Q_REVISION(2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); }
+ Q_REVISION(2, 2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); }
#endif
private:
@@ -133,12 +136,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject
Q_PROPERTY(int button READ button CONSTANT)
Q_PROPERTY(int buttons READ buttons CONSTANT)
Q_PROPERTY(int modifiers READ modifiers CONSTANT)
- Q_PROPERTY(int source READ source CONSTANT REVISION 7)
+ Q_PROPERTY(int source READ source CONSTANT REVISION(2, 7))
Q_PROPERTY(bool wasHeld READ wasHeld CONSTANT)
Q_PROPERTY(bool isClick READ isClick CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
- Q_PROPERTY(int flags READ flags CONSTANT REVISION 11)
+ Q_PROPERTY(int flags READ flags CONSTANT REVISION(2, 11))
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickMouseEvent()
@@ -205,6 +209,7 @@ class QQuickWheelEvent : public QObject
Q_PROPERTY(bool inverted READ inverted CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickWheelEvent()
@@ -250,6 +255,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject
Q_OBJECT
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickCloseEvent() {}
@@ -278,7 +284,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject
QML_NAMED_ELEMENT(EventPoint)
QML_UNCREATABLE("EventPoint is only available as a member of PointerEvent.")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
enum State {
@@ -373,7 +379,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint
QML_NAMED_ELEMENT(EventTouchPoint)
QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
QQuickEventTouchPoint(QQuickPointerTouchEvent *parent);
@@ -406,7 +412,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject
QML_NAMED_ELEMENT(PointerEvent)
QML_UNCREATABLE("PointerEvent is only available as a parameter of several signals in PointerHandler")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
@@ -502,7 +508,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointE
QML_NAMED_ELEMENT(PointerMouseEvent)
QML_UNCREATABLE("PointerMouseEvent is only available as a parameter of several signals in PointerHandler")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device);
@@ -526,7 +532,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent
QML_NAMED_ELEMENT(PointerTouchEvent)
QML_UNCREATABLE("PointerTouchEvent is only available as a parameter of several signals in PointerHandler")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
@@ -578,7 +584,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint
QML_NAMED_ELEMENT(EventTabletPoint)
QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
- QML_ADDED_IN_MINOR_VERSION(15)
+ QML_ADDED_IN_VERSION(2, 15)
public:
QQuickEventTabletPoint(QQuickPointerTabletEvent *parent);
@@ -655,7 +661,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
QML_NAMED_ELEMENT(PointerScrollEvent)
QML_UNCREATABLE("PointerScrollEvent is only available via the WheelHandler::wheel signal.")
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
public:
QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device);
@@ -707,7 +713,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
QML_NAMED_ELEMENT(PointerDevice)
QML_UNCREATABLE("PointerDevice is only available as a property of PointerEvent.")
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
public:
enum DeviceType : qint16 {
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index c91a5ef92b..00cd0a2d61 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1799,11 +1799,10 @@ void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent,
data.vTime = timeline.time();
}
-void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+void QQuickFlickable::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickFlickable);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
bool changed = false;
if (newGeometry.width() != oldGeometry.width()) {
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 2d8d4a5e9a..d0fea9d5c5 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -80,7 +80,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged)
Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged)
- Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION 10)
+ Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION(2, 10))
Q_PROPERTY(QQuickTransition *rebound READ rebound WRITE setRebound NOTIFY reboundChanged)
Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged)
Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
@@ -106,15 +106,16 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(QQuickFlickableVisibleArea *visibleArea READ visibleArea CONSTANT)
Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged)
- Q_PROPERTY(bool synchronousDrag READ synchronousDrag WRITE setSynchronousDrag NOTIFY synchronousDragChanged REVISION 12)
+ Q_PROPERTY(bool synchronousDrag READ synchronousDrag WRITE setSynchronousDrag NOTIFY synchronousDragChanged REVISION(2, 12))
- Q_PROPERTY(qreal horizontalOvershoot READ horizontalOvershoot NOTIFY horizontalOvershootChanged REVISION 9)
- Q_PROPERTY(qreal verticalOvershoot READ verticalOvershoot NOTIFY verticalOvershootChanged REVISION 9)
+ Q_PROPERTY(qreal horizontalOvershoot READ horizontalOvershoot NOTIFY horizontalOvershootChanged REVISION(2, 9))
+ Q_PROPERTY(qreal verticalOvershoot READ verticalOvershoot NOTIFY verticalOvershootChanged REVISION(2, 9))
Q_PROPERTY(QQmlListProperty<QObject> flickableData READ flickableData)
Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren)
Q_CLASSINFO("DefaultProperty", "flickableData")
QML_NAMED_ELEMENT(Flickable)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickFlickable(QQuickItem *parent=nullptr);
@@ -252,7 +253,7 @@ Q_SIGNALS:
void flickableDirectionChanged();
void interactiveChanged();
void boundsBehaviorChanged();
- Q_REVISION(10) void boundsMovementChanged();
+ Q_REVISION(2, 10) void boundsMovementChanged();
void reboundChanged();
void maximumFlickVelocityChanged();
void flickDecelerationChanged();
@@ -264,11 +265,11 @@ Q_SIGNALS:
void dragStarted();
void dragEnded();
void pixelAlignedChanged();
- Q_REVISION(12) void synchronousDragChanged();
- Q_REVISION(9) void horizontalOvershootChanged();
- Q_REVISION(9) void verticalOvershootChanged();
+ Q_REVISION(2, 12) void synchronousDragChanged();
+ Q_REVISION(2, 9) void horizontalOvershootChanged();
+ Q_REVISION(2, 9) void verticalOvershootChanged();
- // The next four signals should be marked as Q_REVISION(12). See QTBUG-71243
+ // The next four signals should be marked as Q_REVISION(2, 12). See QTBUG-71243
void atXEndChanged();
void atYEndChanged();
void atXBeginningChanged();
@@ -302,8 +303,7 @@ protected:
qreal vHeight() const;
void componentComplete() override;
virtual void viewportMoved(Qt::Orientations orient);
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void mouseUngrabEvent() override;
bool filterMouseEvent(QQuickItem *receiver, QMouseEvent *event);
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 3f5f11effd..0d7f27492a 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -285,6 +285,7 @@ class QQuickFlickableVisibleArea : public QObject
Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr);
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index 42c632a33c..8d6716ec53 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem
Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged)
Q_PROPERTY(Side side READ side NOTIFY sideChanged)
QML_NAMED_ELEMENT(Flipable)
+ QML_ADDED_IN_VERSION(2, 0)
//### flipAxis
//### flipRotation
public:
diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h
index c32fa93cd9..d3e9197fc7 100644
--- a/src/quick/items/qquickfocusscope_p.h
+++ b/src/quick/items/qquickfocusscope_p.h
@@ -59,6 +59,7 @@ class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem
{
Q_OBJECT
QML_NAMED_ELEMENT(FocusScope)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickFocusScope(QQuickItem *parent=nullptr);
virtual ~QQuickFocusScope();
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index d5550e78b6..41a56788fa 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -39,8 +39,8 @@
#include "qquickframebufferobject.h"
-#include <QtGui/QOpenGLFramebufferObject>
-#include <QtGui/QOpenGLFunctions>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFunctions>
#include <private/qquickitem_p.h>
#include <private/qsgadaptationlayer_p.h>
#include <qsgtextureprovider.h>
@@ -75,6 +75,12 @@ public:
* for integrating OpenGL rendering using a framebuffer object (FBO)
* with Qt Quick.
*
+ * \warning This class is only functional when Qt Quick is rendering via
+ * OpenGL. It is not compatible with other graphics APIs, such as Vulkan or
+ * Metal. It should be treated as a legacy class that is only present in order
+ * to enable Qt 5 applications to function without source compatibility breaks
+ * as long as they tie themselves to openGL.
+ *
* On most platforms, the rendering will occur on a \l {Scene Graph and Rendering}{dedicated thread}.
* For this reason, the QQuickFramebufferObject class enforces a strict
* separation between the item implementation and the FBO rendering. All
@@ -83,11 +89,6 @@ public:
* Everything that relates to rendering must be located in the
* QQuickFramebufferObject::Renderer class.
*
- * \warning This class is only functional when Qt Quick is rendering
- * via OpenGL, either directly or through the \l{Scene Graph
- * Adaptations}{RHI-based rendering path}. It is not compatible with
- * other RHI backends, such as, Vulkan or Metal.
- *
* To avoid race conditions and read/write issues from two threads
* it is important that the renderer and the item never read or
* write shared variables. Communication between the item and the renderer
@@ -184,9 +185,9 @@ bool QQuickFramebufferObject::mirrorVertically() const
/*!
* \internal
*/
-void QQuickFramebufferObject::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickFramebufferObject::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
Q_D(QQuickFramebufferObject);
if (newGeometry.size() != oldGeometry.size() && d->followsItemSize)
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index e26c8293a6..4bb335c6ed 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -48,9 +48,6 @@ class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
-// ### Qt 6: Consider what to do here. QQuickFbo supports both direct OpenGL and
-// OpenGL via QRhi, but it cannot function when running with another rhi backend.
-
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{
Q_OBJECT
@@ -92,7 +89,7 @@ public:
void releaseResources() override;
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
protected:
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index a3d04f5dd3..b7f52a8146 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -269,12 +269,14 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui
if (!node) {
QSGRenderContext *rc = QQuickWindowPrivate::get(m_item->window())->context;
- node = rc->sceneGraphContext()->createShaderEffectNode(rc, mgr);
+ node = rc->sceneGraphContext()->createShaderEffectNode(rc);
if (!node) {
qWarning("No shader effect node");
return nullptr;
}
m_dirty = QSGShaderEffectNode::DirtyShaderAll;
+ connect(node, &QSGShaderEffectNode::textureChanged,
+ this, &QQuickGenericShaderEffect::markGeometryDirtyAndUpdateIfSupportsAtlas);
}
QSGShaderEffectNode::SyncData sd;
@@ -369,7 +371,6 @@ QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager(
if (m_mgr) {
connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(logChanged()));
connect(m_mgr, SIGNAL(logAndStatusChanged()), m_item, SIGNAL(statusChanged()));
- connect(m_mgr, SIGNAL(textureChanged()), this, SLOT(markGeometryDirtyAndUpdateIfSupportsAtlas()));
connect(m_mgr, &QSGGuiThreadShaderEffectManager::shaderCodePrepared, this, &QQuickGenericShaderEffect::shaderCodePrepared);
}
}
diff --git a/src/quick/items/qquickgraphicsdevice.cpp b/src/quick/items/qquickgraphicsdevice.cpp
new file mode 100644
index 0000000000..029546a5f8
--- /dev/null
+++ b/src/quick/items/qquickgraphicsdevice.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $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 "qquickgraphicsdevice_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickGraphicsDevice
+ \since 6.0
+ \inmodule QtQuick
+
+ \brief The QQuickGraphicsDevice class provides an opaque container for
+ native graphics objects representing graphics devices or contexts.
+
+ \sa QQuickWindow::setGraphicsDevice(), QQuickRenderTarget
+*/
+
+/*!
+ Constructs a default QQuickGraphicsDEvice that does not reference any native
+ objects.
+ */
+QQuickGraphicsDevice::QQuickGraphicsDevice()
+ : d(new QQuickGraphicsDevicePrivate)
+{
+}
+
+/*!
+ \internal
+ */
+void QQuickGraphicsDevice::detach()
+{
+ qAtomicDetach(d);
+}
+
+/*!
+ \internal
+ */
+QQuickGraphicsDevice::QQuickGraphicsDevice(const QQuickGraphicsDevice &other)
+ : d(other.d)
+{
+ d->ref.ref();
+}
+
+/*!
+ \internal
+ */
+QQuickGraphicsDevice &QQuickGraphicsDevice::operator=(const QQuickGraphicsDevice &other)
+{
+ qAtomicAssign(d, other.d);
+ return *this;
+}
+
+/*!
+ Destructor.
+ */
+QQuickGraphicsDevice::~QQuickGraphicsDevice()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+/*!
+ Constructs a default QQuickRenderTarget that does not reference any native
+ objects.
+ */
+bool QQuickGraphicsDevice::isNull() const
+{
+ return d->type == QQuickGraphicsDevicePrivate::Type::Null;
+}
+
+/*!
+ \return a new QQuickGraphicsDevice referencing an existing QOpenGLContext.
+
+ This factory function is suitable for OpenGL.
+ */
+QQuickGraphicsDevice QQuickGraphicsDevice::fromOpenGLContext(QOpenGLContext *context)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::OpenGLContext;
+ d->u.context = context;
+ return dev;
+}
+
+/*!
+ \return a new QQuickGraphicsDevice referencing a native device and context
+ object.
+
+ This factory function is suitable for:
+
+ \list
+
+ \li Direct3D11 - \a device is expected to be a \c{ID3D11Device*}, \a
+ context is expected to be a \c{ID3D11DeviceContext*}.
+
+ \endlist
+
+ \note the resulting QQuickGraphicsDevice does not own any native resources,
+ it merely contains references. It is the caller's responsibility to ensure
+ that the native resource exists as long as necessary.
+
+ */
+QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndContext(void *device, void *context)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::DeviceAndContext;
+ d->u.deviceAndContext = { device, context };
+ return dev;
+}
+
+/*!
+ \return a new QQuickGraphicsDevice referencing a native device and command
+ queue object.
+
+ This factory function is suitable for:
+
+ \list
+
+ \li Metal - \a device is expected to be a \c{MTLDevice*}, \a cmdQueue is
+ expected to be a \c{MTLCommandQueue*}.
+
+ \endlist
+
+ \note the resulting QQuickGraphicsDevice does not own any native resources,
+ it merely contains references. It is the caller's responsibility to ensure
+ that the native resource exists as long as necessary.
+
+ */
+QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndCommandQueue(void *device, void *cmdQueue)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::DeviceAndCommandQueue;
+ d->u.deviceAndCommandQueue = { device, cmdQueue };
+ return dev;
+}
+
+/*!
+ \return a new QQuickGraphicsDevice referencing a native device and related
+ objects.
+
+ This factory function is suitable for:
+
+ \list
+
+ \li Vulkan - \a physicalDevice is expected to be \c VkPhysicalDevice, \a
+ device is expected to be a \a VkDevice, while \a queueFamilyIndex is the
+ index of the graphics queue family on the device.
+
+ \endlist
+
+ \note the resulting QQuickGraphicsDevice does not own any native resources,
+ it merely contains references. It is the caller's responsibility to ensure
+ that the native resource exists as long as necessary.
+
+ */
+QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceObjects(void *physicalDevice, void *device, int queueFamilyIndex)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::DeviceObjects;
+ d->u.deviceObjects = { physicalDevice, device, queueFamilyIndex };
+ return dev;
+}
+
+QQuickGraphicsDevicePrivate::QQuickGraphicsDevicePrivate()
+ : ref(1)
+{
+}
+
+QQuickGraphicsDevicePrivate::QQuickGraphicsDevicePrivate(const QQuickGraphicsDevicePrivate *other)
+ : ref(1),
+ type(other->type),
+ u(other->u)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h b/src/quick/items/qquickgraphicsdevice.h
index 2fc3c69285..811d510a5f 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h
+++ b/src/quick/items/qquickgraphicsdevice.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,38 +37,37 @@
**
****************************************************************************/
-#ifndef QSGD3D12INTERNALRECTANGLENODE_P_H
-#define QSGD3D12INTERNALRECTANGLENODE_P_H
+#ifndef QQUICKGRAPHICSDEVICE_H
+#define QQUICKGRAPHICSDEVICE_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 <private/qsgbasicinternalrectanglenode_p.h>
-#include "qsgd3d12builtinmaterials_p.h"
+#include <QtQuick/qtquickglobal.h>
QT_BEGIN_NAMESPACE
-class QSGD3D12InternalRectangleNode : public QSGBasicInternalRectangleNode
+class QQuickGraphicsDevicePrivate;
+class QOpenGLContext;
+
+class Q_QUICK_EXPORT QQuickGraphicsDevice
{
public:
- QSGD3D12InternalRectangleNode();
+ QQuickGraphicsDevice();
+ ~QQuickGraphicsDevice();
+ QQuickGraphicsDevice(const QQuickGraphicsDevice &other);
+ QQuickGraphicsDevice &operator=(const QQuickGraphicsDevice &other);
-private:
- void updateMaterialAntialiasing() override;
- void updateMaterialBlending(QSGNode::DirtyState *state) override;
+ bool isNull() const;
- QSGD3D12VertexColorMaterial m_material;
- QSGD3D12SmoothColorMaterial m_smoothMaterial;
+ static QQuickGraphicsDevice fromOpenGLContext(QOpenGLContext *context);
+ static QQuickGraphicsDevice fromDeviceAndContext(void *device, void *context);
+ static QQuickGraphicsDevice fromDeviceAndCommandQueue(void *device, void *cmdQueue);
+ static QQuickGraphicsDevice fromDeviceObjects(void *physicalDevice, void *device, int queueFamilyIndex);
+
+private:
+ void detach();
+ QQuickGraphicsDevicePrivate *d;
+ friend class QQuickGraphicsDevicePrivate;
};
QT_END_NAMESPACE
-#endif // QSGD3D12INTERNALRECTANGLENODE_P_H
+#endif // QQUICKGRAPHICSDEVICE_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h b/src/quick/items/qquickgraphicsdevice_p.h
index f6a5257773..0a206725a6 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h
+++ b/src/quick/items/qquickgraphicsdevice_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QSGD3D12TEXTURE_P_H
-#define QSGD3D12TEXTURE_P_H
+#ifndef QQUICKGRAPHICSDEVICE_P_H
+#define QQUICKGRAPHICSDEVICE_P_H
//
// W A R N I N G
@@ -51,46 +51,55 @@
// We mean it.
//
-#include <private/qsgtexture_p.h>
-#include <basetsd.h>
+#include <QtQuick/private/qtquickglobal_p.h>
+#include <QAtomicInt>
+#include "qquickgraphicsdevice.h"
QT_BEGIN_NAMESPACE
-class QSGD3D12Engine;
-class QSGD3D12TexturePrivate;
-
-class QSGD3D12Texture : public QSGTexture
+class Q_QUICK_PRIVATE_EXPORT QQuickGraphicsDevicePrivate
{
- Q_DECLARE_PRIVATE(QSGD3D12Texture)
public:
- QSGD3D12Texture(QSGD3D12Engine *engine);
- ~QSGD3D12Texture();
+ static QQuickGraphicsDevicePrivate *get(QQuickGraphicsDevice *p) { return p->d; }
+ static const QQuickGraphicsDevicePrivate *get(const QQuickGraphicsDevice *p) { return p->d; }
+ QQuickGraphicsDevicePrivate();
+ QQuickGraphicsDevicePrivate(const QQuickGraphicsDevicePrivate *other);
- void create(const QImage &image, uint flags);
+ enum class Type {
+ Null,
+ OpenGLContext,
+ DeviceAndContext,
+ DeviceAndCommandQueue,
+ DeviceObjects
+ };
- int textureId() const override;
- QSize textureSize() const override;
- bool hasAlphaChannel() const override;
- bool hasMipmaps() const override;
- QRectF normalizedTextureSubRect() const override;
- void bind() override;
+ QAtomicInt ref;
+ Type type = Type::Null;
-protected:
- QSGD3D12Engine *m_engine;
- QImage m_image;
- bool m_createPending = false;
- bool m_createdWithMipMaps = false;
- uint m_id = 0;
- bool m_alphaWanted = false;
-};
+ struct DeviceAndContext {
+ void *device;
+ void *context;
+ };
-class QSGD3D12TexturePrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGD3D12Texture)
-public:
- int comparisonKey() const override;
+ struct DeviceAndCommandQueue {
+ void *device;
+ void *cmdQueue;
+ };
+
+ struct DeviceObjects {
+ void *physicalDevice;
+ void *device;
+ int queueFamilyIndex;
+ };
+
+ union {
+ QOpenGLContext *context;
+ DeviceAndContext deviceAndContext;
+ DeviceAndCommandQueue deviceAndCommandQueue;
+ DeviceObjects deviceObjects;
+ } u;
};
QT_END_NAMESPACE
-#endif
+#endif // QQUICKGRAPHICSDEVICE_P_H
diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp
index 8f6f4386fb..0e711afcf2 100644
--- a/src/quick/items/qquickgraphicsinfo.cpp
+++ b/src/quick/items/qquickgraphicsinfo.cpp
@@ -40,7 +40,7 @@
#include "qquickgraphicsinfo_p.h"
#include "qquickwindow.h"
#include "qquickitem.h"
-#include <QtGui/qopenglcontext.h>
+#include <qopenglcontext.h>
QT_BEGIN_NAMESPACE
@@ -95,7 +95,6 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object)
\li GraphicsInfo.Unknown - the default value when no active scenegraph is associated with the item
\li GraphicsInfo.Software - Qt Quick's software renderer based on QPainter with the raster paint engine
\li GraphicsInfo.OpenGL - OpenGL or OpenGL ES
- \li GraphicsInfo.Direct3D12 - Direct3D 12
\li GraphicsInfo.OpenVG - OpenVG
\li GraphicsInfo.OpenGLRhi - OpenGL on top of QRhi, a graphics abstraction layer
\li GraphicsInfo.Direct3D11Rhi - Direct3D 11 on top of QRhi, a graphics abstraction layer
diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h
index 066a419c37..c55a35ed5e 100644
--- a/src/quick/items/qquickgraphicsinfo_p.h
+++ b/src/quick/items/qquickgraphicsinfo_p.h
@@ -76,7 +76,7 @@ class QQuickGraphicsInfo : public QObject
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
QML_NAMED_ELEMENT(GraphicsInfo)
- QML_ADDED_IN_MINOR_VERSION(8)
+ QML_ADDED_IN_VERSION(2, 8)
QML_UNCREATABLE("GraphicsInfo is only available via attached properties.")
QML_ATTACHED(QQuickGraphicsInfo)
@@ -85,7 +85,6 @@ public:
Unknown = QSGRendererInterface::Unknown,
Software = QSGRendererInterface::Software,
OpenGL = QSGRendererInterface::OpenGL,
- Direct3D12 = QSGRendererInterface::Direct3D12,
OpenVG = QSGRendererInterface::OpenVG,
OpenGLRhi = QSGRendererInterface::OpenGLRhi,
Direct3D11Rhi = QSGRendererInterface::Direct3D11Rhi,
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 7ca5b0c34c..32cc5edf40 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -2153,7 +2153,7 @@ void QQuickGridView::keyPressEvent(QKeyEvent *event)
QQuickItemView::keyPressEvent(event);
}
-void QQuickGridView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickGridView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickGridView);
d->resetColumns();
@@ -2167,7 +2167,7 @@ void QQuickGridView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
QQuickFlickable::setContentY(d->contentYForPosition(d->position()));
}
- QQuickItemView::geometryChanged(newGeometry, oldGeometry);
+ QQuickItemView::geometryChange(newGeometry, oldGeometry);
}
void QQuickGridView::initItem(int index, QObject *obj)
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 9072e5f269..8aa7f0be12 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
Q_CLASSINFO("DefaultProperty", "data")
QML_NAMED_ELEMENT(GridView)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQuickGridViewAttached)
public:
@@ -121,7 +122,7 @@ Q_SIGNALS:
protected:
void viewportMoved(Qt::Orientations) override;
void keyPressEvent(QKeyEvent *) override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void initItem(int index, QObject *item) override;
};
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 1882ec8997..c58454362c 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -628,9 +628,9 @@ void QQuickImage::updatePaintedGeometry()
emit paintedGeometryChanged();
}
-void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickImage::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
+ QQuickImageBase::geometryChange(newGeometry, oldGeometry);
if (newGeometry.size() != oldGeometry.size())
updatePaintedGeometry();
}
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index e22a94c5af..b8678be5b7 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -66,10 +66,11 @@ 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 3)
- Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5)
- Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION 15)
+ Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION(2, 3))
+ Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION(2, 5))
+ Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION(2, 15))
QML_NAMED_ELEMENT(Image)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickImage(QQuickItem *parent=nullptr);
@@ -114,8 +115,8 @@ Q_SIGNALS:
void paintedGeometryChanged();
void horizontalAlignmentChanged(HAlignment alignment);
void verticalAlignmentChanged(VAlignment alignment);
- Q_REVISION(3) void mipmapChanged(bool);
- Q_REVISION(5) void autoTransformChanged();
+ Q_REVISION(2, 3) void mipmapChanged(bool);
+ Q_REVISION(2, 5) void autoTransformChanged();
private Q_SLOTS:
void invalidateSceneGraph();
@@ -126,7 +127,7 @@ protected:
void updatePaintedGeometry();
void releaseResources() override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 8849c2005c..0e5313db67 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -298,9 +298,8 @@ void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions)
options |= QQuickPixmap::Cache;
d->pix.clear(this);
QUrl loadUrl = url;
- QQmlEngine* engine = qmlEngine(this);
- if (engine && engine->urlInterceptor())
- loadUrl = engine->urlInterceptor()->intercept(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
+ if (const QQmlEngine *engine = qmlEngine(this))
+ loadUrl = engine->interceptUrl(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
if (loadOptions & HandleDPR) {
const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 095547a2cf..9265792be1 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -69,12 +69,12 @@ 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)
- Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION 15)
+ Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION(2, 14))
+ Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION(2, 14))
+ Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION(2, 15))
QML_NAMED_ELEMENT(ImageBase);
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
QML_UNCREATABLE("ImageBase is an abstract base class.")
public:
@@ -141,10 +141,10 @@ Q_SIGNALS:
void asynchronousChanged();
void cacheChanged();
void mirrorChanged();
- Q_REVISION(14) void currentFrameChanged();
- Q_REVISION(14) void frameCountChanged();
- Q_REVISION(15) void sourceClipRectChanged();
- Q_REVISION(15) void colorSpaceChanged();
+ Q_REVISION(2, 14) void currentFrameChanged();
+ Q_REVISION(2, 14) void frameCountChanged();
+ Q_REVISION(2, 15) void sourceClipRectChanged();
+ Q_REVISION(2, 15) void colorSpaceChanged();
protected:
void loadEmptyUrl();
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 3f655e84fa..3280ae861f 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3711,15 +3711,16 @@ void QQuickItem::setClip(bool c)
emit clipChanged(c);
}
-
/*!
+ \since 6.0
+
This function is called to handle this item's changes in
geometry from \a oldGeometry to \a newGeometry. If the two
geometries are the same, it doesn't do anything.
Derived classes must call the base class method within their implementation.
*/
-void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickItem);
@@ -3802,7 +3803,7 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
\note All classes with QSG prefix should be used solely on the scene graph's
rendering thread. See \l {Scene Graph and Rendering} for more information.
- \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
+ \sa QSGMaterial, QSGGeometryNode, QSGGeometry,
QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty(), {Graphics Resource Handling}
*/
@@ -6618,8 +6619,8 @@ void QQuickItem::setX(qreal v)
d->dirty(QQuickItemPrivate::Position);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(oldx, d->y, d->width, d->height));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(oldx, d->y, d->width, d->height));
}
void QQuickItem::setY(qreal v)
@@ -6635,8 +6636,8 @@ void QQuickItem::setY(qreal v)
d->dirty(QQuickItemPrivate::Position);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, oldy, d->width, d->height));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, oldy, d->width, d->height));
}
/*!
@@ -6656,8 +6657,8 @@ void QQuickItem::setPosition(const QPointF &pos)
d->dirty(QQuickItemPrivate::Position);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(oldx, oldy, d->width, d->height));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(oldx, oldy, d->width, d->height));
}
/*!
@@ -6686,8 +6687,8 @@ void QQuickItem::setWidth(qreal w)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, oldWidth, d->height));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, oldWidth, d->height));
}
void QQuickItem::resetWidth()
@@ -6810,8 +6811,8 @@ void QQuickItem::setImplicitWidth(qreal w)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, oldWidth, d->height));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, oldWidth, d->height));
if (changed)
d->implicitWidthChanged();
@@ -6852,8 +6853,8 @@ void QQuickItem::setHeight(qreal h)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, d->width, oldHeight));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, d->width, oldHeight));
}
void QQuickItem::resetHeight()
@@ -6906,8 +6907,8 @@ void QQuickItem::setImplicitHeight(qreal h)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, d->width, oldHeight));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, d->width, oldHeight));
if (changed)
d->implicitHeightChanged();
@@ -6951,8 +6952,8 @@ void QQuickItem::setImplicitSize(qreal w, qreal h)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, oldWidth, oldHeight));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, oldWidth, oldHeight));
if (!wDone && wChanged)
d->implicitWidthChanged();
@@ -7007,8 +7008,8 @@ void QQuickItem::setSize(const QSizeF &size)
d->dirty(QQuickItemPrivate::Size);
- geometryChanged(QRectF(d->x, d->y, d->width, d->height),
- QRectF(d->x, d->y, oldWidth, oldHeight));
+ geometryChange(QRectF(d->x, d->y, d->width, d->height),
+ QRectF(d->x, d->y, oldWidth, oldHeight));
}
/*!
@@ -7303,10 +7304,7 @@ Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
{
Q_D(QQuickItem);
- if (buttons & Qt::LeftButton)
- d->extra.setFlag();
- else
- d->extra.clearFlag();
+ d->extra.setTag(d->extra.tag().setFlag(QQuickItemPrivate::LeftMouseButtonAccepted, buttons & Qt::LeftButton));
buttons &= ~Qt::LeftButton;
if (buttons || d->extra.isAllocated())
@@ -8269,6 +8267,48 @@ QSGTextureProvider *QQuickItem::textureProvider() const
}
/*!
+ \since 6.0
+ \qmlproperty Palette QtQuick::Item::palette
+
+ This property holds the palette currently set for the item.
+
+ This property describes the item's requested palette. The palette is used by the item's style
+ when rendering all controls, and is available as a means to ensure that custom controls can
+ maintain consistency with the native platform's native look and feel. It's common that
+ different platforms, or different styles, define different palettes for an application.
+
+ The default palette depends on the system environment. ApplicationWindow maintains a
+ system/theme palette which serves as a default for all controls. There may also be special
+ palette defaults for certain types of controls. You can also set the default palette for
+ controls by either:
+
+ \list
+ \li passing a custom palette to QGuiApplication::setPalette(), before loading any QML; or
+ \li specifying the colors in the \l {Qt Quick Controls 2 Configuration File}
+ {qtquickcontrols2.conf file}.
+ \endlist
+
+ Items propagate explicit palette properties from parents to children. If you change a specific
+ property on a items's palette, that property propagates to all of the item's children,
+ overriding any system defaults for that property.
+
+ \code
+ Item {
+ palette {
+ buttonText: "maroon"
+ button: "lavender"
+ }
+
+ Button {
+ text: "Click Me"
+ }
+ }
+ \endcode
+
+ \sa Window::palette, Popup::palette, QQuickAbstractPaletteProvider, ColorGroup, Palette
+*/
+
+/*!
\property QQuickItem::layer
\internal
*/
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 8c04ced11b..813a6244dd 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -50,7 +50,6 @@
#include <QtGui/qfont.h>
#include <QtGui/qaccessible.h>
-
QT_BEGIN_NAMESPACE
class QQuickItem;
@@ -59,6 +58,7 @@ class Q_QUICK_EXPORT QQuickTransform : public QObject
{
Q_OBJECT
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickTransform(QObject *parent = nullptr);
~QQuickTransform() override;
@@ -93,6 +93,7 @@ class QSGNode;
class QSGTransformNode;
class QSGTextureProvider;
class QQuickItemGrabResult;
+class QQuickPalette;
class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
{
@@ -113,6 +114,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
+ Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickPalette *palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged REVISION(6, 0))
Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQmlListProperty<QQuickItem> visibleChildren READ visibleChildren NOTIFY visibleChildrenChanged DESIGNABLE false)
Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQmlListProperty<QQuickState> states READ states DESIGNABLE false)
@@ -133,7 +135,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL)
Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL)
- Q_PROPERTY(bool activeFocusOnTab READ activeFocusOnTab WRITE setActiveFocusOnTab NOTIFY activeFocusOnTabChanged FINAL REVISION 1)
+ Q_PROPERTY(bool activeFocusOnTab READ activeFocusOnTab WRITE setActiveFocusOnTab NOTIFY activeFocusOnTabChanged FINAL REVISION(2, 1))
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
@@ -145,13 +147,14 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing)
Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
- Q_PROPERTY(QObject *containmentMask READ containmentMask WRITE setContainmentMask NOTIFY containmentMaskChanged REVISION 11)
+ Q_PROPERTY(QObject *containmentMask READ containmentMask WRITE setContainmentMask NOTIFY containmentMaskChanged REVISION(2, 11))
Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickItemLayer *layer READ layer DESIGNABLE false CONSTANT FINAL)
Q_CLASSINFO("DefaultProperty", "data")
Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
QML_NAMED_ELEMENT(Item)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum Flag {
@@ -320,7 +323,7 @@ public:
void setKeepTouchGrab(bool);
// implemented in qquickitemgrabresult.cpp
- Q_REVISION(4) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
+ Q_REVISION(2, 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;
@@ -343,11 +346,11 @@ public:
Q_INVOKABLE void mapFromItem(QQmlV4Function*) const;
Q_INVOKABLE void mapToItem(QQmlV4Function*) const;
- Q_REVISION(7) Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const;
- Q_REVISION(7) Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const;
+ Q_REVISION(2, 7) Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const;
+ Q_REVISION(2, 7) Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const;
Q_INVOKABLE void forceActiveFocus();
Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason);
- Q_REVISION(1) Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true);
+ Q_REVISION(2, 1) Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true);
Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const;
#if QT_CONFIG(im)
@@ -373,13 +376,13 @@ Q_SIGNALS:
void stateChanged(const QString &);
void focusChanged(bool);
void activeFocusChanged(bool);
- Q_REVISION(1) void activeFocusOnTabChanged(bool);
+ Q_REVISION(2, 1) void activeFocusOnTabChanged(bool);
void parentChanged(QQuickItem *);
void transformOriginChanged(TransformOrigin);
void smoothChanged(bool);
void antialiasingChanged(bool);
void clipChanged(bool);
- Q_REVISION(1) void windowChanged(QQuickWindow* window);
+ Q_REVISION(2, 1) void windowChanged(QQuickWindow* window);
void childrenChanged();
void opacityChanged();
@@ -396,13 +399,17 @@ Q_SIGNALS:
void zChanged();
void implicitWidthChanged();
void implicitHeightChanged();
- Q_REVISION(11) void containmentMaskChanged();
+ Q_REVISION(2, 11) void containmentMaskChanged();
+
+ Q_REVISION(6, 0) void paletteChanged();
+ Q_REVISION(6, 0) void paletteCreated();
protected:
bool event(QEvent *) override;
bool isComponentComplete() const;
virtual void itemChange(ItemChange, const ItemChangeData &);
+ virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry);
#if QT_CONFIG(im)
void updateInputMethod(Qt::InputMethodQueries queries = Qt::ImQueryInput);
@@ -444,9 +451,6 @@ protected:
virtual bool childMouseEventFilter(QQuickItem *, QEvent *);
virtual void windowDeactivateEvent();
- virtual void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry);
-
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
virtual void releaseResources();
virtual void updatePolish();
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 841d91bb40..395dfee496 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -75,7 +75,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qdebug.h>
#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qpointer.h>
+#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h>
#if QT_CONFIG(quick_shadereffect)
#include <QtQuick/private/qquickshadereffectsource_p.h>
@@ -153,6 +153,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickItemLayer(QQuickItem *item);
@@ -248,7 +249,9 @@ private:
#endif
-class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate : public QObjectPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate
+ : public QObjectPrivate
+ , public QQuickPaletteProviderPrivateBase<QQuickItem, QQuickItemPrivate>
{
Q_DECLARE_PUBLIC(QQuickItem)
@@ -394,7 +397,7 @@ public:
QObjectList resourcesList;
// Although acceptedMouseButtons is inside ExtraData, we actually store
- // the LeftButton flag in the extra.flag() bit. This is because it is
+ // the LeftButton flag in the extra.tag() bit. This is because it is
// extremely common to set acceptedMouseButtons to LeftButton, but very
// rare to use any of the other buttons.
Qt::MouseButtons acceptedMouseButtons;
@@ -404,7 +407,14 @@ public:
// 26 bits padding
};
- QLazilyAllocated<ExtraData> extra;
+
+ enum ExtraDataTag {
+ NoTag = 0x1,
+ LeftMouseButtonAccepted = 0x2
+ };
+ Q_DECLARE_FLAGS(ExtraDataTags, ExtraDataTag)
+
+ QLazilyAllocated<ExtraData, ExtraDataTags> extra;
// Contains mask
QPointer<QObject> mask;
// If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false)
@@ -660,6 +670,8 @@ public:
virtual void updatePolish() { }
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ExtraDataTags)
+
/*
Key filters can be installed on a QQuickItem, but not removed. Currently they
are only used by attached objects (which are only destroyed on Item
@@ -722,6 +734,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
QML_NAMED_ELEMENT(KeyNavigation)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("KeyNavigation is only available via attached properties.")
QML_ATTACHED(QQuickKeyNavigationAttached)
@@ -771,6 +784,7 @@ class QQuickLayoutMirroringAttached : public QObject
Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
QML_NAMED_ELEMENT(LayoutMirroring)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("LayoutMirroring is only available via attached properties.")
QML_ATTACHED(QQuickLayoutMirroringAttached)
@@ -800,7 +814,7 @@ class QQuickEnterKeyAttached : public QObject
QML_NAMED_ELEMENT(EnterKey)
QML_UNCREATABLE("EnterKey is only available via attached properties")
- QML_ADDED_IN_MINOR_VERSION(6)
+ QML_ADDED_IN_VERSION(2, 6)
QML_ATTACHED(QQuickEnterKeyAttached)
public:
@@ -849,6 +863,7 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
QML_NAMED_ELEMENT(Keys)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Keys is only available via attached properties")
QML_ATTACHED(QQuickKeysAttached)
@@ -941,7 +956,7 @@ private:
Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
{
- return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
+ return ((extra.tag().testFlag(LeftMouseButtonAccepted) ? Qt::LeftButton : Qt::MouseButton(0)) |
(extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{}));
}
diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h
index 28c18c874d..ee4df1b6ca 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup
Q_PROPERTY(QQuickItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged)
Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged)
QML_NAMED_ELEMENT(ParentAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickParentAnimation(QObject *parent=nullptr);
@@ -102,6 +103,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
QML_NAMED_ELEMENT(AnchorAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnchorAnimation(QObject *parent=nullptr);
@@ -146,6 +148,7 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation
Q_PROPERTY(int orientationExitDuration READ orientationExitDuration WRITE setOrientationExitDuration NOTIFY orientationExitDurationChanged)
Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
QML_NAMED_ELEMENT(PathAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathAnimation(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h
index a45ed62ed5..96d18b907b 100644
--- a/src/quick/items/qquickitemgrabresult.h
+++ b/src/quick/items/qquickitemgrabresult.h
@@ -62,6 +62,7 @@ class Q_QUICK_EXPORT QQuickItemGrabResult : public QObject
Q_PROPERTY(QImage image READ image CONSTANT)
Q_PROPERTY(QUrl url READ url CONSTANT)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QImage image() const;
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index 815c5ae644..f7081f6ece 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -68,7 +68,7 @@ struct QPointingDeviceUniqueIdForeign
Q_GADGET
QML_FOREIGN(QPointingDeviceUniqueId)
QML_NAMED_ELEMENT(PointingDeviceUniqueId)
- QML_ADDED_IN_MINOR_VERSION(9)
+ QML_ADDED_IN_VERSION(2, 9)
QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.")
};
@@ -78,7 +78,7 @@ struct QQuickAnimatedImageNotAvailable
Q_GADGET
QML_UNAVAILABLE
QML_NAMED_ELEMENT(AnimatedImage)
- QML_ADDED_IN_MINOR_VERSION(0)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Qt was built without support for QMovie.")
};
#endif
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 7fb392233e..d75247afdd 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1366,13 +1366,13 @@ void QQuickItemView::trackedPositionChanged()
}
}
-void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickItemView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickItemView);
d->markExtentsDirty();
if (isComponentComplete() && (d->isValid() || !d->visibleItems.isEmpty()))
d->forceLayoutPolish();
- QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
+ QQuickFlickable::geometryChange(newGeometry, oldGeometry);
}
qreal QQuickItemView::minYExtent() const
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 3f83383cd5..f05618579a 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -79,10 +79,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged)
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
- Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7)
+ Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION(2, 7))
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
- 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(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION(2, 3))
+ Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION(2, 3))
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
@@ -110,11 +110,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
- Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15)
+ Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION(2, 15))
QML_NAMED_ELEMENT(ItemView)
QML_UNCREATABLE("ItemView is an abstract base class.")
- QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ADDED_IN_VERSION(2, 1)
public:
// this holds all layout enum values so they can be referred to by other enums
@@ -237,10 +237,10 @@ public:
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
- Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
+ Q_REVISION(2, 13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
Q_INVOKABLE void positionViewAtBeginning();
Q_INVOKABLE void positionViewAtEnd();
- Q_REVISION(1) Q_INVOKABLE void forceLayout();
+ Q_REVISION(2, 1) Q_INVOKABLE void forceLayout();
void setContentX(qreal pos) override;
void setContentY(qreal pos) override;
@@ -255,7 +255,7 @@ Q_SIGNALS:
void currentItemChanged();
void keyNavigationWrapsChanged();
- Q_REVISION(7) void keyNavigationEnabledChanged();
+ Q_REVISION(2, 7) void keyNavigationEnabledChanged();
void cacheBufferChanged();
void displayMarginBeginningChanged();
void displayMarginEndChanged();
@@ -286,12 +286,12 @@ Q_SIGNALS:
void preferredHighlightEndChanged();
void highlightMoveDurationChanged();
- Q_REVISION(15) void reuseItemsChanged();
+ Q_REVISION(2, 15) void reuseItemsChanged();
protected:
void updatePolish() override;
void componentComplete() override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
qreal minYExtent() const override;
qreal maxYExtent() const override;
qreal minXExtent() const override;
@@ -303,8 +303,8 @@ protected Q_SLOTS:
virtual void initItem(int index, QObject *item);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
void destroyingItem(QObject *item);
- Q_REVISION(15) void onItemPooled(int modelIndex, QObject *object);
- Q_REVISION(15) void onItemReused(int modelIndex, QObject *object);
+ Q_REVISION(2, 15) void onItemPooled(int modelIndex, QObject *object);
+ Q_REVISION(2, 15) void onItemReused(int modelIndex, QObject *object);
void animStopped();
void trackedPositionChanged();
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 5f4e74171e..43858db688 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -195,6 +195,7 @@ class QQuickViewTransitionAttached : public QObject
Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged)
QML_NAMED_ELEMENT(ViewTransition)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("ViewTransition is only available via attached properties.")
QML_ATTACHED(QQuickViewTransitionAttached)
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 0d78070401..df49a4cb8a 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -467,7 +467,7 @@ qreal QQuickListViewPrivate::lastPosition() const
// All visible items are in delayRemove state
invisibleCount = model->count();
}
- pos = (*(--visibleItems.constEnd()))->endPosition();
+ pos = (*(visibleItems.constEnd() - 1))->endPosition();
if (invisibleCount > 0)
pos += invisibleCount * (averageSize + spacing);
} else if (model && model->count()) {
@@ -492,7 +492,7 @@ qreal QQuickListViewPrivate::positionAt(int modelIndex) const
return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs;
} else {
int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
- return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing);
+ return (*(visibleItems.constEnd() - 1))->endPosition() + spacing + count * (averageSize + spacing);
}
}
return 0;
@@ -508,7 +508,7 @@ qreal QQuickListViewPrivate::endPositionAt(int modelIndex) const
return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing;
} else {
int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
- return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing);
+ return (*(visibleItems.constEnd() - 1))->endPosition() + count * (averageSize + spacing);
}
}
return 0;
@@ -534,7 +534,7 @@ qreal QQuickListViewPrivate::snapPosAt(qreal pos)
return snapItem->itemPosition();
if (visibleItems.count()) {
qreal firstPos = (*visibleItems.constBegin())->position();
- qreal endPos = (*(--visibleItems.constEnd()))->position();
+ qreal endPos = (*(visibleItems.constEnd() - 1))->position();
if (pos < firstPos) {
return firstPos - qRound((firstPos - pos) / averageSize) * averageSize;
} else if (pos > endPos)
@@ -679,7 +679,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
qreal itemEnd = visiblePos;
if (visibleItems.count()) {
visiblePos = (*visibleItems.constBegin())->position();
- itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing;
+ itemEnd = (*(visibleItems.constEnd() - 1))->endPosition() + spacing;
}
int modelIndex = findLastVisibleIndex();
@@ -2440,7 +2440,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
\list
\li Qt.LeftToRight (default) - Items will be laid out from left to right.
- \li Qt.RightToLeft - Items will be laid out from right to let.
+ \li Qt.RightToLeft - Items will be laid out from right to left.
\endlist
Setting this property has no effect if the \l orientation is Qt.Vertical.
@@ -3380,7 +3380,7 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
QQuickItemView::keyPressEvent(event);
}
-void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickListView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickListView);
@@ -3399,7 +3399,7 @@ void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
qreal dy = newGeometry.height() - oldGeometry.height();
setContentY(contentY() - dy);
}
- QQuickItemView::geometryChanged(newGeometry, oldGeometry);
+ QQuickItemView::geometryChange(newGeometry, oldGeometry);
}
void QQuickListView::initItem(int index, QObject *object)
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index be21b93155..be91dafaca 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -71,6 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickViewSection : public QObject
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
QML_NAMED_ELEMENT(ViewSection)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickViewSection(QQuickListView *parent=nullptr);
@@ -127,11 +128,12 @@ 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 4)
- Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4)
+ Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION(2, 4))
+ Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION(2, 4))
Q_CLASSINFO("DefaultProperty", "data")
QML_NAMED_ELEMENT(ListView)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQuickListViewAttached)
public:
@@ -193,13 +195,13 @@ Q_SIGNALS:
void highlightResizeVelocityChanged();
void highlightResizeDurationChanged();
void snapModeChanged();
- Q_REVISION(4) void headerPositioningChanged();
- Q_REVISION(4) void footerPositioningChanged();
+ Q_REVISION(2, 4) void headerPositioningChanged();
+ Q_REVISION(2, 4) void footerPositioningChanged();
protected:
void viewportMoved(Qt::Orientations orient) override;
void keyPressEvent(QKeyEvent *) override;
- void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry,const QRectF &oldGeometry) override;
void initItem(int index, QObject *item) override;
qreal maxYExtent() const override;
qreal maxXExtent() const override;
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index e1d533f092..40e0c3219a 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -711,7 +711,6 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status)
emit q->progressChanged();
if (status == QQmlIncubator::Ready)
emit q->loaded();
- disposeInitialPropertyValues(); // cleanup
}
void QQuickLoaderPrivate::_q_sourceLoaded()
@@ -948,13 +947,13 @@ QObject *QQuickLoader::item() const
return d->object;
}
-void QQuickLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickLoader::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickLoader);
if (newGeometry != oldGeometry) {
d->_q_updateSize();
}
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
}
QUrl QQuickLoaderPrivate::resolveSourceUrl(QQmlV4Function *args)
@@ -962,12 +961,7 @@ QUrl QQuickLoaderPrivate::resolveSourceUrl(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
QString arg = v->toQString();
- if (arg.isEmpty())
- return QUrl();
-
- QQmlContextData *context = scope.engine->callingQmlContext();
- Q_ASSERT(context);
- return context->resolvedUrl(QUrl(arg));
+ return arg.isEmpty() ? QUrl() : scope.engine->callingQmlContext()->resolvedUrl(QUrl(arg));
}
QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error)
diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h
index 2d560fb856..dbe920c4f8 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
QML_NAMED_ELEMENT(Loader)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickLoader(QQuickItem *parent = nullptr);
@@ -106,7 +107,7 @@ Q_SIGNALS:
void asynchronousChanged();
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index f54858e4eb..4ac80def33 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -688,11 +688,17 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
return;
}
- d->saveEvent(event);
-
// ### we should skip this if these signals aren't used
// ### can GV handle this for us?
- setHovered(contains(d->lastPos));
+ setHovered(contains(event->localPos()));
+
+ if ((event->buttons() & acceptedMouseButtons()) == 0) {
+ QQuickItem::mouseMoveEvent(event);
+ return;
+ }
+
+ d->saveEvent(event);
+
#if QT_CONFIG(quick_draganddrop)
if (d->drag && d->drag->target()) {
@@ -1038,11 +1044,10 @@ void QQuickMouseArea::windowDeactivateEvent()
QQuickItem::windowDeactivateEvent();
}
-void QQuickMouseArea::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+void QQuickMouseArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickMouseArea);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
if (d->lastScenePos.isNull)
d->lastScenePos = mapToScene(d->lastPos);
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 806cc41369..c368f43b30 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 5)
+ Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION(2, 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,9 +83,10 @@ 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 4)
- Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9)
+ Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION(2, 4))
+ Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION(2, 9))
QML_NAMED_ELEMENT(MouseArea)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickMouseArea(QQuickItem *parent=nullptr);
@@ -135,7 +136,7 @@ Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
void enabledChanged();
- Q_REVISION(5) void scrollGestureEnabledChanged();
+ Q_REVISION(2, 5) void scrollGestureEnabledChanged();
void pressedButtonsChanged();
void acceptedButtonsChanged();
void hoverEnabledChanged();
@@ -157,8 +158,8 @@ Q_SIGNALS:
void entered();
void exited();
void canceled();
- Q_REVISION(4) void containsPressChanged();
- Q_REVISION(9) void pressAndHoldIntervalChanged();
+ Q_REVISION(2, 4) void containsPressChanged();
+ Q_REVISION(2, 9) void pressAndHoldIntervalChanged();
protected:
void setHovered(bool);
@@ -181,8 +182,7 @@ protected:
void timerEvent(QTimerEvent *event) override;
void windowDeactivateEvent() override;
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void itemChange(ItemChange change, const ItemChangeData& value) override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index e34a3faad6..d37cc6df7e 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -67,13 +67,13 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
{
Q_OBJECT
Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged)
- Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION 9)
+ Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION(2, 9))
Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
Q_PROPERTY(qreal x READ x NOTIFY xChanged)
Q_PROPERTY(qreal y READ y NOTIFY yChanged)
- Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION 9)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION(2, 9))
Q_PROPERTY(qreal pressure READ pressure NOTIFY pressureChanged)
- Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION 9)
+ Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION(2, 9))
Q_PROPERTY(QVector2D velocity READ velocity NOTIFY velocityChanged)
Q_PROPERTY(QRectF area READ area NOTIFY areaChanged)
@@ -84,6 +84,7 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged)
Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged)
QML_NAMED_ELEMENT(TouchPoint)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTouchPoint(bool qmlDefined = true)
@@ -144,12 +145,12 @@ public:
Q_SIGNALS:
void pressedChanged();
void pointIdChanged();
- Q_REVISION(9) void uniqueIdChanged();
+ Q_REVISION(2, 9) void uniqueIdChanged();
void xChanged();
void yChanged();
- Q_REVISION(9) void ellipseDiametersChanged();
+ Q_REVISION(2, 9) void ellipseDiametersChanged();
void pressureChanged();
- Q_REVISION(9) void rotationChanged();
+ Q_REVISION(2, 9) void rotationChanged();
void velocityChanged();
void areaChanged();
void startXChanged();
@@ -187,6 +188,7 @@ class QQuickGrabGestureEvent : public QObject
Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints CONSTANT)
Q_PROPERTY(qreal dragThreshold READ dragThreshold CONSTANT)
QML_NAMED_ELEMENT(GestureEvent)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea.")
public:
@@ -216,6 +218,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem
Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged)
Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged)
QML_NAMED_ELEMENT(MultiPointTouchArea)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickMultiPointTouchArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickopenglinfo.cpp b/src/quick/items/qquickopenglinfo.cpp
index 3e634725f4..294572e693 100644
--- a/src/quick/items/qquickopenglinfo.cpp
+++ b/src/quick/items/qquickopenglinfo.cpp
@@ -41,7 +41,9 @@
#include "qquickopenglinfo_p.h"
#include "qopenglcontext.h"
#include "qquickwindow.h"
+#include "qquickwindow_p.h"
#include "qquickitem.h"
+#include "qquickitem_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickopenglinfo_p.h b/src/quick/items/qquickopenglinfo_p.h
index b733d205e3..e0c2572b8d 100644
--- a/src/quick/items/qquickopenglinfo_p.h
+++ b/src/quick/items/qquickopenglinfo_p.h
@@ -72,7 +72,7 @@ class QQuickOpenGLInfo : public QObject
QML_NAMED_ELEMENT(OpenGLInfo)
QML_UNCREATABLE("OpenGLInfo is only available via attached properties.")
- QML_ADDED_IN_MINOR_VERSION(4)
+ QML_ADDED_IN_VERSION(2, 4)
QML_ATTACHED(QQuickOpenGLInfo)
public:
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp
index e217fdb5d0..280cdbf831 100644
--- a/src/quick/items/qquickopenglshadereffect.cpp
+++ b/src/quick/items/qquickopenglshadereffect.cpp
@@ -52,8 +52,9 @@
#include "qquickshadereffectmesh_p.h"
#include <QtQml/qqmlfile.h>
-#include <QtCore/qsignalmapper.h>
+#include <QtCore/qfile.h>
#include <QtCore/qfileselector.h>
+#include <QtCore/qsignalmapper.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp
index 5721f116e8..919b92780a 100644
--- a/src/quick/items/qquickopenglshadereffectnode.cpp
+++ b/src/quick/items/qquickopenglshadereffectnode.cpp
@@ -45,7 +45,7 @@
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
#include <QtQuick/private/qsgtexture_p.h>
#include <QtCore/qmutex.h>
-#include <QtGui/qopenglfunctions.h>
+#include <qopenglfunctions.h>
#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
@@ -351,9 +351,9 @@ bool QQuickOpenGLShaderEffectMaterialKey::operator != (const QQuickOpenGLShaderE
return !(*this == other);
}
-uint qHash(const QQuickOpenGLShaderEffectMaterialKey &key)
+size_t qHash(const QQuickOpenGLShaderEffectMaterialKey &key)
{
- uint hash = 1;
+ size_t hash = 1;
typedef QQuickOpenGLShaderEffectMaterialKey Key;
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType)
hash = hash * 31337 + qHash(key.sourceCode[shaderType]);
diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h
index 705b8d4f47..377c34eb95 100644
--- a/src/quick/items/qquickopenglshadereffectnode_p.h
+++ b/src/quick/items/qquickopenglshadereffectnode_p.h
@@ -81,7 +81,7 @@ struct QQuickOpenGLShaderEffectMaterialKey {
bool operator != (const QQuickOpenGLShaderEffectMaterialKey &other) const;
};
-uint qHash(const QQuickOpenGLShaderEffectMaterialKey &key);
+size_t qHash(const QQuickOpenGLShaderEffectMaterialKey &key);
class QQuickCustomMaterialShader;
class QQuickOpenGLShaderEffectNode;
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp
index 386c8d8862..1eb852f6bf 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -44,6 +44,9 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qsgadaptationlayer_p.h>
#include <qsgtextureprovider.h>
+#if QT_CONFIG(opengl)
+#include <QOpenGLContext>
+#endif // QT_CONFIG(opengl)
#include <qmath.h>
@@ -368,10 +371,6 @@ void QQuickPaintedItem::setTextureSize(const QSize &size)
emit textureSizeChanged();
}
-#if QT_VERSION >= 0x060000
-#warning "Remove: QQuickPaintedItem::contentsBoundingRect, contentsScale, contentsSize. Also remove them from qsgadaptationlayer_p.h and qsgdefaultpainternode.h/cpp."
-#endif
-
/*!
\obsolete
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index 4821a409be..a6a78f6166 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -57,6 +57,7 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem
Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
QML_NAMED_ELEMENT(PaintedItem)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Cannot create instance of abstract class PaintedItem.")
public:
diff --git a/src/quick/items/qquickpalette.cpp b/src/quick/items/qquickpalette.cpp
new file mode 100644
index 0000000000..f5c0aa8b04
--- /dev/null
+++ b/src/quick/items/qquickpalette.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpalette_p.h"
+
+#include <QtQuick/private/qquickpalettecolorprovider_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+
+ \class QQuickPalette
+ \brief The QQuickPalette class contains color groups for each QML item state.
+ \inmodule QtQuick
+ \since 6.0
+
+ This class is the wrapper around QPalette.
+
+ \sa QQuickColorGroup, QQuickAbstractPaletteProvider, QPalette
+ */
+
+/*!
+ \qmltype Palette
+ \instantiates QQuickPalette
+ \inherits QQuickColorGroup
+ \inqmlmodule QtQuick
+ \ingroup qtquick-visual
+ \brief The QQuickPalette class contains color groups for each QML item state.
+
+ A palette consists of three color groups: Active, Disabled, and Inactive.
+ Active color group is the default group, its colors are used for other groups
+ if colors of these groups aren't explicitly specified.
+
+ In the following example, color is applied for all color groups:
+ \code
+ ApplicationWindow {
+ palette.buttonText: "salmon"
+
+ ColumnLayout {
+ Button {
+ text: qsTr("Disabled button")
+ enabled: false
+ }
+
+ Button {
+ text: qsTr("Enabled button")
+ }
+ }
+ }
+ \endcode
+ It means that text color will be the same for both buttons.
+
+ In the following example, colors will be different for enabled and disabled states:
+ \code
+ ApplicationWindow {
+ palette.buttonText: "salmon"
+ palette.disabled.buttonText: "lavender"
+
+ ColumnLayout {
+ Button {
+ text: qsTr("Disabled button")
+ enabled: false
+ }
+
+ Button {
+ text: qsTr("Enabled button")
+ }
+ }
+ }
+ \endcode
+
+ It is also possible to specify colors like this:
+ \code
+ palette {
+ buttonText: "azure"
+ button: "khaki"
+
+ disabled {
+ buttonText: "lavender"
+ button: "coral"
+ }
+ }
+ \endcode
+ This approach is convenient when you need to specify a whole palette with all color groups.
+*/
+
+/*!
+ \qmlproperty QQuickColorGroup QtQuick::QQuickPalette::inactive
+
+ The Inactive group is used for windows that have no keyboard focus.
+
+ \sa QPalette::Inactive
+*/
+
+/*!
+ \qmlproperty QQuickColorGroup QtQuick::QQuickPalette::disabled
+
+ The Disabled group is used for elements that are disabled for some reason.
+
+ \sa QPalette::Disabled
+*/
+
+QQuickPalette::QQuickPalette(QObject *parent)
+ : QQuickColorGroup(parent)
+ , m_currentGroup(defaultCurrentGroup())
+{
+}
+
+QQuickColorGroup *QQuickPalette::active() const
+{
+ return colorGroup(QPalette::Active);
+}
+
+QQuickColorGroup *QQuickPalette::inactive() const
+{
+ return colorGroup(QPalette::Inactive);
+}
+
+QQuickColorGroup *QQuickPalette::disabled() const
+{
+ return colorGroup(QPalette::Disabled);
+}
+
+/*!
+ \internal
+
+ Returns the palette's current color group.
+ The default value is Active.
+ */
+QPalette::ColorGroup QQuickPalette::currentColorGroup() const
+{
+ return m_currentGroup;
+}
+
+/*!
+ \internal
+
+ Sets \a currentGroup for this palette.
+
+ The current color group is used when accessing colors of this palette.
+ For example, if color group is Disabled, color accessors will be
+ returning colors form the respective group.
+ \code
+ QQuickPalette palette;
+
+ palette.setAlternateBase(Qt::green);
+ palette.disabled()->setAlternateBase(Qt::red);
+
+ auto color = palette.alternateBase(); // Qt::green
+
+ palette.setCurrentGroup(QPalette::Disabled);
+ color = palette.alternateBase(); // Qt::red
+ \endcode
+
+ Emits QColorGroup::changed().
+ */
+void QQuickPalette::setCurrentGroup(QPalette::ColorGroup currentGroup)
+{
+ if (m_currentGroup != currentGroup) {
+ m_currentGroup = currentGroup;
+ Q_EMIT changed();
+ }
+}
+
+void QQuickPalette::fromQPalette(QPalette palette)
+{
+ if (colorProvider().fromQPalette(std::move(palette))) {
+ Q_EMIT changed();
+ }
+}
+
+QPalette QQuickPalette::toQPalette() const
+{
+ return colorProvider().palette();
+}
+
+const QQuickAbstractPaletteProvider *QQuickPalette::paletteProvider() const
+{
+ return colorProvider().paletteProvider();
+}
+
+void QQuickPalette::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider)
+{
+ colorProvider().setPaletteProvider(paletteProvider);
+}
+
+void QQuickPalette::reset()
+{
+ if (colorProvider().reset()) {
+ Q_EMIT changed();
+ }
+}
+
+void QQuickPalette::inheritPalette(const QPalette &palette)
+{
+ if (colorProvider().inheritPalette(palette)) {
+ Q_EMIT changed();
+ }
+}
+
+void QQuickPalette::setActive(QQuickColorGroup *active)
+{
+ setColorGroup(QPalette::Active, active, &QQuickPalette::activeChanged);
+}
+
+void QQuickPalette::setInactive(QQuickColorGroup *inactive)
+{
+ setColorGroup(QPalette::Inactive, inactive, &QQuickPalette::inactiveChanged);
+}
+
+void QQuickPalette::setDisabled(QQuickColorGroup *disabled)
+{
+ setColorGroup(QPalette::Disabled, disabled, &QQuickPalette::disabledChanged);
+}
+
+
+void QQuickPalette::setColorGroup(QPalette::ColorGroup groupTag,
+ const QQuickColorGroup::GroupPtr &group,
+ void (QQuickPalette::*notifier)())
+{
+ if (isValidColorGroup(groupTag, group)) {
+ if (colorProvider().copyColorGroup(groupTag, group->colorProvider())) {
+ Q_EMIT (this->*notifier)();
+ Q_EMIT changed();
+ }
+ }
+}
+
+QQuickColorGroup::GroupPtr QQuickPalette::colorGroup(QPalette::ColorGroup groupTag) const
+{
+ if (auto group = findColorGroup(groupTag)) {
+ return group;
+ }
+
+ auto group = QQuickColorGroup::createWithParent(*const_cast<QQuickPalette*>(this));
+ const_cast<QQuickPalette*>(this)->registerColorGroup(group, groupTag);
+ return group;
+}
+
+QQuickColorGroup::GroupPtr QQuickPalette::findColorGroup(QPalette::ColorGroup groupTag) const
+{
+ if (auto it = m_colorGroups.find(groupTag); it != m_colorGroups.end()) {
+ return it->second;
+ }
+
+ return nullptr;
+}
+
+void QQuickPalette::registerColorGroup(QQuickColorGroup *group, QPalette::ColorGroup groupTag)
+{
+ if (auto it = m_colorGroups.find(groupTag); it != m_colorGroups.end() && it->second) {
+ it->second->deleteLater();
+ }
+
+ m_colorGroups[groupTag] = group;
+
+ group->setGroupTag(groupTag);
+
+ QQuickColorGroup::connect(group, &QQuickColorGroup::changed, this, &QQuickPalette::changed);
+}
+
+bool QQuickPalette::isValidColorGroup(QPalette::ColorGroup groupTag,
+ const QQuickColorGroup::GroupPtr &colorGroup) const
+{
+ if (!colorGroup) {
+ qWarning("Color group cannot be null.");
+ return false;
+ }
+
+ if (!colorGroup->parent()) {
+ qWarning("Color group should have a parent.");
+ return false;
+ }
+
+ if (colorGroup->parent() && !qobject_cast<QQuickPalette*>(colorGroup->parent())) {
+ qWarning("Color group should be a part of QQuickPalette.");
+ return false;
+ }
+
+ if (groupTag == defaultGroupTag()) {
+ qWarning("Register %i color group is not allowed."
+ " QQuickPalette is %i color group itself.", groupTag, groupTag);
+ return false;
+ }
+
+ if (findColorGroup(groupTag) == colorGroup) {
+ qWarning("The color group is already a part of the current palette.");
+ return false;
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpalette_p.h b/src/quick/items/qquickpalette_p.h
new file mode 100644
index 0000000000..11688048ed
--- /dev/null
+++ b/src/quick/items/qquickpalette_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKPALETTE_H
+#define QQUICKPALETTE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QQuickPalette. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <vector> // Workaround: I think we should include vector to qflatmap_p.h
+#include <QtCore/private/qflatmap_p.h>
+
+#include <QtQuick/private/qquickcolorgroup_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractPaletteProvider;
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPalette : public QQuickColorGroup
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQuickColorGroup *active READ active WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(QQuickColorGroup *inactive READ inactive WRITE setInactive NOTIFY inactiveChanged)
+ Q_PROPERTY(QQuickColorGroup *disabled READ disabled WRITE setDisabled NOTIFY disabledChanged)
+
+ QML_NAMED_ELEMENT(Palette)
+ QML_ADDED_IN_VERSION(6, 0)
+
+public: // Types
+ using PalettePtr = QPointer<QQuickPalette>;
+
+public:
+ Q_DISABLE_COPY_MOVE(QQuickPalette)
+ explicit QQuickPalette(QObject *parent = nullptr);
+
+ QQuickColorGroup *active() const;
+ QQuickColorGroup *inactive() const;
+ QQuickColorGroup *disabled() const;
+
+ QPalette::ColorGroup currentColorGroup() const;
+ void setCurrentGroup(QPalette::ColorGroup currentGroup);
+
+ void fromQPalette(QPalette palette);
+ QPalette toQPalette() const;
+
+ const QQuickAbstractPaletteProvider *paletteProvider() const;
+ void setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider);
+
+ void reset();
+
+ void inheritPalette(const QPalette &palette);
+
+public Q_SLOTS:
+ void setActive(QQuickColorGroup *active);
+ void setInactive(QQuickColorGroup *inactive);
+ void setDisabled(QQuickColorGroup *disabled);
+
+Q_SIGNALS:
+ void activeChanged();
+ void inactiveChanged();
+ void disabledChanged();
+
+private:
+ void setColorGroup(QPalette::ColorGroup groupTag,
+ const QQuickColorGroup::GroupPtr &group,
+ void (QQuickPalette::*notifier)());
+ QQuickColorGroup::GroupPtr colorGroup(QPalette::ColorGroup groupTag) const;
+ QQuickColorGroup::GroupPtr findColorGroup(QPalette::ColorGroup groupTag) const;
+
+ void registerColorGroup(QQuickColorGroup *group, QPalette::ColorGroup groupTag);
+
+ bool isValidColorGroup(QPalette::ColorGroup groupTag,
+ const QQuickColorGroup::GroupPtr &colorGroup) const;
+
+ static constexpr QPalette::ColorGroup defaultCurrentGroup() { return QPalette::Active; }
+
+private:
+ QFlatMap<QPalette::ColorGroup, QQuickColorGroup::GroupPtr> m_colorGroups;
+ QPalette::ColorGroup m_currentGroup;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPalette)
+
+#endif // QQUICKPALETTE_H
diff --git a/src/quick/items/qquickpalettecolorprovider.cpp b/src/quick/items/qquickpalettecolorprovider.cpp
new file mode 100644
index 0000000000..6808e8843a
--- /dev/null
+++ b/src/quick/items/qquickpalettecolorprovider.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://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 "qquickpalettecolorprovider_p.h"
+
+#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool notEq(const QPalette &p1, const QPalette &p2)
+{
+ return p1.resolve() != p2.resolve() || p1 != p2;
+}
+
+static QPalette::ColorGroup adjustCg(QPalette::ColorGroup group)
+{
+ return group == QPalette::All ? QPalette::Active : group;
+}
+
+class DefaultPalettesProvider : public QQuickAbstractPaletteProvider
+{
+public:
+ QPalette defaultPalette() const override { static QPalette p; return p; }
+ QPalette parentPalette() const override { return defaultPalette(); }
+};
+
+static std::default_delete<const QQuickAbstractPaletteProvider> defaultDeleter() { return {}; }
+
+QQuickPaletteColorProvider::QQuickPaletteColorProvider()
+ : m_paletteProvider(ProviderPtr(new DefaultPalettesProvider, defaultDeleter()))
+{
+}
+
+const QColor &QQuickPaletteColorProvider::color(QPalette::ColorGroup group, QPalette::ColorRole role) const
+{
+ return m_resolvedPalette.color(adjustCg(group), role);
+}
+
+bool QQuickPaletteColorProvider::setColor(QPalette::ColorGroup g, QPalette::ColorRole r, QColor c)
+{
+ m_requestedPalette.value() = m_resolvedPalette;
+ m_requestedPalette->setColor(g, r, c);
+
+ return inheritPalette(paletteProvider()->parentPalette());
+}
+
+bool QQuickPaletteColorProvider::resetColor(QPalette::ColorGroup group, QPalette::ColorRole role)
+{
+ const auto &defaultPalette = paletteProvider()->defaultPalette() ;
+ const auto &defaultColor = defaultPalette.color(adjustCg(group), role);
+
+ return setColor(group, role, defaultColor);
+}
+
+bool QQuickPaletteColorProvider::fromQPalette(QPalette p)
+{
+ m_requestedPalette.value() = std::move(p);
+ return inheritPalette(paletteProvider()->parentPalette());
+}
+
+QPalette QQuickPaletteColorProvider::palette() const
+{
+ return m_resolvedPalette;
+}
+
+const QQuickAbstractPaletteProvider *QQuickPaletteColorProvider::paletteProvider() const
+{
+ Q_ASSERT(m_paletteProvider);
+ return m_paletteProvider.get();
+}
+
+void QQuickPaletteColorProvider::setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider)
+{
+ static const auto emptyDeleter = [](auto &&){};
+ m_paletteProvider = ProviderPtr(paletteProvider, emptyDeleter);
+}
+
+bool QQuickPaletteColorProvider::copyColorGroup(QPalette::ColorGroup cg,
+ const QQuickPaletteColorProvider &p)
+{
+ m_requestedPalette.value() = m_resolvedPalette;
+
+ auto srcPalette = p.palette();
+ for (int roleIndex = QPalette::WindowText; roleIndex < QPalette::NColorRoles; ++roleIndex) {
+ const auto cr = QPalette::ColorRole(roleIndex);
+ if (srcPalette.isBrushSet(cg, cr)) {
+ m_requestedPalette->setBrush(cg, cr, srcPalette.brush(cg, cr));
+ }
+ }
+
+ return inheritPalette(paletteProvider()->parentPalette());
+}
+
+bool QQuickPaletteColorProvider::reset()
+{
+ return fromQPalette(QPalette());
+}
+
+bool QQuickPaletteColorProvider::inheritPalette(const QPalette &p)
+{
+ QPalette parentPalette = m_requestedPalette.isAllocated() ? m_requestedPalette->resolve(p) : p;
+ parentPalette.resolve(m_requestedPalette.isAllocated() ? m_requestedPalette->resolve() | p.resolve() : p.resolve());
+
+ auto tmpResolvedPalette = parentPalette.resolve(paletteProvider()->defaultPalette());
+
+ bool changed = notEq(tmpResolvedPalette, m_resolvedPalette);
+ if (changed) {
+ std::swap(tmpResolvedPalette, m_resolvedPalette);
+ }
+
+ return changed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpalettecolorprovider_p.h b/src/quick/items/qquickpalettecolorprovider_p.h
new file mode 100644
index 0000000000..952c74aa0d
--- /dev/null
+++ b/src/quick/items/qquickpalettecolorprovider_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKPALETTECOLORPROVIDER_P_H
+#define QQUICKPALETTECOLORPROVIDER_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 <QtGui/QPalette>
+
+#include <QtQuick/qtquickglobal.h>
+
+#include <QtQuick/private/qtquickglobal_p.h>
+#include <private/qlazilyallocated_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractPaletteProvider;
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPaletteColorProvider
+ : public std::enable_shared_from_this<QQuickPaletteColorProvider>
+{
+public:
+ QQuickPaletteColorProvider();
+
+ const QColor &color(QPalette::ColorGroup group, QPalette::ColorRole role) const;
+ bool setColor(QPalette::ColorGroup group, QPalette::ColorRole role, QColor color);
+ bool resetColor(QPalette::ColorGroup group, QPalette::ColorRole role);
+
+ bool fromQPalette(QPalette p);
+ QPalette palette() const;
+
+ const QQuickAbstractPaletteProvider *paletteProvider() const;
+ void setPaletteProvider(const QQuickAbstractPaletteProvider *paletteProvider);
+
+ bool copyColorGroup(QPalette::ColorGroup cg, const QQuickPaletteColorProvider &p);
+
+ bool reset();
+
+ bool inheritPalette(const QPalette &p);
+
+private:
+ QPalette m_resolvedPalette;
+ QLazilyAllocated<QPalette> m_requestedPalette;
+
+ using Deleter = std::function<void(const QQuickAbstractPaletteProvider*)>;
+ using ProviderPtr = std::unique_ptr<const QQuickAbstractPaletteProvider, Deleter>;
+ ProviderPtr m_paletteProvider;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPALETTECOLORPROVIDER_P_H
diff --git a/src/quick/items/qquickpaletteproviderprivatebase_p.h b/src/quick/items/qquickpaletteproviderprivatebase_p.h
new file mode 100644
index 0000000000..2461b2d1a9
--- /dev/null
+++ b/src/quick/items/qquickpaletteproviderprivatebase_p.h
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKPALETTEPROVIDERPRIVATEBASE_H
+#define QQUICKPALETTEPROVIDERPRIVATEBASE_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/qquickpalette_p.h>
+#include <QtQuick/private/qquickabstractpaletteprovider_p.h>
+
+#include <QtQml/private/qlazilyallocated_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+class QQuickWindow;
+class QQuickWindowPrivate;
+class QQuickItem;
+class QQuickItemPrivate;
+class QQuickPopup;
+class QQuickPopupPrivate;
+
+/*!
+ \internal
+
+ Implements all required operations with palette.
+
+ I -- is interface class (e.g. QQuickItem).
+ Impl -- is implementation class (e.g. QQuickItemPrivate).
+
+ To use this class you need to inherit implementation class from it.
+ */
+template <class I, class Impl>
+class QQuickPaletteProviderPrivateBase : public QQuickAbstractPaletteProvider
+{
+ static_assert(std::is_base_of<QObject, I>{}, "The interface class must inherit QObject");
+
+public:
+ virtual ~QQuickPaletteProviderPrivateBase() = default;
+
+ /*!
+ \internal
+
+ Get current palette.
+
+ \note Palette might be lazily allocated. Signal \p paletteCreated()
+ will be emitted by an object of interface class in this case.
+
+ \note This function doesn't ask an object of interface class to emit
+ paletteChanged() signal in order to avoid problems with
+ property bindigns.
+ */
+ virtual QQuickPalette *palette() const;
+
+ /*!
+ \internal
+
+ Set new palette. Doesn't transfer ownership.
+ */
+ virtual void setPalette(QQuickPalette *p);
+
+ /*!
+ \internal
+
+ Reset palette to the default one.
+ */
+ virtual void resetPalette();
+
+ /*!
+ \internal
+
+ Check if everything is internally allocated and palette exists.
+
+ Use before call \p palette() to avoid unnecessary allocations.
+ */
+ virtual bool providesPalette() const;
+
+ /*!
+ \internal
+
+ A default palette for this component.
+ */
+ virtual QPalette defaultPalette() const;
+
+ /*!
+ \internal
+
+ A parent palette for this component. Can be null.
+ */
+ virtual QPalette parentPalette() const;
+
+ /*!
+ \internal
+
+ Inherit from \p parentPalette. This function is also called when
+ either parent or window of this item is changed.
+ */
+ void inheritPalette(const QPalette &parentPalette);
+
+ /*!
+ \internal
+
+ Updates children palettes. The default implementation invokes
+ inheritPalette for all visual children.
+
+ This function is also called when palette is changed
+ (signal changed() is emitted).
+ */
+ virtual void updateChildrenPalettes(const QPalette &parentPalette);
+
+private:
+ using PalettePtr = std::unique_ptr<QQuickPalette>;
+ using Self = QQuickPaletteProviderPrivateBase<I, Impl>;
+
+ void registerPalette(PalettePtr palette);
+
+ bool isValidPalette(const QQuickPalette *palette) const;
+
+ QQuickPalette *windowPalette() const;
+
+ void setCurrentColorGroup();
+
+ void connectItem();
+
+ const I *itemWithPalette() const;
+ I *itemWithPalette();
+
+ QQuickPalette *paletteData() const;
+
+ QPalette toQPalette() const;
+
+private:
+ PalettePtr m_palette;
+};
+
+template<class I, class Impl>
+QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::palette() const
+{
+ if (!providesPalette()) {
+ // It's required to create a new palette without parent,
+ // because this method can be called from the rendering thread
+ const_cast<Self*>(this)->registerPalette(std::make_unique<QQuickPalette>());
+ Q_EMIT const_cast<Self*>(this)->itemWithPalette()->paletteCreated();
+ }
+
+ return paletteData();
+}
+
+template<class I, class Impl>
+bool QQuickPaletteProviderPrivateBase<I, Impl>::isValidPalette(const QQuickPalette *palette) const
+{
+ if (!palette) {
+ qWarning("Palette cannot be null.");
+ return false;
+ }
+
+ if (providesPalette() && paletteData() == palette) {
+ qWarning("Self assignment makes no sense.");
+ return false;
+ }
+
+ return true;
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::setPalette(QQuickPalette *p)
+{
+ if (isValidPalette(p)) {
+ palette()->fromQPalette(p->toQPalette());
+ }
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::resetPalette()
+{
+ paletteData()->reset();
+}
+
+template<class I, class Impl>
+bool QQuickPaletteProviderPrivateBase<I, Impl>::providesPalette() const
+{
+ return !!m_palette;
+}
+
+template<class I, class Impl>
+QPalette QQuickPaletteProviderPrivateBase<I, Impl>::defaultPalette() const
+{
+ return QPalette();
+}
+
+template <class Window>
+inline constexpr bool isRootWindow() { return std::is_base_of_v<QWindow, Window>; }
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::registerPalette(PalettePtr palette)
+{
+ if constexpr (!isRootWindow<I>()) {
+ // Connect item only once, before initial data allocation
+ if (!providesPalette()) {
+ connectItem();
+ }
+ }
+
+ m_palette = std::move(palette);
+ m_palette->setPaletteProvider(this);
+ m_palette->inheritPalette(parentPalette());
+
+ setCurrentColorGroup();
+
+ // In order to avoid extra noise, we should connect
+ // the following signals only after everything is already setup
+ I::connect(paletteData(), &QQuickPalette::changed, itemWithPalette(), &I::paletteChanged);
+ I::connect(paletteData(), &QQuickPalette::changed, [this]{ updateChildrenPalettes(toQPalette()); });
+}
+
+template<class T> struct dependent_false : std::false_type {};
+template<class Impl, class I> decltype(auto) getPrivateImpl(I &t) { return Impl::get(&t); }
+
+template <class T>
+decltype(auto) getPrivate(T &item)
+{
+ if constexpr (std::is_same_v<T, QQuickWindow>) {
+ return getPrivateImpl<QQuickWindowPrivate>(item);
+ } else if constexpr (std::is_same_v<T, QQuickItem>) {
+ return getPrivateImpl<QQuickItemPrivate>(item);
+ } else {
+ static_assert (dependent_false<T>::value, "Extend please.");
+ }
+}
+
+template<class I, class Impl>
+QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::windowPalette() const
+{
+ if constexpr (!isRootWindow<I>()) {
+ if (auto window = itemWithPalette()->window()) {
+ if (getPrivate(*window)->providesPalette()) {
+ return getPrivate(*window)->palette();
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+template<class I, class Impl>
+QPalette QQuickPaletteProviderPrivateBase<I, Impl>::parentPalette() const
+{
+ if constexpr (!isRootWindow<I>()) {
+ for (auto parentItem = itemWithPalette()->parentItem(); parentItem;
+ parentItem = parentItem->parentItem()) {
+
+ // Don't allocate a new palette here. Use only if it's already pre allocated
+ if (parentItem && getPrivate(*parentItem)->providesPalette()) {
+ return getPrivate(*parentItem)->palette()->toQPalette();
+ }
+ }
+
+ if (auto wp = windowPalette()) {
+ return wp->toQPalette();
+ }
+ }
+
+ return defaultPalette();
+}
+
+template<class I>
+const QQuickItem* rootItem(const I &item)
+{
+ if constexpr (isRootWindow<I>()) {
+ return item.contentItem();
+ } else if constexpr (std::is_same_v<QQuickPopup, I>) {
+ return nullptr;
+ } else {
+ return &item;
+ }
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::inheritPalette(const QPalette &parentPalette)
+{
+ if (providesPalette()) {
+ // If palette is changed, then this function will be invoked
+ // for all children because of connection with signal changed()
+ m_palette->inheritPalette(parentPalette);
+ } else {
+ // Otherwise, just propagate parent palette to all children
+ updateChildrenPalettes(parentPalette);
+ }
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::setCurrentColorGroup()
+{
+ if constexpr (!isRootWindow<I>()) {
+ if (paletteData()) {
+ const bool enabled = itemWithPalette()->isEnabled();
+ paletteData()->setCurrentGroup(enabled ? QPalette::Active : QPalette::Disabled);
+ }
+ }
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::updateChildrenPalettes(const QPalette &parentPalette)
+{
+ if (auto root = rootItem(*itemWithPalette())) {
+ for (auto &&child : root->childItems()) {
+ if (Q_LIKELY(child)) {
+ getPrivate(*child)->inheritPalette(parentPalette);
+ }
+ }
+ }
+}
+
+template<class I, class Impl>
+void QQuickPaletteProviderPrivateBase<I, Impl>::connectItem()
+{
+ Q_ASSERT(itemWithPalette());
+
+ if constexpr (!isRootWindow<I>()) {
+ // Item with palette has the same lifetime as its implementation that inherits this class
+ I::connect(itemWithPalette(), &I::parentChanged , [this]() { inheritPalette(parentPalette()); });
+ I::connect(itemWithPalette(), &I::windowChanged , [this]() { inheritPalette(parentPalette()); });
+ I::connect(itemWithPalette(), &I::enabledChanged, [this]() { setCurrentColorGroup(); });
+ }
+}
+
+template<class I, class Impl>
+const I *QQuickPaletteProviderPrivateBase<I, Impl>::itemWithPalette() const
+{
+ static_assert(std::is_base_of<QObjectData, Impl>{},
+ "The Impl class must inherit QObjectData");
+
+ return static_cast<const I*>(static_cast<const Impl*>(this)->q_ptr);
+}
+
+template<class I, class Impl>
+I *QQuickPaletteProviderPrivateBase<I, Impl>::itemWithPalette()
+{
+ return const_cast<I*>(const_cast<const Self*>(this)->itemWithPalette());
+}
+
+template<class I, class Impl>
+QQuickPalette *QQuickPaletteProviderPrivateBase<I, Impl>::paletteData() const
+{
+ Q_ASSERT(m_palette); return m_palette.get();
+}
+
+template<class I, class Impl>
+QPalette QQuickPaletteProviderPrivateBase<I, Impl>::toQPalette() const
+{
+ return palette()->toQPalette();
+}
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPALETTEPROVIDERPRIVATEBASE_H
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index c12358e4f6..0c5a6578c3 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -97,10 +97,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathView : public QQuickItem
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount RESET resetPathItemCount NOTIFY pathItemCountChanged)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
- Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION 7)
+ Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION(2, 7))
Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged)
QML_NAMED_ELEMENT(PathView)
+ QML_ADDED_IN_VERSION(2, 0)
QML_ATTACHED(QQuickPathViewAttached)
public:
@@ -182,7 +183,7 @@ public:
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
- Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
+ Q_REVISION(2, 13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
static QQuickPathViewAttached *qmlAttachedProperties(QObject *);
@@ -215,7 +216,7 @@ Q_SIGNALS:
void highlightMoveDurationChanged();
void movementStarted();
void movementEnded();
- Q_REVISION(7) void movementDirectionChanged();
+ Q_REVISION(2, 7) void movementDirectionChanged();
void flickStarted();
void flickEnded();
void dragStarted();
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 0692a1da42..5f767bf1f5 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -658,10 +658,9 @@ bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
return QQuickItem::childMouseEventFilter(i, e);
}
-void QQuickPinchArea::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+void QQuickPinchArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
}
void QQuickPinchArea::itemChange(ItemChange change, const ItemChangeData &value)
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index d7f814cc8a..b488f436df 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
QML_NAMED_ELEMENT(Pinch)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPinch();
@@ -212,6 +213,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject
Q_PROPERTY(int pointCount READ pointCount)
Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPinchEvent(QPointF c, qreal s, qreal a, qreal r)
@@ -271,6 +273,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT)
QML_NAMED_ELEMENT(PinchArea)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPinchArea(QQuickItem *parent=nullptr);
@@ -286,14 +289,13 @@ Q_SIGNALS:
void pinchStarted(QQuickPinchEvent *pinch);
void pinchUpdated(QQuickPinchEvent *pinch);
void pinchFinished(QQuickPinchEvent *pinch);
- Q_REVISION(5) void smartZoom(QQuickPinchEvent *pinch);
+ Q_REVISION(2, 5) void smartZoom(QQuickPinchEvent *pinch);
protected:
bool childMouseEventFilter(QQuickItem *i, QEvent *e) override;
void touchEvent(QTouchEvent *event) override;
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void itemChange(ItemChange change, const ItemChangeData& value) override;
bool event(QEvent *) override;
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index b924cb9c12..2c3aa674c6 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -107,13 +107,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(QQuickTransition *move READ move WRITE setMove NOTIFY moveChanged)
Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged)
- Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
- Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
- Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
- Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
- Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6))
QML_NAMED_ELEMENT(Positioner)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Positioner is an abstract type that is only available as an attached property.")
QML_ATTACHED(QQuickPositionerAttached)
@@ -159,7 +160,7 @@ public:
void setBottomPadding(qreal padding);
void resetBottomPadding();
- Q_REVISION(9) Q_INVOKABLE void forceLayout();
+ Q_REVISION(2, 9) Q_INVOKABLE void forceLayout();
protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
@@ -173,12 +174,12 @@ Q_SIGNALS:
void populateChanged();
void moveChanged();
void addChanged();
- Q_REVISION(6) void paddingChanged();
- Q_REVISION(6) void topPaddingChanged();
- Q_REVISION(6) void leftPaddingChanged();
- Q_REVISION(6) void rightPaddingChanged();
- Q_REVISION(6) void bottomPaddingChanged();
- Q_REVISION(9) void positioningComplete();
+ Q_REVISION(2, 6) void paddingChanged();
+ Q_REVISION(2, 6) void topPaddingChanged();
+ Q_REVISION(2, 6) void leftPaddingChanged();
+ Q_REVISION(2, 6) void rightPaddingChanged();
+ Q_REVISION(2, 6) void bottomPaddingChanged();
+ Q_REVISION(2, 9) void positioningComplete();
protected Q_SLOTS:
void prePositioning();
@@ -236,6 +237,7 @@ class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
{
Q_OBJECT
QML_NAMED_ELEMENT(Column)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickColumn(QQuickItem *parent=nullptr);
@@ -253,6 +255,7 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
QML_NAMED_ELEMENT(Row)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickRow(QQuickItem *parent=nullptr);
@@ -284,10 +287,11 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
- Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1)
- Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1)
- Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1)
+ Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION(2, 1))
+ Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION(2, 1))
+ Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION(2, 1))
QML_NAMED_ELEMENT(Grid)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickGrid(QQuickItem *parent=nullptr);
@@ -339,9 +343,9 @@ Q_SIGNALS:
void effectiveLayoutDirectionChanged();
void rowSpacingChanged();
void columnSpacingChanged();
- Q_REVISION(1) void horizontalAlignmentChanged(HAlignment alignment);
- Q_REVISION(1) void effectiveHorizontalAlignmentChanged(HAlignment alignment);
- Q_REVISION(1) void verticalAlignmentChanged(VAlignment alignment);
+ Q_REVISION(2, 1) void horizontalAlignmentChanged(HAlignment alignment);
+ Q_REVISION(2, 1) void effectiveHorizontalAlignmentChanged(HAlignment alignment);
+ Q_REVISION(2, 1) void verticalAlignmentChanged(VAlignment alignment);
protected:
void doPositioning(QSizeF *contentSize) override;
@@ -369,6 +373,7 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
QML_NAMED_ELEMENT(Flow)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickFlow(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h
index 934300b63b..c4f03de770 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -67,6 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPen(QObject *parent=nullptr);
@@ -98,6 +99,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject
Q_PROPERTY(qreal position READ position WRITE setPosition)
Q_PROPERTY(QColor color READ color WRITE setColor)
QML_NAMED_ELEMENT(GradientStop)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickGradientStop(QObject *parent=nullptr);
@@ -121,9 +123,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QQuickGradientStop> stops READ stops)
- Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION 12)
+ Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION(2, 12))
Q_CLASSINFO("DefaultProperty", "stops")
QML_NAMED_ELEMENT(Gradient)
+ QML_ADDED_IN_VERSION(2, 0)
Q_ENUMS(QGradient::Preset)
public:
@@ -165,6 +168,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem
Q_PROPERTY(QQuickPen * border READ border CONSTANT)
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
QML_NAMED_ELEMENT(Rectangle)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickRectangle(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 9f9777f199..b42a3ea6aa 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -43,28 +43,36 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QTime>
#include <QtQuick/private/qquickanimatorcontroller_p.h>
+#include <QtQuick/private/qsgdefaultrendercontext_p.h>
+#include <QtQuick/private/qsgrhisupport_p.h>
#if QT_CONFIG(opengl)
-# include <QtGui/QOpenGLContext>
-# include <QtQuick/private/qsgdefaultrendercontext_p.h>
+# include <QOpenGLContext>
#if QT_CONFIG(quick_shadereffect)
# include <QtQuick/private/qquickopenglshadereffectnode_p.h>
#endif
#endif
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <QtGui/qoffscreensurface.h>
#include <QtQml/private/qqmlglobal_p.h>
#include <QtQuick/QQuickWindow>
+#include <QtQuick/QQuickRenderTarget>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qsgsoftwarerenderer_p.h>
#include <QtCore/private/qobject_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtGui/private/qrhi_p.h>
+
QT_BEGIN_NAMESPACE
#if QT_CONFIG(opengl)
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
#endif
+
/*!
\class QQuickRenderControl
@@ -135,9 +143,14 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
QSGContext *QQuickRenderControlPrivate::sg = nullptr;
-QQuickRenderControlPrivate::QQuickRenderControlPrivate()
- : initialized(0),
- window(nullptr)
+QQuickRenderControlPrivate::QQuickRenderControlPrivate(QQuickRenderControl *renderControl)
+ : q(renderControl),
+ initialized(false),
+ window(nullptr),
+ rhi(nullptr),
+ cb(nullptr),
+ offscreenSurface(nullptr),
+ sampleCount(1)
{
if (!sg) {
qAddPostRoutine(cleanup);
@@ -157,7 +170,7 @@ void QQuickRenderControlPrivate::cleanup()
object \a parent.
*/
QQuickRenderControl::QQuickRenderControl(QObject *parent)
- : QObject(*(new QQuickRenderControlPrivate), parent)
+ : QObject(*(new QQuickRenderControlPrivate(this)), parent)
{
}
@@ -181,11 +194,16 @@ QQuickRenderControl::~QQuickRenderControl()
d->windowDestroyed();
delete d->rc;
+
+ d->resetRhi();
}
void QQuickRenderControlPrivate::windowDestroyed()
{
if (window) {
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ cd->cleanupNodesOnShutdown();
+
rc->invalidate();
QQuickWindowPrivate::get(window)->animationController.reset();
@@ -214,6 +232,91 @@ void QQuickRenderControl::prepareThread(QThread *targetThread)
}
/*!
+ Sets the number of samples to use for multisampling. When \a sampleCount is
+ 0 or 1, multisampling is disabled.
+
+ \note This function is always used in combination with a multisample render
+ target, which means \a sampleCount must match the sample count passed to
+ QQuickRenderTarget::fromNativeTexture(), which in turn must match the
+ sample count of the native texture.
+
+ \since 6.0
+
+ \sa initialize(), QQuickRenderTarget
+ */
+void QQuickRenderControl::setSamples(int sampleCount)
+{
+ Q_D(QQuickRenderControl);
+ d->sampleCount = qMax(1, sampleCount);
+}
+
+/*!
+ \return the current sample count. 1 or 0 means no multisampling.
+
+ \since 6.0
+ */
+int QQuickRenderControl::samples() const
+{
+ Q_D(const QQuickRenderControl);
+ return d->sampleCount;
+}
+
+/*!
+ Initializes the scene graph resources. When using a graphics API, such as
+ Vulkan, Metal, OpenGL, or Direct3D, for Qt Quick rendering,
+ QQuickRenderControl will set up an appropriate rendering engine when this
+ function is called. This rendering infrastructure exists as long as the
+ QQuickRenderControl exists.
+
+ To control what graphics API Qt Quick uses, call
+ QQuickWindow::setSceneGraphBackend() with one of the
+ QSGRendererInterface:GraphicsApi constants. That must be done before
+ calling this function.
+
+ To prevent the scenegraph from creating its own device and context objects,
+ specify an appropriate QQuickGraphicsDevice, wrapping existing graphics
+ objects, by calling QQuickWindow::setGraphicsDevice().
+
+ \note This function does not need to be, and must not be, called when using
+ the \c software adaptation of Qt Quick.
+
+ \since 6.0
+
+ \sa QQuickRenderTarget, QQuickGraphicsDevice
+ */
+bool QQuickRenderControl::initialize()
+{
+ Q_D(QQuickRenderControl);
+// ### Qt 6 clean this up
+#if QT_CONFIG(opengl)
+ if (!d->window) {
+ qWarning("QQuickRenderControl::initialize called with no associated window");
+ return false;
+ }
+
+ if (!d->initRhi())
+ return false;
+
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
+ wd->rhi = d->rhi;
+
+ QSGDefaultRenderContext *renderContext = qobject_cast<QSGDefaultRenderContext *>(d->rc);
+ if (renderContext) {
+ QSGDefaultRenderContext::InitParams params;
+ params.rhi = d->rhi;
+ params.sampleCount = d->sampleCount;
+ params.initialSurfacePixelSize = d->window->size() * d->window->effectiveDevicePixelRatio();
+ params.maybeSurface = d->window;
+ renderContext->initialize(&params);
+ } else {
+ qWarning("QRhi is only compatible with default adaptation");
+ return false;
+ }
+#endif
+ return true;
+}
+
+/*!
Initializes the scene graph resources. The context \a gl has to be the
current OpenGL context or null if it is not relevant because a Qt Quick
backend other than OpenGL is in use.
@@ -294,24 +397,33 @@ bool QQuickRenderControl::sync()
return false;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ // we may not have a d->rhi (software backend) hence the check is important
+ if (d->rhi) {
+ if (!d->rhi->isRecordingFrame()) {
+ qWarning("QQuickRenderControl can only sync when beginFrame() has been called");
+ return false;
+ }
+ if (!d->cb) {
+ qWarning("QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided");
+ return false;
+ }
+ cd->setCustomCommandBuffer(d->cb);
+ }
+
cd->syncSceneGraph();
d->rc->endSync();
- // TODO: find out if the sync actually caused a scenegraph update.
return true;
}
/*!
- Stop rendering and release resources. Requires a current context.
+ Stop rendering and release resources.
This is the equivalent of the cleanup operations that happen with a
real QQuickWindow when the window becomes hidden.
This function is called from the destructor. Therefore there will
- typically be no need to call it directly. Pay attention however to
- the fact that this requires the context, that was passed to
- initialize(), to be the current one at the time of destroying the
- QQuickRenderControl instance.
+ typically be no need to call it directly.
Once invalidate() has been called, it is possible to reuse the
QQuickRenderControl instance by calling initialize() again.
@@ -352,6 +464,19 @@ void QQuickRenderControl::render()
return;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ // we may not have a d->rhi (software backend) hence the check is important
+ if (d->rhi) {
+ if (!d->rhi->isRecordingFrame()) {
+ qWarning("QQuickRenderControl can only render when beginFrame() has been called");
+ return;
+ }
+ if (!d->cb) {
+ qWarning("QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided");
+ return;
+ }
+ cd->setCustomCommandBuffer(d->cb);
+ }
+
cd->renderSceneGraph(d->window->size());
}
@@ -377,48 +502,50 @@ void QQuickRenderControl::render()
for example. This will lead to better performance.
*/
-/*!
- Grabs the contents of the scene and returns it as an image.
-
- \note Requires the context to be current.
- */
-QImage QQuickRenderControl::grab()
+QImage QQuickRenderControlPrivate::grab()
{
- Q_D(QQuickRenderControl);
- if (!d->window)
+ if (!window)
return QImage();
QImage grabContent;
- if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
+ if (rhi) {
+
+ // As documented by QQuickWindow::grabWindow(): Nothing to do here, we
+ // do not support "grabbing" with an application-provided render target
+ // in Qt 6. (with the exception of the software backend because that
+ // does not support custom render targets, so the grab implementation
+ // here is still valuable)
+
+ } else if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
#if QT_CONFIG(opengl)
- QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
cd->polishItems();
cd->syncSceneGraph();
- d->rc->endSync();
- render();
- const bool alpha = d->window->format().alphaBufferSize() > 0 && d->window->color().alpha() < 255;
- grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), alpha, alpha);
- if (QQuickRenderControl::renderWindowFor(d->window)) {
- grabContent.setDevicePixelRatio(d->window->effectiveDevicePixelRatio());
+ rc->endSync();
+ q->render();
+ const bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() < 255;
+ grabContent = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), alpha, alpha);
+ if (QQuickRenderControl::renderWindowFor(window)) {
+ grabContent.setDevicePixelRatio(window->effectiveDevicePixelRatio());
}
#endif
#if QT_CONFIG(thread)
- } else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
- QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ } else if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
cd->polishItems();
cd->syncSceneGraph();
QSGSoftwareRenderer *softwareRenderer = static_cast<QSGSoftwareRenderer *>(cd->renderer);
if (softwareRenderer) {
- const qreal dpr = d->window->effectiveDevicePixelRatio();
- const QSize imageSize = d->window->size() * dpr;
+ const qreal dpr = window->effectiveDevicePixelRatio();
+ const QSize imageSize = window->size() * dpr;
grabContent = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
grabContent.setDevicePixelRatio(dpr);
QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
softwareRenderer->setCurrentPaintDevice(&grabContent);
softwareRenderer->markDirty();
- d->rc->endSync();
- render();
+ rc->endSync();
+ q->render();
softwareRenderer->setCurrentPaintDevice(prevDev);
}
#endif
@@ -473,6 +600,135 @@ QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset)
return nullptr;
}
+/*!
+ \return the QQuickWindow this QQuickRenderControl is associated with.
+
+ \note A QQuickRenderControl gets associated with a QQuickWindow when
+ constructing the QQuickWindow. The return value from this function is null
+ before that point.
+
+ \since 6.0
+ */
+QQuickWindow *QQuickRenderControl::window() const
+{
+ Q_D(const QQuickRenderControl);
+ return d->window;
+}
+
+/*!
+ Specifies the start of a graphics frame. Calls to sync() or render() must
+ be enclosed by calls to beginFrame() and endFrame().
+
+ Unlike the earlier OpenGL-only world of Qt 5, rendering with other graphics
+ APIs requires more well-defined points of starting and ending a frame. When
+ manually driving the rendering loop via QQuickRenderControl, it now falls
+ to the user of QQuickRenderControl to specify these points.
+
+ A typical update step, including initialization of rendering into an
+ existing texture, could like like the following. The example snippet
+ assumes Direct3D 11 but the same concepts apply other graphics APIs as
+ well.
+
+ \badcode
+ if (!m_quickInitialized) {
+ m_quickWindow->setGraphicsDevice(QQuickGraphicsDevice::fromDeviceAndContext(m_engine->device(), m_engine->context()));
+
+ if (!m_renderControl->initialize())
+ qWarning("Failed to initialize redirected Qt Quick rendering");
+
+ m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ &m_res.texture, 0 },
+ QSize(QML_WIDTH, QML_HEIGHT),
+ SAMPLE_COUNT));
+
+ m_quickInitialized = true;
+ }
+
+ m_renderControl->polishItems();
+
+ m_renderControl->beginFrame();
+ m_renderControl->sync();
+ m_renderControl->render();
+ m_renderControl->endFrame(); // Qt Quick's rendering commands are submitted to the device context here
+ \endcode
+
+ \since 6.0
+
+ \sa endFrame(), initialize(), sync(), render(), QQuickGraphicsDevice, QQuickRenderTarget
+ */
+void QQuickRenderControl::beginFrame()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->rhi || d->rhi->isRecordingFrame())
+ return;
+
+ emit d->window->beforeFrameBegin();
+
+ d->rhi->beginOffscreenFrame(&d->cb, QRhi::ExternalContentsInPass); // must specify ExternalContents since we do not know in advance
+}
+
+/*!
+ Specifies the end of a graphics frame. Calls to sync() or render() must be
+ enclosed by calls to beginFrame() and endFrame().
+
+ When this function is called, any graphics commands enqueued by the
+ scenegraph are submitted to the context or command queue, whichever is
+ applicable.
+
+ \since 6.0
+
+ \sa beginFrame(), initialize(), sync(), render(), QQuickGraphicsDevice, QQuickRenderTarget
+ */
+void QQuickRenderControl::endFrame()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->rhi || !d->rhi->isRecordingFrame())
+ return;
+
+ d->rhi->endOffscreenFrame();
+ d->cb = nullptr;
+
+ emit d->window->afterFrameEnd();
+}
+
+bool QQuickRenderControlPrivate::initRhi()
+{
+ // initialize() - invalidate() - initialize() uses the QRhi the first
+ // initialize() created, so if already exists, we are done
+ if (rhi)
+ return true;
+
+ QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
+
+ // sanity check for Vulkan
+#if QT_CONFIG(vulkan)
+ if (rhiSupport->rhiBackend() == QRhi::Vulkan && !window->vulkanInstance()) {
+ qWarning("QQuickRenderControl: No QVulkanInstance set for QQuickWindow, cannot initialize");
+ return false;
+ }
+#endif
+
+ // for OpenGL
+ if (!offscreenSurface)
+ offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
+
+ rhi = rhiSupport->createRhi(window, offscreenSurface);
+ if (!rhi) {
+ qWarning("QQuickRenderControl: Failed to initialize QRhi");
+ return false;
+ }
+
+ return true;
+}
+
+void QQuickRenderControlPrivate::resetRhi()
+{
+ delete rhi;
+ rhi = nullptr;
+
+ delete offscreenSurface;
+ offscreenSurface = nullptr;
+}
+
QT_END_NAMESPACE
#include "moc_qquickrendercontrol.cpp"
diff --git a/src/quick/items/qquickrendercontrol.h b/src/quick/items/qquickrendercontrol.h
index 8ec9b8aafc..cdcad589f6 100644
--- a/src/quick/items/qquickrendercontrol.h
+++ b/src/quick/items/qquickrendercontrol.h
@@ -41,7 +41,7 @@
#define QQUICKRENDERCONTROL_H
#include <QtQuick/qtquickglobal.h>
-#include <QtGui/QImage>
+#include <QtGui/qimage.h>
QT_BEGIN_NAMESPACE
@@ -59,18 +59,27 @@ public:
~QQuickRenderControl() override;
void prepareThread(QThread *targetThread);
- void initialize(QOpenGLContext *gl);
+
+ void setSamples(int sampleCount);
+ int samples() const;
+
+ bool initialize();
+ void initialize(QOpenGLContext *gl); // ### Qt 6 remove
+
void invalidate();
+ void beginFrame();
+ void endFrame();
+
void polishItems();
- void render();
bool sync();
-
- QImage grab();
+ void render();
static QWindow *renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr);
virtual QWindow *renderWindow(QPoint *offset) { Q_UNUSED(offset); return nullptr; }
+ QQuickWindow *window() const;
+
Q_SIGNALS:
void renderRequested();
void sceneChanged();
diff --git a/src/quick/items/qquickrendercontrol_p.h b/src/quick/items/qquickrendercontrol_p.h
index 487af45db5..c24ea9b8c6 100644
--- a/src/quick/items/qquickrendercontrol_p.h
+++ b/src/quick/items/qquickrendercontrol_p.h
@@ -56,12 +56,16 @@
QT_BEGIN_NAMESPACE
-class QQuickRenderControlPrivate : public QObjectPrivate
+class QRhi;
+class QRhiCommandBuffer;
+class QOffscreenSurface;
+
+class Q_AUTOTEST_EXPORT QQuickRenderControlPrivate : public QObjectPrivate
{
public:
Q_DECLARE_PUBLIC(QQuickRenderControl)
- QQuickRenderControlPrivate();
+ QQuickRenderControlPrivate(QQuickRenderControl *renderControl);
static QQuickRenderControlPrivate *get(QQuickRenderControl *renderControl) {
return renderControl->d_func();
@@ -74,10 +78,20 @@ public:
void update();
void maybeUpdate();
+ bool initRhi();
+ void resetRhi();
+
+ QImage grab();
+
+ QQuickRenderControl *q;
bool initialized;
QQuickWindow *window;
static QSGContext *sg;
QSGRenderContext *rc;
+ QRhi *rhi;
+ QRhiCommandBuffer *cb;
+ QOffscreenSurface *offscreenSurface;
+ int sampleCount;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrendertarget.cpp b/src/quick/items/qquickrendertarget.cpp
new file mode 100644
index 0000000000..924824e456
--- /dev/null
+++ b/src/quick/items/qquickrendertarget.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $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 "qquickrendertarget_p.h"
+#include <QtGui/private/qrhi_p.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickRenderTarget
+ \since 6.0
+ \inmodule QtQuick
+
+ \brief The QQuickRenderTarget class provides an opaque container for native
+ graphics resources specifying a render target, and associated metadata.
+
+ \sa QQuickWindow::setRenderTarget(), QQuickGraphicsDevice
+*/
+
+QQuickRenderTargetPrivate::QQuickRenderTargetPrivate()
+ : ref(1)
+{
+}
+
+QQuickRenderTargetPrivate::QQuickRenderTargetPrivate(const QQuickRenderTargetPrivate *other)
+ : ref(1),
+ type(other->type),
+ pixelSize(other->pixelSize),
+ sampleCount(other->sampleCount),
+ u(other->u)
+{
+}
+
+/*!
+ Constructs a default QQuickRenderTarget that does not reference any native
+ objects.
+ */
+QQuickRenderTarget::QQuickRenderTarget()
+ : d(new QQuickRenderTargetPrivate)
+{
+}
+
+/*!
+ \internal
+ */
+void QQuickRenderTarget::detach()
+{
+ qAtomicDetach(d);
+}
+
+/*!
+ \internal
+ */
+QQuickRenderTarget::QQuickRenderTarget(const QQuickRenderTarget &other)
+ : d(other.d)
+{
+ d->ref.ref();
+}
+
+/*!
+ \internal
+ */
+QQuickRenderTarget &QQuickRenderTarget::operator=(const QQuickRenderTarget &other)
+{
+ qAtomicAssign(d, other.d);
+ return *this;
+}
+
+/*!
+ Destructor.
+ */
+QQuickRenderTarget::~QQuickRenderTarget()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+/*!
+ \return true if this QQuickRenderTarget is default constructed, referencing
+ no native objects.
+ */
+bool QQuickRenderTarget::isNull() const
+{
+ return d->type == QQuickRenderTargetPrivate::Type::Null;
+}
+
+/*!
+ \return a new QQuickRenderTarget referencing a native texture or image
+ object.
+
+ \a nativeTexture references a native resource, for example, a \c VkImage,
+ \c ID3D11Texture2D*, c MTLTexture*, or \c GLuint. Where applicable, this
+ must be complemented by the current layout of the image.
+
+ \note the \c object field in \a nativeTexture must always be a pointer to
+ the native object, even if the type is already a pointer.
+
+ \a pixelSize specifies the size of the image, in pixels. Currently only 2D
+ textures are supported.
+
+ \a sampleCount specific the number of samples. 0 or 1 means no
+ multisampling, while a value like 4 or 8 states that the native object is a
+ multisample texture.
+
+ \note the resulting QQuickRenderTarget does not own any native resources,
+ it merely contains references and the associated metadata of the size and
+ sample count. It is the caller's responsibility to ensure that the native
+ resource exists as long as necessary.
+
+ \sa QQuickWindow::setRenderTarget(), QQuickRenderControl
+ */
+QQuickRenderTarget QQuickRenderTarget::fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture,
+ const QSize &pixelSize,
+ int sampleCount)
+{
+ QQuickRenderTarget rt;
+ QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
+
+ if (!nativeTexture.object) {
+ qWarning("QQuickRenderTarget: nativeTexture.object is null");
+ return rt;
+ }
+
+ if (pixelSize.isEmpty()) {
+ qWarning("QQuickRenderTarget: Cannot create with empty size");
+ return rt;
+ }
+
+ d->type = QQuickRenderTargetPrivate::Type::NativeTexture;
+ d->pixelSize = pixelSize;
+ d->sampleCount = qMax(1, sampleCount);
+ d->u.nativeTexture = nativeTexture;
+
+ return rt;
+}
+
+/*!
+ \internal
+ */
+QQuickRenderTarget QQuickRenderTarget::fromRhiRenderTarget(QRhiRenderTarget *renderTarget)
+{
+ QQuickRenderTarget rt;
+ QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
+
+ if (!renderTarget) {
+ qWarning("QQuickRenderTarget: Needs a valid QRhiRenderTarget");
+ return rt;
+ }
+
+ d->type = QQuickRenderTargetPrivate::Type::RhiRenderTarget;
+ d->pixelSize = renderTarget->pixelSize();
+ d->sampleCount = renderTarget->sampleCount();
+ d->u.rhiRt = renderTarget;
+
+ return rt;
+}
+
+/*!
+ \return true if \a a and \a b refer to the same set of native objects and
+ have matching associated data (size, sample count).
+ */
+bool operator==(const QQuickRenderTarget &a, const QQuickRenderTarget &b) Q_DECL_NOTHROW
+{
+ const QQuickRenderTargetPrivate *da = QQuickRenderTargetPrivate::get(&a);
+ const QQuickRenderTargetPrivate *db = QQuickRenderTargetPrivate::get(&b);
+ if (da->type != db->type
+ || da->pixelSize != db->pixelSize
+ || da->sampleCount != db->sampleCount)
+ {
+ return false;
+ }
+
+ switch (da->type) {
+ case QQuickRenderTargetPrivate::Type::Null:
+ break;
+ case QQuickRenderTargetPrivate::Type::NativeTexture:
+ if (da->u.nativeTexture.object != db->u.nativeTexture.object
+ || da->u.nativeTexture.layout != db->u.nativeTexture.layout)
+ return false;
+ break;
+ case QQuickRenderTargetPrivate::Type::RhiRenderTarget:
+ if (da->u.rhiRt != db->u.rhiRt)
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/*!
+ \return true if \a a and \a b refer to a different set of native objects,
+ or the associated data (size, sample count) does not match.
+ */
+bool operator!=(const QQuickRenderTarget &a, const QQuickRenderTarget &b) Q_DECL_NOTHROW
+{
+ return !(a == b);
+}
+
+bool QQuickRenderTargetPrivate::resolve(QRhi *rhi, QQuickWindowRenderTarget *dst)
+{
+ switch (type) {
+ case Type::Null:
+ dst->renderTarget = nullptr;
+ dst->owns = false;
+ return true;
+
+ case Type::NativeTexture:
+ {
+ QRhiTexture *texture = rhi->newTexture(QRhiTexture::RGBA8, pixelSize, sampleCount, QRhiTexture::RenderTarget);
+ if (!texture->buildFrom({ u.nativeTexture.object, u.nativeTexture.layout })) {
+ qWarning("Failed to build texture for QQuickRenderTarget");
+ return false;
+ }
+ QRhiRenderBuffer *depthStencil = rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, pixelSize, sampleCount);
+ if (!depthStencil->build()) {
+ qWarning("Failed to build depth-stencil buffer for QQuickRenderTarget");
+ delete texture;
+ return false;
+ }
+
+ QRhiColorAttachment att(texture);
+ QRhiTextureRenderTargetDescription rtDesc(att);
+ rtDesc.setDepthStencilBuffer(depthStencil);
+ QRhiTextureRenderTarget *rt = rhi->newTextureRenderTarget(rtDesc);
+ QRhiRenderPassDescriptor *rp = rt->newCompatibleRenderPassDescriptor();
+ rt->setRenderPassDescriptor(rp);
+ if (!rt->build()) {
+ qWarning("Failed to build texture render target for QQuickRenderTarget");
+ delete rp;
+ delete depthStencil;
+ delete texture;
+ return false;
+ }
+ dst->renderTarget = rt;
+ dst->rpDesc = rp;
+ dst->texture = texture;
+ dst->depthStencil = depthStencil;
+ dst->owns = true; // ownership of the native resource itself is not transferred but the QRhi objects are on us now
+ }
+ return true;
+
+ case Type::RhiRenderTarget:
+ dst->renderTarget = u.rhiRt;
+ dst->owns = false;
+ return true;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h b/src/quick/items/qquickrendertarget.h
index 035c3408ff..5139046ad4 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h
+++ b/src/quick/items/qquickrendertarget.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,45 +37,42 @@
**
****************************************************************************/
-#ifndef QSGD3D12ADAPTATION_P_H
-#define QSGD3D12ADAPTATION_P_H
+#ifndef QQUICKRENDERTARGET_H
+#define QQUICKRENDERTARGET_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 <private/qsgcontextplugin_p.h>
+#include <QtQuick/qtquickglobal.h>
+#include <QtQuick/qsgtexture.h>
QT_BEGIN_NAMESPACE
-class QSGD3D12Context;
-class QSGContext;
-class QSGRenderLoop;
+class QQuickRenderTargetPrivate;
+class QRhiRenderTarget;
-class QSGD3D12Adaptation : public QSGContextPlugin
+class Q_QUICK_EXPORT QQuickRenderTarget
{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSGContextFactoryInterface" FILE "d3d12.json")
-
public:
- QSGD3D12Adaptation(QObject *parent = 0);
+ QQuickRenderTarget();
+ ~QQuickRenderTarget();
+ QQuickRenderTarget(const QQuickRenderTarget &other);
+ QQuickRenderTarget &operator=(const QQuickRenderTarget &other);
+
+ bool isNull() const;
- QStringList keys() const override;
- QSGContext *create(const QString &key) const override;
- QSGContextFactoryInterface::Flags flags(const QString &key) const override;
- QSGRenderLoop *createWindowManager() override;
+ static QQuickRenderTarget fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture,
+ const QSize &pixelSize,
+ int sampleCount = 1);
+
+ static QQuickRenderTarget fromRhiRenderTarget(QRhiRenderTarget *renderTarget);
private:
- static QSGD3D12Context *contextInstance;
+ void detach();
+ QQuickRenderTargetPrivate *d;
+ friend class QQuickRenderTargetPrivate;
};
+Q_QUICK_EXPORT bool operator==(const QQuickRenderTarget &a, const QQuickRenderTarget &b) Q_DECL_NOTHROW;
+Q_QUICK_EXPORT bool operator!=(const QQuickRenderTarget &a, const QQuickRenderTarget &b) Q_DECL_NOTHROW;
+
QT_END_NAMESPACE
-#endif // QSGD3D12ADAPTATION_P_H
+#endif // QQUICKRENDERTARGET_H
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h b/src/quick/items/qquickrendertarget_p.h
index 265bec7c78..628e5c277b 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h
+++ b/src/quick/items/qquickrendertarget_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QSGD3D12SPRITENODE_H
-#define QSGD3D12SPRITENODE_H
+#ifndef QQUICKRENDERTARGET_P_H
+#define QQUICKRENDERTARGET_P_H
//
// W A R N I N G
@@ -51,40 +51,40 @@
// We mean it.
//
-#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
+#include "qquickrendertarget.h"
+#include <QAtomicInt>
QT_BEGIN_NAMESPACE
-class QSGD3D12SpriteMaterial;
+class QRhi;
+class QQuickWindowRenderTarget;
-class QSGD3D12SpriteNode : public QSGSpriteNode
+class Q_QUICK_PRIVATE_EXPORT QQuickRenderTargetPrivate
{
public:
- QSGD3D12SpriteNode();
+ static QQuickRenderTargetPrivate *get(QQuickRenderTarget *rt) { return rt->d; }
+ static const QQuickRenderTargetPrivate *get(const QQuickRenderTarget *rt) { return rt->d; }
+ QQuickRenderTargetPrivate();
+ QQuickRenderTargetPrivate(const QQuickRenderTargetPrivate *other);
+ bool resolve(QRhi *rhi, QQuickWindowRenderTarget *dst);
- void setTexture(QSGTexture *texture) override;
- void setTime(float time) override;
- void setSourceA(const QPoint &source) override;
- void setSourceB(const QPoint &source) override;
- void setSpriteSize(const QSize &size) override;
- void setSheetSize(const QSize &size) override;
- void setSize(const QSizeF &size) override;
- void setFiltering(QSGTexture::Filtering filtering) override;
- void update() override;
+ enum class Type {
+ Null,
+ NativeTexture,
+ RhiRenderTarget
+ };
-private:
- void updateGeometry();
-
- QSGD3D12SpriteMaterial *m_material;
- QSGGeometry *m_geometry;
- bool m_geometryDirty;
- QPoint m_sourceA;
- QPoint m_sourceB;
- QSize m_spriteSize;
- QSize m_sheetSize;
- QSizeF m_size;
+ QAtomicInt ref;
+ Type type = Type::Null;
+ QSize pixelSize;
+ int sampleCount = 1;
+ union {
+ QSGTexture::NativeTexture nativeTexture;
+ QRhiRenderTarget *rhiRt;
+ } u;
};
QT_END_NAMESPACE
-#endif // QSGD3D12SPRITENODE_H
+#endif // QQUICKRENDERTARGET_P_H
diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h
index 20984fa23e..652651efb9 100644
--- a/src/quick/items/qquickrepeater_p.h
+++ b/src/quick/items/qquickrepeater_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
QML_NAMED_ELEMENT(Repeater)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickRepeater(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h
index 56b0ee86ab..1eb6c05ef1 100644
--- a/src/quick/items/qquickscalegrid_p_p.h
+++ b/src/quick/items/qquickscalegrid_p_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject
Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightBorderChanged)
Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomBorderChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickScaleGrid(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index ed2d7eda3e..9a2799ae96 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -213,18 +213,16 @@ QT_BEGIN_NAMESPACE
\qmlattachedproperty Qt::ScreenOrientation Screen::orientation
\readonly
- This contains the current orientation of the screen, from the accelerometer
- (if any). On a desktop computer, this value typically does not change.
-
- If primaryOrientation == orientation, it means that the screen
- automatically rotates all content which is displayed, depending on how you
- hold it. But if orientation changes while primaryOrientation does NOT
- change, then probably you are using a device which does not rotate its own
- display. In that case you may need to use \l {Item::rotation}{Item.rotation} or
- \l {Item::transform}{Item.transform} to rotate your content.
-
- \note This property does not update unless a Screen::orientationUpdateMask
- is set to a value other than \c 0.
+ This contains the current orientation of the screen from the
+ window system perspective.
+
+ Most mobile devices and tablet computers contain accelerometer sensors.
+ The Qt Sensors module provides the ability to read this sensor directly.
+ However, the windowing system may rotate the entire screen automatically
+ based on how it is being held, or manually via settings to rotate a desktop
+ monitor; in that case, this \c orientation property will change.
+
+ \sa primaryOrientation(), QWindow::contentOrientation(), QOrientationSensor
*/
/*!
\qmlattachedmethod int Screen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
@@ -233,16 +231,6 @@ QT_BEGIN_NAMESPACE
orientations \a a and \a b.
*/
-/*!
- \qmlattachedproperty Qt::ScreenOrientations Screen::orientationUpdateMask
- \since 5.4
-
- This contains the update mask for the orientation. Screen::orientation
- only emits changes for the screen orientations matching this mask.
-
- By default it is set to the value of the QScreen that the window uses.
-*/
-
QQuickScreenInfo::QQuickScreenInfo(QObject *parent, QScreen *wrappedScreen)
: QObject(parent)
, m_screen(wrappedScreen)
@@ -442,25 +430,6 @@ QQuickScreenAttached::QQuickScreenAttached(QObject* attachee)
screenChanged(QGuiApplication::primaryScreen());
}
-Qt::ScreenOrientations QQuickScreenAttached::orientationUpdateMask() const
-{
- return m_updateMask;
-}
-
-void QQuickScreenAttached::setOrientationUpdateMask(Qt::ScreenOrientations mask)
-{
- m_updateMaskSet = true;
- if (m_updateMask == mask)
- return;
-
- m_updateMask = mask;
-
- if (m_screen)
- m_screen->setOrientationUpdateMask(m_updateMask);
-
- emit orientationUpdateMaskChanged();
-}
-
int QQuickScreenAttached::angleBetween(int a, int b)
{
if (!m_screen)
@@ -481,17 +450,8 @@ void QQuickScreenAttached::windowChanged(QQuickWindow* c)
void QQuickScreenAttached::screenChanged(QScreen *screen)
{
//qDebug() << "QQuickScreenAttached::screenChanged" << (screen ? screen->name() : QString::fromLatin1("null"));
- if (screen != m_screen) {
+ if (screen != m_screen)
setWrappedScreen(screen);
- if (!m_screen)
- return;
- if (m_updateMaskSet) {
- m_screen->setOrientationUpdateMask(m_updateMask);
- } else if (m_updateMask != m_screen->orientationUpdateMask()) {
- m_updateMask = m_screen->orientationUpdateMask();
- emit orientationUpdateMaskChanged();
- }
- }
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 9a2a9eaecf..78e82a420a 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -68,9 +68,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
- Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged REVISION 10)
- Q_PROPERTY(QString model READ model NOTIFY modelChanged REVISION 10)
- Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged REVISION 10)
+ Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged REVISION(2, 10))
+ Q_PROPERTY(QString model READ model NOTIFY modelChanged REVISION(2, 10))
+ Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged REVISION(2, 10))
Q_PROPERTY(int width READ width NOTIFY widthChanged)
Q_PROPERTY(int height READ height NOTIFY heightChanged)
Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged)
@@ -81,8 +81,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged)
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
- Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3)
- Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 3)
+ Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION(2, 3))
+ Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION(2, 3))
+ QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0);
public:
QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr);
@@ -108,9 +110,9 @@ public:
Q_SIGNALS:
void nameChanged();
- Q_REVISION(10) void manufacturerChanged();
- Q_REVISION(10) void modelChanged();
- Q_REVISION(10) void serialNumberChanged();
+ Q_REVISION(2, 10) void manufacturerChanged();
+ Q_REVISION(2, 10) void modelChanged();
+ Q_REVISION(2, 10) void serialNumberChanged();
void widthChanged();
void heightChanged();
void desktopGeometryChanged();
@@ -119,8 +121,8 @@ Q_SIGNALS:
void devicePixelRatioChanged();
void primaryOrientationChanged();
void orientationChanged();
- Q_REVISION(3) void virtualXChanged();
- Q_REVISION(3) void virtualYChanged();
+ Q_REVISION(2, 3) void virtualXChanged();
+ Q_REVISION(2, 3) void virtualYChanged();
protected:
QPointer<QScreen> m_screen;
@@ -129,31 +131,24 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickScreenAttached : public QQuickScreenInfo
{
Q_OBJECT
- Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask
- WRITE setOrientationUpdateMask NOTIFY orientationUpdateMaskChanged)
+
+ QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0);
public:
QQuickScreenAttached(QObject* attachee);
- Qt::ScreenOrientations orientationUpdateMask() const;
- void setOrientationUpdateMask(Qt::ScreenOrientations mask);
-
//Treats int as Qt::ScreenOrientation, due to QTBUG-20639
Q_INVOKABLE int angleBetween(int a, int b);
void windowChanged(QQuickWindow*);
-Q_SIGNALS:
- void orientationUpdateMaskChanged();
-
protected Q_SLOTS:
void screenChanged(QScreen*);
private:
QQuickWindow* m_window = nullptr;
QQuickItem* m_attachee;
- Qt::ScreenOrientations m_updateMask;
- bool m_updateMaskSet = false;
};
class Q_QUICK_PRIVATE_EXPORT QQuickScreen : public QObject
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index b3c8386fd9..dee997b22d 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -179,201 +179,11 @@ QT_BEGIN_NAMESPACE
is a URL with the \c file or \c qrc schema, it is treated as a file
reference and the source code is read from the specified file.
- \section1 Direct3D and HLSL
-
- Direct3D backends provide ShaderEffect support with HLSL. The Direct3D 12
- backend requires using at least Shader Model 5.0 both for vertex and pixel
- shaders. When necessary, GraphicsInfo.shaderType can be used to decide
- at runtime what kind of value to assign to \l fragmentShader or
- \l vertexShader.
-
- All concepts described above for OpenGL and GLSL apply to Direct3D and HLSL
- as well. There are however a number of notable practical differences, which
- are the following:
-
- Instead of uniforms, HLSL shaders are expected to use a single constant
- buffer, assigned to register \c b0. The special names \c qt_Matrix,
- \c qt_Opacity, and \c qt_SubRect_<name> function the same way as with GLSL.
- All other members of the buffer are expected to map to properties in the
- ShaderEffect item.
-
- \note The buffer layout must be compatible for both shaders. This means
- that application-provided shaders must make sure \c qt_Matrix and
- \c qt_Opacity are included in the buffer, starting at offset 0, when custom
- code is provided for one type of shader only, leading to ShaderEffect
- providing the other shader. This is due to ShaderEffect's built-in shader code
- declaring a constant buffer containing \c{float4x4 qt_Matrix; float qt_Opacity;}.
-
- Unlike GLSL's attributes, no names are used for vertex input elements.
- Therefore qt_Vertex and qt_MultiTexCoord0 are not relevant. Instead, the
- standard Direct3D semantics, \c POSITION and \c TEXCOORD (or \c TEXCOORD0)
- are used for identifying the correct input layout.
-
- Unlike GLSL's samplers, texture and sampler objects are separate in HLSL.
- Shaders are expected to expect 2D, non-array, non-multisample textures.
- Both the texture and sampler binding points are expected to be sequential
- and start from 0 (meaning registers \c{t0, t1, ...}, and \c{s0, s1, ...},
- respectively). Unlike with OpenGL, samplers are not mapped to Qt Quick item
- properties and therefore the name of the sampler is not relevant. Instead,
- it is the textures that map to properties referencing \l Image or
- \l ShaderEffectSource items.
-
- Unlike OpenGL, backends for modern APIs will typically prefer offline
- compilation and shipping pre-compiled bytecode with applications instead of
- inlined shader source strings. In this case the string properties for
- vertex and fragment shaders are treated as URLs referring to local files or
- files shipped via the Qt resource system.
-
- To check at runtime what is supported, use the
- GraphicsInfo.shaderSourceType and GraphicsInfo.shaderCompilationType
- properties. Note that these are bitmasks, because some backends may support
- multiple approaches.
-
- In case of Direct3D 12, all combinations are supported. If the vertexShader
- and fragmentShader properties form a valid URL with the \c file or \c qrc
- schema, the bytecode or HLSL source code is read from the specified file.
- The type of the file contents is detected automatically. Otherwise, the
- string is treated as HLSL source code and is compiled at runtime, assuming
- Shader Model 5.0 and an entry point of \c{"main"}. This allows dynamically
- constructing shader strings. However, whenever the shader source code is
- static, it is strongly recommended to pre-compile to bytecode using the
- \c fxc tool and refer to these files from QML. This will be a lot more
- efficient at runtime and allows catching syntax errors in the shaders at
- compile time.
-
- Unlike OpenGL, the Direct3D backend is able to perform runtime shader
- compilation on dedicated threads. This is managed transparently to the
- applications, and means that ShaderEffect items that contain HLSL source
- strings do not block the rendering or other parts of the application until
- the bytecode is ready.
-
- Using files with bytecode is more flexible also when it comes to the entry
- point name (it can be anything, not limited to \c main) and the shader
- model (it can be something newer than 5.0, for instance 5.1).
-
- \table 70%
- \row
- \li \qml
- import QtQuick 2.0
-
- Rectangle {
- width: 200; height: 100
- Row {
- Image { id: img;
- sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
- ShaderEffect {
- width: 100; height: 100
- property variant src: img
- fragmentShader: "qrc:/effect_ps.cso"
- }
- }
- }
- \endqml
- \row
- \li where \c effect_ps.cso is the compiled bytecode for the following HLSL shader:
- \code
- cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
- return float4(col, tex.a) * qt_Opacity;
- }
- \endcode
- \endtable
-
- The above is equivalent to the OpenGL example presented earlier. The vertex
- shader is provided implicitly by ShaderEffect. Note that the output of the
- pixel shader is using premultiplied alpha and that \c qt_Matrix is present
- in the constant buffer at offset 0, even though the pixel shader does not
- use the value.
-
- If desired, the HLSL source code can be placed directly into the QML
- source, similarly to how its done with GLSL. The only difference in this
- case is the entry point name, which must be \c main when using inline
- source strings.
-
- Alternatively, we could also have referred to a file containing the source
- of the effect instead of the compiled bytecode version.
-
- Some effects will want to provide a vertex shader as well. Below is a
- similar effect with both the vertex and fragment shader provided by the
- application. This time the colorization factor is provided by the QML item
- instead of hardcoding it in the shader. This can allow, among others,
- animating the value using QML's and Qt Quick's standard facilities.
-
- \table 70%
- \row
- \li \qml
- import QtQuick 2.0
-
- Rectangle {
- width: 200; height: 100
- Row {
- Image { id: img;
- sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
- ShaderEffect {
- width: 100; height: 100
- property variant src: img
- property variant color: Qt.vector3d(0.344, 0.5, 0.156)
- vertexShader: "qrc:/effect_vs.cso"
- fragmentShader: "qrc:/effect_ps.cso"
- }
- }
- }
- \endqml
- \row
- \li where \c effect_vs.cso and \c effect_ps.cso are the compiled bytecode
- for \c ExampleVertexShader and \c ExamplePixelShader. The source code is
- presented as one snippet here, the shaders can however be placed in
- separate source files as well.
- \code
- cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- float3 color;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- struct PSInput
- {
- float4 position : SV_POSITION;
- float2 coord : TEXCOORD0;
- };
- PSInput ExampleVertexShader(float4 position : POSITION, float2 coord : TEXCOORD0)
- {
- PSInput result;
- result.position = mul(qt_Matrix, position);
- result.coord = coord;
- return result;
- }
- float4 ExamplePixelShader(PSInput input) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, color);
- return float4(col, tex.a) * qt_Opacity;
- }
- \endcode
- \endtable
-
- \note With OpenGL the \c y coordinate runs from bottom to top whereas with
- Direct 3D it goes top to bottom. For shader effect sources Qt Quick hides
- the difference by treating QtQuick::ShaderEffectSource::textureMirroring as
- appropriate, meaning texture coordinates in HLSL version of the shaders
- will not need any adjustments compared to the equivalent GLSL code.
-
\section1 Cross-platform, Cross-API ShaderEffect Items
- Some applications will want to be functional with multiple accelerated
- graphics backends. This has consequences for ShaderEffect items because the
- supported shading languages may vary from backend to backend.
+ Some applications will want to be functional with multiple graphics
+ APIs. This has consequences for ShaderEffect items because the supported
+ shading languages may vary from backend to backend.
There are two approaches to handle this: either write conditional property
values based on GraphicsInfo.shaderType, or use file selectors. In practice
@@ -404,20 +214,8 @@ QT_BEGIN_NAMESPACE
gl_FragColor = vec4(vec3(dot(tex.rgb,
vec3(0.344, 0.5, 0.156))),
tex.a) * qt_Opacity;"
- : GraphicsInfo.shaderType === GraphicsInfo.HLSL ?
- "cbuffer ConstantBuffer : register(b0)
- {
- float4x4 qt_Matrix;
- float qt_Opacity;
- };
- Texture2D src : register(t0);
- SamplerState srcSampler : register(s0);
- float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET
- {
- float4 tex = src.Sample(srcSampler, coord);
- float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156));
- return float4(col, tex.a) * qt_Opacity;
- }"
+ : GraphicsInfo.shaderType === GraphicsInfo.RhiShader ?
+ "qrc:/shader.frag.qsb"
: ""
}
}
@@ -429,15 +227,14 @@ QT_BEGIN_NAMESPACE
reported by GraphicsInfo is not up-to-date until the ShaderEffect item gets
associated with a QQuickWindow. Before that, the reported value is
GraphicsInfo.UnknownShadingLanguage. The alternative is to place the GLSL
- source code and the compiled D3D bytecode into the files
- \c{shaders/effect.frag} and \c{shaders/+hlsl/effect.frag}, include them in
- the Qt resource system, and let the ShaderEffect's internal QFileSelector
- do its job. The selector-less version is the GLSL source, while the \c hlsl
- selector is used when running on the D3D12 backend. The file under
- \c{+hlsl} can then contain either HLSL source code or compiled bytecode
- from the \c fxc tool. Additionally, when using a version 3.2 or newer core
- profile context with OpenGL, GLSL sources with a core profile compatible
- syntax can be placed under \c{+glslcore}.
+ source code and the RHI-compatible shader pack into the files
+ \c{shaders/effect.frag} and \c{shaders/+qsb/effect.frag}, include them in
+ the Qt resource system, and let the ShaderEffect's internal QFileSelector do
+ its job. The selector-less version is the GLSL source, while the \c qsb
+ selector is used when running with the Qt graphics abstraction (RHI).
+ Additionally, when using a version 3.2 or newer core profile context with
+ OpenGL, GLSL sources with a core profile compatible syntax can be placed
+ under \c{+glslcore}.
\qml
import QtQuick 2.8 // for GraphicsInfo
@@ -552,11 +349,7 @@ QQuickShaderEffect::~QQuickShaderEffect()
With GLSL the default shader expects the texture coordinate to be passed
from the vertex shader as \c{varying highp vec2 qt_TexCoord0}, and it
- samples from a sampler2D named \c source. With HLSL the texture is named
- \c source, while the vertex shader is expected to provide
- \c{float2 coord : TEXCOORD0} in its output in addition to
- \c{float4 position : SV_POSITION} (names can differ since linking is done
- based on the semantics).
+ samples from a sampler2D named \c source.
\sa vertexShader, GraphicsInfo
*/
@@ -593,9 +386,7 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
filesystem or bundled with the executable via Qt's resource system.
With GLSL the default shader passes the texture coordinate along to the
- fragment shader as \c{varying highp vec2 qt_TexCoord0}. With HLSL it is
- enough to use the standard \c TEXCOORD0 semantic, for example
- \c{float2 coord : TEXCOORD0}.
+ fragment shader as \c{varying highp vec2 qt_TexCoord0}.
\sa fragmentShader, GraphicsInfo
*/
@@ -824,17 +615,17 @@ bool QQuickShaderEffect::event(QEvent *e)
return QQuickItem::event(e);
}
-void QQuickShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickShaderEffect::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
#if QT_CONFIG(opengl)
if (m_glImpl) {
m_glImpl->handleGeometryChanged(newGeometry, oldGeometry);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
return;
}
#endif
m_impl->handleGeometryChanged(newGeometry, oldGeometry);
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
}
QSGNode *QQuickShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index c14907092c..b3d5473ae4 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -74,8 +74,9 @@ 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 4)
+ Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION(2, 4))
QML_NAMED_ELEMENT(ShaderEffect)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum CullMode {
@@ -135,7 +136,7 @@ Q_SIGNALS:
protected:
bool event(QEvent *e) override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index 710d37c275..4cd885a740 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -78,6 +78,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMesh : public QObject
Q_OBJECT
QML_NAMED_ELEMENT(ShaderEffectMesh)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Cannot create instance of abstract class ShaderEffectMesh.")
public:
@@ -102,6 +103,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGridMesh : public QQuickShaderEffectMesh
Q_OBJECT
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
QML_NAMED_ELEMENT(GridMesh)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickGridMesh(QObject *parent = nullptr);
bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override;
@@ -131,7 +133,7 @@ class QQuickBorderImageMesh : public QQuickShaderEffectMesh
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
QML_NAMED_ELEMENT(BorderImageMesh)
- QML_ADDED_IN_MINOR_VERSION(8)
+ QML_ADDED_IN_VERSION(2, 8)
public:
QQuickBorderImageMesh(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index c0a1ccab78..fe419e5959 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -87,9 +87,10 @@ 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 6)
- Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9)
+ Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION(2, 6))
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION(2, 9))
QML_NAMED_ELEMENT(ShaderEffectSource)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum WrapMode {
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index 98e5b82db8..328dc74f47 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -87,6 +87,7 @@ class Q_QUICK_EXPORT QQuickSprite : public QQuickStochasticState
Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration)
Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged)
QML_NAMED_ELEMENT(Sprite)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickSprite(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 8c52703938..3e4ed8707b 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -45,7 +45,7 @@
#include <QPainter>
#include <QRandomGenerator>
#include <QSet>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QOpenGLFunctions>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index 8361f7832a..39b536daae 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -75,6 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem
Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
Q_CLASSINFO("DefaultProperty", "sprites")
QML_NAMED_ELEMENT(SpriteSequence)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickSpriteSequence(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h
index d451dc6f77..5ba5400367 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -75,6 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public
Q_PROPERTY(QQmlScriptString scale READ scale WRITE setScale)
Q_PROPERTY(QQmlScriptString rotation READ rotation WRITE setRotation)
QML_NAMED_ELEMENT(ParentChange)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickParentChange(QObject *parent=nullptr);
~QQuickParentChange();
@@ -138,6 +139,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject
Q_PROPERTY(QQmlScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter)
Q_PROPERTY(QQmlScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnchorSet(QObject *parent=nullptr);
@@ -188,6 +190,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, publi
Q_PROPERTY(QQuickItem *target READ object WRITE setObject)
Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT)
QML_NAMED_ELEMENT(AnchorChanges)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickAnchorChanges(QObject *parent=nullptr);
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index c7882fb2b1..29b279c8ef 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -355,6 +355,144 @@
*/
/*!
+ \qmlproperty int QtQuick::TableView::leftColumn
+
+ This property holds the leftmost column that is currently visible inside the view.
+
+ \sa rightColumn, topRow, bottomRow
+*/
+
+/*!
+ \qmlproperty int QtQuick::TableView::rightColumn
+
+ This property holds the rightmost column that is currently visible inside the view.
+
+ \sa leftColumn, topRow, bottomRow
+*/
+
+/*!
+ \qmlproperty int QtQuick::TableView::topRow
+
+ This property holds the topmost row that is currently visible inside the view.
+
+ \sa leftColumn, rightColumn, bottomRow
+*/
+
+/*!
+ \qmlproperty int QtQuick::TableView::bottomRow
+
+ This property holds the bottom-most row that is currently visible inside the view.
+
+ \sa leftColumn, rightColumn, topRow
+*/
+
+/*!
+ \qmlmethod QtQuick::TableView::positionViewAtCell(point cell, Qt.Alignment alignment, point offset)
+
+ Positions \l contentX and \l contentY such that \a cell is at the position specified by
+ \a alignment. \a alignment can be an or-ed combination of the following:
+
+ \list
+ \li Qt.AlignLeft - position the cell at the left of the view.
+ \li Qt.AlignHCenter - position the cell at the horizontal center of the view.
+ \li Qt.AlignRight - position the cell at the right of the view.
+ \li Qt.AlignTop - position the cell at the top of the view.
+ \li Qt.AlignVCenter - position the cell at the vertical center of the view.
+ \li Qt.AlignBottom - position the cell at the bottom of the view.
+ \li Qt.AlignCenter - the same as (Qt.AlignHCenter | Qt.AlignVCenter)
+ \endlist
+
+ If no vertical alignment is specified, vertical positioning will be ignored.
+ The same is true for horizontal alignment.
+
+ Optionally, you can specify \a offset to move \l contentX and \l contentY an extra number of
+ pixels beyond the target alignment. E.g if you want to position the view so
+ that cell [10, 10] ends up at the top-left corner with a 5px margin, you could do:
+
+ \code
+ positionViewAtCell(Qt.point(10, 10), Qt.AlignLeft | Qt.AlignTop, Qt.point(-5, -5))
+ \endcode
+
+ \note it is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY}
+ to position the view at a particular cell. This is unreliable since removing items from
+ the start of the table does not cause all other items to be repositioned.
+ TableView can also sometimes place rows and columns at approximate positions to
+ optimize for speed. The only exception is if the cell is already visible in
+ the view, which can be checked upfront by calling \l itemAtCell().
+
+ Methods should only be called after the Component has completed. To position
+ the view at startup, this method should be called by Component.onCompleted. For
+ example, to position the view at the end:
+
+ \code
+ Component.onCompleted: positionViewAtCell(Qt.point(columns - 1, rows - 1), Qt.AlignRight | Qt.AlignBottom)
+ \endcode
+*/
+
+/*!
+ \qmlmethod QtQuick::TableView::positionViewAtCell(int column, int row, Qt.Alignment alignment, point offset)
+
+ Convenience for calling
+ \code
+ positionViewAtCell(Qt.point(column, row), alignment, offset)
+ \endcode
+*/
+
+/*!
+ \qmlmethod QtQuick::TableView::positionViewAtRow(int row, Qt.Alignment alignment, real offset)
+
+ Convenience for calling
+ \code
+ positionViewAtCell(Qt.point(0, row), alignment & Qt.AlignVertical_Mask, Qt.point(0, offset))
+ \endcode
+*/
+
+/*!
+ \qmlmethod QtQuick::TableView::positionViewAtColumn(int column, Qt.Alignment alignment, real offset)
+
+ Convenience for calling
+ \code
+ positionViewAtCell(Qt.point(column, 0), alignment & Qt.AlignHorizontal_Mask, Qt.point(offset, 0))
+ \endcode
+*/
+
+/*!
+ \qmlmethod Item QtQuick::TableView::itemAtCell(point cell)
+
+ Returns the delegate item at \a cell if loaded, otherwise \c null.
+
+ \note only the items that are visible in the view are normally loaded.
+ As soon as a cell is flicked out of the view, the item inside will
+ either be unloaded or placed in the recycle pool. As such, the return
+ value should never be stored.
+*/
+
+/*!
+ \qmlmethod Item QtQuick::TableView::itemAtCell(int column, int row)
+
+ Convenience for calling \code itemAtCell(Qt.point(column, row)) \endcode
+*/
+
+/*!
+ \qmlmethod Point QtQuick::TableView::cellAtPos(point position, bool includeSpacing)
+
+ Returns the cell at the given \a position in the view. If no cell intersects with
+ \a position, the return value will be \c point(-1, -1).
+
+ If \a includeSpacing is set to \c true, a cell's bounding box will be considered
+ to include half the adjacent \l rowSpacing and \l columnSpacing on each side. The
+ default value is \c false.
+
+ \sa columnSpacing, rowSpacing
+*/
+
+/*!
+ \qmlmethod Point QtQuick::TableView::cellAtPos(real x, real y, bool includeSpacing)
+
+ Convenience for calling \code cellAtPos(Qt.point(x, y), includeSpacing) \endcode
+*/
+
+/*!
\qmlattachedproperty TableView QtQuick::TableView::view
This attached property holds the view that manages the delegate instance.
@@ -550,10 +688,10 @@ int QQuickTableViewPrivate::nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge)
// visible, and should be loaded next if the content item moves.
int startIndex = -1;
switch (edge) {
- case Qt::LeftEdge: startIndex = loadedColumns.firstKey() - 1; break;
- case Qt::RightEdge: startIndex = loadedColumns.lastKey() + 1; break;
- case Qt::TopEdge: startIndex = loadedRows.firstKey() - 1; break;
- case Qt::BottomEdge: startIndex = loadedRows.lastKey() + 1; break;
+ case Qt::LeftEdge: startIndex = leftColumn() - 1; break;
+ case Qt::RightEdge: startIndex = rightColumn() + 1; break;
+ case Qt::TopEdge: startIndex = topRow() - 1; break;
+ case Qt::BottomEdge: startIndex = bottomRow() + 1; break;
}
return nextVisibleEdgeIndex(edge, startIndex);
@@ -913,6 +1051,18 @@ void QQuickTableViewPrivate::syncLoadedTableRectFromLoadedTable()
loadedTableInnerRect = QRectF(topLeftRect.bottomRight(), bottomRightRect.topLeft());
}
+void QQuickTableViewPrivate::shiftLoadedTableRect(const QPointF newPosition)
+{
+ // Move the tracked table rects to the new position. For this to
+ // take visual effect (move the delegate items to be inside the table
+ // rect), it needs to be followed by a relayoutTableItems().
+ // Also note that the position of the viewport needs to be adjusted
+ // separately for it to overlap the loaded table.
+ const QPointF innerDiff = loadedTableOuterRect.topLeft() - loadedTableInnerRect.topLeft();
+ loadedTableOuterRect.moveTopLeft(newPosition);
+ loadedTableInnerRect.moveTopLeft(newPosition + innerDiff);
+}
+
QQuickTableViewPrivate::RebuildOptions QQuickTableViewPrivate::checkForVisibilityChanges()
{
// Go through all columns from first to last, find the columns that used
@@ -988,6 +1138,8 @@ void QQuickTableViewPrivate::forceLayout()
void QQuickTableViewPrivate::syncLoadedTableFromLoadRequest()
{
+ Q_Q(QQuickTableView);
+
if (loadRequest.edge() == Qt::Edge(0)) {
// No edge means we're loading the top-left item
loadedColumns.insert(loadRequest.column(), 0);
@@ -997,12 +1149,24 @@ void QQuickTableViewPrivate::syncLoadedTableFromLoadRequest()
switch (loadRequest.edge()) {
case Qt::LeftEdge:
+ loadedColumns.insert(loadRequest.column(), 0);
+ if (rebuildState == RebuildState::Done)
+ emit q->leftColumnChanged();
+ break;
case Qt::RightEdge:
loadedColumns.insert(loadRequest.column(), 0);
+ if (rebuildState == RebuildState::Done)
+ emit q->rightColumnChanged();
break;
case Qt::TopEdge:
+ loadedRows.insert(loadRequest.row(), 0);
+ if (rebuildState == RebuildState::Done)
+ emit q->topRowChanged();
+ break;
case Qt::BottomEdge:
loadedRows.insert(loadRequest.row(), 0);
+ if (rebuildState == RebuildState::Done)
+ emit q->bottomRowChanged();
break;
}
}
@@ -1298,6 +1462,20 @@ qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
return columnWidth;
}
+qreal QQuickTableViewPrivate::getEffectiveRowHeight(int row) const
+{
+ // Return row height after layout
+ Q_TABLEVIEW_ASSERT(loadedRows.contains(row), row);
+ return loadedTableItem(QPoint(leftColumn(), row))->geometry().height();
+}
+
+qreal QQuickTableViewPrivate::getEffectiveColumnWidth(int column) const
+{
+ // Return column width after layout
+ Q_TABLEVIEW_ASSERT(loadedColumns.contains(column), column);
+ return loadedTableItem(QPoint(column, topRow()))->geometry().width();
+}
+
qreal QQuickTableViewPrivate::getRowLayoutHeight(int row)
{
// Return the row height specified by the application, or go
@@ -1522,31 +1700,44 @@ void QQuickTableViewPrivate::layoutHorizontalEdge(Qt::Edge tableEdge)
{
int rowThatNeedsLayout;
int neighbourRow;
- qreal rowY;
- qreal rowHeight;
if (tableEdge == Qt::TopEdge) {
rowThatNeedsLayout = topRow();
neighbourRow = loadedRows.keys().value(1);
- rowHeight = getRowLayoutHeight(rowThatNeedsLayout);
- const auto neighbourItem = loadedTableItem(QPoint(leftColumn(), neighbourRow));
- rowY = neighbourItem->geometry().top() - cellSpacing.height() - rowHeight;
} else {
rowThatNeedsLayout = bottomRow();
neighbourRow = loadedRows.keys().value(loadedRows.count() - 2);
- rowHeight = getRowLayoutHeight(rowThatNeedsLayout);
- const auto neighbourItem = loadedTableItem(QPoint(leftColumn(), neighbourRow));
- rowY = neighbourItem->geometry().bottom() + cellSpacing.height();
}
+ // Set the width first, since text items in QtQuick will calculate
+ // implicitHeight based on the text items width.
for (auto c = loadedColumns.cbegin(); c != loadedColumns.cend(); ++c) {
const int column = c.key();
auto fxTableItem = loadedTableItem(QPoint(column, rowThatNeedsLayout));
auto const neighbourItem = loadedTableItem(QPoint(column, neighbourRow));
const qreal columnX = neighbourItem->geometry().x();
const qreal columnWidth = neighbourItem->geometry().width();
+ fxTableItem->item->setX(columnX);
+ fxTableItem->item->setWidth(columnWidth);
+ }
- fxTableItem->setGeometry(QRectF(columnX, rowY, columnWidth, rowHeight));
+ qreal rowY;
+ qreal rowHeight;
+ if (tableEdge == Qt::TopEdge) {
+ rowHeight = getRowLayoutHeight(rowThatNeedsLayout);
+ const auto neighbourItem = loadedTableItem(QPoint(leftColumn(), neighbourRow));
+ rowY = neighbourItem->geometry().top() - cellSpacing.height() - rowHeight;
+ } else {
+ rowHeight = getRowLayoutHeight(rowThatNeedsLayout);
+ const auto neighbourItem = loadedTableItem(QPoint(leftColumn(), neighbourRow));
+ rowY = neighbourItem->geometry().bottom() + cellSpacing.height();
+ }
+
+ for (auto c = loadedColumns.cbegin(); c != loadedColumns.cend(); ++c) {
+ const int column = c.key();
+ auto fxTableItem = loadedTableItem(QPoint(column, rowThatNeedsLayout));
+ fxTableItem->item->setY(rowY);
+ fxTableItem->item->setHeight(rowHeight);
fxTableItem->setVisible(true);
qCDebug(lcTableViewDelegateLifecycle()) << "layout item:" << QPoint(column, rowThatNeedsLayout) << fxTableItem->geometry();
@@ -1618,7 +1809,9 @@ void QQuickTableViewPrivate::processLoadRequest()
loadRequest.markAsDone();
- qCDebug(lcTableViewDelegateLifecycle()) << "request completed! Table:" << tableLayoutToString();
+ qCDebug(lcTableViewDelegateLifecycle()) << "current table:" << tableLayoutToString();
+ qCDebug(lcTableViewDelegateLifecycle()) << "Load request completed!";
+ qCDebug(lcTableViewDelegateLifecycle()) << "****************************************";
}
void QQuickTableViewPrivate::processRebuildTable()
@@ -1637,12 +1830,15 @@ void QQuickTableViewPrivate::processRebuildTable()
else
Q_TABLEVIEW_UNREACHABLE(rebuildOptions);
}
+
+ edgesBeforeRebuild = loadedItems.isEmpty() ? QMargins()
+ : QMargins(q->leftColumn(), q->topRow(), q->rightColumn(), q->bottomRow());
}
moveToNextRebuildState();
if (rebuildState == RebuildState::LoadInitalTable) {
- beginRebuildTable();
+ loadInitialTable();
if (!moveToNextRebuildState())
return;
}
@@ -1694,8 +1890,23 @@ void QQuickTableViewPrivate::processRebuildTable()
return;
}
+ if (rebuildState == RebuildState::Done) {
+ if (edgesBeforeRebuild.left() != q->leftColumn())
+ emit q->leftColumnChanged();
+ if (edgesBeforeRebuild.right() != q->rightColumn())
+ emit q->rightColumnChanged();
+ if (edgesBeforeRebuild.top() != q->topRow())
+ emit q->topRowChanged();
+ if (edgesBeforeRebuild.bottom() != q->bottomRow())
+ emit q->bottomRowChanged();
+
+ qCDebug(lcTableViewDelegateLifecycle()) << "current table:" << tableLayoutToString();
+ qCDebug(lcTableViewDelegateLifecycle()) << "rebuild completed!";
+ qCDebug(lcTableViewDelegateLifecycle()) << "################################################";
+ qCDebug(lcTableViewDelegateLifecycle());
+ }
+
Q_TABLEVIEW_ASSERT(rebuildState == RebuildState::Done, int(rebuildState));
- qCDebug(lcTableViewDelegateLifecycle()) << "rebuild complete:" << q;
}
bool QQuickTableViewPrivate::moveToNextRebuildState()
@@ -1788,10 +1999,16 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL
const int newColumn = int(viewportRect.x() / (averageEdgeSize.width() + cellSpacing.width()));
topLeftCell.rx() = qBound(0, newColumn, tableSize.width() - 1);
topLeftPos.rx() = topLeftCell.x() * (averageEdgeSize.width() + cellSpacing.width());
+ } else if (rebuildOptions & RebuildOption::PositionViewAtColumn) {
+ topLeftCell.rx() = qBound(0, positionViewAtColumn, tableSize.width() - 1);
+ topLeftPos.rx() = qFloor(topLeftCell.x()) * (averageEdgeSize.width() + cellSpacing.width());
} else {
// Keep the current top left, unless it's outside model
topLeftCell.rx() = qBound(0, leftColumn(), tableSize.width() - 1);
- topLeftPos.rx() = loadedTableOuterRect.topLeft().x();
+ // We begin by loading the columns where the viewport is at
+ // now. But will move the whole table and the viewport
+ // later, when we do a layoutAfterLoadingInitialTable().
+ topLeftPos.rx() = loadedTableOuterRect.x();
}
}
@@ -1808,21 +2025,25 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL
const int newRow = int(viewportRect.y() / (averageEdgeSize.height() + cellSpacing.height()));
topLeftCell.ry() = qBound(0, newRow, tableSize.height() - 1);
topLeftPos.ry() = topLeftCell.y() * (averageEdgeSize.height() + cellSpacing.height());
+ } else if (rebuildOptions & RebuildOption::PositionViewAtRow) {
+ topLeftCell.ry() = qBound(0, positionViewAtRow, tableSize.height() - 1);
+ topLeftPos.ry() = qFloor(topLeftCell.y()) * (averageEdgeSize.height() + cellSpacing.height());
} else {
- // Keep the current top left, unless it's outside model
topLeftCell.ry() = qBound(0, topRow(), tableSize.height() - 1);
- topLeftPos.ry() = loadedTableOuterRect.topLeft().y();
+ topLeftPos.ry() = loadedTableOuterRect.y();
}
}
}
-void QQuickTableViewPrivate::beginRebuildTable()
+void QQuickTableViewPrivate::loadInitialTable()
{
updateTableSize();
QPoint topLeft;
QPointF topLeftPos;
calculateTopLeft(topLeft, topLeftPos);
+ qCDebug(lcTableViewDelegateLifecycle()) << "initial viewport rect:" << viewportRect;
+ qCDebug(lcTableViewDelegateLifecycle()) << "initial top left cell:" << topLeft << ", pos:" << topLeftPos;
if (!loadedItems.isEmpty()) {
if (rebuildOptions & RebuildOption::All)
@@ -1845,15 +2066,17 @@ void QQuickTableViewPrivate::beginRebuildTable()
loadedTableInnerRect = QRect();
clearEdgeSizeCache();
- if (syncHorizontally) {
+ if (syncHorizontally)
setLocalViewportX(syncView->contentX());
- viewportRect.moveLeft(syncView->d_func()->viewportRect.left());
- }
- if (syncVertically) {
+ if (syncVertically)
setLocalViewportY(syncView->contentY());
- viewportRect.moveTop(syncView->d_func()->viewportRect.top());
- }
+
+ if (!syncHorizontally && rebuildOptions & RebuildOption::PositionViewAtColumn)
+ setLocalViewportX(topLeftPos.x());
+
+ if (!syncVertically && rebuildOptions & RebuildOption::PositionViewAtRow)
+ setLocalViewportY(topLeftPos.y());
if (!model) {
qCDebug(lcTableViewDelegateLifecycle()) << "no model found, leaving table empty";
@@ -1911,28 +2134,117 @@ void QQuickTableViewPrivate::layoutAfterLoadingInitialTable()
}
updateExtents();
+ adjustViewportXAccordingToAlignment();
+ adjustViewportYAccordingToAlignment();
+}
+
+void QQuickTableViewPrivate::adjustViewportXAccordingToAlignment()
+{
+ // Check if we are supposed to position the viewport at a certain column
+ if (!rebuildOptions.testFlag(RebuildOption::PositionViewAtColumn))
+ return;
+ // The requested column might have been hidden or is outside model bounds
+ if (positionViewAtColumn != leftColumn())
+ return;
+
+ const float columnWidth = getEffectiveColumnWidth(positionViewAtColumn);
+
+ switch (positionViewAtColumnAlignment) {
+ case Qt::AlignLeft:
+ setLocalViewportX(loadedTableOuterRect.left() + positionViewAtColumnOffset);
+ break;
+ case Qt::AlignHCenter:
+ setLocalViewportX(loadedTableOuterRect.left()
+ - (viewportRect.width() / 2)
+ + (columnWidth / 2)
+ + positionViewAtColumnOffset);
+ break;
+ case Qt::AlignRight:
+ setLocalViewportX(loadedTableOuterRect.left()
+ - viewportRect.width()
+ + columnWidth
+ + positionViewAtColumnOffset);
+ break;
+ default:
+ Q_TABLEVIEW_UNREACHABLE("options are checked in setter");
+ break;
+ }
+}
+
+void QQuickTableViewPrivate::adjustViewportYAccordingToAlignment()
+{
+ // Check if we are supposed to position the viewport at a certain row
+ if (!rebuildOptions.testFlag(RebuildOption::PositionViewAtRow))
+ return;
+ // The requested row might have been hidden or is outside model bounds
+ if (positionViewAtRow != topRow())
+ return;
+
+ const float rowHeight = getEffectiveRowHeight(positionViewAtRow);
+
+ switch (positionViewAtRowAlignment) {
+ case Qt::AlignTop:
+ setLocalViewportY(loadedTableOuterRect.top() + positionViewAtRowOffset);
+ break;
+ case Qt::AlignVCenter:
+ setLocalViewportY(loadedTableOuterRect.top()
+ - (viewportRect.height() / 2)
+ + (rowHeight / 2)
+ + positionViewAtRowOffset);
+ break;
+ case Qt::AlignBottom:
+ setLocalViewportY(loadedTableOuterRect.top()
+ - viewportRect.height()
+ + rowHeight
+ + positionViewAtRowOffset);
+ break;
+ default:
+ Q_TABLEVIEW_UNREACHABLE("options are checked in setter");
+ break;
+ }
}
void QQuickTableViewPrivate::unloadEdge(Qt::Edge edge)
{
+ Q_Q(QQuickTableView);
qCDebug(lcTableViewDelegateLifecycle) << edge;
switch (edge) {
- case Qt::LeftEdge:
+ case Qt::LeftEdge: {
+ const int column = leftColumn();
+ for (auto r = loadedRows.cbegin(); r != loadedRows.cend(); ++r)
+ unloadItem(QPoint(column, r.key()));
+ loadedColumns.remove(column);
+ syncLoadedTableRectFromLoadedTable();
+ if (rebuildState == RebuildState::Done)
+ emit q->leftColumnChanged();
+ break; }
case Qt::RightEdge: {
- const int column = edge == Qt::LeftEdge ? leftColumn() : rightColumn();
+ const int column = rightColumn();
for (auto r = loadedRows.cbegin(); r != loadedRows.cend(); ++r)
unloadItem(QPoint(column, r.key()));
loadedColumns.remove(column);
syncLoadedTableRectFromLoadedTable();
+ if (rebuildState == RebuildState::Done)
+ emit q->rightColumnChanged();
+ break; }
+ case Qt::TopEdge: {
+ const int row = topRow();
+ for (auto c = loadedColumns.cbegin(); c != loadedColumns.cend(); ++c)
+ unloadItem(QPoint(c.key(), row));
+ loadedRows.remove(row);
+ syncLoadedTableRectFromLoadedTable();
+ if (rebuildState == RebuildState::Done)
+ emit q->topRowChanged();
break; }
- case Qt::TopEdge:
case Qt::BottomEdge: {
- const int row = edge == Qt::TopEdge ? topRow() : bottomRow();
+ const int row = bottomRow();
for (auto c = loadedColumns.cbegin(); c != loadedColumns.cend(); ++c)
unloadItem(QPoint(c.key(), row));
loadedRows.remove(row);
syncLoadedTableRectFromLoadedTable();
+ if (rebuildState == RebuildState::Done)
+ emit q->bottomRowChanged();
break; }
}
@@ -1944,7 +2256,7 @@ void QQuickTableViewPrivate::loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMo
const int edgeIndex = nextVisibleEdgeIndexAroundLoadedTable(edge);
qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex;
- const QList<int> visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge)
+ const auto visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge)
? loadedRows.keys() : loadedColumns.keys();
loadRequest.begin(edge, edgeIndex, visibleCells, incubationMode);
processLoadRequest();
@@ -2081,9 +2393,15 @@ bool QQuickTableViewPrivate::updateTableRecursive()
if (!updateComplete)
return false;
- for (auto syncChild : qAsConst(syncChildren)) {
+ const auto children = syncChildren;
+ for (auto syncChild : children) {
auto syncChild_d = syncChild->d_func();
- syncChild_d->scheduledRebuildOptions |= rebuildOptions;
+ const int mask =
+ RebuildOption::PositionViewAtRow |
+ RebuildOption::PositionViewAtColumn |
+ RebuildOption::CalculateNewTopLeftRow |
+ RebuildOption::CalculateNewTopLeftColumn;
+ syncChild_d->scheduledRebuildOptions |= rebuildOptions & ~mask;
const bool descendantUpdateComplete = syncChild_d->updateTableRecursive();
if (!descendantUpdateComplete)
@@ -2151,15 +2469,17 @@ void QQuickTableViewPrivate::fixup(QQuickFlickablePrivate::AxisData &data, qreal
QQuickFlickablePrivate::fixup(data, minExtent, maxExtent);
}
-int QQuickTableViewPrivate::resolveImportVersion()
+QTypeRevision QQuickTableViewPrivate::resolveImportVersion()
{
const auto data = QQmlData::get(q_func());
if (!data || !data->propertyCache)
- return 0;
+ return QTypeRevision::zero();
const auto cppMetaObject = data->propertyCache->firstCppMetaObject();
const auto qmlTypeView = QQmlMetaType::qmlType(cppMetaObject);
- return qmlTypeView.minorVersion();
+
+ // TODO: did we rather want qmlTypeView.revision() here?
+ return qmlTypeView.metaObjectRevision();
}
void QQuickTableViewPrivate::createWrapperModel()
@@ -2234,6 +2554,7 @@ void QQuickTableViewPrivate::syncWithPendingChanges()
syncModel();
syncDelegate();
syncSyncView();
+ syncPositionView();
syncRebuildOptions();
}
@@ -2257,6 +2578,12 @@ void QQuickTableViewPrivate::syncRebuildOptions()
} else if (rebuildOptions.testFlag(RebuildOption::ViewportOnly)) {
rebuildOptions.setFlag(RebuildOption::LayoutOnly, false);
}
+
+ if (rebuildOptions.testFlag(RebuildOption::PositionViewAtRow))
+ rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow, false);
+
+ if (rebuildOptions.testFlag(RebuildOption::PositionViewAtColumn))
+ rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn, false);
}
void QQuickTableViewPrivate::syncDelegate()
@@ -2373,6 +2700,16 @@ void QQuickTableViewPrivate::syncSyncView()
}
}
+void QQuickTableViewPrivate::syncPositionView()
+{
+ // Only positionViewAtRow/positionViewAtColumn are critical
+ // to sync before a rebuild to avoid them being overwritten
+ // by the setters while building. The other position properties
+ // can change without it causing trouble.
+ positionViewAtRow = assignedPositionViewAtRow;
+ positionViewAtColumn = assignedPositionViewAtColumn;
+}
+
void QQuickTableViewPrivate::connectToModel()
{
Q_Q(QQuickTableView);
@@ -2542,6 +2879,10 @@ void QQuickTableViewPrivate::setLocalViewportX(qreal contentX)
return;
q->setContentX(contentX);
+
+ // Keep our own viewportRect in sync
+ viewportRect.moveLeft(contentX);
+ qCDebug(lcTableViewDelegateLifecycle) << "viewportRect adjusted to:" << viewportRect;
}
void QQuickTableViewPrivate::setLocalViewportY(qreal contentY)
@@ -2556,6 +2897,10 @@ void QQuickTableViewPrivate::setLocalViewportY(qreal contentY)
return;
q->setContentY(contentY);
+
+ // Keep our own viewportRect in sync
+ viewportRect.moveTop(contentY);
+ qCDebug(lcTableViewDelegateLifecycle) << "viewportRect adjusted to:" << viewportRect;
}
void QQuickTableViewPrivate::syncViewportPosRecursive()
@@ -2640,7 +2985,7 @@ qreal QQuickTableView::rowSpacing() const
void QQuickTableView::setRowSpacing(qreal spacing)
{
Q_D(QQuickTableView);
- if (qt_is_nan(spacing) || !qt_is_finite(spacing) || spacing < 0)
+ if (qt_is_nan(spacing) || !qt_is_finite(spacing))
return;
if (qFuzzyCompare(d->cellSpacing.height(), spacing))
return;
@@ -2658,7 +3003,7 @@ qreal QQuickTableView::columnSpacing() const
void QQuickTableView::setColumnSpacing(qreal spacing)
{
Q_D(QQuickTableView);
- if (qt_is_nan(spacing) || !qt_is_finite(spacing) || spacing < 0)
+ if (qt_is_nan(spacing) || !qt_is_finite(spacing))
return;
if (qFuzzyCompare(d->cellSpacing.width(), spacing))
return;
@@ -2833,6 +3178,153 @@ void QQuickTableView::setSyncDirection(Qt::Orientations direction)
emit syncDirectionChanged();
}
+int QQuickTableView::leftColumn() const
+{
+ Q_D(const QQuickTableView);
+ return d->loadedItems.isEmpty() ? -1 : d_func()->leftColumn();
+}
+
+int QQuickTableView::rightColumn() const
+{
+ Q_D(const QQuickTableView);
+ return d->loadedItems.isEmpty() ? -1 : d_func()->rightColumn();
+}
+
+int QQuickTableView::topRow() const
+{
+ Q_D(const QQuickTableView);
+ return d->loadedItems.isEmpty() ? -1 : d_func()->topRow();
+}
+
+int QQuickTableView::bottomRow() const
+{
+ Q_D(const QQuickTableView);
+ return d->loadedItems.isEmpty() ? -1 : d_func()->bottomRow();
+}
+
+void QQuickTableView::positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset)
+{
+ Q_D(QQuickTableView);
+
+ Qt::Alignment verticalAlignment = alignment & (Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
+ Qt::Alignment horizontalAlignment = alignment & (Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
+
+ if (!verticalAlignment && !horizontalAlignment) {
+ qmlWarning(this) << "No valid alignment specified";
+ return;
+ }
+
+ if (horizontalAlignment) {
+ if (d->syncVertically) {
+ d->syncView->positionViewAtCell(QPoint(cell.x(), topRow()), horizontalAlignment, offset);
+ } else {
+ d->assignedPositionViewAtColumn = cell.x();
+ d->positionViewAtColumnAlignment = horizontalAlignment;
+ d->positionViewAtColumnOffset = offset.x();
+ d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::ViewportOnly |
+ QQuickTableViewPrivate::RebuildOption::PositionViewAtColumn);
+ }
+ }
+
+ if (verticalAlignment) {
+ if (d->syncHorizontally) {
+ d->syncView->positionViewAtCell(QPoint(leftColumn(), cell.y()), verticalAlignment, offset);
+ } else {
+ d->assignedPositionViewAtRow = cell.y();
+ d->positionViewAtRowAlignment = verticalAlignment;
+ d->positionViewAtRowOffset = offset.y();
+ d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::ViewportOnly |
+ QQuickTableViewPrivate::RebuildOption::PositionViewAtRow);
+ }
+ }
+}
+
+void QQuickTableView::positionViewAtCell(int column, int row, Qt::Alignment alignment, const QPointF &offset)
+{
+ positionViewAtCell(QPoint(column, row), alignment, offset);
+}
+
+void QQuickTableView::positionViewAtRow(int row, Qt::Alignment alignment, qreal offset)
+{
+ positionViewAtCell(QPoint(0, row), alignment & Qt::AlignVertical_Mask, QPointF(0, offset));
+}
+
+void QQuickTableView::positionViewAtColumn(int column, Qt::Alignment alignment, qreal offset)
+{
+ positionViewAtCell(QPoint(column, 0), alignment & Qt::AlignHorizontal_Mask, QPointF(offset, 0));
+}
+
+QQuickItem *QQuickTableView::itemAtCell(const QPoint &cell) const
+{
+ Q_D(const QQuickTableView);
+ const int modelIndex = d->modelIndexAtCell(cell);
+ if (!d->loadedItems.contains(modelIndex))
+ return nullptr;
+ return d->loadedItems.value(modelIndex)->item;
+}
+
+QQuickItem *QQuickTableView::itemAtCell(int column, int row) const
+{
+ return itemAtCell(QPoint(column, row));
+}
+
+QPoint QQuickTableView::cellAtPos(qreal x, qreal y, bool includeSpacing) const
+{
+ return cellAtPos(QPoint(x, y), includeSpacing);
+}
+
+QPoint QQuickTableView::cellAtPos(const QPointF &position, bool includeSpacing) const
+{
+ Q_D(const QQuickTableView);
+
+ if (!boundingRect().contains(position))
+ return QPoint(-1, -1);
+
+ const qreal hSpace = d->cellSpacing.width();
+ const qreal vSpace = d->cellSpacing.height();
+ qreal currentColumnEnd = d->loadedTableOuterRect.x() - contentX();
+ qreal currentRowEnd = d->loadedTableOuterRect.y() - contentY();
+ int foundColumn = -1;
+ int foundRow = -1;
+
+ for (auto columnPair : qAsConst(d->loadedColumns)) {
+ const int column = columnPair.first;
+ currentColumnEnd += d->getEffectiveColumnWidth(column);
+ if (position.x() < currentColumnEnd) {
+ foundColumn = column;
+ break;
+ }
+ currentColumnEnd += hSpace;
+ if (!includeSpacing && position.x() < currentColumnEnd) {
+ // Hit spacing
+ return QPoint(-1, -1);
+ } else if (includeSpacing && position.x() < currentColumnEnd - (hSpace / 2)) {
+ foundColumn = column;
+ break;
+ }
+ }
+
+ for (auto rowPair : qAsConst(d->loadedRows)) {
+ const int row = rowPair.first;
+ currentRowEnd += d->getEffectiveRowHeight(row);
+ if (position.y() < currentRowEnd) {
+ foundRow = row;
+ break;
+ }
+ currentRowEnd += vSpace;
+ if (!includeSpacing && position.y() < currentRowEnd) {
+ // Hit spacing
+ return QPoint(-1, -1);
+ }
+ if (includeSpacing && position.y() < currentRowEnd - (vSpace / 2)) {
+ foundRow = row;
+ break;
+ }
+ }
+
+ return QPoint(foundColumn, foundRow);
+}
+
void QQuickTableView::forceLayout()
{
d_func()->forceLayout();
@@ -2843,10 +3335,10 @@ QQuickTableViewAttached *QQuickTableView::qmlAttachedProperties(QObject *obj)
return new QQuickTableViewAttached(obj);
}
-void QQuickTableView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickTableView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickTableView);
- QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
+ QQuickFlickable::geometryChange(newGeometry, oldGeometry);
if (d->tableModel) {
// When the view changes size, we force the pool to
diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h
index d549aaddf7..64d202dc85 100644
--- a/src/quick/items/qquicktableview_p.h
+++ b/src/quick/items/qquicktableview_p.h
@@ -79,11 +79,15 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableView : public QQuickFlickable
Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged)
Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
- Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION 14)
- Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION 14)
+ Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION(2, 14))
+ Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION(2, 14))
+ Q_PROPERTY(int leftColumn READ leftColumn NOTIFY leftColumnChanged REVISION(6, 0))
+ Q_PROPERTY(int rightColumn READ rightColumn NOTIFY rightColumnChanged REVISION(6, 0))
+ Q_PROPERTY(int topRow READ topRow NOTIFY topRowChanged REVISION(6, 0))
+ Q_PROPERTY(int bottomRow READ bottomRow NOTIFY bottomRowChanged REVISION(6, 0))
QML_NAMED_ELEMENT(TableView)
- QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ADDED_IN_VERSION(2, 12)
QML_ATTACHED(QQuickTableViewAttached)
public:
@@ -122,7 +126,20 @@ public:
Qt::Orientations syncDirection() const;
void setSyncDirection(Qt::Orientations direction);
+ int leftColumn() const;
+ int rightColumn() const;
+ int topRow() const;
+ int bottomRow() const;
+
Q_INVOKABLE void forceLayout();
+ Q_INVOKABLE void positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset = QPointF());
+ Q_INVOKABLE void positionViewAtCell(int column, int row, Qt::Alignment alignment, const QPointF &offset = QPointF());
+ Q_INVOKABLE void positionViewAtRow(int row, Qt::Alignment alignment, qreal offset = 0);
+ Q_INVOKABLE void positionViewAtColumn(int column, Qt::Alignment alignment, qreal offset = 0);
+ Q_INVOKABLE QQuickItem *itemAtCell(const QPoint &cell) const;
+ Q_INVOKABLE QQuickItem *itemAtCell(int column, int row) const;
+ Q_INVOKABLE QPoint cellAtPos(const QPointF &position, bool includeSpacing = false) const;
+ Q_INVOKABLE QPoint cellAtPos(qreal x, qreal y, bool includeSpacing = false) const;
static QQuickTableViewAttached *qmlAttachedProperties(QObject *);
@@ -136,11 +153,15 @@ Q_SIGNALS:
void modelChanged();
void delegateChanged();
void reuseItemsChanged();
- Q_REVISION(14) void syncViewChanged();
- Q_REVISION(14) void syncDirectionChanged();
+ Q_REVISION(2, 14) void syncViewChanged();
+ Q_REVISION(2, 14) void syncDirectionChanged();
+ Q_REVISION(6, 0) void leftColumnChanged();
+ Q_REVISION(6, 0) void rightColumnChanged();
+ Q_REVISION(6, 0) void topRowChanged();
+ Q_REVISION(6, 0) void bottomRowChanged();
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void viewportMoved(Qt::Orientations orientation) override;
void componentComplete() override;
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index fe4cf82b46..876a175d87 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -54,6 +54,7 @@
#include "qquicktableview_p.h"
#include <QtCore/qtimer.h>
+#include <QtCore/private/qflatmap_p.h>
#include <QtQmlModels/private/qqmltableinstancemodel_p.h>
#include <QtQml/private/qqmlincubator_p.h>
#include <QtQmlModels/private/qqmlchangeset_p.h>
@@ -119,7 +120,7 @@ public:
qCDebug(lcTableViewDelegateLifecycle()) << "begin top-left:" << toString();
}
- void begin(Qt::Edge edgeToLoad, int edgeIndex, const QList<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode)
+ void begin(Qt::Edge edgeToLoad, int edgeIndex, const QVector<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode)
{
Q_ASSERT(!m_active);
m_active = true;
@@ -169,7 +170,7 @@ public:
private:
Qt::Edge m_edge = Qt::Edge(0);
- QList<int> m_visibleCellsInEdge;
+ QVector<int> m_visibleCellsInEdge;
int m_edgeIndex = 0;
int m_currentIndex = 0;
bool m_active = false;
@@ -207,11 +208,13 @@ public:
enum class RebuildOption {
None = 0,
- LayoutOnly = 0x1,
- ViewportOnly = 0x2,
- CalculateNewTopLeftRow = 0x4,
- CalculateNewTopLeftColumn = 0x8,
- All = 0x10,
+ All = 0x1,
+ LayoutOnly = 0x2,
+ ViewportOnly = 0x4,
+ CalculateNewTopLeftRow = 0x8,
+ CalculateNewTopLeftColumn = 0x10,
+ PositionViewAtRow = 0x20,
+ PositionViewAtColumn = 0x40,
};
Q_DECLARE_FLAGS(RebuildOptions, RebuildOption)
@@ -246,8 +249,8 @@ public:
// we need to fill up with more rows/columns. loadedTableInnerRect describes the pixels
// that the loaded table covers if you remove one row/column on each side of the table, and
// is used to determine rows/columns that are no longer visible and can be unloaded.
- QMap<int, int> loadedColumns;
- QMap<int, int> loadedRows;
+ QFlatMap<int, int> loadedColumns;
+ QFlatMap<int, int> loadedRows;
QRectF loadedTableOuterRect;
QRectF loadedTableInnerRect;
@@ -309,6 +312,17 @@ public:
QList<QPointer<QQuickTableView> > syncChildren;
Qt::Orientations assignedSyncDirection = Qt::Horizontal | Qt::Vertical;
+ int assignedPositionViewAtRow = 0;
+ int assignedPositionViewAtColumn = 0;
+ int positionViewAtRow = 0;
+ int positionViewAtColumn = 0;
+ qreal positionViewAtRowOffset = 0;
+ qreal positionViewAtColumnOffset = 0;
+ Qt::Alignment positionViewAtRowAlignment = Qt::AlignTop;
+ Qt::Alignment positionViewAtColumnAlignment = Qt::AlignLeft;
+
+ QMargins edgesBeforeRebuild;
+
const static QPoint kLeft;
const static QPoint kRight;
const static QPoint kUp;
@@ -336,11 +350,13 @@ public:
qreal getRowLayoutHeight(int row);
qreal getColumnWidth(int column);
qreal getRowHeight(int row);
+ qreal getEffectiveRowHeight(int row) const;
+ qreal getEffectiveColumnWidth(int column) const;
- inline int topRow() const { return loadedRows.firstKey(); }
- inline int bottomRow() const { return loadedRows.lastKey(); }
- inline int leftColumn() const { return loadedColumns.firstKey(); }
- inline int rightColumn() const { return loadedColumns.lastKey(); }
+ inline int topRow() const { return loadedRows.cbegin().key(); }
+ inline int bottomRow() const { return (--loadedRows.cend()).key(); }
+ inline int leftColumn() const { return loadedColumns.cbegin().key(); }
+ inline int rightColumn() const { return (--loadedColumns.cend()).key(); }
QQuickTableView *rootSyncView() const;
@@ -362,6 +378,7 @@ public:
void updateExtents();
void syncLoadedTableRectFromLoadedTable();
void syncLoadedTableFromLoadRequest();
+ void shiftLoadedTableRect(const QPointF newPosition);
int nextVisibleEdgeIndex(Qt::Edge edge, int startIndex);
int nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge);
@@ -393,12 +410,15 @@ public:
void processRebuildTable();
bool moveToNextRebuildState();
void calculateTopLeft(QPoint &topLeft, QPointF &topLeftPos);
- void beginRebuildTable();
+ void loadInitialTable();
+
void layoutAfterLoadingInitialTable();
+ void adjustViewportXAccordingToAlignment();
+ void adjustViewportYAccordingToAlignment();
void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options);
- int resolveImportVersion();
+ QTypeRevision resolveImportVersion();
void createWrapperModel();
void initItemCallback(int modelIndex, QObject *item);
@@ -412,8 +432,9 @@ public:
virtual QVariant modelImpl() const;
virtual void setModelImpl(const QVariant &newModel);
virtual void syncModel();
- inline void syncRebuildOptions();
virtual void syncSyncView();
+ virtual void syncPositionView();
+ inline void syncRebuildOptions();
void connectToModel();
void disconnectFromModel();
@@ -458,6 +479,8 @@ public:
QPoint cell;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickTableViewPrivate::RebuildOptions)
+
QT_END_NAMESPACE
#endif
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 90469ee82b..af8a0c476e 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1468,11 +1468,10 @@ QQuickText::~QQuickText()
*/
/*!
- \qmlproperty enumeration QtQuick::Text::font.weight
+ \qmlproperty int QtQuick::Text::font.weight
- Sets the font's weight.
-
- The weight can be one of:
+ The requested weight of the font. The weight requested must be an integer
+ between 0 and 99, or one of the predefined values:
\list
\li Font.Thin
\li Font.Light
@@ -2364,11 +2363,11 @@ QRectF QQuickText::clipRect() const
}
/*! \internal */
-void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickText::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickText);
if (d->text.isEmpty()) {
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
return;
}
@@ -2437,7 +2436,7 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
}
geomChangeDone:
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
}
void QQuickText::triggerPreprocess()
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 0fffc1fb9a..30e64f7185 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -90,17 +90,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(int minimumPointSize READ minimumPointSize WRITE setMinimumPointSize NOTIFY minimumPointSizeChanged)
Q_PROPERTY(FontSizeMode fontSizeMode READ fontSizeMode WRITE setFontSizeMode NOTIFY fontSizeModeChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
- Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
+ Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION(2, 2))
- Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
- Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
- Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
- Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
- Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6))
- Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9)
- Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10)
+ Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION(2, 9))
+ Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION(2, 10))
QML_NAMED_ELEMENT(Text)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickText(QQuickItem *parent=nullptr);
@@ -229,14 +230,14 @@ public:
Q_INVOKABLE void doLayout();
#endif
#endif
- Q_REVISION(9) Q_INVOKABLE void forceLayout();
+ Q_REVISION(2, 9) Q_INVOKABLE void forceLayout();
RenderType renderType() const;
void setRenderType(RenderType renderType);
QString hoveredLink() const;
- Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ Q_REVISION(2, 3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
qreal padding() const;
void setPadding(qreal padding);
@@ -264,7 +265,7 @@ public:
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
- Q_REVISION(2) void linkHovered(const QString &link);
+ Q_REVISION(2, 2) void linkHovered(const QString &link);
void fontChanged(const QFont &font);
void colorChanged();
void linkColorChanged();
@@ -279,7 +280,7 @@ Q_SIGNALS:
void textFormatChanged(QQuickText::TextFormat textFormat);
void elideModeChanged(QQuickText::TextElideMode mode);
void contentSizeChanged();
- // The next two signals should be marked as Q_REVISION(12). See QTBUG-71247
+ // The next two signals should be marked as Q_REVISION(2, 12). See QTBUG-71247
void contentWidthChanged(qreal contentWidth);
void contentHeightChanged(qreal contentHeight);
@@ -292,12 +293,12 @@ Q_SIGNALS:
void lineLaidOut(QQuickTextLine *line);
void baseUrlChanged();
void renderTypeChanged();
- Q_REVISION(6) void paddingChanged();
- Q_REVISION(6) void topPaddingChanged();
- Q_REVISION(6) void leftPaddingChanged();
- Q_REVISION(6) void rightPaddingChanged();
- Q_REVISION(6) void bottomPaddingChanged();
- Q_REVISION(9) void fontInfoChanged();
+ Q_REVISION(2, 6) void paddingChanged();
+ Q_REVISION(2, 6) void topPaddingChanged();
+ Q_REVISION(2, 6) void leftPaddingChanged();
+ Q_REVISION(2, 6) void rightPaddingChanged();
+ Q_REVISION(2, 6) void bottomPaddingChanged();
+ Q_REVISION(2, 9) void fontInfoChanged();
protected:
QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = nullptr);
@@ -305,8 +306,7 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
void updatePolish() override;
@@ -335,9 +335,10 @@ class QQuickTextLine : public QObject
Q_PROPERTY(qreal height READ height WRITE setHeight)
Q_PROPERTY(qreal x READ x WRITE setX)
Q_PROPERTY(qreal y READ y WRITE setY)
- Q_PROPERTY(qreal implicitWidth READ implicitWidth REVISION 15)
- Q_PROPERTY(bool isLast READ isLast REVISION 15)
+ Q_PROPERTY(qreal implicitWidth READ implicitWidth REVISION(2, 15))
+ Q_PROPERTY(bool isLast READ isLast REVISION(2, 15))
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTextLine();
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 4c741f67e3..cc6ecbf23a 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1883,7 +1883,7 @@ void QQuickTextEditMimeData::setup() const
{
QQuickTextEditMimeData *that = const_cast<QQuickTextEditMimeData *>(this);
#if QT_CONFIG(texthtmlparser)
- that->setData(QLatin1String("text/html"), fragment.toHtml("utf-8").toUtf8());
+ that->setData(QLatin1String("text/html"), fragment.toHtml().toUtf8());
#endif
#if QT_CONFIG(textodfwriter)
{
diff --git a/src/quick/items/qquicktextdocument.h b/src/quick/items/qquicktextdocument.h
index bf9162755c..aadc4ca8c0 100644
--- a/src/quick/items/qquicktextdocument.h
+++ b/src/quick/items/qquicktextdocument.h
@@ -50,6 +50,7 @@ class Q_QUICK_EXPORT QQuickTextDocument : public QObject
{
Q_OBJECT
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTextDocument(QQuickItem *parent);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 247d8abc3c..5494b73784 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -231,11 +231,10 @@ QString QQuickTextEdit::text() const
*/
/*!
- \qmlproperty enumeration QtQuick::TextEdit::font.weight
+ \qmlproperty int QtQuick::TextEdit::font.weight
- Sets the font's weight.
-
- The weight can be one of:
+ The requested weight of the font. The weight requested must be an integer
+ between 0 and 99, or one of the predefined values:
\list
\li Font.Thin
\li Font.Light
@@ -1444,8 +1443,7 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints)
#endif // im
}
-void QQuickTextEdit::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+void QQuickTextEdit::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickTextEdit);
if (!d->inLayout && ((newGeometry.width() != oldGeometry.width() && widthValid())
@@ -1454,7 +1452,7 @@ void QQuickTextEdit::geometryChanged(const QRectF &newGeometry,
updateWholeDocument();
moveCursorDelegate();
}
- QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickImplicitSizeItem::geometryChange(newGeometry, oldGeometry);
}
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 227d8cbf51..41245f904e 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -94,7 +94,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged)
Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged)
Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged)
- Q_PROPERTY(bool selectByKeyboard READ selectByKeyboard WRITE setSelectByKeyboard NOTIFY selectByKeyboardChanged REVISION 1)
+ Q_PROPERTY(bool selectByKeyboard READ selectByKeyboard WRITE setSelectByKeyboard NOTIFY selectByKeyboardChanged REVISION(2, 1))
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
@@ -103,16 +103,17 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
- Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION 1)
- Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
- Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
- Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
- Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
- Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
- Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
- Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
- Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10)
+ Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION(2, 1))
+ Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION(2, 2))
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION(2, 7))
+ Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION(2, 10))
QML_NAMED_ELEMENT(TextEdit)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTextEdit(QQuickItem *parent=nullptr);
@@ -162,7 +163,7 @@ public:
QString text() const;
void setText(const QString &);
- Q_REVISION(7) QString preeditText() const;
+ Q_REVISION(2, 7) QString preeditText() const;
TextFormat textFormat() const;
void setTextFormat(TextFormat format);
@@ -247,7 +248,7 @@ public:
#if QT_CONFIG(im)
QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
- Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
+ Q_REVISION(2, 4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
qreal contentWidth() const;
@@ -277,7 +278,7 @@ public:
QString hoveredLink() const;
- Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ Q_REVISION(2, 3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
qreal padding() const;
void setPadding(qreal padding);
@@ -304,7 +305,7 @@ public:
Q_SIGNALS:
void textChanged();
- Q_REVISION(7) void preeditTextChanged();
+ Q_REVISION(2, 7) void preeditTextChanged();
void contentSizeChanged();
void cursorPositionChanged();
void cursorRectangleChanged();
@@ -327,11 +328,11 @@ Q_SIGNALS:
void activeFocusOnPressChanged(bool activeFocusOnPressed);
void persistentSelectionChanged(bool isPersistentSelection);
void textMarginChanged(qreal textMargin);
- Q_REVISION(1) void selectByKeyboardChanged(bool selectByKeyboard);
+ Q_REVISION(2, 1) void selectByKeyboardChanged(bool selectByKeyboard);
void selectByMouseChanged(bool selectByMouse);
void mouseSelectionModeChanged(QQuickTextEdit::SelectionMode mode);
void linkActivated(const QString &link);
- Q_REVISION(2) void linkHovered(const QString &link);
+ Q_REVISION(2, 2) void linkHovered(const QString &link);
void canPasteChanged();
void canUndoChanged();
void canRedoChanged();
@@ -340,13 +341,13 @@ Q_SIGNALS:
void baseUrlChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
- Q_REVISION(6) void editingFinished();
- Q_REVISION(6) void paddingChanged();
- Q_REVISION(6) void topPaddingChanged();
- Q_REVISION(6) void leftPaddingChanged();
- Q_REVISION(6) void rightPaddingChanged();
- Q_REVISION(6) void bottomPaddingChanged();
- Q_REVISION(10) void tabStopDistanceChanged(qreal distance);
+ Q_REVISION(2, 6) void editingFinished();
+ Q_REVISION(2, 6) void paddingChanged();
+ Q_REVISION(2, 6) void topPaddingChanged();
+ Q_REVISION(2, 6) void leftPaddingChanged();
+ Q_REVISION(2, 6) void rightPaddingChanged();
+ Q_REVISION(2, 6) void bottomPaddingChanged();
+ Q_REVISION(2, 10) void tabStopDistanceChanged(qreal distance);
public Q_SLOTS:
void selectAll();
@@ -363,8 +364,8 @@ public Q_SLOTS:
void redo();
void insert(int position, const QString &text);
void remove(int start, int end);
- Q_REVISION(2) void append(const QString &text);
- Q_REVISION(7) void clear();
+ Q_REVISION(2, 2) void append(const QString &text);
+ Q_REVISION(2, 7) void clear();
private Q_SLOTS:
void q_textChanged();
@@ -390,8 +391,7 @@ private:
protected:
QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent = nullptr);
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
bool event(QEvent *) override;
void keyPressEvent(QKeyEvent *) override;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 06a9f134ac..39424d5f9d 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -255,11 +255,10 @@ QString QQuickTextInputPrivate::realText() const
*/
/*!
- \qmlproperty enumeration QtQuick::TextInput::font.weight
+ \qmlproperty int QtQuick::TextInput::font.weight
- Sets the font's weight.
-
- The weight can be one of:
+ The requested weight of the font. The weight requested must be an integer
+ between 0 and 99, or one of the predefined values:
\list
\li Font.Thin
\li Font.Light
@@ -1009,10 +1008,10 @@ void QQuickTextInput::setAutoScroll(bool b)
an acceptable or intermediate state. The accepted signal will only be sent
if the text is in an acceptable state when enter is pressed.
- Currently supported validators are IntValidator, DoubleValidator,
- RegExpValidator and RegularExpressionValidator. An example of using
- validators is shown below, which allows input of integers between 11 and 31
- into the text input:
+ Currently supported validators are IntValidator, DoubleValidator
+ and RegularExpressionValidator. An example of using validators is shown
+ below, which allows input of integers between 11 and 31 into the
+ text input:
\code
import QtQuick 2.0
@@ -1725,8 +1724,8 @@ bool QQuickTextInput::event(QEvent* ev)
return QQuickImplicitSizeItem::event(ev);
}
-void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry)
+void QQuickTextInput::geometryChange(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
{
Q_D(QQuickTextInput);
if (!d->inLayout) {
@@ -1736,7 +1735,7 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
d->updateBaselineOffset();
updateCursorRectangle();
}
- QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
+ QQuickImplicitSizeItem::geometryChange(newGeometry, oldGeometry);
}
void QQuickTextInputPrivate::ensureVisible(int position, int preeditCursor, int preeditLength)
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 9f7b82b168..ee06eb88e7 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -93,9 +93,9 @@ 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 4)
+ Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION(2, 4))
Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
- Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
+ Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION(2, 7))
Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
@@ -108,12 +108,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentSizeChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
- Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
- Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
- Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
- Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
- Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6))
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6))
QML_NAMED_ELEMENT(TextInput)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTextInput(QQuickItem * parent=nullptr);
@@ -242,7 +243,7 @@ public:
void resetPasswordMaskDelay();
QString displayText() const;
- Q_REVISION(7) QString preeditText() const;
+ Q_REVISION(2, 7) QString preeditText() const;
QQmlComponent* cursorDelegate() const;
void setCursorDelegate(QQmlComponent*);
@@ -269,7 +270,7 @@ public:
#if QT_CONFIG(im)
QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
- Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const;
+ Q_REVISION(2, 4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const;
#endif
QRectF boundingRect() const override;
@@ -319,8 +320,8 @@ Q_SIGNALS:
void selectedTextChanged();
void accepted();
void acceptableInputChanged();
- Q_REVISION(2) void editingFinished();
- Q_REVISION(9) void textEdited();
+ Q_REVISION(2, 2) void editingFinished();
+ Q_REVISION(2, 9) void textEdited();
void colorChanged();
void selectionColorChanged();
void selectedTextColorChanged();
@@ -337,9 +338,9 @@ Q_SIGNALS:
void inputMaskChanged(const QString &inputMask);
void echoModeChanged(QQuickTextInput::EchoMode echoMode);
void passwordCharacterChanged();
- Q_REVISION(4) void passwordMaskDelayChanged(int delay);
+ Q_REVISION(2, 4) void passwordMaskDelayChanged(int delay);
void displayTextChanged();
- Q_REVISION(7) void preeditTextChanged();
+ Q_REVISION(2, 7) void preeditTextChanged();
void activeFocusOnPressChanged(bool activeFocusOnPress);
void autoScrollChanged(bool autoScroll);
void selectByMouseChanged(bool selectByMouse);
@@ -353,11 +354,11 @@ Q_SIGNALS:
void contentSizeChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
- Q_REVISION(6) void paddingChanged();
- Q_REVISION(6) void topPaddingChanged();
- Q_REVISION(6) void leftPaddingChanged();
- Q_REVISION(6) void rightPaddingChanged();
- Q_REVISION(6) void bottomPaddingChanged();
+ Q_REVISION(2, 6) void paddingChanged();
+ Q_REVISION(2, 6) void topPaddingChanged();
+ Q_REVISION(2, 6) void leftPaddingChanged();
+ Q_REVISION(2, 6) void rightPaddingChanged();
+ Q_REVISION(2, 6) void bottomPaddingChanged();
private:
void invalidateFontCaches();
@@ -366,8 +367,7 @@ private:
protected:
QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = nullptr);
- void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
@@ -400,8 +400,8 @@ public Q_SLOTS:
void redo();
void insert(int position, const QString &text);
void remove(int start, int end);
- Q_REVISION(4) void ensureVisible(int position);
- Q_REVISION(7) void clear();
+ Q_REVISION(2, 4) void ensureVisible(int position);
+ Q_REVISION(2, 7) void clear();
private Q_SLOTS:
void selectionChanged();
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 2356ab36ef..ccdf2c9fa5 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -54,6 +54,7 @@
#include <private/qtextimagehandler_p.h>
#include <private/qrawfont_p.h>
#include <private/qglyphrun_p.h>
+#include <private/qquickitem_p.h>
QT_BEGIN_NAMESPACE
@@ -697,7 +698,7 @@ void QQuickTextNodeEngine::addFrameDecorations(QTextDocument *document, QTextFra
}
}
-uint qHash(const QQuickTextNodeEngine::BinaryTreeNodeKey &key)
+size_t qHash(const QQuickTextNodeEngine::BinaryTreeNodeKey &key)
{
// Just use the default hash for pairs
return qHash(qMakePair(key.fontEngine, qMakePair(key.clipNode,
diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp
index 872fe25a18..3bdcfa752e 100644
--- a/src/quick/items/qquicktranslate.cpp
+++ b/src/quick/items/qquicktranslate.cpp
@@ -434,14 +434,6 @@ void QQuickRotation::setAxis(Qt::Axis axis)
}
}
-class QGraphicsRotation {
-public:
- static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z)
- {
- matrix->projectedRotate(angle, x, y, z);
- }
-};
-
void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
{
Q_D(const QQuickRotation);
@@ -450,7 +442,7 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
return;
matrix->translate(d->origin);
- QGraphicsRotation::projectedRotate(matrix, d->angle, d->axis.x(), d->axis.y(), d->axis.z());
+ matrix->projectedRotate(d->angle, d->axis.x(), d->axis.y(), d->axis.z());
matrix->translate(-d->origin);
}
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index aeda6ca589..9832989e73 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform
Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
QML_NAMED_ELEMENT(Translate)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTranslate(QObject *parent = nullptr);
@@ -97,6 +98,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform
Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
QML_NAMED_ELEMENT(Scale)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickScale(QObject *parent = nullptr);
~QQuickScale();
@@ -135,6 +137,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
QML_NAMED_ELEMENT(Rotation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickRotation(QObject *parent = nullptr);
~QQuickRotation();
@@ -167,7 +170,7 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
QML_NAMED_ELEMENT(Matrix4x4)
- QML_ADDED_IN_MINOR_VERSION(3)
+ QML_ADDED_IN_VERSION(2, 3)
public:
QQuickMatrix4x4(QObject *parent = nullptr);
~QQuickMatrix4x4();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 48ba0ecc28..c53fd00e45 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -43,6 +43,7 @@
#include "qquickitem.h"
#include "qquickitem_p.h"
#include "qquickevents_p_p.h"
+#include "qquickgraphicsdevice_p.h"
#if QT_CONFIG(quick_draganddrop)
#include <private/qquickdrag_p.h>
@@ -72,14 +73,19 @@
#include <QtCore/QLibraryInfo>
#include <QtCore/QRunnable>
#include <QtQml/qqmlincubator.h>
+#include <QtQml/qqmlinfo.h>
+#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQuick/private/qquickpixmapcache_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qqmldebugconnector_p.h>
#if QT_CONFIG(opengl)
-# include <private/qopenglvertexarrayobject_p.h>
-# include <private/qsgdefaultrendercontext_p.h>
+#include <private/qopenglvertexarrayobject_p.h>
+#include <private/qsgdefaultrendercontext_p.h>
+#include <private/qopengl_p.h>
+#include <QOpenGLContext>
+#include <QOpenGLFramebufferObject>
#endif
#ifndef QT_NO_DEBUG_STREAM
#include <private/qdebug_p.h>
@@ -262,6 +268,15 @@ void QQuickWindow::hideEvent(QHideEvent *)
}
/*! \reimp */
+void QQuickWindow::closeEvent(QCloseEvent *e)
+{
+ QQuickCloseEvent qev;
+ qev.setAccepted(e->isAccepted());
+ emit closing(&qev);
+ e->setAccepted(qev.isAccepted());
+}
+
+/*! \reimp */
void QQuickWindow::focusOutEvent(QFocusEvent *ev)
{
Q_D(QQuickWindow);
@@ -298,6 +313,79 @@ static bool transformDirtyOnItemOrAncestor(const QQuickItem *item)
}
#endif
+/*!
+ * \internal
+
+ A "polish loop" can occur inside QQuickWindowPrivate::polishItems(). It is when an item calls
+ polish() on an(other?) item from updatePolish(). If this anomaly happens repeatedly and without
+ interruption (of a well-behaved updatePolish() that doesn't call polish()), it is a strong
+ indication that we are heading towards an infinite polish loop. A polish loop is not a bug in
+ Qt Quick - it is a bug caused by ill-behaved items put in the scene.
+
+ We can detect this sequence of polish loops easily, since the
+ QQuickWindowPrivate::itemsToPolish is basically a stack: polish() will push to it, and
+ polishItems() will pop from it.
+ Therefore if updatePolish() calls polish(), the immediate next item polishItems() processes is
+ the item that was polished by the previous call to updatePolish().
+ We therefore just need to count the number of polish loops we detected in _sequence_.
+*/
+struct PolishLoopDetector
+{
+ PolishLoopDetector(const QVector<QQuickItem*> &itemsToPolish)
+ : itemsToPolish(itemsToPolish)
+ {
+ }
+
+ /*
+ * returns true when it detected a likely infinite loop
+ * (suggests it should abort the polish loop)
+ **/
+ bool check(QQuickItem *item, int itemsRemainingBeforeUpdatePolish)
+ {
+ if (itemsToPolish.count() > itemsRemainingBeforeUpdatePolish) {
+ // Detected potential polish loop.
+ ++numPolishLoopsInSequence;
+ if (numPolishLoopsInSequence >= 1000) {
+ // Start to warn about polish loop after 1000 consecutive polish loops
+ if (numPolishLoopsInSequence == 100000) {
+ // We have looped 100,000 times without actually reducing the list of items to
+ // polish, give up for now.
+ // This is not a fix, just a remedy so that the application can be somewhat
+ // responsive.
+ numPolishLoopsInSequence = 0;
+ return true;
+ } else if (numPolishLoopsInSequence < 1005) {
+ // Show the 5 next items involved in the polish loop.
+ // (most likely they will be the same 5 items...)
+ QQuickItem *guiltyItem = itemsToPolish.last();
+ qmlWarning(item) << "possible QQuickItem::polish() loop";
+
+ auto typeAndObjectName = [](QQuickItem *item) {
+ QString typeName = QQmlMetaType::prettyTypeName(item);
+ QString objName = item->objectName();
+ if (!objName.isNull())
+ return QLatin1String("%1(%2)").arg(typeName, objName);
+ return typeName;
+ };
+
+ qmlWarning(guiltyItem) << typeAndObjectName(guiltyItem)
+ << " called polish() inside updatePolish() of " << typeAndObjectName(item);
+
+ if (numPolishLoopsInSequence == 1004)
+ // Enough warnings. Reset counter in order to speed things up and re-detect
+ // more loops
+ numPolishLoopsInSequence = 0;
+ }
+ }
+ } else {
+ numPolishLoopsInSequence = 0;
+ }
+ return false;
+ }
+ const QVector<QQuickItem*> &itemsToPolish; // Just a ref to the one in polishItems()
+ int numPolishLoopsInSequence = 0;
+};
+
void QQuickWindowPrivate::polishItems()
{
// An item can trigger polish on another item, or itself for that matter,
@@ -305,20 +393,21 @@ void QQuickWindowPrivate::polishItems()
// iterate through the set, we must continue pulling items out until it
// is empty.
// In the case where polish is called from updatePolish() either directly
- // or indirectly, we use a recursionSafeguard to print a warning to
- // the user.
- int recursionSafeguard = INT_MAX;
- while (!itemsToPolish.isEmpty() && --recursionSafeguard > 0) {
+ // or indirectly, we use a PolishLoopDetector to determine if a warning should
+ // be printed to the user.
+
+ PolishLoopDetector polishLoopDetector(itemsToPolish);
+ while (!itemsToPolish.isEmpty()) {
QQuickItem *item = itemsToPolish.takeLast();
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
itemPrivate->polishScheduled = false;
+ const int itemsRemaining = itemsToPolish.count();
itemPrivate->updatePolish();
item->updatePolish();
+ if (polishLoopDetector.check(item, itemsRemaining) == true)
+ break;
}
- if (recursionSafeguard == 0)
- qWarning("QQuickWindow: possible QQuickItem::polish() loop");
-
#if QT_CONFIG(im)
if (QQuickItem *focusItem = q_func()->activeFocusItem()) {
// If the current focus item, or any of its anchestors, has changed location
@@ -421,16 +510,69 @@ void forceUpdate(QQuickItem *item)
forceUpdate(items.at(i));
}
+void QQuickWindowRenderTarget::reset(QRhi *rhi, QSGRenderer *renderer)
+{
+ if (rhi && owns) {
+ if (renderer != nullptr && rpDesc != nullptr)
+ renderer->invalidatePipelineCacheDependency(rpDesc);
+
+ delete renderTarget;
+ delete rpDesc;
+ delete texture;
+ delete depthStencil;
+ }
+
+ renderTarget = nullptr;
+ rpDesc = nullptr;
+ texture = nullptr;
+ depthStencil = nullptr;
+ owns = false;
+}
+
+void QQuickWindowPrivate::ensureCustomRenderTarget()
+{
+ // resolve() can be expensive when importing an existing native texture, so
+ // it is important to only do it when the QQuickRenderTarget* was really changed
+ if (!redirect.renderTargetDirty || !rhi)
+ return;
+
+ redirect.renderTargetDirty = false;
+
+ redirect.rt.reset(rhi, renderer);
+
+ // a default constructed QQuickRenderTarget means no redirection
+ if (customRenderTarget.isNull())
+ return;
+
+ QQuickRenderTargetPrivate::get(&customRenderTarget)->resolve(rhi, &redirect.rt);
+}
+
+void QQuickWindowPrivate::setCustomCommandBuffer(QRhiCommandBuffer *cb)
+{
+ // ownership not transferred
+ redirect.commandBuffer = cb;
+}
+
void QQuickWindowPrivate::syncSceneGraph()
{
Q_Q(QQuickWindow);
+ ensureCustomRenderTarget();
+
// Calculate the dpr the same way renderSceneGraph() will.
qreal devicePixelRatio = q->effectiveDevicePixelRatio();
- if (renderTargetId && !QQuickRenderControl::renderWindowFor(q))
+ const bool hasCustomRenderTarget = customRenderTargetGl.renderTargetId || redirect.rt.renderTarget;
+ if (hasCustomRenderTarget && !QQuickRenderControl::renderWindowFor(q))
devicePixelRatio = 1;
- context->prepareSync(devicePixelRatio, rhi ? swapchain->currentFrameCommandBuffer() : nullptr);
+ QRhiCommandBuffer *cb = nullptr;
+ if (rhi) {
+ if (redirect.commandBuffer)
+ cb = redirect.commandBuffer;
+ else
+ cb = swapchain->currentFrameCommandBuffer();
+ }
+ context->prepareSync(devicePixelRatio, cb);
animationController->beforeNodeSync();
@@ -481,11 +623,32 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
return;
if (rhi) {
- // ### no offscreen ("renderTargetId") support yet
- context->beginNextRhiFrame(renderer,
- swapchain->currentFrameRenderTarget(),
- rpDescForSwapchain,
- swapchain->currentFrameCommandBuffer(),
+ ensureCustomRenderTarget();
+ QRhiRenderTarget *rt;
+ QRhiRenderPassDescriptor *rp;
+ QRhiCommandBuffer *cb;
+ if (redirect.rt.renderTarget) {
+ rt = redirect.rt.renderTarget;
+ rp = rt->renderPassDescriptor();
+ if (!rp) {
+ qWarning("Custom render target is set but no renderpass descriptor has been provided.");
+ return;
+ }
+ cb = redirect.commandBuffer;
+ if (!cb) {
+ qWarning("Custom render target is set but no command buffer has been provided.");
+ return;
+ }
+ } else {
+ if (!swapchain) {
+ qWarning("QQuickWindow: No render target (neither swapchain nor custom target was provided)");
+ return;
+ }
+ rt = swapchain->currentFrameRenderTarget();
+ rp = rpDescForSwapchain;
+ cb = swapchain->currentFrameCommandBuffer();
+ }
+ context->beginNextRhiFrame(renderer, rt, rp, cb,
emitBeforeRenderPassRecording,
emitAfterRenderPassRecording,
q);
@@ -500,18 +663,28 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
emit q->beforeRendering();
runAndClearJobs(&beforeRenderingJobs);
if (!customRenderStage || !customRenderStage->render()) {
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
+ const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
+ if (flipY)
+ matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
int fboId = 0;
const qreal devicePixelRatio = q->effectiveDevicePixelRatio();
- if (renderTargetId) {
- QRect rect(QPoint(0, 0), renderTargetSize);
- fboId = renderTargetId;
+ const bool hasCustomRenderTarget = customRenderTargetGl.renderTargetId || redirect.rt.renderTarget;
+ if (hasCustomRenderTarget) {
+ QRect rect;
+ if (redirect.rt.renderTarget) {
+ rect = QRect(QPoint(0, 0), redirect.rt.renderTarget->pixelSize());
+ } else {
+ fboId = customRenderTargetGl.renderTargetId;
+ rect = QRect(QPoint(0, 0), customRenderTargetGl.renderTargetSize);
+ }
renderer->setDeviceRect(rect);
renderer->setViewportRect(rect);
if (QQuickRenderControl::renderWindowFor(q)) {
- renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size));
+ renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size), matrixFlags);
renderer->setDevicePixelRatio(devicePixelRatio);
} else {
- renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size()));
+ renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size()), matrixFlags);
renderer->setDevicePixelRatio(1);
}
} else {
@@ -527,10 +700,6 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
QRect rect(QPoint(0, 0), pixelSize);
renderer->setDeviceRect(rect);
renderer->setViewportRect(rect);
- const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
- if (flipY)
- matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags);
renderer->setDevicePixelRatio(devicePixelRatio);
}
@@ -586,8 +755,6 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, allowChildEventFiltering(true)
, allowDoubleClick(true)
, lastFocusReason(Qt::OtherFocusReason)
- , renderTarget(nullptr)
- , renderTargetId(0)
, vaoHelper(nullptr)
, incubationController(nullptr)
, hasActiveSwapchain(false)
@@ -601,6 +768,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
QQuickWindowPrivate::~QQuickWindowPrivate()
{
+ redirect.rt.reset(rhi, renderer);
delete customRenderStage;
if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
service->removeWindow(q_func());
@@ -649,7 +817,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface);
q->setFormat(sg->defaultSurfaceFormat());
#if QT_CONFIG(vulkan)
- if (q->surfaceType() == QSurface::VulkanSurface)
+ if (!renderControl && q->surfaceType() == QSurface::VulkanSurface)
q->setVulkanInstance(QSGRhiSupport::vulkanInstance());
#endif
@@ -1528,8 +1696,9 @@ bool QQuickWindow::isPersistentOpenGLContext() const
/*!
- Sets whether the scene graph nodes and resources can be released
- to \a persistent. The default value is true.
+ Sets whether the scene graph nodes and resources are \a persistent.
+ Persistent means the nodes and resources cannot be released.
+ The default value is \c true.
The scene graph nodes and resources can be released to free up
graphics resources when the window is obscured, hidden or not
@@ -1728,14 +1897,6 @@ bool QQuickWindow::event(QEvent *e)
if (d->contentItem)
d->contentItem->windowDeactivateEvent();
break;
- case QEvent::Close: {
- // TOOD Qt 6 (binary incompatible)
- // closeEvent(static_cast<QCloseEvent *>(e));
- QQuickCloseEvent qev;
- qev.setAccepted(e->isAccepted());
- emit closing(&qev);
- e->setAccepted(qev.isAccepted());
- } break;
case QEvent::PlatformSurface:
if ((static_cast<QPlatformSurfaceEvent *>(e))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
// Ensure that the rendering thread is notified before
@@ -1770,6 +1931,25 @@ bool QQuickWindow::event(QEvent *e)
if (d->contentItem)
QCoreApplication::sendEvent(d->contentItem, e);
break;
+ case QEvent::InputMethod:
+ case QEvent::InputMethodQuery:
+ {
+ QQuickItem *target = d->activeFocusItem;
+ // while an input method delivers the event, this window might still be inactive
+ if (!target) {
+ target = d->contentItem;
+ if (!target || !target->isEnabled())
+ break;
+ // see setFocusInScope for a similar loop
+ while (target->isFocusScope() && target->scopedFocusItem() && target->scopedFocusItem()->isEnabled())
+ target = target->scopedFocusItem();
+ }
+ if (target) {
+ QCoreApplication::sendEvent(target, e);
+ return true;
+ }
+ }
+ break;
default:
break;
}
@@ -4025,13 +4205,13 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
return;
}
- d->renderTarget = fbo;
+ d->customRenderTargetGl.renderTarget = fbo;
if (fbo) {
- d->renderTargetId = fbo->handle();
- d->renderTargetSize = fbo->size();
+ d->customRenderTargetGl.renderTargetId = fbo->handle();
+ d->customRenderTargetGl.renderTargetSize = fbo->size();
} else {
- d->renderTargetId = 0;
- d->renderTargetSize = QSize();
+ d->customRenderTargetGl.renderTargetId = 0;
+ d->customRenderTargetGl.renderTargetSize = QSize();
}
}
#endif
@@ -4066,11 +4246,11 @@ void QQuickWindow::setRenderTarget(uint fboId, const QSize &size)
return;
}
- d->renderTargetId = fboId;
- d->renderTargetSize = size;
+ d->customRenderTargetGl.renderTargetId = fboId;
+ d->customRenderTargetGl.renderTargetSize = size;
// Unset any previously set instance...
- d->renderTarget = nullptr;
+ d->customRenderTargetGl.renderTarget = nullptr;
}
@@ -4080,7 +4260,7 @@ void QQuickWindow::setRenderTarget(uint fboId, const QSize &size)
uint QQuickWindow::renderTargetId() const
{
Q_D(const QQuickWindow);
- return d->renderTargetId;
+ return d->customRenderTargetGl.renderTargetId;
}
/*!
@@ -4089,11 +4269,9 @@ uint QQuickWindow::renderTargetId() const
QSize QQuickWindow::renderTargetSize() const
{
Q_D(const QQuickWindow);
- return d->renderTargetSize;
+ return d->customRenderTargetGl.renderTargetSize;
}
-
-
#if QT_CONFIG(opengl)
/*!
Returns the render target for this window.
@@ -4110,11 +4288,84 @@ QSize QQuickWindow::renderTargetSize() const
QOpenGLFramebufferObject *QQuickWindow::renderTarget() const
{
Q_D(const QQuickWindow);
- return d->renderTarget;
+ return d->customRenderTargetGl.renderTarget;
}
#endif
/*!
+ Sets the render target for this window to be \a target.
+
+ A QQuickRenderTarget serves as an opaque handle for a renderable native
+ object, most commonly a 2D texture, and associated metadata, such as the
+ size in pixels.
+
+ A default constructed QQuickRenderTarget means no redirection. A valid
+ \a target, created via one of the static QQuickRenderTarget factory functions,
+ on the other hand, enables redirection of the rendering of the Qt Quick
+ scene: it will no longer target the color buffers for the surface
+ associated with the window, but rather the textures or other graphics
+ objects specified in \a target.
+
+ For example, assuming the scenegraph is using Vulkan to render, one can
+ redirect its output into a \c VkImage. For graphics APIs like Vulkan, the
+ image layout must be provided as well. QQuickRenderTarget instances are
+ implicitly shared and are copyable and can be passed by value. They do not
+ own the associated native objects (such as, the VkImage in the example),
+ however.
+
+ \badcode
+ QQuickRenderTarget rt = QQuickRenderTarget::fromNativeTexture({ &vulkanImage, VK_IMAGE_LAYOUT_PREINITIALIZED }, pixelSize);
+ quickWindow->setRenderTarget(rt);
+ \endcode
+
+ This function is very often used in combination with QQuickRenderControl
+ and an invisible QQuickWindow, in order to render Qt Quick content into a
+ texture, without creating an on-screen native window for this QQuickWindow.
+
+ When the desired target, or associated data, such as the size, changes,
+ call this function with a new QQuickRenderTarget. Constructing
+ QQuickRenderTarget instances and calling this function is cheap, but be
+ aware that setting a new \a target with a different native object or other
+ data may lead to potentially expensive initialization steps when the
+ scenegraph is about to render the next frame. Therefore change the target
+ only when necessary.
+
+ \note This function should not be used when using the \c software backend.
+ Instead, use grabWindow() to render the content into a QImage.
+
+ \note The window does not take ownership of any native objects referenced
+ in \a target.
+
+ \note It is the caller's responsibility to ensure the native objects
+ referred to in \a target are valid for the scenegraph renderer too. For
+ instance, with Vulkan, Metal, and Direct3D this implies that the texture or
+ image is created on the same graphics device that is used by the scenegraph
+ internally. This is often achieved by using this function in combination
+ with setGraphicsDevice().
+
+ \note With graphics APIs where relevant, the application must pay attention
+ to image layout transitions performed by the scenegraph. For example, once
+ a VkImage is associated with the scenegraph by calling this function, its
+ layout will transition to \c VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when
+ rendering a frame.
+
+ \warning This function can only be called from the thread doing the
+ rendering.
+
+ \since 6.0
+
+ \sa QQuickRenderControl, setGraphicsDevice(), setSceneGraphBackend()
+ */
+void QQuickWindow::setRenderTarget(const QQuickRenderTarget &target)
+{
+ Q_D(QQuickWindow);
+ if (target != d->customRenderTarget) {
+ d->customRenderTarget = target;
+ d->redirect.renderTargetDirty = true;
+ }
+}
+
+/*!
Grabs the contents of the window and returns it as an image.
It is possible to call the grabWindow() function when the window is not
@@ -4122,6 +4373,14 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const
and has a valid size and that no other QQuickWindow instances are rendering
in the same process.
+ \note When using this window in combination with QQuickRenderControl, the
+ result of this function is an empty image, unless the \c software backend
+ is in use. This is because when redirecting the output to an
+ application-managed graphics resource (such as, a texture) by using
+ QQuickRenderControl and setRenderTarget(), the application is better suited
+ for managing and executing an eventual read back operation, since it is in
+ full control of the resource to begin with.
+
\warning Calling this function will cause performance problems.
\warning This function can only be called from the GUI thread.
@@ -4131,19 +4390,15 @@ QImage QQuickWindow::grabWindow()
Q_D(QQuickWindow);
if (!isVisible() && !d->renderControl) {
- // backends like software and d3d12 can grab regardless of the window state
+ // backends like software can grab regardless of the window state
if (d->windowManager && (d->windowManager->flags() & QSGRenderLoop::SupportsGrabWithoutExpose))
return d->windowManager->grab(this);
}
if (!isVisible() && !d->renderControl) {
if (d->rhi) {
- // ### we may need a full offscreen round when non-exposed...
-
- if (d->renderControl)
- return d->renderControl->grab();
- else if (d->windowManager)
- return d->windowManager->grab(this);
+ if (d->windowManager)
+ return d->windowManager->grab(this); // ### we may need a full offscreen round when non-exposed?
return QImage();
}
@@ -4181,7 +4436,7 @@ QImage QQuickWindow::grabWindow()
}
if (d->renderControl)
- return d->renderControl->grab();
+ return QQuickRenderControlPrivate::get(d->renderControl)->grab();
else if (d->windowManager)
return d->windowManager->grab(this);
return QImage();
@@ -4465,6 +4720,58 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \fn void QQuickWindow::beforeFrameBegin()
+
+ This signal is emitted before the scene graph starts preparing the frame.
+ This precedes signals like beforeSynchronizing() or beforeRendering(). It is
+ the earliest signal that is emitted by the scene graph rendering thread
+ when starting to prepare a new frame.
+
+ This signal is relevant for lower level graphics frameworks that need to
+ execute certain operations, such as resource cleanup, at a stage where Qt
+ Quick has not initiated the recording of a new frame via the underlying
+ rendering hardware interface APIs.
+
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
+
+ \since 6.0
+
+ \sa afterFrameEnd()
+*/
+
+/*!
+ \qmlsignal QtQuick.Window::Window::beforeFrameBegin()
+ \internal
+*/
+
+/*!
+ \fn void QQuickWindow::afterFrameEnd()
+
+ This signal is emitted when the scene graph has submitted a frame. This is
+ emitted after all other related signals, such as afterRendering(). It is
+ the last signal that is emitted by the scene graph rendering thread when
+ rendering a frame.
+
+ \note Unlike frameSwapped(), this signal is guaranteed to be emitted also
+ when the Qt Quick output is redirected via QQuickRenderControl.
+
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
+
+ \since 6.0
+
+ \sa beforeFrameBegin()
+*/
+
+/*!
+ \qmlsignal QtQuick.Window::Window::afterFrameEnd()
+ \internal
+*/
+
+/*!
\qmlsignal QtQuick.Window::Window::afterRenderPassRecording()
\internal
\since 5.14
@@ -5650,7 +5957,11 @@ QSGRendererInterface *QQuickWindow::rendererInterface() const
loaded plugins.
\note The call to the function must happen before constructing the first
- QQuickWindow in the application. It cannot be changed afterwards.
+ QQuickWindow in the application. The graphics API cannot be changed
+ afterwards. When used in combination with QQuickRenderControl, this rule is
+ relaxed: it is possible to change the graphics API, but only when all
+ existing QQuickRenderControl and QQuickWindow instances have been
+ destroyed.
If the selected backend is invalid or an error occurs, the default backend
(OpenGL or software, depending on the Qt configuration) is used.
@@ -5663,9 +5974,6 @@ void QQuickWindow::setSceneGraphBackend(QSGRendererInterface::GraphicsApi api)
case QSGRendererInterface::Software:
setSceneGraphBackend(QStringLiteral("software"));
break;
- case QSGRendererInterface::Direct3D12:
- setSceneGraphBackend(QStringLiteral("d3d12"));
- break;
default:
break;
}
@@ -5714,6 +6022,65 @@ QString QQuickWindow::sceneGraphBackend()
}
/*!
+ Sets the graphics device objects for this window. The scenegraph will use
+ existing device, physical device, and other objects specified by \a device
+ instead of creating new ones.
+
+ This function is very often used in combination with QQuickRenderControl
+ and setRenderTarget(), in order to redirect Qt Quick rendering into a
+ texture.
+
+ A default constructed QQuickGraphicsDevice does not change the default
+ behavior in any way. Once a \a device created via one of the
+ QQuickGraphicsDevice factory functions, such as,
+ QQuickGraphicsDevice::fromDeviceObjects(), is passed in, and the scenegraph
+ uses a matching graphics API (with the example of fromDeviceObjects(), that
+ would be Vulkan), the scenegraph will use the existing device objects (such
+ as, the \c VkPhysicalDevice, \c VkDevice, and graphics queue family index,
+ in case of Vulkan) encapsulated by the QQuickGraphicsDevice. This allows
+ using the same device, and so sharing resources, such as buffers and
+ textures, between Qt Quick and native rendering engines.
+
+ \warning This function can only be called before initializing the
+ scenegraph and will have no effect if called afterwards. In practice this
+ typically means calling it right before QQuickRenderControl::initialize().
+
+ As an example, this time with Direct3D, the typical usage is expected to be
+ the following:
+
+ \badcode
+ // native graphics resources set up by a custom D3D rendering engine
+ ID3D11Device *device;
+ ID3D11DeviceContext *context;
+ ID3D11Texture2D *texture;
+ ...
+ // now to redirect Qt Quick content into 'texture' we could do the following:
+ QQuickRenderControl *renderControl = new QQuickRenderControl;
+ QQuickWindow *window = new QQuickWindow(renderControl); // this window will never be shown on-screen
+ ...
+ window->setGraphicsDevice(QQuickGraphicsDevice::fromDeviceAndContext(device, context));
+ renderControl->initialize();
+ window->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ &texture, 0 }, textureSize);
+ ...
+ \endcode
+
+ The key aspect of using this function is to ensure that resources or
+ handles to resources, such as \c texture in the above example, are visible
+ to and usable by both the external rendering engine and the scenegraph
+ renderer. This requires using the same graphics device (or with OpenGL,
+ OpenGL context).
+
+ \since 6.0
+
+ \sa QQuickRenderControl, setRenderTarget(), setSceneGraphBackend()
+ */
+void QQuickWindow::setGraphicsDevice(const QQuickGraphicsDevice &device)
+{
+ Q_D(QQuickWindow);
+ d->customDeviceObjects = device;
+}
+
+/*!
Creates a simple rectangle node. When the scenegraph is not initialized, the return value is null.
This is cross-backend alternative to constructing a QSGSimpleRectNode directly.
@@ -5780,6 +6147,24 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType)
QQuickWindowPrivate::textRenderType = renderType;
}
+
+/*!
+ \since 6.0
+ \qmlproperty QQuickPalette Window::palette
+
+ This property holds the palette currently set for the window.
+
+ The default palette depends on the system environment. QGuiApplication maintains a system/theme
+ palette which serves as a default for all application windows. You can also set the default palette
+ for windows by passing a custom palette to QGuiApplication::setPalette(), before loading any QML.
+
+ ApplicationWindow propagates explicit palette properties to child controls. If you change a specific
+ property on the window's palette, that property propagates to all child controls in the window,
+ overriding any system defaults for that property.
+
+ \sa Item::palette, Popup::palette, QQuickAbstractPaletteProvider, QQuickColorGroup, QQuickPalette
+*/
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QQuickWindow *win)
{
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 097627374c..ea3f787d12 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -43,7 +43,7 @@
#include <QtQuick/qtquickglobal.h>
#include <QtQuick/qsgrendererinterface.h>
#include <QtCore/qmetatype.h>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QtGui/qwindow.h>
#include <QtGui/qevent.h>
#include <QtQml/qqml.h>
@@ -66,7 +66,8 @@ class QQuickRenderControl;
class QSGRectangleNode;
class QSGImageNode;
class QSGNinePatchNode;
-class QRhi;
+class QQuickRenderTarget;
+class QQuickGraphicsDevice;
class Q_QUICK_EXPORT QQuickWindow : public QWindow
{
@@ -74,7 +75,7 @@ class Q_QUICK_EXPORT QQuickWindow : public QWindow
Q_PRIVATE_PROPERTY(QQuickWindow::d_func(), QQmlListProperty<QObject> data READ data DESIGNABLE false)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT)
- Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged REVISION 1)
+ Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged REVISION(2, 1))
Q_CLASSINFO("DefaultProperty", "data")
Q_DECLARE_PRIVATE(QQuickWindow)
public:
@@ -131,6 +132,8 @@ public:
#endif
QImage grabWindow();
+
+ // ### Qt 6 remove all these 5 functions. Replaced by setRenderTarget(QQuickRenderTarget*).
#if QT_CONFIG(opengl)
void setRenderTarget(QOpenGLFramebufferObject *fbo);
QOpenGLFramebufferObject *renderTarget() const;
@@ -138,8 +141,11 @@ public:
void setRenderTarget(uint fboId, const QSize &size);
uint renderTargetId() const;
QSize renderTargetSize() const;
+
+ void setRenderTarget(const QQuickRenderTarget &target);
+
#if QT_CONFIG(opengl)
- void resetOpenGLState();
+ void resetOpenGLState(); // ### Qt 6 remove
#endif
struct GraphicsStateInfo {
int currentFrameSlot;
@@ -178,13 +184,14 @@ public:
static bool hasDefaultAlphaBuffer();
static void setDefaultAlphaBuffer(bool useAlpha);
- void setPersistentOpenGLContext(bool persistent);
+ void setPersistentOpenGLContext(bool persistent); // ### Qt 6 is this relevant / usable anymore?
bool isPersistentOpenGLContext() const;
- void setPersistentSceneGraph(bool persistent);
+ void setPersistentSceneGraph(bool persistent); // ### Qt 6 is this relevant / usable anymore?
bool isPersistentSceneGraph() const;
- QOpenGLContext *openglContext() const;
+ QOpenGLContext *openglContext() const; // ### Qt 6 consider if this is kept or not
+
bool isSceneGraphInitialized() const;
void scheduleRenderJob(QRunnable *job, RenderStage schedule);
@@ -197,6 +204,8 @@ public:
static void setSceneGraphBackend(const QString &backend);
static QString sceneGraphBackend();
+ void setGraphicsDevice(const QQuickGraphicsDevice &device);
+
QSGRectangleNode *createRectangleNode() const;
QSGImageNode *createImageNode() const;
QSGNinePatchNode *createNinePatchNode() const;
@@ -206,23 +215,29 @@ public:
Q_SIGNALS:
void frameSwapped();
- Q_REVISION(2) void openglContextCreated(QOpenGLContext *context);
+ Q_REVISION(2, 2) void openglContextCreated(QOpenGLContext *context); // ### Qt 6 remove
void sceneGraphInitialized();
void sceneGraphInvalidated();
void beforeSynchronizing();
- Q_REVISION(2) void afterSynchronizing();
+ Q_REVISION(2, 2) void afterSynchronizing();
void beforeRendering();
void afterRendering();
- Q_REVISION(2) void afterAnimating();
- Q_REVISION(2) void sceneGraphAboutToStop();
+ Q_REVISION(2, 2) void afterAnimating();
+ Q_REVISION(2, 2) void sceneGraphAboutToStop();
- Q_REVISION(1) void closing(QQuickCloseEvent *close);
+ Q_REVISION(2, 1) void closing(QQuickCloseEvent *close);
void colorChanged(const QColor &);
- Q_REVISION(1) void activeFocusItemChanged();
- Q_REVISION(2) void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
+ Q_REVISION(2, 1) void activeFocusItemChanged();
+ Q_REVISION(2, 2) void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
+
+ Q_REVISION(2, 14) void beforeRenderPassRecording();
+ Q_REVISION(2, 14) void afterRenderPassRecording();
+
+ Q_REVISION(6, 0) void paletteChanged();
+ Q_REVISION(6, 0) void paletteCreated();
- Q_REVISION(14) void beforeRenderPassRecording();
- Q_REVISION(14) void afterRenderPassRecording();
+ Q_REVISION(6, 0) void beforeFrameBegin();
+ Q_REVISION(6, 0) void afterFrameEnd();
public Q_SLOTS:
void update();
@@ -237,7 +252,7 @@ protected:
void showEvent(QShowEvent *) override;
void hideEvent(QHideEvent *) override;
- // TODO Qt 6: reimplement QWindow::closeEvent to emit closing
+ void closeEvent(QCloseEvent *) override;
void focusInEvent(QFocusEvent *) override;
void focusOutEvent(QFocusEvent *) override;
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index e1ee7daf1c..3d629cd74f 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -56,15 +56,15 @@
#include "qquickevents_p_p.h"
#include <QtQuick/private/qsgcontext_p.h>
+#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h>
+#include <QtQuick/private/qquickrendertarget_p.h>
+#include <QtQuick/private/qquickgraphicsdevice_p.h>
#include <QtCore/qthread.h>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/qrunnable.h>
#include <private/qwindow_p.h>
-#include <private/qopengl_p.h>
-#include <qopenglcontext.h>
-#include <QtGui/qopenglframebufferobject.h>
#include <QtGui/qevent.h>
#include <QtGui/qstylehints.h>
#include <QtGui/qguiapplication.h>
@@ -86,6 +86,7 @@ class QRhi;
class QRhiSwapChain;
class QRhiRenderBuffer;
class QRhiRenderPassDescriptor;
+class QRhiTexture;
//Make it easy to identify and customize the root item if needed
class Q_QUICK_PRIVATE_EXPORT QQuickRootItem : public QQuickItem
@@ -106,7 +107,20 @@ public:
virtual bool swap() = 0;
};
-class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate : public QWindowPrivate
+class QQuickWindowRenderTarget
+{
+public:
+ void reset(QRhi *rhi, QSGRenderer *renderer);
+ QRhiRenderTarget *renderTarget = nullptr;
+ QRhiRenderPassDescriptor *rpDesc = nullptr;
+ QRhiTexture *texture = nullptr;
+ QRhiRenderBuffer *depthStencil = nullptr;
+ bool owns = false;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate
+ : public QWindowPrivate
+ , public QQuickPaletteProviderPrivateBase<QQuickWindow, QQuickWindowPrivate>
{
public:
Q_DECLARE_PUBLIC(QQuickWindow)
@@ -218,6 +232,9 @@ public:
void dirtyItem(QQuickItem *);
void cleanup(QSGNode *);
+ void ensureCustomRenderTarget();
+ void setCustomCommandBuffer(QRhiCommandBuffer *cb);
+
void polishItems();
void forcePolish();
void syncSceneGraph();
@@ -277,11 +294,26 @@ public:
Qt::FocusReason lastFocusReason;
- QOpenGLFramebufferObject *renderTarget;
- uint renderTargetId;
- QSize renderTargetSize;
+ // Storage for setRenderTarget(QQuickRenderTarget).
+ // Gets baked into redirect.renderTarget by ensureCustomRenderTarget() when rendering the next frame.
+ QQuickRenderTarget customRenderTarget;
+
+ struct Redirect {
+ QRhiCommandBuffer *commandBuffer = nullptr;
+ QQuickWindowRenderTarget rt;
+ bool renderTargetDirty = false;
+ } redirect;
+
+ QQuickGraphicsDevice customDeviceObjects;
+
+ // ### Qt 6 remove
+ struct {
+ QOpenGLFramebufferObject *renderTarget = nullptr;
+ uint renderTargetId = 0;
+ QSize renderTargetSize;
+ } customRenderTargetGl;
- QOpenGLVertexArrayObjectHelper *vaoHelper;
+ QOpenGLVertexArrayObjectHelper *vaoHelper; // ### Qt 6 remove
mutable QQuickWindowIncubationController *incubationController;
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index ad0aa53f72..7d7cf20210 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -42,6 +42,8 @@
#include "qquickrendercontrol.h"
#include "qquickscreen_p.h"
#include "qquickview_p.h"
+#include "qquickwindowmodule_p_p.h"
+#include "qquickitem_p.h"
#include <QtQuick/QQuickWindow>
#include <QtCore/QCoreApplication>
#include <QtQml/QQmlEngine>
@@ -56,28 +58,11 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcTransient)
-class QQuickWindowQmlImplPrivate : public QQuickWindowPrivate
-{
-public:
- QQuickWindowQmlImplPrivate()
- : complete(false)
- , visible(false)
- , visibility(QQuickWindow::AutomaticVisibility)
- {
- }
-
- bool complete;
- bool visible;
- QQuickWindow::Visibility visibility;
- QV4::PersistentValue rootItemMarker;
-};
+QQuickWindowQmlImplPrivate::QQuickWindowQmlImplPrivate() = default;
QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent)
- : QQuickWindow(*(new QQuickWindowQmlImplPrivate), parent)
+ : QQuickWindowQmlImpl(*(new QQuickWindowQmlImplPrivate), parent)
{
- connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged);
- connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged);
- connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged);
}
void QQuickWindowQmlImpl::setVisible(bool visible)
@@ -140,6 +125,14 @@ void QQuickWindowQmlImpl::componentComplete()
}
}
+QQuickWindowQmlImpl::QQuickWindowQmlImpl(QQuickWindowQmlImplPrivate &dd, QWindow *parent)
+ : QQuickWindow(dd, parent)
+{
+ connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged);
+ connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged);
+ connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged);
+}
+
void QQuickWindowQmlImpl::setWindowVisibility()
{
Q_D(QQuickWindowQmlImpl);
@@ -162,9 +155,9 @@ void QQuickWindowQmlImpl::setWindowVisibility()
QQmlError error;
error.setObject(this);
- const QQmlContextData* urlContext = data->context;
+ QQmlRefPointer<QQmlContextData> urlContext = data->context;
while (urlContext && urlContext->url().isEmpty())
- urlContext = urlContext->parent;
+ urlContext = urlContext->parent();
error.setUrl(urlContext ? urlContext->url() : QUrl());
QString objectId = data->context->findObjectId(this);
@@ -175,7 +168,7 @@ void QQuickWindowQmlImpl::setWindowVisibility()
error.setDescription(QCoreApplication::translate("QQuickWindowQmlImpl",
"Conflicting properties 'visible' and 'visibility'"));
- QQmlEnginePrivate::get(data->context->engine)->warning(error);
+ QQmlEnginePrivate::get(data->context->engine())->warning(error);
}
if (d->visibility == AutomaticVisibility) {
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index d4925cb1d5..87f0b240b8 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 3)
+ Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION(2, 3))
QML_ATTACHED(QQuickWindowAttached)
public:
@@ -84,12 +84,14 @@ public:
Q_SIGNALS:
void visibleChanged(bool arg);
void visibilityChanged(QWindow::Visibility visibility);
- Q_REVISION(3) void screenChanged();
+ Q_REVISION(2, 3) void screenChanged();
protected:
void classBegin() override;
void componentComplete() override;
+ QQuickWindowQmlImpl(QQuickWindowQmlImplPrivate &dd, QWindow *parent);
+
private Q_SLOTS:
void setWindowVisibility();
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h b/src/quick/items/qquickwindowmodule_p_p.h
index d04a8e8777..4e94a4e43d 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h
+++ b/src/quick/items/qquickwindowmodule_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -36,9 +36,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#ifndef QSGD3D12GLYPHNODE_P_H
-#define QSGD3D12GLYPHNODE_P_H
+#ifndef QQUICKWINDOWMODULE_P_P_H
+#define QQUICKWINDOWMODULE_P_P_H
//
// W A R N I N G
@@ -51,24 +50,22 @@
// We mean it.
//
-#include <private/qsgbasicglyphnode_p.h>
+#include "qquickwindow_p.h"
+#include <QtQml/private/qv4persistent_p.h>
QT_BEGIN_NAMESPACE
-class QSGD3D12RenderContext;
-
-class QSGD3D12GlyphNode : public QSGBasicGlyphNode
+class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImplPrivate : public QQuickWindowPrivate
{
public:
- QSGD3D12GlyphNode(QSGD3D12RenderContext *rc) : m_rc(rc) { }
-
- void setMaterialColor(const QColor &color) override;
- void update() override;
+ QQuickWindowQmlImplPrivate();
-private:
- QSGD3D12RenderContext *m_rc;
+ bool complete = false;
+ bool visible = false;
+ QQuickWindow::Visibility visibility = QQuickWindow::AutomaticVisibility;
+ QV4::PersistentValue rootItemMarker;
};
QT_END_NAMESPACE
-#endif // QSGD3D12GLYPHNODE_P_H
+#endif // QQUICKWINDOWMODULE_P_P_H
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index f2d49cf939..77517a45e0 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -3,6 +3,10 @@ TARGET = QtQuick
QT = core-private gui-private qml-private qmlmodels-private
qtConfig(qml-network): \
QT_PRIVATE += network
+qtConfig(opengl) {
+ QT_PRIVATE += opengl-private
+ QT += opengl
+}
TRACEPOINT_PROVIDER = $$PWD/qtquick.tracepoints
CONFIG += qt_tracepoints
@@ -49,7 +53,7 @@ INCLUDEPATH += $$PWD
load(qt_module)
QMLTYPES_FILENAME = plugins.qmltypes
-QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick.2
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick
QML_IMPORT_NAME = QtQuick
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index ca620965a8..49151551b1 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -77,6 +77,12 @@ QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode *
return m_nodes.value(node, nullptr);
}
+// Used by GammaRay
+const QVector<QSGSoftwareRenderableNode*> &QSGAbstractSoftwareRenderer::renderableNodes() const
+{
+ return m_renderableNodes;
+}
+
void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode)
{
m_nodes.insert(node, renderableNode);
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index e1b477ab97..d4bfb5a9f7 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -87,6 +87,7 @@ protected:
QRect backgroundRect();
// only known after calling optimizeRenderList()
bool isOpaque() const { return m_isOpaque; }
+ const QVector<QSGSoftwareRenderableNode*> &renderableNodes() const;
private:
void nodeAdded(QSGNode *node);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index f1d0e28fc8..91c26780b1 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -56,6 +56,7 @@
#include <QtGui/QWindow>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickitem_p.h>
// Used for very high-level info about the renderering and gl context
// Includes GL_VERSION, type of render loop, atlas size, etc.
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
index 683ccb60c2..ffeb55c7ef 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE
QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext)
- : QSGLayer(*(new QSGSoftwareLayerPrivate))
+ : QSGLayer(*(new QSGTexturePrivate))
, m_item(nullptr)
, m_context(renderContext)
, m_renderer(nullptr)
@@ -70,7 +70,7 @@ int QSGSoftwareLayer::textureId() const
return 0;
}
-int QSGSoftwareLayerPrivate::comparisonKey() const
+int QSGSoftwareLayer::comparisonKey() const
{
return 0;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
index 1859e14514..4961c91c1c 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
@@ -58,11 +58,9 @@
QT_BEGIN_NAMESPACE
class QSGSoftwarePixmapRenderer;
-class QSGSoftwareLayerPrivate;
class QSGSoftwareLayer : public QSGLayer
{
- Q_DECLARE_PRIVATE(QSGSoftwareLayer)
Q_OBJECT
public:
QSGSoftwareLayer(QSGRenderContext *renderContext);
@@ -72,6 +70,7 @@ public:
// QSGTexture interface
public:
+ int comparisonKey() const override;
int textureId() const override;
QSize textureSize() const override;
bool hasAlphaChannel() const override;
@@ -120,13 +119,6 @@ private:
bool m_dirtyTexture;
};
-class QSGSoftwareLayerPrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGSoftwareLayer)
-public:
- int comparisonKey() const override;
-};
-
QT_END_NAMESPACE
#endif // QSGSOFTWARELAYER_H
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp
index 82a48d80ca..7a3be61cc0 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp
@@ -43,7 +43,6 @@
QT_BEGIN_NAMESPACE
QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image, uint flags)
- : QSGTexture(*(new QSGSoftwarePixmapTexturePrivate))
{
// Prevent pixmap format conversion to reduce memory consumption
// and surprises in calling code. (See QTBUG-47328)
@@ -57,8 +56,7 @@ QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image, uint fla
}
QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QPixmap &pixmap)
- : QSGTexture(*(new QSGSoftwarePixmapTexturePrivate)),
- m_pixmap(pixmap)
+ : m_pixmap(pixmap)
{
}
@@ -87,7 +85,7 @@ void QSGSoftwarePixmapTexture::bind()
Q_UNREACHABLE();
}
-int QSGSoftwarePixmapTexturePrivate::comparisonKey() const
+int QSGSoftwarePixmapTexture::comparisonKey() const
{
return 0;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h
index baa62d93de..dda1358124 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h
@@ -56,16 +56,15 @@
QT_BEGIN_NAMESPACE
-class QSGSoftwarePixmapTexturePrivate;
-
class QSGSoftwarePixmapTexture : public QSGTexture
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QSGSoftwarePixmapTexture)
+
public:
QSGSoftwarePixmapTexture(const QImage &image, uint flags);
QSGSoftwarePixmapTexture(const QPixmap &pixmap);
+ int comparisonKey() const override;
int textureId() const override;
QSize textureSize() const override;
bool hasAlphaChannel() const override;
@@ -78,13 +77,6 @@ private:
QPixmap m_pixmap;
};
-class QSGSoftwarePixmapTexturePrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGSoftwarePixmapTexture)
-public:
- int comparisonKey() const override;
-};
-
QT_END_NAMESPACE
#endif // QSGSOFTWAREPIXMAPTEXTURE_H
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
index 114137fb55..470bb73f78 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h
@@ -97,6 +97,9 @@ public:
void setMipmapFiltering(QSGTexture::Filtering) override { }
QSGTexture::Filtering mipmapFiltering() const override { return QSGTexture::None; }
+ void setAnisotropyLevel(QSGTexture::AnisotropyLevel) override { }
+ QSGTexture::AnisotropyLevel anisotropyLevel() const override { return QSGTexture::AnisotropyNone; }
+
void setTextureCoordinatesTransform(TextureCoordinatesTransformMode transformNode) override;
TextureCoordinatesTransformMode textureCoordinatesTransform() const override { return m_transformMode; }
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index c010e0cae5..ad1f9cacf4 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QCoreApplication>
#include <private/qquickwindow_p.h>
+#include <private/qquickitem_p.h>
#include <QElapsedTimer>
#include <private/qquickanimatorcontroller_p.h>
#include <private/qquickprofiler_p.h>
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index f07cc28827..7075d3e1cb 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -43,6 +43,7 @@
#include <private/qsgrenderer_p.h>
#include <private/qquickwindow_p.h>
+#include <private/qquickitem_p.h>
#include <private/qquickprofiler_p.h>
#include <private/qquickanimatorcontroller_p.h>
#include <private/qquickprofiler_p.h>
@@ -423,7 +424,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - sync");
mutex.lock();
- Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked");
+ Q_ASSERT_X(renderLoop->lockedForSync, "QSGSoftwareRenderThread::sync()", "sync triggered with gui not locked");
if (exposedWindow) {
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
index 7c98e2c1e1..ed37305374 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
@@ -43,13 +43,13 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QtMath>
-#include <QtGui/QOpenGLContext>
+#include <QOpenGLContext>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QSurface>
#include <QtGui/QWindow>
-#include <QtGui/QOpenGLFunctions>
-#include <QtGui/QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QOpenGLTexture>
#include <QDebug>
#include <private/qqmlglobal_p.h>
@@ -154,7 +154,7 @@ bool Texture::hasAlphaChannel() const
return !QSGCompressedTexture::formatIsOpaque(static_cast<Atlas*>(m_atlas)->format());
}
-QSGTexture *Texture::removedFromAtlas() const
+QSGTexture *Texture::removedFromAtlas(QRhiResourceUpdateBatch *) const
{
if (m_nonatlas_texture) {
m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
index 78051778f5..a2d6d96dfe 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
@@ -53,7 +53,7 @@
#include <QtCore/QSize>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QtQuick/QSGTexture>
#include <QtQuick/private/qsgareaallocator_p.h>
@@ -97,7 +97,7 @@ public:
QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; }
- QSGTexture *removedFromAtlas() const override;
+ QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *) const override;
const QByteArray &data() const { return m_data; }
int sizeInBytes() const { return m_dataLength; }
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
index 65abb2a1af..59cc967167 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -44,6 +44,7 @@
#include <QOpenGLFunctions>
#include <QDebug>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <QtGui/private/qrhi_p.h>
QT_BEGIN_NAMESPACE
@@ -51,7 +52,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio");
QSGCompressedTexture::QSGCompressedTexture(const QTextureFileData &texData)
- : QSGTexture(*(new QSGCompressedTexturePrivate)),
+ : QSGTexture(*(new QSGTexturePrivate)),
m_textureData(texData)
{
m_size = m_textureData.size();
@@ -89,18 +90,17 @@ int QSGCompressedTexture::textureId() const
return m_textureId;
}
-int QSGCompressedTexturePrivate::comparisonKey() const
+int QSGCompressedTexture::comparisonKey() const
{
- Q_Q(const QSGCompressedTexture);
// not textureId() as that would create an id when not yet done - that's not wanted here
- if (q->m_textureId)
- return q->m_textureId;
+ if (m_textureId)
+ return m_textureId;
- if (q->m_texture)
- return int(qintptr(q->m_texture));
+ if (m_texture)
+ return int(qintptr(m_texture));
// two textures (and so materials) with not-yet-created texture underneath are never equal
- return int(qintptr(q));
+ return int(qintptr(this));
}
QSize QSGCompressedTexture::textureSize() const
@@ -271,28 +271,26 @@ static QPair<QRhiTexture::Format, bool> toRhiCompressedFormat(uint glinternalfor
}
}
-QRhiTexture *QSGCompressedTexturePrivate::rhiTexture() const
+QRhiTexture *QSGCompressedTexture::rhiTexture() const
{
- Q_Q(const QSGCompressedTexture);
- return q->m_texture;
+ return m_texture;
}
-void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void QSGCompressedTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
- Q_Q(QSGCompressedTexture);
- if (q->m_uploaded)
+ if (m_uploaded)
return;
- q->m_uploaded = true; // even if fails, no point in trying again
+ m_uploaded = true; // even if fails, no point in trying again
- if (!q->m_textureData.isValid()) {
- qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", q->m_textureData.logName().constData());
+ if (!m_textureData.isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", m_textureData.logName().constData());
return;
}
- const QPair<QRhiTexture::Format, bool> fmt = toRhiCompressedFormat(q->m_textureData.glInternalFormat());
+ const QPair<QRhiTexture::Format, bool> fmt = toRhiCompressedFormat(m_textureData.glInternalFormat());
if (fmt.first == QRhiTexture::UnknownFormat) {
- qWarning("Unknown compressed format 0x%x", q->m_textureData.glInternalFormat());
+ qWarning("Unknown compressed format 0x%x", m_textureData.glInternalFormat());
return;
}
@@ -301,25 +299,25 @@ void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdate
texFlags |= QRhiTexture::sRGB;
if (!rhi->isTextureFormatSupported(fmt.first, texFlags)) {
- qWarning("Unsupported compressed format 0x%x", q->m_textureData.glInternalFormat());
+ qWarning("Unsupported compressed format 0x%x", m_textureData.glInternalFormat());
return;
}
- if (!q->m_texture) {
- q->m_texture = rhi->newTexture(fmt.first, q->m_size, 1, texFlags);
- if (!q->m_texture->build()) {
+ if (!m_texture) {
+ m_texture = rhi->newTexture(fmt.first, m_size, 1, texFlags);
+ if (!m_texture->build()) {
qWarning("Failed to create QRhiTexture for compressed data");
- delete q->m_texture;
- q->m_texture = nullptr;
+ delete m_texture;
+ m_texture = nullptr;
return;
}
}
// only upload mip level 0 since we never do mipmapping for compressed textures (for now?)
- resourceUpdates->uploadTexture(q->m_texture, QRhiTextureUploadEntry(0, 0,
- { q->m_textureData.data().constData() + q->m_textureData.dataOffset(), q->m_textureData.dataLength() }));
+ resourceUpdates->uploadTexture(m_texture, QRhiTextureUploadEntry(0, 0,
+ { m_textureData.data().constData() + m_textureData.dataOffset(), m_textureData.dataLength() }));
- q->m_textureData = QTextureFileData(); // Release this memory, not needed anymore
+ m_textureData = QTextureFileData(); // Release this memory, not needed anymore
}
QTextureFileData QSGCompressedTexture::textureData() const
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
index b858d8ddee..d584f0e2d4 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
@@ -59,11 +59,8 @@
QT_BEGIN_NAMESPACE
-class QSGCompressedTexturePrivate;
-
class Q_QUICK_PRIVATE_EXPORT QSGCompressedTexture : public QSGTexture
{
- Q_DECLARE_PRIVATE(QSGCompressedTexture)
Q_OBJECT
public:
QSGCompressedTexture(const QTextureFileData& texData);
@@ -73,8 +70,11 @@ public:
bool hasAlphaChannel() const override;
bool hasMipmaps() const override;
+ int comparisonKey() const override;
int textureId() const override;
void bind() override;
+ QRhiTexture *rhiTexture() const override;
+ void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
QTextureFileData textureData() const;
@@ -93,15 +93,6 @@ namespace QSGOpenGLAtlasTexture {
class Manager;
}
-class QSGCompressedTexturePrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGCompressedTexture)
-public:
- int comparisonKey() const override;
- QRhiTexture *rhiTexture() const override;
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
-};
-
class Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureFactory : public QQuickTextureFactory
{
public:
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
index 62ed342244..502ee27e27 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp
@@ -37,26 +37,16 @@
**
****************************************************************************/
-#include "qsgabstractrenderer_p.h"
+#include "qsgabstractrenderer_p_p.h"
QT_BEGIN_NAMESPACE
/*!
\class QSGAbstractRenderer
- \brief QSGAbstractRenderer gives access to the scene graph nodes and rendering of a QSGEngine.
+ \brief QSGAbstractRenderer gives access to the scene graph nodes and rendering.
\inmodule QtQuick
\since 5.4
-
- A QSGAbstractRenderer created by a QSGEngine allows you to set your QSGNode
- tree through setRootNode() and control the rendering viewport through
- setDeviceRect(), setViewportRect() and setProjectionMatrixToRect().
- You can finally trigger the rendering to the desired framebuffer through
- renderScene().
-
- The QSGAbstractRenderer is only available when used with a QSGEngine
- and isn't exposed when used internally by QQuickWindow.
-
- \sa QSGEngine, QSGNode
+ \internal
*/
/*!
@@ -387,5 +377,3 @@ QSGAbstractRenderer::ClearMode QSGAbstractRenderer::clearMode() const
*/
QT_END_NAMESPACE
-
-#include "moc_qsgabstractrenderer.cpp"
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
deleted file mode 100644
index 258a5fed14..0000000000
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGABSTRACTRENDERER_H
-#define QSGABSTRACTRENDERER_H
-
-#include <QtQuick/qsgnode.h>
-
-#ifndef GLuint
-#define GLuint uint
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QSGAbstractRendererPrivate;
-
-class Q_QUICK_EXPORT QSGAbstractRenderer : public QObject
-{
- Q_OBJECT
-public:
- enum ClearModeBit
- {
- ClearColorBuffer = 0x0001,
- ClearDepthBuffer = 0x0002,
- ClearStencilBuffer = 0x0004
- };
- Q_DECLARE_FLAGS(ClearMode, ClearModeBit)
- Q_FLAG(ClearMode)
-
- enum MatrixTransformFlag
- {
- MatrixTransformFlipY = 0x01
- };
- Q_DECLARE_FLAGS(MatrixTransformFlags, MatrixTransformFlag)
- Q_FLAG(MatrixTransformFlags)
-
- ~QSGAbstractRenderer() override;
-
- // just have a warning about becoming private, ifdefing the whole class is not feasible
-#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("QSGAbstractRenderer is no longer going to be public in Qt 6.0. QSGEngine-based workflows are expected to migrate to QQuickRenderControl instead.")
-#endif
- void setRootNode(QSGRootNode *node);
- QSGRootNode *rootNode() const;
- void setDeviceRect(const QRect &rect);
- inline void setDeviceRect(const QSize &size) { setDeviceRect(QRect(QPoint(), size)); }
- QRect deviceRect() const;
-
- void setViewportRect(const QRect &rect);
- inline void setViewportRect(const QSize &size) { setViewportRect(QRect(QPoint(), size)); }
- QRect viewportRect() const;
-
- void setProjectionMatrixToRect(const QRectF &rect);
- void setProjectionMatrixToRect(const QRectF &rect, MatrixTransformFlags flags);
- void setProjectionMatrix(const QMatrix4x4 &matrix);
- void setProjectionMatrixWithNativeNDC(const QMatrix4x4 &matrix);
- QMatrix4x4 projectionMatrix() const;
- QMatrix4x4 projectionMatrixWithNativeNDC() const;
-
- void setClearColor(const QColor &color);
- QColor clearColor() const;
-
- void setClearMode(ClearMode mode);
- ClearMode clearMode() const;
-
- virtual void renderScene(GLuint fboId = 0) = 0;
-
-Q_SIGNALS:
- void sceneGraphChanged();
-
-protected:
- explicit QSGAbstractRenderer(QObject *parent = nullptr);
- virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) = 0;
-
-private:
- Q_DECLARE_PRIVATE(QSGAbstractRenderer)
- friend class QSGRootNode;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGAbstractRenderer::ClearMode)
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
index bbc4289b2c..5d48f18310 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h
@@ -51,37 +51,78 @@
// We mean it.
//
-#include "qsgabstractrenderer.h"
-
-#include "qsgnode.h"
-#include <qcolor.h>
-
-#include <QtCore/private/qobject_p.h>
#include <QtQuick/private/qtquickglobal_p.h>
+#include <QtQuick/qsgnode.h>
+
+#ifndef GLuint
+#define GLuint uint
+#endif
QT_BEGIN_NAMESPACE
-class Q_QUICK_PRIVATE_EXPORT QSGAbstractRendererPrivate : public QObjectPrivate
+class QSGAbstractRendererPrivate;
+
+class Q_QUICK_PRIVATE_EXPORT QSGAbstractRenderer : public QObject
{
- Q_DECLARE_PUBLIC(QSGAbstractRenderer)
+ Q_OBJECT
public:
- static const QSGAbstractRendererPrivate *get(const QSGAbstractRenderer *q) { return q->d_func(); }
+ enum ClearModeBit
+ {
+ ClearColorBuffer = 0x0001,
+ ClearDepthBuffer = 0x0002,
+ ClearStencilBuffer = 0x0004
+ };
+ Q_DECLARE_FLAGS(ClearMode, ClearModeBit)
+ Q_FLAG(ClearMode)
+
+ enum MatrixTransformFlag
+ {
+ MatrixTransformFlipY = 0x01
+ };
+ Q_DECLARE_FLAGS(MatrixTransformFlags, MatrixTransformFlag)
+ Q_FLAG(MatrixTransformFlags)
+
+ ~QSGAbstractRenderer() override;
- QSGAbstractRendererPrivate();
- void updateProjectionMatrix();
+ void setRootNode(QSGRootNode *node);
+ QSGRootNode *rootNode() const;
+ void setDeviceRect(const QRect &rect);
+ inline void setDeviceRect(const QSize &size) { setDeviceRect(QRect(QPoint(), size)); }
+ QRect deviceRect() const;
- QSGRootNode *m_root_node;
- QColor m_clear_color;
- QSGAbstractRenderer::ClearMode m_clear_mode;
+ void setViewportRect(const QRect &rect);
+ inline void setViewportRect(const QSize &size) { setViewportRect(QRect(QPoint(), size)); }
+ QRect viewportRect() const;
- QRect m_device_rect;
- QRect m_viewport_rect;
+ void setProjectionMatrixToRect(const QRectF &rect);
+ void setProjectionMatrixToRect(const QRectF &rect, MatrixTransformFlags flags);
+ void setProjectionMatrix(const QMatrix4x4 &matrix);
+ void setProjectionMatrixWithNativeNDC(const QMatrix4x4 &matrix);
+ QMatrix4x4 projectionMatrix() const;
+ QMatrix4x4 projectionMatrixWithNativeNDC() const;
- QMatrix4x4 m_projection_matrix;
- QMatrix4x4 m_projection_matrix_native_ndc;
- uint m_mirrored : 1;
+ void setClearColor(const QColor &color);
+ QColor clearColor() const;
+
+ void setClearMode(ClearMode mode);
+ ClearMode clearMode() const;
+
+ virtual void renderScene(GLuint fboId = 0) = 0;
+
+Q_SIGNALS:
+ void sceneGraphChanged();
+
+protected:
+ explicit QSGAbstractRenderer(QObject *parent = nullptr);
+ virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) = 0;
+
+private:
+ Q_DECLARE_PRIVATE(QSGAbstractRenderer)
+ friend class QSGRootNode;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGAbstractRenderer::ClearMode)
+
QT_END_NAMESPACE
#endif
diff --git a/src/quick/scenegraph/util/qsgengine_p.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p_p.h
index 662c32d3d9..42e9acb437 100644
--- a/src/quick/scenegraph/util/qsgengine_p.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QSGENGINE_P_H
-#define QSGENGINE_P_H
+#ifndef QSGABSTRACTRENDERER_P_P_H
+#define QSGABSTRACTRENDERER_P_P_H
//
// W A R N I N G
@@ -51,27 +51,37 @@
// We mean it.
//
-#include "qsgengine.h"
-#include <private/qobject_p.h>
+#include "qsgabstractrenderer_p.h"
-QT_BEGIN_NAMESPACE
+#include "qsgnode.h"
+#include <qcolor.h>
+
+#include <QtCore/private/qobject_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
-class QSGContext;
-class QSGRenderContext;
+QT_BEGIN_NAMESPACE
-#if QT_DEPRECATED_SINCE(5, 15)
-class QSGEnginePrivate : public QObjectPrivate
+class Q_QUICK_PRIVATE_EXPORT QSGAbstractRendererPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QSGEngine)
+ Q_DECLARE_PUBLIC(QSGAbstractRenderer)
public:
- static QSGEnginePrivate *get(QSGEngine *engine) { return engine->d_func(); }
- QSGEnginePrivate();
+ static const QSGAbstractRendererPrivate *get(const QSGAbstractRenderer *q) { return q->d_func(); }
+
+ QSGAbstractRendererPrivate();
+ void updateProjectionMatrix();
- QScopedPointer<QSGContext> sgContext;
- QScopedPointer<QSGRenderContext> sgRenderContext;
+ QSGRootNode *m_root_node;
+ QColor m_clear_color;
+ QSGAbstractRenderer::ClearMode m_clear_mode;
+
+ QRect m_device_rect;
+ QRect m_viewport_rect;
+
+ QMatrix4x4 m_projection_matrix;
+ QMatrix4x4 m_projection_matrix_native_ndc;
+ uint m_mirrored : 1;
};
-#endif
QT_END_NAMESPACE
-#endif // QSGENGINE_P_H
+#endif
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index ce3c4aac4f..ed790fdc5c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -50,10 +50,11 @@
#include <QtCore/QtNumeric>
#include <QtGui/QGuiApplication>
-#include <QtGui/QOpenGLFramebufferObject>
-#include <QtGui/QOpenGLVertexArrayObject>
-#include <QtGui/QOpenGLFunctions_1_0>
-#include <QtGui/QOpenGLFunctions_3_2_Core>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLVertexArrayObject>
+#include <QOpenGLFunctions_1_0>
+#include <QOpenGLFunctions_3_2_Core>
+#include <QOpenGLVersionFunctionsFactory>
#include <private/qnumeric_p.h>
#include <private/qquickprofiler_p.h>
@@ -138,6 +139,7 @@ struct QMatrix4x4_Accessor
static bool isScale(const QMatrix4x4 &m) { return ((const QMatrix4x4_Accessor &) m).flagBits <= 0x2; }
static bool is2DSafe(const QMatrix4x4 &m) { return ((const QMatrix4x4_Accessor &) m).flagBits < 0x8; }
};
+Q_STATIC_ASSERT(sizeof(QMatrix4x4_Accessor) == sizeof(QMatrix4x4));
const float OPAQUE_LIMIT = 0.999f;
@@ -480,8 +482,6 @@ Updater::Updater(Renderer *r)
m_roots.add(0);
m_combined_matrix_stack.add(&m_identityMatrix);
m_rootMatrices.add(m_identityMatrix);
-
- Q_ASSERT(sizeof(QMatrix4x4_Accessor) == sizeof(QMatrix4x4));
}
void Updater::updateStates(QSGNode *n)
@@ -2964,16 +2964,16 @@ void Renderer::updateLineWidth(QSGGeometry *g) // legacy (GL-only)
{
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
else {
QOpenGLContext *ctx = m_context->openglContext();
if (!ctx->isOpenGLES() && g->drawingMode() == GL_POINTS) {
QOpenGLFunctions_1_0 *gl1funcs = nullptr;
QOpenGLFunctions_3_2_Core *gl3funcs = nullptr;
if (ctx->format().profile() == QSurfaceFormat::CoreProfile)
- gl3funcs = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ gl3funcs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx);
else
- gl1funcs = ctx->versionFunctions<QOpenGLFunctions_1_0>();
+ gl1funcs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_1_0>(ctx);
Q_ASSERT(gl1funcs || gl3funcs);
if (gl1funcs)
gl1funcs->glPointSize(g->lineWidth());
@@ -3499,7 +3499,7 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms,
}
if (pd->textureBindingTable[binding] && pd->samplerBindingTable[binding]) {
- QRhiTexture *texture = QSGTexturePrivate::get(pd->textureBindingTable[binding])->rhiTexture();
+ QRhiTexture *texture = 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.
@@ -4117,6 +4117,8 @@ void Renderer::renderBatches()
if (m_renderPassRecordingCallbacks.start)
m_renderPassRecordingCallbacks.start(m_renderPassRecordingCallbacks.userData);
+ cb->debugMarkBegin(QByteArrayLiteral("Qt Quick scene render"));
+
for (int i = 0, ie = opaqueRenderBatches.count(); i != ie; ++i) {
PreparedRenderBatch *renderBatch = &opaqueRenderBatches[i];
if (renderBatch->batch->merged)
@@ -4138,6 +4140,8 @@ void Renderer::renderBatches()
if (m_currentShader)
setActiveRhiShader(nullptr, nullptr);
+ cb->debugMarkEnd();
+
if (m_renderPassRecordingCallbacks.end)
m_renderPassRecordingCallbacks.end(m_renderPassRecordingCallbacks.userData);
@@ -4534,8 +4538,7 @@ bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBat
opacity = opacity->parent();
}
- if (rd->m_prepareCallback)
- rd->m_prepareCallback();
+ e->renderNode->prepare();
renderBatch->batch = batch;
renderBatch->sms = nullptr;
@@ -4568,7 +4571,7 @@ void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render (
const QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
QRhiCommandBuffer *cb = commandBuffer();
- const bool needsExternal = rd->m_needsExternalRendering;
+ const bool needsExternal = !e->renderNode->flags().testFlag(QSGRenderNode::NoExternalRendering);
if (needsExternal)
cb->beginExternal();
e->renderNode->render(&state);
@@ -4612,6 +4615,22 @@ bool Renderer::hasCustomRenderModeWithContinuousUpdate() const
return m_visualizer->mode() == Visualizer::VisualizeOverdraw;
}
+void Renderer::invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *rpDesc)
+{
+ if (!rpDesc)
+ return;
+
+ for (auto it = m_shaderManager->pipelineCache.begin(); it != m_shaderManager->pipelineCache.end(); ) {
+ if (it.key().compatibleRenderPassDescriptor == rpDesc) {
+ QRhiGraphicsPipeline *ps = it.value();
+ it = m_shaderManager->pipelineCache.erase(it);
+ ps->releaseAndDestroyLater(); // QRhi takes care of it in endFrame()
+ } else {
+ ++it;
+ }
+ }
+}
+
bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW
{
return a.depthTest == b.depthTest
@@ -4634,7 +4653,7 @@ bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW
return !(a == b);
}
-uint qHash(const GraphicsState &s, uint seed) Q_DECL_NOTHROW
+size_t qHash(const GraphicsState &s, uint seed) Q_DECL_NOTHROW
{
// do not bother with all fields
return seed
@@ -4662,7 +4681,7 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
return !(a == b);
}
-uint qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW
+size_t qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW
{
// no srb and rp included due to their special comparison semantics and lack of hash keys
return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 878b63fc8c..3db93bee41 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -62,7 +62,7 @@
#include <QtCore/QBitArray>
#include <QtCore/QStack>
-#include <QtGui/QOpenGLFunctions>
+#include <QOpenGLFunctions>
#include <QtGui/private/qrhi_p.h>
@@ -645,7 +645,7 @@ struct GraphicsState
bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
+size_t qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
struct ShaderManagerShader;
@@ -659,7 +659,7 @@ struct GraphicsPipelineStateKey
bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
+size_t qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
struct ShaderManagerShader
{
@@ -847,6 +847,8 @@ private:
void setCustomRenderMode(const QByteArray &mode) override;
bool hasCustomRenderModeWithContinuousUpdate() const override;
+ void invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *rpDesc) override;
+
QSGDefaultRenderContext *m_context;
QSet<Node *> m_taggedRoots;
QDataBuffer<Element *> m_opaqueRenderList;
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h
index d17915a842..9c60876597 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.h
+++ b/src/quick/scenegraph/coreapi/qsggeometry.h
@@ -41,7 +41,7 @@
#define QSGGEOMETRY_H
#include <QtQuick/qtquickglobal.h>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QtCore/QRectF>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
index d614f9be4c..64956e2ca4 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
@@ -44,8 +44,8 @@
# include <private/qsgshadersourcebuilder_p.h>
# include <private/qsgdefaultcontext_p.h>
# include <private/qsgdefaultrendercontext_p.h>
-# include <QtGui/QOpenGLFunctions>
-# include <QtGui/QOpenGLContext>
+# include <QOpenGLFunctions>
+# include <QOpenGLContext>
#endif
QT_BEGIN_NAMESPACE
@@ -69,10 +69,6 @@ const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
- The QSGMaterialShader API is relatively low-level. A more convenient API,
- which provides almost all the same features, is available through
- QSGSimpleMaterialShader.
-
\warning This class is only functional when running with the legacy OpenGL
renderer of the Qt Quick scenegraph.
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.h b/src/quick/scenegraph/coreapi/qsgmaterialshader.h
index d7ee23384f..6783b3f890 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialshader.h
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.h
@@ -42,7 +42,7 @@
#include <QtQuick/qtquickglobal.h>
#if QT_CONFIG(opengl)
-# include <QtGui/qopenglshaderprogram.h>
+# include <qopenglshaderprogram.h>
#endif
#include <QtGui/QMatrix4x4>
#include <QtCore/QRect>
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index a35629d874..e22ffa10d2 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -850,7 +850,7 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry)
\note All classes with QSG prefix should be used solely on the scene graph's
rendering thread. See \l {Scene Graph and Rendering} for more information.
- \sa QSGGeometry, QSGMaterial, QSGSimpleMaterial
+ \sa QSGGeometry, QSGMaterial
*/
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index 5a7faed5e0..19b8cf9354 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -177,7 +177,6 @@ private:
int m_subtreeRenderableCount = 0;
Flags m_nodeFlags;
- DirtyState m_dirtyState; // Obsolete, remove in Qt 6
protected:
friend class QSGNodePrivate;
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 90090e1cc0..cd16014d41 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -40,9 +40,9 @@
#include "qsgrenderer_p.h"
#include "qsgnodeupdater_p.h"
#if QT_CONFIG(opengl)
-# include <QtGui/QOpenGLFramebufferObject>
-# include <QtGui/QOpenGLContext>
-# include <QtGui/QOpenGLFunctions>
+# include <QOpenGLFramebufferObject>
+# include <QOpenGLContext>
+# include <QOpenGLFunctions>
#endif
#include <private/qquickprofiler_p.h>
#include <qtquick_tracepoints_p.h>
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index c4ed0072f6..3f2154e3c1 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -51,8 +51,7 @@
// We mean it.
//
-#include "qsgabstractrenderer.h"
-#include "qsgabstractrenderer_p.h"
+#include "qsgabstractrenderer_p_p.h"
#include "qsgnode.h"
#include "qsgmaterial.h"
@@ -99,6 +98,7 @@ public:
virtual void setCustomRenderMode(const QByteArray &) { }
virtual bool hasCustomRenderModeWithContinuousUpdate() const { return false; }
virtual void releaseCachedResources() { }
+ virtual void invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *) { }
void clearChangedFlag() { m_changed_emitted = false; }
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
index 0fee1486cf..9b5701df5a 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
@@ -76,7 +76,6 @@ QT_BEGIN_NAMESPACE
\value Unknown An unknown graphics API is in use
\value Software The Qt Quick 2D Renderer is in use
\value OpenGL OpenGL ES 2.0 or higher
- \value Direct3D12 Direct3D 12
\value OpenVG OpenVG via EGL
\value OpenGLRhi OpenGL ES 2.0 or higher via a graphics abstraction layer. This value was introduced in Qt 5.14.
\value Direct3D11Rhi Direct3D 11 via a graphics abstraction layer. This value was introduced in Qt 5.14.
@@ -189,10 +188,10 @@ QSGRendererInterface::~QSGRendererInterface()
not supported or not available.
When successful, the returned pointer is either a direct pointer to an
- interface (and can be cast, for example, to \c{ID3D12Device *}) or a
- pointer to an opaque handle that needs to be dereferenced first (for
- example, \c{VkDevice dev = *static_cast<VkDevice *>(result)}). The latter
- is necessary since such handles may have sizes different from a pointer.
+ interface, or a pointer to an opaque handle that needs to be dereferenced
+ first (for example, \c{VkDevice dev = *static_cast<VkDevice
+ *>(result)}). The latter is necessary since such handles may have sizes
+ different from a pointer.
\note The ownership of the returned pointer is never transferred to the caller.
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.h b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
index 7aa7d0e769..6224e08e84 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.h
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
@@ -53,7 +53,6 @@ public:
Unknown,
Software,
OpenGL,
- Direct3D12,
OpenVG,
OpenGLRhi,
Direct3D11Rhi,
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 45ad49475f..ec8e3dda57 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -77,8 +77,6 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
: m_matrix(nullptr)
, m_clip_list(nullptr)
, m_opacity(1)
- , m_needsExternalRendering(true)
- , m_prepareCallback(nullptr)
{
}
@@ -101,8 +99,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
With APIs other than OpenGL, the only relevant values are the ones that
correspond to dynamic state changes recorded on the command list/buffer.
- For example, RSSetViewports, RSSetScissorRects, OMSetBlendFactor,
- OMSetStencilRef in case of D3D12, or vkCmdSetViewport, vkCmdSetScissor,
+ For example, RSSetViewports, RSSetScissorRects, OMSetBlendState,
+ OMSetDepthStencilState in case of D3D11, or vkCmdSetViewport, vkCmdSetScissor,
vkCmdSetBlendConstants, vkCmdSetStencilRef in case of Vulkan, and only when
such commands were added to the scenegraph's command list queried via the
QSGRendererInterface::CommandList resource enum. States set in pipeline
@@ -137,6 +135,24 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
}
/*!
+ Called from the frame preparation phase. There is a call to this function
+ before each invocation of render().
+
+ Unlike render(), this function is called before the scenegraph starts
+ recording the render pass for the current frame on the underlying command
+ buffer. This is useful when doing rendering with graphics APIs, such as
+ Vulkan, where copy type of operations will need to be recorded before the
+ render pass.
+
+ The default implementation is empty.
+
+ \since 6.0
+ */
+void QSGRenderNode::prepare()
+{
+}
+
+/*!
\fn void QSGRenderNode::render(const RenderState *state)
This function is called by the renderer and should paint this node with
@@ -301,6 +317,8 @@ void QSGRenderNode::releaseResources()
transparent pixels. Setting this flag can improve performance in some
cases.
+ \omitvalue NoExternalRendering
+
\sa render(), rect()
*/
@@ -383,11 +401,6 @@ QSGRenderNode::RenderState::~RenderState()
\return the current scissor rectangle when clipping is active. x and y are
the bottom left coordinates.
-
- \note Be aware of the differences between graphics APIs: for some the
- scissor rect is only active when scissoring is enabled (for example,
- OpenGL), while for others the scissor rect is equal to the viewport rect
- when there is no need to scissor away anything (for example, Direct3D 12).
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.h b/src/quick/scenegraph/coreapi/qsgrendernode.h
index 0fb83b080c..2a5a5ce106 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.h
@@ -64,7 +64,8 @@ public:
enum RenderingFlag {
BoundedRectRendering = 0x01,
DepthAwareRendering = 0x02,
- OpaqueRendering = 0x04
+ OpaqueRendering = 0x04,
+ NoExternalRendering = 0x08
};
Q_DECLARE_FLAGS(RenderingFlags, RenderingFlag)
@@ -83,6 +84,7 @@ public:
~QSGRenderNode() override;
virtual StateFlags changedStates() const;
+ virtual void prepare();
virtual void render(const RenderState *state) = 0;
virtual void releaseResources();
virtual RenderingFlags flags() const;
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode_p.h b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
index 534d630f15..ca38f344ef 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
@@ -54,7 +54,6 @@
#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgrendernode.h>
-#include <functional>
QT_BEGIN_NAMESPACE
@@ -68,11 +67,6 @@ public:
const QMatrix4x4 *m_matrix;
const QSGClipNode *m_clip_list;
qreal m_opacity;
-
- // ### Qt 6: change this into a value for flags()
- bool m_needsExternalRendering;
- // ### Qt 6: change this into a virtual prepare() function
- std::function<void()> m_prepareCallback;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index 418aaca605..25e02d8058 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -39,8 +39,8 @@
#include "qsgtexture_p.h"
#if QT_CONFIG(opengl)
-# include <QtGui/qopenglcontext.h>
-# include <QtGui/qopenglfunctions.h>
+# include <qopenglcontext.h>
+# include <qopenglfunctions.h>
#endif
#include <private/qqmlglobal_p.h>
#include <private/qsgmaterialshader_p.h>
@@ -83,7 +83,7 @@ bool operator!=(const QSGSamplerDescription &a, const QSGSamplerDescription &b)
return !(a == b);
}
-uint qHash(const QSGSamplerDescription &s, uint seed) Q_DECL_NOTHROW
+size_t qHash(const QSGSamplerDescription &s, uint seed) Q_DECL_NOTHROW
{
const int f = s.filtering;
const int m = s.mipmapFiltering;
@@ -453,11 +453,19 @@ QSGTexture::~QSGTexture()
Implementations of this function are recommended to return the same instance
for multiple calls to limit memory usage.
+ \a resourceUpdates is an optional resource update batch, on which texture
+ operations, if any, are enqueued. Materials can retrieve an instance from
+ QSGMaterialRhiShader::RenderState. When null, the removedFromAtlas()
+ implementation creates its own batch and submit it right away. However,
+ when a valid instance is specified, this function will not submit the
+ update batch.
+
\warning This function can only be called from the rendering thread.
*/
-QSGTexture *QSGTexture::removedFromAtlas() const
+QSGTexture *QSGTexture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates) const
{
+ Q_UNUSED(resourceUpdates);
Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture");
return nullptr;
}
@@ -485,6 +493,8 @@ bool QSGTexture::isAtlasTexture() const
*/
/*!
+ \fn int QSGTexture::comparisonKey() const
+
Returns a key suitable for comparing textures. Typically used in
QSGMaterial::compare() implementations.
@@ -506,11 +516,6 @@ bool QSGTexture::isAtlasTexture() const
\since 5.14
*/
-int QSGTexture::comparisonKey() const
-{
- Q_D(const QSGTexture);
- return d->comparisonKey();
-}
/*!
\fn QSize QSGTexture::textureSize() const
@@ -727,6 +732,32 @@ void QSGTexture::updateBindOptions(bool force) // legacy (GL-only)
}
/*!
+ \return the QRhiTexture for this QSGTexture or null if there is none (either
+ because a valid texture has not been created internally yet, or because the
+ concept is not applicable to the scenegraph backend in use).
+
+ 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.
+
+ \warning This function can only be called from the rendering thread.
+
+ \since 6.0
+ */
+QRhiTexture *QSGTexture::rhiTexture() const
+{
+ return nullptr;
+}
+
+QRhiTexture *QSGTexturePrivate::rhiTexture() const
+{
+ // Just calls the public API, this private function exists for internal
+ // source compatibility only until all Qt modules migrate away from it.
+ Q_Q(const QSGTexture);
+ return q->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
@@ -735,17 +766,14 @@ void QSGTexture::updateBindOptions(bool force) // legacy (GL-only)
Materials involving \a rhi textures are expected to call this function from
their updateSampledImage() implementation, typically without any conditions.
- \note This function is only used when running the graphics API independent
- rendering path of the scene graph.
-
\warning This function can only be called from the rendering thread.
- \since 5.14
+ \since 6.0
*/
-void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void QSGTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
- Q_D(QSGTexture);
- d->updateRhiTexture(rhi, resourceUpdates);
+ Q_UNUSED(rhi);
+ Q_UNUSED(resourceUpdates);
}
/*!
@@ -762,23 +790,13 @@ void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUp
*/
QSGTexture::NativeTexture QSGTexture::nativeTexture() const
{
- Q_D(const QSGTexture);
- if (auto *tex = d->rhiTexture()) {
+ if (auto *tex = rhiTexture()) {
auto nativeTexture = tex->nativeTexture();
return {nativeTexture.object, nativeTexture.layout};
}
return {};
}
-/*!
- \internal
- */
-void QSGTexture::setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates)
-{
- Q_D(QSGTexture);
- d->workResourceUpdateBatch = resourceUpdates;
-}
-
bool QSGTexturePrivate::hasDirtySamplerOptions() const
{
return wrapChanged || filteringChanged || anisotropyChanged;
@@ -789,42 +807,6 @@ void QSGTexturePrivate::resetDirtySamplerOptions()
wrapChanged = filteringChanged = anisotropyChanged = false;
}
-int QSGTexturePrivate::comparisonKey() const
-{
- // Must be overridden in subclasses but we cannot make this pure virtual
- // before Qt 6 because the simple QSGTexture ctor must be kept working.
- Q_Q(const QSGTexture);
- 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;
-}
-
-void QSGTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
-{
- Q_UNUSED(rhi);
- Q_UNUSED(resourceUpdates);
-}
-
/*!
\class QSGDynamicTexture
\brief The QSGDynamicTexture class serves as a baseclass for dynamically changing textures,
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h
index 207ef52f4e..b0f01b1933 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture.h
@@ -85,7 +85,9 @@ public:
int layout;
};
+ virtual int comparisonKey() const = 0;
virtual int textureId() const = 0; // ### Qt 6: remove
+ virtual QRhiTexture *rhiTexture() const;
NativeTexture nativeTexture() const;
virtual QSize textureSize() const = 0;
virtual bool hasAlphaChannel() const = 0;
@@ -95,10 +97,12 @@ public:
virtual bool isAtlasTexture() const;
- virtual QSGTexture *removedFromAtlas() const;
+ virtual QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates = nullptr) const;
- virtual void bind() = 0;
- void updateBindOptions(bool force = false);
+ virtual void bind() = 0; // ### Qt 6: remove
+ void updateBindOptions(bool force = false); // ### Qt 6: remove
+
+ virtual void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates);
void setMipmapFiltering(Filtering filter);
QSGTexture::Filtering mipmapFiltering() const;
@@ -117,13 +121,6 @@ public:
inline QRectF convertToNormalizedSourceRect(const QRectF &rect) const;
- // ### Qt 6: make these virtual
- int comparisonKey() const;
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates);
-
- // ### Qt 6: make this an argument for removedFromAtlas()
- void setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates);
-
protected:
QSGTexture(QSGTexturePrivate &dd);
};
diff --git a/src/quick/scenegraph/coreapi/qsgtexture_p.h b/src/quick/scenegraph/coreapi/qsgtexture_p.h
index cb59d32012..e24088229c 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture_p.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture_p.h
@@ -72,7 +72,7 @@ Q_DECLARE_TYPEINFO(QSGSamplerDescription, Q_MOVABLE_TYPE);
bool operator==(const QSGSamplerDescription &a, const QSGSamplerDescription &b) Q_DECL_NOTHROW;
bool operator!=(const QSGSamplerDescription &a, const QSGSamplerDescription &b) Q_DECL_NOTHROW;
-uint qHash(const QSGSamplerDescription &s, uint seed = 0) Q_DECL_NOTHROW;
+size_t qHash(const QSGSamplerDescription &s, uint seed = 0) Q_DECL_NOTHROW;
class Q_QUICK_PRIVATE_EXPORT QSGTexturePrivate : public QObjectPrivate
{
@@ -82,14 +82,7 @@ public:
static QSGTexturePrivate *get(QSGTexture *t) { return t->d_func(); }
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 void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates);
-
- QRhiResourceUpdateBatch *workResourceUpdateBatch = nullptr; // ### Qt 6: remove
+ QRhiTexture *rhiTexture() const;
uint wrapChanged : 1;
uint filteringChanged : 1;
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index eab0369be7..e0d9d5db68 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -329,7 +329,7 @@ void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTextu
}
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
-#include <QtGui/qopenglfunctions.h>
+#include <qopenglfunctions.h>
void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const
{
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 1db49feb5d..6376317427 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -299,7 +299,6 @@ public:
Q_SIGNALS:
void shaderCodePrepared(bool ok, ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result);
- void textureChanged();
void logAndStatusChanged();
};
@@ -307,8 +306,10 @@ Q_SIGNALS:
Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v);
#endif
-class Q_QUICK_PRIVATE_EXPORT QSGShaderEffectNode : public QSGVisitableNode
+class Q_QUICK_PRIVATE_EXPORT QSGShaderEffectNode : public QObject, public QSGVisitableNode
{
+ Q_OBJECT
+
public:
enum DirtyShaderFlag {
DirtyShaders = 0x01,
@@ -355,12 +356,14 @@ public:
};
// Each ShaderEffect item has one node (render thread) and one manager (gui thread).
- QSGShaderEffectNode(QSGGuiThreadShaderEffectManager *) { }
virtual QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) = 0;
virtual void syncMaterial(SyncData *syncData) = 0;
void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
+
+Q_SIGNALS:
+ void textureChanged();
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QSGShaderEffectNode::DirtyShaderFlags)
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index e3c951e5ed..9baf530889 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -284,7 +284,7 @@ QSGGuiThreadShaderEffectManager *QSGContext::createGuiThreadShaderEffectManager(
valid as long as the backend does not claim SupportsShaderEffectNode or
ignoring ShaderEffect elements is acceptable.
*/
-QSGShaderEffectNode *QSGContext::createShaderEffectNode(QSGRenderContext *, QSGGuiThreadShaderEffectManager *)
+QSGShaderEffectNode *QSGContext::createShaderEffectNode(QSGRenderContext *)
{
return nullptr;
}
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index d389420907..a2cb21a60c 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -128,8 +128,7 @@ public:
virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) = 0;
virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0;
virtual QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager();
- virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext,
- QSGGuiThreadShaderEffectManager *mgr);
+ virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext);
#if QT_CONFIG(quick_sprite)
virtual QSGSpriteNode *createSpriteNode() = 0;
#endif
diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp
index ea01b0a3b4..f7701d8f7f 100644
--- a/src/quick/scenegraph/qsgdefaultcontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultcontext.cpp
@@ -57,10 +57,11 @@
#endif
#include <QtQuick/private/qsgrhishadereffectnode_p.h>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLFramebufferObject>
+#include <QOpenGLContext>
+#include <QOpenGLFramebufferObject>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <private/qqmlglobal_p.h>
@@ -296,13 +297,10 @@ QSGGuiThreadShaderEffectManager *QSGDefaultContext::createGuiThreadShaderEffectM
return nullptr;
}
-QSGShaderEffectNode *QSGDefaultContext::createShaderEffectNode(QSGRenderContext *renderContext,
- QSGGuiThreadShaderEffectManager *mgr)
+QSGShaderEffectNode *QSGDefaultContext::createShaderEffectNode(QSGRenderContext *renderContext)
{
- if (QSGRhiSupport::instance()->isRhiEnabled()) {
- return new QSGRhiShaderEffectNode(static_cast<QSGDefaultRenderContext *>(renderContext),
- static_cast<QSGRhiGuiThreadShaderEffectManager *>(mgr));
- }
+ if (QSGRhiSupport::instance()->isRhiEnabled())
+ return new QSGRhiShaderEffectNode(static_cast<QSGDefaultRenderContext *>(renderContext));
return nullptr;
}
diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h
index 8fdd29caee..414a4151f1 100644
--- a/src/quick/scenegraph/qsgdefaultcontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultcontext_p.h
@@ -80,8 +80,7 @@ public:
QSGSpriteNode *createSpriteNode() override;
#endif
QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager() override;
- QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext,
- QSGGuiThreadShaderEffectManager *mgr) override;
+ QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext) override;
void setDistanceFieldEnabled(bool enabled);
bool isDistanceFieldEnabled() const;
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index be6ef25feb..f73b64f537 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -451,8 +451,8 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
changed = true;
}
- QRhiTexture *oldRtex = oldMat ? QSGTexturePrivate::get(oldMat->texture())->rhiTexture() : nullptr;
- QRhiTexture *newRtex = QSGTexturePrivate::get(mat->texture())->rhiTexture();
+ QRhiTexture *oldRtex = oldMat ? oldMat->texture()->rhiTexture() : nullptr;
+ QRhiTexture *newRtex = mat->texture()->rhiTexture();
if (updated || !oldMat || oldRtex != newRtex) {
const QVector2D textureScale = QVector2D(1.0f / mat->rhiGlyphCache()->width(),
1.0f / mat->rhiGlyphCache()->height());
@@ -789,11 +789,12 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
const QMargins &margins)
{
Q_ASSERT(m_font.isValid());
+ QPointF position(p.x(), p.y() - m_font.ascent());
QVector<QFixedPoint> fixedPointPositions;
const int glyphPositionsSize = glyphPositions.size();
fixedPointPositions.reserve(glyphPositionsSize);
for (int i=0; i < glyphPositionsSize; ++i)
- fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i)));
+ fixedPointPositions.append(QFixedPoint::fromPointF(position + glyphPositions.at(i)));
QTextureGlyphCache *cache = glyphCache();
@@ -815,18 +816,16 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D));
ushort *ip = geometry->indexDataAsUShort();
- QPointF position(p.x(), p.y() - m_font.ascent());
bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
for (int i=0; i<glyphIndexes.size(); ++i) {
+ QPointF glyphPosition = glyphPositions.at(i) + position;
QFixed subPixelPosition;
if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x()));
+ subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x()));
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
- QPointF glyphPosition = glyphPositions.at(i) + position;
-
// On a retina screen the glyph positions are not pre-scaled (as opposed to
// eg. the raster paint engine). To ensure that we get the same behavior as
// the raster engine (and CoreText itself) when it comes to rounding of the
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
index 4cff2d3d24..f70d51d1ee 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
@@ -53,7 +53,6 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qsgbasicglyphnode_p.h>
-#include <qlinkedlist.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
index 7d2635794d..4ddef9af24 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
@@ -52,7 +52,7 @@
//
#include <qcolor.h>
-#include <QtGui/private/qopengltextureglyphcache_p.h>
+#include <private/qopengltextureglyphcache_p.h>
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgtexture.h>
#include <QtQuick/qsggeometry.h>
diff --git a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
index 500d4e6e95..e609bea439 100644
--- a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
@@ -41,7 +41,7 @@
#include <private/qsgdefaultrendercontext_p.h>
#include <private/qsgmaterialshader_p.h>
#include <private/qsgtexturematerial_p.h>
-#include <QtGui/qopenglfunctions.h>
+#include <qopenglfunctions.h>
#include <QtCore/qmath.h>
#include <QtGui/private/qrhi_p.h>
@@ -254,7 +254,7 @@ bool QSGDefaultInternalImageNode::supportsWrap(const QSize &size) const
|| (isPowerOfTwo(size.width()) && isPowerOfTwo(size.height()));
} else {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
-#ifndef QT_OPENGL_ES_2
+#if !QT_CONFIG(opengles2)
if (ctx->isOpenGLES())
#endif
{
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 1d18caa0b4..a5d352b7f1 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -40,7 +40,7 @@
#include "qsgdefaultrendercontext_p.h"
#include <QtGui/QGuiApplication>
-#include <QtGui/QOpenGLFramebufferObject>
+#include <QOpenGLFramebufferObject>
#include <QtQuick/private/qsgbatchrenderer_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
@@ -69,6 +69,7 @@ QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context)
, m_rhiAtlasManager(nullptr)
, m_currentFrameCommandBuffer(nullptr)
, m_currentFrameRenderPass(nullptr)
+ , m_separateIndexBuffer(false)
{
}
@@ -92,6 +93,8 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
m_maxTextureSize = m_rhi->resourceLimit(QRhi::TextureSizeMax);
if (!m_rhiAtlasManager)
m_rhiAtlasManager = new QSGRhiAtlasTexture::Manager(this, m_initParams.initialSurfacePixelSize, m_initParams.maybeSurface);
+ // unlike OpenGL (and like WebGL), QRhi does not guarantee buffer usage types can be mixed
+ m_separateIndexBuffer = true;
} else {
QOpenGLFunctions *funcs = m_rhi ? nullptr : QOpenGLContext::currentContext()->functions();
funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
@@ -124,6 +127,15 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
if (!m_glAtlasManager)
m_glAtlasManager = new QSGOpenGLAtlasTexture::Manager(m_initParams.initialSurfacePixelSize);
+
+ // WebGL: A given WebGLBuffer object may only be bound to one of
+ // the ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target in its
+ // lifetime. An attempt to bind a buffer object to the other
+ // target will generate an INVALID_OPERATION error, and the
+ // current binding will remain untouched.
+ const bool isWebGL = (qGuiApp->platformName().compare(QLatin1String("webgl")) == 0
+ || qGuiApp->platformName().compare(QLatin1String("wasm")) == 0);
+ m_separateIndexBuffer = isWebGL;
}
m_sg->renderContextInitialized(this);
@@ -377,7 +389,7 @@ QString QSGDefaultRenderContext::fontKey(const QRawFont &font)
{
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName = fe->faceId().filename;
+ QByteArray keyName = fe->faceId().filename + ' ' + QByteArray::number(fe->faceId().index);
if (font.style() != QFont::StyleNormal)
keyName += QByteArray(" I");
if (font.weight() != QFont::Normal)
@@ -417,17 +429,7 @@ QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context)
bool QSGDefaultRenderContext::separateIndexBuffer() const
{
- if (m_rhi)
- return true;
-
- // WebGL: A given WebGLBuffer object may only be bound to one of
- // the ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target in its
- // lifetime. An attempt to bind a buffer object to the other
- // target will generate an INVALID_OPERATION error, and the
- // current binding will remain untouched.
- static const bool isWebGL = (qGuiApp->platformName().compare(QLatin1String("webgl")) == 0
- || qGuiApp->platformName().compare(QLatin1String("wasm")) == 0);
- return isWebGL;
+ return m_separateIndexBuffer;
}
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font)
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 97ed681f9a..be83f5a9f5 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -69,6 +69,7 @@ class QSGMaterialRhiShader;
class QOpenGLFramebufferObject;
class QSGDepthStencilBufferManager;
class QSGDepthStencilBuffer;
+class QSurface;
namespace QSGOpenGLAtlasTexture {
class Manager;
@@ -179,6 +180,7 @@ protected:
QRhiCommandBuffer *m_currentFrameCommandBuffer;
QRhiRenderPassDescriptor *m_currentFrameRenderPass;
qreal m_currentDevicePixelRatio;
+ bool m_separateIndexBuffer;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp
index 6422a252d9..b179838576 100644
--- a/src/quick/scenegraph/qsgdefaultspritenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp
@@ -40,7 +40,7 @@
#include "qsgdefaultspritenode_p.h"
#include <QtQuick/QSGMaterial>
-#include <QtGui/QOpenGLShaderProgram>
+#include <QOpenGLShaderProgram>
QT_BEGIN_NAMESPACE
@@ -199,7 +199,7 @@ void SpriteMaterialRhiShader::updateSampledImage(RenderState &state, int binding
QQuickSpriteMaterial *mat = static_cast<QQuickSpriteMaterial *>(newMaterial);
QSGTexture *t = mat->texture;
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index e8e9f76d04..a25daa6070 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -39,7 +39,7 @@
#include "qsgdistancefieldglyphnode_p_p.h"
#include "qsgrhidistancefieldglyphcache_p.h"
-#include <QtGui/qopenglfunctions.h>
+#include <qopenglfunctions.h>
#include <QtGui/qsurface.h>
#include <QtGui/qwindow.h>
#include <qmath.h>
diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
index b6b6f3b057..04dd6d64ad 100644
--- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
@@ -45,16 +45,17 @@
#include <QtQml/qqmlfile.h>
#include <QtGui/private/qdistancefield_p.h>
-#include <QtGui/private/qopenglcontext_p.h>
+#include <private/qopenglcontext_p.h>
#include <QtQml/private/qqmlglobal_p.h>
#include <qopenglfunctions.h>
+#include <qopenglversionfunctionsfactory.h>
#include <qopenglframebufferobject.h>
#include <qmath.h>
#include "qsgcontext_p.h"
-#if !defined(QT_OPENGL_ES_2)
-#include <QtGui/qopenglfunctions_3_2_core.h>
+#if !QT_CONFIG(opengles2)
+#include <qopenglfunctions_3_2_core.h>
#endif
QT_BEGIN_NAMESPACE
@@ -77,7 +78,7 @@ QSGOpenGLDistanceFieldGlyphCache::QSGOpenGLDistanceFieldGlyphCache(QOpenGLContex
, m_blitBuffer(QOpenGLBuffer::VertexBuffer)
, m_fboGuard(nullptr)
, m_funcs(c->functions())
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
, m_coreFuncs(nullptr)
#endif
{
@@ -222,7 +223,7 @@ void QSGOpenGLDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &
}
}
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
#else
const GLenum format = GL_ALPHA;
@@ -291,7 +292,7 @@ void QSGOpenGLDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo,
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
if (!QOpenGLContext::currentContext()->isOpenGLES())
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
const GLint internalFormat = isCoreProfile() ? GL_R8 : GL_ALPHA;
@@ -337,13 +338,13 @@ void QSGOpenGLDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int w
updateTexture(oldTexture, texInfo->texture, texInfo->size);
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
if (isCoreProfile() && !useTextureResizeWorkaround()) {
// For an OpenGL Core Profile we can use http://www.opengl.org/wiki/Framebuffer#Blitting
// to efficiently copy the contents of the old texture to the new texture
// TODO: Use ARB_copy_image if available of if we have >=4.3 context
if (!m_coreFuncs) {
- m_coreFuncs = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ m_coreFuncs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx);
Q_ASSERT(m_coreFuncs);
m_coreFuncs->initializeOpenGLFunctions();
}
@@ -388,7 +389,7 @@ void QSGOpenGLDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int w
m_funcs->glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
m_funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
#else
const GLenum format = GL_ALPHA;
@@ -434,7 +435,7 @@ void QSGOpenGLDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int w
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
if (!ctx->isOpenGLES())
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
index 66d1b52f86..b095fc94a0 100644
--- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
@@ -52,17 +52,17 @@
//
#include "qsgadaptationlayer_p.h"
-#include <QtGui/qopenglfunctions.h>
+#include <qopenglfunctions.h>
#include <qopenglshaderprogram.h>
#include <qopenglbuffer.h>
#include <qopenglvertexarrayobject.h>
-#include <QtGui/private/qopenglengineshadersource_p.h>
+#include <private/qopenglengineshadersource_p.h>
#include <private/qsgareaallocator_p.h>
QT_BEGIN_NAMESPACE
class QOpenGLSharedResourceGuard;
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
class QOpenGLFunctions_3_2_Core;
#endif
@@ -154,7 +154,7 @@ private:
QOpenGLSharedResourceGuard *m_fboGuard;
QOpenGLFunctions *m_funcs;
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
QOpenGLFunctions_3_2_Core *m_coreFuncs;
#endif
};
diff --git a/src/quick/scenegraph/qsgopengllayer.cpp b/src/quick/scenegraph/qsgopengllayer.cpp
index ae5032231d..c585cd05f8 100644
--- a/src/quick/scenegraph/qsgopengllayer.cpp
+++ b/src/quick/scenegraph/qsgopengllayer.cpp
@@ -42,9 +42,9 @@
#include <private/qsgrenderer_p.h>
#include <private/qsgdefaultrendercontext_p.h>
-#include <QtGui/QOpenGLFramebufferObject>
-#include <QtGui/QOpenGLFunctions>
-#include <QtGui/private/qopenglextensions_p.h>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFunctions>
+#include <private/qopenglextensions_p.h>
#include <QtQuick/private/qsgdepthstencilbuffer_p.h>
@@ -89,7 +89,7 @@ namespace
}
QSGOpenGLLayer::QSGOpenGLLayer(QSGRenderContext *context)
- : QSGLayer(*(new QSGOpenGLLayerPrivate))
+ : QSGLayer(*(new QSGTexturePrivate))
, m_item(nullptr)
, m_device_pixel_ratio(1)
, m_format(GL_RGBA)
@@ -141,10 +141,9 @@ int QSGOpenGLLayer::textureId() const
return m_fbo ? m_fbo->texture() : 0;
}
-int QSGOpenGLLayerPrivate::comparisonKey() const
+int QSGOpenGLLayer::comparisonKey() const
{
- Q_Q(const QSGOpenGLLayer);
- return q->m_fbo ? q->m_fbo->texture() : 0;
+ return m_fbo ? m_fbo->texture() : 0;
}
bool QSGOpenGLLayer::hasAlphaChannel() const
diff --git a/src/quick/scenegraph/qsgopengllayer_p.h b/src/quick/scenegraph/qsgopengllayer_p.h
index c6246843e2..e54571e311 100644
--- a/src/quick/scenegraph/qsgopengllayer_p.h
+++ b/src/quick/scenegraph/qsgopengllayer_p.h
@@ -62,11 +62,9 @@ QT_BEGIN_NAMESPACE
class QOpenGLFramebufferObject;
class QSGDepthStencilBuffer;
class QSGDefaultRenderContext;
-class QSGOpenGLLayerPrivate;
class Q_QUICK_PRIVATE_EXPORT QSGOpenGLLayer : public QSGLayer
{
- Q_DECLARE_PRIVATE(QSGOpenGLLayer)
Q_OBJECT
public:
QSGOpenGLLayer(QSGRenderContext *context);
@@ -92,6 +90,7 @@ public:
bool hasMipmaps() const override;
int textureId() const override;
QSize textureSize() const override { return m_size; }
+ int comparisonKey() const override;
GLenum format() const { return m_format; }
void setFormat(GLenum format) override;
@@ -157,13 +156,6 @@ private:
uint m_mirrorVertical : 1;
};
-class QSGOpenGLLayerPrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGOpenGLLayer)
-public:
- int comparisonKey() const override;
-};
-
QT_END_NAMESPACE
#endif // QSGOPENGLLAYER_P_H
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 94f15b55d4..aa956fda9e 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -39,7 +39,6 @@
#include "qsgrenderloop_p.h"
#include "qsgthreadedrenderloop_p.h"
-#include "qsgwindowsrenderloop_p.h"
#include "qsgrhisupport_p.h"
#include <private/qquickanimatorcontroller_p.h>
@@ -57,6 +56,7 @@
#include <QtQuick/QQuickWindow>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <private/qquickprofiler_p.h>
@@ -65,7 +65,7 @@
#include <private/qsgrhishadereffectnode_p.h>
#if QT_CONFIG(opengl)
-#include <QtGui/QOpenGLContext>
+#include <QOpenGLContext>
#if QT_CONFIG(quick_shadereffect)
#include <private/qquickopenglshadereffectnode_p.h>
#endif
@@ -125,7 +125,7 @@ void QSGRenderLoop::cleanup()
s_instance = nullptr;
#ifdef ENABLE_DEFAULT_BACKEND
- QSGRhiSupport::instance()->cleanup();
+ QSGRhiSupport::cleanupVulkanInstance();
QSGRhiProfileConnection::instance()->cleanup();
#endif
}
@@ -237,13 +237,10 @@ QSGRenderLoop *QSGRenderLoop::instance()
} else {
loopType = BasicRenderLoop;
#ifdef Q_OS_WIN
- // With desktop OpenGL (opengl32.dll), use threaded. Otherwise (ANGLE) use windows.
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
&& QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))
{
loopType = ThreadedRenderLoop;
- } else {
- loopType = WindowsRenderLoop;
}
#else
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))
@@ -270,10 +267,6 @@ QSGRenderLoop *QSGRenderLoop::instance()
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
@@ -287,12 +280,14 @@ QSGRenderLoop *QSGRenderLoop::instance()
if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_RENDER_LOOP"))) {
const QByteArray loopName = qgetenv("QSG_RENDER_LOOP");
- if (loopName == "windows")
- loopType = WindowsRenderLoop;
- else if (loopName == "basic")
+ if (loopName == "windows") {
+ qWarning("The 'windows' render loop is no longer supported. Using 'basic' instead.");
+ loopType = BasicRenderLoop;
+ } else if (loopName == "basic") {
loopType = BasicRenderLoop;
- else if (loopName == "threaded")
+ } else if (loopName == "threaded") {
loopType = ThreadedRenderLoop;
+ }
}
switch (loopType) {
@@ -302,12 +297,8 @@ QSGRenderLoop *QSGRenderLoop::instance()
s_instance = new QSGThreadedRenderLoop();
break;
#endif
- case WindowsRenderLoop:
- qCDebug(QSG_LOG_INFO, "windows render loop");
- s_instance = new QSGWindowsRenderLoop();
- break;
default:
- qCDebug(QSG_LOG_INFO, "QSG: basic render loop");
+ qCDebug(QSG_LOG_INFO, "basic render loop");
s_instance = new QSGGuiThreadRenderLoop();
break;
}
@@ -473,6 +464,15 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
void QSGGuiThreadRenderLoop::releaseSwapchain(QQuickWindow *window)
{
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
+
+ // Unlike the threaded render loop, this one reuses the same rendercontext
+ // for all QQuickWindows for the entire lifetime of the render loop.
+ // Therefore the renderer, if there is one, needs to be notified about the
+ // destruction of certain resources because they may be referenced from
+ // per-rendercontext data structures.
+ if (wd->renderer)
+ wd->renderer->invalidatePipelineCacheDependency(wd->rpDescForSwapchain);
+
delete wd->rpDescForSwapchain;
wd->rpDescForSwapchain = nullptr;
delete wd->swapchain;
@@ -703,6 +703,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
emit window->afterAnimating();
+ emit window->beforeFrameBegin();
+
// Begin the frame before syncing -> sync is where we may invoke
// updatePaintNode() on the items and they may want to do resource updates.
// Also relevant for applications that connect to the before/afterSynchronizing
@@ -798,6 +800,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (needsPresent)
cd->fireFrameSwapped();
+ emit window->afterFrameEnd();
+
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 9fd0ab02f5..e9357f2061 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -126,8 +126,7 @@ private:
enum QSGRenderLoopType
{
BasicRenderLoop,
- ThreadedRenderLoop,
- WindowsRenderLoop
+ ThreadedRenderLoop
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index 952279a3ff..003ffaf5ea 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -44,7 +44,7 @@
#include <private/qsgdefaultrendercontext_p.h>
QSGRhiLayer::QSGRhiLayer(QSGRenderContext *context)
- : QSGLayer(*(new QSGRhiLayerPrivate))
+ : QSGLayer(*(new QSGTexturePrivate))
, m_mipmap(false)
, m_live(true)
, m_recursive(false)
@@ -72,10 +72,9 @@ void QSGRhiLayer::invalidated()
m_renderer = nullptr;
}
-int QSGRhiLayerPrivate::comparisonKey() const
+int QSGRhiLayer::comparisonKey() const
{
- Q_Q(const QSGRhiLayer);
- return int(qintptr(q->m_texture));
+ return int(qintptr(m_texture));
}
bool QSGRhiLayer::hasAlphaChannel() const
@@ -99,13 +98,12 @@ void QSGRhiLayer::bind()
Q_ASSERT_X(false, "QSGRhiLayer::bind()", "Not implemented for RHI");
}
-QRhiTexture *QSGRhiLayerPrivate::rhiTexture() const
+QRhiTexture *QSGRhiLayer::rhiTexture() const
{
- Q_Q(const QSGRhiLayer);
- return q->m_texture;
+ return m_texture;
}
-void QSGRhiLayerPrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void QSGRhiLayer::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
Q_UNUSED(rhi);
Q_UNUSED(resourceUpdates);
@@ -227,8 +225,12 @@ void QSGRhiLayer::releaseResources()
delete m_rt;
m_rt = nullptr;
- delete m_rtRp;
- m_rtRp = nullptr;
+ if (m_rtRp) {
+ if (m_renderer)
+ m_renderer->invalidatePipelineCacheDependency(m_rtRp);
+ delete m_rtRp;
+ m_rtRp = nullptr;
+ }
delete m_ds;
m_ds = nullptr;
diff --git a/src/quick/scenegraph/qsgrhilayer_p.h b/src/quick/scenegraph/qsgrhilayer_p.h
index 6c4953ce17..ba0567c737 100644
--- a/src/quick/scenegraph/qsgrhilayer_p.h
+++ b/src/quick/scenegraph/qsgrhilayer_p.h
@@ -58,12 +58,11 @@
QT_BEGIN_NAMESPACE
class QSGDefaultRenderContext;
-class QSGRhiLayerPrivate;
class Q_QUICK_PRIVATE_EXPORT QSGRhiLayer : public QSGLayer
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QSGRhiLayer)
+
public:
QSGRhiLayer(QSGRenderContext *context);
~QSGRhiLayer();
@@ -76,6 +75,9 @@ public:
void bind() override;
int textureId() const override;
+ int comparisonKey() const override;
+ QRhiTexture *rhiTexture() const override;
+ void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
void setItem(QSGNode *item) override;
void setRect(const QRectF &rect) override;
@@ -129,15 +131,6 @@ private:
uint m_mirrorVertical : 1;
};
-class QSGRhiLayerPrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGRhiLayer)
-public:
- int comparisonKey() const override;
- QRhiTexture *rhiTexture() const override;
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
-};
-
QT_END_NAMESPACE
#endif // QSGRHILAYER_P_H
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index e86dae7c09..5d3b158de8 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -185,9 +185,9 @@ struct QSGRhiShaderMaterialTypeCache
QHash<Key, QSGMaterialType *> m_types;
};
-uint qHash(const QSGRhiShaderMaterialTypeCache::Key &key, uint seed = 0)
+size_t qHash(const QSGRhiShaderMaterialTypeCache::Key &key, uint seed = 0)
{
- uint hash = seed;
+ size_t hash = seed;
for (int i = 0; i < 2; ++i)
hash = hash * 31337 + qHash(key.blob[i]);
return hash;
@@ -393,7 +393,7 @@ void QSGRhiShaderEffectMaterialShader::updateSampledImage(RenderState &state, in
QSGTextureProvider *tp = mat->m_textureProviders.at(binding);
if (tp) {
if (QSGTexture *t = tp->texture()) {
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
if (t->isAtlasTexture() && !mat->m_geometryUsesTextureSubRect) {
// Why the hassle with the batch: while removedFromAtlas() is
// able to operate with its own resource update batch (which is
@@ -402,9 +402,7 @@ void QSGRhiShaderEffectMaterialShader::updateSampledImage(RenderState &state, in
// committed operations to state.resourceUpdateBatch()... The
// only safe way then is to use the same batch the atlas'
// updateRhiTexture() used.
- t->setWorkResourceUpdateBatch(state.resourceUpdateBatch());
- QSGTexture *newTexture = t->removedFromAtlas();
- t->setWorkResourceUpdateBatch(nullptr);
+ QSGTexture *newTexture = t->removedFromAtlas(state.resourceUpdateBatch());
if (newTexture)
t = newTexture;
}
@@ -421,7 +419,7 @@ void QSGRhiShaderEffectMaterialShader::updateSampledImage(RenderState &state, in
QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
mat->m_dummyTexture->setImage(img);
- mat->m_dummyTexture->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ mat->m_dummyTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
}
*texture = mat->m_dummyTexture;
}
@@ -570,10 +568,8 @@ void QSGRhiShaderEffectMaterial::updateTextureProviders(bool layoutChange)
}
}
-QSGRhiShaderEffectNode::QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc, QSGRhiGuiThreadShaderEffectManager *mgr)
- : QSGShaderEffectNode(mgr),
- m_rc(rc),
- m_mgr(mgr),
+QSGRhiShaderEffectNode::QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc)
+ : m_rc(rc),
m_material(this)
{
setFlag(UsePreprocess, true);
@@ -751,7 +747,7 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData)
void QSGRhiShaderEffectNode::handleTextureChange()
{
markDirty(QSGNode::DirtyMaterial);
- emit m_mgr->textureChanged();
+ emit textureChanged();
}
void QSGRhiShaderEffectNode::handleTextureProviderDestroyed(QObject *object)
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode_p.h b/src/quick/scenegraph/qsgrhishadereffectnode_p.h
index 26460d24b2..fb98bbf10e 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode_p.h
+++ b/src/quick/scenegraph/qsgrhishadereffectnode_p.h
@@ -59,7 +59,6 @@ QT_BEGIN_NAMESPACE
class QSGDefaultRenderContext;
class QSGPlainTexture;
class QSGRhiShaderEffectNode;
-class QSGRhiGuiThreadShaderEffectManager;
class QFileSelector;
class QSGRhiShaderLinker
@@ -121,12 +120,12 @@ public:
QSGPlainTexture *m_dummyTexture = nullptr;
};
-class QSGRhiShaderEffectNode : public QObject, public QSGShaderEffectNode
+class QSGRhiShaderEffectNode : public QSGShaderEffectNode
{
Q_OBJECT
public:
- QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc, QSGRhiGuiThreadShaderEffectManager *mgr);
+ QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc);
QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) override;
void syncMaterial(SyncData *syncData) override;
@@ -140,7 +139,6 @@ private Q_SLOTS:
private:
QSGDefaultRenderContext *m_rc;
- QSGRhiGuiThreadShaderEffectManager *m_mgr;
QSGRhiShaderEffectMaterial m_material;
};
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index 0df19c247f..b86667a972 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -42,12 +42,17 @@
#if QT_CONFIG(opengl)
# include "qsgdefaultrendercontext_p.h"
#endif
-#include <QtGui/qwindow.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+
+#include <QtGui/qwindow.h>
#if QT_CONFIG(vulkan)
#include <QtGui/qvulkaninstance.h>
#endif
+#include <QOperatingSystemVersion>
+
QT_BEGIN_NAMESPACE
#if QT_CONFIG(vulkan)
@@ -91,7 +96,7 @@ QVulkanInstance *QSGRhiSupport::vulkanInstance()
#endif
}
-void QSGRhiSupport::cleanup()
+void QSGRhiSupport::cleanupVulkanInstance()
{
#if QT_CONFIG(vulkan)
delete s_vulkanInstance;
@@ -100,7 +105,7 @@ void QSGRhiSupport::cleanup()
}
QSGRhiSupport::QSGRhiSupport()
- : m_set(false),
+ : m_settingsApplied(false),
m_enableRhi(false),
m_debugLayer(false),
m_profile(false),
@@ -111,7 +116,7 @@ QSGRhiSupport::QSGRhiSupport()
void QSGRhiSupport::applySettings()
{
- m_set = true;
+ m_settingsApplied = 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
@@ -121,7 +126,7 @@ void QSGRhiSupport::applySettings()
if (m_requested.valid) {
// explicit rhi backend request from C++ (e.g. via QQuickWindow)
- m_enableRhi = m_requested.rhi;
+ m_enableRhi = true;
switch (m_requested.api) {
case QSGRendererInterface::OpenGLRhi:
m_rhiBackend = QRhi::OpenGLES2;
@@ -143,8 +148,11 @@ void QSGRhiSupport::applySettings()
break;
}
} else {
+
+ // New Qt 6 default: enable RHI, unless QSG_NO_RHI is set
+ m_enableRhi = !qEnvironmentVariableIsSet("QSG_NO_RHI");
+
// check env.vars., fall back to platform-specific defaults when backend is not set
- m_enableRhi = uint(qEnvironmentVariableIntValue("QSG_RHI"));
const QByteArray rhiBackend = qgetenv("QSG_RHI_BACKEND");
if (rhiBackend == QByteArrayLiteral("gl")
|| rhiBackend == QByteArrayLiteral("gles2")
@@ -172,12 +180,23 @@ void QSGRhiSupport::applySettings()
m_rhiBackend = QRhi::OpenGLES2;
#endif
// Vulkan has to be requested explicitly
+
+ // Now that we established our initial choice, we may want to opt
+ // for another backend under certain special circumstances.
+ if (m_enableRhi) // guard because this may do actual graphics calls on some platforms
+ adjustToPlatformQuirks();
}
}
if (!m_enableRhi)
return;
+ // At this point the RHI backend is fixed, it cannot be changed once we
+ // return from this function. This is because things like the QWindow
+ // (QQuickWindow) may depend on the graphics API as well (surfaceType
+ // f.ex.), and all that is based on what we report from here. So further
+ // adjustments are not possible (or, at minimum, not safe and portable).
+
// validation layers (Vulkan) or debug layer (D3D)
m_debugLayer = uint(qEnvironmentVariableIntValue("QSG_RHI_DEBUG_LAYER"));
@@ -200,6 +219,39 @@ void QSGRhiSupport::applySettings()
qCDebug(QSG_LOG_INFO, "Prioritizing software renderers");
}
+void QSGRhiSupport::adjustToPlatformQuirks()
+{
+#if defined(Q_OS_WIN)
+ // Temporary Windows 7 workaround: no D3D. Just stick with OpenGL like Qt 5
+ // would. Can be removed when Win 7 support is finally dropped from Qt 6.
+ // (but as long as we have a Win 7 CI, this is mandatory)
+ if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) {
+ if (m_rhiBackend == QRhi::D3D11) {
+ qCDebug(QSG_LOG_INFO, "D3D on Windows 7 is not supported. Trying OpenGL instead.");
+ m_rhiBackend = QRhi::OpenGLES2;
+ }
+ }
+#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+
+ // ### For now just create a throwaway QRhi instance. This will be replaced
+ // by a more lightweight way, once a helper function is added gui/rhi.
+
+ // A macOS VM may not have Metal support at all. We have to decide at this
+ // point, it will be too late afterwards, and the only way is to see if
+ // MTLCreateSystemDefaultDevice succeeds.
+ if (m_rhiBackend == QRhi::Metal) {
+ QRhiMetalInitParams rhiParams;
+ QRhi *tempRhi = QRhi::create(m_rhiBackend, &rhiParams, {});
+ if (!tempRhi) {
+ m_rhiBackend = QRhi::OpenGLES2;
+ qCDebug(QSG_LOG_INFO, "Metal does not seem to be supported. Falling back to OpenGL.");
+ } else {
+ delete tempRhi;
+ }
+ }
+#endif
+}
+
QSGRhiSupport *QSGRhiSupport::staticInst()
{
static QSGRhiSupport inst;
@@ -217,20 +269,15 @@ void QSGRhiSupport::configure(QSGRendererInterface::GraphicsApi api)
{
Q_ASSERT(QSGRendererInterface::isApiRhiBased(api));
QSGRhiSupport *inst = staticInst();
- if (inst->m_set) {
- qWarning("QRhi is already configured, request ignored");
- return;
- }
inst->m_requested.valid = true;
inst->m_requested.api = api;
- inst->m_requested.rhi = true;
inst->applySettings();
}
QSGRhiSupport *QSGRhiSupport::instance()
{
QSGRhiSupport *inst = staticInst();
- if (!inst->m_set)
+ if (!inst->m_settingsApplied)
inst->applySettings();
return inst;
}
@@ -483,11 +530,10 @@ QOffscreenSurface *QSGRhiSupport::maybeCreateOffscreenSurface(QWindow *window)
}
// must be called on the render thread
-QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurface)
+QRhi *QSGRhiSupport::createRhi(QQuickWindow *window, QOffscreenSurface *offscreenSurface)
{
-#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan)
- Q_UNUSED(window);
-#endif
+ const QQuickGraphicsDevice &customDev(QQuickWindowPrivate::get(window)->customDeviceObjects);
+ const QQuickGraphicsDevicePrivate *customDevD = QQuickGraphicsDevicePrivate::get(&customDev);
QRhi *rhi = nullptr;
@@ -509,7 +555,14 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhiParams.format = format;
rhiParams.fallbackSurface = offscreenSurface;
rhiParams.window = window;
- rhi = QRhi::create(backend, &rhiParams, flags);
+ if (customDevD->type == QQuickGraphicsDevicePrivate::Type::OpenGLContext) {
+ QRhiGles2NativeHandles importDev;
+ importDev.context = customDevD->u.context;
+ qCDebug(QSG_LOG_INFO, "Using existing QOpenGLContext %p", importDev.context);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else {
+ rhi = QRhi::create(backend, &rhiParams, flags);
+ }
}
#else
Q_UNUSED(offscreenSurface);
@@ -520,8 +573,19 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhiParams.inst = window->vulkanInstance();
if (!rhiParams.inst)
qWarning("No QVulkanInstance set for QQuickWindow, this is wrong.");
- rhiParams.window = window;
- rhi = QRhi::create(backend, &rhiParams, flags);
+ if (window->handle()) // only used for vkGetPhysicalDeviceSurfaceSupportKHR and that implies having a valid native window
+ rhiParams.window = window;
+ if (customDevD->type == QQuickGraphicsDevicePrivate::Type::DeviceObjects) {
+ QRhiVulkanNativeHandles importDev;
+ importDev.physDev = reinterpret_cast<VkPhysicalDevice>(customDevD->u.deviceObjects.physicalDevice);
+ importDev.dev = reinterpret_cast<VkDevice>(customDevD->u.deviceObjects.device);
+ importDev.gfxQueueFamilyIdx = customDevD->u.deviceObjects.queueFamilyIndex;
+ qCDebug(QSG_LOG_INFO, "Using existing native Vulkan physical device %p device %p graphics queue family index %d",
+ importDev.physDev, importDev.dev, importDev.gfxQueueFamilyIdx);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else {
+ rhi = QRhi::create(backend, &rhiParams, flags);
+ }
}
#endif
#ifdef Q_OS_WIN
@@ -532,13 +596,31 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhiParams.framesUntilKillingDeviceViaTdr = m_killDeviceFrameCount;
rhiParams.repeatDeviceKill = true;
}
- rhi = QRhi::create(backend, &rhiParams, flags);
+ if (customDevD->type == QQuickGraphicsDevicePrivate::Type::DeviceAndContext) {
+ QRhiD3D11NativeHandles importDev;
+ importDev.dev = customDevD->u.deviceAndContext.device;
+ importDev.context = customDevD->u.deviceAndContext.context;
+ qCDebug(QSG_LOG_INFO, "Using existing native D3D11 device %p and context %p",
+ importDev.dev, importDev.context);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else {
+ rhi = QRhi::create(backend, &rhiParams, flags);
+ }
}
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (backend == QRhi::Metal) {
QRhiMetalInitParams rhiParams;
- rhi = QRhi::create(backend, &rhiParams, flags);
+ if (customDevD->type == QQuickGraphicsDevicePrivate::Type::DeviceAndCommandQueue) {
+ QRhiMetalNativeHandles importDev;
+ importDev.dev = customDevD->u.deviceAndCommandQueue.device;
+ importDev.cmdQueue = customDevD->u.deviceAndCommandQueue.cmdQueue;
+ qCDebug(QSG_LOG_INFO, "Using existing native Metal device %p and command queue %p",
+ importDev.dev, importDev.cmdQueue);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else {
+ rhi = QRhi::create(backend, &rhiParams, flags);
+ }
}
#endif
diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h
index 0a95a09ad2..ec7ebbbfd1 100644
--- a/src/quick/scenegraph/qsgrhisupport_p.h
+++ b/src/quick/scenegraph/qsgrhisupport_p.h
@@ -91,7 +91,7 @@ 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
// creating a render loop. A well-written render loop sets up its QRhi and
-// related machinery based on the settings queriable from here.
+// related machinery using the helper functions in here.
//
// cleanup() must be called to perform global (not per thread) cleanup, such
// as, destroying the QVulkanInstance (if one was created in vulkanInstance()).
@@ -99,13 +99,13 @@ class QOffscreenSurface;
// In addition, the class provides handy conversion and query stuff for the
// renderloop and the QSGRendererInterface implementations.
//
-class QSGRhiSupport
+class Q_QUICK_PRIVATE_EXPORT QSGRhiSupport
{
public:
static void configure(QSGRendererInterface::GraphicsApi api);
static QSGRhiSupport *instance();
static QVulkanInstance *vulkanInstance();
- void cleanup();
+ static void cleanupVulkanInstance();
bool isRhiEnabled() const { return m_enableRhi; }
QRhi::Implementation rhiBackend() const { return m_rhiBackend; }
@@ -124,7 +124,7 @@ public:
int chooseSampleCountForWindowWithRhi(QWindow *window, QRhi *rhi);
QOffscreenSurface *maybeCreateOffscreenSurface(QWindow *window);
- QRhi *createRhi(QWindow *window, QOffscreenSurface *offscreenSurface);
+ QRhi *createRhi(QQuickWindow *window, QOffscreenSurface *offscreenSurface);
QImage grabAndBlockInCurrentFrame(QRhi *rhi, QRhiSwapChain *swapchain);
@@ -133,15 +133,15 @@ public:
private:
QSGRhiSupport();
void applySettings();
+ void adjustToPlatformQuirks();
static QSGRhiSupport *staticInst();
struct {
bool valid = false;
QSGRendererInterface::GraphicsApi api;
- uint rhi : 1;
} m_requested;
QRhi::Implementation m_rhiBackend = QRhi::Null;
int m_killDeviceFrameCount;
- uint m_set : 1;
+ uint m_settingsApplied : 1;
uint m_enableRhi : 1;
uint m_debugLayer : 1;
uint m_profile : 1;
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 9b288029b4..0a62f85388 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -53,6 +53,7 @@
#include <QtQuick/QQuickWindow>
#include <private/qquickwindow_p.h>
+#include <private/qquickitem_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
@@ -712,6 +713,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (!grabRequested)
pendingUpdate = 0;
+ emit window->beforeFrameBegin();
+
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
// Begin the frame before syncing -> sync is where we may invoke
// updatePaintNode() on the items and they may want to do resource updates.
@@ -790,12 +793,16 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
&& !(pendingUpdate & RepaintRequest) // may have been set in sync()
&& sgrc->isValid()
&& !grabRequested
- && (gl || (rhi && !rhi->isRecordingFrame())))
+ && (gl || rhi))
{
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
+ if (rhi && rhi->isRecordingFrame())
+ rhi->endFrame(cd->swapchain, QRhi::SkipPresent);
+
int waitTime = vsyncDelta - (int) waitTimer.elapsed();
if (waitTime > 0)
msleep(waitTime);
+
return;
}
@@ -882,6 +889,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering done");
+ emit window->afterFrameEnd();
+
// Though it would be more correct to put this block directly after
// fireFrameSwapped in the if (current) branch above, we don't do
// that to avoid blocking the GUI thread in the case where it
@@ -1404,7 +1413,7 @@ bool QSGThreadedRenderLoop::eventFilter(QObject *watched, QEvent *event)
QQuickWindow *window = qobject_cast<QQuickWindow *>(watched);
if (window) {
Window *w = windowFor(m_windows, window);
- if (w) {
+ if (w && w->thread->isRunning()) {
w->thread->mutex.lock();
w->thread->postEvent(new WMReleaseSwapchainEvent(window));
w->thread->waitCondition.wait(&w->thread->mutex);
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index e5e9fa8b48..d805c91d79 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/QThread>
-#include <QtGui/QOpenGLContext>
+#include <QOpenGLContext>
#include <private/qsgcontext_p.h>
#include "qsgrenderloop_p.h"
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
deleted file mode 100644
index 20d7c4557f..0000000000
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgwindowsrenderloop_p.h"
-#include <QtCore/QCoreApplication>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QThread>
-
-#include <QtGui/QScreen>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QOffscreenSurface>
-
-#include <QtQuick/private/qsgcontext_p.h>
-#include <QtQuick/private/qquickwindow_p.h>
-#include <QtQuick/private/qsgrenderer_p.h>
-#include <QtQuick/private/qsgdefaultrendercontext_p.h>
-
-#include <QtQuick/QQuickWindow>
-
-#include <private/qquickprofiler_p.h>
-#include <private/qquickanimatorcontroller_p.h>
-
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
-#include <private/qquickopenglshadereffectnode_p.h>
-#endif
-
-#include <qtquick_tracepoints_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Single-threaded render loop with a custom animation driver. Like a
-// combination of basic+threaded but still working on the main thread. Only
-// compatible with direct OpenGL, no RHI support here.
-
-extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
-
-#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP, x)
-
-static QElapsedTimer qsg_render_timer;
-#define QSG_LOG_TIME_SAMPLE(sampleName) \
- qint64 sampleName = 0; \
- if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled()) \
- sampleName = qsg_render_timer.nsecsElapsed(); \
-
-#define QSG_RENDER_TIMING_SAMPLE(frameType, sampleName, position) \
- QSG_LOG_TIME_SAMPLE(sampleName) \
- Q_QUICK_SG_PROFILE_RECORD(frameType, position);
-
-
-QSGWindowsRenderLoop::QSGWindowsRenderLoop()
- : m_gl(nullptr)
- , m_sg(QSGContext::createDefaultContext())
- , m_updateTimer(0)
- , m_animationTimer(0)
-{
- m_rc = static_cast<QSGDefaultRenderContext *>(m_sg->createRenderContext());
-
- m_vsyncDelta = 1000 / QGuiApplication::primaryScreen()->refreshRate();
- if (m_vsyncDelta <= 0)
- m_vsyncDelta = 16;
-
- RLDEBUG("Windows Render Loop created");
-
- m_animationDriver = m_sg->createAnimationDriver(m_sg);
- connect(m_animationDriver, SIGNAL(started()), this, SLOT(started()));
- connect(m_animationDriver, SIGNAL(stopped()), this, SLOT(stopped()));
- m_animationDriver->install();
-
- qsg_render_timer.start();
-}
-
-QSGWindowsRenderLoop::~QSGWindowsRenderLoop()
-{
- delete m_rc;
- delete m_sg;
-}
-
-bool QSGWindowsRenderLoop::interleaveIncubation() const
-{
- return m_animationDriver->isRunning() && anyoneShowing();
-}
-
-QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow *window)
-{
- for (int i=0; i<m_windows.size(); ++i) {
- WindowData &wd = m_windows[i];
- if (wd.window == window)
- return &wd;
- }
- return nullptr;
-}
-
-void QSGWindowsRenderLoop::maybePostUpdateTimer()
-{
- if (!m_updateTimer) {
- RLDEBUG(" - posting event");
- m_updateTimer = startTimer(m_vsyncDelta / 3);
- }
-}
-
-/*
- * If no windows are showing, start ticking animations using a timer,
- * otherwise, start rendering
- */
-void QSGWindowsRenderLoop::started()
-{
- RLDEBUG("Animations started...");
- if (!anyoneShowing()) {
- if (m_animationTimer == 0) {
- RLDEBUG(" - starting non-visual animation timer");
- m_animationTimer = startTimer(m_vsyncDelta);
- }
- } else {
- maybePostUpdateTimer();
- }
-}
-
-void QSGWindowsRenderLoop::stopped()
-{
- RLDEBUG("Animations stopped...");
- if (m_animationTimer) {
- RLDEBUG(" - stopping non-visual animation timer");
- killTimer(m_animationTimer);
- m_animationTimer = 0;
- }
-}
-
-void QSGWindowsRenderLoop::show(QQuickWindow *window)
-{
- RLDEBUG("show");
- if (windowData(window) != nullptr)
- return;
-
- // This happens before the platform window is shown, but after
- // it is created. Creating the GL context takes a lot of time
- // (hundreds of milliseconds) and will prevent us from rendering
- // the first frame in time for the initial show on screen.
- // By preparing the GL context here, it is feasible (if the app
- // is quick enough) to have a perfect first frame.
- if (!m_gl) {
- RLDEBUG(" - creating GL context");
- m_gl = new QOpenGLContext();
- m_gl->setFormat(window->requestedFormat());
- m_gl->setScreen(window->screen());
- if (qt_gl_global_share_context())
- m_gl->setShareContext(qt_gl_global_share_context());
- bool created = m_gl->create();
- if (!created) {
- delete m_gl;
- m_gl = nullptr;
- handleContextCreationFailure(window);
- return;
- }
-
- QQuickWindowPrivate::get(window)->fireOpenGLContextCreated(m_gl);
-
- RLDEBUG(" - making current");
- bool current = m_gl->makeCurrent(window);
- RLDEBUG(" - initializing SG");
- if (current) {
- QSGDefaultRenderContext::InitParams rcParams;
- rcParams.sampleCount = qMax(1, m_gl->format().samples());
- rcParams.openGLContext = m_gl;
- rcParams.initialSurfacePixelSize = window->size() * window->effectiveDevicePixelRatio();
- rcParams.maybeSurface = window;
- m_rc->initialize(&rcParams);
- }
- }
-
- WindowData data;
- data.window = window;
- data.pendingUpdate = false;
- m_windows << data;
-
- RLDEBUG(" - done with show");
-}
-
-void QSGWindowsRenderLoop::hide(QQuickWindow *window)
-{
- RLDEBUG("hide");
- // The expose event is queued while hide is sent synchronously, so
- // the value might not be updated yet. (plus that the windows plugin
- // sends exposed=true when it goes to hidden, so it is doubly broken)
- // The check is made here, after the removal from m_windows, so
- // anyoneShowing will report the right value.
- if (window->isExposed())
- handleObscurity();
- if (!m_gl)
- return;
- QQuickWindowPrivate::get(window)->fireAboutToStop();
-}
-
-void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
-{
- RLDEBUG("windowDestroyed");
- for (int i=0; i<m_windows.size(); ++i) {
- if (m_windows.at(i).window == window) {
- m_windows.removeAt(i);
- break;
- }
- }
-
- hide(window);
-
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
-
- bool current = false;
- QScopedPointer<QOffscreenSurface> offscreenSurface;
- if (m_gl) {
- QSurface *surface = window;
- // There may be no platform window if the window got closed.
- if (!window->handle()) {
- offscreenSurface.reset(new QOffscreenSurface);
- offscreenSurface->setFormat(m_gl->format());
- offscreenSurface->create();
- surface = offscreenSurface.data();
- }
- current = m_gl->makeCurrent(surface);
- }
- if (Q_UNLIKELY(!current))
- RLDEBUG("cleanup without an OpenGL context");
-
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
- if (current)
- QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache();
-#endif
-
- d->cleanupNodesOnShutdown();
- if (m_windows.size() == 0) {
- d->context->invalidate();
- delete m_gl;
- m_gl = nullptr;
- } else if (m_gl && current) {
- m_gl->doneCurrent();
- }
-
- d->animationController.reset();
-}
-
-bool QSGWindowsRenderLoop::anyoneShowing() const
-{
- for (const WindowData &wd : qAsConst(m_windows))
- if (wd.window->isVisible() && wd.window->isExposed() && wd.window->size().isValid())
- return true;
- return false;
-}
-
-void QSGWindowsRenderLoop::exposureChanged(QQuickWindow *window)
-{
-
- if (windowData(window) == nullptr)
- return;
-
- if (window->isExposed() && window->isVisible()) {
-
- // Stop non-visual animation timer as we now have a window rendering
- if (m_animationTimer && anyoneShowing()) {
- RLDEBUG(" - stopping non-visual animation timer");
- killTimer(m_animationTimer);
- m_animationTimer = 0;
- }
-
- RLDEBUG("exposureChanged - exposed");
- WindowData *wd = windowData(window);
- wd->pendingUpdate = true;
-
- // If we have a pending timer and we get an expose, we need to stop it.
- // Otherwise we get two frames and two animation ticks in the same time-interval.
- if (m_updateTimer) {
- RLDEBUG(" - killing pending update timer");
- killTimer(m_updateTimer);
- m_updateTimer = 0;
- }
- render();
- } else {
- handleObscurity();
- }
-}
-
-void QSGWindowsRenderLoop::handleObscurity()
-{
- RLDEBUG("handleObscurity");
- // Potentially start the non-visual animation timer if nobody is rendering
- if (m_animationDriver->isRunning() && !anyoneShowing() && !m_animationTimer) {
- RLDEBUG(" - starting non-visual animation timer");
- m_animationTimer = startTimer(m_vsyncDelta);
- }
-}
-
-QImage QSGWindowsRenderLoop::grab(QQuickWindow *window)
-{
- RLDEBUG("grab");
- if (!m_gl)
- return QImage();
-
- m_gl->makeCurrent(window);
-
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
- d->polishItems();
- d->syncSceneGraph();
- d->renderSceneGraph(window->size());
-
- bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
- QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), alpha, alpha);
- image.setDevicePixelRatio(window->effectiveDevicePixelRatio());
- return image;
-}
-
-void QSGWindowsRenderLoop::update(QQuickWindow *window)
-{
- RLDEBUG("update");
- maybeUpdate(window);
-}
-
-void QSGWindowsRenderLoop::maybeUpdate(QQuickWindow *window)
-{
- RLDEBUG("maybeUpdate");
-
- WindowData *wd = windowData(window);
- if (!wd || !anyoneShowing())
- return;
-
- wd->pendingUpdate = true;
- maybePostUpdateTimer();
-}
-
-QSGRenderContext *QSGWindowsRenderLoop::createRenderContext(QSGContext *) const
-{
- return m_rc;
-}
-
-bool QSGWindowsRenderLoop::event(QEvent *event)
-{
- switch (event->type()) {
- case QEvent::Timer: {
- QTimerEvent *te = static_cast<QTimerEvent *>(event);
- if (te->timerId() == m_animationTimer) {
- RLDEBUG("event : animation tick while nothing is showing");
- m_animationDriver->advance();
- } else if (te->timerId() == m_updateTimer) {
- RLDEBUG("event : update");
- killTimer(m_updateTimer);
- m_updateTimer = 0;
- render();
- }
- return true; }
- default:
- break;
- }
-
- return QObject::event(event);
-}
-
-/*
- * Go through all windows we control and render them in turn.
- * Then tick animations if active.
- */
-void QSGWindowsRenderLoop::render()
-{
- RLDEBUG("render");
- Q_TRACE(QSG_render_entry);
- bool rendered = false;
- for (const WindowData &wd : qAsConst(m_windows)) {
- if (wd.pendingUpdate) {
- const_cast<WindowData &>(wd).pendingUpdate = false;
- renderWindow(wd.window);
- rendered = true;
- }
- }
-
- if (!rendered) {
- RLDEBUG("no changes, sleep");
- QThread::msleep(m_vsyncDelta);
- }
-
- Q_TRACE(QSG_render_exit);
-
- if (m_animationDriver->isRunning()) {
- RLDEBUG("advancing animations");
- QSG_LOG_TIME_SAMPLE(time_start);
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations);
- Q_TRACE(QSG_animations_entry);
- m_animationDriver->advance();
- RLDEBUG("animations advanced");
-
- qCDebug(QSG_LOG_TIME_RENDERLOOP,
- "animations ticked in %dms",
- int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
-
- Q_TRACE(QSG_animations_exit);
- Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1);
-
- // It is not given that animations triggered another maybeUpdate()
- // and thus another render pass, so to keep things running,
- // make sure there is another frame pending.
- maybePostUpdateTimer();
-
- emit timeToIncubate();
- }
-}
-
-/*
- * Render the contents of this window. First polish, then sync, render
- * then finally swap.
- *
- * Note: This render function does not implement aborting
- * the render call when sync step results in no scene graph changes,
- * like the threaded renderer does.
- */
-void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
-{
- RLDEBUG("renderWindow");
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
-
- if (!d->isRenderable())
- return;
-
- if (!m_gl->makeCurrent(window)) {
- // Check for context loss.
- if (!m_gl->isValid()) {
- d->cleanupNodesOnShutdown();
- m_rc->invalidate();
- if (m_gl->create() && m_gl->makeCurrent(window)) {
- QSGDefaultRenderContext::InitParams rcParams;
- rcParams.sampleCount = qMax(1, m_gl->format().samples());
- rcParams.openGLContext = m_gl;
- rcParams.initialSurfacePixelSize = window->size() * window->effectiveDevicePixelRatio();
- rcParams.maybeSurface = window;
- m_rc->initialize(&rcParams);
- } else {
- return;
- }
- }
- }
-
- bool lastDirtyWindow = true;
- for (int i=0; i<m_windows.size(); ++i) {
- if ( m_windows[i].pendingUpdate) {
- lastDirtyWindow = false;
- break;
- }
- }
-
- d->flushFrameSynchronousEvents();
- // Event delivery or processing has caused the window to stop rendering.
- if (!windowData(window))
- return;
-
- Q_TRACE_SCOPE(QSG_renderWindow);
-
- QSG_LOG_TIME_SAMPLE(time_start);
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
- Q_TRACE(QSG_polishItems_entry);
-
- RLDEBUG(" - polishing");
- d->polishItems();
- QSG_LOG_TIME_SAMPLE(time_polished);
- Q_TRACE(QSG_polishItems_exit);
- Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
- QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphPolishPolish);
- Q_TRACE(QSG_sync_entry);
-
- emit window->afterAnimating();
-
- RLDEBUG(" - syncing");
- d->syncSceneGraph();
- if (lastDirtyWindow)
- m_rc->endSync();
- Q_TRACE(QSG_sync_exit);
- QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
- QQuickProfiler::SceneGraphRenderLoopSync);
- Q_TRACE(QSG_render_entry);
-
- RLDEBUG(" - rendering");
- d->renderSceneGraph(window->size());
- Q_TRACE(QSG_render_exit);
- QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered,
- QQuickProfiler::SceneGraphRenderLoopRender);
- Q_TRACE(QSG_swap_entry);
-
- RLDEBUG(" - swapping");
- if (!d->customRenderStage || !d->customRenderStage->swap())
- m_gl->swapBuffers(window);
- Q_TRACE(QSG_swap_exit);
- QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped,
- QQuickProfiler::SceneGraphRenderLoopSwap);
-
- RLDEBUG(" - frameDone");
- d->fireFrameSwapped();
-
- qCDebug(QSG_LOG_TIME_RENDERLOOP()).nospace()
- << "Frame rendered with 'windows' renderloop in: " << (time_swapped - time_start) / 1000000 << "ms"
- << ", polish=" << (time_polished - time_start) / 1000000
- << ", sync=" << (time_synced - time_polished) / 1000000
- << ", render=" << (time_rendered - time_synced) / 1000000
- << ", swap=" << (time_swapped - time_rendered) / 1000000
- << " - " << window;
-
- Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphRenderLoopFrame,
- QQuickProfiler::SceneGraphRenderLoopSwap);
-}
-
-void QSGWindowsRenderLoop::releaseResources(QQuickWindow *w)
-{
- // No full invalidation of the rendercontext, just clear some caches.
- RLDEBUG("releaseResources");
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(w);
- if (d->renderer)
- d->renderer->releaseCachedResources();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qsgwindowsrenderloop_p.cpp"
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
deleted file mode 100644
index a1188fed8a..0000000000
--- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGWINDOWSRENDERLOOP_P_H
-#define QSGWINDOWSRENDERLOOP_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 <QtCore/QObject>
-#include <QtCore/QElapsedTimer>
-
-#include <QtGui/QOpenGLContext>
-
-#include "qsgrenderloop_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGRenderContext;
-class QSGDefaultRenderContext;
-
-class QSGWindowsRenderLoop : public QSGRenderLoop
-{
- Q_OBJECT
-public:
- explicit QSGWindowsRenderLoop();
- ~QSGWindowsRenderLoop();
-
- void show(QQuickWindow *window) override;
- void hide(QQuickWindow *window) override;
-
- void windowDestroyed(QQuickWindow *window) override;
-
- void exposureChanged(QQuickWindow *window) override;
- QImage grab(QQuickWindow *window) override;
-
- void update(QQuickWindow *window) override;
- void maybeUpdate(QQuickWindow *window) override;
-
- QAnimationDriver *animationDriver() const override { return m_animationDriver; }
-
- QSGContext *sceneGraphContext() const override { return m_sg; }
- QSGRenderContext *createRenderContext(QSGContext *) const override;
-
- void releaseResources(QQuickWindow *) override;
-
- void render();
- void renderWindow(QQuickWindow *window);
-
- bool event(QEvent *event) override;
- bool anyoneShowing() const;
-
- bool interleaveIncubation() const override;
-
-public Q_SLOTS:
- void started();
- void stopped();
-
-private:
- struct WindowData {
- QQuickWindow *window;
- bool pendingUpdate;
- };
-
- void handleObscurity();
- void maybePostUpdateTimer();
- WindowData *windowData(QQuickWindow *window);
-
- QList<WindowData> m_windows;
-
- QOpenGLContext *m_gl;
- QSGContext *m_sg;
- QSGDefaultRenderContext *m_rc;
-
- QAnimationDriver *m_animationDriver;
-
- int m_updateTimer;
- int m_animationTimer;
-
- int m_vsyncDelta;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGWINDOWSRENDERLOOP_P_H
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index b12f57d8ef..87146dcac8 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -12,8 +12,8 @@ HEADERS += \
$$PWD/coreapi/qsgnode.h \
$$PWD/coreapi/qsgnode_p.h \
$$PWD/coreapi/qsgnodeupdater_p.h \
- $$PWD/coreapi/qsgabstractrenderer.h \
$$PWD/coreapi/qsgabstractrenderer_p.h \
+ $$PWD/coreapi/qsgabstractrenderer_p_p.h \
$$PWD/coreapi/qsgrenderer_p.h \
$$PWD/coreapi/qsgrendernode.h \
$$PWD/coreapi/qsgrendernode_p.h \
@@ -50,14 +50,11 @@ qtConfig(opengl(es1|es2)?) {
# Util API
HEADERS += \
$$PWD/util/qsgareaallocator_p.h \
- $$PWD/util/qsgengine.h \
- $$PWD/util/qsgengine_p.h \
$$PWD/util/qsgplaintexture_p.h \
$$PWD/util/qsgsimplerectnode.h \
$$PWD/util/qsgsimpletexturenode.h \
$$PWD/util/qsgtextureprovider.h \
$$PWD/util/qsgflatcolormaterial.h \
- $$PWD/util/qsgsimplematerial.h \
$$PWD/util/qsgtexturematerial.h \
$$PWD/util/qsgtexturematerial_p.h \
$$PWD/util/qsgvertexcolormaterial.h \
@@ -67,13 +64,11 @@ HEADERS += \
SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
- $$PWD/util/qsgengine.cpp \
$$PWD/util/qsgplaintexture.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtextureprovider.cpp \
$$PWD/util/qsgflatcolormaterial.cpp \
- $$PWD/util/qsgsimplematerial.cpp \
$$PWD/util/qsgtexturematerial.cpp \
$$PWD/util/qsgvertexcolormaterial.cpp \
$$PWD/util/qsgrectanglenode.cpp \
@@ -142,8 +137,7 @@ qtConfig(opengl(es1|es2)?) {
$$PWD/util/qsgdefaultrectanglenode.cpp \
$$PWD/util/qsgdefaultimagenode.cpp \
$$PWD/util/qsgdefaultninepatchnode.cpp \
- $$PWD/qsgopengllayer.cpp \
- $$PWD/qsgwindowsrenderloop.cpp
+ $$PWD/qsgopengllayer.cpp
HEADERS += \
$$PWD/qsgdefaultglyphnode_p.h \
$$PWD/qsgopengldistancefieldglyphcache_p.h \
@@ -158,8 +152,7 @@ qtConfig(opengl(es1|es2)?) {
$$PWD/util/qsgdefaultrectanglenode_p.h \
$$PWD/util/qsgdefaultimagenode_p.h \
$$PWD/util/qsgdefaultninepatchnode_p.h \
- $$PWD/qsgopengllayer_p.h \
- $$PWD/qsgwindowsrenderloop_p.h
+ $$PWD/qsgopengllayer_p.h
qtConfig(thread) {
SOURCES += \
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
index 7b26daf541..5fc91b44d3 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
@@ -79,16 +79,15 @@ public:
void setMipmapFiltering(QSGTexture::Filtering filtering) override;
QSGTexture::Filtering mipmapFiltering() const override;
+ void setAnisotropyLevel(QSGTexture::AnisotropyLevel level) override;
+ QSGTexture::AnisotropyLevel anisotropyLevel() const override;
+
void setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode) override;
TextureCoordinatesTransformMode textureCoordinatesTransform() const override;
void setOwnsTexture(bool owns) override;
bool ownsTexture() const override;
- // QSGImageNode now being a public class does not allow any additional virtual methods. Placing these here, non-virtual.
- void setAnisotropyLevel(QSGTexture::AnisotropyLevel level);
- QSGTexture::AnisotropyLevel anisotropyLevel() const;
-
private:
QSGGeometry m_geometry;
QSGOpaqueTextureMaterial m_opaque_material;
diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
index f15ea67b46..cd8426db97 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
#define QT_MINIMUM_DYNAMIC_FBO_SIZE 64U
QSGPainterTexture::QSGPainterTexture()
- : QSGPlainTexture(*(new QSGPainterTexturePrivate))
+ : QSGPlainTexture(*(new QSGPlainTexturePrivate))
{
m_retain_image = true;
}
@@ -73,14 +73,13 @@ void QSGPainterTexture::bind()
m_dirty_rect = QRect();
}
-void QSGPainterTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void QSGPainterTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
- Q_Q(QSGPainterTexture);
- if (!q->m_dirty_rect.isNull()) {
- q->setImage(q->m_image);
- q->m_dirty_rect = QRect();
+ if (!m_dirty_rect.isNull()) {
+ setImage(m_image);
+ m_dirty_rect = QRect();
}
- QSGPlainTexturePrivate::updateRhiTexture(rhi, resourceUpdates);
+ QSGPlainTexture::commitTextureOperations(rhi, resourceUpdates);
}
QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item)
diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
index a86f7397be..b2402dc70e 100644
--- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h
@@ -64,29 +64,21 @@ QT_BEGIN_NAMESPACE
class QOpenGLFramebufferObject;
class QOpenGLPaintDevice;
class QSGDefaultRenderContext;
-class QSGPainterTexturePrivate;
class Q_QUICK_PRIVATE_EXPORT QSGPainterTexture : public QSGPlainTexture
{
- Q_DECLARE_PRIVATE(QSGPainterTexture)
public:
QSGPainterTexture();
void setDirtyRect(const QRect &rect) { m_dirty_rect = rect; }
void bind() override;
+ void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
private:
QRect m_dirty_rect;
};
-class QSGPainterTexturePrivate : public QSGPlainTexturePrivate
-{
- Q_DECLARE_PUBLIC(QSGPainterTexture)
-public:
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
-};
-
class Q_QUICK_PRIVATE_EXPORT QSGDefaultPainterNode : public QSGPainterNode
{
public:
@@ -159,9 +151,6 @@ private:
QSize m_textureSize;
QRect m_dirtyRect;
QColor m_fillColor;
-#if QT_VERSION >= 0x060000
-#warning "Remove m_contentsScale and assume 1 everywhere"
-#endif
qreal m_contentsScale;
bool m_dirtyContents : 1;
diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
index 1154c06d7c..907dbdfd0e 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer.cpp
@@ -112,7 +112,7 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte
m_functions.glGenRenderbuffers(1, &m_depthBuffer);
m_functions.glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
if (format.samples && m_functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#if defined(QT_OPENGL_ES_2)
+#if QT_CONFIG(opengles2)
m_functions.glRenderbufferStorageMultisample(GL_RENDERBUFFER, format.samples,
GL_DEPTH24_STENCIL8_OES, width, height);
#else
@@ -120,7 +120,7 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte
GL_DEPTH24_STENCIL8, width, height);
#endif
} else {
-#if defined(QT_OPENGL_ES_2)
+#if QT_CONFIG(opengles2)
m_functions.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
#else
m_functions.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
@@ -145,7 +145,7 @@ QSGDefaultDepthStencilBuffer::QSGDefaultDepthStencilBuffer(QOpenGLContext *conte
if (!m_stencilBuffer && (format.attachments & StencilAttachment)) {
m_functions.glGenRenderbuffers(1, &m_stencilBuffer);
m_functions.glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
-#ifdef QT_OPENGL_ES
+#if QT_CONFIG(opengles2)
const GLenum internalFormat = GL_STENCIL_INDEX8;
#else
const GLenum internalFormat = context->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
@@ -207,7 +207,7 @@ void QSGDepthStencilBufferManager::insertBuffer(const QSharedPointer<QSGDepthSte
m_buffers.insert(buffer->m_format, buffer.toWeakRef());
}
-uint qHash(const QSGDepthStencilBuffer::Format &format)
+size_t qHash(const QSGDepthStencilBuffer::Format &format)
{
return qHash(qMakePair(format.size.width(), format.size.height()))
^ (uint(format.samples) << 12) ^ (uint(format.attachments) << 28);
diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
index f7c6923021..dfcd854fc2 100644
--- a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
+++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h
@@ -52,8 +52,8 @@
//
#include <QtCore/qsize.h>
-#include <QtGui/private/qopenglcontext_p.h>
-#include <QtGui/private/qopenglextensions_p.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qhash.h>
@@ -140,7 +140,7 @@ private:
friend class QSGDepthStencilBuffer;
};
-extern uint qHash(const QSGDepthStencilBuffer::Format &format);
+extern size_t qHash(const QSGDepthStencilBuffer::Format &format);
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
deleted file mode 100644
index aec981871b..0000000000
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgengine_p.h"
-
-#include <QtQuick/qsgtexture.h>
-#include <private/qsgcontext_p.h>
-#include <private/qsgrenderer_p.h>
-#include <private/qsgplaintexture_p.h>
-
-#if QT_CONFIG(opengl)
-# include <QtGui/QOpenGLContext>
-# include <private/qsgdefaultrendercontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#if QT_DEPRECATED_SINCE(5, 15)
-
-/*!
- \class QSGEngine
- \brief The QSGEngine class allows low level rendering of a scene graph.
- \inmodule QtQuick
- \since 5.4
-
- \deprecated
-
- A QSGEngine can be used to render a tree of QSGNode directly on a QWindow
- or QOpenGLFramebufferObject without any integration with QML, QQuickWindow
- or QQuickItem and the convenience that they provide.
-
- This means that you must handle event propagation, animation timing,
- and node lifetime yourself.
-
- \note This class is for very low level access to an independent scene graph.
- 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
- */
-
-/*!
- \enum QSGEngine::CreateTextureOption
-
- The CreateTextureOption enums are used to customize how a texture is wrapped.
-
- \value TextureHasAlphaChannel The texture has an alpha channel and should
- be drawn using blending.
-
- \value TextureOwnsGLTexture The texture object owns the texture id and
- will delete the GL texture when the texture object is deleted.
-
- \value TextureCanUseAtlas The image can be uploaded into a texture atlas.
-
- \value TextureIsOpaque The texture object is opaque.
- */
-
-QSGEnginePrivate::QSGEnginePrivate()
- : sgContext(QSGContext::createDefaultContext())
- , sgRenderContext(sgContext.data()->createRenderContext())
-{
-}
-
-/*!
- Constructs a new QSGEngine with its \a parent
- */
-QSGEngine::QSGEngine(QObject *parent)
- : QObject(*(new QSGEnginePrivate), parent)
-{
-}
-
-/*!
- Destroys the engine
- */
-QSGEngine::~QSGEngine()
-{
-}
-
-/*!
- Initialize the engine with \a context.
-
- \warning You have to make sure that you call
- QOpenGLContext::makeCurrent() on \a context before calling this.
- */
-void QSGEngine::initialize(QOpenGLContext *context)
-{
- Q_D(QSGEngine);
-#if QT_CONFIG(opengl)
- if (context && QOpenGLContext::currentContext() != context) {
- qWarning("WARNING: The context must be current before calling QSGEngine::initialize.");
- return;
- }
-#endif
- if (d->sgRenderContext && !d->sgRenderContext->isValid()) {
- d->sgRenderContext->setAttachToGraphicsContext(false);
-#if QT_CONFIG(opengl)
- QSGDefaultRenderContext *rc = qobject_cast<QSGDefaultRenderContext *>(d->sgRenderContext.data());
- if (rc) {
- QSGDefaultRenderContext::InitParams params;
- params.sampleCount = qMax(1, context->format().samples());
- params.openGLContext = context;
- // leave the size hint and surface unset, we do not know, that's fine
- rc->initialize(&params);
- } else {
- d->sgRenderContext->initialize(nullptr);
- }
-#else
- d->sgRenderContext->initialize(nullptr);
-#endif
-#if QT_CONFIG(opengl)
- if (context)
- connect(context, &QOpenGLContext::aboutToBeDestroyed, this, &QSGEngine::invalidate);
-#endif
- }
-
-#if !QT_CONFIG(opengl)
- Q_UNUSED(context);
-#endif
-}
-
-/*!
- Invalidate the engine releasing its resources
-
- You will have to call initialize() and createRenderer() if you
- want to use it again.
- */
-void QSGEngine::invalidate()
-{
- Q_D(QSGEngine);
- d->sgRenderContext->invalidate();
-}
-
-/*!
- Returns a renderer that can be used to render a QSGNode tree
-
- You call initialize() first with the QOpenGLContext that you
- want to use with this renderer. This will return a null
- renderer otherwise.
- */
-QSGAbstractRenderer *QSGEngine::createRenderer() const
-{
- Q_D(const QSGEngine);
- if (!d->sgRenderContext->isValid())
- return nullptr;
-
- QSGRenderer *renderer = d->sgRenderContext->createRenderer();
- renderer->setCustomRenderMode(qgetenv("QSG_VISUALIZE"));
- return renderer;
-}
-
-/*!
- Creates a texture using the data of \a image
-
- Valid \a options are TextureCanUseAtlas and TextureIsOpaque.
-
- The caller takes ownership of the texture and the
- texture should only be used with this engine.
-
- \sa createTextureFromId(), QSGSimpleTextureNode::setOwnsTexture(), QQuickWindow::createTextureFromImage()
- */
-QSGTexture *QSGEngine::createTextureFromImage(const QImage &image, CreateTextureOptions options) const
-{
- Q_D(const QSGEngine);
- if (!d->sgRenderContext->isValid())
- return nullptr;
- uint flags = 0;
- if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
- if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
- return d->sgRenderContext->createTexture(image, flags);
-}
-
-/*!
- Creates a texture object that wraps the GL texture \a id uploaded with \a size
-
- Valid \a options are TextureHasAlphaChannel and TextureOwnsGLTexture
-
- The caller takes ownership of the texture object and the
- texture should only be used with this engine.
-
- \sa createTextureFromImage(), QSGSimpleTextureNode::setOwnsTexture(), QQuickWindow::createTextureFromId()
- */
-QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const
-{
- Q_D(const QSGEngine);
- if (d->sgRenderContext->isValid()) {
- QSGPlainTexture *texture = new QSGPlainTexture();
- texture->setTextureId(id);
- texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
- texture->setOwnsTexture(options & TextureOwnsGLTexture);
- texture->setTextureSize(size);
- return texture;
- }
- return nullptr;
-}
-
-/*!
- Returns the current renderer interface if there is one. Otherwise null is returned.
-
- \sa QSGRenderNode, QSGRendererInterface
- \since 5.8
- */
-QSGRendererInterface *QSGEngine::rendererInterface() const
-{
- Q_D(const QSGEngine);
- return d->sgRenderContext->isValid()
- ? d->sgRenderContext->sceneGraphContext()->rendererInterface(d->sgRenderContext.data())
- : nullptr;
-}
-
-/*!
- Creates a simple rectangle node. When the scenegraph is not initialized, the return value is null.
-
- This is cross-backend alternative to constructing a QSGSimpleRectNode directly.
-
- \since 5.8
- \sa QSGRectangleNode
- */
-QSGRectangleNode *QSGEngine::createRectangleNode() const
-{
- Q_D(const QSGEngine);
- return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createRectangleNode() : nullptr;
-}
-
-/*!
- Creates a simple image node. When the scenegraph is not initialized, the return value is null.
-
- This is cross-backend alternative to constructing a QSGSimpleTextureNode directly.
-
- \since 5.8
- \sa QSGImageNode
- */
-
-QSGImageNode *QSGEngine::createImageNode() const
-{
- Q_D(const QSGEngine);
- return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createImageNode() : nullptr;
-}
-
-/*!
- Creates a nine patch node. When the scenegraph is not initialized, the return value is null.
-
- \since 5.8
- */
-
-QSGNinePatchNode *QSGEngine::createNinePatchNode() const
-{
- Q_D(const QSGEngine);
- return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createNinePatchNode() : nullptr;
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qsgengine.cpp"
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
deleted file mode 100644
index f00b7a0b6f..0000000000
--- a/src/quick/scenegraph/util/qsgengine.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGENGINE_H
-#define QSGENGINE_H
-
-#include <QtCore/QObject>
-#include <QtQuick/qtquickglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLContext;
-class QSGAbstractRenderer;
-class QSGEnginePrivate;
-class QSGTexture;
-class QSGRendererInterface;
-class QSGRectangleNode;
-class QSGImageNode;
-class QSGNinePatchNode;
-
-#if QT_DEPRECATED_SINCE(5, 15)
-class Q_QUICK_EXPORT QSGEngine : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QSGEngine)
-public:
- enum CreateTextureOption {
- TextureHasAlphaChannel = 0x0001,
- TextureOwnsGLTexture = 0x0004,
- TextureCanUseAtlas = 0x0008,
- TextureIsOpaque = 0x0010
- };
- Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
- Q_FLAG(CreateTextureOptions)
-
- explicit QSGEngine(QObject *parent = nullptr);
- ~QSGEngine() override;
-
- QT_DEPRECATED_X("QSGEngine is going to be removed in Qt 6.0. Use QQuickRenderControl instead.")
- void initialize(QOpenGLContext *context);
- void invalidate();
-
- QSGAbstractRenderer *createRenderer() const;
- QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options = CreateTextureOption()) const;
- QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const;
- QSGRendererInterface *rendererInterface() const;
- QSGRectangleNode *createRectangleNode() const;
- QSGImageNode *createImageNode() const;
- QSGNinePatchNode *createNinePatchNode() const;
-};
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QSGENGINE_H
diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp
index b154023247..a94e3e0a5d 100644
--- a/src/quick/scenegraph/util/qsgimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgimagenode.cpp
@@ -143,6 +143,18 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn void QSGImageNode::setAnisotropyLevel(QSGTexture::AnisotropyLevel level)
+
+ Sets this image node's anistropy level to \a level.
+*/
+
+/*!
+ \fn QSGTexture::AnisotropyLevel QSGImageNode::anisotropyLevel() const
+
+ Returns this image node's anistropy level.
+*/
+
+/*!
\enum QSGImageNode::TextureCoordinatesTransformFlag
The TextureCoordinatesTransformFlag enum is used to specify the mode used
diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h
index 3b78f78a0e..45962415fc 100644
--- a/src/quick/scenegraph/util/qsgimagenode.h
+++ b/src/quick/scenegraph/util/qsgimagenode.h
@@ -67,7 +67,8 @@ public:
virtual void setMipmapFiltering(QSGTexture::Filtering filtering) = 0;
virtual QSGTexture::Filtering mipmapFiltering() const = 0;
- // ### Qt6: Add anisotropy support here, and possibly a virtual hook or another mean to extend this class.
+ virtual void setAnisotropyLevel(QSGTexture::AnisotropyLevel level) = 0;
+ virtual QSGTexture::AnisotropyLevel anisotropyLevel() const = 0;
enum TextureCoordinatesTransformFlag {
NoTransform = 0x00,
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
index 18c72286d1..aa5ee3d7b8 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
@@ -43,9 +43,9 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QtMath>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLTexture>
-#include <QtGui/QOpenGLFunctions>
+#include <QOpenGLContext>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QSurface>
@@ -222,7 +222,7 @@ void AtlasBase::bind(QSGTexture::Filtering filtering)
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(QT_OPENGL_ES_2)
+#if !QT_CONFIG(opengles2)
if (!QOpenGLContext::currentContext()->isOpenGLES())
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
@@ -295,7 +295,7 @@ Atlas::Atlas(const QSize &size)
m_internalFormat = GL_RGBA;
m_externalFormat = GL_BGRA;
-#ifndef QT_OPENGL_ES
+#if !QT_CONFIG(opengles2)
if (QOpenGLContext::currentContext()->isOpenGLES()) {
#endif
@@ -332,7 +332,7 @@ Atlas::Atlas(const QSize &size)
m_internalFormat = m_externalFormat = GL_RGBA;
}
-#ifndef QT_OPENGL_ES
+#if !QT_CONFIG(opengles2)
}
#endif
@@ -516,6 +516,19 @@ TextureBase::~TextureBase()
m_atlas->remove(this);
}
+int TextureBase::comparisonKey() const
+{
+ // We need special care here: a typical comparisonKey() implementation
+ // returns a unique result when there is no underlying texture yet. This is
+ // not quite ideal for atlasing however since textures with the same atlas
+ // should be considered equal regardless of the state of the underlying
+ // graphics resources.
+
+ // base the comparison on the atlas ptr; this way textures for the same
+ // atlas are considered equal
+ return int(qintptr(m_atlas));
+}
+
void TextureBase::bind()
{
m_atlas->bind(filtering());
@@ -542,7 +555,7 @@ Texture::~Texture()
delete m_nonatlas_texture;
}
-QSGTexture *Texture::removedFromAtlas() const
+QSGTexture *Texture::removedFromAtlas(QRhiResourceUpdateBatch *) const
{
if (m_nonatlas_texture) {
m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h b/src/quick/scenegraph/util/qsgopenglatlastexture_p.h
index f8dd7cdf02..a81c62ad63 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture_p.h
@@ -53,7 +53,7 @@
#include <QtCore/QSize>
-#include <QtGui/qopengl.h>
+#include <qopengl.h>
#include <QtQuick/QSGTexture>
#include <QtQuick/private/qsgplaintexture_p.h>
@@ -103,6 +103,7 @@ public:
void invalidate();
+ int comparisonKey() const { return m_texture_id; }
int textureId() const;
void bind(QSGTexture::Filtering filtering);
@@ -158,6 +159,7 @@ public:
TextureBase(AtlasBase *atlas, const QRect &textureRect);
~TextureBase();
+ int comparisonKey() const override;
int textureId() const override { return m_atlas->textureId(); }
bool isAtlasTexture() const override { return true; }
@@ -187,7 +189,7 @@ public:
QRect atlasSubRect() const { return m_allocated_rect; }
QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); }
- QSGTexture *removedFromAtlas() const override;
+ QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *) const override;
void releaseImage() { m_image = QImage(); }
const QImage &image() const { return m_image; }
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index f00918bb4e..037cf8c254 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -45,9 +45,9 @@
#include <QtGui/qguiapplication.h>
#include <QtGui/qpa/qplatformnativeinterface.h>
#if QT_CONFIG(opengl)
-# include <QtGui/qopenglcontext.h>
-# include <QtGui/qopenglfunctions.h>
-# include <QtGui/private/qopengltextureuploader_p.h>
+# include <qopenglcontext.h>
+# include <qopenglfunctions.h>
+# include <private/qopengltextureuploader_p.h>
# include <private/qsgdefaultrendercontext_p.h>
#endif
#include <QtGui/private/qrhi_p.h>
@@ -304,81 +304,78 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native
setTexture(t);
}
-int QSGPlainTexturePrivate::comparisonKey() const
+int QSGPlainTexture::comparisonKey() const
{
- Q_Q(const QSGPlainTexture);
-
// not textureId() as that would create an id when not yet done - that's not wanted here
- if (q->m_texture_id)
- return q->m_texture_id;
+ if (m_texture_id)
+ return m_texture_id;
- if (q->m_texture)
- return int(qintptr(q->m_texture));
+ if (m_texture)
+ return int(qintptr(m_texture));
// two textures (and so materials) with not-yet-created texture underneath are never equal
- return int(qintptr(q));
+ return int(qintptr(this));
}
-QRhiTexture *QSGPlainTexturePrivate::rhiTexture() const
+QRhiTexture *QSGPlainTexture::rhiTexture() const
{
- Q_Q(const QSGPlainTexture);
- return q->m_texture;
+ return m_texture;
}
-void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void QSGPlainTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
- Q_Q(QSGPlainTexture);
+ Q_D(QSGPlainTexture);
- const bool hasMipMaps = q->mipmapFiltering() != QSGTexture::None;
- const bool mipmappingChanged = q->m_texture && ((hasMipMaps && !q->m_texture->flags().testFlag(QRhiTexture::MipMapped)) // did not have it before
- || (!hasMipMaps && q->m_texture->flags().testFlag(QRhiTexture::MipMapped))); // does not have it anymore
+ const bool hasMipMaps = mipmapFiltering() != QSGTexture::None;
+ const bool mipmappingChanged = m_texture && ((hasMipMaps && !m_texture->flags().testFlag(QRhiTexture::MipMapped)) // did not have it before
+ || (!hasMipMaps && m_texture->flags().testFlag(QRhiTexture::MipMapped))); // does not have it anymore
- if (!q->m_dirty_texture) {
- if (!q->m_texture)
+ if (!m_dirty_texture) {
+ if (!m_texture)
return;
- if (q->m_texture && !mipmappingChanged) {
- if (hasMipMaps && !q->m_mipmaps_generated) {
- resourceUpdates->generateMips(q->m_texture);
- q->m_mipmaps_generated = true;
+ if (m_texture && !mipmappingChanged) {
+ if (hasMipMaps && !m_mipmaps_generated) {
+ resourceUpdates->generateMips(m_texture);
+ m_mipmaps_generated = true;
}
return;
}
}
- if (q->m_image.isNull()) {
- if (!q->m_dirty_texture && mipmappingChanged) {
+ if (m_image.isNull()) {
+ if (!m_dirty_texture && mipmappingChanged) {
// Full Mipmap Panic!
- if (!q->m_mipmap_warned) {
+ if (!m_mipmap_warned) {
qWarning("QSGPlainTexture: Mipmap settings changed without having image data available. "
"Call setImage() again or enable m_retain_image. "
"Falling back to previous mipmap filtering mode.");
- q->m_mipmap_warned = true;
+ m_mipmap_warned = true;
}
// leave the texture valid and rather ignore the mipmap mode change attempt
- q->setMipmapFiltering(m_last_mipmap_filter);
+ setMipmapFiltering(d->m_last_mipmap_filter);
return;
}
- if (q->m_texture && q->m_owns_texture)
- delete q->m_texture;
+ if (m_texture && m_owns_texture)
+ delete m_texture;
- q->m_texture = nullptr;
- q->m_texture_size = QSize();
- q->m_has_alpha = false;
+ m_texture = nullptr;
+ m_texture_size = QSize();
+ m_has_alpha = false;
- q->m_dirty_texture = false;
+ m_dirty_texture = false;
return;
}
- q->m_dirty_texture = false;
+ m_dirty_texture = false;
QImage tmp;
bool bgra = false;
bool needsConvert = false;
- if (q->m_image.format() == QImage::Format_RGB32 || q->m_image.format() == QImage::Format_ARGB32_Premultiplied) {
+ if (m_image.format() == QImage::Format_RGB32 || m_image.format() == QImage::Format_ARGB32_Premultiplied) {
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
if (rhi->isTextureFormatSupported(QRhiTexture::BGRA8)) {
- tmp = q->m_image;
+ tmp = m_image;
bgra = true;
} else {
needsConvert = true;
@@ -386,14 +383,14 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
#else
needsConvert = true;
#endif
- } else if (q->m_image.format() == QImage::Format_RGBX8888 || q->m_image.format() == QImage::Format_RGBA8888_Premultiplied) {
- tmp = q->m_image;
+ } else if (m_image.format() == QImage::Format_RGBX8888 || m_image.format() == QImage::Format_RGBA8888_Premultiplied) {
+ tmp = m_image;
} else {
needsConvert = true;
}
if (needsConvert)
- tmp = q->m_image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
+ tmp = m_image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
// Downscale the texture to fit inside the max texture limit if it is too big.
// It would be better if the image was already downscaled to the right size,
@@ -405,45 +402,45 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
const int max = rhi->resourceLimit(QRhi::TextureSizeMax);
if (tmp.width() > max || tmp.height() > max) {
tmp = tmp.scaled(qMin(max, tmp.width()), qMin(max, tmp.height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- q->m_texture_size = tmp.size();
+ m_texture_size = tmp.size();
}
- if ((q->mipmapFiltering() != QSGTexture::None
- || q->horizontalWrapMode() != QSGTexture::ClampToEdge
- || q->verticalWrapMode() != QSGTexture::ClampToEdge)
+ if ((mipmapFiltering() != QSGTexture::None
+ || horizontalWrapMode() != QSGTexture::ClampToEdge
+ || 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();
+ m_texture_size = tmp.size();
}
}
- bool needsRebuild = q->m_texture && q->m_texture->pixelSize() != q->m_texture_size;
+ bool needsRebuild = m_texture && m_texture->pixelSize() != m_texture_size;
if (mipmappingChanged) {
- QRhiTexture::Flags f = q->m_texture->flags();
+ QRhiTexture::Flags f = m_texture->flags();
f.setFlag(QRhiTexture::MipMapped, hasMipMaps);
f.setFlag(QRhiTexture::UsedWithGenerateMips, hasMipMaps);
- q->m_texture->setFlags(f);
+ m_texture->setFlags(f);
needsRebuild = true;
}
- if (!q->m_texture) {
+ if (!m_texture) {
QRhiTexture::Flags f;
if (hasMipMaps)
f |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
- q->m_texture = rhi->newTexture(bgra ? QRhiTexture::BGRA8 : QRhiTexture::RGBA8, q->m_texture_size, 1, f);
+ m_texture = rhi->newTexture(bgra ? QRhiTexture::BGRA8 : QRhiTexture::RGBA8, m_texture_size, 1, f);
needsRebuild = true;
}
if (needsRebuild) {
- if (!q->m_texture->build()) {
+ if (!m_texture->build()) {
qWarning("Failed to build texture for QSGPlainTexture (size %dx%d)",
- q->m_texture_size.width(), q->m_texture_size.height());
+ m_texture_size.width(), m_texture_size.height());
return;
}
}
@@ -451,18 +448,18 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
if (tmp.width() * 4 != tmp.bytesPerLine())
tmp = tmp.copy();
- resourceUpdates->uploadTexture(q->m_texture, tmp);
+ resourceUpdates->uploadTexture(m_texture, tmp);
if (hasMipMaps) {
- resourceUpdates->generateMips(q->m_texture);
- q->m_mipmaps_generated = true;
+ resourceUpdates->generateMips(m_texture);
+ m_mipmaps_generated = true;
}
- m_last_mipmap_filter = q->mipmapFiltering();
- q->m_texture_rect = QRectF(0, 0, 1, 1);
+ d->m_last_mipmap_filter = mipmapFiltering();
+ m_texture_rect = QRectF(0, 0, 1, 1);
- if (!q->m_retain_image)
- q->m_image = QImage();
+ if (!m_retain_image)
+ m_image = QImage();
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgplaintexture_p.h b/src/quick/scenegraph/util/qsgplaintexture_p.h
index 1eb0b59d2e..4bde505ec4 100644
--- a/src/quick/scenegraph/util/qsgplaintexture_p.h
+++ b/src/quick/scenegraph/util/qsgplaintexture_p.h
@@ -83,8 +83,13 @@ public:
void setImage(const QImage &image);
const QImage &image() { return m_image; }
+ int comparisonKey() const override;
+
void bind() override;
+ QRhiTexture *rhiTexture() const override;
+ void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
+
void setTexture(QRhiTexture *texture);
void setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type,
const void *nativeObjectPtr, int nativeLayout,
@@ -119,10 +124,6 @@ class QSGPlainTexturePrivate : public QSGTexturePrivate
{
Q_DECLARE_PUBLIC(QSGPlainTexture)
public:
- int comparisonKey() const override;
- QRhiTexture *rhiTexture() const override;
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
-
QSGTexture::Filtering m_last_mipmap_filter = QSGTexture::None;
};
diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
index 6b5f1aec4f..172cfc4791 100644
--- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
@@ -184,7 +184,7 @@ void AtlasBase::invalidate()
m_texture = nullptr;
}
-void AtlasBase::updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates)
+void AtlasBase::commitTextureOperations(QRhiResourceUpdateBatch *resourceUpdates)
{
if (!m_allocated) {
m_allocated = true;
@@ -381,7 +381,7 @@ void Atlas::enqueueTextureUpload(TextureBase *t, QRhiResourceUpdateBatch *resour
}
TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect)
- : QSGTexture(*(new TextureBasePrivate))
+ : QSGTexture(*(new QSGTexturePrivate))
, m_allocated_rect(textureRect)
, m_atlas(atlas)
{
@@ -392,16 +392,8 @@ TextureBase::~TextureBase()
m_atlas->remove(this);
}
-QRhiResourceUpdateBatch *TextureBase::workResourceUpdateBatch() const
+int TextureBase::comparisonKey() const
{
- Q_D(const TextureBase);
- return d->workResourceUpdateBatch;
-}
-
-int TextureBasePrivate::comparisonKey() const
-{
- Q_Q(const TextureBase);
-
// We need special care here: a typical comparisonKey() implementation
// returns a unique result when there is no underlying texture yet. This is
// not quite ideal for atlasing however since textures with the same atlas
@@ -410,23 +402,21 @@ int TextureBasePrivate::comparisonKey() const
// base the comparison on the atlas ptr; this way textures for the same
// atlas are considered equal
- return int(qintptr(q->m_atlas));
+ return int(qintptr(m_atlas));
}
-QRhiTexture *TextureBasePrivate::rhiTexture() const
+QRhiTexture *TextureBase::rhiTexture() const
{
- Q_Q(const TextureBase);
- return q->m_atlas->m_texture;
+ return m_atlas->m_texture;
}
-void TextureBasePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
+void TextureBase::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
- Q_Q(TextureBase);
#ifdef QT_NO_DEBUG
Q_UNUSED(rhi);
#endif
- Q_ASSERT(rhi == q->m_atlas->m_rhi);
- q->m_atlas->updateRhiTexture(resourceUpdates);
+ Q_ASSERT(rhi == m_atlas->m_rhi);
+ m_atlas->commitTextureOperations(resourceUpdates);
}
Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
@@ -449,7 +439,7 @@ Texture::~Texture()
delete m_nonatlas_texture;
}
-QSGTexture *Texture::removedFromAtlas() const
+QSGTexture *Texture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates) const
{
if (!m_nonatlas_texture) {
m_nonatlas_texture = new QSGPlainTexture;
@@ -465,7 +455,7 @@ QSGTexture *Texture::removedFromAtlas() const
QRhiTexture *extractTex = rhi->newTexture(m_atlas->texture()->format(), r.size());
if (extractTex->build()) {
bool ownResUpd = false;
- QRhiResourceUpdateBatch *resUpd = workResourceUpdateBatch(); // ### Qt 6: should be an arg to this function
+ QRhiResourceUpdateBatch *resUpd = resourceUpdates;
if (!resUpd) {
ownResUpd = true;
resUpd = rhi->nextResourceUpdateBatch();
diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture_p.h b/src/quick/scenegraph/util/qsgrhiatlastexture_p.h
index 50d7b2a53f..739498f137 100644
--- a/src/quick/scenegraph/util/qsgrhiatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgrhiatlastexture_p.h
@@ -71,7 +71,6 @@ namespace QSGRhiAtlasTexture
class Texture;
class TextureBase;
-class TextureBasePrivate;
class Atlas;
class Manager : public QObject
@@ -105,7 +104,7 @@ public:
~AtlasBase();
void invalidate();
- void updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates);
+ void commitTextureOperations(QRhiResourceUpdateBatch *resourceUpdates);
void remove(TextureBase *t);
QSGDefaultRenderContext *renderContext() const { return m_rc; }
@@ -153,34 +152,25 @@ private:
class TextureBase : public QSGTexture
{
- Q_DECLARE_PRIVATE(TextureBase)
Q_OBJECT
public:
TextureBase(AtlasBase *atlas, const QRect &textureRect);
~TextureBase();
+ int comparisonKey() const override;
int textureId() const override { return 0; } // not used
void bind() override { } // not used
+ QRhiTexture *rhiTexture() const override;
+ void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
bool isAtlasTexture() const override { return true; }
QRect atlasSubRect() const { return m_allocated_rect; }
- QRhiResourceUpdateBatch *workResourceUpdateBatch() const;
-
protected:
QRect m_allocated_rect;
AtlasBase *m_atlas;
};
-class TextureBasePrivate : public QSGTexturePrivate
-{
- Q_DECLARE_PUBLIC(TextureBase)
-public:
- int comparisonKey() const override;
- QRhiTexture *rhiTexture() const override;
- void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override;
-};
-
class Texture : public TextureBase
{
Q_OBJECT
@@ -198,7 +188,7 @@ public:
QRect atlasSubRect() const { return m_allocated_rect; }
QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); }
- QSGTexture *removedFromAtlas() const override;
+ QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates) const override;
void releaseImage() { m_image = QImage(); }
const QImage &image() const { return m_image; }
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
index 93fc213f2e..77fded6c21 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
@@ -39,8 +39,8 @@
#include "qsgshadersourcebuilder_p.h"
-#include <QtGui/qopenglcontext.h>
-#include <QtGui/qopenglshaderprogram.h>
+#include <qopenglcontext.h>
+#include <qopenglshaderprogram.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
deleted file mode 100644
index 4bbc2b17ba..0000000000
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QSGSimpleMaterialShader
-
- \brief The QSGSimpleMaterialShader class provides a convenient way of
- building custom OpenGL-based materials for the scene graph.
-
- \inmodule QtQuick
- \ingroup qtquick-scenegraph-materials
-
- \deprecated
-
- \warning This utility class is only functional when running with the legacy
- OpenGL renderer of the Qt Quick scenegraph. Its usage is not recommended in
- new application code.
-
- Where the QSGMaterial and QSGMaterialShader API requires a bit of
- boilerplate code to create a functioning material, the
- QSGSimpleMaterialShader tries to hide some of this through the use
- of templates.
-
- QSGSimpleMaterialShader::vertexShader() and
- QSGSimpleMaterialShader::fragmentShader() are used to specify the
- actual shader source code. The names of the vertex attributes
- should be listed in the QSGSimpleMaterialShader::attributes()
-
- QSGSimpleMaterialShader::updateState() is used to push the material
- state to the OpenGL shader program.
-
- The actual OpenGL shader program is accessible through the
- QSGSimpleMaterialShader::program() function.
-
- Each QSGSimpleMaterialShader implementation operates on a unique
- state struct. The state struct must be declared using the
- \c {QSG_DECLARE_SIMPLE_SHADER} macro.
-
- Here is a simple example of a custom solid-color:
-
- \code
- struct Color
- {
- float r, g, b, a;
- };
-
- class MinimalShader : public QSGSimpleMaterialShader<Color>
- {
- QSG_DECLARE_SIMPLE_SHADER(MinimalShader, Color)
- public:
-
- const char *vertexShader() const {
- return
- "attribute highp vec4 vertex; \n"
- "uniform highp mat4 qt_Matrix; \n"
- "void main() { \n"
- " gl_Position = qt_Matrix * vertex; \n"
- "}";
- }
-
- const char *fragmentShader() const {
- return
- "uniform lowp float qt_Opacity; \n"
- "uniform lowp vec4 color; \n"
- "void main() { \n"
- " gl_FragColor = color * qt_Opacity; \n"
- "}";
- }
-
- QList<QByteArray> attributes() const {
- return QList<QByteArray>() << "vertex";
- }
-
- void updateState(const Color *color, const Color *) {
- program()->setUniformValue("color", color->r, color->g, color->b, color->a);
- }
-
- };
- \endcode
-
- Instances of materials using this shader can be created using the
- createMaterial() function which will be defined by the
- QSG_DECLARE_SIMPLE_SHADER macro.
-
- \code
- QSGSimpleMaterial<Color> *material = MinimalShader::createMaterial();
- material->state()->r = 1;
- material->state()->g = 0;
- material->state()->b = 0;
- material->state()->a = 1;
-
- node->setMaterial(material);
- \endcode
-
- The scene graph will often try to find materials that have the
- same or at least similar state so that these can be batched
- together inside the renderer, which gives better performance. To
- specify sortable material states, use
- QSG_DECLARE_SIMPLE_COMPARABLE_SHADER instead of
- QSG_DECLARE_SIMPLE_SHADER. The state struct must then also define
- the function:
-
- \code
- int compare(const Type *other) const;
- \endcode
-
- \warning The QSGSimpleMaterialShader relies on template
- instantiation to create a QSGMaterialType which the scene graph
- renderer internally uses to identify this shader. For this reason,
- the unique QSGSimpleMaterialShader implementation must be
- instantiated with a unique C++ type.
-
- \note All classes with QSG prefix should be used solely on the scene graph's
- rendering thread. See \l {Scene Graph and Rendering} for more information.
-
- \sa {Scene Graph - Simple Material}
- */
-
-/*!
- \macro QSG_DECLARE_SIMPLE_SHADER(Shader, State)
- \relates QSGSimpleMaterialShader
-
- This macro is used to declare a QSGMaterialType and a \c
- createMaterial() function for \a Shader with the given \a State.
- */
-
-/*!
- \macro QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(Shader, State)
- \relates QSGSimpleMaterialShader
-
- This macro is used to declare a QSGMaterialType and a \c
- createMaterial() function for \a Shader with the given \a State,
- where the \a State class must define a compare function on the
- form:
-
- \code
- int compare(const State *other) const;
- \endcode
-*/
-
-
-/*!
- \fn template <typename State> char const *const *QSGSimpleMaterialShader<State>::attributeNames() const
- \internal
- */
-
-/*!
- \fn template <typename State> void QSGSimpleMaterialShader<State>::initialize()
- \internal
- */
-
-/*!
- \fn template <typename State> void QSGSimpleMaterialShader<State>::resolveUniforms()
-
- Reimplement this function to resolve the location of named uniforms
- in the shader program.
-
- This function is called when the material shader is initialized.
- */
-
-/*!
- \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformMatrixName() const
-
- Returns the name for the transform matrix uniform of this item.
- The default value is \c qt_Matrix.
- */
-
-/*!
- \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformOpacityName() const
-
- Returns the name for the opacity uniform of this item.
- The default value is \c qt_Opacity.
- */
-
-/*!
- \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
- \internal
- */
-
-
-/*!
- \fn template <typename State> QList<QByteArray> QSGSimpleMaterialShader<State>::attributes() const
-
- Returns a list of names, declaring the vertex attributes in the
- vertex shader.
-*/
-
-/*!
- \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const State *newState, const State *oldState)
-
- Called whenever the state of this shader should be updated from
- \a oldState to \a newState, typical for each new set of
- geometries being drawn.
-
- Both the old and the new state are passed in so that the
- implementation can compare and minimize the state changes when
- applicable.
-*/
-
-/*!
- \class QSGSimpleMaterial
-
- \deprecated
-
- \inmodule QtQuick
- \ingroup qtquick-scenegraph-materials
-
- \brief The QSGSimpleMaterial class is a template generated class
- used to store the state used with a QSGSimpleMateralShader.
-
- The state of the material is accessible through the template
- generated state() function.
-
- \inmodule QtQuick
-
- \note All classes with QSG prefix should be used solely on the scene graph's
- rendering thread. See \l {Scene Graph and Rendering} for more information.
-
- \sa QSGSimpleMaterialShader
-*/
-
-
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
deleted file mode 100644
index 78cd05f2d8..0000000000
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSGSIMPLEMATERIAL_H
-#define QSGSIMPLEMATERIAL_H
-
-#include <QtQuick/qsgmaterial.h>
-
-QT_BEGIN_NAMESPACE
-
-#if QT_DEPRECATED_SINCE(5, 15)
-
-template <typename State>
-class QSGSimpleMaterialShader : public QSGMaterialShader
-{
-public:
- void initialize() override {
- QSGMaterialShader::initialize();
-#if QT_CONFIG(opengl)
- m_id_matrix = program()->uniformLocation(uniformMatrixName());
- if (m_id_matrix < 0) {
- qFatal("QSGSimpleMaterialShader does not implement 'uniform highp mat4 %s;' in its vertex shader",
- uniformMatrixName());
- }
-
- const char *opacity = uniformOpacityName();
- if (opacity) {
- m_id_opacity = program()->uniformLocation(uniformOpacityName());
- if (m_id_opacity < 0) {
- qFatal("QSGSimpleMaterialShader does not implement 'uniform lowp float %s' in its fragment shader",
- uniformOpacityName());
- }
- } else {
- m_id_opacity = -1;
- }
-#endif
- resolveUniforms();
- }
-
- // ### Qt 6: make both virtual and fix docs
- const char *uniformMatrixName() const { return "qt_Matrix"; }
- const char *uniformOpacityName() const { return "qt_Opacity"; }
-
- void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
-
- QT_DEPRECATED_X("QSGSimpleMaterialShader is going to be removed in Qt 6.0. Use QSGMaterialShader instead.")
- virtual void updateState(const State *newState, const State *oldState) = 0;
-
- virtual void resolveUniforms() {}
-
- virtual QList<QByteArray> attributes() const = 0;
-
- char const *const *attributeNames() const override
- {
- if (m_attribute_pointers.size())
- return m_attribute_pointers.constData();
-
- QList<QByteArray> names = attributes();
-
- // Calculate the total number of bytes needed, so we don't get rellocs and
- // bad pointers while copying over the individual names.
- // Add an extra byte pr entry for the '\0' char.
- int total = 0;
- for (int i=0; i<names.size(); ++i)
- total += names.at(i).size() + 1;
- m_attribute_name_data.reserve(total);
-
- // Copy over the names
- for (int i=0; i<names.size(); ++i) {
- m_attribute_pointers << m_attribute_name_data.constData() + m_attribute_name_data.size();
- m_attribute_name_data.append(names.at(i));
- m_attribute_name_data.append('\0');
- }
-
- // Append the "null" terminator
- m_attribute_pointers << 0;
-
- return m_attribute_pointers.constData();
- }
-
-private:
- int m_id_matrix;
- int m_id_opacity;
-
- mutable QByteArray m_attribute_name_data;
- mutable QVector<const char *> m_attribute_pointers;
-};
-
-#define QSG_DECLARE_SIMPLE_SHADER(Shader, State) \
-static QSGMaterialShader *createShader() \
-{ \
- return new Shader; \
-} \
-public: \
-static QSGSimpleMaterial<State> *createMaterial() \
-{ \
- return new QSGSimpleMaterial<State>(createShader); \
-}
-
-
-typedef QSGMaterialShader *(*PtrShaderCreateFunc)();
-
-
-template <typename State>
-class QSGSimpleMaterial : public QSGMaterial
-{
-public:
-#ifndef Q_CLANG_QDOC
- QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
- QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func)
- : m_state(aState)
- , m_func(func)
- {
- }
-
- QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
- QSGSimpleMaterial(PtrShaderCreateFunc func)
- : m_func(func)
- {
- }
-
- QSGMaterialShader *createShader() const override { return m_func(); }
- QSGMaterialType *type() const override { return &m_type; }
-
- State *state() { return &m_state; }
- const State *state() const { return &m_state; }
-#endif
-
-private:
- static QSGMaterialType m_type;
- State m_state;
- PtrShaderCreateFunc m_func;
-};
-
-#define QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(Shader, State) \
-static QSGMaterialShader *createShader() \
-{ \
- return new Shader; \
-} \
-public: \
-static QSGSimpleMaterialComparableMaterial<State> *createMaterial() \
-{ \
- return new QSGSimpleMaterialComparableMaterial<State>(createShader); \
-}
-
-template <typename State>
-class QSGSimpleMaterialComparableMaterial : public QSGSimpleMaterial<State>
-{
-
-public:
- QSGSimpleMaterialComparableMaterial(const State &state, PtrShaderCreateFunc func)
- : QSGSimpleMaterial<State>(state, func) {}
-
- QSGSimpleMaterialComparableMaterial(PtrShaderCreateFunc func)
- : QSGSimpleMaterial<State>(func) {}
-
- int compare(const QSGMaterial *other) const override {
- return QSGSimpleMaterialComparableMaterial<State>::state()->compare(static_cast<const QSGSimpleMaterialComparableMaterial<State> *>(other)->state());
- }
-};
-
-
-template <typename State>
-QSGMaterialType QSGSimpleMaterial<State>::m_type;
-
-
-template <typename State>
-Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
-{
-#if QT_CONFIG(opengl)
- if (state.isMatrixDirty())
- program()->setUniformValue(m_id_matrix, state.combinedMatrix());
- if (state.isOpacityDirty() && m_id_opacity >= 0)
- program()->setUniformValue(m_id_opacity, state.opacity());
-#else
- Q_UNUSED(state)
-#endif
- State *ns = static_cast<QSGSimpleMaterial<State> *>(newMaterial)->state();
- State *old = nullptr;
- if (oldMaterial)
- old = static_cast<QSGSimpleMaterial<State> *>(oldMaterial)->state();
- updateState(ns, old);
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-
-#endif
diff --git a/src/quick/scenegraph/util/qsgsimplerectnode.cpp b/src/quick/scenegraph/util/qsgsimplerectnode.cpp
index 7b96a3fdde..de961d4f26 100644
--- a/src/quick/scenegraph/util/qsgsimplerectnode.cpp
+++ b/src/quick/scenegraph/util/qsgsimplerectnode.cpp
@@ -51,10 +51,9 @@ QT_BEGIN_NAMESPACE
\warning This utility class is only functional when running with the default
or software backends of the Qt Quick scenegraph. As an alternative, prefer
- using QSGRectangleNode via QQuickWindow::createRectangleNode() or
- QSGEngine::createRectangleNode().
-
- \deprecated
+ using QSGRectangleNode via QQuickWindow::createRectangleNode(). However, this
+ standalone class is still useful when used via subclassing and the
+ application knows that no special scenegraph backends will be involved.
*/
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
index 1d0a423aa9..8dbfcad38b 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
@@ -99,10 +99,9 @@ static void qsgsimpletexturenode_update(QSGGeometry *g,
\warning This utility class is only functional when running with the default
or software backends of the Qt Quick scenegraph. As an alternative, prefer
- using QSGImageNode via QQuickWindow::createImageNode() or
- QSGEngine::createImageNode().
-
- \deprecated
+ using QSGImageNode via QQuickWindow::createImageNode(). However, this
+ standalone class is still useful when used via subclassing and the
+ application knows that no special scenegraph backends will be involved.
*/
/*!
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index 67b8748119..e6311fc652 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -40,8 +40,8 @@
#include "qsgtexturematerial_p.h"
#include <private/qsgtexture_p.h>
#if QT_CONFIG(opengl)
-# include <QtGui/qopenglshaderprogram.h>
-# include <QtGui/qopenglfunctions.h>
+# include <qopenglshaderprogram.h>
+# include <qopenglfunctions.h>
#endif
#include <QtGui/private/qrhi_p.h>
@@ -168,7 +168,7 @@ void QSGOpaqueTextureMaterialRhiShader::updateSampledImage(RenderState &state, i
}
}
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index 7bad9d50c4..b86533eb3f 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -81,6 +81,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimation : public QObject, public QQ
Q_CLASSINFO("DefaultMethod", "start()")
QML_NAMED_ELEMENT(Animation)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Animation is an abstract class")
public:
@@ -129,7 +130,7 @@ Q_SIGNALS:
void pausedChanged(bool);
void alwaysRunToEndChanged(bool);
void loopCountChanged(int);
- Q_REVISION(12) void finished();
+ Q_REVISION(2, 12) void finished();
public Q_SLOTS:
void restart();
@@ -169,6 +170,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPauseAnimation : public QQuickAbstractAnimati
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
QML_NAMED_ELEMENT(PauseAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPauseAnimation(QObject *parent=nullptr);
@@ -196,6 +198,7 @@ class QQuickScriptAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName)
QML_NAMED_ELEMENT(ScriptAction)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickScriptAction(QObject *parent=nullptr);
@@ -227,6 +230,7 @@ class QQuickPropertyAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
QML_NAMED_ELEMENT(PropertyAction)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPropertyAction(QObject *parent=nullptr);
@@ -276,6 +280,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyAnimation : public QQuickAbstractAnim
Q_PROPERTY(QQmlListProperty<QObject> targets READ targets)
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
QML_NAMED_ELEMENT(PropertyAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPropertyAnimation(QObject *parent=nullptr);
@@ -332,6 +337,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickColorAnimation : public QQuickPropertyAnimati
Q_PROPERTY(QColor from READ from WRITE setFrom)
Q_PROPERTY(QColor to READ to WRITE setTo)
QML_NAMED_ELEMENT(ColorAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickColorAnimation(QObject *parent=nullptr);
@@ -352,6 +358,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
QML_NAMED_ELEMENT(NumberAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickNumberAnimation(QObject *parent=nullptr);
@@ -378,6 +385,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim
Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged)
QML_NAMED_ELEMENT(Vector3dAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickVector3dAnimation(QObject *parent=nullptr);
@@ -400,6 +408,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
QML_NAMED_ELEMENT(RotationAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickRotationAnimation(QObject *parent=nullptr);
@@ -445,6 +454,7 @@ class QQuickSequentialAnimation : public QQuickAnimationGroup
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
QML_NAMED_ELEMENT(SequentialAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickSequentialAnimation(QObject *parent=nullptr);
@@ -463,6 +473,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGro
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
QML_NAMED_ELEMENT(ParallelAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickParallelAnimation(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h
index da6df6038a..de308735ef 100644
--- a/src/quick/util/qquickanimationcontroller_p.h
+++ b/src/quick/util/qquickanimationcontroller_p.h
@@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlP
Q_DECLARE_PRIVATE(QQuickAnimationController)
Q_CLASSINFO("DefaultProperty", "animation")
QML_NAMED_ELEMENT(AnimationController)
+ QML_ADDED_IN_VERSION(2, 0)
Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation NOTIFY animationChanged)
diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h
index 9f7aaafcb0..0bcf4c40a4 100644
--- a/src/quick/util/qquickanimator_p.h
+++ b/src/quick/util/qquickanimator_p.h
@@ -70,7 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimator : public QQuickAbstractAnimation
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
QML_NAMED_ELEMENT(Animator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
QML_UNCREATABLE("Animator is an abstract class")
public:
@@ -114,7 +114,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator
{
Q_OBJECT
QML_NAMED_ELEMENT(ScaleAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
QQuickScaleAnimator(QObject *parent = nullptr);
protected:
@@ -126,7 +126,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator
{
Q_OBJECT
QML_NAMED_ELEMENT(XAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
QQuickXAnimator(QObject *parent = nullptr);
protected:
@@ -138,7 +138,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator
{
Q_OBJECT
QML_NAMED_ELEMENT(YAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
QQuickYAnimator(QObject *parent = nullptr);
protected:
@@ -150,7 +150,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator
{
Q_OBJECT
QML_NAMED_ELEMENT(OpacityAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
QQuickOpacityAnimator(QObject *parent = nullptr);
protected:
@@ -165,7 +165,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimator : public QQuickAnimator
Q_DECLARE_PRIVATE(QQuickRotationAnimator)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
QML_NAMED_ELEMENT(RotationAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise };
@@ -192,7 +192,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator
Q_DECLARE_PRIVATE(QQuickUniformAnimator)
Q_PROPERTY(QString uniform READ uniform WRITE setUniform NOTIFY uniformChanged)
QML_NAMED_ELEMENT(UniformAnimator)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
public:
QQuickUniformAnimator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp
index 5cf8051922..ad9d4b08cd 100644
--- a/src/quick/util/qquickanimatorcontroller.cpp
+++ b/src/quick/util/qquickanimatorcontroller.cpp
@@ -41,6 +41,7 @@
#include "qquickanimatorcontroller_p.h"
#include <private/qquickwindow_p.h>
+#include <private/qquickitem_p.h>
#include <private/qsgrenderloop_p.h>
#include <private/qanimationgroupjob_p.h>
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 767be96403..642329dcaf 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -48,6 +48,7 @@
# include <private/qquickopenglshadereffectnode_p.h>
# include <private/qquickopenglshadereffect_p.h>
# include <private/qquickshadereffect_p.h>
+# include <QOpenGLContext>
#endif
#include <private/qanimationgroupjob_p.h>
diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h
index b0eb6fa604..a740067bf3 100644
--- a/src/quick/util/qquickapplication_p.h
+++ b/src/quick/util/qquickapplication_p.h
@@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication
Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged)
QML_NAMED_ELEMENT(Application)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Application is an abstract class.")
public:
diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h
index a57a26d822..1ce687ac44 100644
--- a/src/quick/util/qquickbehavior_p.h
+++ b/src/quick/util/qquickbehavior_p.h
@@ -69,10 +69,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBehavior : public QObject, public QQmlPropert
Q_CLASSINFO("DefaultProperty", "animation")
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION 13)
- Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION 15)
+ Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION(2, 13))
+ Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION(2, 15))
Q_CLASSINFO("DeferredPropertyNames", "animation")
QML_NAMED_ELEMENT(Behavior)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickBehavior(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp
index 2de9768243..e672fb8510 100644
--- a/src/quick/util/qquickfontloader.cpp
+++ b/src/quick/util/qquickfontloader.cpp
@@ -59,6 +59,8 @@
#include <QtCore/QCoreApplication>
+#include <QtGui/private/qfontdatabase_p.h>
+
QT_BEGIN_NAMESPACE
#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
@@ -74,7 +76,7 @@ public:
void download(const QUrl &url, QNetworkAccessManager *manager);
Q_SIGNALS:
- void fontDownloaded(const QString&, QQuickFontLoader::Status);
+ void fontDownloaded(int id);
private:
int redirectCount = 0;
@@ -123,14 +125,11 @@ void QQuickFontObject::replyFinished()
if (!reply->error()) {
id = QFontDatabase::addApplicationFontFromData(reply->readAll());
- if (id != -1)
- emit fontDownloaded(QFontDatabase::applicationFontFamilies(id).at(0), QQuickFontLoader::Ready);
- else
- emit fontDownloaded(QString(), QQuickFontLoader::Error);
+ emit fontDownloaded(id);
} else {
qWarning("%s: Unable to load font '%s': %s", Q_FUNC_INFO,
qPrintable(reply->url().toString()), qPrintable(reply->errorString()));
- emit fontDownloaded(QString(), QQuickFontLoader::Error);
+ emit fontDownloaded(-1);
}
reply->deleteLater();
reply = nullptr;
@@ -146,7 +145,7 @@ public:
QQuickFontLoaderPrivate() {}
QUrl url;
- QString name;
+ QFont font;
QQuickFontLoader::Status status = QQuickFontLoader::Null;
};
@@ -213,8 +212,8 @@ static void q_QFontLoaderFontsStaticReset()
FontLoader { id: fixedFont; name: "Courier" }
FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" }
- Text { text: "Fixed-size font"; font.family: fixedFont.name }
- Text { text: "Fancy font"; font.family: webFont.name }
+ Text { text: "Fixed-size font"; font: fixedFont.font }
+ Text { text: "Fancy font"; font: webFont.font }
}
\endqml
@@ -223,6 +222,7 @@ static void q_QFontLoaderFontsStaticReset()
QQuickFontLoader::QQuickFontLoader(QObject *parent)
: QObject(*(new QQuickFontLoaderPrivate), parent)
{
+ connect(this, &QQuickFontLoader::fontChanged, this, &QQuickFontLoader::nameChanged);
}
QQuickFontLoader::~QQuickFontLoader()
@@ -251,15 +251,13 @@ void QQuickFontLoader::setSource(const QUrl &url)
if (!localFile.isEmpty()) {
if (!fontLoaderFonts()->map.contains(d->url)) {
int id = QFontDatabase::addApplicationFont(localFile);
+ updateFontInfo(id);
if (id != -1) {
- updateFontInfo(QFontDatabase::applicationFontFamilies(id).at(0), Ready);
QQuickFontObject *fo = new QQuickFontObject(id);
fontLoaderFonts()->map[d->url] = fo;
- } else {
- updateFontInfo(QString(), Error);
}
} else {
- updateFontInfo(QFontDatabase::applicationFontFamilies(fontLoaderFonts()->map.value(d->url)->id).at(0), Ready);
+ updateFontInfo(fontLoaderFonts()->map.value(d->url)->id);
}
} else {
if (!fontLoaderFonts()->map.contains(d->url)) {
@@ -269,8 +267,8 @@ void QQuickFontLoader::setSource(const QUrl &url)
fo->download(d->url, qmlEngine(this)->networkAccessManager());
d->status = Loading;
emit statusChanged();
- QObject::connect(fo, SIGNAL(fontDownloaded(QString,QQuickFontLoader::Status)),
- this, SLOT(updateFontInfo(QString,QQuickFontLoader::Status)));
+ QObject::connect(fo, SIGNAL(fontDownloaded(int)),
+ this, SLOT(updateFontInfo(int)));
#else
// Silently fail if compiled with no_network
#endif
@@ -280,26 +278,48 @@ void QQuickFontLoader::setSource(const QUrl &url)
#if QT_CONFIG(qml_network)
d->status = Loading;
emit statusChanged();
- QObject::connect(fo, SIGNAL(fontDownloaded(QString,QQuickFontLoader::Status)),
- this, SLOT(updateFontInfo(QString,QQuickFontLoader::Status)));
+ QObject::connect(fo, SIGNAL(fontDownloaded(int)),
+ this, SLOT(updateFontInfo(int)));
#else
// Silently fail if compiled with no_network
#endif
}
else
- updateFontInfo(QFontDatabase::applicationFontFamilies(fo->id).at(0), Ready);
+ updateFontInfo(fo->id);
}
}
}
-void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Status status)
+void QQuickFontLoader::updateFontInfo(int id)
{
Q_D(QQuickFontLoader);
- if (name != d->name) {
- d->name = name;
- emit nameChanged();
+ QFont font;
+
+ QQuickFontLoader::Status status = Error;
+ if (id >= 0) {
+ QFontDatabasePrivate *p = QFontDatabasePrivate::instance();
+ if (id < p->applicationFonts.size()) {
+ const QFontDatabasePrivate::ApplicationFont &applicationFont = p->applicationFonts.at(id);
+
+ if (!applicationFont.properties.isEmpty()) {
+ const QFontDatabasePrivate::ApplicationFont::Properties &properties = applicationFont.properties.at(0);
+ font.setFamily(properties.familyName);
+ font.setStyleName(properties.styleName);
+ font.setWeight(properties.weight);
+ font.setStyle(properties.style);
+ font.setStretch(properties.stretch);
+ }
+ }
+
+ status = Ready;
+ }
+
+ if (font != d->font) {
+ d->font = font;
+ emit fontChanged();
}
+
if (status != d->status) {
if (status == Error)
qmlWarning(this) << "Cannot load font: \"" << d->url.toString() << '"';
@@ -309,11 +329,68 @@ void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Sta
}
/*!
+ \qmlproperty font QtQuick::FontLoader::font
+ \since 6.0
+
+ This property holds a default query for the loaded font.
+
+ You can use this to select the font if other properties than just the
+ family name are needed to disambiguate. You can either specify the
+ font using individual properties:
+
+ \qml
+ Item {
+ width: 200; height: 50
+
+ FontLoader {
+ id: webFont
+ source: "http://www.mysite.com/myfont.ttf"
+ }
+ Text {
+ text: "Fancy font"
+ font.family: webFont.font.family
+ font.weight: webFont.font.weight
+ font.style: webFont.font.style
+ font.pixelSize: 24
+ }
+ }
+ \endqml
+
+ Or you can set the full font query directly:
+
+ \qml
+ Item {
+ width: 200; height: 50
+
+ FontLoader {
+ id: webFont
+ source: "http://www.mysite.com/myfont.ttf"
+ }
+ Text {
+ text: "Fancy font"
+ font: webFont.font
+ }
+ }
+ \endqml
+
+ In this case, the default font query will be used with no modifications
+ (so font size, for instance, will be the system default).
+*/
+QFont QQuickFontLoader::font() const
+{
+ Q_D(const QQuickFontLoader);
+ return d->font;
+}
+
+/*!
\qmlproperty string QtQuick::FontLoader::name
+ \readonly
This property holds the name of the font family.
It is set automatically when a font is loaded using the \l source property.
+ This is equivalent to the family property of the FontLoader's \l font property.
+
Use this to set the \c font.family property of a \c Text item.
Example:
@@ -335,18 +412,7 @@ void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Sta
QString QQuickFontLoader::name() const
{
Q_D(const QQuickFontLoader);
- return d->name;
-}
-
-void QQuickFontLoader::setName(const QString &name)
-{
- Q_D(QQuickFontLoader);
- if (d->name == name)
- return;
- d->name = name;
- emit nameChanged();
- d->status = Ready;
- emit statusChanged();
+ return d->font.resolve() == 0 ? QString() : d->font.family();
}
/*!
diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h
index e849c52a35..bc7046e808 100644
--- a/src/quick/util/qquickfontloader_p.h
+++ b/src/quick/util/qquickfontloader_p.h
@@ -65,9 +65,11 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject
Q_DECLARE_PRIVATE(QQuickFontLoader)
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QFont font READ font NOTIFY fontChanged)
QML_NAMED_ELEMENT(FontLoader)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum Status { Null = 0, Ready, Loading, Error };
@@ -80,16 +82,18 @@ public:
void setSource(const QUrl &url);
QString name() const;
- void setName(const QString &name);
+
+ QFont font() const;
Status status() const;
private Q_SLOTS:
- void updateFontInfo(const QString&, QQuickFontLoader::Status);
+ void updateFontInfo(int);
Q_SIGNALS:
void sourceChanged();
void nameChanged();
+ void fontChanged();
void statusChanged();
};
diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h
index ee6d679649..59f4aa8355 100644
--- a/src/quick/util/qquickfontmetrics_p.h
+++ b/src/quick/util/qquickfontmetrics_p.h
@@ -80,7 +80,7 @@ class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject
Q_PROPERTY(qreal strikeOutPosition READ strikeOutPosition NOTIFY fontChanged)
Q_PROPERTY(qreal lineWidth READ lineWidth NOTIFY fontChanged)
QML_NAMED_ELEMENT(FontMetrics)
- QML_ADDED_IN_MINOR_VERSION(4)
+ QML_ADDED_IN_VERSION(2, 4)
public:
explicit QQuickFontMetrics(QObject *parent = nullptr);
~QQuickFontMetrics();
diff --git a/src/quick/util/qquickforeignutils_p.h b/src/quick/util/qquickforeignutils_p.h
index 7e51bc4f82..5db1197abe 100644
--- a/src/quick/util/qquickforeignutils_p.h
+++ b/src/quick/util/qquickforeignutils_p.h
@@ -73,13 +73,7 @@ struct QValidatorForeign
Q_GADGET
QML_FOREIGN(QValidator)
QML_ANONYMOUS
-};
-
-struct QRegExpValidatorForeign
-{
- Q_GADGET
- QML_FOREIGN(QRegExpValidator)
- QML_NAMED_ELEMENT(RegExpValidator)
+ QML_ADDED_IN_VERSION(2, 0)
};
#if QT_CONFIG(regularexpression)
@@ -88,7 +82,7 @@ struct QRegularExpressionValidatorForeign
Q_GADGET
QML_FOREIGN(QRegularExpressionValidator)
QML_NAMED_ELEMENT(RegularExpressionValidator)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
};
#endif // QT_CONFIG(regularexpression)
@@ -100,6 +94,7 @@ struct QInputMethodForeign
Q_GADGET
QML_FOREIGN(QInputMethod)
QML_NAMED_ELEMENT(InputMethod)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("InputMethod is an abstract class.")
};
#endif // QT_CONFIG(im)
@@ -110,7 +105,7 @@ struct QKeySequenceForeign
Q_GADGET
QML_FOREIGN(QKeySequence)
QML_NAMED_ELEMENT(StandardKey)
- QML_ADDED_IN_MINOR_VERSION(2)
+ QML_ADDED_IN_VERSION(2, 2)
QML_UNCREATABLE("Cannot create an instance of StandardKey.")
};
#endif // QT_CONFIG(shortcut)
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 70256e202e..e8439121ca 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -123,6 +123,13 @@ public:
return QVariant::fromValue(color);
}
+ QVariant alpha(const QVariant &var, qreal value) override
+ {
+ QColor color = var.value<QColor>();
+ color.setAlphaF(value);
+ return QVariant::fromValue(color);
+ }
+
QVariant tint(const QVariant &baseVar, const QVariant &tintVar) override
{
QColor tintColor = tintVar.value<QColor>();
@@ -392,7 +399,7 @@ public:
if (ok) *ok = true;
}
if (vweight->isInt32()) {
- retn.setWeight(static_cast<QFont::Weight>(vweight->integerValue()));
+ retn.setWeight(vweight->integerValue());
if (ok) *ok = true;
}
if (vwspac->isNumber()) {
diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h
index 82d0501697..f3dba81446 100644
--- a/src/quick/util/qquickimageprovider.h
+++ b/src/quick/util/qquickimageprovider.h
@@ -92,9 +92,11 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_finished())
};
+class QQuickImageProviderOptions;
+
class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase
{
- friend class QQuickImageProviderWithOptions; // ### Qt 6 Remove
+ friend class QQuickImageProviderWithOptions;
public:
QQuickImageProvider(ImageType type, Flags flags = Flags());
~QQuickImageProvider() override;
@@ -102,15 +104,9 @@ public:
ImageType imageType() const override;
Flags flags() const override;
-#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
- virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options);
- virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options);
- virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options);
-#else
virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize);
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize);
-#endif
private:
QQuickImageProviderPrivate *d;
@@ -122,11 +118,7 @@ public:
QQuickAsyncImageProvider();
~QQuickAsyncImageProvider() override;
-#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
- virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options) = 0;
-#else
virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) = 0;
-#endif
private:
QQuickAsyncImageProviderPrivate *d;
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index 159c46d13c..8660537587 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -79,6 +79,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject
{
Q_OBJECT
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {}
Q_SIGNALS:
@@ -92,6 +93,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
QML_NAMED_ELEMENT(PathAttribute)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -120,6 +122,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement
Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged)
Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged)
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -158,6 +161,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve
{
Q_OBJECT
QML_NAMED_ELEMENT(PathLine)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -168,7 +172,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve
{
Q_OBJECT
QML_NAMED_ELEMENT(PathMove)
- QML_ADDED_IN_MINOR_VERSION(9)
+ QML_ADDED_IN_VERSION(2, 9)
public:
QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -185,6 +189,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve
Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged)
QML_NAMED_ELEMENT(PathQuad)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -230,6 +235,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve
Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged)
Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged)
QML_NAMED_ELEMENT(PathCubic)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -288,6 +294,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve
{
Q_OBJECT
QML_NAMED_ELEMENT(PathCurve)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -301,8 +308,9 @@ 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 9)
+ Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION(2, 9))
QML_NAMED_ELEMENT(PathArc)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathArc(QObject *parent=nullptr)
@@ -333,7 +341,7 @@ Q_SIGNALS:
void radiusYChanged();
void useLargeArcChanged();
void directionChanged();
- Q_REVISION(9) void xAxisRotationChanged();
+ Q_REVISION(2, 9) void xAxisRotationChanged();
private:
qreal _radiusX = 0;
@@ -355,7 +363,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve
Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged)
QML_NAMED_ELEMENT(PathAngleArc)
- QML_ADDED_IN_MINOR_VERSION(11)
+ QML_ADDED_IN_VERSION(2, 11)
public:
QQuickPathAngleArc(QObject *parent=nullptr)
@@ -408,6 +416,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve
Q_OBJECT
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
QML_NAMED_ELEMENT(PathSvg)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -428,6 +437,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement
Q_OBJECT
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
QML_NAMED_ELEMENT(PathPercent)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -447,7 +457,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged)
QML_NAMED_ELEMENT(PathPolyline)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
public:
QQuickPathPolyline(QObject *parent=nullptr);
@@ -471,7 +481,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged)
QML_NAMED_ELEMENT(PathMultiline)
- QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ADDED_IN_VERSION(2, 14)
public:
QQuickPathMultiline(QObject *parent=nullptr);
@@ -512,9 +522,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu
Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged)
Q_PROPERTY(qreal startY READ startY WRITE setStartY NOTIFY startYChanged)
Q_PROPERTY(bool closed READ isClosed NOTIFY changed)
- Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14)
+ Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION(2, 14))
Q_CLASSINFO("DefaultProperty", "pathElements")
QML_NAMED_ELEMENT(Path)
+ QML_ADDED_IN_VERSION(2, 0)
Q_INTERFACES(QQmlParserStatus)
public:
QQuickPath(QObject *parent=nullptr);
@@ -535,7 +546,7 @@ public:
QPainterPath path() const;
QStringList attributes() const;
qreal attributeAt(const QString &, qreal) const;
- Q_REVISION(14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const;
+ Q_REVISION(2, 14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const;
QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const;
void invalidateSequentialHistory() const;
@@ -546,7 +557,7 @@ Q_SIGNALS:
void changed();
void startXChanged();
void startYChanged();
- Q_REVISION(14) void scaleChanged();
+ Q_REVISION(2, 14) void scaleChanged();
protected:
QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr);
@@ -609,7 +620,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
QML_NAMED_ELEMENT(PathText)
- QML_ADDED_IN_MINOR_VERSION(15)
+ QML_ADDED_IN_VERSION(2, 15)
public:
QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent)
{
diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h
index 440ea06841..70fb0935e8 100644
--- a/src/quick/util/qquickpathinterpolator_p.h
+++ b/src/quick/util/qquickpathinterpolator_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject
Q_PROPERTY(qreal y READ y NOTIFY yChanged)
Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
QML_NAMED_ELEMENT(PathInterpolator)
+ QML_ADDED_IN_VERSION(2, 0)
public:
explicit QQuickPathInterpolator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index d96ebe70b2..8dde8fbdd9 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -1033,7 +1033,7 @@ inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
lhs.options == rhs.options;
}
-inline uint qHash(const QQuickPixmapKey &key)
+inline size_t qHash(const QQuickPixmapKey &key)
{
return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^
(key.region->x()*29) ^ (key.region->y()*31) ^ (key.options.autoTransform() * 0x5c5c5c5c);
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index 93dec63e94..87724d6210 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -197,8 +197,8 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPixmap::Options)
-// This class will disappear with Qt6 and will just be the regular QQuickImageProvider
-// ### Qt 6: Remove this class and fold it with QQuickImageProvider
+// ### Qt 6: This should be made public in Qt 6. It's functionality can't be merged into
+// QQuickImageProvider without breaking source compatibility.
class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider
{
public:
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 1cb30f5a8d..74e8d056c5 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -411,10 +411,9 @@ QQmlProperty
QQuickPropertyChangesPrivate::property(const QString &property)
{
Q_Q(QQuickPropertyChanges);
- QQmlContextData *context = nullptr;
- if (QQmlData *ddata = QQmlData::get(q))
- context = ddata->outerContext;
- QQmlProperty prop = QQmlPropertyPrivate::create(object, property, context);
+ QQmlData *ddata = QQmlData::get(q);
+ QQmlProperty prop = QQmlPropertyPrivate::create(
+ object, property, ddata ? ddata->outerContext : QQmlRefPointer<QQmlContextData>());
if (!prop.isValid()) {
qmlWarning(q) << QQuickPropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property);
return QQmlProperty();
@@ -469,7 +468,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
a.specifiedObject = d->object;
a.specifiedProperty = property;
- QQmlContextData *context = QQmlContextData::get(qmlContext(this));
+ QQmlRefPointer<QQmlContextData> context = QQmlContextData::get(qmlContext(this));
QQmlBinding *newBinding = nullptr;
if (e.binding && e.binding->isTranslationBinding()) {
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 27a00420af..ff48de96c6 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyChanges : public QQuickStateOperation
Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues)
Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit)
QML_NAMED_ELEMENT(PropertyChanges)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickPropertyChanges();
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index 0e66a38e75..67dab928b7 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -67,14 +67,14 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_OBJECT
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 6)
- Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 6)
+ Q_PROPERTY(QVariantList sequences READ sequences WRITE setSequences NOTIFY sequencesChanged FINAL REVISION(2, 9))
+ Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION(2, 6))
+ Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION(2, 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)
QML_NAMED_ELEMENT(Shortcut)
- QML_ADDED_IN_MINOR_VERSION(5)
+ QML_ADDED_IN_VERSION(2, 5)
public:
explicit QQuickShortcut(QObject *parent = nullptr);
@@ -100,7 +100,7 @@ public:
Q_SIGNALS:
void sequenceChanged();
- Q_REVISION(9) void sequencesChanged();
+ Q_REVISION(2, 9) void sequencesChanged();
void enabledChanged();
void autoRepeatChanged();
void contextChanged();
diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h
index d7e637446d..4a53a4406f 100644
--- a/src/quick/util/qquicksmoothedanimation_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p.h
@@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation
Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged)
Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged)
QML_NAMED_ELEMENT(SmoothedAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
enum ReversingMode { Eased, Immediate, Sync };
diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h
index 771b746622..c09806e0ec 100644
--- a/src/quick/util/qquickspringanimation_p.h
+++ b/src/quick/util/qquickspringanimation_p.h
@@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation
Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged)
QML_NAMED_ELEMENT(SpringAnimation)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickSpringAnimation(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h
index af49bb1c2f..ee9aa92bbd 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -126,6 +126,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateOperation : public QObject
{
Q_OBJECT
QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickStateOperation(QObject *parent = nullptr)
: QObject(parent) {}
@@ -159,6 +160,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickState : public QObject
Q_CLASSINFO("DefaultProperty", "changes")
Q_CLASSINFO("DeferredPropertyNames", "changes")
QML_NAMED_ELEMENT(State)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickState(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h
index 931baaca4e..62f4910606 100644
--- a/src/quick/util/qquickstatechangescript_p.h
+++ b/src/quick/util/qquickstatechangescript_p.h
@@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, p
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString name READ name WRITE setName)
QML_NAMED_ELEMENT(StateChangeScript)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickStateChangeScript(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h
index 11a0c5f442..c3d66fd824 100644
--- a/src/quick/util/qquickstategroup_p.h
+++ b/src/quick/util/qquickstategroup_p.h
@@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateGroup : public QObject, public QQmlParse
Q_PROPERTY(QQmlListProperty<QQuickState> states READ statesProperty DESIGNABLE false)
Q_PROPERTY(QQmlListProperty<QQuickTransition> transitions READ transitionsProperty DESIGNABLE false)
QML_NAMED_ELEMENT(StateGroup)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickStateGroup(QObject * = nullptr);
diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h
index c6d9fc2604..43d7277bea 100644
--- a/src/quick/util/qquicksystempalette_p.h
+++ b/src/quick/util/qquicksystempalette_p.h
@@ -80,6 +80,7 @@ class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject
Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged)
Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged)
QML_NAMED_ELEMENT(SystemPalette)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickSystemPalette(QObject *parent=nullptr);
diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h
index a1d64e3d0a..33c64073c2 100644
--- a/src/quick/util/qquicktextmetrics_p.h
+++ b/src/quick/util/qquicktextmetrics_p.h
@@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickTextMetrics : public QObject
Q_PROPERTY(Qt::TextElideMode elide READ elide WRITE setElide NOTIFY elideChanged FINAL)
Q_PROPERTY(qreal elideWidth READ elideWidth WRITE setElideWidth NOTIFY elideWidthChanged FINAL)
QML_NAMED_ELEMENT(TextMetrics)
- QML_ADDED_IN_MINOR_VERSION(4)
+ QML_ADDED_IN_VERSION(2, 4)
public:
explicit QQuickTextMetrics(QObject *parent = 0);
diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h
index 6e45143126..bfb7d75821 100644
--- a/src/quick/util/qquicktransition_p.h
+++ b/src/quick/util/qquicktransition_p.h
@@ -104,6 +104,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTransition : public QObject
Q_CLASSINFO("DefaultProperty", "animations")
Q_CLASSINFO("DeferredPropertyNames", "animations")
QML_NAMED_ELEMENT(Transition)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickTransition(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp
index 4709b3dda3..c309460263 100644
--- a/src/quick/util/qquickvalidator.cpp
+++ b/src/quick/util/qquickvalidator.cpp
@@ -201,49 +201,6 @@ void QQuickDoubleValidator::resetLocaleName()
*/
/*!
- \qmltype RegExpValidator
- \instantiates QRegExpValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Provides a string validator.
- \deprecated
-
- The RegExpValidator type provides a validator, which counts as valid any string which
- matches a specified regular expression.
-
- RegExpValidator is deprecated since it is based on the deprecated \l {QRegExp}. Use
- \l RegularExpressionValidator instead.
-*/
-/*!
- \qmlproperty regExp QtQuick::RegExpValidator::regExp
-
- This property holds the regular expression used for validation.
-
- Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
- matching "a".
-
- By default, this property contains a regular expression with the pattern .* that matches any string.
-
- Below you can find an example of a \l TextInput object with a RegExpValidator specified:
-
- \snippet qml/regexp.qml 0
-
- Some more examples of regular expressions:
-
- \list
- \li A list of numbers with one to three positions separated by a comma:
- \badcode
- /\d{1,3}(?:,\d{1,3})+$/
- \endcode
-
- \li An amount consisting of up to 3 numbers before the decimal point, and
- 1 to 2 after the decimal point:
- \badcode
- /(\d{1,3})([.,]\d{1,2})?$/
- \endcode
- \endlist
-*/
-/*!
\qmltype RegularExpressionValidator
\instantiates QRegularExpressionValidator
\inqmlmodule QtQuick
diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h
index a0dc2cd5ba..d0e3c9d784 100644
--- a/src/quick/util/qquickvalidator_p.h
+++ b/src/quick/util/qquickvalidator_p.h
@@ -62,6 +62,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
QML_NAMED_ELEMENT(IntValidator)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickIntValidator(QObject *parent = nullptr);
@@ -78,6 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
QML_NAMED_ELEMENT(DoubleValidator)
+ QML_ADDED_IN_VERSION(2, 0)
public:
QQuickDoubleValidator(QObject *parent = nullptr);
@@ -96,7 +98,6 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QValidator)
QML_DECLARE_TYPE(QQuickIntValidator)
QML_DECLARE_TYPE(QQuickDoubleValidator)
-QML_DECLARE_TYPE(QRegExpValidator)
#if QT_CONFIG(regularexpression)
QML_DECLARE_TYPE(QRegularExpressionValidator)
#endif
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 395385fa0d..d836946214 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -44,7 +44,6 @@
#include <private/qcolorspace_p.h>
#include <private/qfont_p.h>
-
QT_BEGIN_NAMESPACE
namespace QQuickValueTypes {
@@ -59,6 +58,26 @@ QString QQuickColorValueType::toString() const
return v.name(v.alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
}
+QVariant QQuickColorValueType::lighter(qreal factor) const
+{
+ return QQml_colorProvider()->lighter(this->v, factor);
+}
+
+QVariant QQuickColorValueType::darker(qreal factor) const
+{
+ return QQml_colorProvider()->darker(this->v, factor);
+}
+
+QVariant QQuickColorValueType::alpha(qreal value) const
+{
+ return QQml_colorProvider()->alpha(this->v, value);
+}
+
+QVariant QQuickColorValueType::tint(QVariant tintColor) const
+{
+ return QQml_colorProvider()->tint(this->v, tintColor);
+}
+
qreal QQuickColorValueType::r() const
{
return v.redF();
@@ -635,14 +654,14 @@ void QQuickFontValueType::setBold(bool b)
v.setBold(b);
}
-QQuickFontValueType::FontWeight QQuickFontValueType::weight() const
+int QQuickFontValueType::weight() const
{
- return (QQuickFontValueType::FontWeight)v.weight();
+ return v.weight();
}
-void QQuickFontValueType::setWeight(QQuickFontValueType::FontWeight w)
+void QQuickFontValueType::setWeight(int w)
{
- v.setWeight((QFont::Weight)w);
+ v.setWeight(qBound(0, w, 99));
}
bool QQuickFontValueType::italic() const
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 638fdd2773..a94f4ac6a7 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -87,9 +87,18 @@ class QQuickColorValueType
Q_PROPERTY(qreal hslLightness READ hslLightness WRITE setHslLightness FINAL)
Q_PROPERTY(bool valid READ isValid)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QColor)
+ QML_VALUE_TYPE(color)
+
public:
Q_INVOKABLE QString toString() const;
+ Q_INVOKABLE QVariant alpha(qreal value) const;
+ Q_INVOKABLE QVariant lighter(qreal factor = 1.5) const;
+ Q_INVOKABLE QVariant darker(qreal factor = 2.0) const;
+ Q_INVOKABLE QVariant tint(QVariant factor) const;
+
qreal r() const;
qreal g() const;
qreal b() const;
@@ -119,6 +128,10 @@ class QQuickVector2DValueType
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector2D)
+ QML_VALUE_TYPE(vector2d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -147,6 +160,10 @@ class QQuickVector3DValueType
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector3D)
+ QML_VALUE_TYPE(vector3d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -180,6 +197,10 @@ class QQuickVector4DValueType
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_PROPERTY(qreal w READ w WRITE setW FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector4D)
+ QML_VALUE_TYPE(vector4d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -214,6 +235,10 @@ class QQuickQuaternionValueType
Q_PROPERTY(qreal y READ y WRITE setY)
Q_PROPERTY(qreal z READ z WRITE setZ)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QQuaternion)
+ QML_VALUE_TYPE(quaternion)
+
public:
Q_INVOKABLE QString toString() const;
@@ -247,6 +272,10 @@ class QQuickMatrix4x4ValueType
Q_PROPERTY(qreal m43 READ m43 WRITE setM43 FINAL)
Q_PROPERTY(qreal m44 READ m44 WRITE setM44 FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QMatrix4x4)
+ QML_VALUE_TYPE(matrix4x4)
+
public:
qreal m11() const { return v(0, 0); }
qreal m12() const { return v(0, 1); }
@@ -307,29 +336,12 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QMatrix4x4 &m) const;
};
-class QQuickFontValueType
+class QQuickFontEnums
{
- QFont v;
Q_GADGET
- Q_PROPERTY(QString family READ family WRITE setFamily FINAL)
- Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL)
- Q_PROPERTY(bool bold READ bold WRITE setBold FINAL)
- Q_PROPERTY(FontWeight weight READ weight WRITE setWeight FINAL)
- Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL)
- Q_PROPERTY(bool underline READ underline WRITE setUnderline FINAL)
- Q_PROPERTY(bool overline READ overline WRITE setOverline FINAL)
- Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout FINAL)
- Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize FINAL)
- Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize FINAL)
- Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization FINAL)
- Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing FINAL)
- Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing FINAL)
- Q_PROPERTY(HintingPreference hintingPreference READ hintingPreference WRITE setHintingPreference FINAL)
- Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
- Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
-
QML_NAMED_ELEMENT(Font)
+ QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Element is not creatable.")
public:
@@ -357,7 +369,35 @@ public:
PreferFullHinting = QFont::PreferFullHinting
};
Q_ENUM(HintingPreference)
+};
+
+class QQuickFontValueType : public QQuickFontEnums
+{
+ QFont v;
+ Q_GADGET
+ Q_PROPERTY(QString family READ family WRITE setFamily FINAL)
+ Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL)
+ Q_PROPERTY(bool bold READ bold WRITE setBold FINAL)
+ Q_PROPERTY(int weight READ weight WRITE setWeight FINAL)
+ Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL)
+ Q_PROPERTY(bool underline READ underline WRITE setUnderline FINAL)
+ Q_PROPERTY(bool overline READ overline WRITE setOverline FINAL)
+ Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout FINAL)
+ Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize FINAL)
+ Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize FINAL)
+ Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization FINAL)
+ Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing FINAL)
+ Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing FINAL)
+ Q_PROPERTY(HintingPreference hintingPreference READ hintingPreference WRITE setHintingPreference FINAL)
+ Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
+ Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
+
+ QML_VALUE_TYPE(font)
+ QML_FOREIGN(QFont)
+ QML_ADDED_IN_VERSION(2, 0)
+
+public:
Q_INVOKABLE QString toString() const;
QString family() const;
@@ -369,8 +409,8 @@ public:
bool bold() const;
void setBold(bool b);
- FontWeight weight() const;
- void setWeight(FontWeight);
+ int weight() const;
+ void setWeight(int);
bool italic() const;
void setItalic(bool b);
@@ -420,7 +460,7 @@ class QQuickColorSpaceValueType
Q_PROPERTY(float gamma READ gamma WRITE setGamma FINAL)
QML_NAMED_ELEMENT(ColorSpace)
- QML_ADDED_IN_MINOR_VERSION(15)
+ QML_ADDED_IN_VERSION(2, 15)
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
public:
diff --git a/src/quickshapes/CMakeLists.txt b/src/quickshapes/CMakeLists.txt
new file mode 100644
index 0000000000..3287fb1dd5
--- /dev/null
+++ b/src/quickshapes/CMakeLists.txt
@@ -0,0 +1,80 @@
+# Generated from quickshapes.pro.
+
+#####################################################################
+## QuickShapes Module:
+#####################################################################
+
+qt_add_module(QuickShapes
+ INTERNAL_MODULE
+ GENERATE_METATYPES
+ SOURCES
+ qquickshape.cpp qquickshape_p.h
+ qquickshape_p_p.h
+ qquickshapegenericrenderer.cpp qquickshapegenericrenderer_p.h
+ qquickshapesglobal.h qquickshapesglobal_p.h
+ qquickshapesoftwarerenderer.cpp qquickshapesoftwarerenderer_p.h
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::GuiPrivate
+ Qt::Qml
+ Qt::QuickPrivate
+)
+
+# Resources:
+set(qtquickshapes_resource_files
+ "shaders/blit.frag"
+ "shaders/blit.vert"
+ "shaders/blit_core.frag"
+ "shaders/blit_core.vert"
+ "shaders/conicalgradient.frag"
+ "shaders/conicalgradient.vert"
+ "shaders/conicalgradient_core.frag"
+ "shaders/conicalgradient_core.vert"
+ "shaders/lineargradient.frag"
+ "shaders/lineargradient.vert"
+ "shaders/lineargradient_core.frag"
+ "shaders/lineargradient_core.vert"
+ "shaders/radialgradient.frag"
+ "shaders/radialgradient.vert"
+ "shaders/radialgradient_core.frag"
+ "shaders/radialgradient_core.vert"
+ "shaders_ng/conicalgradient.frag.qsb"
+ "shaders_ng/conicalgradient.vert.qsb"
+ "shaders_ng/lineargradient.frag.qsb"
+ "shaders_ng/lineargradient.vert.qsb"
+ "shaders_ng/radialgradient.frag.qsb"
+ "shaders_ng/radialgradient.vert.qsb"
+)
+
+qt_add_resource(QuickShapes "qtquickshapes"
+ PREFIX
+ "/qt-project.org/shapes"
+ FILES
+ ${qtquickshapes_resource_files}
+)
+
+
+#### Keys ignored in scope 1:.:.:quickshapes.pro:<TRUE>:
+# QMLTYPES_FILENAME = "plugins.qmltypes"
+# QMLTYPES_INSTALL_DIR = "$$[QT_INSTALL_QML]/QtQuick/Shapes"
+# QML_IMPORT_NAME = "QtQuick.Shapes"
+# QML_IMPORT_VERSION = "$$QT_VERSION"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(QuickShapes CONDITION QT_FEATURE_opengl
+ SOURCES
+ qquicknvprfunctions.cpp qquicknvprfunctions_p.h
+ qquicknvprfunctions_p_p.h
+ qquickshapenvprrenderer.cpp qquickshapenvprrenderer_p.h
+)
+
+set_target_properties(QuickShapes PROPERTIES
+ QT_QML_MODULE_INSTALL_QMLTYPES TRUE
+ QT_QML_MODULE_VERSION ${CMAKE_PROJECT_VERSION}
+ QT_QML_MODULE_URI QtQuick.Shapes
+ QT_QML_MODULE_INSTALL_DIR "${INSTALL_QMLDIR}/QtQuick/Shapes"
+)
+
+qt6_qml_type_registration(QuickShapes)
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index dcd331b388..563303b84a 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -600,8 +600,6 @@ void QQuickShapePath::resetFillGradient()
\li The \c software backend is fully supported. The path is rendered via
QPainter::strokePath() and QPainter::fillPath() in this case.
- \li The Direct 3D 12 backend is not currently supported.
-
\li The OpenVG backend is not currently supported.
\endlist
diff --git a/src/quickshapes/qquickshape_p.h b/src/quickshapes/qquickshape_p.h
index f86f2b03d6..ca72c628c5 100644
--- a/src/quickshapes/qquickshape_p.h
+++ b/src/quickshapes/qquickshape_p.h
@@ -76,6 +76,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeGradient : public QQuickGradient
Q_CLASSINFO("DefaultProperty", "stops")
QML_NAMED_ELEMENT(ShapeGradient)
+ QML_ADDED_IN_VERSION(1, 0)
QML_UNCREATABLE("ShapeGradient is an abstract base class.");
public:
@@ -107,6 +108,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeLinearGradient : public QQuickShap
Q_PROPERTY(qreal y2 READ y2 WRITE setY2 NOTIFY y2Changed)
Q_CLASSINFO("DefaultProperty", "stops")
QML_NAMED_ELEMENT(LinearGradient)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QQuickShapeLinearGradient(QObject *parent = nullptr);
@@ -142,6 +144,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeRadialGradient : public QQuickShap
Q_PROPERTY(qreal focalRadius READ focalRadius WRITE setFocalRadius NOTIFY focalRadiusChanged)
Q_CLASSINFO("DefaultProperty", "stops")
QML_NAMED_ELEMENT(RadialGradient)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QQuickShapeRadialGradient(QObject *parent = nullptr);
@@ -187,6 +190,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeConicalGradient : public QQuickSha
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_CLASSINFO("DefaultProperty", "stops")
QML_NAMED_ELEMENT(ConicalGradient)
+ QML_ADDED_IN_VERSION(1, 0)
public:
QQuickShapeConicalGradient(QObject *parent = nullptr);
@@ -225,8 +229,9 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapePath : public QQuickPath
Q_PROPERTY(qreal dashOffset READ dashOffset WRITE setDashOffset NOTIFY dashOffsetChanged)
Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged)
Q_PROPERTY(QQuickShapeGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient)
- Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14)
+ Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION(1, 14))
QML_NAMED_ELEMENT(ShapePath)
+ QML_ADDED_IN_VERSION(1, 0)
public:
enum FillRule {
@@ -318,10 +323,11 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShape : public QQuickItem
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
Q_PROPERTY(bool vendorExtensionsEnabled READ vendorExtensionsEnabled WRITE setVendorExtensionsEnabled NOTIFY vendorExtensionsEnabledChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION 11)
+ Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION(1, 11))
Q_PROPERTY(QQmlListProperty<QObject> data READ data)
Q_CLASSINFO("DefaultProperty", "data")
QML_NAMED_ELEMENT(Shape)
+ QML_ADDED_IN_VERSION(1, 0)
public:
enum RendererType {
@@ -377,7 +383,7 @@ Q_SIGNALS:
void asynchronousChanged();
void vendorExtensionsEnabledChanged();
void statusChanged();
- Q_REVISION(11) void containsModeChanged();
+ Q_REVISION(1, 11) void containsModeChanged();
private:
Q_DISABLE_COPY(QQuickShape)
diff --git a/src/quickshapes/qquickshape_p_p.h b/src/quickshapes/qquickshape_p_p.h
index e9b89d2ab3..7851137465 100644
--- a/src/quickshapes/qquickshape_p_p.h
+++ b/src/quickshapes/qquickshape_p_p.h
@@ -200,7 +200,7 @@ struct QQuickShapeGradientCacheKey
}
};
-inline uint qHash(const QQuickShapeGradientCacheKey &v, uint seed = 0)
+inline size_t qHash(const QQuickShapeGradientCacheKey &v, uint seed = 0)
{
uint h = seed + v.spread;
for (int i = 0; i < 3 && i < v.stops.count(); ++i)
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp
index e0df739987..9fbff8fdda 100644
--- a/src/quickshapes/qquickshapegenericrenderer.cpp
+++ b/src/quickshapes/qquickshapegenericrenderer.cpp
@@ -49,7 +49,7 @@
#if QT_CONFIG(opengl)
#include <QOpenGLContext>
#include <QOffscreenSurface>
-#include <QtGui/private/qopenglextensions_p.h>
+#include <private/qopenglextensions_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -123,10 +123,11 @@ static bool q_supportsElementIndexUint(QSGRendererInterface::GraphicsApi api)
if (!elementIndexUintChecked) {
elementIndexUintChecked = true;
QOpenGLContext *context = QOpenGLContext::currentContext();
+ const bool needsTempContext = !context;
QScopedPointer<QOpenGLContext> dummyContext;
QScopedPointer<QOffscreenSurface> dummySurface;
bool ok = true;
- if (!context) {
+ if (needsTempContext) {
dummyContext.reset(new QOpenGLContext);
dummyContext->create();
context = dummyContext.data();
@@ -138,6 +139,13 @@ static bool q_supportsElementIndexUint(QSGRendererInterface::GraphicsApi api)
if (ok) {
elementIndexUint = static_cast<QOpenGLExtensions *>(context->functions())->hasOpenGLExtension(
QOpenGLExtensions::ElementIndexUint);
+
+ if (needsTempContext) {
+ // Must not let the temprary context be destroyed while current and
+ // the associated surface already gone, because some implementations
+ // (Mesa on drm) do not like that.
+ context->doneCurrent();
+ }
}
}
}
@@ -844,7 +852,7 @@ void QQuickShapeLinearGradientRhiShader::updateSampledImage(RenderState &state,
QQuickShapeGenericStrokeFillNode *node = m->node();
const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
@@ -1036,7 +1044,7 @@ void QQuickShapeRadialGradientRhiShader::updateSampledImage(RenderState &state,
QQuickShapeGenericStrokeFillNode *node = m->node();
const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
@@ -1210,7 +1218,7 @@ void QQuickShapeConicalGradientRhiShader::updateSampledImage(RenderState &state,
QQuickShapeGenericStrokeFillNode *node = m->node();
const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
- t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch());
+ t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
diff --git a/src/quickshapes/quickshapes.pro b/src/quickshapes/quickshapes.pro
index 4dbd3e5e46..7b77391d92 100644
--- a/src/quickshapes/quickshapes.pro
+++ b/src/quickshapes/quickshapes.pro
@@ -35,5 +35,5 @@ load(qt_module)
QMLTYPES_FILENAME = plugins.qmltypes
QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Shapes
QML_IMPORT_NAME = QtQuick.Shapes
-IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+QML_IMPORT_VERSION = $$QT_VERSION
CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quickwidgets/CMakeLists.txt b/src/quickwidgets/CMakeLists.txt
new file mode 100644
index 0000000000..53a233e341
--- /dev/null
+++ b/src/quickwidgets/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Generated from quickwidgets.pro.
+
+#####################################################################
+## QuickWidgets Module:
+#####################################################################
+
+qt_add_module(QuickWidgets
+ SOURCES
+ qquickwidget.cpp qquickwidget.h qquickwidget_p.h
+ qtquickwidgetsglobal.h
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_INTEGER_EVENT_COORDINATES
+ QT_NO_URL_CAST_FROM_STRING
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+ Qt::WidgetsPrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+ Qt::Widgets
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickPrivate
+ Qt::WidgetsPrivate
+)
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 35cf06927a..f3d26e4a73 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -59,9 +59,11 @@
#include <QtGui/qpa/qplatformintegration.h>
#if QT_CONFIG(opengl)
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLFunctions>
-#include <QtGui/private/qopenglextensions_p.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
#endif
#include <QtGui/QPainter>
@@ -381,7 +383,7 @@ QImage QQuickWidgetPrivate::grabFramebuffer()
context->makeCurrent(offscreenSurface);
#endif
}
- return renderControl->grab();
+ return offscreenWindow->grabWindow();
}
// Intentionally not overriding the QQuickWindow's focusObject.
@@ -501,7 +503,7 @@ QImage QQuickWidgetPrivate::grabFramebuffer()
\section1 Support when not using OpenGL
In addition to OpenGL, the \c software backend of Qt Quick also supports
- QQuickWidget. Other backends, for example the Direct 3D 12 one, are not
+ QQuickWidget. Other backends, for example OpenVG, are not
compatible however and attempting to construct a QQuickWidget will lead to
problems.
diff --git a/src/src.pro b/src/src.pro
index 2855102eff..c9de88e942 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -4,9 +4,6 @@ include($$OUT_PWD/qml/qtqml-config.pri)
include($$OUT_PWD/quick/qtquick-config.pri)
QT_FOR_CONFIG += qml qml-private quick-private
-# Otherwise we cannot compile qmltyperegistrar
-requires(qtConfig(commandlineparser))
-
# We need qmltyperegistrar for all type registrations, even in qml
SUBDIRS += \
qmltyperegistrar \