summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/quick/demos/photosurface/main.cpp8
-rw-r--r--examples/quick/embeddedinwidgets/main.cpp3
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp4
-rw-r--r--examples/quick/quickwidgets/quickwidget/main.cpp3
-rw-r--r--examples/quick/rendercontrol/cuberenderer.cpp4
-rw-r--r--examples/quick/rendercontrol/window_multithreaded.cpp8
-rw-r--r--examples/quick/rendercontrol/window_singlethreaded.cpp8
-rw-r--r--examples/quick/scenegraph/openglunderqml/squircle.cpp32
-rw-r--r--examples/quick/scenegraph/rendernode/openglrenderer.cpp4
-rw-r--r--examples/quick/scenegraph/sgengine/window.cpp2
-rw-r--r--examples/quick/scenegraph/shared/logorenderer.cpp8
-rw-r--r--examples/quick/scenegraph/textureinthread/main.cpp2
-rw-r--r--examples/quick/shared/Label.qml46
-rw-r--r--examples/quick/shared/quick_shared.qrc1
-rw-r--r--examples/quick/shared/shared.qrc1
-rw-r--r--examples/quick/window/AllScreens.qml75
-rw-r--r--examples/quick/window/CurrentScreen.qml (renamed from examples/quick/window/ScreenInfo.qml)36
-rw-r--r--examples/quick/window/Splash.qml2
-rw-r--r--examples/quick/window/doc/src/window.qdoc2
-rw-r--r--examples/quick/window/main.cpp3
-rw-r--r--examples/quick/window/window.qml23
-rw-r--r--examples/quick/window/window.qrc3
-rw-r--r--src/imports/folderlistmodel/fileinfothread_p.h2
-rw-r--r--src/imports/folderlistmodel/fileproperty_p.h20
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h12
-rw-r--r--src/imports/layouts/qquickgridlayoutengine_p.h6
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h4
-rw-r--r--src/imports/localstorage/plugin.cpp2
-rw-r--r--src/imports/settings/qqmlsettings_p.h6
-rw-r--r--src/imports/statemachine/state.h4
-rw-r--r--src/imports/statemachine/statemachine.h4
-rw-r--r--src/imports/statemachine/timeouttransition.h4
-rw-r--r--src/imports/testlib/TestCase.qml258
-rw-r--r--src/imports/testlib/main.cpp1
-rw-r--r--src/imports/testlib/qmldir1
-rw-r--r--src/imports/testlib/toucheventsequence.qdoc110
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp4
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel_p.h14
-rw-r--r--src/particles/qquickage_p.h3
-rw-r--r--src/particles/qquickangledirection.cpp2
-rw-r--r--src/particles/qquickangledirection_p.h2
-rw-r--r--src/particles/qquickcumulativedirection.cpp2
-rw-r--r--src/particles/qquickcumulativedirection_p.h2
-rw-r--r--src/particles/qquickcustomaffector_p.h5
-rw-r--r--src/particles/qquickcustomparticle.cpp9
-rw-r--r--src/particles/qquickcustomparticle_p.h14
-rw-r--r--src/particles/qquickdirection.cpp2
-rw-r--r--src/particles/qquickdirection_p.h2
-rw-r--r--src/particles/qquickellipseextruder_p.h4
-rw-r--r--src/particles/qquickfriction_p.h2
-rw-r--r--src/particles/qquickgravity_p.h3
-rw-r--r--src/particles/qquickgroupgoal_p.h2
-rw-r--r--src/particles/qquickimageparticle.cpp7
-rw-r--r--src/particles/qquickimageparticle_p.h12
-rw-r--r--src/particles/qquickitemparticle_p.h10
-rw-r--r--src/particles/qquicklineextruder_p.h6
-rw-r--r--src/particles/qquickmaskextruder_p.h4
-rw-r--r--src/particles/qquickparticleaffector.cpp2
-rw-r--r--src/particles/qquickparticleaffector_p.h4
-rw-r--r--src/particles/qquickparticleemitter_p.h2
-rw-r--r--src/particles/qquickparticlegroup_p.h4
-rw-r--r--src/particles/qquickparticlepainter_p.h4
-rw-r--r--src/particles/qquickparticlesystem_p.h6
-rw-r--r--src/particles/qquickpointattractor_p.h3
-rw-r--r--src/particles/qquickpointdirection.cpp2
-rw-r--r--src/particles/qquickpointdirection_p.h2
-rw-r--r--src/particles/qquickrectangleextruder_p.h4
-rw-r--r--src/particles/qquickspritegoal_p.h3
-rw-r--r--src/particles/qquicktargetdirection.cpp2
-rw-r--r--src/particles/qquicktargetdirection_p.h2
-rw-r--r--src/particles/qquicktrailemitter_p.h4
-rw-r--r--src/particles/qquickturbulence_p.h6
-rw-r--r--src/particles/qquickv4particledata.cpp2
-rw-r--r--src/particles/qquickv4particledata_p.h2
-rw-r--r--src/particles/qquickwander_p.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservice.json2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp14
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp16
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp44
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h23
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp38
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp23
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/highlight.h4
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservicefactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp12
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp (renamed from src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp)0
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.h (renamed from src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h)4
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.json3
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp54
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.h57
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro21
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp14
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro21
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp (renamed from src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp)39
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h (renamed from src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h)2
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.json3
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp54
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.h57
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp9
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h1
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp51
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp16
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h2
-rw-r--r--src/plugins/qmltooling/qmltooling.pro6
-rw-r--r--src/plugins/scenegraph/openvg/openvg.json3
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro56
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgcontext.cpp218
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgcontext_p.h88
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgmatrix.cpp378
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgmatrix.h108
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp123
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgoffscreensurface.h75
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp78
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h68
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp219
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h104
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp162
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h97
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp214
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h95
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp433
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvghelpers.h64
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp239
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h92
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp732
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h100
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvglayer.cpp315
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvglayer.h113
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp275
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h92
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp253
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpainternode.h97
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp325
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h145
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp87
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderable.h75
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp90
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h61
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp261
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h94
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp157
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.h78
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp123
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgtexture.h67
-rw-r--r--src/plugins/scenegraph/scenegraph.pro2
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h6
-rw-r--r--src/qml/animations/qanimationgroupjob_p.h2
-rw-r--r--src/qml/animations/qcontinuinganimationgroupjob_p.h12
-rw-r--r--src/qml/animations/qparallelanimationgroupjob_p.h12
-rw-r--r--src/qml/animations/qpauseanimationjob_p.h6
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob_p.h16
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp22
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h40
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp10
-rw-r--r--src/qml/compiler/qv4codegen_p.h228
-rw-r--r--src/qml/compiler/qv4compiler.cpp4
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp6
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h123
-rw-r--r--src/qml/compiler/qv4ssa.cpp120
-rw-r--r--src/qml/compiler/qv4ssa_p.h15
-rw-r--r--src/qml/debugger/qqmldebug.cpp14
-rw-r--r--src/qml/debugger/qqmldebug.h1
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp18
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h4
-rw-r--r--src/qml/doc/src/javascript/dynamicobjectcreation.qdoc2
-rw-r--r--src/qml/doc/src/javascript/functionlist.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc12
-rw-r--r--src/qml/jit/qv4isel_masm.cpp21
-rw-r--r--src/qml/jit/qv4isel_masm_p.h121
-rw-r--r--src/qml/jit/qv4regalloc.cpp124
-rw-r--r--src/qml/jsruntime/jsruntime.pri2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp76
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp4
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp2
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp24
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp14
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4script.cpp6
-rw-r--r--src/qml/jsruntime/qv4util_p.h6
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp7
-rw-r--r--src/qml/parser/qqmljsast_p.h558
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp6
-rw-r--r--src/qml/qml/ftw/qqmlthread_p.h24
-rw-r--r--src/qml/qml/qqml.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp17
-rw-r--r--src/qml/qml/qqmlapplicationengine.h6
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlbinding_p.h4
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp2
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h4
-rw-r--r--src/qml/qml/qqmlcomponent.cpp8
-rw-r--r--src/qml/qml/qqmlcomponent_p.h4
-rw-r--r--src/qml/qml/qqmlcontext_p.h6
-rw-r--r--src/qml/qml/qqmlengine.cpp22
-rw-r--r--src/qml/qml/qqmlengine.h2
-rw-r--r--src/qml/qml/qqmlexpression.cpp2
-rw-r--r--src/qml/qml/qqmlexpression_p.h4
-rw-r--r--src/qml/qml/qqmlextensionplugin.h4
-rw-r--r--src/qml/qml/qqmlfileselector_p.h2
-rw-r--r--src/qml/qml/qqmlimport.cpp72
-rw-r--r--src/qml/qml/qqmlincubator.cpp2
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h2
-rw-r--r--src/qml/qml/qqmlloggingcategory.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp46
-rw-r--r--src/qml/qml/qqmlmetatype_p.h5
-rw-r--r--src/qml/qml/qqmlnotifier_p.h12
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h6
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h6
-rw-r--r--src/qml/qml/qqmlproperty.cpp9
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp32
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h14
-rw-r--r--src/qml/qml/qqmlproxymetaobject_p.h4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp21
-rw-r--r--src/qml/qml/qqmltypeloader_p.h38
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp8
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h14
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h6
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp2
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding_p.h6
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp34
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h38
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp9
-rw-r--r--src/qml/qml/v8/qv8engine_p.h6
-rw-r--r--src/qml/types/qqmlbind_p.h6
-rw-r--r--src/qml/types/qqmlconnections.cpp2
-rw-r--r--src/qml/types/qqmlconnections_p.h8
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp18
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h24
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h36
-rw-r--r--src/qml/types/qqmlinstantiator.cpp6
-rw-r--r--src/qml/types/qqmlinstantiator_p.h6
-rw-r--r--src/qml/types/qqmllistmodel.cpp61
-rw-r--r--src/qml/types/qqmllistmodel_p.h12
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h20
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h2
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp2
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h16
-rw-r--r--src/qml/types/qqmltimer.cpp4
-rw-r--r--src/qml/types/qqmltimer_p.h6
-rw-r--r--src/qml/types/qquickworkerscript.cpp4
-rw-r--r--src/qml/types/qquickworkerscript_p.h12
-rw-r--r--src/qml/util/qqmladaptormodel.cpp4
-rw-r--r--src/qml/util/qqmladaptormodel_p.h2
-rw-r--r--src/qml/util/qqmlchangeset.cpp12
-rw-r--r--src/qml/util/qqmllistcompositor.cpp4
-rw-r--r--src/qml/util/qqmlpropertymap.cpp8
-rw-r--r--src/qmldebug/qqmlenginecontrolclient_p.h2
-rw-r--r--src/qmldebug/qqmlprofilerclient_p.h2
-rw-r--r--src/qmltest/qmltest.pro2
-rw-r--r--src/qmltest/quicktest.cpp3
-rw-r--r--src/qmltest/quicktestevent.cpp97
-rw-r--r--src/qmltest/quicktestevent_p.h24
-rw-r--r--src/qmltest/quicktestresult.cpp2
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp4
-rw-r--r--src/quick/accessible/qaccessiblequickview_p.h20
-rw-r--r--src/quick/designer/qqmldesignermetaobject_p.h2
-rw-r--r--src/quick/designer/qquickdesignerwindowmanager_p.h22
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc80
-rwxr-xr-xsrc/quick/items/checksync.pl106
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp44
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h2
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h18
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h4
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h16
-rw-r--r--src/quick/items/context2d/qquickcontext2dtile_p.h8
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h2
-rw-r--r--src/quick/items/qquickanchors.cpp4
-rw-r--r--src/quick/items/qquickanchors_p_p.h4
-rw-r--r--src/quick/items/qquickdrag_p.h4
-rw-r--r--src/quick/items/qquickdroparea.cpp2
-rw-r--r--src/quick/items/qquickdroparea_p.h2
-rw-r--r--src/quick/items/qquickevents.cpp2
-rw-r--r--src/quick/items/qquickflickable.cpp10
-rw-r--r--src/quick/items/qquickflickable_p.h2
-rw-r--r--src/quick/items/qquickflickable_p_p.h6
-rw-r--r--src/quick/items/qquickflipable.cpp2
-rw-r--r--src/quick/items/qquickflipable_p.h2
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp4
-rw-r--r--src/quick/items/qquickimage.cpp15
-rw-r--r--src/quick/items/qquickimagebase.cpp13
-rw-r--r--src/quick/items/qquickimagebase_p_p.h3
-rw-r--r--src/quick/items/qquickitem.cpp72
-rw-r--r--src/quick/items/qquickitem_p.h8
-rw-r--r--src/quick/items/qquickitemanimation_p_p.h4
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp17
-rw-r--r--src/quick/items/qquickitemgrabresult.h7
-rw-r--r--src/quick/items/qquickitemsmodule.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp56
-rw-r--r--src/quick/items/qquickitemview_p.h2
-rw-r--r--src/quick/items/qquickitemview_p_p.h4
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp2
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h2
-rw-r--r--src/quick/items/qquicklistview_p.h2
-rw-r--r--src/quick/items/qquickloader_p_p.h2
-rw-r--r--src/quick/items/qquickmousearea.cpp47
-rw-r--r--src/quick/items/qquickmousearea_p.h6
-rw-r--r--src/quick/items/qquickmousearea_p_p.h1
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp16
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp10
-rw-r--r--src/quick/items/qquickpainteditem.cpp2
-rw-r--r--src/quick/items/qquickpathview.cpp86
-rw-r--r--src/quick/items/qquickpathview_p.h6
-rw-r--r--src/quick/items/qquickpathview_p_p.h2
-rw-r--r--src/quick/items/qquickscreen.cpp195
-rw-r--r--src/quick/items/qquickscreen_p.h48
-rw-r--r--src/quick/items/qquickshadereffectmesh.cpp17
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h2
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp2
-rw-r--r--src/quick/items/qquickspriteengine.cpp4
-rw-r--r--src/quick/items/qquickspriteengine_p.h10
-rw-r--r--src/quick/items/qquickstateoperations.cpp8
-rw-r--r--src/quick/items/qquickstateoperations_p.h4
-rw-r--r--src/quick/items/qquicktextcontrol.cpp4
-rw-r--r--src/quick/items/qquicktextcontrol_p.h6
-rw-r--r--src/quick/items/qquicktextdocument.cpp2
-rw-r--r--src/quick/items/qquicktextdocument_p.h8
-rw-r--r--src/quick/items/qquicktextedit.cpp2
-rw-r--r--src/quick/items/qquicktextinput.cpp49
-rw-r--r--src/quick/items/qquickwindow.cpp34
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h4
-rw-r--r--src/quick/items/qquickwindowmodule.cpp25
-rw-r--r--src/quick/items/qquickwindowmodule_p.h5
-rw-r--r--src/quick/qtquick2.cpp26
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp1
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.h3
-rw-r--r--src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp14
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h10
-rw-r--r--src/quick/scenegraph/qsgbasicglyphnode_p.h14
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h6
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h28
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p_p.h16
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp4
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.h18
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h34
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp6
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h30
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop_p.h26
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h16
-rw-r--r--src/quick/scenegraph/util/qsgdefaultpainternode_p.h30
-rw-r--r--src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgflatcolormaterial.h6
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder.cpp15
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h10
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h10
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.h10
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial_p.h10
-rw-r--r--src/quick/scenegraph/util/qsgvertexcolormaterial.h6
-rw-r--r--src/quick/util/qquickanimation.cpp4
-rw-r--r--src/quick/util/qquickanimation_p.h32
-rw-r--r--src/quick/util/qquickanimation_p_p.h30
-rw-r--r--src/quick/util/qquickanimationcontroller.cpp4
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h4
-rw-r--r--src/quick/util/qquickanimator_p.h28
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp268
-rw-r--r--src/quick/util/qquickanimatorcontroller_p.h50
-rw-r--r--src/quick/util/qquickanimatorjob.cpp424
-rw-r--r--src/quick/util/qquickanimatorjob_p.h102
-rw-r--r--src/quick/util/qquickapplication.cpp46
-rw-r--r--src/quick/util/qquickapplication_p.h13
-rw-r--r--src/quick/util/qquickbehavior.cpp2
-rw-r--r--src/quick/util/qquickbehavior_p.h4
-rw-r--r--src/quick/util/qquickimageprovider.cpp165
-rw-r--r--src/quick/util/qquickimageprovider.h17
-rw-r--r--src/quick/util/qquickpath_p.h16
-rw-r--r--src/quick/util/qquickpixmapcache.cpp176
-rw-r--r--src/quick/util/qquickpixmapcache_p.h76
-rw-r--r--src/quick/util/qquickpropertychanges.cpp20
-rw-r--r--src/quick/util/qquickpropertychanges_p.h6
-rw-r--r--src/quick/util/qquickshortcut.cpp151
-rw-r--r--src/quick/util/qquickshortcut_p.h27
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h8
-rw-r--r--src/quick/util/qquicksmoothedanimation_p_p.h8
-rw-r--r--src/quick/util/qquickspringanimation.cpp8
-rw-r--r--src/quick/util/qquickspringanimation_p.h4
-rw-r--r--src/quick/util/qquickstate_p_p.h2
-rw-r--r--src/quick/util/qquickstatechangescript_p.h6
-rw-r--r--src/quick/util/qquickstategroup_p.h4
-rw-r--r--src/quick/util/qquickstyledtext.cpp3
-rw-r--r--src/quick/util/qquicktimeline_p_p.h8
-rw-r--r--src/quick/util/qquicktransition.cpp4
-rw-r--r--src/quick/util/qquickutilmodule.cpp2
-rw-r--r--src/quick/util/qquickvaluetypes.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/data/test.qml1
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp96
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp23
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp68
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp11
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp26
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp17
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/data/works22.qml3
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2.2/plugin.2.2.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2.2/plugin.cpp72
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/plugin.2.2/qmldir1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro3
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp76
-rw-r--r--tests/auto/qmltest-blacklist/animators/tst_stopped.qml86
-rw-r--r--tests/auto/qmltest/events/tst_events.qml16
-rw-r--r--tests/auto/qmltest/events/tst_touch.qml182
-rw-r--r--tests/auto/qmltest/selftests/tst_createTemporaryObject.qml179
-rw-r--r--tests/auto/quick/drawingmodes/data/DrawingModes.qml14
-rw-r--r--tests/auto/quick/drawingmodes/drawingmodes.pro17
-rw-r--r--tests/auto/quick/drawingmodes/tst_drawingmodes.cpp340
-rw-r--r--tests/auto/quick/qquickapplication/data/tst_displayname.qml7
-rw-r--r--tests/auto/quick/qquickapplication/qquickapplication.pro6
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp27
-rw-r--r--tests/auto/quick/qquickitem/data/shortcutOverride.qml65
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp35
-rw-r--r--tests/auto/quick/qquickmousearea/data/pressAndHold.qml12
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp45
-rw-r--r--tests/auto/quick/qquickscreen/data/screen.qml14
-rw-r--r--tests/auto/quick/qquickscreen/tst_qquickscreen.cpp40
-rw-r--r--tests/auto/quick/qquickshortcut/data/multiple.qml45
-rw-r--r--tests/auto/quick/qquickshortcut/tst_qquickshortcut.cpp45
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp1
-rw-r--r--tests/auto/quick/qquickwindow/data/windowWithScreen.qml10
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp19
-rw-r--r--tests/auto/quick/quick.pro1
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp17
-rw-r--r--tests/manual/v4/fun.4.js3
-rw-r--r--tools/qml/main.cpp2
-rw-r--r--tools/qmleasing/mainwindow.cpp3
-rw-r--r--tools/qmleasing/mainwindow.h6
-rw-r--r--tools/qmleasing/splineeditor.cpp4
-rw-r--r--tools/qmleasing/splineeditor.h10
-rw-r--r--tools/qmlimportscanner/main.cpp12
-rw-r--r--tools/qmljs/qmljs.cpp10
-rw-r--r--tools/qmllint/main.cpp9
-rw-r--r--tools/qmlplugindump/main.cpp50
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.h26
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp10
452 files changed, 12608 insertions, 2993 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 556f554e5e..f03d05c7ac 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,4 +1,4 @@
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.8.0
+MODULE_VERSION = 5.9.0
diff --git a/examples/quick/demos/photosurface/main.cpp b/examples/quick/demos/photosurface/main.cpp
index 9456694032..b9d093df40 100644
--- a/examples/quick/demos/photosurface/main.cpp
+++ b/examples/quick/demos/photosurface/main.cpp
@@ -59,9 +59,11 @@ static QStringList imageNameFilters()
{
QStringList result;
QMimeDatabase mimeDatabase;
- foreach (const QByteArray &m, QImageReader::supportedMimeTypes()) {
- foreach (const QString &suffix, mimeDatabase.mimeTypeForName(m).suffixes())
- result.append(QStringLiteral("*.") + suffix);
+ const auto supportedMimeTypes = QImageReader::supportedMimeTypes();
+ for (const QByteArray &m : supportedMimeTypes) {
+ const auto suffixes = mimeDatabase.mimeTypeForName(m).suffixes();
+ for (const QString &suffix : suffixes)
+ result.append(QLatin1String("*.") + suffix);
}
return result;
}
diff --git a/examples/quick/embeddedinwidgets/main.cpp b/examples/quick/embeddedinwidgets/main.cpp
index 96b0df7e13..91147772ba 100644
--- a/examples/quick/embeddedinwidgets/main.cpp
+++ b/examples/quick/embeddedinwidgets/main.cpp
@@ -103,7 +103,8 @@ void MainWindow::quickViewStatusChanged(QQuickView::Status status)
{
if (status == QQuickView::Error) {
QStringList errors;
- foreach (const QQmlError &error, m_quickView->errors())
+ const auto viewErrors = m_quickView->errors();
+ for (const QQmlError &error : viewErrors)
errors.append(error.toString());
statusBar()->showMessage(errors.join(QStringLiteral(", ")));
}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
index c5924bf159..49c4450b89 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
@@ -263,8 +263,8 @@ static const char *fragmentShaderSource =
void FbItemRenderer::initProgram()
{
m_program.reset(new QOpenGLShaderProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1);
m_program->link();
diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp
index 6bb6722e02..7cb35d7bcd 100644
--- a/examples/quick/quickwidgets/quickwidget/main.cpp
+++ b/examples/quick/quickwidgets/quickwidget/main.cpp
@@ -133,7 +133,8 @@ void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status)
{
if (status == QQuickWidget::Error) {
QStringList errors;
- foreach (const QQmlError &error, m_quickWidget->errors())
+ const auto widgetErrors = m_quickWidget->errors();
+ for (const QQmlError &error : widgetErrors)
errors.append(error.toString());
statusBar()->showMessage(errors.join(QStringLiteral(", ")));
}
diff --git a/examples/quick/rendercontrol/cuberenderer.cpp b/examples/quick/rendercontrol/cuberenderer.cpp
index 1b2d7dec8f..4651882542 100644
--- a/examples/quick/rendercontrol/cuberenderer.cpp
+++ b/examples/quick/rendercontrol/cuberenderer.cpp
@@ -101,8 +101,8 @@ void CubeRenderer::init(QWindow *w, QOpenGLContext *share)
" gl_FragColor = vec4(texture2D(sampler, v_coord).rgb, 1.0);\n"
"}\n";
m_program = new QOpenGLShaderProgram;
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("coord", 1);
m_program->link();
diff --git a/examples/quick/rendercontrol/window_multithreaded.cpp b/examples/quick/rendercontrol/window_multithreaded.cpp
index 4df3488ab3..013ee7c208 100644
--- a/examples/quick/rendercontrol/window_multithreaded.cpp
+++ b/examples/quick/rendercontrol/window_multithreaded.cpp
@@ -356,16 +356,16 @@ void WindowMultiThreaded::run()
disconnect(m_qmlComponent, &QQmlComponent::statusChanged, this, &WindowMultiThreaded::run);
if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- foreach (const QQmlError &error, errorList)
+ const QList<QQmlError> errorList = m_qmlComponent->errors();
+ for (const QQmlError &error : errorList)
qWarning() << error.url() << error.line() << error;
return;
}
QObject *rootObject = m_qmlComponent->create();
if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- foreach (const QQmlError &error, errorList)
+ const QList<QQmlError> errorList = m_qmlComponent->errors();
+ for (const QQmlError &error : errorList)
qWarning() << error.url() << error.line() << error;
return;
}
diff --git a/examples/quick/rendercontrol/window_singlethreaded.cpp b/examples/quick/rendercontrol/window_singlethreaded.cpp
index 45f2635ca4..ef8f2fed43 100644
--- a/examples/quick/rendercontrol/window_singlethreaded.cpp
+++ b/examples/quick/rendercontrol/window_singlethreaded.cpp
@@ -209,16 +209,16 @@ void WindowSingleThreaded::run()
disconnect(m_qmlComponent, &QQmlComponent::statusChanged, this, &WindowSingleThreaded::run);
if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- foreach (const QQmlError &error, errorList)
+ const QList<QQmlError> errorList = m_qmlComponent->errors();
+ for (const QQmlError &error : errorList)
qWarning() << error.url() << error.line() << error;
return;
}
QObject *rootObject = m_qmlComponent->create();
if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- foreach (const QQmlError &error, errorList)
+ const QList<QQmlError> errorList = m_qmlComponent->errors();
+ for (const QQmlError &error : errorList)
qWarning() << error.url() << error.line() << error;
return;
}
diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp
index 6b25756e61..b7082892b8 100644
--- a/examples/quick/scenegraph/openglunderqml/squircle.cpp
+++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp
@@ -125,22 +125,22 @@ void SquircleRenderer::paint()
initializeOpenGLFunctions();
m_program = new QOpenGLShaderProgram();
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
- "attribute highp vec4 vertices;"
- "varying highp vec2 coords;"
- "void main() {"
- " gl_Position = vertices;"
- " coords = vertices.xy;"
- "}");
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
- "uniform lowp float t;"
- "varying highp vec2 coords;"
- "void main() {"
- " lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
- " i = smoothstep(t - 0.8, t + 0.8, i);"
- " i = floor(i * 20.) / 20.;"
- " gl_FragColor = vec4(coords * .5 + .5, i, i);"
- "}");
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
+ "attribute highp vec4 vertices;"
+ "varying highp vec2 coords;"
+ "void main() {"
+ " gl_Position = vertices;"
+ " coords = vertices.xy;"
+ "}");
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
+ "uniform lowp float t;"
+ "varying highp vec2 coords;"
+ "void main() {"
+ " lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
+ " i = smoothstep(t - 0.8, t + 0.8, i);"
+ " i = floor(i * 20.) / 20.;"
+ " gl_FragColor = vec4(coords * .5 + .5, i, i);"
+ "}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
index 65c2a210bc..c84867797d 100644
--- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp
+++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
@@ -86,8 +86,8 @@ void OpenGLRenderNode::init()
" gl_FragColor = col * opacity;\n"
"}\n";
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->bindAttributeLocation("posAttr", 0);
m_program->bindAttributeLocation("colAttr", 1);
m_program->link();
diff --git a/examples/quick/scenegraph/sgengine/window.cpp b/examples/quick/scenegraph/sgengine/window.cpp
index 2e4a70d2af..759bbf1fcd 100644
--- a/examples/quick/scenegraph/sgengine/window.cpp
+++ b/examples/quick/scenegraph/sgengine/window.cpp
@@ -187,7 +187,7 @@ void Window::update()
void Window::sync()
{
QList<QSharedPointer<Item> > validItems;
- foreach (QSharedPointer<Item> item, m_items) {
+ for (QSharedPointer<Item> item : qAsConst(m_items)) {
if (!item->isDone()) {
validItems.append(item);
item->sync();
diff --git a/examples/quick/scenegraph/shared/logorenderer.cpp b/examples/quick/scenegraph/shared/logorenderer.cpp
index 06f4892a49..8eb2d44c1e 100644
--- a/examples/quick/scenegraph/shared/logorenderer.cpp
+++ b/examples/quick/scenegraph/shared/logorenderer.cpp
@@ -70,7 +70,6 @@ void LogoRenderer::initialize()
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
- QOpenGLShader *vshader1 = new QOpenGLShader(QOpenGLShader::Vertex, &program1);
const char *vsrc1 =
"attribute highp vec4 vertex;\n"
"attribute mediump vec3 normal;\n"
@@ -85,19 +84,16 @@ void LogoRenderer::initialize()
" color = clamp(color, 0.0, 1.0);\n"
" gl_Position = matrix * vertex;\n"
"}\n";
- vshader1->compileSourceCode(vsrc1);
- QOpenGLShader *fshader1 = new QOpenGLShader(QOpenGLShader::Fragment, &program1);
const char *fsrc1 =
"varying mediump vec4 color;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = color;\n"
"}\n";
- fshader1->compileSourceCode(fsrc1);
- program1.addShader(vshader1);
- program1.addShader(fshader1);
+ program1.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vsrc1);
+ program1.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fsrc1);
program1.link();
vertexAttr1 = program1.attributeLocation("vertex");
diff --git a/examples/quick/scenegraph/textureinthread/main.cpp b/examples/quick/scenegraph/textureinthread/main.cpp
index 22550cd22b..61d1c5e6dc 100644
--- a/examples/quick/scenegraph/textureinthread/main.cpp
+++ b/examples/quick/scenegraph/textureinthread/main.cpp
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
// As the render threads make use of our QGuiApplication object
// to clean up gracefully, wait for them to finish before
// QGuiApp is taken off the heap.
- foreach (QThread *t, ThreadRenderer::threads) {
+ for (QThread *t : qAsConst(ThreadRenderer::threads)) {
t->wait();
delete t;
}
diff --git a/examples/quick/shared/Label.qml b/examples/quick/shared/Label.qml
new file mode 100644
index 0000000000..ea4bef5415
--- /dev/null
+++ b/examples/quick/shared/Label.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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
+
+Text {
+ SystemPalette { id: palette }
+ color: palette.text
+}
diff --git a/examples/quick/shared/quick_shared.qrc b/examples/quick/shared/quick_shared.qrc
index ea7e0fdd89..21f393a64d 100644
--- a/examples/quick/shared/quick_shared.qrc
+++ b/examples/quick/shared/quick_shared.qrc
@@ -4,6 +4,7 @@
<file>SimpleLauncherDelegate.qml</file>
<file>Button.qml</file>
<file>CheckBox.qml</file>
+ <file>Label.qml</file>
<file>TextField.qml</file>
<file>images/back.png</file>
<file>images/next.png</file>
diff --git a/examples/quick/shared/shared.qrc b/examples/quick/shared/shared.qrc
index 7e0c66c34b..89b3ff757e 100644
--- a/examples/quick/shared/shared.qrc
+++ b/examples/quick/shared/shared.qrc
@@ -6,6 +6,7 @@
<file>Slider.qml</file>
<file>images/slider_handle.png</file>
<file>CheckBox.qml</file>
+ <file>Label.qml</file>
<file>TabSet.qml</file>
<file>TextField.qml</file>
<file>images/back.png</file>
diff --git a/examples/quick/window/AllScreens.qml b/examples/quick/window/AllScreens.qml
new file mode 100644
index 0000000000..83a6c5f958
--- /dev/null
+++ b/examples/quick/window/AllScreens.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.3
+import QtQuick.Window 2.3
+import "../shared" as Shared
+
+Column {
+ id: root
+ spacing: 8
+
+ Shared.Label {
+ text: "Total number of screens: " + screenInfo.count
+ font.bold: true
+ }
+
+ Flow {
+ spacing: 12
+ width: parent.width
+
+ Repeater {
+ id: screenInfo
+ model: Qt.application.screens
+ Shared.Label {
+ lineHeight: 1.5
+ text: name + "\n" + virtualX + ", " + virtualY + " " + modelData.width + "x" + modelData.height
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ var screens = Qt.application.screens;
+ for (var i = 0; i < screens.length; ++i)
+ console.log("screen " + screens[i].name + " has geometry " +
+ screens[i].virtualX + ", " + screens[i].virtualY + " " +
+ screens[i].width + "x" + screens[i].height)
+ }
+}
diff --git a/examples/quick/window/ScreenInfo.qml b/examples/quick/window/CurrentScreen.qml
index ee0a31c794..c65baab1f4 100644
--- a/examples/quick/window/ScreenInfo.qml
+++ b/examples/quick/window/CurrentScreen.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@@ -40,6 +40,7 @@
import QtQuick 2.3
import QtQuick.Window 2.1
+import "../shared" as Shared
Item {
id: root
@@ -70,32 +71,35 @@ Item {
y: spacing
//! [screen]
- Text {
+ Shared.Label {
text: "Screen \"" + Screen.name + "\":"
font.bold: true
}
Item { width: 1; height: 1 } // spacer
- Text { text: "dimensions" }
- Text { text: Screen.width + "x" + Screen.height }
+ Shared.Label { text: "dimensions" }
+ Shared.Label { text: Screen.width + "x" + Screen.height }
- Text { text: "pixel density" }
- Text { text: Screen.pixelDensity.toFixed(2) + " dots/mm (" + (Screen.pixelDensity * 25.4).toFixed(2) + " dots/inch)" }
+ Shared.Label { text: "pixel density" }
+ Shared.Label { text: Screen.pixelDensity.toFixed(2) + " dots/mm (" + (Screen.pixelDensity * 25.4).toFixed(2) + " dots/inch)" }
- Text { text: "logical pixel density" }
- Text { text: Screen.logicalPixelDensity.toFixed(2) + " dots/mm (" + (Screen.logicalPixelDensity * 25.4).toFixed(2) + " dots/inch)" }
+ Shared.Label { text: "logical pixel density" }
+ Shared.Label { text: Screen.logicalPixelDensity.toFixed(2) + " dots/mm (" + (Screen.logicalPixelDensity * 25.4).toFixed(2) + " dots/inch)" }
- Text { text: "device pixel ratio" }
- Text { text: Screen.devicePixelRatio.toFixed(2) }
+ Shared.Label { text: "device pixel ratio" }
+ Shared.Label { text: Screen.devicePixelRatio.toFixed(2) }
- Text { text: "available virtual desktop" }
- Text { text: Screen.desktopAvailableWidth + "x" + Screen.desktopAvailableHeight }
+ Shared.Label { text: "available virtual desktop" }
+ Shared.Label { text: Screen.desktopAvailableWidth + "x" + Screen.desktopAvailableHeight }
- Text { text: "orientation" }
- Text { text: orientationToString(Screen.orientation) + " (" + Screen.orientation + ")" }
+ Shared.Label { text: "position in virtual desktop" }
+ Shared.Label { text: Screen.virtualX + ", " + Screen.virtualY }
- Text { text: "primary orientation" }
- Text { text: orientationToString(Screen.primaryOrientation) + " (" + Screen.primaryOrientation + ")" }
+ Shared.Label { text: "orientation" }
+ Shared.Label { text: orientationToString(Screen.orientation) + " (" + Screen.orientation + ")" }
+
+ Shared.Label { text: "primary orientation" }
+ Shared.Label { text: orientationToString(Screen.primaryOrientation) + " (" + Screen.primaryOrientation + ")" }
//! [screen]
}
}
diff --git a/examples/quick/window/Splash.qml b/examples/quick/window/Splash.qml
index 083c3babc8..3baf207992 100644
--- a/examples/quick/window/Splash.qml
+++ b/examples/quick/window/Splash.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
diff --git a/examples/quick/window/doc/src/window.qdoc b/examples/quick/window/doc/src/window.qdoc
index 5cd51beceb..2028b31383 100644
--- a/examples/quick/window/doc/src/window.qdoc
+++ b/examples/quick/window/doc/src/window.qdoc
@@ -73,7 +73,7 @@
\l Screen has several properties which are generally useful to
applications which need to rotate some content when the screen orientation
changes, to position windows on the screen or to convert real units to
- logical pixel units. ScreenInfo.qml (which is displayed inline in
+ logical pixel units. CurrentScreen.qml (which is displayed inline in
window.qml, or can be run by itself with qmlscene) simply displays the
property values, while the splash screen uses them to center the window on
the screen.
diff --git a/examples/quick/window/main.cpp b/examples/quick/window/main.cpp
index bacf52af15..ee8855cbc8 100644
--- a/examples/quick/window/main.cpp
+++ b/examples/quick/window/main.cpp
@@ -49,7 +49,8 @@
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
- foreach (QScreen * screen, QGuiApplication::screens())
+ const auto screens = QGuiApplication::screens();
+ for (QScreen *screen : screens)
screen->setOrientationUpdateMask(Qt::LandscapeOrientation | Qt::PortraitOrientation |
Qt::InvertedLandscapeOrientation | Qt::InvertedPortraitOrientation);
QQmlEngine engine;
diff --git a/examples/quick/window/window.qml b/examples/quick/window/window.qml
index d50bce61b3..d27ab3d0a3 100644
--- a/examples/quick/window/window.qml
+++ b/examples/quick/window/window.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Window 2.1
+import QtQuick.Window 2.3
import "../shared" as Shared
QtObject {
@@ -47,7 +47,7 @@ QtObject {
property SystemPalette palette: SystemPalette { }
property var controlWindow: Window {
- width: visibilityLabel.implicitWidth * 1.2
+ width: col.implicitWidth + defaultSpacing * 2
height: col.implicitHeight + defaultSpacing * 2
color: palette.window
title: "Control Window"
@@ -57,7 +57,7 @@ QtObject {
anchors.margins: defaultSpacing
spacing: defaultSpacing
property real cellWidth: col.width / 3 - spacing
- Text { text: "Control the second window:" }
+ Shared.Label { text: "Control the second window:" }
Grid {
id: grid
columns: 3
@@ -121,18 +121,23 @@ QtObject {
}
return "unknown";
}
- Text {
+ Shared.Label {
id: visibilityLabel
text: "second window is " + (testWindow.visible ? "visible" : "invisible") +
" and has visibility " + parent.visibilityToString(testWindow.visibility)
}
Rectangle {
- id: horizontalRule
- color: "black"
+ color: palette.text
width: parent.width
height: 1
}
- ScreenInfo { }
+ CurrentScreen { }
+ Rectangle {
+ color: palette.text
+ width: parent.width
+ height: 1
+ }
+ AllScreens { width: parent.width }
}
}
@@ -145,7 +150,7 @@ QtObject {
Rectangle {
anchors.fill: parent
anchors.margins: defaultSpacing
- Text {
+ Shared.Label {
anchors.centerIn: parent
text: "Second Window"
}
diff --git a/examples/quick/window/window.qrc b/examples/quick/window/window.qrc
index dc211bdaaf..89d1de1b1f 100644
--- a/examples/quick/window/window.qrc
+++ b/examples/quick/window/window.qrc
@@ -2,6 +2,7 @@
<qresource prefix="/window">
<file>window.qml</file>
<file>Splash.qml</file>
- <file>ScreenInfo.qml</file>
+ <file>CurrentScreen.qml</file>
+ <file>AllScreens.qml</file>
</qresource>
</RCC>
diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h
index 75da12a421..b505ece750 100644
--- a/src/imports/folderlistmodel/fileinfothread_p.h
+++ b/src/imports/folderlistmodel/fileinfothread_p.h
@@ -94,7 +94,7 @@ public Q_SLOTS:
#endif
protected:
- void run();
+ void run() override;
void getFileInfos(const QString &path);
void findChangeRange(const QList<FileProperty> &list, int &fromIndex, int &toIndex);
diff --git a/src/imports/folderlistmodel/fileproperty_p.h b/src/imports/folderlistmodel/fileproperty_p.h
index f385cdfdb4..48be4a3d85 100644
--- a/src/imports/folderlistmodel/fileproperty_p.h
+++ b/src/imports/folderlistmodel/fileproperty_p.h
@@ -57,17 +57,17 @@
class FileProperty
{
public:
- FileProperty(const QFileInfo &info)
+ FileProperty(const QFileInfo &info) :
+ mFileName(info.fileName()),
+ mFilePath(info.filePath()),
+ mBaseName(info.baseName()),
+ mSuffix(info.completeSuffix()),
+ mSize(info.size()),
+ mIsDir(info.isDir()),
+ mIsFile(info.isFile()),
+ mLastModified(info.lastModified()),
+ mLastRead(info.lastRead())
{
- mFileName = info.fileName();
- mFilePath = info.filePath();
- mBaseName = info.baseName();
- mSize = info.size();
- mSuffix = info.completeSuffix();
- mIsDir = info.isDir();
- mIsFile = info.isFile();
- mLastModified = info.lastModified();
- mLastRead = info.lastRead();
}
~FileProperty()
{}
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index aae6df452d..dee73dff3e 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -94,10 +94,10 @@ public:
FileUrlRole = Qt::UserRole + 9
};
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
- virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- virtual QHash<int, QByteArray> roleNames() const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QHash<int, QByteArray> roleNames() const override;
//![abslistmodel]
//![count]
@@ -144,8 +144,8 @@ public:
Q_INVOKABLE int indexOf(const QUrl &file) const;
//![parserstatus]
- virtual void classBegin();
- virtual void componentComplete();
+ void classBegin() override;
+ void componentComplete() override;
//![parserstatus]
int roleFromString(const QString &roleName) const;
diff --git a/src/imports/layouts/qquickgridlayoutengine_p.h b/src/imports/layouts/qquickgridlayoutengine_p.h
index 86f56a5af4..2810e2e5d0 100644
--- a/src/imports/layouts/qquickgridlayoutengine_p.h
+++ b/src/imports/layouts/qquickgridlayoutengine_p.h
@@ -67,7 +67,7 @@ public:
: QGridLayoutItem(row, column, rowSpan, columnSpan, alignment), m_item(item), sizeHintCacheDirty(true), useFallbackToWidthOrHeight(true) {}
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const override
{
Q_UNUSED(constraint); // Quick Layouts does not support constraint atm
return effectiveSizeHints()[which];
@@ -99,12 +99,12 @@ public:
sizeHintCacheDirty = true;
}
- QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const
+ QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const override
{
return QQuickLayout::effectiveSizePolicy_helper(m_item, orientation, attachedLayoutObject(m_item, false));
}
- void setGeometry(const QRectF &rect)
+ void setGeometry(const QRectF &rect) override
{
QQuickLayoutAttached *info = attachedLayoutObject(m_item, false);
const QRectF r = info ? rect.marginsRemoved(info->qMargins()) : rect;
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index c289416540..b425df0fa4 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -157,7 +157,7 @@ public:
Flow flow() const;
void setFlow(Flow flow);
- void insertLayoutItems();
+ void insertLayoutItems() override;
signals:
void columnSpacingChanged();
@@ -199,7 +199,7 @@ public:
qreal spacing() const;
void setSpacing(qreal spacing);
- void insertLayoutItems();
+ void insertLayoutItems() override;
signals:
void spacingChanged();
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 6704283cb9..d3ea93c80a 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -812,7 +812,7 @@ public:
}
void registerTypes(const char *uri) Q_DECL_OVERRIDE
{
- Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage");
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.LocalStorage"));
qmlRegisterSingletonType<QQuickLocalStorage>(uri, 2, 0, "LocalStorage", module_api_factory);
}
};
diff --git a/src/imports/settings/qqmlsettings_p.h b/src/imports/settings/qqmlsettings_p.h
index 0ed55579dd..ce942d7564 100644
--- a/src/imports/settings/qqmlsettings_p.h
+++ b/src/imports/settings/qqmlsettings_p.h
@@ -74,10 +74,10 @@ public:
void setCategory(const QString &category);
protected:
- void timerEvent(QTimerEvent *event);
+ void timerEvent(QTimerEvent *event) override;
- void classBegin();
- void componentComplete();
+ void classBegin() override;
+ void componentComplete() override;
private:
Q_DISABLE_COPY(QQmlSettings)
diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h
index 73e4ecda6b..8e8cefab19 100644
--- a/src/imports/statemachine/state.h
+++ b/src/imports/statemachine/state.h
@@ -58,8 +58,8 @@ class State : public QState, public QQmlParserStatus
public:
explicit State(QState *parent = 0);
- void classBegin() {}
- void componentComplete();
+ void classBegin() override {}
+ void componentComplete() override;
QQmlListProperty<QObject> children();
diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h
index 59a810f387..cb0ab43f8b 100644
--- a/src/imports/statemachine/statemachine.h
+++ b/src/imports/statemachine/statemachine.h
@@ -62,8 +62,8 @@ class StateMachine : public QStateMachine, public QQmlParserStatus
public:
explicit StateMachine(QObject *parent = 0);
- void classBegin() {}
- void componentComplete();
+ void classBegin() override {}
+ void componentComplete() override;
QQmlListProperty<QObject> children();
bool isRunning() const;
diff --git a/src/imports/statemachine/timeouttransition.h b/src/imports/statemachine/timeouttransition.h
index 5d71e86bb4..0e5f5377e3 100644
--- a/src/imports/statemachine/timeouttransition.h
+++ b/src/imports/statemachine/timeouttransition.h
@@ -59,8 +59,8 @@ public:
int timeout() const;
void setTimeout(int timeout);
- void classBegin() {}
- void componentComplete();
+ void classBegin() override {}
+ void componentComplete() override;
Q_SIGNALS:
void timeoutChanged();
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index d22ec7c44f..18c70e1169 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -206,6 +206,59 @@ import Qt.test.qtestroot 1.0
will fail. Use the \l when and windowShown properties to track
when the main window has been shown.
+ \section1 Managing Dynamically Created Test Objects
+
+ A typical pattern with QML tests is to
+ \l {Dynamic QML Object Creation from JavaScript}{dynamically create}
+ an item and then destroy it at the end of the test function:
+
+ \code
+ TestCase {
+ id: testCase
+ name: "MyTest"
+ when: windowShown
+
+ function test_click() {
+ var item = Qt.createQmlObject("import QtQuick 2.0; Item {}", testCase);
+ verify(item);
+
+ // Test item...
+
+ item.destroy();
+ }
+ }
+ \endcode
+
+ The problem with this pattern is that any failures in the test function
+ will cause the call to \c item.destroy() to be skipped, leaving the item
+ hanging around in the scene until the test case has finished. This can
+ result in interference with future tests; for example, by blocking input
+ events or producing unrelated debug output that makes it difficult to
+ follow the code's execution.
+
+ By calling \l createTemporaryQmlObject() instead, the object is guaranteed
+ to be destroyed at the end of the test function:
+
+ \code
+ TestCase {
+ id: testCase
+ name: "MyTest"
+ when: windowShown
+
+ function test_click() {
+ var item = createTemporaryQmlObject("import QtQuick 2.0; Item {}", testCase);
+ verify(item);
+
+ // Test item...
+
+ // Don't need to worry about destroying "item" here.
+ }
+ }
+ \endcode
+
+ For objects that are created via the \l {Component::}{createObject()} function
+ of \l Component, the \l createTemporaryObject() function can be used.
+
\sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test Reference Documentation}
*/
@@ -358,6 +411,8 @@ Item {
/*! \internal */
property var qtest_events: qtest_events_normal
TestEvent { id: qtest_events_normal }
+ /*! \internal */
+ property var qtest_temporaryObjects: []
/*!
\qmlmethod TestCase::fail(message = "")
@@ -461,6 +516,105 @@ Item {
throw new Error("QtQuickTest::fail")
}
+ /*!
+ \since 5.9
+ \qmlmethod object TestCase::createTemporaryQmlObject(string qml, object parent, string filePath)
+
+ This function dynamically creates a QML object from the given \a qml
+ string with the specified \a parent. The returned object will be
+ destroyed (if it was not already) after \l cleanup() has finished
+ executing, meaning that objects created with this function are
+ guaranteed to be destroyed after each test, regardless of whether or
+ not the tests fail.
+
+ If there was an error while creating the object, \c null will be
+ returned.
+
+ If \a filePath is specified, it will be used for error reporting for
+ the created object.
+
+ This function calls
+ \l {QtQml::Qt::createQmlObject()}{Qt.createQmlObject()} internally.
+
+ \sa {Managing Dynamically Created Test Objects}
+ */
+ function createTemporaryQmlObject(qml, parent, filePath) {
+ if (typeof qml !== "string") {
+ qtest_results.fail("First argument must be a string of QML; actual type is " + typeof qml,
+ util.callerFile(), util.callerLine());
+ throw new Error("QtQuickTest::fail");
+ }
+
+ if (!parent || typeof parent !== "object") {
+ qtest_results.fail("Second argument must be a valid parent object; actual type is " + typeof parent,
+ util.callerFile(), util.callerLine());
+ throw new Error("QtQuickTest::fail");
+ }
+
+ if (filePath !== undefined && typeof filePath !== "string") {
+ qtest_results.fail("Third argument must be a file path string; actual type is " + typeof filePath,
+ util.callerFile(), util.callerLine());
+ throw new Error("QtQuickTest::fail");
+ }
+
+ var object = Qt.createQmlObject(qml, parent, filePath);
+ qtest_temporaryObjects.push(object);
+ return object;
+ }
+
+ /*!
+ \since 5.9
+ \qmlmethod object TestCase::createTemporaryObject(Component component, object parent, object properties)
+
+ This function dynamically creates a QML object from the given
+ \a component with the specified optional \a parent and \a properties.
+ The returned object will be destroyed (if it was not already) after
+ \l cleanup() has finished executing, meaning that objects created with
+ this function are guaranteed to be destroyed after each test,
+ regardless of whether or not the tests fail.
+
+ If there was an error while creating the object, \c null will be
+ returned.
+
+ This function calls
+ \l {QtQml::Component::createObject()}{component.createObject()}
+ internally.
+
+ \sa {Managing Dynamically Created Test Objects}
+ */
+ function createTemporaryObject(component, parent, properties) {
+ if (typeof component !== "object") {
+ qtest_results.fail("First argument must be a Component; actual type is " + typeof component,
+ util.callerFile(), util.callerLine());
+ throw new Error("QtQuickTest::fail");
+ }
+
+ if (properties && typeof properties !== "object") {
+ qtest_results.fail("Third argument must be an object; actual type is " + typeof properties,
+ util.callerFile(), util.callerLine());
+ throw new Error("QtQuickTest::fail");
+ }
+
+ var object = component.createObject(parent, properties ? properties : ({}));
+ qtest_temporaryObjects.push(object);
+ return object;
+ }
+
+ /*!
+ \internal
+
+ Destroys all temporary objects that still exist.
+ */
+ function qtest_destroyTemporaryObjects() {
+ for (var i = 0; i < qtest_temporaryObjects.length; ++i) {
+ var temporaryObject = qtest_temporaryObjects[i];
+ // ### the typeof check can be removed when QTBUG-57749 is fixed
+ if (temporaryObject && typeof temporaryObject.destroy === "function")
+ temporaryObject.destroy();
+ }
+ qtest_temporaryObjects = [];
+ }
+
/*! \internal */
// Determine what is o.
// Discussions and reference: http://philrathe.com/articles/equiv
@@ -1317,6 +1471,109 @@ Item {
qtest_fail("window not shown", 2)
}
+ /*!
+ \qmlmethod TouchEventSequence TestCase::touchEvent(object item)
+
+ \since 5.9
+
+ Begins a sequence of touch events through a simulated QTouchDevice::TouchScreen.
+ Events are delivered to the window containing \a item.
+
+ The returned object is used to enumerate events to be delivered through a single
+ QTouchEvent. Touches are delivered to the window containing the TestCase unless
+ otherwise specified.
+
+ \code
+ Rectangle {
+ width: 640; height: 480
+
+ MultiPointTouchArea {
+ id: area
+ anchors.fill: parent
+
+ property bool touched: false
+
+ onPressed: touched = true
+ }
+
+ TestCase {
+ name: "ItemTests"
+ when: area.pressed
+ id: test1
+
+ function test_touch() {
+ var touch = touchEvent(area);
+ touch.press(0, area, 10, 10);
+ touch.commit();
+ verify(area.touched);
+ }
+ }
+ }
+ \endcode
+
+ \sa TouchEventSequence::press(), TouchEventSequence::move(), TouchEventSequence::release(), TouchEventSequence::stationary(), TouchEventSequence::commit(), QTouchDevice::TouchScreen
+ */
+
+ function touchEvent(item) {
+ if (!item)
+ qtest_fail("No item given to touchEvent", 1)
+
+ return {
+ _defaultItem: item,
+ _sequence: qtest_events.touchEvent(item),
+
+ press: function (id, target, x, y) {
+ if (!target)
+ target = this._defaultItem;
+ if (id === undefined)
+ qtest_fail("No id given to TouchEventSequence::press", 1);
+ if (x === undefined)
+ x = target.width / 2;
+ if (y === undefined)
+ y = target.height / 2;
+ this._sequence.press(id, target, x, y);
+ return this;
+ },
+
+ move: function (id, target, x, y) {
+ if (!target)
+ target = this._defaultItem;
+ if (id === undefined)
+ qtest_fail("No id given to TouchEventSequence::move", 1);
+ if (x === undefined)
+ x = target.width / 2;
+ if (y === undefined)
+ y = target.height / 2;
+ this._sequence.move(id, target, x, y);
+ return this;
+ },
+
+ stationary: function (id) {
+ if (id === undefined)
+ qtest_fail("No id given to TouchEventSequence::stationary", 1);
+ this._sequence.stationary(id);
+ return this;
+ },
+
+ release: function (id, target, x, y) {
+ if (!target)
+ target = this._defaultItem;
+ if (id === undefined)
+ qtest_fail("No id given to TouchEventSequence::release", 1);
+ if (x === undefined)
+ x = target.width / 2;
+ if (y === undefined)
+ y = target.height / 2;
+ this._sequence.release(id, target, x, y);
+ return this;
+ },
+
+ commit: function () {
+ this._sequence.commit();
+ return this;
+ }
+ };
+ }
// Functions that can be overridden in subclasses for init/cleanup duties.
/*!
@@ -1389,6 +1646,7 @@ Item {
qtest_runInternal(prop, arg)
qtest_results.finishTestData()
qtest_runInternal("cleanup")
+ qtest_destroyTemporaryObjects()
qtest_results.finishTestDataCleanup()
// wait(0) will call processEvents() so objects marked for deletion
// in the test function will be deleted.
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 4e2bd919e9..3c28000e35 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -158,6 +158,7 @@ public:
qmlRegisterType<QuickTestResult, 1>(uri,1,1,"TestResult");
qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent");
qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil");
+ qmlRegisterType<QQuickTouchEventSequence>();
}
};
diff --git a/src/imports/testlib/qmldir b/src/imports/testlib/qmldir
index 9da8ebb4be..e5757f6a88 100644
--- a/src/imports/testlib/qmldir
+++ b/src/imports/testlib/qmldir
@@ -3,4 +3,5 @@ plugin qmltestplugin
classname QTestQmlModule
typeinfo plugins.qmltypes
TestCase 1.0 TestCase.qml
+TestCase 1.2 TestCase.qml
SignalSpy 1.0 SignalSpy.qml
diff --git a/src/imports/testlib/toucheventsequence.qdoc b/src/imports/testlib/toucheventsequence.qdoc
new file mode 100644
index 0000000000..f85a1cd4f9
--- /dev/null
+++ b/src/imports/testlib/toucheventsequence.qdoc
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jeremy Katz
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmltype TouchEventSequence
+ \inqmlmodule QtTest
+ \ingroup qtquicktest
+ \brief TouchEventSequence is used to build and dispatch touch events
+ for testing.
+
+ \since 5.9
+
+ A TouchEventSequence is created by calling \l [QML] {TestCase::touchEvent()}{TestCase.touchEvent()}.
+ The type can not be directly instantiated. Each method provided by the type returns
+ the same object, allowing chained calls.
+
+ For example:
+ \code
+ touchEvent(item).press(0).commit();
+ \endcode
+ is equivalent to:
+ \code
+ var sequence = touchEvent(item);
+ sequence.press(0);
+ sequence.commit();
+ \endcode
+
+ Events are delivered to the window which contains the item specified in touchEvent.
+
+ \sa TestCase::touchEvent(), QTest::QTouchEventSequence
+*/
+
+/*!
+ \qmlmethod TouchEventSequence TouchEventSequence::press(int touchId, object item, real x = item.width / 2, real y = item.height / 2)
+
+ Creates a new point identified as \a touchId, at the point indicated by \a x and \a y relative to \a item.
+ Further use of the same touch point should maintain the same touchId.
+
+ Item defaults to the value provided via touchEvent().
+ X and y default to the midpoint of the item.
+*/
+
+/*!
+ \qmlmethod TouchEventSequence TouchEventSequence::move(int touchId, object item, real x = item.width / 2, real y = item.height / 2)
+
+ Moves \a touchId to the point indicated by \a x and \a y relative to \a item.
+
+ Item defaults to the value provided via touchEvent().
+ X and y default to the midpoint of the item.
+*/
+
+/*!
+ \qmlmethod TouchEventSequence TouchEventSequence::release(int touchId, object item, real x = item.width / 2, real y = item.height / 2)
+
+ Removes \a touchId at the point indicated by \a x and \a y relative to \a item.
+
+ Item defaults to the value provided via touchEvent().
+ X and y default to the midpoint of the item.
+*/
+
+/*!
+ \qmlmethod TouchEventSequence TouchEventSequence::stationary(int touchId)
+
+ Indicates that \a touchId is present but otherwise unchanged from prior events.
+*/
+
+/*!
+ \qmlmethod TouchEventSequence TouchEventSequence::commit()
+
+ Sends the touch event composed by prior use of press(), move(), release(), and stationary().
+ Following commit's return, the TouchEventSequence can be used to compose a new event.
+
+ \code
+ var sequence = touchEvent(target);
+ // Touch the middle of target with 1 point
+ sequence.press(1);
+ sequence.commit();
+
+ // Begin a new event
+ // Move the point to target's upper left corner
+ sequence.move(1, target, 0, 0);
+ sequence.commit();
+ \endcode
+
+ Commit is automatically invoked when the TouchEventSequence object is destroyed.
+*/
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index 6e9e57a046..4306f477e9 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -176,7 +176,7 @@ public:
QQuickXmlQueryThreadObject(QQuickXmlQueryEngine *);
void processJobs();
- virtual bool event(QEvent *e);
+ bool event(QEvent *e) override;
private:
QQuickXmlQueryEngine *m_queryEngine;
@@ -202,7 +202,7 @@ signals:
void error(void*, const QString&);
protected:
- void run();
+ void run() override;
private:
void processQuery(XmlQueryJob *job);
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
index f0096a9125..3a4487a085 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
@@ -95,10 +95,10 @@ public:
QQuickXmlListModel(QObject *parent = 0);
~QQuickXmlListModel();
- QModelIndex index(int row, int column, const QModelIndex &parent) const;
- int rowCount(const QModelIndex &parent) const;
- QVariant data(const QModelIndex &index, int role) const;
- QHash<int, QByteArray> roleNames() const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const override;
+ int rowCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ QHash<int, QByteArray> roleNames() const override;
int count() const;
@@ -124,8 +124,8 @@ public:
Q_INVOKABLE QString errorString() const;
- virtual void classBegin();
- virtual void componentComplete();
+ void classBegin() override;
+ void componentComplete() override;
Q_SIGNALS:
void statusChanged(QQuickXmlListModel::Status);
@@ -194,7 +194,7 @@ public:
Q_EMIT isKeyChanged();
}
- bool isValid() {
+ bool isValid() const {
return !m_name.isEmpty() && !m_query.isEmpty();
}
diff --git a/src/particles/qquickage_p.h b/src/particles/qquickage_p.h
index f6e277f8a7..5db6167dc1 100644
--- a/src/particles/qquickage_p.h
+++ b/src/particles/qquickage_p.h
@@ -74,7 +74,8 @@ public:
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
Q_SIGNALS:
void lifeLeftChanged(int arg);
void advancePositionChanged(bool arg);
diff --git a/src/particles/qquickangledirection.cpp b/src/particles/qquickangledirection.cpp
index 09aa047670..6f30e24a26 100644
--- a/src/particles/qquickangledirection.cpp
+++ b/src/particles/qquickangledirection.cpp
@@ -104,7 +104,7 @@ QQuickAngleDirection::QQuickAngleDirection(QObject *parent) :
}
-const QPointF QQuickAngleDirection::sample(const QPointF &from)
+QPointF QQuickAngleDirection::sample(const QPointF &from)
{
Q_UNUSED(from);
QPointF ret;
diff --git a/src/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h
index 3e981c5f9e..66290fb19e 100644
--- a/src/particles/qquickangledirection_p.h
+++ b/src/particles/qquickangledirection_p.h
@@ -62,7 +62,7 @@ class QQuickAngleDirection : public QQuickDirection
Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged)
public:
explicit QQuickAngleDirection(QObject *parent = 0);
- const QPointF sample(const QPointF &from);
+ QPointF sample(const QPointF &from) override;
qreal angle() const
{
return m_angle;
diff --git a/src/particles/qquickcumulativedirection.cpp b/src/particles/qquickcumulativedirection.cpp
index b6b3e76f69..6fbd53df48 100644
--- a/src/particles/qquickcumulativedirection.cpp
+++ b/src/particles/qquickcumulativedirection.cpp
@@ -59,7 +59,7 @@ QQmlListProperty<QQuickDirection> QQuickCumulativeDirection::directions()
return QQmlListProperty<QQuickDirection>(this, m_directions);//TODO: Proper list property
}
-const QPointF QQuickCumulativeDirection::sample(const QPointF &from)
+QPointF QQuickCumulativeDirection::sample(const QPointF &from)
{
QPointF ret;
foreach (QQuickDirection* dir, m_directions)
diff --git a/src/particles/qquickcumulativedirection_p.h b/src/particles/qquickcumulativedirection_p.h
index 9af86bd39e..39f8ab8a24 100644
--- a/src/particles/qquickcumulativedirection_p.h
+++ b/src/particles/qquickcumulativedirection_p.h
@@ -62,7 +62,7 @@ class QQuickCumulativeDirection : public QQuickDirection
public:
explicit QQuickCumulativeDirection(QObject *parent = 0);
QQmlListProperty<QQuickDirection> directions();
- const QPointF sample(const QPointF &from);
+ QPointF sample(const QPointF &from) override;
private:
QList<QQuickDirection*> m_directions;
};
diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index a383b196c2..c1745798c3 100644
--- a/src/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
@@ -69,7 +69,7 @@ class QQuickCustomAffector : public QQuickParticleAffector
public:
explicit QQuickCustomAffector(QQuickItem *parent = 0);
- virtual void affectSystem(qreal dt);
+ void affectSystem(qreal dt) override;
QQuickDirection * position() const
{
@@ -153,7 +153,8 @@ public Q_SLOTS:
protected:
bool isAffectConnected();
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
private:
void affectProperties(const QList<QQuickParticleData*> particles, qreal dt);
QQuickDirection * m_position;
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index c08ae3d9ff..babf13a93c 100644
--- a/src/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
@@ -40,6 +40,7 @@
#include "qquickcustomparticle_p.h"
#include <QtQuick/private/qquickshadereffectmesh_p.h>
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
+#include <QtQml/qqmlinfo.h>
#include <cstdlib>
QT_BEGIN_NAMESPACE
@@ -90,6 +91,7 @@ struct PlainVertices {
\brief For specifying shaders to paint particles
\ingroup qtquick-particles
+ \note The maximum number of custom particles is limited to 16383.
*/
QQuickCustomParticle::QQuickCustomParticle(QQuickItem* parent)
@@ -316,13 +318,14 @@ QQuickOpenGLShaderEffectNode* QQuickCustomParticle::buildCustomNodes()
if (!QOpenGLContext::currentContext())
return 0;
- if (QOpenGLContext::currentContext()->isOpenGLES() && m_count * 4 > 0xffff) {
- printf("CustomParticle: Too many particles... \n");
+ if (m_count * 4 > 0xffff) {
+ // Index data is ushort.
+ qmlInfo(this) << "CustomParticle: Too many particles - maximum 16383 per CustomParticle";
return 0;
}
if (m_count <= 0) {
- printf("CustomParticle: Too few particles... \n");
+ qmlInfo(this) << "CustomParticle: Too few particles";
return 0;
}
diff --git a/src/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h
index e9d68cbe5c..1d48786a41 100644
--- a/src/particles/qquickcustomparticle_p.h
+++ b/src/particles/qquickcustomparticle_p.h
@@ -84,18 +84,18 @@ Q_SIGNALS:
void vertexShaderChanged();
protected:
- virtual void initialize(int gIdx, int pIdx);
- virtual void commit(int gIdx, int pIdx);
+ void initialize(int gIdx, int pIdx) override;
+ void commit(int gIdx, int pIdx) override;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
QQuickOpenGLShaderEffectNode *prepareNextFrame(QQuickOpenGLShaderEffectNode *rootNode);
- void reset();
+ void reset() override;
void resize(int oldCount, int newCount);
- virtual void componentComplete();
+ void componentComplete() override;
QQuickOpenGLShaderEffectNode *buildCustomNodes();
- void sceneGraphInvalidated();
- void itemChange(ItemChange change, const ItemChangeData &value);
+ void sceneGraphInvalidated() override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
private Q_SLOTS:
void sourceDestroyed(QObject *object);
diff --git a/src/particles/qquickdirection.cpp b/src/particles/qquickdirection.cpp
index da1edfb3c3..fd94c8945c 100644
--- a/src/particles/qquickdirection.cpp
+++ b/src/particles/qquickdirection.cpp
@@ -56,7 +56,7 @@ QQuickDirection::QQuickDirection(QObject *parent) :
{
}
-const QPointF QQuickDirection::sample(const QPointF &from)
+QPointF QQuickDirection::sample(const QPointF &from)
{
Q_UNUSED(from);
return QPointF();
diff --git a/src/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h
index f7029488f7..10960f9920 100644
--- a/src/particles/qquickdirection_p.h
+++ b/src/particles/qquickdirection_p.h
@@ -62,7 +62,7 @@ class QQuickDirection : public QObject
public:
explicit QQuickDirection(QObject *parent = 0);
- virtual const QPointF sample(const QPointF &from);
+ virtual QPointF sample(const QPointF &from);
Q_SIGNALS:
public Q_SLOTS:
diff --git a/src/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h
index 1df7e32c83..0af7f4d94f 100644
--- a/src/particles/qquickellipseextruder_p.h
+++ b/src/particles/qquickellipseextruder_p.h
@@ -60,8 +60,8 @@ class QQuickEllipseExtruder : public QQuickParticleExtruder
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box
public:
explicit QQuickEllipseExtruder(QObject *parent = 0);
- virtual QPointF extrude(const QRectF &);
- virtual bool contains(const QRectF &bounds, const QPointF &point);
+ QPointF extrude(const QRectF &) override;
+ bool contains(const QRectF &bounds, const QPointF &point) override;
bool fill() const
{
diff --git a/src/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h
index b67de631be..05ae7a38d5 100644
--- a/src/particles/qquickfriction_p.h
+++ b/src/particles/qquickfriction_p.h
@@ -73,7 +73,7 @@ public:
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
Q_SIGNALS:
diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index 7c071c932d..d3a7f6665c 100644
--- a/src/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
@@ -72,7 +72,8 @@ public:
return m_angle;
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
Q_SIGNALS:
void magnitudeChanged(qreal arg);
diff --git a/src/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h
index 0b935fc1d1..9a56ef5cce 100644
--- a/src/particles/qquickgroupgoal_p.h
+++ b/src/particles/qquickgroupgoal_p.h
@@ -75,7 +75,7 @@ public:
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
Q_SIGNALS:
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index e6b921792f..60cbf6175d 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -510,6 +510,8 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
So if you explicitly set an attribute affecting color, such as redVariation, and then reset it (by setting redVariation
to undefined), all color data will be reset and it will begin to have an implicit value of any shared color from
other ImageParticles.
+
+ \note The maximum number of image particles is limited to 16383.
*/
/*!
\qmlproperty url QtQuick.Particles::ImageParticle::source
@@ -1240,8 +1242,9 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
if (!QOpenGLContext::currentContext())
return;
- if (QOpenGLContext::currentContext()->isOpenGLES() && m_count * 4 > 0xffff) {
- printf("ImageParticle: Too many particles - maximum 16,000 per ImageParticle.\n");//ES 2 vertex count limit is ushort
+ if (m_count * 4 > 0xffff) {
+ // Index data is ushort.
+ qmlInfo(this) << "ImageParticle: Too many particles - maximum 16383 per ImageParticle";
return;
}
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 492ec23c07..95323c25a6 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -347,15 +347,15 @@ public Q_SLOTS:
void setEntryEffect(EntryEffect arg);
protected:
- void reset();
- virtual void initialize(int gIdx, int pIdx);
- virtual void commit(int gIdx, int pIdx);
+ void reset() override;
+ void initialize(int gIdx, int pIdx) override;
+ void commit(int gIdx, int pIdx) override;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
void prepareNextFrame(QSGNode**);
void buildParticleNodes(QSGNode**);
- void sceneGraphInvalidated();
+ void sceneGraphInvalidated() override;
private Q_SLOTS:
void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
@@ -440,7 +440,7 @@ private:
}
template<class MaterialData>
- MaterialData* getState(QSGMaterial* m){
+ static MaterialData* getState(QSGMaterial* m) {
return static_cast<QSGSimpleMaterial<MaterialData> *>(m)->state();
}
EntryEffect m_entryEffect;
diff --git a/src/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h
index 0edd05dfc7..9e6c7deaea 100644
--- a/src/particles/qquickitemparticle_p.h
+++ b/src/particles/qquickitemparticle_p.h
@@ -70,7 +70,7 @@ public:
bool fade() const { return m_fade; }
- virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
static QQuickItemParticleAttached *qmlAttachedProperties(QObject *object);
QQmlComponent* delegate() const
@@ -100,9 +100,9 @@ public Q_SLOTS:
}
protected:
- virtual void reset();
- virtual void commit(int gIdx, int pIdx);
- virtual void initialize(int gIdx, int pIdx);
+ void reset() override;
+ void commit(int gIdx, int pIdx) override;
+ void initialize(int gIdx, int pIdx) override;
void prepareNextFrame();
private:
void processDeletables();
@@ -131,7 +131,7 @@ public:
QQuickItemParticleAttached(QObject* parent)
: QObject(parent), m_mp(0)
{;}
- QQuickItemParticle* particle() {return m_mp;}
+ QQuickItemParticle* particle() const { return m_mp; }
void detach(){Q_EMIT detached();}
void attach(){Q_EMIT attached();}
private:
diff --git a/src/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h
index 72d2300dce..306f3a1dd6 100644
--- a/src/particles/qquicklineextruder_p.h
+++ b/src/particles/qquicklineextruder_p.h
@@ -56,11 +56,11 @@ class QQuickLineExtruder : public QQuickParticleExtruder
{
Q_OBJECT
//Default is topleft to bottom right. Flipped makes it topright to bottom left
- Q_PROPERTY(bool mirrored READ mirrored WRITE setmirrored NOTIFY mirroredChanged)
+ Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged)
public:
explicit QQuickLineExtruder(QObject *parent = 0);
- virtual QPointF extrude(const QRectF &);
+ QPointF extrude(const QRectF &) override;
bool mirrored() const
{
return m_mirrored;
@@ -72,7 +72,7 @@ Q_SIGNALS:
public Q_SLOTS:
- void setmirrored(bool arg)
+ void setMirrored(bool arg)
{
if (m_mirrored != arg) {
m_mirrored = arg;
diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h
index 32ace521da..0fc0331db8 100644
--- a/src/particles/qquickmaskextruder_p.h
+++ b/src/particles/qquickmaskextruder_p.h
@@ -63,8 +63,8 @@ class QQuickMaskExtruder : public QQuickParticleExtruder
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
public:
explicit QQuickMaskExtruder(QObject *parent = 0);
- virtual QPointF extrude(const QRectF &);
- virtual bool contains(const QRectF &bounds, const QPointF &point);
+ QPointF extrude(const QRectF &) override;
+ bool contains(const QRectF &bounds, const QPointF &point) override;
QUrl source() const
{
diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp
index 6ed0d9e14a..31bcfb82af 100644
--- a/src/particles/qquickparticleaffector.cpp
+++ b/src/particles/qquickparticleaffector.cpp
@@ -244,7 +244,7 @@ void QQuickParticleAffector::updateOffsets()
m_offset = m_system->mapFromItem(this, QPointF(0, 0));
}
-bool QQuickParticleAffector::isColliding(QQuickParticleData *d)
+bool QQuickParticleAffector::isColliding(QQuickParticleData *d) const
{
qreal myCurX = d->curX(m_system);
qreal myCurY = d->curY(m_system);
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index c42c0b4cba..5c9652bc32 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -185,7 +185,7 @@ protected:
bool activeGroup(int g);
bool shouldAffect(QQuickParticleData* datum);//Call to do the logic on whether it is affecting that datum
void postAffect(QQuickParticleData* datum);//Call to do the post-affect logic on particles which WERE affected(once off, needs reset, affected signal)
- virtual void componentComplete();
+ void componentComplete() override;
bool isAffectedConnected();
static const qreal simulationDelta;
static const qreal simulationCutoff;
@@ -200,7 +200,7 @@ private:
QStringList m_whenCollidingWith;
- bool isColliding(QQuickParticleData* d);
+ bool isColliding(QQuickParticleData* d) const;
};
QT_END_NAMESPACE
diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index b3f96ae3e6..4f7e12da44 100644
--- a/src/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
@@ -133,7 +133,7 @@ public:
qreal velocityFromMovement() const { return m_velocity_from_movement; }
void setVelocityFromMovement(qreal s);
- virtual void componentComplete();
+ void componentComplete() override;
Q_SIGNALS:
void emitParticles(QQmlV4Handle particles);
void particlesPerSecondChanged(qreal);
diff --git a/src/particles/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h
index 25cc2130b1..0314234569 100644
--- a/src/particles/qquickparticlegroup_p.h
+++ b/src/particles/qquickparticlegroup_p.h
@@ -104,8 +104,8 @@ Q_SIGNALS:
void systemChanged(QQuickParticleSystem* arg);
protected:
- virtual void componentComplete();
- virtual void classBegin(){;}
+ void componentComplete() override;
+ void classBegin() override {}
private:
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index 064ce27fe8..ac14a18103 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -98,7 +98,7 @@ public:
return m_groupIds;
}
- void itemChange(ItemChange, const ItemChangeData &);
+ void itemChange(ItemChange, const ItemChangeData &) override;
Q_SIGNALS:
void countChanged();
@@ -123,7 +123,7 @@ protected:
*/
virtual void reset();
- virtual void componentComplete();
+ void componentComplete() override;
virtual void initialize(int gIdx, int pIdx){//Called from main thread
Q_UNUSED(gIdx);
Q_UNUSED(pIdx);
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index b57d55bd98..de39b436e2 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -389,7 +389,7 @@ public Q_SLOTS:
protected:
//This one only once per frame (effectively)
- void componentComplete();
+ void componentComplete() override;
private Q_SLOTS:
void emittersChanged();
@@ -477,12 +477,12 @@ public:
: QAbstractAnimation(static_cast<QObject*>(system)), m_system(system)
{ }
protected:
- virtual void updateCurrentTime( int t )
+ void updateCurrentTime(int t) override
{
m_system->updateCurrentTime(t);
}
- virtual int duration() const
+ int duration() const override
{
return -1;
}
diff --git a/src/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h
index 99fae300c6..47985b5e82 100644
--- a/src/particles/qquickpointattractor_p.h
+++ b/src/particles/qquickpointattractor_p.h
@@ -160,7 +160,8 @@ void setProportionalToDistance(Proportion arg)
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
private:
qreal m_strength;
qreal m_x;
diff --git a/src/particles/qquickpointdirection.cpp b/src/particles/qquickpointdirection.cpp
index dbd15148ba..9038ce0aa0 100644
--- a/src/particles/qquickpointdirection.cpp
+++ b/src/particles/qquickpointdirection.cpp
@@ -75,7 +75,7 @@ QQuickPointDirection::QQuickPointDirection(QObject *parent) :
{
}
-const QPointF QQuickPointDirection::sample(const QPointF &)
+QPointF QQuickPointDirection::sample(const QPointF &)
{
QPointF ret;
ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2);
diff --git a/src/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h
index b01dc7ea4e..a80be928ad 100644
--- a/src/particles/qquickpointdirection_p.h
+++ b/src/particles/qquickpointdirection_p.h
@@ -63,7 +63,7 @@ class QQuickPointDirection : public QQuickDirection
Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged)
public:
explicit QQuickPointDirection(QObject *parent = 0);
- virtual const QPointF sample(const QPointF &from);
+ QPointF sample(const QPointF &from) override;
qreal x() const
{
return m_x;
diff --git a/src/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h
index 001031c711..630cf3050d 100644
--- a/src/particles/qquickrectangleextruder_p.h
+++ b/src/particles/qquickrectangleextruder_p.h
@@ -62,8 +62,8 @@ class QQuickRectangleExtruder : public QQuickParticleExtruder
public:
explicit QQuickRectangleExtruder(QObject *parent = 0);
- virtual QPointF extrude(const QRectF &);
- virtual bool contains(const QRectF &bounds, const QPointF &point);
+ QPointF extrude(const QRectF &) override;
+ bool contains(const QRectF &bounds, const QPointF &point) override;
bool fill() const
{
return m_fill;
diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index 7174fd2318..2b15d0b8bb 100644
--- a/src/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
@@ -81,7 +81,8 @@ public:
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
Q_SIGNALS:
void goalStateChanged(const QString &arg);
diff --git a/src/particles/qquicktargetdirection.cpp b/src/particles/qquicktargetdirection.cpp
index f9bcfbc564..012c9a151b 100644
--- a/src/particles/qquicktargetdirection.cpp
+++ b/src/particles/qquicktargetdirection.cpp
@@ -94,7 +94,7 @@ QQuickTargetDirection::QQuickTargetDirection(QObject *parent) :
{
}
-const QPointF QQuickTargetDirection::sample(const QPointF &from)
+QPointF QQuickTargetDirection::sample(const QPointF &from)
{
//###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile?
QPointF ret;
diff --git a/src/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h
index 4de5867336..13e826743e 100644
--- a/src/particles/qquicktargetdirection_p.h
+++ b/src/particles/qquicktargetdirection_p.h
@@ -71,7 +71,7 @@ class QQuickTargetDirection : public QQuickDirection
public:
explicit QQuickTargetDirection(QObject *parent = 0);
- virtual const QPointF sample(const QPointF &from);
+ QPointF sample(const QPointF &from) override;
qreal targetX() const
{
diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index b70f34999a..99464436ba 100644
--- a/src/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
@@ -71,8 +71,8 @@ public:
};
Q_ENUM(EmitSize)
explicit QQuickTrailEmitter(QQuickItem *parent = 0);
- virtual void emitWindow(int timeStamp);
- virtual void reset();
+ void emitWindow(int timeStamp) override;
+ void reset() override;
int particlesPerParticlePerSecond() const
{
diff --git a/src/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h
index 7a6be1719e..e73f3ba153 100644
--- a/src/particles/qquickturbulence_p.h
+++ b/src/particles/qquickturbulence_p.h
@@ -65,7 +65,7 @@ class QQuickTurbulenceAffector : public QQuickParticleAffector
public:
explicit QQuickTurbulenceAffector(QQuickItem *parent = 0);
~QQuickTurbulenceAffector();
- virtual void affectSystem(qreal dt);
+ void affectSystem(qreal dt) override;
qreal strength() const
{
@@ -102,8 +102,8 @@ public Q_SLOTS:
}
protected:
- virtual void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry);
+ void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry) override;
private:
void ensureInit();
void mapUpdate();
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index bd43d45c38..967652f31a 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -525,7 +525,7 @@ QQuickV4ParticleData::~QQuickV4ParticleData()
{
}
-QQmlV4Handle QQuickV4ParticleData::v4Value()
+QQmlV4Handle QQuickV4ParticleData::v4Value() const
{
return QQmlV4Handle(m_v4Value.value());
}
diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h
index 437491ff42..d73e3b644d 100644
--- a/src/particles/qquickv4particledata_p.h
+++ b/src/particles/qquickv4particledata_p.h
@@ -63,7 +63,7 @@ class QQuickV4ParticleData {
public:
QQuickV4ParticleData(QV8Engine*, QQuickParticleData*, QQuickParticleSystem *system);
~QQuickV4ParticleData();
- QQmlV4Handle v4Value();
+ QQmlV4Handle v4Value() const;
private:
QV4::PersistentValue m_v4Value;
};
diff --git a/src/particles/qquickwander_p.h b/src/particles/qquickwander_p.h
index 6461444cd1..0ad19d4d13 100644
--- a/src/particles/qquickwander_p.h
+++ b/src/particles/qquickwander_p.h
@@ -105,7 +105,8 @@ public:
}
protected:
- virtual bool affectParticle(QQuickParticleData *d, qreal dt);
+ bool affectParticle(QQuickParticleData *d, qreal dt) override;
+
Q_SIGNALS:
void xVarianceChanged(qreal arg);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
index 27b3a5b513..f3f8a21ff8 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
+++ b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
@@ -2,10 +2,8 @@ TARGET = qmldbg_debugger
QT = qml-private core-private packetprotocol-private
SOURCES += \
- $$PWD/qdebugmessageservice.cpp \
$$PWD/qqmldebuggerservicefactory.cpp \
$$PWD/qqmlenginedebugservice.cpp \
- $$PWD/qqmlnativedebugservice.cpp \
$$PWD/qqmlwatcher.cpp \
$$PWD/qv4debugservice.cpp \
$$PWD/qv4debugger.cpp \
@@ -16,10 +14,8 @@ SOURCES += \
HEADERS += \
$$PWD/../shared/qqmlconfigurabledebugservice.h \
$$PWD/../shared/qqmldebugpacket.h \
- $$PWD/qdebugmessageservice.h \
$$PWD/qqmldebuggerservicefactory.h \
$$PWD/qqmlenginedebugservice.h \
- $$PWD/qqmlnativedebugservice.h \
$$PWD/qqmlwatcher.h \
$$PWD/qv4debugservice.h \
$$PWD/qv4debugger.h \
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservice.json b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservice.json
index 967a725903..442d7781a1 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservice.json
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservice.json
@@ -1,3 +1,3 @@
{
- "Keys": [ "DebugMessages", "QmlDebugger", "V8Debugger", "NativeQmlDebugger" ]
+ "Keys": [ "QmlDebugger", "V8Debugger" ]
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
index ca3f07323d..9315adf4ce 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp
@@ -39,27 +39,19 @@
#include "qqmldebuggerservicefactory.h"
#include "qqmlenginedebugservice.h"
-#include "qdebugmessageservice.h"
#include "qv4debugservice.h"
-#include "qqmlnativedebugservice.h"
#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
QQmlDebugService *QQmlDebuggerServiceFactory::create(const QString &key)
{
- if (key == QDebugMessageServiceImpl::s_key)
- return new QDebugMessageServiceImpl(this);
-
if (key == QQmlEngineDebugServiceImpl::s_key)
return new QQmlEngineDebugServiceImpl(this);
if (key == QV4DebugServiceImpl::s_key)
return new QV4DebugServiceImpl(this);
- if (key == QQmlNativeDebugServiceImpl::s_key)
- return new QQmlNativeDebugServiceImpl(this);
-
return 0;
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.h b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.h
index 99d6679833..50eed2369c 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.h
@@ -49,7 +49,7 @@ class QQmlDebuggerServiceFactory : public QQmlDebugServiceFactory
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlDebugServiceFactory_iid FILE "qqmldebuggerservice.json")
public:
- QQmlDebugService *create(const QString &key);
+ QQmlDebugService *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 2b8dcc19ee..151e44c4d4 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -289,10 +289,12 @@ void QQmlEngineDebugServiceImpl::buildObjectDump(QDataStream &message,
prop.value = expr->expression();
QObject *scope = expr->scopeObject();
if (scope) {
- QString methodName = QString::fromLatin1(QMetaObjectPrivate::signal(scope->metaObject(), signalHandler->signalIndex()).name());
- if (!methodName.isEmpty()) {
- prop.name = QLatin1String("on") + methodName[0].toUpper()
- + methodName.mid(1);
+ const QByteArray methodName = QMetaObjectPrivate::signal(scope->metaObject(),
+ signalHandler->signalIndex()).name();
+ const QLatin1String methodNameStr(methodName);
+ if (methodNameStr.size() != 0) {
+ prop.name = QLatin1String("on") + QChar(methodNameStr.at(0)).toUpper()
+ + methodNameStr.mid(1);
}
}
}
@@ -520,12 +522,12 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
ds >> file >> lineNumber >> columnNumber >> recurse >> dumpProperties;
- QList<QObject*> objects = objectForLocationInfo(file, lineNumber, columnNumber);
+ const QList<QObject*> objects = objectForLocationInfo(file, lineNumber, columnNumber);
rs << QByteArray("FETCH_OBJECTS_FOR_LOCATION_R") << queryId
<< objects.count();
- foreach (QObject *object, objects) {
+ for (QObject *object : objects) {
if (recurse)
prepareDeferredObjects(object);
buildObjectDump(rs, object, recurse, dumpProperties);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index 756b6b28be..773bc937f5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -52,7 +52,7 @@ QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService)
QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
{
- foreach (QV4Debugger *debugger, m_debuggers) {
+ for (QV4Debugger *debugger : m_debuggers) {
if (debugger->state() == QV4Debugger::Paused)
return debugger;
}
@@ -147,13 +147,13 @@ void QV4DebuggerAgent::pause(QV4Debugger *debugger) const
void QV4DebuggerAgent::pauseAll() const
{
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : m_debuggers)
pause(debugger);
}
void QV4DebuggerAgent::resumeAll() const
{
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : m_debuggers)
if (debugger->state() == QV4Debugger::Paused)
debugger->resume(QV4Debugger::FullThrottle);
}
@@ -161,7 +161,7 @@ void QV4DebuggerAgent::resumeAll() const
int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition)
{
if (enabled)
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : qAsConst(m_debuggers))
debugger->addBreakPoint(fileName, lineNumber, condition);
int id = m_breakPoints.size();
@@ -178,7 +178,7 @@ void QV4DebuggerAgent::removeBreakPoint(int id)
m_breakPoints.remove(id);
if (breakPoint.enabled)
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : qAsConst(m_debuggers))
debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
}
@@ -195,7 +195,7 @@ void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff)
return;
breakPoint.enabled = onoff;
- foreach (QV4Debugger *debugger, m_debuggers) {
+ for (QV4Debugger *debugger : qAsConst(m_debuggers)) {
if (onoff)
debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
else
@@ -218,14 +218,14 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff)
{
if (onoff != m_breakOnThrow) {
m_breakOnThrow = onoff;
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : qAsConst(m_debuggers))
debugger->setBreakOnThrow(onoff);
}
}
void QV4DebuggerAgent::clearAllPauseRequests()
{
- foreach (QV4Debugger *debugger, m_debuggers)
+ for (QV4Debugger *debugger : qAsConst(m_debuggers))
debugger->clearPauseRequest();
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index d5cc765ea8..df316c1ae6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -43,6 +43,7 @@
#include <private/qqmlcontext_p.h>
#include <private/qv4qmlcontext_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qqmldebugservice_p.h>
#include <QtQml/qqmlengine.h>
@@ -52,9 +53,10 @@ QV4DebugJob::~QV4DebugJob()
{
}
-JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr,
- const QString &script) :
- engine(engine), frameNr(frameNr), script(script), resultIsException(false)
+JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, int context,
+ const QString &script) :
+ engine(engine), frameNr(frameNr), context(context), script(script),
+ resultIsException(false)
{}
void JavaScriptJob::run()
@@ -65,7 +67,23 @@ void JavaScriptJob::run()
QV4::ExecutionContext *ctx = engine->currentContext;
QObject scopeObject;
- if (frameNr < 0) { // Use QML context if available
+
+ if (frameNr > 0) {
+ for (int i = 0; i < frameNr; ++i) {
+ ctx = engine->parentContext(ctx);
+ }
+ engine->pushContext(ctx);
+ ctx = engine->currentContext;
+ }
+
+ if (context >= 0) {
+ QQmlContext *extraContext = qmlContext(QQmlDebugService::objectForId(context));
+ if (extraContext) {
+ engine->pushContext(QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext),
+ &scopeObject));
+ ctx = engine->currentContext;
+ }
+ } else if (frameNr < 0) { // Use QML context if available
QQmlEngine *qmlEngine = engine->qmlEngine();
if (qmlEngine) {
QQmlContext *qmlRootContext = qmlEngine->rootContext();
@@ -89,13 +107,6 @@ void JavaScriptJob::run()
engine->pushContext(ctx->newWithContext(withContext->toObject(engine)));
ctx = engine->currentContext;
}
- } else {
- if (frameNr > 0) {
- for (int i = 0; i < frameNr; ++i) {
- ctx = engine->parentContext(ctx);
- }
- engine->pushContext(ctx);
- }
}
QV4::Script script(ctx, this->script);
@@ -206,7 +217,7 @@ void ValueLookupJob::run()
QQmlContextData::get(engine->qmlEngine()->rootContext()),
scopeObject.data()));
}
- foreach (const QJsonValue &handle, handles) {
+ for (const QJsonValue &handle : handles) {
QV4DataCollector::Ref ref = handle.toInt();
if (!collector->isValidRef(ref)) {
exception = QString::fromLatin1("Invalid Ref: %1").arg(ref);
@@ -225,8 +236,9 @@ const QString &ValueLookupJob::exceptionMessage() const
}
ExpressionEvalJob::ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr,
- const QString &expression, QV4DataCollector *collector) :
- JavaScriptJob(engine, frameNr, expression), collector(collector)
+ int context, const QString &expression,
+ QV4DataCollector *collector) :
+ JavaScriptJob(engine, frameNr, context, expression), collector(collector)
{
}
@@ -259,7 +271,7 @@ GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine)
void GatherSourcesJob::run()
{
- foreach (QV4::CompiledData::CompilationUnit *unit, engine->compilationUnits) {
+ for (QV4::CompiledData::CompilationUnit *unit : qAsConst(engine->compilationUnits)) {
QString fileName = unit->fileName();
if (!fileName.isEmpty())
sources.append(fileName);
@@ -272,7 +284,7 @@ const QStringList &GatherSourcesJob::result() const
}
EvalJob::EvalJob(QV4::ExecutionEngine *engine, const QString &script) :
- JavaScriptJob(engine, /*frameNr*/-1, script), result(false)
+ JavaScriptJob(engine, /*frameNr*/-1, /*context*/ -1, script), result(false)
{}
void EvalJob::handleResult(QV4::ScopedValue &result)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
index 721f42b7c2..00d3e6206a 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
@@ -60,12 +60,13 @@ class JavaScriptJob : public QV4DebugJob
{
QV4::ExecutionEngine *engine;
int frameNr;
+ int context;
const QString &script;
bool resultIsException;
public:
- JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script);
- void run();
+ JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, int context, const QString &script);
+ void run() override;
bool hasExeption() const;
protected:
@@ -90,7 +91,7 @@ class BacktraceJob: public CollectJob
int toFrame;
public:
BacktraceJob(QV4DataCollector *collector, int fromFrame, int toFrame);
- void run();
+ void run() override;
};
class FrameJob: public CollectJob
@@ -100,7 +101,7 @@ class FrameJob: public CollectJob
public:
FrameJob(QV4DataCollector *collector, int frameNr);
- void run();
+ void run() override;
bool wasSuccessful() const;
};
@@ -112,7 +113,7 @@ class ScopeJob: public CollectJob
public:
ScopeJob(QV4DataCollector *collector, int frameNr, int scopeNr);
- void run();
+ void run() override;
bool wasSuccessful() const;
};
@@ -123,7 +124,7 @@ class ValueLookupJob: public CollectJob
public:
ValueLookupJob(const QJsonArray &handles, QV4DataCollector *collector);
- void run();
+ void run() override;
const QString &exceptionMessage() const;
};
@@ -135,9 +136,9 @@ class ExpressionEvalJob: public JavaScriptJob
QJsonArray collectedRefs;
public:
- ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, const QString &expression,
- QV4DataCollector *collector);
- virtual void handleResult(QV4::ScopedValue &value);
+ ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, int context,
+ const QString &expression, QV4DataCollector *collector);
+ void handleResult(QV4::ScopedValue &value) override;
const QString &exceptionMessage() const;
const QJsonObject &returnValue() const;
const QJsonArray &refs() const;
@@ -150,7 +151,7 @@ class GatherSourcesJob: public QV4DebugJob
public:
GatherSourcesJob(QV4::ExecutionEngine *engine);
- void run();
+ void run() override;
const QStringList &result() const;
};
@@ -161,7 +162,7 @@ class EvalJob: public JavaScriptJob
public:
EvalJob(QV4::ExecutionEngine *engine, const QString &script);
- virtual void handleResult(QV4::ScopedValue &result);
+ void handleResult(QV4::ScopedValue &result) override;
bool resultAsBoolean() const;
};
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 00c5c1ad77..1d2cc092dc 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -152,7 +152,7 @@ class UnknownV8CommandHandler: public V8CommandHandler
public:
UnknownV8CommandHandler(): V8CommandHandler(QString()) {}
- virtual void handleRequest()
+ void handleRequest() override
{
QString msg = QLatin1String("unimplemented command \"")
+ req.value(QLatin1String("command")).toString()
@@ -167,7 +167,7 @@ class V8VersionRequest: public V8CommandHandler
public:
V8VersionRequest(): V8CommandHandler(QStringLiteral("version")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
addCommand();
addRequestSequence();
@@ -177,6 +177,7 @@ public:
body.insert(QStringLiteral("V8Version"),
QLatin1String("this is not V8, this is V4 in Qt " QT_VERSION_STR));
body.insert(QStringLiteral("UnpausedEvaluate"), true);
+ body.insert(QStringLiteral("ContextEvaluate"), true);
addBody(body);
}
};
@@ -186,7 +187,7 @@ class V8SetBreakPointRequest: public V8CommandHandler
public:
V8SetBreakPointRequest(): V8CommandHandler(QStringLiteral("setbreakpoint")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject args = req.value(QLatin1String("arguments")).toObject();
@@ -237,7 +238,7 @@ class V8ClearBreakPointRequest: public V8CommandHandler
public:
V8ClearBreakPointRequest(): V8CommandHandler(QStringLiteral("clearbreakpoint")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject args = req.value(QLatin1String("arguments")).toObject();
@@ -270,7 +271,7 @@ class V8BacktraceRequest: public V8CommandHandler
public:
V8BacktraceRequest(): V8CommandHandler(QStringLiteral("backtrace")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
@@ -303,7 +304,7 @@ class V8FrameRequest: public V8CommandHandler
public:
V8FrameRequest(): V8CommandHandler(QStringLiteral("frame")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
@@ -345,7 +346,7 @@ class V8ScopeRequest: public V8CommandHandler
public:
V8ScopeRequest(): V8CommandHandler(QStringLiteral("scope")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
@@ -390,7 +391,7 @@ class V8LookupRequest: public V8CommandHandler
public:
V8LookupRequest(): V8CommandHandler(QStringLiteral("lookup")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
@@ -430,7 +431,7 @@ class V8ContinueRequest: public V8CommandHandler
public:
V8ContinueRequest(): V8CommandHandler(QStringLiteral("continue")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
// decypher the payload:
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
@@ -476,7 +477,7 @@ class V8DisconnectRequest: public V8CommandHandler
public:
V8DisconnectRequest(): V8CommandHandler(QStringLiteral("disconnect")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
debugService->debuggerAgent.removeAllBreakPoints();
debugService->debuggerAgent.resumeAll();
@@ -494,7 +495,7 @@ class V8SetExceptionBreakRequest: public V8CommandHandler
public:
V8SetExceptionBreakRequest(): V8CommandHandler(QStringLiteral("setexceptionbreak")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
@@ -534,7 +535,7 @@ class V8ScriptsRequest: public V8CommandHandler
public:
V8ScriptsRequest(): V8CommandHandler(QStringLiteral("scripts")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
//decypher the payload:
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
@@ -558,7 +559,7 @@ public:
debugger->runInEngine(&job);
QJsonArray body;
- foreach (const QString &source, job.result()) {
+ for (const QString &source : job.result()) {
QJsonObject src;
src[QLatin1String("name")] = source;
src[QLatin1String("scriptType")] = 4;
@@ -606,10 +607,11 @@ class V8EvaluateRequest: public V8CommandHandler
public:
V8EvaluateRequest(): V8CommandHandler(QStringLiteral("evaluate")) {}
- virtual void handleRequest()
+ void handleRequest() override
{
QJsonObject arguments = req.value(QLatin1String("arguments")).toObject();
QString expression = arguments.value(QLatin1String("expression")).toString();
+ int context = arguments.value(QLatin1String("context")).toInt(-1);
int frame = -1;
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
@@ -627,7 +629,8 @@ public:
frame = arguments.value(QLatin1String("frame")).toInt(0);
}
- ExpressionEvalJob job(debugger->engine(), frame, expression, debugger->collector());
+ ExpressionEvalJob job(debugger->engine(), frame, context, expression,
+ debugger->collector());
debugger->runInEngine(&job);
if (job.hasExeption()) {
createErrorResponse(job.exceptionMessage());
@@ -718,7 +721,8 @@ void QV4DebugServiceImpl::stateAboutToBeChanged(State state)
{
QMutexLocker lock(&m_configMutex);
if (state == Enabled) {
- foreach (QV4Debugger *debugger, debuggerAgent.debuggers()) {
+ const auto debuggers = debuggerAgent.debuggers();
+ for (QV4Debugger *debugger : debuggers) {
QV4::ExecutionEngine *ee = debugger->engine();
if (!ee->debugger())
ee->setDebugger(debugger);
@@ -737,7 +741,7 @@ void QV4DebugServiceImpl::signalEmitted(const QString &signal)
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
- foreach (const QString &signal, breakOnSignals) {
+ for (const QString &signal : qAsConst(breakOnSignals)) {
if (signal == signalName) {
// TODO: pause debugger
break;
diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
index ca7c76ab50..7145645609 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
@@ -92,7 +92,7 @@ void GlobalInspector::setSelectedItems(const QList<QQuickItem *> &items)
QList<QObject*> objectList;
objectList.reserve(items.count());
- foreach (QQuickItem *item, items)
+ for (QQuickItem *item : items)
objectList << item;
sendCurrentObjects(objectList);
@@ -113,7 +113,7 @@ void GlobalInspector::sendCurrentObjects(const QList<QObject*> &objects)
QList<int> debugIds;
debugIds.reserve(objects.count());
- foreach (QObject *object, objects)
+ for (QObject *object : objects)
debugIds << QQmlDebugService::idForObject(object);
ds << debugIds;
@@ -194,7 +194,7 @@ bool GlobalInspector::createQmlObject(int requestId, const QString &qml, QObject
return false;
QString imports;
- foreach (const QString &s, importList)
+ for (const QString &s : importList)
imports += s + QLatin1Char('\n');
ObjectCreator *objectCreator = new ObjectCreator(requestId, parentContext->engine(), parent);
@@ -223,7 +223,7 @@ void GlobalInspector::removeWindow(QQuickWindow *window)
void GlobalInspector::setParentWindow(QQuickWindow *window, QWindow *parentWindow)
{
- foreach (QmlJSDebugger::QQuickWindowInspector *inspector, m_windowInspectors) {
+ for (QmlJSDebugger::QQuickWindowInspector *inspector : qAsConst(m_windowInspectors)) {
if (inspector->quickWindow() == window)
inspector->setParentWindow(parentWindow);
}
@@ -234,7 +234,8 @@ bool GlobalInspector::syncSelectedItems(const QList<QQuickItem *> &items)
bool selectionChanged = false;
// Disconnect and remove items that are no longer selected
- foreach (QQuickItem *item, m_selectedItems) {
+ const auto selectedItemsCopy = m_selectedItems;
+ for (QQuickItem *item : selectedItemsCopy) {
if (items.contains(item))
continue;
@@ -245,14 +246,14 @@ bool GlobalInspector::syncSelectedItems(const QList<QQuickItem *> &items)
}
// Connect and add newly selected items
- foreach (QQuickItem *item, items) {
+ for (QQuickItem *item : items) {
if (m_selectedItems.contains(item))
continue;
selectionChanged = true;
connect(item, &QObject::destroyed, this, &GlobalInspector::removeFromSelectedItems);
m_selectedItems.append(item);
- foreach (QQuickWindowInspector *inspector, m_windowInspectors) {
+ for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors)) {
if (inspector->isEnabled() && inspector->quickWindow() == item->window()) {
m_highlightItems.insert(item, new SelectionHighlight(titleForItem(item), item,
inspector->overlay()));
@@ -312,12 +313,12 @@ void GlobalInspector::processMessage(const QByteArray &message)
ds >> requestId >> command;
if (command == ENABLE) {
- foreach (QQuickWindowInspector *inspector, m_windowInspectors)
+ for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
inspector->setEnabled(true);
success = !m_windowInspectors.isEmpty();
} else if (command == DISABLE) {
setSelectedItems(QList<QQuickItem*>());
- foreach (QQuickWindowInspector *inspector, m_windowInspectors)
+ for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
inspector->setEnabled(false);
success = !m_windowInspectors.isEmpty();
} else if (command == SELECT) {
@@ -325,7 +326,7 @@ void GlobalInspector::processMessage(const QByteArray &message)
ds >> debugIds;
QList<QQuickItem *> selectedObjects;
- foreach (int debugId, debugIds) {
+ for (int debugId : qAsConst(debugIds)) {
if (QQuickItem *obj =
qobject_cast<QQuickItem *>(QQmlDebugService::objectForId(debugId)))
selectedObjects << obj;
@@ -339,7 +340,7 @@ void GlobalInspector::processMessage(const QByteArray &message)
} else if (command == SHOW_APP_ON_TOP) {
bool showOnTop;
ds >> showOnTop;
- foreach (QmlJSDebugger::QQuickWindowInspector *inspector, m_windowInspectors)
+ for (QmlJSDebugger::QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
inspector->setShowAppOnTop(showOnTop);
success = !m_windowInspectors.isEmpty();
} else if (command == CREATE_OBJECT) {
diff --git a/src/plugins/qmltooling/qmldbg_inspector/highlight.h b/src/plugins/qmltooling/qmldbg_inspector/highlight.h
index 2bf4fc1ad5..3f910e833b 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/highlight.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/highlight.h
@@ -81,7 +81,7 @@ class SelectionHighlight : public Highlight
public:
SelectionHighlight(const QString &name, QQuickItem *item, QQuickItem *parent);
- void paint(QPainter *painter);
+ void paint(QPainter *painter) override;
void showName(const QPointF &displayPoint);
private:
@@ -104,7 +104,7 @@ public:
setZ(1); // hover highlight on top of selection highlight
}
- void paint(QPainter *painter);
+ void paint(QPainter *painter) override;
};
} // namespace QmlJSDebugger
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservicefactory.h b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservicefactory.h
index 09e6a01f96..3214532c8d 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservicefactory.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservicefactory.h
@@ -64,7 +64,7 @@ class QQmlInspectorServiceFactory : public QQmlDebugServiceFactory
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlDebugServiceFactory_iid FILE "qqmlinspectorservice.json")
public:
- QQmlDebugService *create(const QString &key);
+ QQmlDebugService *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.h b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.h
index b37a9face1..fc18f33ad3 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.h
@@ -78,7 +78,7 @@ public:
void setEnabled(bool enabled);
protected:
- bool eventFilter(QObject *, QEvent *);
+ bool eventFilter(QObject *, QEvent *) override;
private:
QQuickItem *m_overlay;
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
index 64b26bdd0d..6152853917 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
@@ -43,6 +43,8 @@
#include <QtCore/qplugin.h>
#include <QtNetwork/qlocalsocket.h>
+Q_DECLARE_METATYPE(QLocalSocket::LocalSocketError)
+
QT_BEGIN_NAMESPACE
@@ -133,8 +135,14 @@ bool QLocalClientConnection::connectToServer()
{
m_socket = new QLocalSocket;
m_socket->setParent(this);
- QObject::connect(m_socket, &QLocalSocket::connected,
- this, &QLocalClientConnection::connectionEstablished);
+ connect(m_socket, &QLocalSocket::connected,
+ this, &QLocalClientConnection::connectionEstablished);
+ connect(m_socket, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(
+ &QLocalSocket::error), m_socket, [this](QLocalSocket::LocalSocketError) {
+ m_socket->disconnectFromServer();
+ m_socket->connectToServer(m_filename);
+ }, Qt::QueuedConnection);
+
m_socket->connectToServer(m_filename);
qDebug("QML Debugger: Connecting to socket %s...", m_filename.toLatin1().constData());
return true;
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
index b884a1ec23..b64a1fff95 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
@@ -50,7 +50,7 @@ class QLocalClientConnectionFactory : public QQmlDebugServerConnectionFactory
Q_PLUGIN_METADATA(IID QQmlDebugServerConnectionFactory_iid FILE "qlocalclientconnection.json")
Q_INTERFACES(QQmlDebugServerConnectionFactory)
public:
- QQmlDebugServerConnection *create(const QString &key);
+ QQmlDebugServerConnection *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
index b0f59717ac..b0f59717ac 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.h
index c25e756c2d..24fd27514b 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.h
@@ -68,10 +68,10 @@ public:
QDebugMessageServiceImpl(QObject *parent = 0);
void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt, const QString &buf);
- void synchronizeTime(const QElapsedTimer &otherTimer);
+ void synchronizeTime(const QElapsedTimer &otherTimer) override;
protected:
- void stateChanged(State);
+ void stateChanged(State) override;
private:
friend class QQmlDebuggerServiceFactory;
diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.json b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.json
new file mode 100644
index 0000000000..2e8dc65cf5
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "DebugMessages" ]
+}
diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp
new file mode 100644
index 0000000000..a066237e77
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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 "qdebugmessageservicefactory.h"
+#include "qdebugmessageservice.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlDebugService *QDebugMessageServiceFactory::create(const QString &key)
+{
+ if (key == QDebugMessageServiceImpl::s_key)
+ return new QDebugMessageServiceImpl(this);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.h b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.h
new file mode 100644
index 0000000000..0c5f0f5d0a
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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 QDEBUGMESSAGESERVICEFACTORY_H
+#define QDEBUGMESSAGESERVICEFACTORY_H
+
+#include <private/qqmldebugservicefactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebugMessageServiceFactory : public QQmlDebugServiceFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlDebugServiceFactory_iid FILE "qdebugmessageservice.json")
+public:
+ QQmlDebugService *create(const QString &key) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDEBUGMESSAGESERVICEFACTORY_H
diff --git a/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro b/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro
new file mode 100644
index 0000000000..5ddf7c615d
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro
@@ -0,0 +1,21 @@
+TARGET = qmldbg_messages
+QT = qml-private core packetprotocol-private
+
+SOURCES += \
+ $$PWD/qdebugmessageservice.cpp \
+ $$PWD/qdebugmessageservicefactory.cpp
+
+HEADERS += \
+ $$PWD/../shared/qqmldebugpacket.h \
+ $$PWD/qdebugmessageservice.h \
+ $$PWD/qdebugmessageservicefactory.h
+
+INCLUDEPATH += $$PWD \
+ $$PWD/../shared
+
+OTHER_FILES += \
+ $$PWD/qdebugmessageservice.json
+
+PLUGIN_TYPE = qmltooling
+PLUGIN_CLASS_NAME = QDebugMessageServiceFactory
+load(qt_plugin)
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index 3145601612..1a318b3ca2 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -183,7 +183,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector()
: m_blockingMode(false)
{
const QString args = commandLineArguments();
- const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','));
+ const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts);
QStringList services;
for (const QStringRef &strArgument : lstjsDebugArguments) {
if (strArgument == QLatin1String("block")) {
@@ -195,7 +195,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector()
services.append(strArgument.mid(9).toString());
} else if (!services.isEmpty()) {
services.append(strArgument.toString());
- } else {
+ } else if (!strArgument.startsWith(QLatin1String("connector:"))) {
qWarning("QML Debugger: Invalid argument \"%s\" detected. Ignoring the same.",
strArgument.toUtf8().constData());
}
@@ -205,7 +205,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector()
QQmlNativeDebugConnector::~QQmlNativeDebugConnector()
{
- foreach (QQmlDebugService *service, m_services) {
+ for (QQmlDebugService *service : qAsConst(m_services)) {
service->stateAboutToBeChanged(QQmlDebugService::NotConnected);
service->setState(QQmlDebugService::NotConnected);
service->stateChanged(QQmlDebugService::NotConnected);
@@ -232,12 +232,12 @@ void QQmlNativeDebugConnector::addEngine(QJSEngine *engine)
Q_ASSERT(!m_engines.contains(engine));
TRACE_PROTOCOL("Add engine to connector:" << engine);
- foreach (QQmlDebugService *service, m_services)
+ for (QQmlDebugService *service : qAsConst(m_services))
service->engineAboutToBeAdded(engine);
announceObjectAvailability(QLatin1String("qmlengine"), engine, true);
- foreach (QQmlDebugService *service, m_services)
+ for (QQmlDebugService *service : qAsConst(m_services))
service->engineAdded(engine);
m_engines.append(engine);
@@ -248,12 +248,12 @@ void QQmlNativeDebugConnector::removeEngine(QJSEngine *engine)
Q_ASSERT(m_engines.contains(engine));
TRACE_PROTOCOL("Remove engine from connector:" << engine);
- foreach (QQmlDebugService *service, m_services)
+ for (QQmlDebugService *service : qAsConst(m_services))
service->engineAboutToBeRemoved(engine);
announceObjectAvailability(QLatin1String("qmlengine"), engine, false);
- foreach (QQmlDebugService *service, m_services)
+ for (QQmlDebugService *service : qAsConst(m_services))
service->engineRemoved(engine);
m_engines.removeOne(engine);
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
index 1184925e53..f8b7e1d527 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
@@ -78,7 +78,7 @@ class QQmlNativeDebugConnectorFactory : public QQmlDebugConnectorFactory
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmlnativedebugconnector.json")
public:
- QQmlDebugConnector *create(const QString &key);
+ QQmlDebugConnector *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro b/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro
new file mode 100644
index 0000000000..1873a6a77c
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro
@@ -0,0 +1,21 @@
+TARGET = qmldbg_nativedebugger
+QT = qml-private core packetprotocol-private
+
+SOURCES += \
+ $$PWD/qqmlnativedebugservicefactory.cpp \
+ $$PWD/qqmlnativedebugservice.cpp
+
+HEADERS += \
+ $$PWD/../shared/qqmldebugpacket.h \
+ $$PWD/qqmlnativedebugservicefactory.h \
+ $$PWD/qqmlnativedebugservice.h \
+
+INCLUDEPATH += $$PWD \
+ $$PWD/../shared
+
+OTHER_FILES += \
+ $$PWD/qqmlnativedebugservice.json
+
+PLUGIN_TYPE = qmltooling
+PLUGIN_CLASS_NAME = QQmlNativeDebugServiceFactory
+load(qt_plugin)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index 14dfc5356e..7f842419e7 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -287,7 +287,7 @@ void NativeDebugger::signalEmitted(const QString &signal)
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
- foreach (const QString &signal, breakOnSignals) {
+ for (const QString &signal : qAsConst(breakOnSignals)) {
if (signal == signalName) {
// TODO: pause debugger
break;
@@ -339,15 +339,15 @@ void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &a
if (QV4::Function *function = executionContext->getFunction()) {
QJsonObject frame;
- frame[QStringLiteral("language")] = QStringLiteral("js");
- frame[QStringLiteral("context")] = encodeContext(executionContext);
+ frame.insert(QStringLiteral("language"), QStringLiteral("js"));
+ frame.insert(QStringLiteral("context"), encodeContext(executionContext));
if (QV4::Heap::String *functionName = function->name())
- frame[QStringLiteral("function")] = functionName->toQString();
- frame[QStringLiteral("file")] = function->sourceFile();
+ frame.insert(QStringLiteral("function"), functionName->toQString());
+ frame.insert(QStringLiteral("file"), function->sourceFile());
int line = executionContext->d()->lineNumber;
- frame[QStringLiteral("line")] = (line < 0 ? -line : line);
+ frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
frameArray.push_back(frame);
}
@@ -473,8 +473,8 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a
TRACE_PROTOCOL("Engine: " << engine);
Collector collector(engine);
- QJsonArray expanded = arguments.value(QLatin1String("expanded")).toArray();
- foreach (const QJsonValue &ex, expanded)
+ const QJsonArray expanded = arguments.value(QLatin1String("expanded")).toArray();
+ for (const QJsonValue &ex : expanded)
collector.m_expanded.append(ex.toString());
TRACE_PROTOCOL("Expanded: " << collector.m_expanded);
@@ -525,16 +525,16 @@ void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject
TRACE_PROTOCOL("Engines: " << engine << m_engine);
Collector collector(engine);
- QJsonArray expanded = arguments.value(QLatin1String("expanded")).toArray();
- foreach (const QJsonValue &ex, expanded)
+ const QJsonArray expanded = arguments.value(QLatin1String("expanded")).toArray();
+ for (const QJsonValue &ex : expanded)
collector.m_expanded.append(ex.toString());
TRACE_PROTOCOL("Expanded: " << collector.m_expanded);
QJsonArray output;
QV4::Scope scope(engine);
- QJsonArray expressions = arguments.value(QLatin1String("expressions")).toArray();
- foreach (const QJsonValue &expr, expressions) {
+ const QJsonArray expressions = arguments.value(QLatin1String("expressions")).toArray();
+ for (const QJsonValue &expr : expressions) {
QString expression = expr.toObject().value(QLatin1String("expression")).toString();
QString name = expr.toObject().value(QLatin1String("name")).toString();
TRACE_PROTOCOL("Evaluate expression: " << expression);
@@ -546,15 +546,15 @@ void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject
m_runningJob = false;
if (result->isUndefined()) {
QJsonObject dict;
- dict[QStringLiteral("name")] = name;
- dict[QStringLiteral("valueencoded")] = QStringLiteral("undefined");
+ dict.insert(QStringLiteral("name"), name);
+ dict.insert(QStringLiteral("valueencoded"), QStringLiteral("undefined"));
output.append(dict);
} else if (result.ptr && result.ptr->rawValue()) {
collector.collect(&output, QString(), name, *result);
} else {
QJsonObject dict;
- dict[QStringLiteral("name")] = name;
- dict[QStringLiteral("valueencoded")] = QStringLiteral("notaccessible");
+ dict.insert(QStringLiteral("name"), name);
+ dict.insert(QStringLiteral("valueencoded"), QStringLiteral("notaccessible"));
output.append(dict);
}
TRACE_PROTOCOL("EXCEPTION: " << engine->hasException);
@@ -742,7 +742,8 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
TRACE_PROTOCOL("Removing engine" << engine);
if (engine) {
QV4::ExecutionEngine *executionEngine = QV8Engine::getV4(engine->handle());
- foreach (NativeDebugger *debugger, m_debuggers) {
+ const auto debuggersCopy = m_debuggers;
+ for (NativeDebugger *debugger : debuggersCopy) {
if (debugger->engine() == executionEngine)
m_debuggers.removeAll(debugger);
}
@@ -753,7 +754,7 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
void QQmlNativeDebugServiceImpl::stateAboutToBeChanged(QQmlDebugService::State state)
{
if (state == Enabled) {
- foreach (NativeDebugger *debugger, m_debuggers) {
+ for (NativeDebugger *debugger : qAsConst(m_debuggers)) {
QV4::ExecutionEngine *engine = debugger->engine();
if (!engine->debugger())
engine->setDebugger(debugger);
@@ -777,7 +778,7 @@ void QQmlNativeDebugServiceImpl::messageReceived(const QByteArray &message)
} else if (cmd == QLatin1String("echo")) {
response.insert(QStringLiteral("result"), arguments);
} else {
- foreach (NativeDebugger *debugger, m_debuggers)
+ for (NativeDebugger *debugger : qAsConst(m_debuggers))
if (debugger)
debugger->handleCommand(&response, cmd, arguments);
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
index 8015513f9e..58bf1bc94a 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
@@ -67,7 +67,6 @@ QT_BEGIN_NAMESPACE
class NativeDebugger;
class BreakPointHandler;
-class QQmlDebuggerServiceFactory;
class QQmlNativeDebugServiceImpl : public QQmlNativeDebugService
{
@@ -86,7 +85,6 @@ public:
void emitAsynchronousMessageToClient(const QJsonObject &message);
private:
- friend class QQmlDebuggerServiceFactory;
friend class NativeDebugger;
QList<QPointer<NativeDebugger> > m_debuggers;
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.json b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.json
new file mode 100644
index 0000000000..2951166298
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "NativeQmlDebugger" ]
+}
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp
new file mode 100644
index 0000000000..1841c82d5d
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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 "qqmlnativedebugservice.h"
+#include "qqmlnativedebugservicefactory.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlDebugService *QQmlNativeDebugServiceFactory::create(const QString &key)
+{
+ if (key == QQmlNativeDebugServiceImpl::s_key)
+ return new QQmlNativeDebugServiceImpl(this);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.h b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.h
new file mode 100644
index 0000000000..f2b2e4792e
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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 QQMLNATIVEDEBUGSERVICEFACTORY_H
+#define QQMLNATIVEDEBUGSERVICEFACTORY_H
+
+#include <private/qqmldebugservicefactory_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlNativeDebugServiceFactory : public QQmlDebugServiceFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlDebugServiceFactory_iid FILE "qqmlnativedebugservice.json")
+public:
+ QQmlDebugService *create(const QString &key) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLNATIVEDEBUGSERVICEFACTORY_H
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 6b653d5a54..9918a95116 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) :
QQmlEngineControlService(1, parent)
{
+ blockingMode = QQmlDebugConnector::instance()->blockingMode();
}
void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
@@ -68,7 +69,7 @@ void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
void QQmlEngineControlServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
- if (state() == Enabled) {
+ if (blockingMode && state() == Enabled) {
Q_ASSERT(!stoppingEngines.contains(engine));
Q_ASSERT(!startingEngines.contains(engine));
startingEngines.append(engine);
@@ -81,7 +82,7 @@ void QQmlEngineControlServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
void QQmlEngineControlServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
- if (state() == Enabled) {
+ if (blockingMode && state() == Enabled) {
Q_ASSERT(!stoppingEngines.contains(engine));
Q_ASSERT(!startingEngines.contains(engine));
stoppingEngines.append(engine);
@@ -122,10 +123,10 @@ void QQmlEngineControlServiceImpl::stateChanged(State)
{
// We flush everything for any kind of state change, to avoid complicated timing issues.
QMutexLocker lock(&dataMutex);
- foreach (QJSEngine *engine, startingEngines)
+ for (QJSEngine *engine : qAsConst(startingEngines))
emit attachedToEngine(engine);
startingEngines.clear();
- foreach (QJSEngine *engine, stoppingEngines)
+ for (QJSEngine *engine : qAsConst(stoppingEngines))
emit detachedFromEngine(engine);
stoppingEngines.clear();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
index 1138310820..6392944519 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
@@ -79,6 +79,7 @@ protected:
QMutex dataMutex;
QList<QJSEngine *> startingEngines;
QList<QJSEngine *> stoppingEngines;
+ bool blockingMode;
void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index dba2fd3cc3..c1f6f93ef1 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -51,6 +51,8 @@
#include <QtCore/qthread.h>
#include <QtCore/qcoreapplication.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter)
@@ -92,16 +94,18 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler)
m_startTimes.insert(0, profiler);
if (dataComplete) {
QList<QJSEngine *> enginesToRelease;
- foreach (QJSEngine *engine, m_stoppingEngines) {
- foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers.values(engine)) {
- if (m_startTimes.values().contains(engineProfiler)) {
+ for (QJSEngine *engine : qAsConst(m_stoppingEngines)) {
+ const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ const auto startTimesEnd = m_startTimes.cend();
+ for (auto it = range.first; it != range.second; ++it) {
+ if (std::find(m_startTimes.cbegin(), startTimesEnd, *it) != startTimesEnd) {
enginesToRelease.append(engine);
break;
}
}
}
sendMessages();
- foreach (QJSEngine *engine, enginesToRelease) {
+ for (QJSEngine *engine : qAsConst(enginesToRelease)) {
m_stoppingEngines.removeOne(engine);
emit detachedFromEngine(engine);
}
@@ -130,8 +134,9 @@ void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine)
"QML profilers have to be added from the engine thread");
QMutexLocker lock(&m_configMutex);
- foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine))
- profiler->stopWaiting();
+ const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ for (auto it = range.first; it != range.second; ++it)
+ (*it)->stopWaiting();
}
void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
@@ -141,7 +146,9 @@ void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
QMutexLocker lock(&m_configMutex);
bool isRunning = false;
- foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
+ const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ for (auto it = range.first; it != range.second; ++it) {
+ QQmlAbstractProfilerAdapter *profiler = *it;
if (profiler->isRunning())
isRunning = true;
profiler->startWaiting();
@@ -160,7 +167,9 @@ void QQmlProfilerServiceImpl::engineRemoved(QJSEngine *engine)
"QML profilers have to be removed from the engine thread");
QMutexLocker lock(&m_configMutex);
- foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
+ const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ for (auto it = range.first; it != range.second; ++it) {
+ QQmlAbstractProfilerAdapter *profiler = *it;
removeProfilerFromStartTimes(profiler);
delete profiler;
}
@@ -183,7 +192,7 @@ void QQmlProfilerServiceImpl::addGlobalProfiler(QQmlAbstractProfilerAdapter *pro
// Global profilers are started whenever any engine profiler is started and stopped when
// all engine profilers are stopped.
quint64 features = 0;
- foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers)
+ for (QQmlAbstractProfilerAdapter *engineProfiler : qAsConst(m_engineProfilers))
features |= engineProfiler->features();
if (features != 0)
@@ -231,7 +240,9 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features
d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace;
bool startedAny = false;
if (engine != 0) {
- foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
+ const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ for (auto it = range.first; it != range.second; ++it) {
+ QQmlAbstractProfilerAdapter *profiler = *it;
if (!profiler->isRunning()) {
profiler->startProfiling(features);
startedAny = true;
@@ -249,12 +260,12 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features
startedAny = true;
}
}
- foreach (QJSEngine *profiledEngine, engines)
+ for (QJSEngine *profiledEngine : qAsConst(engines))
d << idForObject(profiledEngine);
}
if (startedAny) {
- foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) {
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
if (!profiler->isRunning())
profiler->startProfiling(features);
}
@@ -294,7 +305,7 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
if (stopping.isEmpty())
return;
- foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) {
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
if (!profiler->isRunning())
continue;
m_startTimes.insert(-1, profiler);
@@ -308,10 +319,10 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
emit stopFlushTimer();
m_waitingForStop = true;
- foreach (QQmlAbstractProfilerAdapter *profiler, reporting)
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting))
profiler->reportData(m_useMessageTypes);
- foreach (QQmlAbstractProfilerAdapter *profiler, stopping)
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(stopping))
profiler->stopProfiling();
}
@@ -327,7 +338,7 @@ void QQmlProfilerServiceImpl::sendMessages()
traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace;
QSet<QJSEngine *> seen;
- foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) {
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_startTimes)) {
for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
i != m_engineProfilers.end(); ++i) {
if (i.value() == profiler && !seen.contains(i.key())) {
@@ -367,7 +378,7 @@ void QQmlProfilerServiceImpl::sendMessages()
emit messagesToClient(name(), messages);
// Restart flushing if any profilers are still running
- foreach (const QQmlAbstractProfilerAdapter *profiler, m_engineProfilers) {
+ for (const QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) {
if (profiler->isRunning()) {
emit startFlushTimer();
break;
@@ -438,21 +449,21 @@ void QQmlProfilerServiceImpl::flush()
QMutexLocker lock(&m_configMutex);
QList<QQmlAbstractProfilerAdapter *> reporting;
- foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers) {
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) {
if (profiler->isRunning()) {
m_startTimes.insert(-1, profiler);
reporting.append(profiler);
}
}
- foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) {
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
if (profiler->isRunning()) {
m_startTimes.insert(-1, profiler);
reporting.append(profiler);
}
}
- foreach (QQmlAbstractProfilerAdapter *profiler, reporting)
+ for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting))
profiler->reportData(m_useMessageTypes);
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
index 772e53bde7..cdce4cd240 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
@@ -60,7 +60,7 @@ class QQmlProfilerServiceFactory : public QQmlDebugServiceFactory
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlDebugServiceFactory_iid FILE "qqmlprofilerservice.json")
public:
- QQmlDebugService *create(const QString &key);
+ QQmlDebugService *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h
index 489545b504..41b9875c03 100644
--- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h
@@ -61,7 +61,7 @@ class QQuickProfilerAdapterFactory : public QQmlAbstractProfilerAdapterFactory
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlAbstractProfilerAdapterFactory_iid FILE "qquickprofileradapter.json")
public:
- QQmlAbstractProfilerAdapter *create(const QString &key);
+ QQmlAbstractProfilerAdapter *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index 96b3455790..f6f48e43a4 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -346,7 +346,7 @@ void QQmlDebugServerImpl::parseArguments()
QString fileName;
QStringList services;
- const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','));
+ const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts);
for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) {
const QStringRef &strArgument = *argsIt;
if (strArgument.startsWith(QLatin1String("port:"))) {
@@ -377,7 +377,7 @@ void QQmlDebugServerImpl::parseArguments()
services.append(strArgument.mid(9).toString());
} else if (!services.isEmpty()) {
services.append(strArgument.toString());
- } else {
+ } else if (!strArgument.startsWith(QLatin1String("connector:"))) {
const QString message = tr("QML Debugger: Invalid argument \"%1\" detected."
" Ignoring the same.").arg(strArgument.toString());
qWarning("%s", qPrintable(message));
@@ -589,12 +589,12 @@ void QQmlDebugServerImpl::addEngine(QJSEngine *engine)
QMutexLocker locker(&m_helloMutex);
Q_ASSERT(!m_engineConditions.contains(engine));
- foreach (QQmlDebugService *service, m_plugins)
+ for (QQmlDebugService *service : qAsConst(m_plugins))
service->engineAboutToBeAdded(engine);
m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count());
- foreach (QQmlDebugService *service, m_plugins)
+ for (QQmlDebugService *service : qAsConst(m_plugins))
service->engineAdded(engine);
}
@@ -606,12 +606,12 @@ void QQmlDebugServerImpl::removeEngine(QJSEngine *engine)
QMutexLocker locker(&m_helloMutex);
Q_ASSERT(m_engineConditions.contains(engine));
- foreach (QQmlDebugService *service, m_plugins)
+ for (QQmlDebugService *service : qAsConst(m_plugins))
service->engineAboutToBeRemoved(engine);
m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count());
- foreach (QQmlDebugService *service, m_plugins)
+ for (QQmlDebugService *service : qAsConst(m_plugins))
service->engineRemoved(engine);
m_engineConditions.remove(engine);
@@ -703,11 +703,11 @@ void QQmlDebugServerImpl::sendMessages(const QString &name, const QList<QByteArr
if (m_clientSupportsMultiPackets) {
QQmlDebugPacket out;
out << name;
- foreach (const QByteArray &message, messages)
+ for (const QByteArray &message : messages)
out << message;
m_protocol->send(out.data());
} else {
- foreach (const QByteArray &message, messages)
+ for (const QByteArray &message : messages)
doSendMessage(name, message);
}
m_connection->flush();
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.h b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.h
index fd71b03019..2debabaeb2 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.h
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.h
@@ -63,7 +63,7 @@ class QQmlDebugServerFactory : public QQmlDebugConnectorFactory
// QQmlDebugServer is for connection plugins.
Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmldebugserver.json")
public:
- QQmlDebugConnector *create(const QString &key);
+ QQmlDebugConnector *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
index 52d9f4b709..d3b0e00584 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
@@ -50,7 +50,7 @@ class QTcpServerConnectionFactory : public QQmlDebugServerConnectionFactory
Q_PLUGIN_METADATA(IID QQmlDebugServerConnectionFactory_iid FILE "qtcpserverconnection.json")
Q_INTERFACES(QQmlDebugServerConnectionFactory)
public:
- QQmlDebugServerConnection *create(const QString &key);
+ QQmlDebugServerConnection *create(const QString &key) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index 907fbe9273..8123e2999e 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -19,12 +19,16 @@ qtConfig(qml-network) {
# Services
SUBDIRS += \
qmldbg_debugger \
- qmldbg_profiler
+ qmldbg_profiler \
+ qmldbg_messages \
+ qmldbg_nativedebugger
qmldbg_server.depends = packetprotocol
qmldbg_native.depends = packetprotocol
qmldbg_debugger.depends = packetprotocol
qmldbg_profiler.depends = packetprotocol
+qmldbg_messages.depends = packetprotocol
+qmldbg_nativedebugger.depends = packetprotocol
qtHaveModule(quick) {
SUBDIRS += \
diff --git a/src/plugins/scenegraph/openvg/openvg.json b/src/plugins/scenegraph/openvg/openvg.json
new file mode 100644
index 0000000000..224afbf784
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/openvg.json
@@ -0,0 +1,3 @@
+{
+ "Keys": ["openvg"]
+}
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
new file mode 100644
index 0000000000..8a58796a05
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -0,0 +1,56 @@
+TARGET = qsgopenvgbackend
+
+QT += gui-private core-private qml-private quick-private
+
+PLUGIN_TYPE = scenegraph
+PLUGIN_CLASS_NAME = QSGOpenVGAdaptation
+load(qt_plugin)
+
+QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
+QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
+
+QMAKE_USE += openvg
+
+OTHER_FILES += $$PWD/openvg.json
+
+HEADERS += \
+ qsgopenvgadaptation_p.h \
+ qsgopenvgcontext_p.h \
+ qsgopenvgrenderloop_p.h \
+ qsgopenvgglyphnode_p.h \
+ qopenvgcontext_p.h \
+ qsgopenvgrenderer_p.h \
+ qsgopenvginternalrectanglenode.h \
+ qsgopenvgnodevisitor.h \
+ qopenvgmatrix.h \
+ qsgopenvgpublicnodes.h \
+ qsgopenvginternalimagenode.h \
+ qsgopenvgtexture.h \
+ qsgopenvglayer.h \
+ qsgopenvghelpers.h \
+ qsgopenvgfontglyphcache.h \
+ qsgopenvgpainternode.h \
+ qsgopenvgspritenode.h \
+ qsgopenvgrenderable.h \
+ qopenvgoffscreensurface.h
+
+SOURCES += \
+ qsgopenvgadaptation.cpp \
+ qsgopenvgcontext.cpp \
+ qsgopenvgrenderloop.cpp \
+ qsgopenvgglyphnode.cpp \
+ qopenvgcontext.cpp \
+ qsgopenvgrenderer.cpp \
+ qsgopenvginternalrectanglenode.cpp \
+ qsgopenvgnodevisitor.cpp \
+ qopenvgmatrix.cpp \
+ qsgopenvgpublicnodes.cpp \
+ qsgopenvginternalimagenode.cpp \
+ qsgopenvgtexture.cpp \
+ qsgopenvglayer.cpp \
+ qsgopenvghelpers.cpp \
+ qsgopenvgfontglyphcache.cpp \
+ qsgopenvgpainternode.cpp \
+ qsgopenvgspritenode.cpp \
+ qsgopenvgrenderable.cpp \
+ qopenvgoffscreensurface.cpp
diff --git a/src/plugins/scenegraph/openvg/qopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qopenvgcontext.cpp
new file mode 100644
index 0000000000..ea2c24afdb
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgcontext.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** 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 <qpa/qplatformnativeinterface.h>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QOpenVGContext::QOpenVGContext(QWindow *window)
+ : m_window(window)
+{
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ m_display = reinterpret_cast<EGLDisplay>(nativeInterface->nativeResourceForWindow("EglDisplay", window));
+ m_surface = reinterpret_cast<EGLSurface>(nativeInterface->nativeResourceForWindow("EglSurface", window));
+
+ if (m_display == 0)
+ qFatal("QOpenVGContext: failed to get EGLDisplay");
+ if (m_surface == 0)
+ qFatal("QOpenVGContext: failed to get EGLSurface");
+
+ EGLint configID = 0;
+ if (eglQuerySurface(m_display, m_surface, EGL_CONFIG_ID, &configID)) {
+ EGLint numConfigs;
+ const EGLint configAttribs[] = {
+ EGL_CONFIG_ID, configID,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &m_config, 1, &numConfigs);
+ } else {
+ qFatal("QOpenVGContext: failed to get surface config");
+ }
+
+ // Create an EGL Context
+ eglBindAPI(EGL_OPENVG_API);
+ m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, 0);
+ if (!m_context)
+ qFatal("QOpenVGContext: eglCreateContext failed");
+}
+
+QOpenVGContext::~QOpenVGContext()
+{
+ doneCurrent();
+ eglDestroyContext(m_display, m_context);
+}
+
+void QOpenVGContext::makeCurrent()
+{
+ makeCurrent(m_surface);
+}
+
+void QOpenVGContext::makeCurrent(EGLSurface surface)
+{
+ eglMakeCurrent(m_display, surface, surface, m_context);
+}
+
+void QOpenVGContext::doneCurrent()
+{
+ eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+}
+
+void QOpenVGContext::swapBuffers()
+{
+ swapBuffers(m_surface);
+}
+
+void QOpenVGContext::swapBuffers(EGLSurface surface)
+{
+ eglSwapBuffers(m_display, surface);
+}
+
+QWindow *QOpenVGContext::window() const
+{
+ return m_window;
+}
+
+QImage QOpenVGContext::readFramebuffer(const QSize &size)
+{
+ QImage framebufferImage(size, QImage::Format_RGB32);
+ vgReadPixels(framebufferImage.bits(), framebufferImage.bytesPerLine(), VG_sXRGB_8888, 0, 0, size.width(), size.height());
+ return framebufferImage.mirrored(false, true);
+}
+
+void QOpenVGContext::getConfigs()
+{
+ EGLint configsAvailable = 0;
+ eglGetConfigs(m_display, 0, 0, &configsAvailable);
+
+ QVector<EGLConfig> configs(configsAvailable);
+ eglGetConfigs(m_display, configs.data(), configs.size(), &configsAvailable);
+
+ for (EGLConfig config : configs) {
+ EGLint value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &value);
+ qDebug() << "#################\n" << "EGL_CONFIG_ID:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BUFFER_SIZE, &value);
+ qDebug() << "EGL_BUFFER_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &value);
+ qDebug() << "EGL_ALPHA_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &value);
+ qDebug() << "EGL_RED_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &value);
+ qDebug() << "EGL_GREEN_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &value);
+ qDebug() << "EGL_BLUE_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_DEPTH_SIZE, &value);
+ qDebug() << "EGL_DEPTH_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_STENCIL_SIZE, &value);
+ qDebug() << "EGL_STENCIL_SIZE:" << value;
+
+ eglGetConfigAttrib(m_display, config, EGL_ALPHA_MASK_SIZE, &value);
+ qDebug() << "EGL_ALPHA_MASK_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BIND_TO_TEXTURE_RGB, &value);
+ qDebug() << "EGL_BIND_TO_TEXTURE_RGB:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BIND_TO_TEXTURE_RGBA, &value);
+ qDebug() << "EGL_BIND_TO_TEXTURE_RGBA:" << value;
+
+
+ eglGetConfigAttrib(m_display, config, EGL_COLOR_BUFFER_TYPE, &value);
+ qDebug() << "EGL_COLOR_BUFFER_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFIG_CAVEAT, &value);
+ qDebug() << "EGL_CONFIG_CAVEAT:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFORMANT, &value);
+ qDebug() << "EGL_CONFORMANT:" << value;
+
+
+ eglGetConfigAttrib(m_display, config, EGL_LEVEL, &value);
+ qDebug() << "EGL_LEVEL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_LUMINANCE_SIZE, &value);
+ qDebug() << "EGL_LUMINANCE_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_WIDTH, &value);
+ qDebug() << "EGL_MAX_PBUFFER_WIDTH:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_HEIGHT, &value);
+ qDebug() << "EGL_MAX_PBUFFER_HEIGHT:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_PIXELS, &value);
+ qDebug() << "EGL_MAX_PBUFFER_PIXELS:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_SWAP_INTERVAL, &value);
+ qDebug() << "EGL_MAX_SWAP_INTERVAL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MIN_SWAP_INTERVAL, &value);
+ qDebug() << "EGL_MIN_SWAP_INTERVAL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_RENDERABLE, &value);
+ qDebug() << "EGL_NATIVE_RENDERABLE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &value);
+ qDebug() << "EGL_NATIVE_VISUAL_ID:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_TYPE, &value);
+ qDebug() << "EGL_NATIVE_VISUAL_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_RENDERABLE_TYPE, &value);
+ qDebug() << "EGL_RENDERABLE_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &value);
+ qDebug() << "EGL_SAMPLE_BUFFERS:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_SAMPLES, &value);
+ qDebug() << "EGL_SAMPLES:" << value;
+
+ eglGetConfigAttrib(m_display, config, EGL_SURFACE_TYPE, &value);
+ qDebug() << "EGL_SURFACE_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_TYPE, &value);
+ qDebug() << "EGL_TRANSPARENT_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_RED_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_RED_VALUE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_GREEN_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_GREEN_VALUE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_BLUE_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_BLUE_VALUE:" << value;
+ }
+}
+
+void QOpenVGContext::checkErrors()
+{
+ VGErrorCode error;
+ EGLint eglError;
+ do {
+ error = vgGetError();
+ eglError = eglGetError();
+ qDebug() << "error: " << QString::number(error, 16);
+ qDebug() << "eglError: " << QString::number(eglError, 16);
+ } while (error != VG_NO_ERROR && eglError != EGL_SUCCESS);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qopenvgcontext_p.h
new file mode 100644
index 0000000000..a1ba73957f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgcontext_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 QOPENVGCONTEXT_H
+#define QOPENVGCONTEXT_H
+
+#include <QtGui/QWindow>
+#include <QtGui/QImage>
+
+#include <EGL/egl.h>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext
+{
+public:
+ QOpenVGContext(QWindow *window);
+ ~QOpenVGContext();
+
+ void makeCurrent();
+ void makeCurrent(EGLSurface surface);
+ void doneCurrent();
+ void swapBuffers();
+ void swapBuffers(EGLSurface surface);
+
+
+ QWindow *window() const;
+
+ EGLDisplay eglDisplay() { return m_display; }
+ EGLConfig eglConfig() { return m_config; }
+ EGLContext eglContext() { return m_context; }
+
+ QImage readFramebuffer(const QSize &size);
+
+ void getConfigs();
+
+ static void checkErrors();
+
+private:
+ EGLSurface m_surface;
+ EGLDisplay m_display;
+ EGLConfig m_config;
+ EGLContext m_context;
+
+ QWindow *m_window;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPENVGCONTEXT_H
diff --git a/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp
new file mode 100644
index 0000000000..83ce96578e
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** 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 "qopenvgmatrix.h"
+
+QT_BEGIN_NAMESPACE
+
+// QOpenVGMatrix: Because Qt will never have enough matrix classes
+// Internally the data is stored as column-major format
+// So this is a 3x3 version of QMatrix4x4 for optimal
+// OpenVG usage.
+
+QOpenVGMatrix::QOpenVGMatrix()
+{
+ setToIdentity();
+}
+
+QOpenVGMatrix::QOpenVGMatrix(const float *values)
+{
+ for (int col = 0; col < 3; ++col)
+ for (int row = 0; row < 3; ++row)
+ m[col][row] = values[col * 3 + row];
+}
+
+const float &QOpenVGMatrix::operator()(int row, int column) const
+{
+ Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4);
+ return m[column][row];
+}
+
+float &QOpenVGMatrix::operator()(int row, int column)
+{
+ Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4);
+ return m[column][row];
+}
+
+bool QOpenVGMatrix::isIdentity() const
+{
+ if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
+ return false;
+ if ( m[1][0] != 0.0f || m[1][1] != 1.0f)
+ return false;
+ if (m[1][2] != 0.0f || m[2][0] != 0.0f)
+ return false;
+ if (m[2][1] != 0.0f || m[2][2] != 1.0f)
+ return false;
+
+ return true;
+}
+
+void QOpenVGMatrix::setToIdentity()
+{
+ m[0][0] = 1.0f;
+ m[0][1] = 0.0f;
+ m[0][2] = 0.0f;
+ m[1][0] = 0.0f;
+ m[1][1] = 1.0f;
+ m[1][2] = 0.0f;
+ m[2][0] = 0.0f;
+ m[2][1] = 0.0f;
+ m[2][2] = 1.0f;
+}
+
+bool QOpenVGMatrix::isAffine() const
+{
+ if (m[0][2] == 0.0f && m[1][2] == 0.0f && m[2][2] == 1.0f)
+ return true;
+
+ return false;
+}
+
+QPointF QOpenVGMatrix::map(const QPointF &point) const
+{
+ return *this * point;
+}
+
+void QOpenVGMatrix::fill(float value)
+{
+ m[0][0] = value;
+ m[0][1] = value;
+ m[0][2] = value;
+ m[1][0] = value;
+ m[1][1] = value;
+ m[1][2] = value;
+ m[2][0] = value;
+ m[2][1] = value;
+ m[2][2] = value;
+}
+
+QOpenVGMatrix QOpenVGMatrix::transposed() const
+{
+ QOpenVGMatrix result;
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 3; ++col)
+ result.m[col][row] = m[row][col];
+ }
+ return result;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator+=(const QOpenVGMatrix &other)
+{
+ m[0][0] += other.m[0][0];
+ m[0][1] += other.m[0][1];
+ m[0][2] += other.m[0][2];
+ m[1][0] += other.m[1][0];
+ m[1][1] += other.m[1][1];
+ m[1][2] += other.m[1][2];
+ m[2][0] += other.m[2][0];
+ m[2][1] += other.m[2][1];
+ m[2][2] += other.m[2][2];
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator-=(const QOpenVGMatrix &other)
+{
+ m[0][0] -= other.m[0][0];
+ m[0][1] -= other.m[0][1];
+ m[0][2] -= other.m[0][2];
+ m[1][0] -= other.m[1][0];
+ m[1][1] -= other.m[1][1];
+ m[1][2] -= other.m[1][2];
+ m[2][0] -= other.m[2][0];
+ m[2][1] -= other.m[2][1];
+ m[2][2] -= other.m[2][2];
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator*=(const QOpenVGMatrix &other)
+{
+ float m0, m1;
+ m0 = m[0][0] * other.m[0][0]
+ + m[1][0] * other.m[0][1]
+ + m[2][0] * other.m[0][2];
+ m1 = m[0][0] * other.m[1][0]
+ + m[1][0] * other.m[1][1]
+ + m[2][0] * other.m[1][2];
+ m[2][0] = m[0][0] * other.m[2][0]
+ + m[1][0] * other.m[2][1]
+ + m[2][0] * other.m[2][2];
+ m[0][0] = m0;
+ m[1][0] = m1;
+
+ m0 = m[0][1] * other.m[0][0]
+ + m[1][1] * other.m[0][1]
+ + m[2][1] * other.m[0][2];
+ m1 = m[0][1] * other.m[1][0]
+ + m[1][1] * other.m[1][1]
+ + m[2][1] * other.m[1][2];
+ m[2][1] = m[0][1] * other.m[2][0]
+ + m[1][1] * other.m[2][1]
+ + m[2][1] * other.m[2][2];
+ m[0][1] = m0;
+ m[1][1] = m1;
+
+ m0 = m[0][2] * other.m[0][0]
+ + m[1][2] * other.m[0][1]
+ + m[2][2] * other.m[0][2];
+ m1 = m[0][2] * other.m[1][0]
+ + m[1][2] * other.m[1][1]
+ + m[2][2] * other.m[1][2];
+ m[2][2] = m[0][2] * other.m[2][0]
+ + m[1][2] * other.m[2][1]
+ + m[2][2] * other.m[2][2];
+ m[0][2] = m0;
+ m[1][2] = m1;
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator*=(float factor)
+{
+ m[0][0] *= factor;
+ m[0][1] *= factor;
+ m[0][2] *= factor;
+ m[1][0] *= factor;
+ m[1][1] *= factor;
+ m[1][2] *= factor;
+ m[2][0] *= factor;
+ m[2][1] *= factor;
+ m[2][2] *= factor;
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator/=(float divisor)
+{
+ m[0][0] /= divisor;
+ m[0][1] /= divisor;
+ m[0][2] /= divisor;
+ m[1][0] /= divisor;
+ m[1][1] /= divisor;
+ m[1][2] /= divisor;
+ m[2][0] /= divisor;
+ m[2][1] /= divisor;
+ m[2][2] /= divisor;
+ return *this;
+}
+
+bool QOpenVGMatrix::operator==(const QOpenVGMatrix &other) const
+{
+ return m[0][0] == other.m[0][0] &&
+ m[0][1] == other.m[0][1] &&
+ m[0][2] == other.m[0][2] &&
+ m[1][0] == other.m[1][0] &&
+ m[1][1] == other.m[1][1] &&
+ m[1][2] == other.m[1][2] &&
+ m[2][0] == other.m[2][0] &&
+ m[2][1] == other.m[2][1] &&
+ m[2][2] == other.m[2][2];
+}
+
+bool QOpenVGMatrix::operator!=(const QOpenVGMatrix &other) const
+{
+ return m[0][0] != other.m[0][0] ||
+ m[0][1] != other.m[0][1] ||
+ m[0][2] != other.m[0][2] ||
+ m[1][0] != other.m[1][0] ||
+ m[1][1] != other.m[1][1] ||
+ m[1][2] != other.m[1][2] ||
+ m[2][0] != other.m[2][0] ||
+ m[2][1] != other.m[2][1] ||
+ m[2][2] != other.m[2][2];
+}
+
+void QOpenVGMatrix::copyDataTo(float *values) const
+{
+ // Row-Major?
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 3; ++col)
+ values[row * 3 + col] = float(m[col][row]);
+ }
+}
+
+QOpenVGMatrix operator*(const QOpenVGMatrix &m1, const QOpenVGMatrix &m2)
+{
+ QOpenVGMatrix matrix;
+ matrix.m[0][0] = m1.m[0][0] * m2.m[0][0]
+ + m1.m[1][0] * m2.m[0][1]
+ + m1.m[2][0] * m2.m[0][2];
+ matrix.m[0][1] = m1.m[0][1] * m2.m[0][0]
+ + m1.m[1][1] * m2.m[0][1]
+ + m1.m[2][1] * m2.m[0][2];
+ matrix.m[0][2] = m1.m[0][2] * m2.m[0][0]
+ + m1.m[1][2] * m2.m[0][1]
+ + m1.m[2][2] * m2.m[0][2];
+
+ matrix.m[1][0] = m1.m[0][0] * m2.m[1][0]
+ + m1.m[1][0] * m2.m[1][1]
+ + m1.m[2][0] * m2.m[1][2];
+ matrix.m[1][1] = m1.m[0][1] * m2.m[1][0]
+ + m1.m[1][1] * m2.m[1][1]
+ + m1.m[2][1] * m2.m[1][2];
+ matrix.m[1][2] = m1.m[0][2] * m2.m[1][0]
+ + m1.m[1][2] * m2.m[1][1]
+ + m1.m[2][2] * m2.m[1][2];
+
+ matrix.m[2][0] = m1.m[0][0] * m2.m[2][0]
+ + m1.m[1][0] * m2.m[2][1]
+ + m1.m[2][0] * m2.m[2][2];
+ matrix.m[2][1] = m1.m[0][1] * m2.m[2][0]
+ + m1.m[1][1] * m2.m[2][1]
+ + m1.m[2][1] * m2.m[2][2];
+ matrix.m[2][2] = m1.m[0][2] * m2.m[2][0]
+ + m1.m[1][2] * m2.m[2][1]
+ + m1.m[2][2] * m2.m[2][2];
+ return matrix;
+}
+
+QPointF operator*(const QPointF& point, const QOpenVGMatrix& matrix)
+{
+ float xin = point.x();
+ float yin = point.y();
+ float x = xin * matrix.m[0][0] +
+ yin * matrix.m[0][1] +
+ matrix.m[0][2];
+ float y = xin * matrix.m[1][0] +
+ yin * matrix.m[1][1] +
+ matrix.m[1][2];
+ float w = xin * matrix.m[2][0] +
+ yin * matrix.m[2][1] +
+ matrix.m[2][2];
+ if (w == 1.0f) {
+ return QPointF(float(x), float(y));
+ } else {
+ return QPointF(float(x / w), float(y / w));
+ }
+}
+
+QPointF operator*(const QOpenVGMatrix& matrix, const QPointF& point)
+{
+ float xin = point.x();
+ float yin = point.y();
+ float x = xin * matrix.m[0][0] +
+ yin * matrix.m[1][0] +
+ matrix.m[2][0];
+ float y = xin * matrix.m[0][1] +
+ yin * matrix.m[1][1] +
+ matrix.m[2][1];
+ float w = xin * matrix.m[0][2] +
+ yin * matrix.m[1][2] +
+ matrix.m[2][2];
+ if (w == 1.0f) {
+ return QPointF(float(x), float(y));
+ } else {
+ return QPointF(float(x / w), float(y / w));
+ }
+}
+
+QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m)
+{
+ QDebugStateSaver saver(dbg);
+ // Output in row-major order because it is more human-readable.
+ dbg.nospace() << "QOpenVGMatrix:(" << endl
+ << qSetFieldWidth(10)
+ << m(0, 0) << m(0, 1) << m(0, 2) << endl
+ << m(1, 0) << m(1, 1) << m(1, 2) << endl
+ << m(2, 0) << m(2, 1) << m(2, 2) << endl
+ << qSetFieldWidth(0) << ')';
+ return dbg;
+}
+
+QDataStream &operator<<(QDataStream &stream, const QOpenVGMatrix &matrix)
+{
+ for (int row = 0; row < 3; ++row)
+ for (int col = 0; col < 3; ++col)
+ stream << matrix(row, col);
+ return stream;
+}
+
+
+QDataStream &operator>>(QDataStream &stream, QOpenVGMatrix &matrix)
+{
+ float x;
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ stream >> x;
+ matrix(row, col) = x;
+ }
+ }
+ return stream;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qopenvgmatrix.h b/src/plugins/scenegraph/openvg/qopenvgmatrix.h
new file mode 100644
index 0000000000..f51bf8147d
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgmatrix.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** 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 QOPENVGMATRIX_H
+#define QOPENVGMATRIX_H
+
+#include <QtCore/qdebug.h>
+#include <QtCore/QDataStream>
+#include <QtCore/QPointF>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGMatrix
+{
+public:
+ QOpenVGMatrix();
+ explicit QOpenVGMatrix(const float *values);
+
+ const float& operator()(int row, int column) const;
+ float& operator()(int row, int column);
+
+ bool isIdentity() const;
+ void setToIdentity();
+
+ bool isAffine() const;
+
+ QPointF map(const QPointF& point) const;
+
+ void fill(float value);
+
+ QOpenVGMatrix transposed() const;
+
+ QOpenVGMatrix& operator+=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator-=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator*=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator*=(float factor);
+ QOpenVGMatrix& operator/=(float divisor);
+ friend QOpenVGMatrix operator*(const QOpenVGMatrix& m1, const QOpenVGMatrix& m2);
+ friend QPointF operator*(const QPointF& point, const QOpenVGMatrix& matrix);
+ friend QPointF operator*(const QOpenVGMatrix& matrix, const QPointF& point);
+#ifndef QT_NO_DEBUG_STREAM
+ friend QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m);
+#endif
+ bool operator==(const QOpenVGMatrix& other) const;
+ bool operator!=(const QOpenVGMatrix& other) const;
+
+ void copyDataTo(float *values) const;
+
+ float *data() { return *m; }
+ const float *data() const { return *m; }
+ const float *constData() const { return *m; }
+
+private:
+ float m[3][3];
+};
+
+QOpenVGMatrix operator*(const QOpenVGMatrix& m1, const QOpenVGMatrix& m2);
+QPointF operator*(const QPointF& point, const QOpenVGMatrix& matrix);
+QPointF operator*(const QOpenVGMatrix& matrix, const QPointF& point);
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m);
+#endif
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &, const QOpenVGMatrix &);
+QDataStream &operator>>(QDataStream &, QOpenVGMatrix &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QOPENVGMATRIX_H
diff --git a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
new file mode 100644
index 0000000000..80af227fb4
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 "qopenvgoffscreensurface.h"
+
+#include <QtGui/QImage>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QOpenVGOffscreenSurface::QOpenVGOffscreenSurface(const QSize &size)
+ : m_size(size)
+{
+ m_display = eglGetCurrentDisplay();
+ m_image = vgCreateImage(VG_sARGB_8888_PRE, m_size.width(), m_size.height(), VG_IMAGE_QUALITY_BETTER);
+
+ const EGLint configAttribs[] = {
+ EGL_CONFORMANT, EGL_OPENVG_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_MASK_SIZE, 8,
+ EGL_NONE
+ };
+
+ EGLConfig pbufferConfig;
+ EGLint numConfig;
+ eglChooseConfig(m_display, configAttribs, &pbufferConfig, 1, &numConfig);
+
+ m_context = eglCreateContext(m_display, pbufferConfig, eglGetCurrentContext(), 0);
+ if (m_context == EGL_NO_CONTEXT)
+ qWarning("QOpenVGOffscreenSurface: failed to create EGLContext");
+
+ m_renderTarget = eglCreatePbufferFromClientBuffer(m_display,
+ EGL_OPENVG_IMAGE,
+ (EGLClientBuffer)m_image,
+ pbufferConfig,
+ 0);
+ if (m_renderTarget == EGL_NO_SURFACE)
+ qWarning("QOpenVGOffscreenSurface: failed to create EGLSurface from VGImage");
+}
+
+QOpenVGOffscreenSurface::~QOpenVGOffscreenSurface()
+{
+ vgDestroyImage(m_image);
+ eglDestroySurface(m_display, m_renderTarget);
+ eglDestroyContext(m_display, m_context);
+}
+
+void QOpenVGOffscreenSurface::makeCurrent()
+{
+ EGLContext currentContext = eglGetCurrentContext();
+ if (m_context != currentContext) {
+ m_previousContext = eglGetCurrentContext();
+ m_previousReadSurface = eglGetCurrentSurface(EGL_READ);
+ m_previousDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+
+ eglMakeCurrent(m_display, m_renderTarget, m_renderTarget, m_context);
+ }
+}
+
+void QOpenVGOffscreenSurface::doneCurrent()
+{
+ EGLContext currentContext = eglGetCurrentContext();
+ if (m_context == currentContext) {
+ eglMakeCurrent(m_display, m_previousDrawSurface, m_previousReadSurface, m_previousContext);
+ m_previousContext = EGL_NO_CONTEXT;
+ m_previousReadSurface = EGL_NO_SURFACE;
+ m_previousDrawSurface = EGL_NO_SURFACE;
+ }
+}
+
+void QOpenVGOffscreenSurface::swapBuffers()
+{
+ eglSwapBuffers(m_display, m_renderTarget);
+}
+
+QImage QOpenVGOffscreenSurface::readbackQImage()
+{
+ QImage readbackImage(m_size, QImage::Format_ARGB32_Premultiplied);
+ vgGetImageSubData(m_image, readbackImage.bits(), readbackImage.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, m_size.width(), m_size.height());
+ return readbackImage;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.h b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.h
new file mode 100644
index 0000000000..746e4de1cd
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QOPENVGOFFSCREENSURFACE_H
+#define QOPENVGOFFSCREENSURFACE_H
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGOffscreenSurface
+{
+public:
+ QOpenVGOffscreenSurface(const QSize &size);
+ ~QOpenVGOffscreenSurface();
+
+ void makeCurrent();
+ void doneCurrent();
+ void swapBuffers();
+
+ VGImage image() { return m_image; }
+ QSize size() const { return m_size; }
+
+ QImage readbackQImage();
+
+private:
+ VGImage m_image;
+ QSize m_size;
+ EGLContext m_context;
+ EGLSurface m_renderTarget;
+ EGLContext m_previousContext = EGL_NO_CONTEXT;
+ EGLSurface m_previousReadSurface = EGL_NO_SURFACE;
+ EGLSurface m_previousDrawSurface = EGL_NO_SURFACE;
+ EGLDisplay m_display;
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPENVGOFFSCREENSURFACE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp b/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp
new file mode 100644
index 0000000000..1a26522459
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgadaptation_p.h"
+
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvgrenderloop_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGAdaptation::QSGOpenVGAdaptation(QObject *parent)
+ : QSGContextPlugin(parent)
+{
+}
+
+QStringList QSGOpenVGAdaptation::keys() const
+{
+ return QStringList() << QLatin1String("openvg");
+}
+
+QSGContext *QSGOpenVGAdaptation::create(const QString &key) const
+{
+ Q_UNUSED(key)
+ if (!instance)
+ instance = new QSGOpenVGContext();
+ return instance;
+}
+
+QSGRenderLoop *QSGOpenVGAdaptation::createWindowManager()
+{
+ return new QSGOpenVGRenderLoop();
+}
+
+QSGContextFactoryInterface::Flags QSGOpenVGAdaptation::flags(const QString &key) const
+{
+ Q_UNUSED(key)
+ return 0;
+}
+
+QSGOpenVGContext *QSGOpenVGAdaptation::instance = nullptr;
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h b/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h
new file mode 100644
index 0000000000..77f79af9ac
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGADAPTATION_H
+#define QSGOPENVGADAPTATION_H
+
+#include <private/qsgcontextplugin_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGContext;
+class QSGRenderLoop;
+class QSGOpenVGContext;
+
+class QSGOpenVGAdaptation : public QSGContextPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSGContextFactoryInterface" FILE "openvg.json")
+public:
+ QSGOpenVGAdaptation(QObject *parent = nullptr);
+
+ QStringList keys() const override;
+ QSGContext *create(const QString &key) const override;
+ QSGRenderLoop *createWindowManager() override;
+ Flags flags(const QString &key) const override;
+private:
+ static QSGOpenVGContext *instance;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGADAPTATION_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
new file mode 100644
index 0000000000..22a80c62e8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgcontext_p.h"
+#include "qsgopenvgrenderer_p.h"
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
+#include "qsgopenvgpublicnodes.h"
+#include "qsgopenvgtexture.h"
+#include "qsgopenvglayer.h"
+#include "qsgopenvgglyphnode_p.h"
+#include "qsgopenvgfontglyphcache.h"
+#include "qsgopenvgpainternode.h"
+#include "qsgopenvgspritenode.h"
+
+#include "qopenvgcontext_p.h"
+
+#include <private/qsgrenderer_p.h>
+
+// polish, animations, sync, render and swap in the render loop
+Q_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP, "qt.scenegraph.time.renderloop")
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderContext::QSGOpenVGRenderContext(QSGContext *context)
+ : QSGRenderContext(context)
+ , m_vgContext(nullptr)
+ , m_glyphCacheManager(nullptr)
+{
+
+}
+
+void QSGOpenVGRenderContext::initialize(void *context)
+{
+ m_vgContext = static_cast<QOpenVGContext*>(context);
+ QSGRenderContext::initialize(context);
+}
+
+void QSGOpenVGRenderContext::invalidate()
+{
+ m_vgContext = nullptr;
+ delete m_glyphCacheManager;
+ m_glyphCacheManager = nullptr;
+ QSGRenderContext::invalidate();
+}
+
+void QSGOpenVGRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId)
+{
+ renderer->renderScene(fboId);
+}
+
+QSGTexture *QSGOpenVGRenderContext::createTexture(const QImage &image, uint flags) const
+{
+ QImage tmp = image;
+
+ // Make sure image is not larger than maxTextureSize
+ int maxSize = maxTextureSize();
+ if (tmp.width() > maxSize || tmp.height() > maxSize) {
+ tmp = tmp.scaled(qMin(maxSize, tmp.width()), qMin(maxSize, tmp.height()), Qt::IgnoreAspectRatio, Qt::FastTransformation);
+ }
+
+ return new QSGOpenVGTexture(tmp, flags);
+}
+
+QSGRenderer *QSGOpenVGRenderContext::createRenderer()
+{
+ return new QSGOpenVGRenderer(this);
+}
+
+QSGOpenVGContext::QSGOpenVGContext(QObject *parent)
+{
+ Q_UNUSED(parent)
+}
+
+QSGRenderContext *QSGOpenVGContext::createRenderContext()
+{
+ return new QSGOpenVGRenderContext(this);
+}
+
+QSGRectangleNode *QSGOpenVGContext::createRectangleNode()
+{
+ return new QSGOpenVGRectangleNode;
+}
+
+QSGImageNode *QSGOpenVGContext::createImageNode()
+{
+ return new QSGOpenVGImageNode;
+}
+
+QSGPainterNode *QSGOpenVGContext::createPainterNode(QQuickPaintedItem *item)
+{
+ Q_UNUSED(item)
+ return new QSGOpenVGPainterNode(item);
+}
+
+QSGGlyphNode *QSGOpenVGContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
+{
+ Q_UNUSED(preferNativeGlyphNode)
+ return new QSGOpenVGGlyphNode(rc);
+}
+
+QSGNinePatchNode *QSGOpenVGContext::createNinePatchNode()
+{
+ return new QSGOpenVGNinePatchNode;
+}
+
+QSGLayer *QSGOpenVGContext::createLayer(QSGRenderContext *renderContext)
+{
+ return new QSGOpenVGLayer(renderContext);
+}
+
+QSurfaceFormat QSGOpenVGContext::defaultSurfaceFormat() const
+{
+ QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+ format.setRenderableType(QSurfaceFormat::OpenVG);
+ format.setMajorVersion(1);
+ return format;
+}
+
+QSGInternalRectangleNode *QSGOpenVGContext::createInternalRectangleNode()
+{
+ return new QSGOpenVGInternalRectangleNode();
+}
+
+QSGInternalImageNode *QSGOpenVGContext::createInternalImageNode()
+{
+ return new QSGOpenVGInternalImageNode();
+}
+
+int QSGOpenVGRenderContext::maxTextureSize() const
+{
+ VGint width = vgGeti(VG_MAX_IMAGE_WIDTH);
+ VGint height = vgGeti(VG_MAX_IMAGE_HEIGHT);
+
+ return qMin(width, height);
+}
+
+
+QSGSpriteNode *QSGOpenVGContext::createSpriteNode()
+{
+ return new QSGOpenVGSpriteNode();
+}
+
+QSGRendererInterface *QSGOpenVGContext::rendererInterface(QSGRenderContext *renderContext)
+{
+ return static_cast<QSGOpenVGRenderContext *>(renderContext);
+}
+
+QSGRendererInterface::GraphicsApi QSGOpenVGRenderContext::graphicsApi() const
+{
+ return OpenVG;
+}
+
+QSGRendererInterface::ShaderType QSGOpenVGRenderContext::shaderType() const
+{
+ return UnknownShadingLanguage;
+}
+
+QSGRendererInterface::ShaderCompilationTypes QSGOpenVGRenderContext::shaderCompilationType() const
+{
+ return 0;
+}
+
+QSGRendererInterface::ShaderSourceTypes QSGOpenVGRenderContext::shaderSourceType() const
+{
+ return 0;
+}
+
+QSGOpenVGFontGlyphCache *QSGOpenVGRenderContext::glyphCache(const QRawFont &rawFont)
+{
+ if (!m_glyphCacheManager)
+ m_glyphCacheManager = new QSGOpenVGFontGlyphCacheManager;
+
+ QSGOpenVGFontGlyphCache *cache = m_glyphCacheManager->cache(rawFont);
+ if (!cache) {
+ cache = new QSGOpenVGFontGlyphCache(m_glyphCacheManager, rawFont);
+ m_glyphCacheManager->insertCache(rawFont, cache);
+ }
+
+ return cache;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
new file mode 100644
index 0000000000..fa9939a253
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGCONTEXT_H
+#define QSGOPENVGCONTEXT_H
+
+#include <private/qsgcontext_p.h>
+#include <qsgrendererinterface.h>
+
+Q_DECLARE_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP)
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext;
+class QSGOpenVGFontGlyphCache;
+class QSGOpenVGFontGlyphCacheManager;
+
+class QSGOpenVGRenderContext : public QSGRenderContext, public QSGRendererInterface
+{
+ Q_OBJECT
+public:
+ QSGOpenVGRenderContext(QSGContext *context);
+
+ void initialize(void *context) override;
+ void invalidate() override;
+ void renderNextFrame(QSGRenderer *renderer, uint fboId) override;
+ QSGTexture *createTexture(const QImage &image, uint flags) const override;
+ QSGRenderer *createRenderer() override;
+ int maxTextureSize() const override;
+
+ // QSGRendererInterface interface
+ GraphicsApi graphicsApi() const override;
+ ShaderType shaderType() const override;
+ ShaderCompilationTypes shaderCompilationType() const override;
+ ShaderSourceTypes shaderSourceType() const override;
+
+ QOpenVGContext* vgContext() { return m_vgContext; }
+ QSGOpenVGFontGlyphCache* glyphCache(const QRawFont &rawFont);
+
+private:
+ QOpenVGContext *m_vgContext;
+ QSGOpenVGFontGlyphCacheManager *m_glyphCacheManager;
+
+};
+
+class QSGOpenVGContext : public QSGContext
+{
+ Q_OBJECT
+public:
+ QSGOpenVGContext(QObject *parent = nullptr);
+
+ QSGRenderContext *createRenderContext() override;
+ QSGRectangleNode *createRectangleNode() override;
+ QSGImageNode *createImageNode() override;
+ QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
+ QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
+ QSGNinePatchNode *createNinePatchNode() override;
+ QSGLayer *createLayer(QSGRenderContext *renderContext) override;
+ QSurfaceFormat defaultSurfaceFormat() const override;
+ QSGInternalRectangleNode *createInternalRectangleNode() override;
+ QSGInternalImageNode *createInternalImageNode() override;
+ QSGSpriteNode *createSpriteNode() override;
+ QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
+};
+
+#endif // QSGOPENVGCONTEXT_H
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp
new file mode 100644
index 0000000000..dd630c776f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgfontglyphcache.h"
+#include "qsgopenvghelpers.h"
+#include <private/qfontengine_p.h>
+#include <private/qrawfont_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGFontGlyphCacheManager::QSGOpenVGFontGlyphCacheManager()
+{
+
+}
+
+QSGOpenVGFontGlyphCacheManager::~QSGOpenVGFontGlyphCacheManager()
+{
+ qDeleteAll(m_caches);
+}
+
+QSGOpenVGFontGlyphCache *QSGOpenVGFontGlyphCacheManager::cache(const QRawFont &font)
+{
+ return m_caches.value(font, nullptr);
+}
+
+void QSGOpenVGFontGlyphCacheManager::insertCache(const QRawFont &font, QSGOpenVGFontGlyphCache *cache)
+{
+ m_caches.insert(font, cache);
+}
+
+QSGOpenVGFontGlyphCache::QSGOpenVGFontGlyphCache(QSGOpenVGFontGlyphCacheManager *manager, const QRawFont &font)
+ : m_manager(manager)
+{
+ m_referenceFont = font;
+ QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+ m_glyphCount = fontD->fontEngine->glyphCount();
+ m_font = vgCreateFont(0);
+}
+
+QSGOpenVGFontGlyphCache::~QSGOpenVGFontGlyphCache()
+{
+ if (m_font != VG_INVALID_HANDLE)
+ vgDestroyFont(m_font);
+}
+
+void QSGOpenVGFontGlyphCache::populate(const QVector<quint32> &glyphs)
+{
+ QSet<quint32> referencedGlyphs;
+ QSet<quint32> newGlyphs;
+ int count = glyphs.count();
+ for (int i = 0; i < count; ++i) {
+ quint32 glyphIndex = glyphs.at(i);
+ if ((int) glyphIndex >= glyphCount()) {
+ qWarning("Warning: glyph is not available with index %d", glyphIndex);
+ continue;
+ }
+
+ referencedGlyphs.insert(glyphIndex);
+
+
+ if (!m_cachedGlyphs.contains(glyphIndex)) {
+ newGlyphs.insert(glyphIndex);
+ }
+ }
+
+ referenceGlyphs(referencedGlyphs);
+ if (!newGlyphs.isEmpty())
+ requestGlyphs(newGlyphs);
+}
+
+void QSGOpenVGFontGlyphCache::release(const QVector<quint32> &glyphs)
+{
+ QSet<quint32> unusedGlyphs;
+ int count = glyphs.count();
+ for (int i = 0; i < count; ++i) {
+ quint32 glyphIndex = glyphs.at(i);
+ unusedGlyphs.insert(glyphIndex);
+ }
+ releaseGlyphs(unusedGlyphs);
+}
+
+void QSGOpenVGFontGlyphCache::requestGlyphs(const QSet<quint32> &glyphs)
+{
+ VGfloat origin[2];
+ VGfloat escapement[2];
+ QRectF metrics;
+ QRawFont rawFont = m_referenceFont;
+
+ // Before adding any new glyphs, remove any unused glyphs
+ for (auto glyph : qAsConst(m_unusedGlyphs)) {
+ vgClearGlyph(m_font, glyph);
+ }
+
+ for (auto glyph : glyphs) {
+ m_cachedGlyphs.insert(glyph);
+
+ // Calculate the path for the glyph and cache it.
+ QPainterPath path = rawFont.pathForGlyph(glyph);
+ VGPath vgPath;
+ if (!path.isEmpty()) {
+ vgPath = QSGOpenVGHelpers::qPainterPathToVGPath(path);
+ } else {
+ // Probably a "space" character with no visible outline.
+ vgPath = VG_INVALID_HANDLE;
+ }
+ origin[0] = 0;
+ origin[1] = 0;
+ escapement[0] = 0;
+ escapement[1] = 0;
+ vgSetGlyphToPath(m_font, glyph, vgPath, VG_FALSE, origin, escapement);
+ vgDestroyPath(vgPath); // Reduce reference count.
+ }
+
+}
+
+void QSGOpenVGFontGlyphCache::referenceGlyphs(const QSet<quint32> &glyphs)
+{
+ m_unusedGlyphs -= glyphs;
+}
+
+void QSGOpenVGFontGlyphCache::releaseGlyphs(const QSet<quint32> &glyphs)
+{
+ m_unusedGlyphs += glyphs;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h
new file mode 100644
index 0000000000..a88d28b0fe
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGFONTGLYPHCACHE_H
+#define QSGOPENVGFONTGLYPHCACHE_H
+
+#include <QtGui/QGlyphRun>
+#include <QtCore/QSet>
+#include <QtCore/QLinkedList>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGFontGlyphCache;
+
+class QSGOpenVGFontGlyphCacheManager
+{
+public:
+ QSGOpenVGFontGlyphCacheManager();
+ ~QSGOpenVGFontGlyphCacheManager();
+
+ QSGOpenVGFontGlyphCache *cache(const QRawFont &font);
+ void insertCache(const QRawFont &font, QSGOpenVGFontGlyphCache *cache);
+
+private:
+ QHash<QRawFont, QSGOpenVGFontGlyphCache *> m_caches;
+};
+
+class QSGOpenVGFontGlyphCache
+{
+public:
+ QSGOpenVGFontGlyphCache(QSGOpenVGFontGlyphCacheManager *manager, const QRawFont &font);
+ ~QSGOpenVGFontGlyphCache();
+
+ const QSGOpenVGFontGlyphCacheManager *manager() const { return m_manager; }
+ const QRawFont &referenceFont() const { return m_referenceFont; }
+ int glyphCount() const { return m_glyphCount; }
+
+ void populate(const QVector<quint32> &glyphs);
+ void release(const QVector<quint32> &glyphs);
+
+ VGFont font() { return m_font; }
+
+private:
+ void requestGlyphs(const QSet<quint32> &glyphs);
+ void referenceGlyphs(const QSet<quint32> &glyphs);
+ void releaseGlyphs(const QSet<quint32> &glyphs);
+
+ QSGOpenVGFontGlyphCacheManager *m_manager;
+ QRawFont m_referenceFont;
+ int m_glyphCount;
+
+ VGFont m_font;
+ QSet<quint32> m_cachedGlyphs;
+ QSet<quint32> m_unusedGlyphs;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGFONTGLYPHCACHE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp
new file mode 100644
index 0000000000..8be2a97034
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgglyphnode_p.h"
+#include "qopenvgcontext_p.h"
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvghelpers.h"
+#include "qsgopenvgfontglyphcache.h"
+#include "qopenvgoffscreensurface.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGGlyphNode::QSGOpenVGGlyphNode(QSGRenderContext *rc)
+ : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
+ , m_style(QQuickText::Normal)
+ , m_glyphCache(nullptr)
+{
+ // Set Dummy material to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry(&m_geometry);
+ m_fontColorPaint = vgCreatePaint();
+ m_styleColorPaint = vgCreatePaint();
+
+ // Get handle to Glyph Cache
+ m_renderContext = static_cast<QSGOpenVGRenderContext*>(rc);
+}
+
+QSGOpenVGGlyphNode::~QSGOpenVGGlyphNode()
+{
+ if (m_glyphCache)
+ m_glyphCache->release(m_glyphRun.glyphIndexes());
+
+ vgDestroyPaint(m_fontColorPaint);
+ vgDestroyPaint(m_styleColorPaint);
+}
+
+void QSGOpenVGGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
+{
+ // Obtain glyph cache for font
+ auto oldGlyphCache = m_glyphCache;
+ m_glyphCache = m_renderContext->glyphCache(glyphs.rawFont());
+ if (m_glyphCache != oldGlyphCache) {
+ if (oldGlyphCache)
+ oldGlyphCache->release(m_glyphRun.glyphIndexes());
+ }
+ m_glyphCache->populate(glyphs.glyphIndexes());
+
+ m_position = position;
+ m_glyphRun = glyphs;
+ m_bounding_rect = glyphs.boundingRect().translated(m_position - QPointF(0.0, glyphs.rawFont().ascent()));
+
+ // Recreate ajustments
+ m_xAdjustments.clear();
+ m_yAdjustments.clear();
+
+ for (int i = 1; i < glyphs.positions().count(); ++i) {
+ m_xAdjustments.append(glyphs.positions().at(i).x() - glyphs.positions().at(i-1).x());
+ m_yAdjustments.append(glyphs.positions().at(i).y() - glyphs.positions().at(i-1).y());
+ }
+}
+
+void QSGOpenVGGlyphNode::setColor(const QColor &color)
+{
+ m_color = color;
+ vgSetParameteri(m_fontColorPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_fontColorPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_color, opacity()).constData());
+}
+
+void QSGOpenVGGlyphNode::setStyle(QQuickText::TextStyle style)
+{
+ m_style = style;
+}
+
+void QSGOpenVGGlyphNode::setStyleColor(const QColor &color)
+{
+ m_styleColor = color;
+ vgSetParameteri(m_styleColorPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_styleColorPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_styleColor, opacity()).constData());
+}
+
+QPointF QSGOpenVGGlyphNode::baseLine() const
+{
+ return QPointF();
+}
+
+void QSGOpenVGGlyphNode::setPreferredAntialiasingMode(QSGGlyphNode::AntialiasingMode)
+{
+}
+
+void QSGOpenVGGlyphNode::update()
+{
+}
+
+void QSGOpenVGGlyphNode::render()
+{
+ if (m_glyphRun.positions().count() == 0)
+ return;
+
+ // Rendering Style
+ qreal offset = 1.0;
+
+ QOpenVGOffscreenSurface *offscreenSurface = nullptr;
+
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ if (transform().isAffine()) {
+ vgLoadMatrix(transform().constData());
+ } else {
+ vgLoadIdentity();
+ offscreenSurface = new QOpenVGOffscreenSurface(QSize(ceil(m_bounding_rect.width()), ceil(m_bounding_rect.height())));
+ offscreenSurface->makeCurrent();
+ }
+
+ // Set Quality
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER);
+
+
+ switch (m_style) {
+ case QQuickText::Normal: break;
+ case QQuickText::Outline:
+ // Set the correct fill state
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, offset));
+ drawGlyphsAtOffset(QPointF(0, -offset));
+ drawGlyphsAtOffset(QPointF(offset, 0));
+ drawGlyphsAtOffset(QPointF(-offset, 0));
+ break;
+ case QQuickText::Raised:
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, offset));
+ break;
+ case QQuickText::Sunken:
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, -offset));
+ break;
+ }
+
+ // Set the correct fill state
+ vgSetPaint(m_fontColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0.0, 0.0));
+
+ if (!transform().isAffine()) {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+ offscreenSurface->doneCurrent();
+ vgDrawImage(offscreenSurface->image());
+ delete offscreenSurface;
+ }
+}
+
+void QSGOpenVGGlyphNode::setOpacity(float opacity)
+{
+ if (QSGOpenVGRenderable::opacity() != opacity) {
+ QSGOpenVGRenderable::setOpacity(opacity);
+ // Update Colors
+ setColor(m_color);
+ setStyleColor(m_styleColor);
+ }
+}
+
+void QSGOpenVGGlyphNode::drawGlyphsAtOffset(const QPointF &offset)
+{
+ QPointF firstPosition = m_glyphRun.positions()[0] + (m_position - QPointF(0, m_glyphRun.rawFont().ascent()));
+ VGfloat origin[2];
+ origin[0] = firstPosition.x() + offset.x();
+ origin[1] = firstPosition.y() + offset.y();
+ vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
+
+ vgDrawGlyphs(m_glyphCache->font(),
+ m_glyphRun.glyphIndexes().count(),
+ (VGuint*)m_glyphRun.glyphIndexes().constData(),
+ m_xAdjustments.constData(),
+ m_yAdjustments.constData(),
+ VG_FILL_PATH,
+ VG_TRUE);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h
new file mode 100644
index 0000000000..205e3dcbc8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGGLYPHNODE_H
+#define QSGOPENVGGLYPHNODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtCore/QVector>
+
+#include <VG/openvg.h>
+
+#include "qsgopenvgrenderable.h"
+#include "qsgopenvgfontglyphcache.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGFontGlyphCache;
+class QSGOpenVGRenderContext;
+class QSGRenderContext;
+
+class QSGOpenVGGlyphNode : public QSGGlyphNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGGlyphNode(QSGRenderContext *rc);
+ ~QSGOpenVGGlyphNode();
+
+ void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) override;
+ void setColor(const QColor &color) override;
+ void setStyle(QQuickText::TextStyle style) override;
+ void setStyleColor(const QColor &color) override;
+ QPointF baseLine() const override;
+ void setPreferredAntialiasingMode(AntialiasingMode) override;
+ void update() override;
+
+ void render() override;
+ void setOpacity(float opacity) override;
+
+private:
+ void drawGlyphsAtOffset(const QPointF &offset);
+
+ QPointF m_position;
+ QGlyphRun m_glyphRun;
+ QColor m_color;
+ QSGGeometry m_geometry;
+ QQuickText::TextStyle m_style;
+ QColor m_styleColor;
+
+ QSGOpenVGFontGlyphCache *m_glyphCache;
+ QVector<VGfloat> m_xAdjustments;
+ QVector<VGfloat> m_yAdjustments;
+ VGPaint m_fontColorPaint;
+ VGPaint m_styleColorPaint;
+
+ QSGOpenVGRenderContext *m_renderContext;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGGLYPHNODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp
new file mode 100644
index 0000000000..6bc99d32a1
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** 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 "qsgopenvghelpers.h"
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+namespace QSGOpenVGHelpers {
+
+VGPath qPainterPathToVGPath(const QPainterPath &path)
+{
+ int count = path.elementCount();
+
+ VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F,
+ 1.0f, // scale
+ 0.0f, // bias
+ count + 1, // segmentCapacityHint
+ count * 2, // coordCapacityHint
+ VG_PATH_CAPABILITY_ALL);
+
+ if (count == 0)
+ return vgpath;
+
+ QVector<VGfloat> coords;
+ QVector<VGubyte> segments;
+
+ int curvePos = 0;
+ QPointF temp;
+
+ // Keep track of the start and end of each sub-path. QPainterPath
+ // does not have an "implicit close" flag like QVectorPath does.
+ // We therefore have to detect closed paths by looking for a LineTo
+ // element that connects back to the initial MoveTo element.
+ qreal startx = 0.0;
+ qreal starty = 0.0;
+ qreal endx = 0.0;
+ qreal endy = 0.0;
+ bool haveStart = false;
+ bool haveEnd = false;
+
+ for (int i = 0; i < count; ++i) {
+ const QPainterPath::Element element = path.elementAt(i);
+ switch (element.type) {
+
+ case QPainterPath::MoveToElement:
+ {
+ if (haveStart && haveEnd && startx == endx && starty == endy) {
+ // Implicitly close the previous sub-path.
+ segments.append(VG_CLOSE_PATH);
+ }
+ temp = QPointF(element.x, element.y);
+ startx = temp.x();
+ starty = temp.y();
+ coords.append(startx);
+ coords.append(starty);
+ haveStart = true;
+ haveEnd = false;
+ segments.append(VG_MOVE_TO_ABS);
+ }
+ break;
+
+ case QPainterPath::LineToElement:
+ {
+ temp = QPointF(element.x, element.y);
+ endx = temp.x();
+ endy = temp.y();
+ coords.append(endx);
+ coords.append(endy);
+ haveEnd = true;
+ segments.append(VG_LINE_TO_ABS);
+ }
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ temp = QPointF(element.x, element.y);
+ coords.append(temp.x());
+ coords.append(temp.y());
+ haveEnd = false;
+ curvePos = 2;
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ {
+ temp = QPointF(element.x, element.y);
+ coords.append(temp.x());
+ coords.append(temp.y());
+ haveEnd = false;
+ curvePos += 2;
+ if (curvePos == 6) {
+ curvePos = 0;
+ segments.append(VG_CUBIC_TO_ABS);
+ }
+ }
+ break;
+
+ }
+ }
+
+ if (haveStart && haveEnd && startx == endx && starty == endy) {
+ // Implicitly close the last sub-path.
+ segments.append(VG_CLOSE_PATH);
+ }
+
+ vgAppendPathData(vgpath, segments.count(),
+ segments.constData(), coords.constData());
+
+ return vgpath;
+}
+
+
+void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY) {
+
+ //Check for valid image size and targetRect
+ if (imageSize.width() <= 0 || imageSize.height() <= 0)
+ return;
+ if (targetRect.width() <= 0 || targetRect.height() <= 0)
+ return;
+
+ // This logic is mostly from the Qt Raster PaintEngine's qt_draw_tile
+ qreal drawH;
+ qreal drawW;
+ qreal xPos;
+ qreal xOff;
+ qreal yPos = targetRect.y();
+ qreal yOff;
+
+ if (offset.y() < 0)
+ yOff = imageSize.height() - qRound(-offset.y()) % imageSize.height();
+ else
+ yOff = qRound(offset.y()) % imageSize.height();
+
+
+ // Save the current image transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ QVector<float> originalMatrix(9);
+ vgGetMatrix(originalMatrix.data());
+
+ while (!qFuzzyCompare(yPos, targetRect.y() + targetRect.height()) &&
+ yPos < targetRect.y() + targetRect.height()) {
+ drawH = imageSize.height() - yOff; // Cropping first row
+ if (yPos + drawH * scaleY > targetRect.y() + targetRect.height()) { // Cropping last row
+ // Check that values aren't equal
+ if (!qFuzzyCompare((float)(yPos + drawH * scaleY), (float)(targetRect.y() + targetRect.height())))
+ drawH = targetRect.y() + targetRect.height() - yPos;
+ }
+ xPos = targetRect.x();
+ if (offset.x() < 0)
+ xOff = imageSize.width() - qRound(-offset.x()) % imageSize.width();
+ else
+ xOff = qRound(offset.x()) % imageSize.width();
+
+ while (!qFuzzyCompare(xPos, targetRect.x() + targetRect.width()) &&
+ xPos < targetRect.x() + targetRect.width()) {
+ drawW = imageSize.width() - xOff; // Cropping first column
+ if (xPos + drawW * scaleX > targetRect.x() + targetRect.width()) {
+ // Check that values aren't equal
+ if (!qFuzzyCompare((float)(xPos + drawW * scaleX), (float)(targetRect.x() + targetRect.width())))
+ drawW = targetRect.x() + targetRect.width() - xPos;
+ }
+ if (round(drawW) > 0 && round(drawH) > 0) { // Can't source image less than 1 width or height
+ //Draw here
+ VGImage childRectImage = vgChildImage(image, xOff, yOff, round(drawW), round(drawH));
+ vgTranslate(xPos, yPos);
+ vgScale(scaleX, scaleY);
+ vgDrawImage(childRectImage);
+ vgDestroyImage(childRectImage);
+ vgLoadMatrix(originalMatrix.constData());
+ }
+ if ( drawW > 0)
+ xPos += drawW * scaleX;
+ xOff = 0;
+ }
+ if ( drawH > 0)
+ yPos += drawH * scaleY;
+ yOff = 0;
+
+ }
+}
+
+void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect)
+{
+ // Create normalized margins
+ QMarginsF margins(qMax(innerTargetRect.left() - targetRect.left(), 0.0),
+ qMax(innerTargetRect.top() - targetRect.top(), 0.0),
+ qMax(targetRect.right() - innerTargetRect.right(), 0.0),
+ qMax(targetRect.bottom() - innerTargetRect.bottom(), 0.0));
+
+ QRectF sourceRect(0, 0, textureSize.width(), textureSize.height());
+
+ // Create all the subRects
+ QRectF topLeftSourceRect(sourceRect.topLeft(), QSizeF(margins.left(), margins.top()));
+ QRectF topRightSourceRect(sourceRect.width() - margins.right(), sourceRect.top(), margins.right(), margins.top());
+ QRectF bottomLeftSourceRect(sourceRect.left(), sourceRect.height() - margins.bottom(), margins.left(), margins.bottom());
+ QRectF bottomRightSourceRect(sourceRect.width() - margins.right(), sourceRect.height() - margins.bottom(), margins.right(), margins.bottom());
+
+ QRectF topSourceRect(margins.left(), 0.0, sourceRect.width() - (margins.right() + margins.left()), margins.top());
+ QRectF topTargetRect(margins.left(), 0.0, innerTargetRect.width(), margins.top());
+ QRectF bottomSourceRect(margins.left(), sourceRect.height() - margins.bottom(), sourceRect.width() - (margins.right() + margins.left()), margins.bottom());
+ QRectF bottomTargetRect(margins.left(), targetRect.height() - margins.bottom(), innerTargetRect.width(), margins.bottom());
+ QRectF leftSourceRect(0.0, margins.top(), margins.left(), sourceRect.height() - (margins.bottom() + margins.top()));
+ QRectF leftTargetRect(0.0, margins.top(), margins.left(), innerTargetRect.height());
+ QRectF rightSourceRect(sourceRect.width() - margins.right(), margins.top(), margins.right(), sourceRect.height() - (margins.bottom() + margins.top()));
+ QRectF rightTargetRect(targetRect.width() - margins.right(), margins.top(), margins.right(), innerTargetRect.height());
+
+ QRectF centerSourceRect(margins.left(), margins.top(), sourceRect.width() - (margins.right() + margins.left()), sourceRect.height() - (margins.top() + margins.bottom()));
+
+ // Draw the 9 different sections
+ // (1) Top Left (unscaled)
+ qDrawSubImage(image,
+ topLeftSourceRect,
+ targetRect.topLeft());
+
+ // (3) Top Right (unscaled)
+ qDrawSubImage(image,
+ topRightSourceRect,
+ QPointF(targetRect.width() - margins.right(), 0.0));
+
+ // (7) Bottom Left (unscaled)
+ qDrawSubImage(image,
+ bottomLeftSourceRect,
+ QPointF(targetRect.left(), targetRect.height() - margins.bottom()));
+
+ // (9) Bottom Right (unscaled)
+ qDrawSubImage(image,
+ bottomRightSourceRect,
+ QPointF(targetRect.width() - margins.right(), targetRect.height() - margins.bottom()));
+
+ double scaledWidth = 1.0;
+ double scaledHeight = 1.0;
+
+ // (2) Top (scaled via horizontalTileRule)
+ VGImage topImage = vgChildImage(image, topSourceRect.x(), topSourceRect.y(), topSourceRect.width(), topSourceRect.height());
+ scaledWidth = (topTargetRect.width() / subSourceRect.width()) / topSourceRect.width();
+
+ QSGOpenVGHelpers::qDrawTiled(topImage, topSourceRect.size().toSize(), topTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
+
+ vgDestroyImage(topImage);
+
+ // (8) Bottom (scaled via horizontalTileRule)
+ VGImage bottomImage = vgChildImage(image, bottomSourceRect.x(), bottomSourceRect.y(), bottomSourceRect.width(), bottomSourceRect.height());
+ scaledWidth = (bottomTargetRect.width() / subSourceRect.width()) / bottomSourceRect.width();
+
+ QSGOpenVGHelpers::qDrawTiled(bottomImage, bottomSourceRect.size().toSize(), bottomTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
+
+ vgDestroyImage(bottomImage);
+
+ // (4) Left (scaled via verticalTileRule)
+ VGImage leftImage = vgChildImage(image, leftSourceRect.x(), leftSourceRect.y(), leftSourceRect.width(), leftSourceRect.height());
+ scaledHeight = (leftTargetRect.height() / subSourceRect.height()) / leftSourceRect.height();
+ QSGOpenVGHelpers::qDrawTiled(leftImage, leftSourceRect.size().toSize(), leftTargetRect, QPointF(0.0, 0.0), 1, scaledHeight);
+
+ vgDestroyImage(leftImage);
+
+ // (6) Right (scaled via verticalTileRule)
+ VGImage rightImage = vgChildImage(image, rightSourceRect.x(), rightSourceRect.y(), rightSourceRect.width(), rightSourceRect.height());
+ scaledHeight = (rightTargetRect.height() / subSourceRect.height()) / rightSourceRect.height();
+
+ QSGOpenVGHelpers::qDrawTiled(rightImage, rightSourceRect.size().toSize(), rightTargetRect, QPointF(0, 0), 1, scaledHeight);
+
+ vgDestroyImage(rightImage);
+
+ // (5) Center (saled via verticalTileRule and horizontalTileRule)
+ VGImage centerImage = vgChildImage(image, centerSourceRect.x(), centerSourceRect.y(), centerSourceRect.width(), centerSourceRect.height());
+
+ scaledWidth = (innerTargetRect.width() / subSourceRect.width()) / centerSourceRect.width();
+ scaledHeight = (innerTargetRect.height() / subSourceRect.height()) / centerSourceRect.height();
+
+ QSGOpenVGHelpers::qDrawTiled(centerImage, centerSourceRect.size().toSize(), innerTargetRect, QPointF(0, 0), scaledWidth, scaledHeight);
+
+ vgDestroyImage(centerImage);
+}
+
+void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset)
+{
+ // Check for valid source size
+ if (sourceRect.width() <= 0 || sourceRect.height() <= 0)
+ return;
+
+ // Save the current image transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ QVector<float> originalMatrix(9);
+ vgGetMatrix(originalMatrix.data());
+
+ // Get the child Image
+ VGImage childRectImage = vgChildImage(image, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height());
+ vgTranslate(destOffset.x(), destOffset.y());
+ vgDrawImage(childRectImage);
+ vgDestroyImage(childRectImage);
+
+ // Pop Matrix
+ vgLoadMatrix(originalMatrix.constData());
+}
+
+const QVector<VGfloat> qColorToVGColor(const QColor &color, float opacity)
+{
+ QVector<VGfloat> vgColor(4);
+ vgColor[0] = color.redF();
+ vgColor[1] = color.greenF();
+ vgColor[2] = color.blueF();
+ vgColor[3] = color.alphaF() * opacity;
+ return vgColor;
+}
+
+VGImageFormat qImageFormatToVGImageFormat(QImage::Format format)
+{
+ VGImageFormat vgFormat;
+
+ switch (format) {
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ vgFormat = VG_BW_1;
+ break;
+ case QImage::Format_RGB32:
+ vgFormat = VG_sXRGB_8888;
+ break;
+ case QImage::Format_ARGB32:
+ vgFormat = VG_sARGB_8888;
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ vgFormat = VG_sARGB_8888_PRE;
+ break;
+ case QImage::Format_RGB16:
+ vgFormat = VG_sRGB_565;
+ break;
+ case QImage::Format_RGBX8888:
+ vgFormat = VG_sRGBX_8888;
+ break;
+ case QImage::Format_RGBA8888:
+ vgFormat = VG_sRGBA_8888;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ vgFormat = VG_sRGBA_8888_PRE;
+ break;
+ case QImage::Format_Alpha8:
+ vgFormat = VG_A_8;
+ break;
+ case QImage::Format_Grayscale8:
+ vgFormat = VG_sL_8;
+ break;
+ default:
+ //Invalid
+ vgFormat = (VGImageFormat)-1;
+ break;
+ }
+
+ return vgFormat;
+}
+
+QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format)
+{
+ QImage::Format qImageFormat;
+
+ switch (format) {
+ case VG_BW_1:
+ qImageFormat = QImage::Format_Mono;
+ break;
+ case VG_sXRGB_8888:
+ qImageFormat = QImage::Format_RGB32;
+ break;
+ case VG_sARGB_8888:
+ qImageFormat = QImage::Format_ARGB32;
+ break;
+ case VG_sARGB_8888_PRE:
+ qImageFormat = QImage::Format_ARGB32_Premultiplied;
+ break;
+ case VG_sRGB_565:
+ qImageFormat = QImage::Format_RGB16;
+ break;
+ case VG_sRGBX_8888:
+ qImageFormat = QImage::Format_RGBX8888;
+ break;
+ case VG_sRGBA_8888:
+ qImageFormat = QImage::Format_RGBA8888;
+ break;
+ case VG_sRGBA_8888_PRE:
+ qImageFormat = QImage::Format_RGBA8888_Premultiplied;
+ break;
+ case VG_A_8:
+ qImageFormat = QImage::Format_Alpha8;
+ break;
+ case VG_sL_8:
+ qImageFormat = QImage::Format_Grayscale8;
+ default:
+ qImageFormat = QImage::Format_ARGB32;
+ break;
+ }
+
+ return qImageFormat;
+}
+
+} // end namespace QSGOpenVGHelpers
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvghelpers.h b/src/plugins/scenegraph/openvg/qsgopenvghelpers.h
new file mode 100644
index 0000000000..ee8ff73ca8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvghelpers.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGHELPERS_H
+#define QSGOPENVGHELPERS_H
+
+#include <QtGui/QPainterPath>
+#include <QtGui/QColor>
+#include <QtGui/QImage>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QSGOpenVGHelpers {
+
+VGPath qPainterPathToVGPath(const QPainterPath &path);
+void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY);
+void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect);
+void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset);
+const QVector<VGfloat> qColorToVGColor(const QColor &color, float opacity = 1.0f);
+VGImageFormat qImageFormatToVGImageFormat(QImage::Format format);
+QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format);
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGHELPERS_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp
new file mode 100644
index 0000000000..3dd1f9133c
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** 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 "qsgopenvginternalimagenode.h"
+#include "qsgopenvghelpers.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGInternalImageNode::QSGOpenVGInternalImageNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGInternalImageNode::~QSGOpenVGInternalImageNode()
+{
+ if (m_subSourceRectImage != 0)
+ vgDestroyImage(m_subSourceRectImage);
+}
+
+void QSGOpenVGInternalImageNode::render()
+{
+ if (!m_texture) {
+ return;
+ }
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+ QSize textureSize = m_texture->textureSize();
+
+ if (image == VG_INVALID_HANDLE || !textureSize.isValid())
+ return;
+
+
+ // If Mirrored
+ if (m_mirror) {
+ vgTranslate(m_targetRect.width(), 0.0f);
+ vgScale(-1.0, 1.0);
+ }
+
+ if (m_smooth)
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+ else
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
+
+
+ if (m_innerTargetRect != m_targetRect) {
+ // border image
+ QSGOpenVGHelpers::qDrawBorderImage(image, textureSize, m_targetRect, m_innerTargetRect, m_subSourceRect);
+ } else if (m_tileHorizontal || m_tileVertical) {
+ // Tilled Image
+
+ float sx = m_targetRect.width() / (m_subSourceRect.width() * textureSize.width());
+ float sy = m_targetRect.height() / (m_subSourceRect.height() * textureSize.height());
+ QPointF offset(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height());
+
+ QSGOpenVGHelpers::qDrawTiled(image, textureSize, m_targetRect, offset, sx, sy);
+
+ } else {
+ // Regular BLIT
+
+ QRectF sr(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height(),
+ m_subSourceRect.width() * textureSize.width(), m_subSourceRect.height() * textureSize.height());
+
+ if (m_subSourceRectImageDirty) {
+ if (m_subSourceRectImage != 0)
+ vgDestroyImage(m_subSourceRectImage);
+ m_subSourceRectImage = vgChildImage(image, sr.x(), sr.y(), sr.width(), sr.height());
+ m_subSourceRectImageDirty = false;
+ }
+
+ // If the the source rect is the same as the target rect
+ if (sr == m_targetRect) {
+ vgDrawImage(image);
+ } else {
+ // Scale
+ float scaleX = m_targetRect.width() / sr.width();
+ float scaleY = m_targetRect.height() / sr.height();
+ vgTranslate(m_targetRect.x(), m_targetRect.y());
+ vgScale(scaleX, scaleY);
+ vgDrawImage(m_subSourceRectImage);
+ }
+ }
+}
+
+void QSGOpenVGInternalImageNode::setTargetRect(const QRectF &rect)
+{
+ if (rect == m_targetRect)
+ return;
+ m_targetRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setInnerTargetRect(const QRectF &rect)
+{
+ if (rect == m_innerTargetRect)
+ return;
+ m_innerTargetRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setInnerSourceRect(const QRectF &rect)
+{
+ if (rect == m_innerSourceRect)
+ return;
+ m_innerSourceRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setSubSourceRect(const QRectF &rect)
+{
+ if (rect == m_subSourceRect)
+ return;
+ m_subSourceRect = rect;
+ m_subSourceRectImageDirty = true;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ m_subSourceRectImageDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setMirror(bool mirror)
+{
+ if (m_mirror != mirror) {
+ m_mirror = mirror;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGInternalImageNode::setMipmapFiltering(QSGTexture::Filtering)
+{
+}
+
+void QSGOpenVGInternalImageNode::setFiltering(QSGTexture::Filtering filtering)
+{
+ bool smooth = (filtering == QSGTexture::Linear);
+ if (smooth == m_smooth)
+ return;
+
+ m_smooth = smooth;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
+{
+ bool tileHorizontal = (wrapMode == QSGTexture::Repeat);
+ if (tileHorizontal == m_tileHorizontal)
+ return;
+
+ m_tileHorizontal = tileHorizontal;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
+{
+ bool tileVertical = (wrapMode == QSGTexture::Repeat);
+ if (tileVertical == m_tileVertical)
+ return;
+
+ m_tileVertical = (wrapMode == QSGTexture::Repeat);
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::update()
+{
+}
+
+void QSGOpenVGInternalImageNode::preprocess()
+{
+ bool doDirty = false;
+ QSGLayer *t = qobject_cast<QSGLayer *>(m_texture);
+ if (t) {
+ doDirty = t->updateTexture();
+ markDirty(DirtyGeometry);
+ }
+ if (doDirty)
+ markDirty(DirtyMaterial);
+}
+
+QT_END_NAMESPACE
+
+
+
+
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h
new file mode 100644
index 0000000000..2361aa4892
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGINTERNALIMAGENODE_H
+#define QSGOPENVGINTERNALIMAGENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGInternalImageNode : public QSGInternalImageNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGInternalImageNode();
+ ~QSGOpenVGInternalImageNode();
+
+ void render() override;
+
+ void setTargetRect(const QRectF &rect) override;
+ void setInnerTargetRect(const QRectF &rect) override;
+ void setInnerSourceRect(const QRectF &rect) override;
+ void setSubSourceRect(const QRectF &rect) override;
+ void setTexture(QSGTexture *texture) override;
+ void setMirror(bool mirror) override;
+ 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 update() override;
+
+ void preprocess() override;
+
+private:
+
+ QRectF m_targetRect;
+ QRectF m_innerTargetRect;
+ QRectF m_innerSourceRect = QRectF(0, 0, 1, 1);
+ QRectF m_subSourceRect = QRectF(0, 0, 1, 1);
+
+ bool m_mirror = false;
+ bool m_smooth = true;
+ bool m_tileHorizontal = false;
+ bool m_tileVertical = false;
+
+ QSGTexture *m_texture = nullptr;
+
+ VGImage m_subSourceRectImage = 0;
+ bool m_subSourceRectImageDirty = true;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGINTERNALIMAGENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
new file mode 100644
index 0000000000..be437303bc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
@@ -0,0 +1,732 @@
+/****************************************************************************
+**
+** 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 "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvghelpers.h"
+
+#include <VG/vgu.h>
+
+QSGOpenVGInternalRectangleNode::QSGOpenVGInternalRectangleNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+ createVGResources();
+}
+
+QSGOpenVGInternalRectangleNode::~QSGOpenVGInternalRectangleNode()
+{
+ destroyVGResources();
+}
+
+
+void QSGOpenVGInternalRectangleNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ m_pathDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setColor(const QColor &color)
+{
+ m_fillColor = color;
+ m_fillDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setPenColor(const QColor &color)
+{
+ m_strokeColor = color;
+ m_strokeDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setPenWidth(qreal width)
+{
+ m_penWidth = width;
+ m_strokeDirty = true;
+ m_pathDirty = true;
+}
+
+//Move first stop by pos relative to seconds
+static QGradientStop interpolateStop(const QGradientStop &firstStop, const QGradientStop &secondStop, double newPos)
+{
+ double distance = secondStop.first - firstStop.first;
+ double distanceDelta = newPos - firstStop.first;
+ double modifierValue = distanceDelta / distance;
+ int redDelta = (secondStop.second.red() - firstStop.second.red()) * modifierValue;
+ int greenDelta = (secondStop.second.green() - firstStop.second.green()) * modifierValue;
+ int blueDelta = (secondStop.second.blue() - firstStop.second.blue()) * modifierValue;
+ int alphaDelta = (secondStop.second.alpha() - firstStop.second.alpha()) * modifierValue;
+
+ QGradientStop newStop;
+ newStop.first = newPos;
+ newStop.second = QColor(firstStop.second.red() + redDelta,
+ firstStop.second.green() + greenDelta,
+ firstStop.second.blue() + blueDelta,
+ firstStop.second.alpha() + alphaDelta);
+
+ return newStop;
+}
+
+void QSGOpenVGInternalRectangleNode::setGradientStops(const QGradientStops &stops)
+{
+
+ //normalize stops
+ bool needsNormalization = false;
+ for (const QGradientStop &stop : qAsConst(stops)) {
+ if (stop.first < 0.0 || stop.first > 1.0) {
+ needsNormalization = true;
+ continue;
+ }
+ }
+
+ if (needsNormalization) {
+ QGradientStops normalizedStops;
+ if (stops.count() == 1) {
+ //If there is only one stop, then the position does not matter
+ //It is just treated as a color
+ QGradientStop stop = stops.at(0);
+ stop.first = 0.0;
+ normalizedStops.append(stop);
+ } else {
+ //Clip stops to only the first below 0.0 and above 1.0
+ int below = -1;
+ int above = -1;
+ QVector<int> between;
+ for (int i = 0; i < stops.count(); ++i) {
+ if (stops.at(i).first < 0.0) {
+ below = i;
+ } else if (stops.at(i).first > 1.0) {
+ above = i;
+ break;
+ } else {
+ between.append(i);
+ }
+ }
+
+ //Interpoloate new color values for above and below
+ if (below != -1 ) {
+ //If there are more than one stops left, interpolate
+ if (below + 1 < stops.count()) {
+ normalizedStops.append(interpolateStop(stops.at(below), stops.at(below + 1), 0.0));
+ } else {
+ QGradientStop singleStop;
+ singleStop.first = 0.0;
+ singleStop.second = stops.at(below).second;
+ normalizedStops.append(singleStop);
+ }
+ }
+
+ for (int i = 0; i < between.count(); ++i)
+ normalizedStops.append(stops.at(between.at(i)));
+
+ if (above != -1) {
+ //If there stops before above, interpolate
+ if (above >= 1) {
+ normalizedStops.append(interpolateStop(stops.at(above), stops.at(above - 1), 1.0));
+ } else {
+ QGradientStop singleStop;
+ singleStop.first = 1.0;
+ singleStop.second = stops.at(above).second;
+ normalizedStops.append(singleStop);
+ }
+ }
+ }
+
+ m_gradientStops = normalizedStops;
+
+ } else {
+ m_gradientStops = stops;
+ }
+
+ m_fillDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setRadius(qreal radius)
+{
+ m_radius = radius;
+ m_pathDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setAligned(bool aligned)
+{
+ m_aligned = aligned;
+}
+
+void QSGOpenVGInternalRectangleNode::update()
+{
+}
+
+void QSGOpenVGInternalRectangleNode::render()
+{
+ // Set Transform
+ if (transform().isAffine()) {
+ // Use current transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+ if (m_offscreenSurface) {
+ delete m_offscreenSurface;
+ m_offscreenSurface = nullptr;
+ }
+ } else {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ if (m_radius > 0) {
+ // Fallback to rendering to an image for rounded rects with perspective transforms
+ if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != QSize(ceil(m_rect.width()), ceil(m_rect.height()))) {
+ delete m_offscreenSurface;
+ m_offscreenSurface = new QOpenVGOffscreenSurface(QSize(ceil(m_rect.width()), ceil(m_rect.height())));
+ }
+
+ m_offscreenSurface->makeCurrent();
+ } else if (m_offscreenSurface) {
+ delete m_offscreenSurface;
+ m_offscreenSurface = nullptr;
+ }
+ }
+
+
+ // If path is dirty
+ if (m_pathDirty) {
+ vgClearPath(m_rectanglePath, VG_PATH_CAPABILITY_APPEND_TO);
+ vgClearPath(m_borderPath, VG_PATH_CAPABILITY_APPEND_TO);
+
+ if (m_penWidth == 0) {
+ generateRectanglePath(m_rect, m_radius, m_rectanglePath);
+ } else {
+ generateRectangleAndBorderPaths(m_rect, m_penWidth, m_radius, m_rectanglePath, m_borderPath);
+ }
+
+ m_pathDirty = false;
+ }
+
+ //If fill is drity
+ if (m_fillDirty) {
+ if (m_gradientStops.isEmpty()) {
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_fillColor, opacity()).constData());
+ } else {
+ // Linear Gradient
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
+ const VGfloat verticalLinearGradient[] = {
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ static_cast<VGfloat>(m_rect.height())
+ };
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_LINEAR_GRADIENT, 4, verticalLinearGradient);
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, false);
+
+ QVector<VGfloat> stops;
+ for (const QGradientStop &stop : qAsConst(m_gradientStops)) {
+ // offset
+ stops.append(stop.first);
+ // color
+ stops.append(QSGOpenVGHelpers::qColorToVGColor(stop.second, opacity()));
+ }
+
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_COLOR_RAMP_STOPS, stops.length(), stops.constData());
+ }
+
+ m_fillDirty = false;
+ }
+
+ //If stroke is dirty
+ if (m_strokeDirty) {
+ vgSetParameteri(m_borderPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_borderPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_strokeColor, opacity()).constData());
+
+ m_strokeDirty = false;
+ }
+
+ //Draw
+ if (m_penWidth > 0) {
+ vgSetPaint(m_borderPaint, VG_FILL_PATH);
+ vgDrawPath(m_borderPath, VG_FILL_PATH);
+ vgSetPaint(m_rectanglePaint, VG_FILL_PATH);
+ vgDrawPath(m_rectanglePath, VG_FILL_PATH);
+ } else {
+ vgSetPaint(m_rectanglePaint, VG_FILL_PATH);
+ vgDrawPath(m_rectanglePath, VG_FILL_PATH);
+ }
+
+ if (!transform().isAffine() && m_radius > 0) {
+ m_offscreenSurface->doneCurrent();
+ // Render offscreen surface
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+ vgDrawImage(m_offscreenSurface->image());
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::setOpacity(float opacity)
+{
+ if (opacity != QSGOpenVGRenderable::opacity()) {
+ QSGOpenVGRenderable::setOpacity(opacity);
+ m_strokeDirty = true;
+ m_fillDirty = true;
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::setTransform(const QOpenVGMatrix &transform)
+{
+ // if there transform matrix is not affine, regenerate the path
+ if (transform.isAffine())
+ m_pathDirty = true;
+
+ QSGOpenVGRenderable::setTransform(transform);
+}
+
+void QSGOpenVGInternalRectangleNode::createVGResources()
+{
+ m_rectanglePaint = vgCreatePaint();
+ m_borderPaint = vgCreatePaint();
+ m_rectanglePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ m_borderPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+}
+
+void QSGOpenVGInternalRectangleNode::destroyVGResources()
+{
+ if (m_offscreenSurface)
+ delete m_offscreenSurface;
+
+ vgDestroyPaint(m_rectanglePaint);
+ vgDestroyPaint(m_borderPaint);
+ vgDestroyPath(m_rectanglePath);
+ vgDestroyPath(m_borderPath);
+}
+
+void QSGOpenVGInternalRectangleNode::generateRectanglePath(const QRectF &rect, float radius, VGPath path) const
+{
+ if (radius == 0) {
+ // Generate a rectangle
+ if (transform().isAffine()) {
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(5);
+ coordinates[0] = rect.x();
+ coordinates[1] = rect.y();
+ coordinates[2] = rect.width();
+ coordinates[3] = rect.height();
+ coordinates[4] = -rect.width();
+ vgAppendPathData(path, 5, rectCommands, coordinates.constData());
+ } else {
+ // Pre-transform path
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_CLOSE_PATH
+ };
+
+ QVector<VGfloat> coordinates(8);
+ const QPointF topLeft = transform().map(rect.topLeft());
+ const QPointF topRight = transform().map(rect.topRight());
+ const QPointF bottomLeft = transform().map(rect.bottomLeft());
+ const QPointF bottomRight = transform().map(rect.bottomRight());
+ coordinates[0] = bottomLeft.x();
+ coordinates[1] = bottomLeft.y();
+ coordinates[2] = bottomRight.x();
+ coordinates[3] = bottomRight.y();
+ coordinates[4] = topRight.x();
+ coordinates[5] = topRight.y();
+ coordinates[6] = topLeft.x();
+ coordinates[7] = topLeft.y();
+
+ vgAppendPathData(path, 5, rectCommands, coordinates.constData());
+ }
+ } else {
+ // Generate a rounded rectangle
+ //Radius should never exceeds half of the width or half of the height
+ float adjustedRadius = qMin((float)qMin(rect.width(), rect.height()) * 0.5f, radius);
+
+ // OpenVG expectes radius to be 2x what we expect
+ adjustedRadius *= 2;
+
+ // Create command list
+ static const VGubyte roundedRectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(26);
+
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ vgAppendPathData(path, 10, roundedRectCommands, coordinates.constData());
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::generateBorderPath(const QRectF &rect, float borderWidth, float borderHeight, float radius, VGPath path) const
+{
+ if (radius == 0) {
+ // squared frame
+ if (transform().isAffine()) {
+ // Create command list
+ static const VGubyte squaredBorderCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_MOVE_TO_ABS,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(10);
+ // Outside Square
+ coordinates[0] = rect.x();
+ coordinates[1] = rect.y();
+ coordinates[2] = rect.width();
+ coordinates[3] = rect.height();
+ coordinates[4] = -rect.width();
+ // Inside Square (opposite direction)
+ coordinates[5] = rect.x() + borderWidth;
+ coordinates[6] = rect.y() + borderHeight;
+ coordinates[7] = rect.height() - (borderHeight * 2);
+ coordinates[8] = rect.width() - (borderWidth * 2);
+ coordinates[9] = -(rect.height() - (borderHeight * 2));
+
+ vgAppendPathData(path, 9, squaredBorderCommands, coordinates.constData());
+ } else {
+ // persepective transform
+ static const VGubyte squaredBorderCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_CLOSE_PATH
+ };
+
+ QVector<VGfloat> coordinates(16);
+ QRectF insideRect = rect.marginsRemoved(QMarginsF(borderWidth, borderHeight, borderWidth, borderHeight));
+ QPointF outsideBottomLeft = transform().map(rect.bottomLeft());
+ QPointF outsideBottomRight = transform().map(rect.bottomRight());
+ QPointF outsideTopRight = transform().map(rect.topRight());
+ QPointF outsideTopLeft = transform().map(rect.topLeft());
+ QPointF insideBottomLeft = transform().map(insideRect.bottomLeft());
+ QPointF insideTopLeft = transform().map(insideRect.topLeft());
+ QPointF insideTopRight = transform().map(insideRect.topRight());
+ QPointF insideBottomRight = transform().map(insideRect.bottomRight());
+
+ // Outside
+ coordinates[0] = outsideBottomLeft.x();
+ coordinates[1] = outsideBottomLeft.y();
+ coordinates[2] = outsideBottomRight.x();
+ coordinates[3] = outsideBottomRight.y();
+ coordinates[4] = outsideTopRight.x();
+ coordinates[5] = outsideTopRight.y();
+ coordinates[6] = outsideTopLeft.x();
+ coordinates[7] = outsideTopLeft.y();
+ // Inside
+ coordinates[8] = insideBottomLeft.x();
+ coordinates[9] = insideBottomLeft.y();
+ coordinates[10] = insideTopLeft.x();
+ coordinates[11] = insideTopLeft.y();
+ coordinates[12] = insideTopRight.x();
+ coordinates[13] = insideTopRight.y();
+ coordinates[14] = insideBottomRight.x();
+ coordinates[15] = insideBottomRight.y();
+
+ vgAppendPathData(path, 9, squaredBorderCommands, coordinates.constData());
+ }
+ } else if (radius < qMax(borderWidth, borderHeight)){
+ // rounded outside, squared inside
+ // Create command list
+ static const VGubyte roundedRectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_MOVE_TO_ABS,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Ajust for OpenVG's usage or radius
+ float adjustedRadius = radius * 2;
+
+ // Create command data
+ QVector<VGfloat> coordinates(31);
+ // Outside Rounded Rect
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ // Inside Square (opposite direction)
+ coordinates[26] = rect.x() + borderWidth;
+ coordinates[27] = rect.y() + borderHeight;
+ coordinates[28] = rect.height() - (borderHeight * 2);
+ coordinates[29] = rect.width() - (borderWidth * 2);
+ coordinates[30] = -(rect.height() - (borderHeight * 2));
+
+ vgAppendPathData(path, 14, roundedRectCommands, coordinates.constData());
+ } else {
+ // rounded outside, rounded inside
+
+ static const VGubyte roundedBorderCommands[] = {
+ // Outer
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ // Inner
+ VG_MOVE_TO_ABS,
+ VG_SCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Adjust for OpenVG's usage or radius
+ float adjustedRadius = radius * 2;
+ float adjustedInnerRadius = (radius - qMax(borderWidth, borderHeight)) * 2;
+
+ // Create command data
+ QVector<VGfloat> coordinates(52);
+
+ // Outer
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ // Inner
+ coordinates[26] = rect.width() - (adjustedInnerRadius / 2 + borderWidth);
+ coordinates[27] = rect.height() - borderHeight;
+
+ coordinates[28] = adjustedInnerRadius / 2;
+ coordinates[29] = adjustedInnerRadius / 2;
+ coordinates[30] = 0;
+ coordinates[31] = adjustedInnerRadius / 2;
+ coordinates[32] = -adjustedInnerRadius / 2;
+
+ coordinates[33] = -((rect.height() - borderHeight * 2) - adjustedInnerRadius);
+
+ coordinates[34] = adjustedInnerRadius / 2;
+ coordinates[35] = adjustedInnerRadius / 2;
+ coordinates[36] = 0;
+ coordinates[37] = -adjustedInnerRadius / 2;
+ coordinates[38] = -adjustedInnerRadius / 2;
+
+ coordinates[39] = -((rect.width() - borderWidth * 2) - adjustedInnerRadius);
+
+ coordinates[40] = adjustedInnerRadius / 2;
+ coordinates[41] = adjustedInnerRadius / 2;
+ coordinates[42] = 0;
+ coordinates[43] = -adjustedInnerRadius / 2;
+ coordinates[44] = adjustedInnerRadius / 2;
+
+ coordinates[45] = (rect.height() - borderHeight * 2) - adjustedInnerRadius;
+
+ coordinates[46] = adjustedInnerRadius / 2;
+ coordinates[47] = adjustedInnerRadius / 2;
+ coordinates[48] = 0;
+ coordinates[49] = adjustedInnerRadius / 2;
+ coordinates[50] = adjustedInnerRadius / 2;
+
+ coordinates[51] = (rect.width() - borderWidth * 2) - adjustedInnerRadius;
+
+ vgAppendPathData(path, 19, roundedBorderCommands, coordinates.constData());
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::generateRectangleAndBorderPaths(const QRectF &rect, float penWidth, float radius, VGPath inside, VGPath outside) const
+{
+ //Borders can not be more than half the height/width of a rect
+ float borderWidth = qMin(penWidth, (float)rect.width() * 0.5f);
+ float borderHeight = qMin(penWidth, (float)rect.height() * 0.5f);
+
+ //Radius should never exceeds half of the width or half of the height
+ float adjustedRadius = qMin((float)qMin(rect.width(), rect.height()) * 0.5f, radius);
+
+ QRectF innerRect = rect;
+ innerRect.adjust(borderWidth, borderHeight, -borderWidth, -borderHeight);
+
+ if (radius == 0) {
+ // Regular rect with border
+ generateRectanglePath(innerRect, 0, inside);
+ generateBorderPath(rect, borderWidth, borderHeight, 0, outside);
+ } else {
+ // Rounded Rect with border
+ float innerRadius = radius - qMax(borderWidth, borderHeight);
+ if (innerRadius < 0)
+ innerRadius = 0.0f;
+
+ generateRectanglePath(innerRect, innerRadius, inside);
+ generateBorderPath(rect, borderWidth, borderHeight, adjustedRadius, outside);
+ }
+}
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h
new file mode 100644
index 0000000000..e8d25c94f8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGINTERNALRECTANGLENODE_H
+#define QSGOPENVGINTERNALRECTANGLENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+#include "qopenvgoffscreensurface.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGInternalRectangleNode : public QSGInternalRectangleNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGInternalRectangleNode();
+ ~QSGOpenVGInternalRectangleNode();
+
+ void setRect(const QRectF &rect) override;
+ void setColor(const QColor &color) override;
+ void setPenColor(const QColor &color) override;
+ void setPenWidth(qreal width) override;
+ void setGradientStops(const QGradientStops &stops) override;
+ void setRadius(qreal radius) override;
+ void setAligned(bool aligned) override;
+ void update() override;
+
+ void render() override;
+ void setOpacity(float opacity) override;
+ void setTransform(const QOpenVGMatrix &transform) override;
+
+private:
+ void createVGResources();
+ void destroyVGResources();
+
+ void generateRectanglePath(const QRectF &rect, float radius, VGPath path) const;
+ void generateRectangleAndBorderPaths(const QRectF &rect, float penWidth, float radius, VGPath inside, VGPath outside) const;
+ void generateBorderPath(const QRectF &rect, float borderWidth, float borderHeight, float radius, VGPath path) const;
+
+ bool m_pathDirty = true;
+ bool m_fillDirty = true;
+ bool m_strokeDirty = true;
+
+ QRectF m_rect;
+ QColor m_fillColor;
+ QColor m_strokeColor;
+ qreal m_penWidth = 0.0;
+ qreal m_radius = 0.0;
+ bool m_aligned = false;
+ QGradientStops m_gradientStops;
+
+ VGPath m_rectanglePath;
+ VGPath m_borderPath;
+ VGPaint m_rectanglePaint;
+ VGPaint m_borderPaint;
+
+ QOpenVGOffscreenSurface *m_offscreenSurface = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGINTERNALRECTANGLENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp b/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp
new file mode 100644
index 0000000000..047539d431
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** 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 "qsgopenvglayer.h"
+#include "qsgopenvgrenderer_p.h"
+#include "qsgopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGLayer::QSGOpenVGLayer(QSGRenderContext *renderContext)
+ : m_item(nullptr)
+ , m_renderer(nullptr)
+ , m_device_pixel_ratio(1)
+ , m_mirrorHorizontal(false)
+ , m_mirrorVertical(false)
+ , m_live(true)
+ , m_grab(true)
+ , m_recursive(false)
+ , m_dirtyTexture(true)
+ , m_offscreenSurface(nullptr)
+ , m_secondaryOffscreenSurface(nullptr)
+{
+ m_context = static_cast<QSGOpenVGRenderContext*>(renderContext);
+}
+
+QSGOpenVGLayer::~QSGOpenVGLayer()
+{
+ invalidated();
+}
+
+int QSGOpenVGLayer::textureId() const
+{
+ if (m_offscreenSurface)
+ return static_cast<int>(m_offscreenSurface->image());
+ else
+ return 0;
+}
+
+QSize QSGOpenVGLayer::textureSize() const
+{
+ if (m_offscreenSurface) {
+ return m_offscreenSurface->size();
+ }
+
+ return QSize();
+}
+
+bool QSGOpenVGLayer::hasAlphaChannel() const
+{
+ return true;
+}
+
+bool QSGOpenVGLayer::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGOpenVGLayer::bind()
+{
+}
+
+bool QSGOpenVGLayer::updateTexture()
+{
+ bool doGrab = (m_live || m_grab) && m_dirtyTexture;
+ if (doGrab)
+ grab();
+ if (m_grab)
+ emit scheduledUpdateCompleted();
+ m_grab = false;
+ return doGrab;
+}
+
+void QSGOpenVGLayer::setItem(QSGNode *item)
+{
+ if (item == m_item)
+ return;
+ m_item = item;
+
+ if (m_live && !m_item) {
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ m_offscreenSurface = nullptr;
+ m_secondaryOffscreenSurface = nullptr;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setRect(const QRectF &rect)
+{
+ if (rect == m_rect)
+ return;
+ m_rect = rect;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+ m_size = size;
+
+ if (m_live && m_size.isNull()) {
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ m_offscreenSurface = nullptr;
+ m_secondaryOffscreenSurface = nullptr;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::scheduleUpdate()
+{
+ if (m_grab)
+ return;
+ m_grab = true;
+ if (m_dirtyTexture) {
+ emit updateRequested();
+ }
+}
+
+QImage QSGOpenVGLayer::toImage() const
+{
+ return m_offscreenSurface->readbackQImage();
+}
+
+void QSGOpenVGLayer::setLive(bool live)
+{
+ if (live == m_live)
+ return;
+ m_live = live;
+
+ if (m_live && (!m_item || m_size.isNull())) {
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ m_offscreenSurface = nullptr;
+ m_secondaryOffscreenSurface = nullptr;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setRecursive(bool recursive)
+{
+ m_recursive = recursive;
+}
+
+void QSGOpenVGLayer::setFormat(uint format)
+{
+ Q_UNUSED(format)
+}
+
+void QSGOpenVGLayer::setHasMipmaps(bool mipmap)
+{
+ Q_UNUSED(mipmap)
+}
+
+void QSGOpenVGLayer::setDevicePixelRatio(qreal ratio)
+{
+ m_device_pixel_ratio = ratio;
+}
+
+void QSGOpenVGLayer::setMirrorHorizontal(bool mirror)
+{
+ if (m_mirrorHorizontal == mirror)
+ return;
+ m_mirrorHorizontal = mirror;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setMirrorVertical(bool mirror)
+{
+ if (m_mirrorVertical == mirror)
+ return;
+ m_mirrorVertical = mirror;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::markDirtyTexture()
+{
+ m_dirtyTexture = true;
+ if (m_live || m_grab) {
+ emit updateRequested();
+ }
+}
+
+void QSGOpenVGLayer::invalidated()
+{
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ delete m_renderer;
+ m_renderer = nullptr;
+ m_offscreenSurface = nullptr;
+ m_secondaryOffscreenSurface = nullptr;
+}
+
+void QSGOpenVGLayer::grab()
+{
+ if (!m_item || m_size.isNull()) {
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ m_offscreenSurface = nullptr;
+ m_secondaryOffscreenSurface = nullptr;
+ 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 = new QSGOpenVGRenderer(m_context);
+ connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()));
+ }
+ m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
+ m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
+
+ bool deleteOffscreenSurfaceLater = false;
+ if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != m_size ) {
+ if (m_recursive) {
+ deleteOffscreenSurfaceLater = true;
+ delete m_secondaryOffscreenSurface;
+ m_secondaryOffscreenSurface = new QOpenVGOffscreenSurface(m_size);
+ } else {
+ delete m_offscreenSurface;
+ delete m_secondaryOffscreenSurface;
+ m_offscreenSurface = new QOpenVGOffscreenSurface(m_size);
+ m_secondaryOffscreenSurface = nullptr;
+ }
+ }
+
+ if (m_recursive && !m_secondaryOffscreenSurface)
+ m_secondaryOffscreenSurface = new QOpenVGOffscreenSurface(m_size);
+
+ // Render texture.
+ root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
+ m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
+
+ m_dirtyTexture = false;
+
+ m_renderer->setDeviceRect(m_size);
+ m_renderer->setViewportRect(m_size);
+ QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio,
+ m_mirrorVertical ? m_rect.top() * m_device_pixel_ratio : m_rect.bottom() * m_device_pixel_ratio,
+ m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio,
+ m_mirrorVertical ? m_rect.height() * m_device_pixel_ratio : -m_rect.height() * m_device_pixel_ratio);
+ m_renderer->setProjectionMatrixToRect(mirrored);
+ m_renderer->setClearColor(Qt::transparent);
+
+
+ if (m_recursive)
+ m_secondaryOffscreenSurface->makeCurrent();
+ else
+ m_offscreenSurface->makeCurrent();
+
+ m_renderer->renderScene();
+
+ // Make the previous surface and context active again
+ if (m_recursive) {
+ if (deleteOffscreenSurfaceLater) {
+ delete m_offscreenSurface;
+ m_offscreenSurface = new QOpenVGOffscreenSurface(m_size);
+ }
+ m_secondaryOffscreenSurface->doneCurrent();
+ qSwap(m_offscreenSurface, m_secondaryOffscreenSurface);
+ } else {
+ m_offscreenSurface->doneCurrent();
+ }
+
+ root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
+
+ if (m_recursive)
+ markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvglayer.h b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
new file mode 100644
index 0000000000..2af0bfb40f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGLAYER_H
+#define QSGOPENVGLAYER_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qsgcontext_p.h>
+
+#include "qopenvgcontext_p.h"
+#include "qopenvgoffscreensurface.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderer;
+class QSGOpenVGRenderContext;
+
+class QSGOpenVGLayer : public QSGLayer
+{
+public:
+ QSGOpenVGLayer(QSGRenderContext *renderContext);
+ ~QSGOpenVGLayer();
+
+ // QSGTexture interface
+public:
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ void bind() override;
+
+ // QSGDynamicTexture interface
+public:
+ bool updateTexture() override;
+
+ // QSGLayer interface
+public:
+ 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;
+
+public slots:
+ void markDirtyTexture() override;
+ void invalidated() override;
+
+private:
+ void grab();
+
+ QSGNode *m_item;
+ QSGOpenVGRenderContext *m_context;
+ QSGOpenVGRenderer *m_renderer;
+ QRectF m_rect;
+ QSize m_size;
+ qreal m_device_pixel_ratio;
+ bool m_mirrorHorizontal;
+ bool m_mirrorVertical;
+ bool m_live;
+ bool m_grab;
+ bool m_recursive;
+ bool m_dirtyTexture;
+
+ QOpenVGOffscreenSurface *m_offscreenSurface;
+ QOpenVGOffscreenSurface *m_secondaryOffscreenSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGLAYER_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
new file mode 100644
index 0000000000..8aa179f705
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgnodevisitor.h"
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
+#include "qsgopenvgpublicnodes.h"
+#include "qsgopenvgglyphnode_p.h"
+#include "qsgopenvgpainternode.h"
+#include "qsgopenvgspritenode.h"
+#include "qsgopenvgrenderable.h"
+
+#include "qopenvgcontext_p.h"
+
+#include <QtQuick/qsgsimplerectnode.h>
+#include <QtQuick/qsgsimpletexturenode.h>
+#include <QtQuick/qsgrendernode.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGNodeVisitor::QSGOpenVGNodeVisitor()
+{
+ //Store the current matrix state
+ QVector<VGfloat> matrix(9);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgGetMatrix(matrix.data());
+
+ m_transformStack.push(QOpenVGMatrix(matrix.constData()));
+
+ // Opacity
+ m_opacityState.push(1.0f);
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGTransformNode *node)
+{
+ const QVector<float> matrixData = { node->matrix().constData()[0], node->matrix().constData()[1], node->matrix().constData()[3],
+ node->matrix().constData()[4], node->matrix().constData()[5], node->matrix().constData()[7],
+ node->matrix().constData()[12], node->matrix().constData()[13], node->matrix().constData()[15] };
+ const QOpenVGMatrix matrix2d(matrixData.constData());
+
+ m_transformStack.push(m_transformStack.top() * matrix2d);
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGTransformNode *)
+{
+ m_transformStack.pop();
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGClipNode *node)
+{
+ VGMaskOperation maskOperation = VG_INTERSECT_MASK;
+ if (m_clipStack.count() == 0) {
+ vgSeti(VG_MASKING, VG_TRUE);
+ vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
+ }
+
+ // Render clip node geometry to mask
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ VGPath clipPath = generateClipPath(node->clipRect());
+ vgRenderToMask(clipPath, VG_FILL_PATH, maskOperation);
+
+ m_clipStack.push(clipPath);
+
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGClipNode *)
+{
+ // Remove clip node geometry from mask
+ auto clipState = m_clipStack.pop();
+ vgDestroyPath(clipState);
+
+ if (m_clipStack.count() == 0) {
+ vgSeti(VG_MASKING, VG_FALSE);
+ } else {
+ // Recreate the mask
+ vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ for (auto path : qAsConst(m_clipStack)) {
+ vgRenderToMask(path, VG_FILL_PATH, VG_INTERSECT_MASK);
+ }
+ }
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGGeometryNode *node)
+{
+ if (QSGSimpleRectNode *rectNode = dynamic_cast<QSGSimpleRectNode *>(node)) {
+ // TODO: Try and render the QSGSimpleRectNode
+ Q_UNUSED(rectNode)
+ return false;
+ } else if (QSGSimpleTextureNode *tn = dynamic_cast<QSGSimpleTextureNode *>(node)) {
+ // TODO: Try and render the QSGSimpleTextureNode
+ Q_UNUSED(tn)
+ return false;
+ } else if (QSGOpenVGNinePatchNode *nn = dynamic_cast<QSGOpenVGNinePatchNode *>(node)) {
+ renderRenderableNode(nn);
+ } else if (QSGOpenVGRectangleNode *rn = dynamic_cast<QSGOpenVGRectangleNode *>(node)) {
+ renderRenderableNode(rn);
+ } else if (QSGOpenVGImageNode *n = dynamic_cast<QSGOpenVGImageNode *>(node)) {
+ renderRenderableNode(n);
+ } else {
+ // We dont know, so skip
+ return false;
+ }
+
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGGeometryNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGOpacityNode *node)
+{
+ m_opacityState.push(m_opacityState.top() * node->opacity());
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGOpacityNode *)
+{
+ m_opacityState.pop();
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGInternalImageNode *node)
+{
+ renderRenderableNode(static_cast<QSGOpenVGInternalImageNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGInternalImageNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGPainterNode *node)
+{
+ renderRenderableNode(static_cast<QSGOpenVGPainterNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGPainterNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGInternalRectangleNode *node)
+{
+ renderRenderableNode(static_cast<QSGOpenVGInternalRectangleNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGInternalRectangleNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGGlyphNode *node)
+{
+ renderRenderableNode(static_cast<QSGOpenVGGlyphNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGGlyphNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGRootNode *)
+{
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGRootNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node)
+{
+ renderRenderableNode(static_cast<QSGOpenVGSpriteNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGSpriteNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGRenderNode *)
+{
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGRenderNode *)
+{
+}
+
+VGPath QSGOpenVGNodeVisitor::generateClipPath(const QRectF &rect) const
+{
+ VGPath clipPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_CLOSE_PATH
+ };
+
+ const QOpenVGMatrix &transform = m_transformStack.top();
+
+ // Create command data
+ QVector<VGfloat> coordinates(8);
+ const QPointF topLeft = transform.map(rect.topLeft());
+ const QPointF topRight = transform.map(rect.topRight());
+ const QPointF bottomLeft = transform.map(rect.bottomLeft());
+ const QPointF bottomRight = transform.map(rect.bottomRight());
+ coordinates[0] = bottomLeft.x();
+ coordinates[1] = bottomLeft.y();
+ coordinates[2] = bottomRight.x();
+ coordinates[3] = bottomRight.y();
+ coordinates[4] = topRight.x();
+ coordinates[5] = topRight.y();
+ coordinates[6] = topLeft.x();
+ coordinates[7] = topLeft.y();
+
+ vgAppendPathData(clipPath, 5, rectCommands, coordinates.constData());
+ return clipPath;
+}
+
+void QSGOpenVGNodeVisitor::renderRenderableNode(QSGOpenVGRenderable *node)
+{
+ if (!node)
+ return;
+ node->setTransform(m_transformStack.top());
+ node->setOpacity(m_opacityState.top());
+ node->render();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
new file mode 100644
index 0000000000..4805d63024
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGNODEVISITOR_H
+#define QSGOPENVGNODEVISITOR_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtCore/QStack>
+
+#include "qopenvgmatrix.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderable;
+class QSGOpenVGNodeVisitor : public QSGNodeVisitorEx
+{
+public:
+ QSGOpenVGNodeVisitor();
+
+ bool visit(QSGTransformNode *) override;
+ void endVisit(QSGTransformNode *) override;
+ bool visit(QSGClipNode *) override;
+ void endVisit(QSGClipNode *) override;
+ bool visit(QSGGeometryNode *) override;
+ void endVisit(QSGGeometryNode *) override;
+ bool visit(QSGOpacityNode *) override;
+ void endVisit(QSGOpacityNode *) override;
+ bool visit(QSGInternalImageNode *) override;
+ void endVisit(QSGInternalImageNode *) override;
+ bool visit(QSGPainterNode *) override;
+ void endVisit(QSGPainterNode *) override;
+ bool visit(QSGInternalRectangleNode *) override;
+ void endVisit(QSGInternalRectangleNode *) override;
+ bool visit(QSGGlyphNode *) override;
+ void endVisit(QSGGlyphNode *) override;
+ bool visit(QSGRootNode *) override;
+ void endVisit(QSGRootNode *) override;
+ bool visit(QSGSpriteNode *) override;
+ void endVisit(QSGSpriteNode *) override;
+ bool visit(QSGRenderNode *) override;
+ void endVisit(QSGRenderNode *) override;
+
+private:
+ VGPath generateClipPath(const QRectF &rect) const;
+ void renderRenderableNode(QSGOpenVGRenderable *node);
+
+ QStack<QOpenVGMatrix> m_transformStack;
+ QStack<float> m_opacityState;
+ QStack<VGPath> m_clipStack;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGNODEVISITOR_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp
new file mode 100644
index 0000000000..fb68ebf2bc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgpainternode.h"
+#include "qsgopenvgtexture.h"
+#include <qmath.h>
+
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGPainterNode::QSGOpenVGPainterNode(QQuickPaintedItem *item)
+ : m_preferredRenderTarget(QQuickPaintedItem::Image)
+ , m_item(item)
+ , m_texture(nullptr)
+ , m_dirtyContents(false)
+ , m_opaquePainting(false)
+ , m_linear_filtering(false)
+ , m_smoothPainting(false)
+ , m_fillColor(Qt::transparent)
+ , m_contentsScale(1.0)
+ , m_dirtyGeometry(false)
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGPainterNode::~QSGOpenVGPainterNode()
+{
+ delete m_texture;
+}
+
+void QSGOpenVGPainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget)
+{
+}
+
+void QSGOpenVGPainterNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+
+ m_size = size;
+
+ m_dirtyGeometry = true;
+}
+
+void QSGOpenVGPainterNode::setDirty(const QRect &dirtyRect)
+{
+ m_dirtyContents = true;
+ m_dirtyRect = dirtyRect;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setOpaquePainting(bool opaque)
+{
+ if (opaque == m_opaquePainting)
+ return;
+
+ m_opaquePainting = opaque;
+}
+
+void QSGOpenVGPainterNode::setLinearFiltering(bool linearFiltering)
+{
+ if (linearFiltering == m_linear_filtering)
+ return;
+
+ m_linear_filtering = linearFiltering;
+}
+
+void QSGOpenVGPainterNode::setMipmapping(bool)
+{
+
+}
+
+void QSGOpenVGPainterNode::setSmoothPainting(bool s)
+{
+ if (s == m_smoothPainting)
+ return;
+
+ m_smoothPainting = s;
+}
+
+void QSGOpenVGPainterNode::setFillColor(const QColor &c)
+{
+ if (c == m_fillColor)
+ return;
+
+ m_fillColor = c;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setContentsScale(qreal s)
+{
+ if (s == m_contentsScale)
+ return;
+
+ m_contentsScale = s;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setFastFBOResizing(bool)
+{
+}
+
+void QSGOpenVGPainterNode::setTextureSize(const QSize &size)
+{
+ if (size == m_textureSize)
+ return;
+
+ m_textureSize = size;
+ m_dirtyGeometry = true;
+}
+
+QImage QSGOpenVGPainterNode::toImage() const
+{
+ return m_image;
+}
+
+void QSGOpenVGPainterNode::update()
+{
+ if (m_dirtyGeometry) {
+ if (!m_opaquePainting)
+ m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
+ else
+ m_image = QImage(m_size, QImage::Format_RGB32);
+ }
+
+ if (m_dirtyContents)
+ paint();
+
+ m_dirtyGeometry = false;
+ m_dirtyContents = false;
+}
+
+QSGTexture *QSGOpenVGPainterNode::texture() const
+{
+ return m_texture;
+}
+
+void QSGOpenVGPainterNode::render()
+{
+ if (!m_texture)
+ return;
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ if (m_linear_filtering)
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+ else
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
+
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
+ vgDrawImage(static_cast<VGImage>(m_texture->textureId()));
+}
+
+void QSGOpenVGPainterNode::paint()
+{
+ QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect;
+
+ QPainter painter;
+
+ painter.begin(&m_image);
+ if (m_smoothPainting) {
+ painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+ }
+
+ QRect clipRect;
+
+ if (m_contentsScale == 1) {
+ qreal scaleX = m_textureSize.width() / (qreal) m_size.width();
+ qreal scaleY = m_textureSize.height() / (qreal) m_size.height();
+ painter.scale(scaleX, scaleY);
+ clipRect = dirtyRect;
+ } 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;
+ }
+
+ 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_dirtyRect = QRect();
+
+ if (m_texture)
+ delete m_texture;
+
+ uint textureFlags = m_opaquePainting ? 0 : QSGRenderContext::CreateTexture_Alpha;
+ m_texture = new QSGOpenVGTexture(m_image, textureFlags);
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h
new file mode 100644
index 0000000000..1fe992115f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGPAINTERNODE_H
+#define QSGOPENVGPAINTERNODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/QQuickPaintedItem>
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGTexture;
+
+class QSGOpenVGPainterNode : public QSGPainterNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGPainterNode(QQuickPaintedItem *item);
+ ~QSGOpenVGPainterNode();
+
+ void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) override;
+ void setSize(const QSize &size) override;
+ void setDirty(const QRect &dirtyRect) 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;
+
+ void render() override;
+ void paint();
+
+private:
+ QQuickPaintedItem::RenderTarget m_preferredRenderTarget;
+
+ QQuickPaintedItem *m_item;
+ QSGOpenVGTexture *m_texture;
+ QImage m_image;
+
+ QSize m_size;
+ bool m_dirtyContents;
+ QRect m_dirtyRect;
+ bool m_opaquePainting;
+ bool m_linear_filtering;
+ bool m_smoothPainting;
+ QColor m_fillColor;
+ qreal m_contentsScale;
+ QSize m_textureSize;
+
+ bool m_dirtyGeometry;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGPAINTERNODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
new file mode 100644
index 0000000000..1afc5ea7ca
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgpublicnodes.h"
+#include "qsgopenvghelpers.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRectangleNode::QSGOpenVGRectangleNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+ m_rectPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ m_rectPaint = vgCreatePaint();
+}
+
+QSGOpenVGRectangleNode::~QSGOpenVGRectangleNode()
+{
+ vgDestroyPaint(m_rectPaint);
+ vgDestroyPath(m_rectPath);
+}
+
+void QSGOpenVGRectangleNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ m_pathDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGRectangleNode::setColor(const QColor &color)
+{
+ m_color = color;
+ m_paintDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGRectangleNode::setTransform(const QOpenVGMatrix &transform)
+{
+ // if there transform matrix is not affine, regenerate the path
+ if (transform.isAffine())
+ m_pathDirty = true;
+ markDirty(DirtyGeometry);
+
+ QSGOpenVGRenderable::setTransform(transform);
+}
+
+void QSGOpenVGRectangleNode::render()
+{
+ // Set Transform
+ if (transform().isAffine()) {
+ // Use current transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+ } else {
+ // map the path's to handle the perspective matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ }
+
+ if (m_pathDirty) {
+ vgClearPath(m_rectPath, VG_PATH_CAPABILITY_APPEND_TO);
+
+ if (transform().isAffine()) {
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(5);
+ coordinates[0] = m_rect.x();
+ coordinates[1] = m_rect.y();
+ coordinates[2] = m_rect.width();
+ coordinates[3] = m_rect.height();
+ coordinates[4] = -m_rect.width();
+
+ vgAppendPathData(m_rectPath, 5, rectCommands, coordinates.constData());
+
+ } else {
+ // Pre-transform path
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_CLOSE_PATH
+ };
+
+ QVector<VGfloat> coordinates(8);
+ const QPointF topLeft = transform().map(m_rect.topLeft());
+ const QPointF topRight = transform().map(m_rect.topRight());
+ const QPointF bottomLeft = transform().map(m_rect.bottomLeft());
+ const QPointF bottomRight = transform().map(m_rect.bottomRight());
+ coordinates[0] = bottomLeft.x();
+ coordinates[1] = bottomLeft.y();
+ coordinates[2] = bottomRight.x();
+ coordinates[3] = bottomRight.y();
+ coordinates[4] = topRight.x();
+ coordinates[5] = topRight.y();
+ coordinates[6] = topLeft.x();
+ coordinates[7] = topLeft.y();
+
+ vgAppendPathData(m_rectPath, 5, rectCommands, coordinates.constData());
+ }
+
+ m_pathDirty = false;
+ }
+
+ if (m_paintDirty) {
+ vgSetPaint(m_rectPaint, VG_FILL_PATH);
+ vgSetParameteri(m_rectPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_rectPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_color).constData());
+
+ m_paintDirty = false;
+ }
+
+ vgSetPaint(m_rectPaint, VG_FILL_PATH);
+ vgDrawPath(m_rectPath, VG_FILL_PATH);
+
+}
+
+QSGOpenVGImageNode::QSGOpenVGImageNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+}
+
+QSGOpenVGImageNode::~QSGOpenVGImageNode()
+{
+ if (m_owns) {
+ m_texture->deleteLater();
+ }
+}
+
+void QSGOpenVGImageNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoordinatesTransformMode transformNode)
+{
+ if (m_transformMode == transformNode)
+ return;
+ m_transformMode = transformNode;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGImageNode::render()
+{
+ if (!m_texture) {
+ return;
+ }
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ //Apply the TextureCoordinateTransform Flag
+ if (m_transformMode != QSGImageNode::NoTransform) {
+ float translateX = 0.0f;
+ float translateY = 0.0f;
+ float scaleX = 1.0f;
+ float scaleY = 1.0f;
+
+ if (m_transformMode & QSGImageNode::MirrorHorizontally) {
+ translateX = m_rect.width();
+ scaleX = -1.0;
+ }
+
+ if (m_transformMode & QSGImageNode::MirrorVertically) {
+ translateY = m_rect.height();
+ scaleY = -1.0;
+ }
+
+ vgTranslate(translateX, translateY);
+ vgScale(scaleX, scaleY);
+ }
+
+ // If the the source rect is the same as the target rect
+ if (m_sourceRect == m_rect) {
+ vgDrawImage(image);
+ } else {
+ // Scale
+ float scaleX = m_rect.width() / m_sourceRect.width();
+ float scaleY = m_rect.height() / m_sourceRect.height();
+ vgScale(scaleX, scaleY);
+ VGImage subImage = vgChildImage(image, m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.width(), m_sourceRect.height());
+ vgDrawImage(subImage);
+ vgDestroyImage(subImage);
+ }
+
+}
+
+QSGOpenVGNinePatchNode::QSGOpenVGNinePatchNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+}
+
+void QSGOpenVGNinePatchNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGNinePatchNode::setBounds(const QRectF &bounds)
+{
+ if (m_bounds == bounds)
+ return;
+ m_bounds = bounds;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::setDevicePixelRatio(qreal ratio)
+{
+ if (m_pixelRatio == ratio)
+ return;
+ m_pixelRatio = ratio;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom)
+{
+ QMarginsF margins(left, top, right, bottom);
+ if (m_margins == margins)
+ return;
+ m_margins = margins;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::update()
+{
+
+}
+
+void QSGOpenVGNinePatchNode::render()
+{
+ if (!m_texture)
+ return;
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ //Draw borderImage
+ QSGOpenVGHelpers::qDrawBorderImage(image, m_texture->textureSize(), m_bounds, m_bounds.marginsRemoved(m_margins), QRectF(0, 0, 1, 1));
+}
+
+QRectF QSGOpenVGNinePatchNode::bounds() const
+{
+ return m_bounds;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
new file mode 100644
index 0000000000..34c8e50615
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
@@ -0,0 +1,145 @@
+#ifndef QSGOPENVGPUBLICNODES_H
+#define QSGOPENVGPUBLICNODES_H
+
+/****************************************************************************
+**
+** 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 <QtQuick/qsgrectanglenode.h>
+#include <QtQuick/qsgimagenode.h>
+#include <QtQuick/qsgninepatchnode.h>
+
+#include <QtGui/QPixmap>
+
+#include <VG/openvg.h>
+
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRectangleNode : public QSGRectangleNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGRectangleNode();
+ ~QSGOpenVGRectangleNode();
+
+ void setRect(const QRectF &rect) override;
+ QRectF rect() const override { return m_rect; }
+
+ void setColor(const QColor &color) override;
+ QColor color() const override { return m_color; }
+
+ void setTransform(const QOpenVGMatrix &transform) override;
+
+ void render() override;
+
+private:
+ QRectF m_rect;
+ QColor m_color;
+
+
+ bool m_pathDirty = true;
+ bool m_paintDirty = true;
+
+ VGPath m_rectPath;
+ VGPaint m_rectPaint;
+};
+
+class QSGOpenVGImageNode : public QSGImageNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGImageNode();
+ ~QSGOpenVGImageNode();
+
+ void setRect(const QRectF &rect) override { m_rect = rect; markDirty(DirtyMaterial); }
+ QRectF rect() const override { return m_rect; }
+
+ void setSourceRect(const QRectF &r) override { m_sourceRect = r; }
+ QRectF sourceRect() const override { return m_sourceRect; }
+
+ void setTexture(QSGTexture *texture) override;
+ QSGTexture *texture() const override { return m_texture; }
+
+ void setFiltering(QSGTexture::Filtering filtering) override { m_filtering = filtering; markDirty(DirtyMaterial); }
+ QSGTexture::Filtering filtering() const override { return m_filtering; }
+
+ void setMipmapFiltering(QSGTexture::Filtering) override { }
+ QSGTexture::Filtering mipmapFiltering() const override { return QSGTexture::None; }
+
+ void setTextureCoordinatesTransform(TextureCoordinatesTransformMode transformNode) override;
+ TextureCoordinatesTransformMode textureCoordinatesTransform() const override { return m_transformMode; }
+
+ void setOwnsTexture(bool owns) override { m_owns = owns; }
+ bool ownsTexture() const override { return m_owns; }
+
+ void render() override;
+
+private:
+ QSGTexture *m_texture;
+ QRectF m_rect;
+ QRectF m_sourceRect;
+ bool m_owns;
+ QSGTexture::Filtering m_filtering;
+ TextureCoordinatesTransformMode m_transformMode;
+};
+
+class QSGOpenVGNinePatchNode : public QSGNinePatchNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGNinePatchNode();
+
+ 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;
+
+ void render() override;
+
+ QRectF bounds() const;
+
+private:
+ QSGTexture *m_texture;
+ QRectF m_bounds;
+ qreal m_pixelRatio;
+ QMarginsF m_margins;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGPUBLICNODES_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp
new file mode 100644
index 0000000000..97d0be99c8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderable::QSGOpenVGRenderable()
+ : m_opacity(1.0f)
+{
+ m_opacityPaint = vgCreatePaint();
+}
+
+QSGOpenVGRenderable::~QSGOpenVGRenderable()
+{
+ vgDestroyPaint(m_opacityPaint);
+}
+
+void QSGOpenVGRenderable::setOpacity(float opacity)
+{
+ if (m_opacity == opacity)
+ return;
+
+ m_opacity = opacity;
+ VGfloat values[] = {
+ 1.0f, 1.0f, 1.0f, m_opacity
+ };
+ vgSetParameterfv(m_opacityPaint, VG_PAINT_COLOR, 4, values);
+}
+
+float QSGOpenVGRenderable::opacity() const
+{
+ return m_opacity;
+}
+
+VGPaint QSGOpenVGRenderable::opacityPaint() const
+{
+ return m_opacityPaint;
+}
+
+void QSGOpenVGRenderable::setTransform(const QOpenVGMatrix &transform)
+{
+ m_transform = transform;
+}
+
+const QOpenVGMatrix &QSGOpenVGRenderable::transform() const
+{
+ return m_transform;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h
new file mode 100644
index 0000000000..a544ae743e
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERABLE_H
+#define QSGOPENVGRENDERABLE_H
+
+#include <QtGlobal>
+
+#include <VG/openvg.h>
+
+#include "qopenvgmatrix.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGRenderable();
+ virtual ~QSGOpenVGRenderable();
+
+ virtual void render() = 0;
+
+ virtual void setOpacity(float opacity);
+ float opacity() const;
+ VGPaint opacityPaint() const;
+
+ virtual void setTransform(const QOpenVGMatrix &transform);
+ const QOpenVGMatrix &transform() const;
+
+private:
+ float m_opacity;
+ VGPaint m_opacityPaint;
+ QOpenVGMatrix m_transform;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERABLE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp
new file mode 100644
index 0000000000..acd4cf88dc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderer_p.h"
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvgnodevisitor.h"
+#include "qopenvgcontext_p.h"
+#include "qsgopenvghelpers.h"
+
+#include <QtGui/QWindow>
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderer::QSGOpenVGRenderer(QSGRenderContext *context)
+ : QSGRenderer(context)
+{
+
+}
+
+QSGOpenVGRenderer::~QSGOpenVGRenderer()
+{
+
+}
+
+void QSGOpenVGRenderer::renderScene(uint fboId)
+{
+ Q_UNUSED(fboId)
+ class B : public QSGBindable
+ {
+ public:
+ void bind() const { }
+ } bindable;
+ QSGRenderer::renderScene(bindable);
+}
+
+void QSGOpenVGRenderer::render()
+{
+ //Clear the window geometry with the clear color
+ vgSetfv(VG_CLEAR_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(clearColor()).constData());
+ vgClear(0, 0, VG_MAXINT, VG_MAXINT);
+
+ // Visit each node to render scene
+ QSGOpenVGNodeVisitor rendererVisitor;
+ rendererVisitor.visitChildren(rootNode());
+}
+
+void QSGOpenVGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
+{
+ QSGRenderer::nodeChanged(node, state);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h
new file mode 100644
index 0000000000..24cabd1b89
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERER_H
+#define QSGOPENVGRENDERER_H
+
+#include <private/qsgrenderer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderer : public QSGRenderer
+{
+public:
+ QSGOpenVGRenderer(QSGRenderContext *context);
+ virtual ~QSGOpenVGRenderer();
+
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
+
+ void renderScene(uint fboId = 0) final;
+ void render() final;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERER_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
new file mode 100644
index 0000000000..f7aa704095
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderloop_p.h"
+#include "qsgopenvgcontext_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QElapsedTimer>
+
+#include <private/qquickwindow_p.h>
+#include <private/qquickprofiler_p.h>
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderLoop::QSGOpenVGRenderLoop()
+ : vg(nullptr)
+{
+ sg = QSGContext::createDefaultContext();
+ rc = sg->createRenderContext();
+}
+
+QSGOpenVGRenderLoop::~QSGOpenVGRenderLoop()
+{
+ delete rc;
+ delete sg;
+}
+
+void QSGOpenVGRenderLoop::show(QQuickWindow *window)
+{
+ WindowData data;
+ data.updatePending = false;
+ data.grabOnly = false;
+ m_windows[window] = data;
+
+ maybeUpdate(window);
+}
+
+void QSGOpenVGRenderLoop::hide(QQuickWindow *window)
+{
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ cd->fireAboutToStop();
+}
+
+void QSGOpenVGRenderLoop::windowDestroyed(QQuickWindow *window)
+{
+ m_windows.remove(window);
+ hide(window);
+
+ QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
+ d->cleanupNodesOnShutdown();
+
+ if (m_windows.size() == 0) {
+ rc->invalidate();
+ delete vg;
+ vg = nullptr;
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ } else if (vg && window == vg->window()) {
+ vg->doneCurrent();
+ }
+}
+
+void QSGOpenVGRenderLoop::exposureChanged(QQuickWindow *window)
+{
+ if (window->isExposed()) {
+ m_windows[window].updatePending = true;
+ renderWindow(window);
+ }
+}
+
+QImage QSGOpenVGRenderLoop::grab(QQuickWindow *window)
+{
+ if (!m_windows.contains(window))
+ return QImage();
+
+ m_windows[window].grabOnly = true;
+
+ renderWindow(window);
+
+ QImage grabbed = grabContent;
+ grabContent = QImage();
+ return grabbed;
+}
+
+void QSGOpenVGRenderLoop::update(QQuickWindow *window)
+{
+ maybeUpdate(window);
+}
+
+void QSGOpenVGRenderLoop::handleUpdateRequest(QQuickWindow *window)
+{
+ renderWindow(window);
+}
+
+void QSGOpenVGRenderLoop::maybeUpdate(QQuickWindow *window)
+{
+ if (!m_windows.contains(window))
+ return;
+
+ m_windows[window].updatePending = true;
+ window->requestUpdate();
+}
+
+QAnimationDriver *QSGOpenVGRenderLoop::animationDriver() const
+{
+ return nullptr;
+}
+
+QSGContext *QSGOpenVGRenderLoop::sceneGraphContext() const
+{
+ return sg;
+}
+
+QSGRenderContext *QSGOpenVGRenderLoop::createRenderContext(QSGContext *) const
+{
+ return rc;
+}
+
+void QSGOpenVGRenderLoop::releaseResources(QQuickWindow *window)
+{
+ Q_UNUSED(window)
+}
+
+QSurface::SurfaceType QSGOpenVGRenderLoop::windowSurfaceType() const
+{
+ return QSurface::OpenVGSurface;
+}
+
+void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
+{
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ if (!cd->isRenderable() || !m_windows.contains(window))
+ return;
+
+ WindowData &data = const_cast<WindowData &>(m_windows[window]);
+
+ if (vg == nullptr) {
+ vg = new QOpenVGContext(window);
+ vg->makeCurrent();
+ cd->context->initialize(vg);
+ } else {
+ vg->makeCurrent();
+ }
+
+ bool alsoSwap = data.updatePending;
+ data.updatePending = false;
+
+ if (!data.grabOnly) {
+ // Event delivery/processing triggered the window to be deleted or stop rendering.
+ if (!m_windows.contains(window))
+ return;
+ }
+ QElapsedTimer renderTimer;
+ qint64 renderTime = 0, syncTime = 0, polishTime = 0;
+ bool profileFrames = QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled();
+ if (profileFrames)
+ renderTimer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+
+ cd->polishItems();
+
+ if (profileFrames)
+ polishTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
+ QQuickProfiler::SceneGraphRenderLoopFrame,
+ QQuickProfiler::SceneGraphPolishPolish);
+
+ emit window->afterAnimating();
+
+ cd->syncSceneGraph();
+
+ if (profileFrames)
+ syncTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
+ QQuickProfiler::SceneGraphRenderLoopSync);
+
+ // setup coordinate system for window
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgTranslate(0.0f, window->size().height());
+ vgScale(1.0, -1.0);
+
+ cd->renderSceneGraph(window->size());
+
+ if (profileFrames)
+ renderTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
+ QQuickProfiler::SceneGraphRenderLoopRender);
+
+ if (data.grabOnly) {
+ grabContent = vg->readFramebuffer(window->size() * window->effectiveDevicePixelRatio());
+ data.grabOnly = false;
+ }
+
+ if (alsoSwap && window->isVisible()) {
+ vg->swapBuffers();
+ cd->fireFrameSwapped();
+ }
+
+ qint64 swapTime = 0;
+ if (profileFrames)
+ swapTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
+ QQuickProfiler::SceneGraphRenderLoopSwap);
+
+ if (QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
+ static QTime lastFrameTime = QTime::currentTime();
+ qCDebug(QSG_OPENVG_LOG_TIME_RENDERLOOP,
+ "Frame rendered with 'basic' 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();
+ }
+
+ // Might have been set during syncSceneGraph()
+ if (data.updatePending)
+ maybeUpdate(window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h
new file mode 100644
index 0000000000..f35b689e00
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERLOOP_H
+#define QSGOPENVGRENDERLOOP_H
+
+#include <private/qsgrenderloop_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext;
+
+class QSGOpenVGRenderLoop : public QSGRenderLoop
+{
+public:
+ QSGOpenVGRenderLoop();
+ ~QSGOpenVGRenderLoop();
+
+
+ void show(QQuickWindow *window) override;
+ void hide(QQuickWindow *window) override;
+
+ void windowDestroyed(QQuickWindow *window) override;
+
+ void renderWindow(QQuickWindow *window);
+ void exposureChanged(QQuickWindow *window) override;
+ QImage grab(QQuickWindow *window) override;
+
+ void maybeUpdate(QQuickWindow *window) override;
+ void update(QQuickWindow *window) override;
+ void handleUpdateRequest(QQuickWindow *window) override;
+
+ void releaseResources(QQuickWindow *) override;
+
+ QSurface::SurfaceType windowSurfaceType() const override;
+
+ QAnimationDriver *animationDriver() const override;
+
+ QSGContext *sceneGraphContext() const override;
+ QSGRenderContext *createRenderContext(QSGContext *) const override;
+
+ struct WindowData {
+ bool updatePending : 1;
+ bool grabOnly : 1;
+ };
+
+ QHash<QQuickWindow *, WindowData> m_windows;
+
+ QSGContext *sg;
+ QSGRenderContext *rc;
+ QOpenVGContext *vg;
+
+ QImage grabContent;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERLOOP_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp
new file mode 100644
index 0000000000..fb24df7471
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgspritenode.h"
+#include "qsgopenvgtexture.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGSpriteNode::QSGOpenVGSpriteNode()
+ : m_time(0.0f)
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGSpriteNode::~QSGOpenVGSpriteNode()
+{
+
+}
+
+void QSGOpenVGSpriteNode::setTexture(QSGTexture *texture)
+{
+ m_texture = static_cast<QSGOpenVGTexture*>(texture);
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGSpriteNode::setTime(float time)
+{
+ if (m_time != time) {
+ m_time = time;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSourceA(const QPoint &source)
+{
+ if (m_sourceA != source) {
+ m_sourceA = source;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSourceB(const QPoint &source)
+{
+ if (m_sourceB != source) {
+ m_sourceB = source;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSpriteSize(const QSize &size)
+{
+ if (m_spriteSize != size) {
+ m_spriteSize = size;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSheetSize(const QSize &size)
+{
+ if (m_sheetSize != size) {
+ m_sheetSize = size;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSize(const QSizeF &size)
+{
+ if (m_size != size) {
+ m_size = size;
+ markDirty(DirtyGeometry);
+ }
+}
+
+void QSGOpenVGSpriteNode::setFiltering(QSGTexture::Filtering)
+{
+}
+
+void QSGOpenVGSpriteNode::update()
+{
+}
+
+void QSGOpenVGSpriteNode::render()
+{
+ if (!m_texture)
+ return;
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ QRectF sourceRect(m_sourceA, m_spriteSize);
+ QRectF targetRect(0, 0, m_size.width(), m_size.height());
+
+ VGImage sourceImage = vgChildImage(image, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height());
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ // Set Image Matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
+ if (sourceRect != targetRect) {
+ // Scale
+ float scaleX = targetRect.width() / sourceRect.width();
+ float scaleY = targetRect.height() / sourceRect.height();
+ vgScale(scaleX, scaleY);
+ }
+
+ vgDrawImage(sourceImage);
+
+ vgDestroyImage(sourceImage);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
new file mode 100644
index 0000000000..3ade2ef8ad
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGSPRITENODE_H
+#define QSGOPENVGSPRITENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+class QSGOpenVGTexture;
+class QSGOpenVGSpriteNode : public QSGSpriteNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGSpriteNode();
+ ~QSGOpenVGSpriteNode();
+
+ 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;
+
+ void render() override;
+
+private:
+ QSGOpenVGTexture *m_texture;
+ float m_time;
+ QPoint m_sourceA;
+ QPoint m_sourceB;
+ QSize m_spriteSize;
+ QSize m_sheetSize;
+ QSizeF m_size;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGSPRITENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp b/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp
new file mode 100644
index 0000000000..dd2fdc7020
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgtexture.h"
+#include "qsgopenvghelpers.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGTexture::QSGOpenVGTexture(const QImage &image, uint flags)
+{
+ Q_UNUSED(flags)
+
+ VGImageFormat format = QSGOpenVGHelpers::qImageFormatToVGImageFormat(image.format());
+ m_image = vgCreateImage(format, image.width(), image.height(), VG_IMAGE_QUALITY_BETTER);
+
+ // Do Texture Upload
+ vgImageSubData(m_image, image.constBits(), image.bytesPerLine(), format, 0, 0, image.width(), image.height());
+}
+
+QSGOpenVGTexture::~QSGOpenVGTexture()
+{
+ vgDestroyImage(m_image);
+}
+
+int QSGOpenVGTexture::textureId() const
+{
+ return static_cast<int>(m_image);
+}
+
+QSize QSGOpenVGTexture::textureSize() const
+{
+ VGint imageWidth = vgGetParameteri(m_image, VG_IMAGE_WIDTH);
+ VGint imageHeight = vgGetParameteri(m_image, VG_IMAGE_HEIGHT);
+ return QSize(imageWidth, imageHeight);
+}
+
+bool QSGOpenVGTexture::hasAlphaChannel() const
+{
+ VGImageFormat format = static_cast<VGImageFormat>(vgGetParameteri(m_image, VG_IMAGE_FORMAT));
+
+ switch (format) {
+ case VG_sRGBA_8888:
+ case VG_sRGBA_8888_PRE:
+ case VG_sRGBA_5551:
+ case VG_sRGBA_4444:
+ case VG_lRGBA_8888:
+ case VG_lRGBA_8888_PRE:
+ case VG_A_8:
+ case VG_A_1:
+ case VG_A_4:
+ case VG_sARGB_8888:
+ case VG_sARGB_8888_PRE:
+ case VG_sARGB_1555:
+ case VG_sARGB_4444:
+ case VG_lARGB_8888:
+ case VG_lARGB_8888_PRE:
+ case VG_sBGRA_8888:
+ case VG_sBGRA_8888_PRE:
+ case VG_sBGRA_5551:
+ case VG_sBGRA_4444:
+ case VG_lBGRA_8888:
+ case VG_lBGRA_8888_PRE:
+ case VG_sABGR_8888:
+ case VG_sABGR_8888_PRE:
+ case VG_sABGR_1555:
+ case VG_sABGR_4444:
+ case VG_lABGR_8888:
+ case VG_lABGR_8888_PRE:
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool QSGOpenVGTexture::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGOpenVGTexture::bind()
+{
+ // No need to bind
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgtexture.h b/src/plugins/scenegraph/openvg/qsgopenvgtexture.h
new file mode 100644
index 0000000000..523c9e690d
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgtexture.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGTEXTURE_H
+#define QSGOPENVGTEXTURE_H
+
+#include <private/qsgtexture_p.h>
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGTexture : public QSGTexture
+{
+public:
+ QSGOpenVGTexture(const QImage &image, uint flags);
+ ~QSGOpenVGTexture();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ void bind() override;
+
+private:
+ VGImage m_image;;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGTEXTURE_H
diff --git a/src/plugins/scenegraph/scenegraph.pro b/src/plugins/scenegraph/scenegraph.pro
index a90e8d4814..39c0c0815c 100644
--- a/src/plugins/scenegraph/scenegraph.pro
+++ b/src/plugins/scenegraph/scenegraph.pro
@@ -1,3 +1,5 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += quick
qtConfig(d3d12): SUBDIRS += d3d12
+qtConfig(openvg): SUBDIRS += openvg
+
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index efc86a5823..95a39b1301 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -218,11 +218,11 @@ public:
*/
static void updateAnimationTimer();
- void restartAnimationTimer();
- void updateAnimationsTime(qint64 timeStep);
+ void restartAnimationTimer() override;
+ void updateAnimationsTime(qint64 timeStep) override;
//useful for profiling/debugging
- int runningAnimationCount() { return animations.count(); }
+ int runningAnimationCount() override { return animations.count(); }
bool hasStartAnimationPending() const { return startAnimationPending; }
diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h
index 9bcd63127a..26965c0264 100644
--- a/src/qml/animations/qanimationgroupjob_p.h
+++ b/src/qml/animations/qanimationgroupjob_p.h
@@ -75,7 +75,7 @@ public:
//called by QAbstractAnimationJob
virtual void uncontrolledAnimationFinished(QAbstractAnimationJob *animation);
protected:
- void topLevelAnimationLoopChanged();
+ void topLevelAnimationLoopChanged() override;
virtual void animationInserted(QAbstractAnimationJob*) { }
virtual void animationRemoved(QAbstractAnimationJob*, QAbstractAnimationJob*, QAbstractAnimationJob*);
diff --git a/src/qml/animations/qcontinuinganimationgroupjob_p.h b/src/qml/animations/qcontinuinganimationgroupjob_p.h
index f34a118cad..baf4ff1ae5 100644
--- a/src/qml/animations/qcontinuinganimationgroupjob_p.h
+++ b/src/qml/animations/qcontinuinganimationgroupjob_p.h
@@ -62,14 +62,14 @@ public:
QContinuingAnimationGroupJob();
~QContinuingAnimationGroupJob();
- int duration() const { return -1; }
+ int duration() const override { return -1; }
protected:
- void updateCurrentTime(int currentTime);
- void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState);
- void updateDirection(QAbstractAnimationJob::Direction direction);
- void uncontrolledAnimationFinished(QAbstractAnimationJob *animation);
- void debugAnimation(QDebug d) const;
+ void updateCurrentTime(int currentTime) override;
+ void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override;
+ void updateDirection(QAbstractAnimationJob::Direction direction) override;
+ void uncontrolledAnimationFinished(QAbstractAnimationJob *animation) override;
+ void debugAnimation(QDebug d) const override;
};
QT_END_NAMESPACE
diff --git a/src/qml/animations/qparallelanimationgroupjob_p.h b/src/qml/animations/qparallelanimationgroupjob_p.h
index 3e914c3e76..358b95ce53 100644
--- a/src/qml/animations/qparallelanimationgroupjob_p.h
+++ b/src/qml/animations/qparallelanimationgroupjob_p.h
@@ -62,14 +62,14 @@ public:
QParallelAnimationGroupJob();
~QParallelAnimationGroupJob();
- int duration() const;
+ int duration() const override;
protected:
- void updateCurrentTime(int currentTime);
- void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState);
- void updateDirection(QAbstractAnimationJob::Direction direction);
- void uncontrolledAnimationFinished(QAbstractAnimationJob *animation);
- void debugAnimation(QDebug d) const;
+ void updateCurrentTime(int currentTime) override;
+ void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override;
+ void updateDirection(QAbstractAnimationJob::Direction direction) override;
+ void uncontrolledAnimationFinished(QAbstractAnimationJob *animation) override;
+ void debugAnimation(QDebug d) const override;
private:
bool shouldAnimationStart(QAbstractAnimationJob *animation, bool startIfAtEnd) const;
diff --git a/src/qml/animations/qpauseanimationjob_p.h b/src/qml/animations/qpauseanimationjob_p.h
index 2967e1cf60..e228f46daa 100644
--- a/src/qml/animations/qpauseanimationjob_p.h
+++ b/src/qml/animations/qpauseanimationjob_p.h
@@ -62,12 +62,12 @@ public:
explicit QPauseAnimationJob(int duration = 250);
~QPauseAnimationJob();
- int duration() const;
+ int duration() const override;
void setDuration(int msecs);
protected:
- void updateCurrentTime(int);
- void debugAnimation(QDebug d) const;
+ void updateCurrentTime(int) override;
+ void debugAnimation(QDebug d) const override;
private:
//definition
diff --git a/src/qml/animations/qsequentialanimationgroupjob_p.h b/src/qml/animations/qsequentialanimationgroupjob_p.h
index bb481d1322..5fbafcb9ac 100644
--- a/src/qml/animations/qsequentialanimationgroupjob_p.h
+++ b/src/qml/animations/qsequentialanimationgroupjob_p.h
@@ -63,16 +63,16 @@ public:
QSequentialAnimationGroupJob();
~QSequentialAnimationGroupJob();
- int duration() const;
+ int duration() const override;
QAbstractAnimationJob *currentAnimation() const { return m_currentAnimation; }
protected:
- void updateCurrentTime(int);
- void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState);
- void updateDirection(QAbstractAnimationJob::Direction direction);
- void uncontrolledAnimationFinished(QAbstractAnimationJob *animation);
- void debugAnimation(QDebug d) const;
+ void updateCurrentTime(int) override;
+ void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override;
+ void updateDirection(QAbstractAnimationJob::Direction direction) override;
+ void uncontrolledAnimationFinished(QAbstractAnimationJob *animation) override;
+ void debugAnimation(QDebug d) const override;
private:
struct AnimationIndex
@@ -91,8 +91,8 @@ private:
void setCurrentAnimation(QAbstractAnimationJob *anim, bool intermediate = false);
void activateCurrentAnimation(bool intermediate = false);
- void animationInserted(QAbstractAnimationJob *anim);
- void animationRemoved(QAbstractAnimationJob *anim,QAbstractAnimationJob*,QAbstractAnimationJob*);
+ void animationInserted(QAbstractAnimationJob *anim) override;
+ void animationRemoved(QAbstractAnimationJob *anim, QAbstractAnimationJob *, QAbstractAnimationJob *) override;
bool atEnd() const;
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index c0f953ca2c..54d0cb4f46 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -362,10 +362,11 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen
QQmlJS::Parser parser(&output->jsParserEngine);
- if (! parser.parse() || !parser.diagnosticMessages().isEmpty()) {
-
+ const bool parseResult = parser.parse();
+ const auto diagnosticMessages = parser.diagnosticMessages();
+ if (!parseResult || !diagnosticMessages.isEmpty()) {
// Extract errors from the parser
- foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
+ for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
qWarning("%s:%d : %s", qPrintable(url), m.loc.startLine, qPrintable(m.message));
@@ -1018,7 +1019,8 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST
CompiledFunctionOrExpression *expr = New<CompiledFunctionOrExpression>();
expr->node = statement;
- expr->nameIndex = registerString(QStringLiteral("expression for ") + stringAt(binding->propertyNameIndex));
+ expr->nameIndex = registerString(QLatin1String("expression for ")
+ + stringAt(binding->propertyNameIndex));
expr->disableAcceleratedLookups = false;
const int index = bindingsTarget()->functionsAndExpressions->append(expr);
binding->value.compiledScriptIndex = index;
@@ -1246,7 +1248,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
// If it's a namespace, prepend the qualifier and we'll resolve it later to the correct type.
QString currentName = qualifiedIdElement->name.toString();
if (qualifiedIdElement->next) {
- foreach (const QV4::CompiledData::Import* import, _imports)
+ for (const QV4::CompiledData::Import* import : qAsConst(_imports))
if (import->qualifierIndex != emptyStringIndex
&& stringAt(import->qualifierIndex) == currentName) {
qualifiedIdElement = qualifiedIdElement->next;
@@ -1371,7 +1373,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine
QHash<const Object*, quint32> objectOffsets;
int objectsSize = 0;
- foreach (Object *o, output.objects) {
+ for (Object *o : qAsConst(output.objects)) {
objectOffsets.insert(o, unitSize + importSize + objectOffsetTableSize + objectsSize);
objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->aliasCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
@@ -1417,7 +1419,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine
// write imports
char *importPtr = data + qmlUnit->offsetToImports;
- foreach (const QV4::CompiledData::Import *imp, output.imports) {
+ for (const QV4::CompiledData::Import *imp : qAsConst(output.imports)) {
QV4::CompiledData::Import *importToWrite = reinterpret_cast<QV4::CompiledData::Import*>(importPtr);
*importToWrite = *imp;
importPtr += sizeof(QV4::CompiledData::Import);
@@ -1522,7 +1524,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine
}
// enable flag if we encountered pragma Singleton
- foreach (Pragma *p, output.pragmas) {
+ for (Pragma *p : qAsConst(output.pragmas)) {
if (p->type == Pragma::PragmaSingleton) {
qmlUnit->flags |= QV4::CompiledData::Unit::IsSingleton;
break;
@@ -1588,7 +1590,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
ScanFunctions scan(this, sourceCode, GlobalCode);
scan.enterEnvironment(0, QmlBinding);
scan.enterQmlScope(qmlRoot, QStringLiteral("context scope"));
- foreach (const CompiledFunctionOrExpression &f, functions) {
+ for (const CompiledFunctionOrExpression &f : functions) {
Q_ASSERT(f.node != qmlRoot);
QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(f.node);
@@ -1923,7 +1925,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
// with the correct QML context.
// Look for IDs first.
- foreach (const IdMapping &mapping, _idObjects)
+ for (const IdMapping &mapping : qAsConst(_idObjects))
if (name == mapping.name) {
if (_function->isQmlBinding)
_function->idObjectDependencies.insert(mapping.idIndex);
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index cc16dc2104..95756845c3 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -453,9 +453,9 @@ struct Q_QML_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directive
QList<const QV4::CompiledData::Import *> imports;
bool hasPragmaLibrary;
- virtual void pragmaLibrary();
- virtual void importFile(const QString &jsfile, const QString &module, int lineNumber, int column);
- virtual void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column);
+ void pragmaLibrary() override;
+ void importFile(const QString &jsfile, const QString &module, int lineNumber, int column) override;
+ void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column) override;
};
struct Q_QML_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor
@@ -470,21 +470,21 @@ public:
using QQmlJS::AST::Visitor::visit;
using QQmlJS::AST::Visitor::endVisit;
- virtual bool visit(QQmlJS::AST::UiArrayMemberList *ast);
- virtual bool visit(QQmlJS::AST::UiImport *ast);
- virtual bool visit(QQmlJS::AST::UiPragma *ast);
- virtual bool visit(QQmlJS::AST::UiHeaderItemList *ast);
- virtual bool visit(QQmlJS::AST::UiObjectInitializer *ast);
- virtual bool visit(QQmlJS::AST::UiObjectMemberList *ast);
- virtual bool visit(QQmlJS::AST::UiParameterList *ast);
- virtual bool visit(QQmlJS::AST::UiProgram *);
- virtual bool visit(QQmlJS::AST::UiQualifiedId *ast);
- virtual bool visit(QQmlJS::AST::UiArrayBinding *ast);
- virtual bool visit(QQmlJS::AST::UiObjectBinding *ast);
- virtual bool visit(QQmlJS::AST::UiObjectDefinition *ast);
- virtual bool visit(QQmlJS::AST::UiPublicMember *ast);
- virtual bool visit(QQmlJS::AST::UiScriptBinding *ast);
- virtual bool visit(QQmlJS::AST::UiSourceElement *ast);
+ bool visit(QQmlJS::AST::UiArrayMemberList *ast) override;
+ bool visit(QQmlJS::AST::UiImport *ast) override;
+ bool visit(QQmlJS::AST::UiPragma *ast) override;
+ bool visit(QQmlJS::AST::UiHeaderItemList *ast) override;
+ bool visit(QQmlJS::AST::UiObjectInitializer *ast) override;
+ bool visit(QQmlJS::AST::UiObjectMemberList *ast) override;
+ bool visit(QQmlJS::AST::UiParameterList *ast) override;
+ bool visit(QQmlJS::AST::UiProgram *) override;
+ bool visit(QQmlJS::AST::UiQualifiedId *ast) override;
+ bool visit(QQmlJS::AST::UiArrayBinding *ast) override;
+ bool visit(QQmlJS::AST::UiObjectBinding *ast) override;
+ bool visit(QQmlJS::AST::UiObjectDefinition *ast) override;
+ bool visit(QQmlJS::AST::UiPublicMember *ast) override;
+ bool visit(QQmlJS::AST::UiScriptBinding *ast) override;
+ bool visit(QQmlJS::AST::UiSourceElement *ast) override;
void accept(QQmlJS::AST::Node *node);
@@ -602,8 +602,8 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QQmlJS::Codegen
QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions);
protected:
- virtual void beginFunctionBodyHook();
- virtual QV4::IR::Expr *fallbackNameLookup(const QString &name, int line, int col);
+ void beginFunctionBodyHook() override;
+ QV4::IR::Expr *fallbackNameLookup(const QString &name, int line, int col) override;
private:
QQmlPropertyData *lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name, bool *propertyExistsButForceNameLookup = 0);
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 393616dfac..ab2b0553a9 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -471,7 +471,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QQmlJS::MemoryPool *pool = compiler->memoryPool();
QQmlJS::AST::FormalParameterList *paramList = 0;
- foreach (const QString &param, parameters) {
+ for (const QString &param : qAsConst(parameters)) {
QStringRef paramNameRef = compiler->newStringRef(param);
if (paramList)
@@ -1348,9 +1348,9 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn
functionsToCompile << *foe;
}
const QVector<int> runtimeFunctionIndices = v4CodeGen->generateJSCodeForFunctionsAndBindings(functionsToCompile);
- QList<QQmlError> jsErrors = v4CodeGen->qmlErrors();
+ const QList<QQmlError> jsErrors = v4CodeGen->qmlErrors();
if (!jsErrors.isEmpty()) {
- foreach (const QQmlError &e, jsErrors)
+ for (const QQmlError &e : jsErrors)
compiler->recordError(e);
return false;
}
@@ -1729,7 +1729,7 @@ void QQmlIRFunctionCleanser::clean()
module->functions = newFunctions;
- foreach (QV4::IR::Function *function, module->functions) {
+ for (QV4::IR::Function *function : qAsConst(module->functions)) {
for (QV4::IR::BasicBlock *block : function->basicBlocks()) {
for (QV4::IR::Stmt *s : block->statements()) {
visit(s);
@@ -1737,7 +1737,7 @@ void QQmlIRFunctionCleanser::clean()
}
}
- foreach (QmlIR::Object *obj, *compiler->qmlObjects()) {
+ for (QmlIR::Object *obj : qAsConst(*compiler->qmlObjects())) {
for (int i = 0; i < obj->runtimeFunctionIndices.count; ++i)
obj->runtimeFunctionIndices[i] = newFunctionIndices[obj->runtimeFunctionIndices.at(i)];
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 59199183bd..742ee79648 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -331,103 +331,103 @@ protected:
virtual void beginFunctionBodyHook() {}
// nodes
- virtual bool visit(AST::ArgumentList *ast);
- virtual bool visit(AST::CaseBlock *ast);
- virtual bool visit(AST::CaseClause *ast);
- virtual bool visit(AST::CaseClauses *ast);
- virtual bool visit(AST::Catch *ast);
- virtual bool visit(AST::DefaultClause *ast);
- virtual bool visit(AST::ElementList *ast);
- virtual bool visit(AST::Elision *ast);
- virtual bool visit(AST::Finally *ast);
- virtual bool visit(AST::FormalParameterList *ast);
- virtual bool visit(AST::FunctionBody *ast);
- virtual bool visit(AST::Program *ast);
- virtual bool visit(AST::PropertyNameAndValue *ast);
- virtual bool visit(AST::PropertyAssignmentList *ast);
- virtual bool visit(AST::PropertyGetterSetter *ast);
- virtual bool visit(AST::SourceElements *ast);
- virtual bool visit(AST::StatementList *ast);
- virtual bool visit(AST::UiArrayMemberList *ast);
- virtual bool visit(AST::UiImport *ast);
- virtual bool visit(AST::UiHeaderItemList *ast);
- virtual bool visit(AST::UiPragma *ast);
- virtual bool visit(AST::UiObjectInitializer *ast);
- virtual bool visit(AST::UiObjectMemberList *ast);
- virtual bool visit(AST::UiParameterList *ast);
- virtual bool visit(AST::UiProgram *ast);
- virtual bool visit(AST::UiQualifiedId *ast);
- virtual bool visit(AST::UiQualifiedPragmaId *ast);
- virtual bool visit(AST::VariableDeclaration *ast);
- virtual bool visit(AST::VariableDeclarationList *ast);
+ bool visit(AST::ArgumentList *ast) override;
+ bool visit(AST::CaseBlock *ast) override;
+ bool visit(AST::CaseClause *ast) override;
+ bool visit(AST::CaseClauses *ast) override;
+ bool visit(AST::Catch *ast) override;
+ bool visit(AST::DefaultClause *ast) override;
+ bool visit(AST::ElementList *ast) override;
+ bool visit(AST::Elision *ast) override;
+ bool visit(AST::Finally *ast) override;
+ bool visit(AST::FormalParameterList *ast) override;
+ bool visit(AST::FunctionBody *ast) override;
+ bool visit(AST::Program *ast) override;
+ bool visit(AST::PropertyNameAndValue *ast) override;
+ bool visit(AST::PropertyAssignmentList *ast) override;
+ bool visit(AST::PropertyGetterSetter *ast) override;
+ bool visit(AST::SourceElements *ast) override;
+ bool visit(AST::StatementList *ast) override;
+ bool visit(AST::UiArrayMemberList *ast) override;
+ bool visit(AST::UiImport *ast) override;
+ bool visit(AST::UiHeaderItemList *ast) override;
+ bool visit(AST::UiPragma *ast) override;
+ bool visit(AST::UiObjectInitializer *ast) override;
+ bool visit(AST::UiObjectMemberList *ast) override;
+ bool visit(AST::UiParameterList *ast) override;
+ bool visit(AST::UiProgram *ast) override;
+ bool visit(AST::UiQualifiedId *ast) override;
+ bool visit(AST::UiQualifiedPragmaId *ast) override;
+ bool visit(AST::VariableDeclaration *ast) override;
+ bool visit(AST::VariableDeclarationList *ast) override;
// expressions
- virtual bool visit(AST::Expression *ast);
- virtual bool visit(AST::ArrayLiteral *ast);
- virtual bool visit(AST::ArrayMemberExpression *ast);
- virtual bool visit(AST::BinaryExpression *ast);
- virtual bool visit(AST::CallExpression *ast);
- virtual bool visit(AST::ConditionalExpression *ast);
- virtual bool visit(AST::DeleteExpression *ast);
- virtual bool visit(AST::FalseLiteral *ast);
- virtual bool visit(AST::FieldMemberExpression *ast);
- virtual bool visit(AST::FunctionExpression *ast);
- virtual bool visit(AST::IdentifierExpression *ast);
- virtual bool visit(AST::NestedExpression *ast);
- virtual bool visit(AST::NewExpression *ast);
- virtual bool visit(AST::NewMemberExpression *ast);
- virtual bool visit(AST::NotExpression *ast);
- virtual bool visit(AST::NullExpression *ast);
- virtual bool visit(AST::NumericLiteral *ast);
- virtual bool visit(AST::ObjectLiteral *ast);
- virtual bool visit(AST::PostDecrementExpression *ast);
- virtual bool visit(AST::PostIncrementExpression *ast);
- virtual bool visit(AST::PreDecrementExpression *ast);
- virtual bool visit(AST::PreIncrementExpression *ast);
- virtual bool visit(AST::RegExpLiteral *ast);
- virtual bool visit(AST::StringLiteral *ast);
- virtual bool visit(AST::ThisExpression *ast);
- virtual bool visit(AST::TildeExpression *ast);
- virtual bool visit(AST::TrueLiteral *ast);
- virtual bool visit(AST::TypeOfExpression *ast);
- virtual bool visit(AST::UnaryMinusExpression *ast);
- virtual bool visit(AST::UnaryPlusExpression *ast);
- virtual bool visit(AST::VoidExpression *ast);
- virtual bool visit(AST::FunctionDeclaration *ast);
+ bool visit(AST::Expression *ast) override;
+ bool visit(AST::ArrayLiteral *ast) override;
+ bool visit(AST::ArrayMemberExpression *ast) override;
+ bool visit(AST::BinaryExpression *ast) override;
+ bool visit(AST::CallExpression *ast) override;
+ bool visit(AST::ConditionalExpression *ast) override;
+ bool visit(AST::DeleteExpression *ast) override;
+ bool visit(AST::FalseLiteral *ast) override;
+ bool visit(AST::FieldMemberExpression *ast) override;
+ bool visit(AST::FunctionExpression *ast) override;
+ bool visit(AST::IdentifierExpression *ast) override;
+ bool visit(AST::NestedExpression *ast) override;
+ bool visit(AST::NewExpression *ast) override;
+ bool visit(AST::NewMemberExpression *ast) override;
+ bool visit(AST::NotExpression *ast) override;
+ bool visit(AST::NullExpression *ast) override;
+ bool visit(AST::NumericLiteral *ast) override;
+ bool visit(AST::ObjectLiteral *ast) override;
+ bool visit(AST::PostDecrementExpression *ast) override;
+ bool visit(AST::PostIncrementExpression *ast) override;
+ bool visit(AST::PreDecrementExpression *ast) override;
+ bool visit(AST::PreIncrementExpression *ast) override;
+ bool visit(AST::RegExpLiteral *ast) override;
+ bool visit(AST::StringLiteral *ast) override;
+ bool visit(AST::ThisExpression *ast) override;
+ bool visit(AST::TildeExpression *ast) override;
+ bool visit(AST::TrueLiteral *ast) override;
+ bool visit(AST::TypeOfExpression *ast) override;
+ bool visit(AST::UnaryMinusExpression *ast) override;
+ bool visit(AST::UnaryPlusExpression *ast) override;
+ bool visit(AST::VoidExpression *ast) override;
+ bool visit(AST::FunctionDeclaration *ast) override;
// source elements
- virtual bool visit(AST::FunctionSourceElement *ast);
- virtual bool visit(AST::StatementSourceElement *ast);
+ bool visit(AST::FunctionSourceElement *ast) override;
+ bool visit(AST::StatementSourceElement *ast) override;
// statements
- virtual bool visit(AST::Block *ast);
- virtual bool visit(AST::BreakStatement *ast);
- virtual bool visit(AST::ContinueStatement *ast);
- virtual bool visit(AST::DebuggerStatement *ast);
- virtual bool visit(AST::DoWhileStatement *ast);
- virtual bool visit(AST::EmptyStatement *ast);
- virtual bool visit(AST::ExpressionStatement *ast);
- virtual bool visit(AST::ForEachStatement *ast);
- virtual bool visit(AST::ForStatement *ast);
- virtual bool visit(AST::IfStatement *ast);
- virtual bool visit(AST::LabelledStatement *ast);
- virtual bool visit(AST::LocalForEachStatement *ast);
- virtual bool visit(AST::LocalForStatement *ast);
- virtual bool visit(AST::ReturnStatement *ast);
- virtual bool visit(AST::SwitchStatement *ast);
- virtual bool visit(AST::ThrowStatement *ast);
- virtual bool visit(AST::TryStatement *ast);
- virtual bool visit(AST::VariableStatement *ast);
- virtual bool visit(AST::WhileStatement *ast);
- virtual bool visit(AST::WithStatement *ast);
+ bool visit(AST::Block *ast) override;
+ bool visit(AST::BreakStatement *ast) override;
+ bool visit(AST::ContinueStatement *ast) override;
+ bool visit(AST::DebuggerStatement *ast) override;
+ bool visit(AST::DoWhileStatement *ast) override;
+ bool visit(AST::EmptyStatement *ast) override;
+ bool visit(AST::ExpressionStatement *ast) override;
+ bool visit(AST::ForEachStatement *ast) override;
+ bool visit(AST::ForStatement *ast) override;
+ bool visit(AST::IfStatement *ast) override;
+ bool visit(AST::LabelledStatement *ast) override;
+ bool visit(AST::LocalForEachStatement *ast) override;
+ bool visit(AST::LocalForStatement *ast) override;
+ bool visit(AST::ReturnStatement *ast) override;
+ bool visit(AST::SwitchStatement *ast) override;
+ bool visit(AST::ThrowStatement *ast) override;
+ bool visit(AST::TryStatement *ast) override;
+ bool visit(AST::VariableStatement *ast) override;
+ bool visit(AST::WhileStatement *ast) override;
+ bool visit(AST::WithStatement *ast) override;
// ui object members
- virtual bool visit(AST::UiArrayBinding *ast);
- virtual bool visit(AST::UiObjectBinding *ast);
- virtual bool visit(AST::UiObjectDefinition *ast);
- virtual bool visit(AST::UiPublicMember *ast);
- virtual bool visit(AST::UiScriptBinding *ast);
- virtual bool visit(AST::UiSourceElement *ast);
+ bool visit(AST::UiArrayBinding *ast) override;
+ bool visit(AST::UiObjectBinding *ast) override;
+ bool visit(AST::UiObjectDefinition *ast) override;
+ bool visit(AST::UiPublicMember *ast) override;
+ bool visit(AST::UiScriptBinding *ast) override;
+ bool visit(AST::UiSourceElement *ast) override;
bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(QV4::IR::Expr* expr, const AST::SourceLocation &loc);
virtual void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail);
@@ -486,39 +486,39 @@ protected:
void checkName(const QStringRef &name, const AST::SourceLocation &loc);
void checkForArguments(AST::FormalParameterList *parameters);
- virtual bool visit(AST::Program *ast);
- virtual void endVisit(AST::Program *);
+ bool visit(AST::Program *ast) override;
+ void endVisit(AST::Program *) override;
- virtual bool visit(AST::CallExpression *ast);
- virtual bool visit(AST::NewMemberExpression *ast);
- virtual bool visit(AST::ArrayLiteral *ast);
- virtual bool visit(AST::VariableDeclaration *ast);
- virtual bool visit(AST::IdentifierExpression *ast);
- virtual bool visit(AST::ExpressionStatement *ast);
- virtual bool visit(AST::FunctionExpression *ast);
+ bool visit(AST::CallExpression *ast) override;
+ bool visit(AST::NewMemberExpression *ast) override;
+ bool visit(AST::ArrayLiteral *ast) override;
+ bool visit(AST::VariableDeclaration *ast) override;
+ bool visit(AST::IdentifierExpression *ast) override;
+ bool visit(AST::ExpressionStatement *ast) override;
+ bool visit(AST::FunctionExpression *ast) override;
void enterFunction(AST::FunctionExpression *ast, bool enterName, bool isExpression = true);
- virtual void endVisit(AST::FunctionExpression *);
+ void endVisit(AST::FunctionExpression *) override;
- virtual bool visit(AST::ObjectLiteral *ast);
+ bool visit(AST::ObjectLiteral *ast) override;
- virtual bool visit(AST::PropertyGetterSetter *ast);
- virtual void endVisit(AST::PropertyGetterSetter *);
+ bool visit(AST::PropertyGetterSetter *ast) override;
+ void endVisit(AST::PropertyGetterSetter *) override;
- virtual bool visit(AST::FunctionDeclaration *ast);
- virtual void endVisit(AST::FunctionDeclaration *);
+ bool visit(AST::FunctionDeclaration *ast) override;
+ void endVisit(AST::FunctionDeclaration *) override;
- virtual bool visit(AST::WithStatement *ast);
+ bool visit(AST::WithStatement *ast) override;
- virtual bool visit(AST::DoWhileStatement *ast);
- virtual bool visit(AST::ForStatement *ast);
- virtual bool visit(AST::LocalForStatement *ast);
- virtual bool visit(AST::ForEachStatement *ast);
- virtual bool visit(AST::LocalForEachStatement *ast);
- virtual bool visit(AST::ThisExpression *ast);
+ bool visit(AST::DoWhileStatement *ast) override;
+ bool visit(AST::ForStatement *ast) override;
+ bool visit(AST::LocalForStatement *ast) override;
+ bool visit(AST::ForEachStatement *ast) override;
+ bool visit(AST::LocalForEachStatement *ast) override;
+ bool visit(AST::ThisExpression *ast) override;
- virtual bool visit(AST::Block *ast);
+ bool visit(AST::Block *ast) override;
protected:
void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr, bool isExpression);
@@ -544,8 +544,8 @@ public:
, engine(engine)
{}
- virtual void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail);
- virtual void throwReferenceError(const AST::SourceLocation &loc, const QString &detail);
+ void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail) override;
+ void throwReferenceError(const AST::SourceLocation &loc, const QString &detail) override;
private:
QV4::ExecutionEngine *engine;
};
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index e1ea3a9b88..cd822a2614 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -212,7 +212,7 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, IR::ExprList *arg
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option)
{
registerString(irModule->fileName);
- foreach (QV4::IR::Function *f, irModule->functions) {
+ for (QV4::IR::Function *f : qAsConst(irModule->functions)) {
registerString(*f->name);
for (int i = 0; i < f->formals.size(); ++i)
registerString(*f->formals.at(i));
@@ -244,7 +244,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
}
CompiledData::Lookup *lookupsToWrite = reinterpret_cast<CompiledData::Lookup*>(dataPtr + unit->offsetToLookupTable);
- foreach (const CompiledData::Lookup &l, lookups)
+ for (const CompiledData::Lookup &l : qAsConst(lookups))
*lookupsToWrite++ = l;
CompiledData::RegExp *regexpTable = reinterpret_cast<CompiledData::RegExp *>(dataPtr + unit->offsetToRegexpTable);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index f2bd57ad8f..9dbebd1128 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -209,7 +209,7 @@ void InstructionSelection::run(int functionIndex)
ConvertTemps().toStackSlots(_function);
}
- QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps();
+ BitVector removableJumps = opt.calculateOptionalJumps();
qSwap(_removableJumps, removableJumps);
IR::Stmt *cs = 0;
@@ -297,7 +297,7 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> InstructionSelection::backend
{
compilationUnit->codeRefs.resize(irModule->functions.size());
int i = 0;
- foreach (IR::Function *irFunction, irModule->functions)
+ for (IR::Function *irFunction : qAsConst(irModule->functions))
compilationUnit->codeRefs[i++] = codeRefs[irFunction];
QQmlRefPointer<QV4::CompiledData::CompilationUnit> result;
result.adopt(compilationUnit.take());
@@ -955,7 +955,7 @@ void InstructionSelection::visitJump(IR::Jump *s)
{
if (s->target == _nextBlock)
return;
- if (_removableJumps.contains(s))
+ if (_removableJumps.at(_block->index()))
return;
addDebugInstruction();
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index 74323a2912..afe5fe342e 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -54,6 +54,7 @@
#include <private/qv4global_p.h>
#include <private/qv4isel_p.h>
#include <private/qv4isel_util_p.h>
+#include <private/qv4util_p.h>
#include <private/qv4jsir_p.h>
#include <private/qv4value_p.h>
#include "qv4instr_moth_p.h"
@@ -85,68 +86,68 @@ public:
InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory);
~InstructionSelection();
- virtual void run(int functionIndex);
+ void run(int functionIndex) override;
protected:
- virtual QQmlRefPointer<CompiledData::CompilationUnit> backendCompileStep();
-
- virtual void visitJump(IR::Jump *);
- virtual void visitCJump(IR::CJump *);
- virtual void visitRet(IR::Ret *);
-
- virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result);
- virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result);
- virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result);
- virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result);
- virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result);
- virtual void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result);
- virtual void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result);
- virtual void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result);
- virtual void callBuiltinDeleteName(const QString &name, IR::Expr *result);
- virtual void callBuiltinDeleteValue(IR::Expr *result);
- virtual void callBuiltinThrow(IR::Expr *arg);
- virtual void callBuiltinReThrow();
- virtual void callBuiltinUnwindException(IR::Expr *);
- virtual void callBuiltinPushCatchScope(const QString &exceptionName);
- virtual void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result);
- virtual void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result);
- virtual void callBuiltinPushWithScope(IR::Expr *arg);
- virtual void callBuiltinPopScope();
- virtual void callBuiltinDeclareVar(bool deletable, const QString &name);
- virtual void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args);
- virtual void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray);
- virtual void callBuiltinSetupArgumentObject(IR::Expr *result);
- virtual void callBuiltinConvertThisToObject();
- virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
- virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result);
- virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result);
- virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result);
- virtual void convertType(IR::Expr *source, IR::Expr *target);
- virtual void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result);
- virtual void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result);
- virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
- virtual void loadThisObject(IR::Expr *e);
- virtual void loadQmlContext(IR::Expr *e);
- virtual void loadQmlImportedScripts(IR::Expr *e);
- virtual void loadQmlSingleton(const QString &name, IR::Expr *e);
- virtual void loadConst(IR::Const *sourceConst, IR::Expr *e);
- virtual void loadString(const QString &str, IR::Expr *target);
- virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target);
- virtual void getActivationProperty(const IR::Name *name, IR::Expr *target);
- virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
- virtual void initClosure(IR::Closure *closure, IR::Expr *target);
- virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target);
- virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
- virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
- virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
- virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target);
- virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
- virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target);
- virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex);
- virtual void copyValue(IR::Expr *source, IR::Expr *target);
- virtual void swapValues(IR::Expr *source, IR::Expr *target);
- virtual void unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target);
- virtual void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
+ QQmlRefPointer<CompiledData::CompilationUnit> backendCompileStep() override;
+
+ void visitJump(IR::Jump *) override;
+ void visitCJump(IR::CJump *) override;
+ void visitRet(IR::Ret *) override;
+
+ void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
+ void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) override;
+ void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
+ void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
+ void callBuiltinTypeofName(const QString &name, IR::Expr *result) override;
+ void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result) override;
+ void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
+ void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
+ void callBuiltinDeleteName(const QString &name, IR::Expr *result) override;
+ void callBuiltinDeleteValue(IR::Expr *result) override;
+ void callBuiltinThrow(IR::Expr *arg) override;
+ void callBuiltinReThrow() override;
+ void callBuiltinUnwindException(IR::Expr *) override;
+ void callBuiltinPushCatchScope(const QString &exceptionName) override;
+ void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result) override;
+ void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result) override;
+ void callBuiltinPushWithScope(IR::Expr *arg) override;
+ void callBuiltinPopScope() override;
+ void callBuiltinDeclareVar(bool deletable, const QString &name) override;
+ void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args) override;
+ void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray) override;
+ void callBuiltinSetupArgumentObject(IR::Expr *result) override;
+ void callBuiltinConvertThisToObject() override;
+ void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
+ void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) override;
+ void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
+ void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) override;
+ void convertType(IR::Expr *source, IR::Expr *target) override;
+ void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
+ void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
+ void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
+ void loadThisObject(IR::Expr *e) override;
+ void loadQmlContext(IR::Expr *e) override;
+ void loadQmlImportedScripts(IR::Expr *e) override;
+ void loadQmlSingleton(const QString &name, IR::Expr *e) override;
+ void loadConst(IR::Const *sourceConst, IR::Expr *e) override;
+ void loadString(const QString &str, IR::Expr *target) override;
+ void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target) override;
+ void getActivationProperty(const IR::Name *name, IR::Expr *target) override;
+ void setActivationProperty(IR::Expr *source, const QString &targetName) override;
+ void initClosure(IR::Closure *closure, IR::Expr *target) override;
+ void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) override;
+ void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) override;
+ void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) override;
+ void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) override;
+ void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target) override;
+ void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) override;
+ void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) override;
+ void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override;
+ void copyValue(IR::Expr *source, IR::Expr *target) override;
+ void swapValues(IR::Expr *source, IR::Expr *target) override;
+ void unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target) override;
+ void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) override;
private:
Param binopHelper(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
@@ -199,7 +200,7 @@ private:
uchar *_codeNext;
uchar *_codeEnd;
- QSet<IR::Jump *> _removableJumps;
+ BitVector _removableJumps;
IR::Stmt *_currentStatement;
QScopedPointer<CompilationUnit> compilationUnit;
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index deba41ef9d..943700de44 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -1123,7 +1123,7 @@ public:
{
QVector<UntypedTemp> res;
res.reserve(tempCount());
- foreach (const DefUse &du, _defUses)
+ for (const DefUse &du : _defUses)
if (du.isValid())
res.append(UntypedTemp(du.temp));
return res;
@@ -1150,7 +1150,7 @@ public:
{
Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
QVector<Stmt *> &uses = _defUses[variable.index].uses;
- foreach (Stmt *stmt, newUses)
+ for (Stmt *stmt : newUses)
if (std::find(uses.begin(), uses.end(), stmt) == uses.end())
uses.push_back(stmt);
}
@@ -1226,7 +1226,7 @@ public:
QVector<Stmt*> removeDefUses(Stmt *s)
{
QVector<Stmt*> defStmts;
- foreach (const Temp &usedVar, usedVars(s)) {
+ for (const Temp &usedVar : usedVars(s)) {
if (Stmt *ds = defStmt(usedVar))
defStmts += ds;
removeUse(s, usedVar);
@@ -1247,7 +1247,7 @@ public:
buf.open(QIODevice::WriteOnly);
QTextStream qout(&buf);
qout << "Defines and uses:" << endl;
- foreach (const DefUse &du, _defUses) {
+ for (const DefUse &du : _defUses) {
if (!du.isValid())
continue;
qout << '%' << du.temp.index;
@@ -1255,14 +1255,14 @@ public:
<< ", statement: " << du.defStmt->id()
<< endl;
qout << " uses:";
- foreach (Stmt *s, du.uses)
+ for (Stmt *s : du.uses)
qout << ' ' << s->id();
qout << endl;
}
qout << "Uses per statement:" << endl;
for (size_t i = 0, ei = _usesPerStatement.size(); i != ei; ++i) {
qout << " " << i << ":";
- foreach (const Temp &t, _usesPerStatement[i])
+ for (const Temp &t : _usesPerStatement[i])
qout << ' ' << t.index;
qout << endl;
}
@@ -1633,7 +1633,7 @@ bool hasPhiOnlyUses(Phi *phi, const DefUses &defUses, QBitArray &collectedPhis)
{
collectedPhis.setBit(phi->id());
- foreach (Stmt *use, defUses.uses(*phi->targetTemp)) {
+ for (Stmt *use : defUses.uses(*phi->targetTemp)) {
Phi *dependentPhi = use->asPhi();
if (!dependentPhi)
return false; // there is a use by a non-phi node
@@ -1679,7 +1679,7 @@ void cleanupPhis(DefUses &defUses)
const Temp &targetVar = *phi->targetTemp;
defUses.defStmtBlock(targetVar)->removeStatement(phi);
- foreach (const Temp &usedVar, defUses.usedVars(phi))
+ for (const Temp &usedVar : defUses.usedVars(phi))
defUses.removeUse(phi, usedVar);
defUses.removeDef(targetVar);
}
@@ -1729,7 +1729,7 @@ public:
worklist.assign(worklist.size(), false);
worklistSize = 0;
- foreach (Stmt *s, stmts) {
+ for (Stmt *s : stmts) {
if (!s)
continue;
@@ -1802,7 +1802,7 @@ public:
StatementWorklist &operator+=(const QVector<Stmt *> &stmts)
{
- foreach (Stmt *s, stmts)
+ for (Stmt *s : stmts)
this->operator+=(s);
return *this;
@@ -2091,7 +2091,7 @@ public:
theTemp = temp;
if (Stmt *defStmt = defUses.defStmt(temp.temp))
visit(defStmt);
- foreach (Stmt *use, defUses.uses(temp.temp))
+ for (Stmt *use : defUses.uses(temp.temp))
visit(use);
}
@@ -2245,7 +2245,7 @@ private:
it = ty;
if (DebugTypeInference) {
- foreach (Stmt *s, _defUses.uses(*t)) {
+ for (Stmt *s : _defUses.uses(*t)) {
QBuffer buf;
buf.open(QIODevice::WriteOnly);
QTextStream qout(&buf);
@@ -2605,7 +2605,7 @@ public:
}
PropagateTempTypes propagator(_defUses);
- foreach (const UntypedTemp &t, knownOk) {
+ for (const UntypedTemp &t : qAsConst(knownOk)) {
propagator.run(t, SInt32Type);
if (Stmt *defStmt = _defUses.defStmt(t.temp)) {
if (Move *m = defStmt->asMove()) {
@@ -2629,7 +2629,7 @@ private:
if (uses.isEmpty())
return false;
- foreach (Stmt *use, uses) {
+ for (Stmt *use : uses) {
if (Move *m = use->asMove()) {
Temp *targetTemp = m->target->asTemp();
@@ -3165,7 +3165,8 @@ public:
std::vector<BasicBlock *> backedges;
backedges.reserve(4);
- foreach (BasicBlock *bb, dt.calculateDFNodeIterOrder()) {
+ const auto order = dt.calculateDFNodeIterOrder();
+ for (BasicBlock *bb : order) {
Q_ASSERT(!bb->isRemoved());
backedges.clear();
@@ -3188,12 +3189,12 @@ public:
if (!DebugLoopDetection)
return;
- foreach (LoopInfo *info, loopInfos) {
+ for (const LoopInfo *info : loopInfos) {
qDebug() << "Loop header:" << info->loopHeader->index()
<< "for loop" << quint64(info);
- foreach (BasicBlock *bb, info->loopBody)
+ for (BasicBlock *bb : info->loopBody)
qDebug() << " " << bb->index();
- foreach (LoopInfo *nested, info->nestedLoops)
+ for (LoopInfo *nested : info->nestedLoops)
qDebug() << " sub loop:" << quint64(nested);
qDebug() << " parent loop:" << quint64(info->parentLoop);
}
@@ -3277,15 +3278,15 @@ private:
findLoop(loopHeader)->loopBody.append(bb);
}
- foreach (LoopInfo *info, loopInfos) {
- if (BasicBlock *containingLoopHeader = info->loopHeader->containingGroup())
- findLoop(containingLoopHeader)->addNestedLoop(info);
+ for (int i = 0, size = loopInfos.size(); i < size; ++i) {
+ if (BasicBlock *containingLoopHeader = loopInfos.at(i)->loopHeader->containingGroup())
+ findLoop(containingLoopHeader)->addNestedLoop(loopInfos.at(i));
}
}
LoopInfo *findLoop(BasicBlock *loopHeader)
{
- foreach (LoopInfo *info, loopInfos) {
+ for (LoopInfo *info : qAsConst(loopInfos)) {
if (info->loopHeader == loopHeader)
return info;
}
@@ -3459,8 +3460,8 @@ public:
};
#ifndef QT_NO_DEBUG
-void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
- foreach (BasicBlock *bb, basicBlocks) {
+void checkCriticalEdges(const QVector<BasicBlock *> &basicBlocks) {
+ for (BasicBlock *bb : basicBlocks) {
if (bb && bb->out.size() > 1) {
for (BasicBlock *bb2 : bb->out) {
if (bb2 && bb2->in.size() > 1) {
@@ -3594,7 +3595,7 @@ public:
newUses->reserve(uses.size());
// qout << " " << uses.size() << " uses:"<<endl;
- foreach (Stmt *use, uses) {
+ for (Stmt *use : uses) {
// qout<<" ";use->dump(qout);qout<<"\n";
visit(use);
// qout<<" -> ";use->dump(qout);qout<<"\n";
@@ -3752,7 +3753,7 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
return;
to->in.remove(idx);
- foreach (Stmt *outStmt, to->statements()) {
+ for (Stmt *outStmt : to->statements()) {
if (!outStmt)
continue;
if (Phi *phi = outStmt->asPhi()) {
@@ -3770,7 +3771,7 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
static bool isReachable(BasicBlock *bb, const DominatorTree &dt)
{
- foreach (BasicBlock *in, bb->in) {
+ for (BasicBlock *in : bb->in) {
if (in->isRemoved())
continue;
if (dt.dominates(bb, in)) // a back-edge, not interesting
@@ -3940,13 +3941,13 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
struct Util {
QTextStream &qout;
Util(QTextStream &qout): qout(qout) {}
- void genLoop(LoopDetection::LoopInfo *loop)
+ void genLoop(const LoopDetection::LoopInfo *loop)
{
qout << " subgraph \"cluster" << quint64(loop) << "\" {\n";
qout << " L" << loop->loopHeader->index() << ";\n";
- foreach (BasicBlock *bb, loop->loopBody)
+ for (BasicBlock *bb : loop->loopBody)
qout << " L" << bb->index() << ";\n";
- foreach (LoopDetection::LoopInfo *nested, loop->nestedLoops)
+ for (LoopDetection::LoopInfo *nested : loop->nestedLoops)
genLoop(nested);
qout << " }\n";
}
@@ -3957,7 +3958,7 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
else name = QStringLiteral("%1").arg((unsigned long long)f);
qout << "digraph \"" << name << "\" { ordering=out;\n";
- foreach (LoopDetection::LoopInfo *l, loops) {
+ for (LoopDetection::LoopInfo *l : loops) {
if (l->parentLoop == 0)
Util(qout).genLoop(l);
}
@@ -4461,7 +4462,8 @@ public:
qout << "Life ranges:" << endl;
qout << "Intervals:" << endl;
- foreach (const LifeTimeInterval *range, _sortedIntervals->intervals()) {
+ const auto intervals = _sortedIntervals->intervals();
+ for (const LifeTimeInterval *range : intervals) {
range->dump(qout);
qout << endl;
}
@@ -4721,7 +4723,7 @@ private:
clonedStmt = phi;
phi->targetTemp = clone(p->targetTemp);
- foreach (Expr *in, p->incoming)
+ for (Expr *in : p->incoming)
phi->incoming.append(clone(in));
block->appendStatement(phi);
} else {
@@ -4751,7 +4753,7 @@ public:
void run(const QVector<LoopDetection::LoopInfo *> &loops)
{
- foreach (LoopDetection::LoopInfo *loopInfo, loops)
+ for (LoopDetection::LoopInfo *loopInfo : loops)
peelLoop(loopInfo);
}
@@ -4855,7 +4857,7 @@ private:
// The original loop is now peeled off, and won't jump back to the loop header. Meaning, it
// is not a loop anymore, so unmark it.
loop->loopHeader->markAsGroupStart(false);
- foreach (BasicBlock *bb, loop->loopBody)
+ for (BasicBlock *bb : qAsConst(loop->loopBody))
bb->setContainingGroup(loop->loopHeader->containingGroup());
// calculate the idoms in a separate loop, because addBasicBlock in the previous loop will
@@ -4873,7 +4875,7 @@ private:
}
BasicBlockSet siblings(f);
- foreach (BasicBlock *bb, loopExits)
+ for (BasicBlock *bb : qAsConst(loopExits))
dt.collectSiblings(bb, siblings);
dt.recalculateIDoms(siblings, loop->loopHeader);
@@ -5520,14 +5522,30 @@ LifeTimeIntervals::Ptr Optimizer::lifeTimeIntervals() const
return lifeRanges.intervals();
}
-QSet<Jump *> Optimizer::calculateOptionalJumps()
+static int countPhis(BasicBlock *bb)
{
- QSet<Jump *> optional;
- QSet<BasicBlock *> reachableWithoutJump;
+ int count = 0;
+ for (Stmt *s : bb->statements()) {
+ if (s->isa<Phi>())
+ ++count;
+ else
+ break;
+ }
+ return count;
+}
+
+// Basic blocks can have only 1 terminator. This function returns a bit vector, where a 1 on a
+// certain index indicates that the terminator (jump) at the end of the basic block with that index
+// can be omitted.
+BitVector Optimizer::calculateOptionalJumps()
+{
const int maxSize = function->basicBlockCount();
- optional.reserve(maxSize);
- reachableWithoutJump.reserve(maxSize);
+ BitVector optional(maxSize, false);
+ if (maxSize < 2)
+ return optional;
+
+ BitVector reachableWithoutJump(maxSize, false);
for (int i = maxSize - 1; i >= 0; --i) {
BasicBlock *bb = function->basicBlock(i);
@@ -5535,17 +5553,17 @@ QSet<Jump *> Optimizer::calculateOptionalJumps()
continue;
if (Jump *jump = bb->statements().last()->asJump()) {
- if (reachableWithoutJump.contains(jump->target)) {
- if (bb->statements().size() > 1)
+ if (reachableWithoutJump.at(jump->target->index())) {
+ if (bb->statements().size() - countPhis(bb)> 1)
reachableWithoutJump.clear();
- optional.insert(jump);
- reachableWithoutJump.insert(bb);
+ optional.setBit(bb->index());
+ reachableWithoutJump.setBit(bb->index());
continue;
}
}
reachableWithoutJump.clear();
- reachableWithoutJump.insert(bb);
+ reachableWithoutJump.setBit(bb->index());
}
return optional;
@@ -5644,7 +5662,7 @@ QList<IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, IR::Function *functio
newMoves.reserve(_moves.size());
int insertionPoint = atEnd ? bb->statements().size() - 1 : 0;
- foreach (const Move &m, _moves) {
+ for (const Move &m : _moves) {
IR::Move *move = function->NewStmt<IR::Move>();
move->init(clone(m.to, function), clone(m.from, function));
move->swap = m.needsSwap;
@@ -5663,7 +5681,7 @@ void MoveMapping::dump() const
QTextStream os(&buf);
IRPrinter printer(&os);
os << "Move mapping has " << _moves.size() << " moves..." << endl;
- foreach (const Move &m, _moves) {
+ for (const Move &m : _moves) {
os << "\t";
printer.print(m.to);
if (m.needsSwap)
@@ -5680,8 +5698,8 @@ void MoveMapping::dump() const
MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed,
QList<Move> &output, QList<Move> &swaps) const
{
- Moves usages = sourceUsages(m.to, todo) + sourceUsages(m.to, delayed);
- foreach (const Move &dependency, usages) {
+ const Moves usages = sourceUsages(m.to, todo) + sourceUsages(m.to, delayed);
+ for (const Move &dependency : usages) {
if (!output.contains(dependency)) {
if (delayed.contains(dependency)) {
// We have a cycle! Break it by swapping instead of assigning.
@@ -5692,7 +5710,7 @@ MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QLis
QTextStream out(&buf);
IRPrinter printer(&out);
out<<"we have a cycle! temps:" << endl;
- foreach (const Move &m, delayed) {
+ for (const Move &m : qAsConst(delayed)) {
out<<"\t";
printer.print(m.to);
out<<" <- ";
diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h
index 3a787f0347..db8b6edd1a 100644
--- a/src/qml/compiler/qv4ssa_p.h
+++ b/src/qml/compiler/qv4ssa_p.h
@@ -53,6 +53,7 @@
#include "qv4jsir_p.h"
#include "qv4isel_util_p.h"
+#include <private/qv4util_p.h>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -246,7 +247,7 @@ public:
LifeTimeIntervals::Ptr lifeTimeIntervals() const;
- QSet<IR::Jump *> calculateOptionalJumps();
+ BitVector calculateOptionalJumps();
static void showMeTheCode(Function *function, const char *marker);
@@ -340,7 +341,7 @@ public:
}
protected:
- virtual int allocateFreeSlot()
+ int allocateFreeSlot() override
{
for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) {
if (!_slotIsInUse[i]) {
@@ -357,7 +358,7 @@ protected:
return -1;
}
- virtual void process(IR::Stmt *s)
+ void process(IR::Stmt *s) override
{
// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id);
@@ -411,8 +412,8 @@ protected:
}
}
moves.order();
- QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true);
- foreach (IR::Move *move, newMoves)
+ const QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true);
+ for (IR::Move *move : newMoves)
visit(move);
}
}
@@ -437,13 +438,13 @@ protected:
// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index];
}
- virtual void visitPhi(IR::Phi *phi)
+ void visitPhi(IR::Phi *phi) override
{
Q_UNUSED(phi);
#if !defined(QT_NO_DEBUG)
Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index));
Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]);
- foreach (IR::Expr *e, phi->incoming) {
+ for (IR::Expr *e : phi->incoming) {
if (IR::Temp *t = e->asTemp())
Q_ASSERT(_stackSlotForTemp.contains(t->index));
}
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index b2c4b139ee..15230d75a5 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -84,7 +84,19 @@ QStringList QQmlDebuggingEnabler::inspectorServices()
*/
QStringList QQmlDebuggingEnabler::profilerServices()
{
- return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key;
+ return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key
+ << QDebugMessageService::s_key;
+}
+
+/*!
+ * Retrieves the plugin keys of the debug services designed to be used with a native debugger. The
+ * native debugger will communicate with these services by directly reading and writing the
+ * application's memory.
+ * \return List of plugin keys of debug services designed to be used with a native debugger.
+ */
+QStringList QQmlDebuggingEnabler::nativeDebuggerServices()
+{
+ return QStringList() << QQmlNativeDebugService::s_key;
}
/*!
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index fb41039867..6a0cfdc709 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -60,6 +60,7 @@ struct Q_QML_EXPORT QQmlDebuggingEnabler
static QStringList debuggerServices();
static QStringList inspectorServices();
static QStringList profilerServices();
+ static QStringList nativeDebuggerServices();
static void setServices(const QStringList &services);
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index dd34bb910f..8a16d56c45 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -126,6 +126,16 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
params->instance = loadQQmlDebugConnector(params->pluginKey);
} else if (params->arguments.isEmpty()) {
return 0; // no explicit class name given and no command line arguments
+ } else if (params->arguments.startsWith(QLatin1String("connector:"))) {
+ static const int connectorBegin = int(strlen("connector:"));
+
+ int connectorEnd = params->arguments.indexOf(QLatin1Char(','), connectorBegin);
+ if (connectorEnd == -1)
+ connectorEnd = params->arguments.length();
+
+ params->instance = loadQQmlDebugConnector(params->arguments.mid(
+ connectorBegin,
+ connectorEnd - connectorBegin));
} else {
params->instance = loadQQmlDebugConnector(
params->arguments.startsWith(QLatin1String("native")) ?
@@ -134,9 +144,11 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
}
if (params->instance) {
- foreach (const QJsonObject &object, metaDataForQQmlDebugService()) {
- foreach (const QJsonValue &key, object.value(QLatin1String("MetaData")).toObject()
- .value(QLatin1String("Keys")).toArray()) {
+ const auto metaData = metaDataForQQmlDebugService();
+ for (const QJsonObject &object : metaData) {
+ const auto keys = object.value(QLatin1String("MetaData")).toObject()
+ .value(QLatin1String("Keys")).toArray();
+ for (const QJsonValue &key : keys) {
QString keyString = key.toString();
if (params->services.isEmpty() || params->services.contains(keyString))
loadQQmlDebugService(keyString);
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index ca6293c3ec..2fe3a588c3 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -205,14 +205,14 @@ protected:
class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : public QQmlDebugService
{
Q_OBJECT
+public:
+ static const QString s_key;
protected:
friend class QQmlDebugConnector;
QQmlNativeDebugService(float version, QObject *parent = 0)
: QQmlDebugService(s_key, version, parent) {}
-
- static const QString s_key;
};
#endif
diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
index acd7188db7..fffa783851 100644
--- a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
+++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
@@ -143,7 +143,7 @@ If the string of QML imports files using relative paths, the path should be
relative to the file in which the parent object (the second argument to the
method) is defined.
-\important When building static QML applications, which is enforced on platforms like iOS,
+\important When building static QML applications,
QML files are scanned to detect import dependencies. That way, all
necessary plugins and resources are resolved at compile time.
However, only explicit import statements are considered (those found at
diff --git a/src/qml/doc/src/javascript/functionlist.qdoc b/src/qml/doc/src/javascript/functionlist.qdoc
index b9a25a2440..f5b1ed3cf1 100644
--- a/src/qml/doc/src/javascript/functionlist.qdoc
+++ b/src/qml/doc/src/javascript/functionlist.qdoc
@@ -143,6 +143,8 @@
\li toLocaleString()
\li concat([item1 [, item2 [, ...]]])
\li join(separator)
+ \li find(callbackfn [, thisArg]) // ECMAScript 6: Added in Qt 5.9
+ \li findIndex(callbackfn [, thisArg]) // ECMAScript 6: Added in Qt 5.9
\li pop()
\li push([item1 [, item2 [, ...]]])
\li reverse()
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 8b24d19891..a03c382ed5 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -544,3 +544,15 @@
in order to be found.
*/
+/*!
+ \since 5.9
+ \fn void qmlRegisterModule(const char* uri, int versionMajor, int versionMinor);
+ \relates QQmlEngine
+
+ This function registers a module in a particular \a uri with a version specified
+ in \a versionMajor and \a versionMinor.
+
+ This can be used to make a certain module version available, even if no types
+ are registered for that version. This is particularly useful for keeping the
+ versions of related modules in sync.
+*/
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 6b8264d801..c5d612ae65 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -106,8 +106,7 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput, const Q
{
for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
it != end; ++it) {
- QByteArray ptrString = QByteArray::number(quintptr(it.key()), 16);
- ptrString.prepend("0x");
+ const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
int idx = processedOutput.indexOf(ptrString);
if (idx < 0)
continue;
@@ -184,11 +183,8 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
WTF::setDataFile(new QIODevicePrintStream(&buf));
name = _function->name->toUtf8();
- if (name.isEmpty()) {
- name = QByteArray::number(quintptr(_function), 16);
- name.prepend("IR::Function(0x");
- name.append(')');
- }
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
WTF::setDataFile(stderr);
@@ -225,11 +221,8 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
// this may have been pre-populated, if QV4_SHOW_ASM was on
if (name.isEmpty()) {
name = _function->name->toUtf8();
- if (name.isEmpty()) {
- name = QByteArray::number(quintptr(_function), 16);
- name.prepend("IR::Function(0x");
- name.append(')');
- }
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
}
fprintf(pmap, "%llx %x %.*s\n",
@@ -281,7 +274,7 @@ void InstructionSelection::run(int functionIndex)
IR::Optimizer::showMeTheCode(_function, "After stack slot allocation");
calculateRegistersToSave(Assembler::getRegisterInfo()); // FIXME: this saves all registers. We can probably do with a subset: those that are not used by the register allocator.
}
- QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps();
+ BitVector removableJumps = opt.calculateOptionalJumps();
qSwap(_removableJumps, removableJumps);
Assembler* oldAssembler = _as;
@@ -1412,7 +1405,7 @@ void InstructionSelection::constructValue(IR::Expr *value, IR::ExprList *args, I
void InstructionSelection::visitJump(IR::Jump *s)
{
- if (!_removableJumps.contains(s))
+ if (!_removableJumps.at(_block->index()))
_as->jumpToBlock(_block, s->target);
}
diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h
index b6ddd3c1c9..012745c5f2 100644
--- a/src/qml/jit/qv4isel_masm_p.h
+++ b/src/qml/jit/qv4isel_masm_p.h
@@ -54,6 +54,7 @@
#include "private/qv4jsir_p.h"
#include "private/qv4isel_p.h"
#include "private/qv4isel_util_p.h"
+#include "private/qv4util_p.h"
#include "private/qv4value_p.h"
#include "private/qv4lookup_p.h"
@@ -79,61 +80,61 @@ public:
InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory);
~InstructionSelection();
- virtual void run(int functionIndex);
+ void run(int functionIndex) override;
protected:
- virtual QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep();
-
- virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result);
- virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result);
- virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result);
- virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result);
- virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result);
- virtual void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result);
- virtual void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result);
- virtual void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result);
- virtual void callBuiltinDeleteName(const QString &name, IR::Expr *result);
- virtual void callBuiltinDeleteValue(IR::Expr *result);
- virtual void callBuiltinThrow(IR::Expr *arg);
- virtual void callBuiltinReThrow();
- virtual void callBuiltinUnwindException(IR::Expr *);
- virtual void callBuiltinPushCatchScope(const QString &exceptionName);
- virtual void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result);
- virtual void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result);
- virtual void callBuiltinPushWithScope(IR::Expr *arg);
- virtual void callBuiltinPopScope();
- virtual void callBuiltinDeclareVar(bool deletable, const QString &name);
- virtual void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args);
- virtual void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray);
- virtual void callBuiltinSetupArgumentObject(IR::Expr *result);
- virtual void callBuiltinConvertThisToObject();
- virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
- virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result);
- virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result);
- virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result);
- virtual void convertType(IR::Expr *source, IR::Expr *target);
- virtual void loadThisObject(IR::Expr *temp);
- virtual void loadQmlContext(IR::Expr *target);
- virtual void loadQmlImportedScripts(IR::Expr *target);
- virtual void loadQmlSingleton(const QString &name, IR::Expr *target);
- virtual void loadConst(IR::Const *sourceConst, IR::Expr *target);
- virtual void loadString(const QString &str, IR::Expr *target);
- virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target);
- virtual void getActivationProperty(const IR::Name *name, IR::Expr *target);
- virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
- virtual void initClosure(IR::Closure *closure, IR::Expr *target);
- virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target);
- virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target);
- virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target);
- virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName);
- virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex);
- virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex);
- virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target);
- virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex);
- virtual void copyValue(IR::Expr *source, IR::Expr *target);
- virtual void swapValues(IR::Expr *source, IR::Expr *target);
- virtual void unop(IR::AluOp oper, IR::Expr *sourceTemp, IR::Expr *target);
- virtual void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep() override;
+
+ void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
+ void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) override;
+ void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
+ void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
+ void callBuiltinTypeofName(const QString &name, IR::Expr *result) override;
+ void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result) override;
+ void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
+ void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
+ void callBuiltinDeleteName(const QString &name, IR::Expr *result) override;
+ void callBuiltinDeleteValue(IR::Expr *result) override;
+ void callBuiltinThrow(IR::Expr *arg) override;
+ void callBuiltinReThrow() override;
+ void callBuiltinUnwindException(IR::Expr *) override;
+ void callBuiltinPushCatchScope(const QString &exceptionName) override;
+ void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result) override;
+ void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result) override;
+ void callBuiltinPushWithScope(IR::Expr *arg) override;
+ void callBuiltinPopScope() override;
+ void callBuiltinDeclareVar(bool deletable, const QString &name) override;
+ void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args) override;
+ void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray) override;
+ void callBuiltinSetupArgumentObject(IR::Expr *result) override;
+ void callBuiltinConvertThisToObject() override;
+ void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
+ void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) override;
+ void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
+ void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) override;
+ void convertType(IR::Expr *source, IR::Expr *target) override;
+ void loadThisObject(IR::Expr *temp) override;
+ void loadQmlContext(IR::Expr *target) override;
+ void loadQmlImportedScripts(IR::Expr *target) override;
+ void loadQmlSingleton(const QString &name, IR::Expr *target) override;
+ void loadConst(IR::Const *sourceConst, IR::Expr *target) override;
+ void loadString(const QString &str, IR::Expr *target) override;
+ void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target) override;
+ void getActivationProperty(const IR::Name *name, IR::Expr *target) override;
+ void setActivationProperty(IR::Expr *source, const QString &targetName) override;
+ void initClosure(IR::Closure *closure, IR::Expr *target) override;
+ void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) override;
+ void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target) override;
+ void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) override;
+ void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) override;
+ void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) override;
+ void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) override;
+ void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) override;
+ void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override;
+ void copyValue(IR::Expr *source, IR::Expr *target) override;
+ void swapValues(IR::Expr *source, IR::Expr *target) override;
+ void unop(IR::AluOp oper, IR::Expr *sourceTemp, IR::Expr *target) override;
+ void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) override;
typedef Assembler::Address Address;
typedef Assembler::Pointer Pointer;
@@ -158,13 +159,13 @@ protected:
return _as->stackLayout().callDataAddress();
}
- virtual void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result);
- virtual void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr*result);
- virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result);
+ void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
+ void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr*result) override;
+ void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
- virtual void visitJump(IR::Jump *);
- virtual void visitCJump(IR::CJump *);
- virtual void visitRet(IR::Ret *);
+ void visitJump(IR::Jump *) override;
+ void visitCJump(IR::CJump *) override;
+ void visitRet(IR::Ret *) override;
bool visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Expr *right,
IR::BasicBlock *iftrue, IR::BasicBlock *iffalse);
@@ -272,7 +273,7 @@ private:
}
IR::BasicBlock *_block;
- QSet<IR::Jump *> _removableJumps;
+ BitVector _removableJumps;
Assembler* _as;
QScopedPointer<CompilationUnit> compilationUnit;
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 406b9096ea..63d542b5c8 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -272,32 +272,32 @@ public:
}
protected: // IRDecoder
- virtual void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) {}
- virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) {}
- virtual void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) {}
- virtual void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinTypeofName(const QString &, IR::Expr *) {}
- virtual void callBuiltinTypeofValue(IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinDeleteMember(IR::Expr *, const QString &, IR::Expr *) {}
- virtual void callBuiltinDeleteSubscript(IR::Expr *, IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinDeleteName(const QString &, IR::Expr *) {}
- virtual void callBuiltinDeleteValue(IR::Expr *) {}
- virtual void callBuiltinThrow(IR::Expr *) {}
- virtual void callBuiltinReThrow() {}
- virtual void callBuiltinUnwindException(IR::Expr *) {}
- virtual void callBuiltinPushCatchScope(const QString &) {};
- virtual void callBuiltinForeachIteratorObject(IR::Expr *, IR::Expr *) {}
+ void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) override {}
+ void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) override {}
+ void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) override {}
+ void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
+ void callBuiltinTypeofName(const QString &, IR::Expr *) override {}
+ void callBuiltinTypeofValue(IR::Expr *, IR::Expr *) override {}
+ void callBuiltinDeleteMember(IR::Expr *, const QString &, IR::Expr *) override {}
+ void callBuiltinDeleteSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
+ void callBuiltinDeleteName(const QString &, IR::Expr *) override {}
+ void callBuiltinDeleteValue(IR::Expr *) override {}
+ void callBuiltinThrow(IR::Expr *) override {}
+ void callBuiltinReThrow() override {}
+ void callBuiltinUnwindException(IR::Expr *) override {}
+ void callBuiltinPushCatchScope(const QString &) override {};
+ void callBuiltinForeachIteratorObject(IR::Expr *, IR::Expr *) override {}
virtual void callBuiltinForeachNextProperty(IR::Temp *, IR::Temp *) {}
- virtual void callBuiltinForeachNextPropertyname(IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinPushWithScope(IR::Expr *) {}
- virtual void callBuiltinPopScope() {}
- virtual void callBuiltinDeclareVar(bool , const QString &) {}
- virtual void callBuiltinDefineArray(IR::Expr *, IR::ExprList *) {}
- virtual void callBuiltinDefineObjectLiteral(IR::Expr *, int, IR::ExprList *, IR::ExprList *, bool) {}
- virtual void callBuiltinSetupArgumentObject(IR::Expr *) {}
- virtual void callBuiltinConvertThisToObject() {}
+ void callBuiltinForeachNextPropertyname(IR::Expr *, IR::Expr *) override {}
+ void callBuiltinPushWithScope(IR::Expr *) override {}
+ void callBuiltinPopScope() override {}
+ void callBuiltinDeclareVar(bool , const QString &) override {}
+ void callBuiltinDefineArray(IR::Expr *, IR::ExprList *) override {}
+ void callBuiltinDefineObjectLiteral(IR::Expr *, int, IR::ExprList *, IR::ExprList *, bool) override {}
+ void callBuiltinSetupArgumentObject(IR::Expr *) override {}
+ void callBuiltinConvertThisToObject() override {}
- virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
+ void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
if (IR::Temp *tempValue = value->asTemp())
@@ -306,7 +306,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex, IR::ExprList *args, IR::Expr *result)
+ void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex,
+ IR::ExprList *args, IR::Expr *result) override
{
Q_UNUSED(propertyIndex)
@@ -316,8 +317,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
- IR::Expr *result)
+ void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
+ IR::Expr *result) override
{
Q_UNUSED(name)
@@ -327,8 +328,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
- IR::Expr *result)
+ void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
+ IR::Expr *result) override
{
addDef(result);
addUses(base->asTemp(), Use::CouldHaveRegister);
@@ -337,7 +338,7 @@ protected: // IRDecoder
addCall();
}
- virtual void convertType(IR::Expr *source, IR::Expr *target)
+ void convertType(IR::Expr *source, IR::Expr *target) override
{
addDef(target);
@@ -410,14 +411,14 @@ protected: // IRDecoder
addHint(target->asTemp(), sourceTemp);
}
- virtual void constructActivationProperty(IR::Name *, IR::ExprList *args, IR::Expr *result)
+ void constructActivationProperty(IR::Name *, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(args, Use::CouldHaveRegister);
addCall();
}
- virtual void constructProperty(IR::Expr *base, const QString &, IR::ExprList *args, IR::Expr *result)
+ void constructProperty(IR::Expr *base, const QString &, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(base, Use::CouldHaveRegister);
@@ -425,7 +426,7 @@ protected: // IRDecoder
addCall();
}
- virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
+ void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(value, Use::CouldHaveRegister);
@@ -433,24 +434,24 @@ protected: // IRDecoder
addCall();
}
- virtual void loadThisObject(IR::Expr *temp)
+ void loadThisObject(IR::Expr *temp) override
{
addDef(temp);
}
- virtual void loadQmlContext(IR::Expr *temp)
+ void loadQmlContext(IR::Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void loadQmlImportedScripts(IR::Expr *temp)
+ void loadQmlImportedScripts(IR::Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void loadQmlSingleton(const QString &/*name*/, Expr *temp)
+ void loadQmlSingleton(const QString &/*name*/, Expr *temp) override
{
Q_UNUSED(temp);
@@ -458,21 +459,21 @@ protected: // IRDecoder
addCall();
}
- virtual void loadConst(IR::Const *sourceConst, Expr *targetTemp)
+ void loadConst(IR::Const *sourceConst, Expr *targetTemp) override
{
Q_UNUSED(sourceConst);
addDef(targetTemp);
}
- virtual void loadString(const QString &str, Expr *targetTemp)
+ void loadString(const QString &str, Expr *targetTemp) override
{
Q_UNUSED(str);
addDef(targetTemp);
}
- virtual void loadRegexp(IR::RegExp *sourceRegexp, Expr *targetTemp)
+ void loadRegexp(IR::RegExp *sourceRegexp, Expr *targetTemp) override
{
Q_UNUSED(sourceRegexp);
@@ -480,19 +481,19 @@ protected: // IRDecoder
addCall();
}
- virtual void getActivationProperty(const IR::Name *, Expr *temp)
+ void getActivationProperty(const IR::Name *, Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void setActivationProperty(IR::Expr *source, const QString &)
+ void setActivationProperty(IR::Expr *source, const QString &) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void initClosure(IR::Closure *closure, Expr *target)
+ void initClosure(IR::Closure *closure, Expr *target) override
{
Q_UNUSED(closure);
@@ -500,49 +501,52 @@ protected: // IRDecoder
addCall();
}
- virtual void getProperty(IR::Expr *base, const QString &, Expr *target)
+ void getProperty(IR::Expr *base, const QString &, Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &)
+ void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind /*kind*/, int /*propertyIndex*/)
+ void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase,
+ IR::Member::MemberKind /*kind*/, int /*propertyIndex*/) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/)
+ void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/, bool /*captureRequired*/, IR::Expr *target)
+ void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/,
+ bool /*captureRequired*/, IR::Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target)
+ void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/,
+ bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getElement(IR::Expr *base, IR::Expr *index, Expr *target)
+ void getElement(IR::Expr *base, IR::Expr *index, Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
@@ -550,7 +554,7 @@ protected: // IRDecoder
addCall();
}
- virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex)
+ void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
@@ -558,7 +562,7 @@ protected: // IRDecoder
addCall();
}
- virtual void copyValue(Expr *source, Expr *target)
+ void copyValue(Expr *source, Expr *target) override
{
addDef(target);
Temp *sourceTemp = source->asTemp();
@@ -570,13 +574,13 @@ protected: // IRDecoder
addHint(targetTemp, sourceTemp);
}
- virtual void swapValues(Expr *, Expr *)
+ void swapValues(Expr *, Expr *) override
{
// Inserted by the register allocator, so it cannot occur here.
Q_UNREACHABLE();
}
- virtual void unop(AluOp oper, Expr *source, Expr *target)
+ void unop(AluOp oper, Expr *source, Expr *target) override
{
addDef(target);
@@ -612,7 +616,7 @@ protected: // IRDecoder
}
}
- virtual void binop(AluOp oper, Expr *leftSource, Expr *rightSource, Expr *target)
+ void binop(AluOp oper, Expr *leftSource, Expr *rightSource, Expr *target) override
{
bool needsCall = true;
@@ -675,8 +679,8 @@ protected: // IRDecoder
}
}
- virtual void visitJump(IR::Jump *) {}
- virtual void visitCJump(IR::CJump *s)
+ void visitJump(IR::Jump *) override {}
+ void visitCJump(IR::CJump *s) override
{
if (Temp *t = s->cond->asTemp()) {
#if 0 // TODO: change masm to generate code
@@ -696,10 +700,10 @@ protected: // IRDecoder
}
}
- virtual void visitRet(IR::Ret *s)
+ void visitRet(IR::Ret *s) override
{ addUses(s->expr->asTemp(), Use::CouldHaveRegister); }
- virtual void visitPhi(IR::Phi *s)
+ void visitPhi(IR::Phi *s) override
{
addDef(s->targetTemp, true);
for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
@@ -716,7 +720,7 @@ protected: // IRDecoder
}
protected:
- virtual void callBuiltin(IR::Call *c, IR::Expr *result)
+ void callBuiltin(IR::Call *c, IR::Expr *result) override
{
addDef(result);
addUses(c->base, Use::CouldHaveRegister);
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 0c55200c64..919524d1ed 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -83,7 +83,6 @@ HEADERS += \
$$PWD/qv4serialize_p.h \
$$PWD/qv4script_p.h \
$$PWD/qv4scopedvalue_p.h \
- $$PWD/qv4util_p.h \
$$PWD/qv4executableallocator_p.h \
$$PWD/qv4sequenceobject_p.h \
$$PWD/qv4include_p.h \
@@ -108,6 +107,7 @@ HEADERS += \
$$PWD/qv4runtimeapi_p.h \
$$PWD/qv4value_p.h \
$$PWD/qv4string_p.h \
+ $$PWD/qv4util_p.h \
$$PWD/qv4value_p.h
SOURCES += \
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 659ede7552..20ba11fd75 100644
--- a/