summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation/backend/abstractevaluateclipanimatorjob.cpp5
-rw-r--r--src/animation/backend/animationclip.cpp2
-rw-r--r--src/animation/backend/buildblendtreesjob.cpp3
-rw-r--r--src/animation/backend/channelmapping.cpp7
-rw-r--r--src/animation/backend/evaluateblendclipanimatorjob.cpp1
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp1
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob.cpp3
-rw-r--r--src/animation/backend/gltfimporter.cpp10
-rw-r--r--src/animation/backend/loadanimationclipjob.cpp1
-rw-r--r--src/animation/backend/skeleton.cpp1
-rw-r--r--src/animation/frontend/qabstractanimationclip.cpp8
-rw-r--r--src/animation/frontend/qabstractanimationclip.h3
-rw-r--r--src/animation/frontend/qabstractchannelmapping.cpp1
-rw-r--r--src/animation/frontend/qabstractclipanimator.cpp5
-rw-r--r--src/animation/frontend/qabstractclipanimator.h2
-rw-r--r--src/animation/frontend/qanimationcallback.qdoc51
-rw-r--r--src/animation/frontend/qanimationclip.cpp4
-rw-r--r--src/animation/frontend/qanimationclipdata.cpp2
-rw-r--r--src/animation/frontend/qanimationcliploader.cpp6
-rw-r--r--src/animation/frontend/qanimationcliploader.h2
-rw-r--r--src/animation/frontend/qcallbackmapping.cpp3
-rw-r--r--src/animation/frontend/qchannel.cpp2
-rw-r--r--src/animation/frontend/qchannelmapper.cpp2
-rw-r--r--src/animation/frontend/qchannelmapping.cpp2
-rw-r--r--src/animation/frontend/qclipanimator.cpp3
-rw-r--r--src/animation/frontend/qclipblendvalue.cpp4
-rw-r--r--src/animation/frontend/qmorphtarget.cpp4
-rw-r--r--src/animation/frontend/qvertexblendanimation.cpp4
-rw-r--r--src/core/aspects/aspectcommanddebugger.cpp20
-rw-r--r--src/core/aspects/aspectcommanddebugger_p.h18
-rw-r--r--src/core/aspects/aspects.pri10
-rw-r--r--src/core/aspects/qabstractaspect.cpp21
-rw-r--r--src/core/aspects/qabstractaspect.h3
-rw-r--r--src/core/aspects/qabstractaspect_p.h2
-rw-r--r--src/core/aspects/qaspectengine.cpp24
-rw-r--r--src/core/aspects/qaspectengine_p.h10
-rw-r--r--src/core/aspects/qaspectmanager.cpp106
-rw-r--r--src/core/aspects/qaspectmanager_p.h9
-rw-r--r--src/core/changes/qcomponentaddedchange.h10
-rw-r--r--src/core/changes/qcomponentremovedchange.h10
-rw-r--r--src/core/changes/qdynamicpropertyupdatedchange.h4
-rw-r--r--src/core/changes/qnodecommand.h4
-rw-r--r--src/core/changes/qnodecreatedchange.h6
-rw-r--r--src/core/changes/qnodedestroyedchange.h4
-rw-r--r--src/core/changes/qpropertynodeaddedchange.h4
-rw-r--r--src/core/changes/qpropertynoderemovedchange.h4
-rw-r--r--src/core/changes/qpropertyupdatedchange.h4
-rw-r--r--src/core/changes/qpropertyupdatedchangebase.h4
-rw-r--r--src/core/changes/qpropertyvalueaddedchange.h4
-rw-r--r--src/core/changes/qpropertyvalueaddedchangebase.h6
-rw-r--r--src/core/changes/qpropertyvalueremovedchange.h4
-rw-r--r--src/core/changes/qpropertyvalueremovedchangebase.h6
-rw-r--r--src/core/changes/qscenechange.cpp1
-rw-r--r--src/core/changes/qscenechange.h18
-rw-r--r--src/core/changes/qscenechange_p.h7
-rw-r--r--src/core/changes/qskeletoncreatedchange_p.h6
-rw-r--r--src/core/changes/qstaticpropertyupdatedchangebase.h6
-rw-r--r--src/core/changes/qstaticpropertyvalueaddedchangebase.h2
-rw-r--r--src/core/changes/qstaticpropertyvalueremovedchangebase.h2
-rw-r--r--src/core/configure.json3
-rw-r--r--src/core/jobs/qaspectjob_p.h67
-rw-r--r--src/core/jobs/qaspectjobmanager.cpp14
-rw-r--r--src/core/jobs/qaspectjobmanager_p.h4
-rw-r--r--src/core/jobs/qaspectjobproviderinterface_p.h2
-rw-r--r--src/core/jobs/qthreadpooler.cpp128
-rw-r--r--src/core/jobs/qthreadpooler_p.h17
-rw-r--r--src/core/jobs/task.cpp21
-rw-r--r--src/core/jobs/task_p.h4
-rw-r--r--src/core/nodes/qbackendnode.cpp12
-rw-r--r--src/core/nodes/qbackendnode.h12
-rw-r--r--src/core/nodes/qentity.cpp2
-rw-r--r--src/core/nodes/qnode.cpp29
-rw-r--r--src/core/nodes/qnode.h12
-rw-r--r--src/core/nodes/qnode_p.h21
-rw-r--r--src/core/qchangearbiter_p.h1
-rw-r--r--src/core/qpostman_p.h2
-rw-r--r--src/core/qscheduler.cpp16
-rw-r--r--src/core/qscheduler_p.h4
-rw-r--r--src/core/qt3dcore_global.h6
-rw-r--r--src/core/resources/qframeallocator.cpp2
-rw-r--r--src/core/resources/qloadgltf_p.h80
-rw-r--r--src/core/resources/resources.pri1
-rw-r--r--src/core/services/nullservices_p.h14
-rw-r--r--src/core/services/qservicelocator.cpp16
-rw-r--r--src/core/services/qservicelocator_p.h3
-rw-r--r--src/core/services/qsysteminformationservice.cpp302
-rw-r--r--src/core/services/qsysteminformationservice_p.h24
-rw-r--r--src/core/services/qsysteminformationservice_p_p.h87
-rw-r--r--src/core/transforms/qabstractskeleton.cpp19
-rw-r--r--src/core/transforms/qabstractskeleton.h3
-rw-r--r--src/core/transforms/qskeletonloader.cpp50
-rw-r--r--src/core/transforms/qskeletonloader_p.h1
-rw-r--r--src/core/transforms/qtransform.cpp1
-rw-r--r--src/core/transforms/qtransform.h1
-rw-r--r--src/core/transforms/sqt_p.h2
-rw-r--r--src/doc/src/qmlextramaterials.qdoc35
-rw-r--r--src/extras/defaults/qabstractspritesheet.cpp2
-rw-r--r--src/extras/defaults/qt3dwindow.cpp2
-rw-r--r--src/extras/shaders/es2/distancefieldtext.frag2
-rw-r--r--src/extras/shaders/gl3/distancefieldtext.frag2
-rw-r--r--src/extras/text/qtext2dentity.cpp13
-rw-r--r--src/input/backend/keyboardeventfilter.cpp1
-rw-r--r--src/input/backend/keyboardhandler.cpp1
-rw-r--r--src/input/backend/mouseeventfilter.cpp1
-rw-r--r--src/input/backend/mousehandler.cpp1
-rw-r--r--src/input/frontend/qabstractphysicaldeviceproxy.cpp1
-rw-r--r--src/input/frontend/qaction.cpp6
-rw-r--r--src/input/frontend/qaction.h4
-rw-r--r--src/input/frontend/qactioninput.cpp2
-rw-r--r--src/input/frontend/qaxis.cpp6
-rw-r--r--src/input/frontend/qaxis.h4
-rw-r--r--src/input/frontend/qaxisaccumulator.cpp6
-rw-r--r--src/input/frontend/qaxisaccumulator.h4
-rw-r--r--src/input/frontend/qkeyboarddevice.cpp12
-rw-r--r--src/input/frontend/qkeyboarddevice.h1
-rw-r--r--src/input/frontend/qkeyboardhandler.cpp6
-rw-r--r--src/input/frontend/qkeyboardhandler.h4
-rw-r--r--src/input/frontend/qkeyevent.cpp6
-rw-r--r--src/input/frontend/qmouseevent.cpp6
-rw-r--r--src/input/frontend/qmouseevent.h15
-rw-r--r--src/input/frontend/qmousehandler.cpp12
-rw-r--r--src/input/frontend/qmousehandler.h2
-rw-r--r--src/input/frontend/qphysicaldevicecreatedchange.cpp2
-rw-r--r--src/logic/callbackjob.cpp2
-rw-r--r--src/logic/manager.cpp2
-rw-r--r--src/plugins/geometryloaders/gltf/gltfgeometryloader.cpp11
-rw-r--r--src/plugins/sceneparsers/gltf/gltfimporter.cpp14
-rw-r--r--src/quick3d/imports/animation/plugins.qmltypes55
-rw-r--r--src/quick3d/imports/core/plugins.qmltypes73
-rw-r--r--src/quick3d/imports/extras/plugins.qmltypes55
-rw-r--r--src/quick3d/imports/input/plugins.qmltypes2
-rw-r--r--src/quick3d/imports/logic/plugins.qmltypes2
-rw-r--r--src/quick3d/imports/render/plugins.qmltypes255
-rw-r--r--src/quick3d/imports/scene2d/plugins.qmltypes2
-rw-r--r--src/quick3d/imports/scene3d/plugins.qmltypes38
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp81
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp23
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer_p.h3
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp1
-rw-r--r--src/quick3d/imports/scene3d/scene3dview.cpp2
-rw-r--r--src/quick3d/quick3d/qquaternionanimation.cpp2
-rw-r--r--src/quick3d/quick3dextras/qt3dquickwindow.cpp2
-rw-r--r--src/quick3d/quick3dscene2d/items/qscene2d.cpp6
-rw-r--r--src/quick3d/quick3dscene2d/items/qscene2d.h5
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2d.cpp16
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2dsharedobject.cpp1
-rw-r--r--src/render/backend/abstractrenderer_p.h4
-rw-r--r--src/render/backend/bufferutils_p.h4
-rw-r--r--src/render/backend/cameralens.cpp60
-rw-r--r--src/render/backend/cameralens_p.h7
-rw-r--r--src/render/backend/commandexecuter.cpp20
-rw-r--r--src/render/backend/computecommand.cpp29
-rw-r--r--src/render/backend/computecommand_p.h3
-rw-r--r--src/render/backend/render-backend.pri13
-rw-r--r--src/render/backend/rendersettings.cpp18
-rw-r--r--src/render/backend/segmentsvisitor.cpp52
-rw-r--r--src/render/backend/stringtoint.cpp39
-rw-r--r--src/render/backend/transform.cpp1
-rw-r--r--src/render/backend/trianglesvisitor.cpp11
-rw-r--r--src/render/backend/uniform_p.h4
-rw-r--r--src/render/backend/visitorutils_p.h2
-rw-r--r--src/render/framegraph/qblitframebuffer.cpp4
-rw-r--r--src/render/framegraph/qbuffercapture.cpp12
-rw-r--r--src/render/framegraph/qrendercapture.cpp4
-rw-r--r--src/render/framegraph/qsetfence.cpp9
-rw-r--r--src/render/framegraph/qwaitfence.cpp12
-rw-r--r--src/render/framegraph/rendercapture.cpp26
-rw-r--r--src/render/framegraph/rendercapture_p.h2
-rw-r--r--src/render/framegraph/subtreeenabler.cpp18
-rw-r--r--src/render/frontend/qcamera.cpp2
-rw-r--r--src/render/frontend/qcameralens.cpp38
-rw-r--r--src/render/frontend/qcameralens_p.h21
-rw-r--r--src/render/frontend/qcomputecommand.cpp6
-rw-r--r--src/render/frontend/qlevelofdetail.cpp5
-rw-r--r--src/render/frontend/qlevelofdetail.h2
-rw-r--r--src/render/frontend/qlevelofdetailswitch.cpp6
-rw-r--r--src/render/frontend/qlevelofdetailswitch.h2
-rw-r--r--src/render/frontend/qrenderaspect.cpp18
-rw-r--r--src/render/frontend/qrenderaspect_p.h2
-rw-r--r--src/render/frontend/qrendersettings.cpp14
-rw-r--r--src/render/frontend/qrendersettings.h1
-rw-r--r--src/render/frontend/sphere.cpp48
-rw-r--r--src/render/geometry/buffer.cpp44
-rw-r--r--src/render/geometry/geometryrenderer.cpp10
-rw-r--r--src/render/geometry/gltfskeletonloader.cpp8
-rw-r--r--src/render/geometry/qbuffer.cpp40
-rw-r--r--src/render/geometry/qbuffer.h7
-rw-r--r--src/render/geometry/qbuffer_p.h2
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp5
-rw-r--r--src/render/geometry/qgeometryrenderer.h2
-rw-r--r--src/render/geometry/qmesh.cpp27
-rw-r--r--src/render/geometry/qmesh.h2
-rw-r--r--src/render/geometry/skeleton.cpp2
-rw-r--r--src/render/io/qsceneloader.cpp8
-rw-r--r--src/render/io/qsceneloader.h2
-rw-r--r--src/render/io/scene.cpp4
-rw-r--r--src/render/jobs/abstractpickingjob.cpp2
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp2
-rw-r--r--src/render/jobs/calcgeometrytrianglevolumes.cpp2
-rw-r--r--src/render/jobs/computefilteredboundingvolumejob.cpp37
-rw-r--r--src/render/jobs/computefilteredboundingvolumejob_p.h4
-rw-r--r--src/render/jobs/expandboundingvolumejob.cpp6
-rw-r--r--src/render/jobs/filterentitybycomponentjob_p.h6
-rw-r--r--src/render/jobs/filterlayerentityjob.cpp2
-rw-r--r--src/render/jobs/filterproximitydistancejob.cpp6
-rw-r--r--src/render/jobs/framecleanupjob.cpp2
-rw-r--r--src/render/jobs/frustumcullingjob.cpp2
-rw-r--r--src/render/jobs/genericlambdajob_p.h4
-rw-r--r--src/render/jobs/job_common_p.h10
-rw-r--r--src/render/jobs/jobs.pri2
-rw-r--r--src/render/jobs/lightgatherer.cpp5
-rw-r--r--src/render/jobs/loadbufferjob.cpp32
-rw-r--r--src/render/jobs/loadbufferjob_p.h4
-rw-r--r--src/render/jobs/loadgeometryjob.cpp2
-rw-r--r--src/render/jobs/loadscenejob.cpp2
-rw-r--r--src/render/jobs/loadskeletonjob.cpp2
-rw-r--r--src/render/jobs/sendbuffercapturejob.cpp68
-rw-r--r--src/render/jobs/sendbuffercapturejob_p.h10
-rw-r--r--src/render/jobs/sendrendercapturejob.cpp86
-rw-r--r--src/render/jobs/sendrendercapturejob_p.h90
-rw-r--r--src/render/jobs/updateentitylayersjob.cpp2
-rw-r--r--src/render/jobs/updatemeshtrianglelistjob.cpp2
-rw-r--r--src/render/jobs/updateshaderdatatransformjob.cpp2
-rw-r--r--src/render/jobs/updateskinningpalettejob.cpp2
-rw-r--r--src/render/jobs/updatetreeenabledjob.cpp3
-rw-r--r--src/render/jobs/updateworldboundingvolumejob.cpp4
-rw-r--r--src/render/jobs/updateworldtransformjob.cpp13
-rw-r--r--src/render/lights/qdirectionallight.cpp10
-rw-r--r--src/render/lights/qenvironmentlight.cpp12
-rw-r--r--src/render/lights/qpointlight.cpp30
-rw-r--r--src/render/lights/qspotlight.cpp50
-rw-r--r--src/render/materialsystem/qshaderimage.cpp25
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder.cpp5
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder.h2
-rw-r--r--src/render/materialsystem/shader.cpp71
-rw-r--r--src/render/materialsystem/shader_p.h26
-rw-r--r--src/render/picking/qabstractraycaster.cpp4
-rw-r--r--src/render/picking/qobjectpicker.cpp7
-rw-r--r--src/render/picking/qobjectpicker.h4
-rw-r--r--src/render/picking/qobjectpicker_p.h1
-rw-r--r--src/render/picking/raycaster.cpp1
-rw-r--r--src/render/raycasting/qcollisionqueryresult.cpp1
-rw-r--r--src/render/raycasting/qcollisionqueryresult_p.h2
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp10
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp28
-rw-r--r--src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp2
-rw-r--r--src/render/renderers/opengl/jobs/jobs.pri6
-rw-r--r--src/render/renderers/opengl/jobs/materialparametergathererjob.cpp2
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp81
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h (renamed from src/render/renderers/opengl/jobs/renderviewbuilderjob_p.h)38
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp (renamed from src/render/renderers/opengl/jobs/renderviewbuilderjob.cpp)24
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h103
-rw-r--r--src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp2
-rw-r--r--src/render/renderers/opengl/jobs/renderviewjobutils.cpp28
-rw-r--r--src/render/renderers/opengl/renderer/rendercommand.cpp15
-rw-r--r--src/render/renderers/opengl/renderer/rendercommand_p.h52
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp452
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h50
-rw-r--r--src/render/renderers/opengl/renderer/renderercache_p.h13
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp693
-rw-r--r--src/render/renderers/opengl/renderer/renderview_p.h23
-rw-r--r--src/render/renderers/opengl/renderer/renderviewbuilder.cpp586
-rw-r--r--src/render/renderers/opengl/renderer/renderviewbuilder_p.h56
-rw-r--r--src/render/renderers/opengl/renderer/shaderparameterpack.cpp1
-rw-r--r--src/render/renderers/opengl/renderer/shaderparameterpack_p.h51
-rw-r--r--src/render/renderers/opengl/textures/gltexture.cpp22
-rw-r--r--src/render/renderstates/qrastermode.cpp4
-rw-r--r--src/render/services/vsyncframeadvanceservice.cpp11
-rw-r--r--src/render/texture/qabstracttexture.cpp18
-rw-r--r--src/render/texture/qabstracttextureimage.cpp4
-rw-r--r--src/render/texture/qtexture.cpp18
-rw-r--r--src/render/texture/qtexturegenerator.cpp3
-rw-r--r--src/render/texture/texture.cpp10
273 files changed, 3729 insertions, 2302 deletions
diff --git a/src/animation/backend/abstractevaluateclipanimatorjob.cpp b/src/animation/backend/abstractevaluateclipanimatorjob.cpp
index 236a96efe..5267d4526 100644
--- a/src/animation/backend/abstractevaluateclipanimatorjob.cpp
+++ b/src/animation/backend/abstractevaluateclipanimatorjob.cpp
@@ -53,13 +53,8 @@ public:
void postFrame(Qt3DCore::QAspectManager *manager) override;
- Q_DECLARE_PUBLIC(AbstractEvaluateClipAnimatorJob)
-
AnimationRecord m_record;
QVector<AnimationCallbackAndValue> m_callbacks;
-
-private:
- AbstractEvaluateClipAnimatorJob *q_ptr;
};
AbstractEvaluateClipAnimatorJob::AbstractEvaluateClipAnimatorJob()
diff --git a/src/animation/backend/animationclip.cpp b/src/animation/backend/animationclip.cpp
index 2dea81b52..2c7e4fffb 100644
--- a/src/animation/backend/animationclip.cpp
+++ b/src/animation/backend/animationclip.cpp
@@ -68,6 +68,7 @@ AnimationClip::AnimationClip()
, m_name()
, m_channels()
, m_duration(0.0f)
+ , m_channelComponentCount(0)
{
}
@@ -81,6 +82,7 @@ void AnimationClip::cleanup()
m_dataType = Unknown;
m_channels.clear();
m_duration = 0.0f;
+ m_channelComponentCount = 0;
clearData();
}
diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp
index 3cfa81446..b4cc04323 100644
--- a/src/animation/backend/buildblendtreesjob.cpp
+++ b/src/animation/backend/buildblendtreesjob.cpp
@@ -50,8 +50,9 @@ namespace Animation {
BuildBlendTreesJob::BuildBlendTreesJob()
: Qt3DCore::QAspectJob()
+ , m_handler(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::BuildBlendTree, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::BuildBlendTree, 0)
}
void BuildBlendTreesJob::setBlendedClipAnimators(const QVector<HBlendedClipAnimator> &blendedClipAnimatorHandles)
diff --git a/src/animation/backend/channelmapping.cpp b/src/animation/backend/channelmapping.cpp
index 83e7322da..1e3aa76f0 100644
--- a/src/animation/backend/channelmapping.cpp
+++ b/src/animation/backend/channelmapping.cpp
@@ -59,7 +59,6 @@ ChannelMapping::ChannelMapping()
, m_componentCount(0)
, m_propertyName(nullptr)
, m_callback(nullptr)
- , m_callbackFlags(0)
, m_skeletonId()
, m_mappingType(MappingType::ChannelMappingType)
{
@@ -74,7 +73,7 @@ void ChannelMapping::cleanup()
m_propertyName = nullptr;
m_componentCount = 0;
m_callback = nullptr;
- m_callbackFlags = 0;
+ m_callbackFlags = {};
m_skeletonId = Qt3DCore::QNodeId();
}
@@ -106,9 +105,9 @@ void ChannelMapping::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firs
const QCallbackMapping *callbackMapping = qobject_cast<const QCallbackMapping *>(frontEnd);
if (callbackMapping) {
m_mappingType = ChannelMappingType;
- m_channelName = channelMapping->channelName();
+ m_channelName = callbackMapping->channelName();
- const QCallbackMappingPrivate *d = static_cast<const QCallbackMappingPrivate *>(Qt3DCore::QNodePrivate::get(channelMapping));
+ const QCallbackMappingPrivate *d = static_cast<const QCallbackMappingPrivate *>(Qt3DCore::QNodePrivate::get(callbackMapping));
m_type = d->m_type;
m_callback = d->m_callback;
m_callbackFlags = d->m_callbackFlags;
diff --git a/src/animation/backend/evaluateblendclipanimatorjob.cpp b/src/animation/backend/evaluateblendclipanimatorjob.cpp
index 9b6802d3b..765531902 100644
--- a/src/animation/backend/evaluateblendclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateblendclipanimatorjob.cpp
@@ -54,6 +54,7 @@ namespace Animation {
EvaluateBlendClipAnimatorJob::EvaluateBlendClipAnimatorJob()
: AbstractEvaluateClipAnimatorJob()
+ , m_handler(nullptr)
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateBlendClipAnimator, 0)
}
diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp
index 7a568e829..914a38139 100644
--- a/src/animation/backend/evaluateclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateclipanimatorjob.cpp
@@ -52,6 +52,7 @@ namespace Animation {
EvaluateClipAnimatorJob::EvaluateClipAnimatorJob()
: AbstractEvaluateClipAnimatorJob()
+ , m_handler(nullptr)
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateClipAnimator, 0)
}
diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp
index fde3f7db8..1005914c7 100644
--- a/src/animation/backend/findrunningclipanimatorsjob.cpp
+++ b/src/animation/backend/findrunningclipanimatorsjob.cpp
@@ -48,8 +48,9 @@ namespace Animation {
FindRunningClipAnimatorsJob::FindRunningClipAnimatorsJob()
: Qt3DCore::QAspectJob()
+ , m_handler(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::FindRunningClipAnimator, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::FindRunningClipAnimator, 0)
}
void FindRunningClipAnimatorsJob::setDirtyClipAnimators(const QVector<HClipAnimator> &clipAnimatorHandles)
diff --git a/src/animation/backend/gltfimporter.cpp b/src/animation/backend/gltfimporter.cpp
index a2630fc5e..a5127efd0 100644
--- a/src/animation/backend/gltfimporter.cpp
+++ b/src/animation/backend/gltfimporter.cpp
@@ -35,6 +35,9 @@
****************************************************************************/
#include "gltfimporter_p.h"
+
+#include <Qt3DCore/private/qloadgltf_p.h>
+
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <Qt3DAnimation/private/fcurve_p.h>
#include <Qt3DAnimation/private/keyframe_p.h>
@@ -434,12 +437,7 @@ GLTFImporter::GLTFImporter()
bool GLTFImporter::load(QIODevice *ioDev)
{
- QByteArray jsonData = ioDev->readAll();
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(jsonData);
-
- if (Q_UNLIKELY(!setJSON(sceneDocument))) {
+ if (Q_UNLIKELY(!setJSON(qLoadGLTF(ioDev->readAll())))) {
qWarning("not a JSON document");
return false;
}
diff --git a/src/animation/backend/loadanimationclipjob.cpp b/src/animation/backend/loadanimationclipjob.cpp
index 977564c7f..93d4c2d9d 100644
--- a/src/animation/backend/loadanimationclipjob.cpp
+++ b/src/animation/backend/loadanimationclipjob.cpp
@@ -64,6 +64,7 @@ public:
LoadAnimationClipJob::LoadAnimationClipJob()
: Qt3DCore::QAspectJob(*new LoadAnimationClipJobPrivate)
, m_animationClipHandles()
+ , m_handler(nullptr)
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadAnimationClip, 0)
}
diff --git a/src/animation/backend/skeleton.cpp b/src/animation/backend/skeleton.cpp
index 60e436a71..3788fd0f1 100644
--- a/src/animation/backend/skeleton.cpp
+++ b/src/animation/backend/skeleton.cpp
@@ -35,7 +35,6 @@
****************************************************************************/
#include "skeleton_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qabstractskeleton_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/animation/frontend/qabstractanimationclip.cpp b/src/animation/frontend/qabstractanimationclip.cpp
index e662a1408..08133072c 100644
--- a/src/animation/frontend/qabstractanimationclip.cpp
+++ b/src/animation/frontend/qabstractanimationclip.cpp
@@ -36,7 +36,6 @@
#include "qabstractanimationclip.h"
#include "qabstractanimationclip_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -122,7 +121,7 @@ void QAbstractAnimationClipPrivate::setDuration(float duration)
animator->setRunning(true);
\endcode
- \sa QAnimationClip, QAnimationClipLoader
+ \sa Qt3DAnimation::QAnimationClip, Qt3DAnimation::QAnimationClipLoader
*/
/*!
@@ -134,6 +133,11 @@ QAbstractAnimationClip::QAbstractAnimationClip(QAbstractAnimationClipPrivate &dd
{
}
+// TODO Unused remove in Qt6
+void QAbstractAnimationClip::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
/*!
Destroys this animation clip.
*/
diff --git a/src/animation/frontend/qabstractanimationclip.h b/src/animation/frontend/qabstractanimationclip.h
index f68950c4c..fddee3dec 100644
--- a/src/animation/frontend/qabstractanimationclip.h
+++ b/src/animation/frontend/qabstractanimationclip.h
@@ -62,7 +62,8 @@ Q_SIGNALS:
protected:
QAbstractAnimationClip(QAbstractAnimationClipPrivate &dd, Qt3DCore::QNode *parent = nullptr);
-
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QAbstractAnimationClip)
};
diff --git a/src/animation/frontend/qabstractchannelmapping.cpp b/src/animation/frontend/qabstractchannelmapping.cpp
index 3249e6876..599ec6ed7 100644
--- a/src/animation/frontend/qabstractchannelmapping.cpp
+++ b/src/animation/frontend/qabstractchannelmapping.cpp
@@ -46,6 +46,7 @@ namespace Qt3DAnimation {
QAbstractChannelMappingPrivate::QAbstractChannelMappingPrivate()
: Qt3DCore::QNodePrivate()
+ , m_mappingType(QChannelMappingCreatedChangeBase::ChannelMapping)
{
}
diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp
index cb4621182..8c282da49 100644
--- a/src/animation/frontend/qabstractclipanimator.cpp
+++ b/src/animation/frontend/qabstractclipanimator.cpp
@@ -122,6 +122,11 @@ QAbstractClipAnimator::QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Q
{
}
+// TODO Unused remove in Qt6
+void QAbstractClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
QAbstractClipAnimator::~QAbstractClipAnimator()
{
}
diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h
index 687589b5e..dc9dc9077 100644
--- a/src/animation/frontend/qabstractclipanimator.h
+++ b/src/animation/frontend/qabstractclipanimator.h
@@ -94,6 +94,8 @@ protected:
explicit QAbstractClipAnimator(Qt3DCore::QNode *parent = nullptr);
QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QAbstractClipAnimator)
};
diff --git a/src/animation/frontend/qanimationcallback.qdoc b/src/animation/frontend/qanimationcallback.qdoc
new file mode 100644
index 000000000..5c6e8e212
--- /dev/null
+++ b/src/animation/frontend/qanimationcallback.qdoc
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class Qt3DAnimation::QAnimationCallback
+ \inmodule Qt3DAnimation
+ \brief Represents an animation callback object.
+*/
+
+/*!
+ \enum Qt3DAnimation::QAnimationCallback::Flag
+
+ Flags to indicate how the valueChanged() function is called.
+
+ \value OnOwningThread
+ Callback function is called on the owning (GUI or main) thread.
+ \value OnThreadPool
+ Callback function is called on the thread pool's worker thread.
+*/
+
+/*!
+ \fn Qt3DAnimation::QAnimationCallback::valueChanged(const QVariant &value)
+
+ Callback function that is triggered for changes in the animated \a value.
+
+ \sa QCallbackMapping::setCallback()
+*/
diff --git a/src/animation/frontend/qanimationclip.cpp b/src/animation/frontend/qanimationclip.cpp
index d624a246a..74a9b8371 100644
--- a/src/animation/frontend/qanimationclip.cpp
+++ b/src/animation/frontend/qanimationclip.cpp
@@ -51,8 +51,8 @@ QAnimationClipPrivate::QAnimationClipPrivate()
}
/*!
- \class QAnimationClip
- \inherits QAbstractAnimationClip
+ \class Qt3DAnimation::QAnimationClip
+ \inherits Qt3dAnimation::QAbstractAnimationClip
\inmodule Qt3DAnimation
\brief Specifies key frame animation data.
*/
diff --git a/src/animation/frontend/qanimationclipdata.cpp b/src/animation/frontend/qanimationclipdata.cpp
index 49de71e79..e105b7b43 100644
--- a/src/animation/frontend/qanimationclipdata.cpp
+++ b/src/animation/frontend/qanimationclipdata.cpp
@@ -53,7 +53,7 @@ public:
};
/*!
- \class QAnimationClipData
+ \class Qt3DAnimation::QAnimationClipData
\inmodule Qt3DAnimation
\brief Class containing the animation data.
*/
diff --git a/src/animation/frontend/qanimationcliploader.cpp b/src/animation/frontend/qanimationcliploader.cpp
index 446995b17..bf901e54f 100644
--- a/src/animation/frontend/qanimationcliploader.cpp
+++ b/src/animation/frontend/qanimationcliploader.cpp
@@ -36,7 +36,6 @@
#include "qanimationcliploader.h"
#include "qanimationcliploader_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -113,6 +112,11 @@ QAnimationClipLoader::QAnimationClipLoader(QAnimationClipLoaderPrivate &dd, Qt3D
{
}
+// TODO Unused remove in Qt6
+void QAnimationClipLoader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
QAnimationClipLoader::~QAnimationClipLoader()
{
}
diff --git a/src/animation/frontend/qanimationcliploader.h b/src/animation/frontend/qanimationcliploader.h
index 1ff388297..1b68e852f 100644
--- a/src/animation/frontend/qanimationcliploader.h
+++ b/src/animation/frontend/qanimationcliploader.h
@@ -78,6 +78,8 @@ Q_SIGNALS:
protected:
explicit QAnimationClipLoader(QAnimationClipLoaderPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QAnimationClipLoader)
diff --git a/src/animation/frontend/qcallbackmapping.cpp b/src/animation/frontend/qcallbackmapping.cpp
index 53f7a5e33..a86785012 100644
--- a/src/animation/frontend/qcallbackmapping.cpp
+++ b/src/animation/frontend/qcallbackmapping.cpp
@@ -51,13 +51,12 @@ QCallbackMappingPrivate::QCallbackMappingPrivate()
, m_channelName()
, m_type(static_cast<int>(QVariant::Invalid))
, m_callback(nullptr)
- , m_callbackFlags(0)
{
m_mappingType = QChannelMappingCreatedChangeBase::CallbackMapping;
}
/*!
- \class QCallbackMapping
+ \class Qt3DAnimation::QCallbackMapping
\inherits Qt3DCore::QAbstractChannelMapping
\inmodule Qt3DAnimation
\brief Allows to map the channels within the clip onto an invocation
diff --git a/src/animation/frontend/qchannel.cpp b/src/animation/frontend/qchannel.cpp
index eab7f0df4..1e0da3c3f 100644
--- a/src/animation/frontend/qchannel.cpp
+++ b/src/animation/frontend/qchannel.cpp
@@ -54,7 +54,7 @@ public:
};
/*!
- \class QChannel
+ \class Qt3DAnimation::QChannel
\inmodule Qt3DAnimation
\brief Defines a channel for a QAnimationClipData.
The animation system interpolates each channel component independently
diff --git a/src/animation/frontend/qchannelmapper.cpp b/src/animation/frontend/qchannelmapper.cpp
index ab98039b4..c5909adbc 100644
--- a/src/animation/frontend/qchannelmapper.cpp
+++ b/src/animation/frontend/qchannelmapper.cpp
@@ -49,7 +49,7 @@ QChannelMapperPrivate::QChannelMapperPrivate()
}
/*!
- \class QChannelMapper
+ \class Qt3DAnimation::QChannelMapper
\inmodule Qt3DAnimation
\brief Allows to map the channels within the clip onto properties of
objects in the application.
diff --git a/src/animation/frontend/qchannelmapping.cpp b/src/animation/frontend/qchannelmapping.cpp
index 59620ab49..16651afe6 100644
--- a/src/animation/frontend/qchannelmapping.cpp
+++ b/src/animation/frontend/qchannelmapping.cpp
@@ -161,7 +161,7 @@ void QChannelMappingPrivate::updatePropertyNameTypeAndComponentCount()
}
/*!
- \class QChannelMapping
+ \class Qt3DAnimation::QChannelMapping
\inherits Qt3DCore::QNode
\inmodule Qt3DAnimation
\brief Allows to map the channels within the clip onto properties of
diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp
index 03510aa93..ffad588c1 100644
--- a/src/animation/frontend/qclipanimator.cpp
+++ b/src/animation/frontend/qclipanimator.cpp
@@ -107,7 +107,8 @@ bool QClipAnimatorPrivate::canPlay() const
The properties for controlling the animator are provided by the QAbstractClipAnimator base
class.
- \sa QAbstractClipAnimator, QAbstractAnimationClip, QChannelMapper, QBlendedClipAnimator
+ \sa Qt3DAnimation::QAbstractClipAnimator, Qt3DAnimation::QAbstractAnimationClip,
+ Qt3DAnimation::QChannelMapper, Qt3DAnimation::QBlendedClipAnimator
*/
QClipAnimator::QClipAnimator(Qt3DCore::QNode *parent)
diff --git a/src/animation/frontend/qclipblendvalue.cpp b/src/animation/frontend/qclipblendvalue.cpp
index 72a7dd796..053453e33 100644
--- a/src/animation/frontend/qclipblendvalue.cpp
+++ b/src/animation/frontend/qclipblendvalue.cpp
@@ -53,14 +53,14 @@ QClipBlendValuePrivate::QClipBlendValuePrivate()
}
/*!
- \class QClipBlendValue
+ \class Qt3DAnimation::QClipBlendValue
\inherits Qt3DAnimation::QAbstractClipBlendNode
\inmodule Qt3DAnimation
\brief Class used for including a clip in a blend tree.
*/
/*!
\qmltype ClipBlendValue
- \instantiates QClipBlendValue
+ \instantiates Qt3DAnimation::QClipBlendValue
\inqmlmodule Qt3D.Animation
\brief Type used for including a clip in a blend tree.
*/
diff --git a/src/animation/frontend/qmorphtarget.cpp b/src/animation/frontend/qmorphtarget.cpp
index 76b1a598e..da068d477 100644
--- a/src/animation/frontend/qmorphtarget.cpp
+++ b/src/animation/frontend/qmorphtarget.cpp
@@ -86,8 +86,8 @@ namespace Qt3DAnimation {
*/
/*!
\qmlmethod MorphTarget Qt3D.Animation::MorphTarget::fromGeometry(geometry, stringList)
- Returns a morph target based on the attributes defined by the given stringList from
- the given geometry.
+ Returns a morph target based on the attributes defined by the given \a stringList from
+ the given \a geometry.
*/
QMorphTargetPrivate::QMorphTargetPrivate()
diff --git a/src/animation/frontend/qvertexblendanimation.cpp b/src/animation/frontend/qvertexblendanimation.cpp
index 25468d4a7..143b9553a 100644
--- a/src/animation/frontend/qvertexblendanimation.cpp
+++ b/src/animation/frontend/qvertexblendanimation.cpp
@@ -192,8 +192,8 @@ void QVertexBlendAnimationPrivate::updateAnimation(float position)
Qt3DRender::QGeometry *geometry = m_target->geometry();
// remove attributes from previous frame
- if ((m_currentBase && (base != m_currentBase))
- || (m_currentTarget && (target != m_currentTarget))) {
+ if (m_currentBase && m_currentTarget &&
+ (base != m_currentBase || target != m_currentTarget)) {
const QVector<Qt3DRender::QAttribute *> baseAttributes = m_currentBase->attributeList();
const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList();
for (int i = 0; i < baseAttributes.size(); ++i) {
diff --git a/src/core/aspects/aspectcommanddebugger.cpp b/src/core/aspects/aspectcommanddebugger.cpp
index eceec1bbd..7635f44c0 100644
--- a/src/core/aspects/aspectcommanddebugger.cpp
+++ b/src/core/aspects/aspectcommanddebugger.cpp
@@ -39,12 +39,12 @@
#include "aspectcommanddebugger_p.h"
-#include <Qt3DCore/qaspectengine.h>
#include <QtNetwork/QTcpSocket>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <Qt3DCore/private/qabstractaspect_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p.h>
QT_BEGIN_NAMESPACE
@@ -64,13 +64,6 @@ struct CommandHeader
} // anonymous
-AspectCommandDebugger::ReadBuffer::ReadBuffer()
- : buffer()
- , startIdx(0)
- , endIdx(0)
-{
-}
-
void AspectCommandDebugger::ReadBuffer::insert(const QByteArray &array)
{
buffer.insert(endIdx, array);
@@ -88,9 +81,9 @@ void AspectCommandDebugger::ReadBuffer::trim()
}
}
-AspectCommandDebugger::AspectCommandDebugger(QObject *parent)
+AspectCommandDebugger::AspectCommandDebugger(QSystemInformationService *parent)
: QTcpServer(parent)
- , m_aspectEngine(nullptr)
+ , m_service(parent)
{
}
@@ -115,11 +108,6 @@ void AspectCommandDebugger::initialize()
qWarning() << Q_FUNC_INFO << "failed to listen on port 8883";
}
-void AspectCommandDebugger::setAspectEngine(QAspectEngine *engine)
-{
- m_aspectEngine = engine;
-}
-
void AspectCommandDebugger::asynchronousReplyFinished(AsynchronousCommandReply *reply)
{
Q_ASSERT(reply->isFinished());
@@ -189,7 +177,7 @@ void AspectCommandDebugger::executeCommand(const QString &command,
QTcpSocket *socket)
{
// Only a single aspect is going to reply
- const QVariant response = m_aspectEngine->executeCommand(command);
+ const QVariant response = m_service->executeCommand(command);
if (response.userType() == qMetaTypeId<AsynchronousCommandReply *>()) { // AsynchronousCommand
// Store the command | socket in a table
AsynchronousCommandReply *reply = response.value<AsynchronousCommandReply *>();
diff --git a/src/core/aspects/aspectcommanddebugger_p.h b/src/core/aspects/aspectcommanddebugger_p.h
index bb6100df5..b39708ab1 100644
--- a/src/core/aspects/aspectcommanddebugger_p.h
+++ b/src/core/aspects/aspectcommanddebugger_p.h
@@ -54,32 +54,30 @@
//
#include <QTcpServer>
+#include <Qt3DCore/private/qt3dcore_global_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-class QAspectEngine;
+class QSystemInformationService;
namespace Debug {
class AsynchronousCommandReply;
-class Q_AUTOTEST_EXPORT AspectCommandDebugger : public QTcpServer
+class Q_3DCORE_PRIVATE_EXPORT AspectCommandDebugger : public QTcpServer
{
Q_OBJECT
public:
- explicit AspectCommandDebugger(QObject *parent = nullptr);
+ explicit AspectCommandDebugger(QSystemInformationService *parent = nullptr);
void initialize();
- void setAspectEngine(QAspectEngine *engine);
-
- struct ReadBuffer {
- ReadBuffer();
+ struct Q_3DCORE_PRIVATE_EXPORT ReadBuffer {
QByteArray buffer;
- int startIdx;
- int endIdx;
+ int startIdx = 0;
+ int endIdx = 0;
inline int size() const { return endIdx - startIdx; }
void insert(const QByteArray &array);
@@ -95,7 +93,7 @@ private:
void executeCommand(const QString &command, QTcpSocket *socket);
QVector<QTcpSocket *> m_connections;
- QAspectEngine *m_aspectEngine;
+ QSystemInformationService *m_service;
ReadBuffer m_readBuffer;
QHash<AsynchronousCommandReply *, QTcpSocket *> m_asyncCommandToSocketEntries;
diff --git a/src/core/aspects/aspects.pri b/src/core/aspects/aspects.pri
index 5e8327192..068f74389 100644
--- a/src/core/aspects/aspects.pri
+++ b/src/core/aspects/aspects.pri
@@ -4,7 +4,8 @@ SOURCES += \
$$PWD/qabstractaspect.cpp \
$$PWD/qaspectengine.cpp \
$$PWD/qaspectfactory.cpp \
- $$PWD/qaspectmanager.cpp
+ $$PWD/qaspectmanager.cpp \
+ $$PWD/aspectcommanddebugger.cpp
HEADERS += \
$$PWD/qabstractaspect.h \
@@ -12,13 +13,10 @@ HEADERS += \
$$PWD/qabstractaspect_p.h \
$$PWD/qaspectengine_p.h \
$$PWD/qaspectfactory_p.h \
- $$PWD/qaspectmanager_p.h
+ $$PWD/qaspectmanager_p.h \
+ $$PWD/aspectcommanddebugger_p.h
INCLUDEPATH += $$PWD
include($$QT3D_BUILD_ROOT/src/core/qt3dcore-config.pri)
QT_FOR_CONFIG += 3dcore-private
-qtConfig(qt3d-profile-jobs): {
- HEADERS += $$PWD/aspectcommanddebugger_p.h
- SOURCES += $$PWD/aspectcommanddebugger.cpp
-}
diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp
index 05afdd293..a2aed732b 100644
--- a/src/core/aspects/qabstractaspect.cpp
+++ b/src/core/aspects/qabstractaspect.cpp
@@ -198,28 +198,16 @@ void QAbstractAspect::unregisterBackendType(const QMetaObject &obj)
QVariant QAbstractAspect::executeCommand(const QStringList &args)
{
- Q_UNUSED(args);
+ Q_UNUSED(args)
return QVariant();
}
QVector<QAspectJobPtr> QAbstractAspect::jobsToExecute(qint64 time)
{
- Q_UNUSED(time);
+ Q_UNUSED(time)
return QVector<QAspectJobPtr>();
}
-void QAbstractAspect::syncDirtyFrontEndNodes(const QVector<QNode *> &nodes)
-{
- Q_D(QAbstractAspect);
- d->syncDirtyFrontEndNodes(nodes);
-}
-
-void QAbstractAspect::syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes)
-{
- Q_D(QAbstractAspect);
- d->syncDirtyFrontEndSubNodes(nodes);
-}
-
QAbstractAspectPrivate::BackendNodeMapperAndInfo QAbstractAspectPrivate::mapperForNode(const QMetaObject *metaObj) const
{
Q_ASSERT(metaObj);
@@ -520,6 +508,11 @@ QVector<QAspectJobPtr> QAbstractAspectPrivate::jobsToExecute(qint64 time)
return res;
}
+void QAbstractAspectPrivate::jobsDone(QAspectManager *manager)
+{
+ Q_UNUSED(manager)
+}
+
/*!
* Called in the context of the aspect thread once the aspect has been registered.
* This provides an opportunity for the aspect to do any initialization tasks that
diff --git a/src/core/aspects/qabstractaspect.h b/src/core/aspects/qabstractaspect.h
index 8059421a6..3b2f31c50 100644
--- a/src/core/aspects/qabstractaspect.h
+++ b/src/core/aspects/qabstractaspect.h
@@ -87,9 +87,6 @@ protected:
void unregisterBackendType(const QMetaObject &);
private:
- void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes);
- void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes);
-
virtual QVariant executeCommand(const QStringList &args);
virtual QVector<QAspectJobPtr> jobsToExecute(qint64 time);
diff --git a/src/core/aspects/qabstractaspect_p.h b/src/core/aspects/qabstractaspect_p.h
index 670302cfa..9435f2bc6 100644
--- a/src/core/aspects/qabstractaspect_p.h
+++ b/src/core/aspects/qabstractaspect_p.h
@@ -57,6 +57,7 @@
#include <Qt3DCore/private/qaspectjobproviderinterface_p.h>
#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DCore/private/qt3dcore_global_p.h>
+#include <Qt3DCore/private/qscenechange_p.h>
#include <QtCore/private/qobject_p.h>
#include <QMutex>
@@ -126,6 +127,7 @@ public:
QAbstractAspectJobManager *jobManager() const;
QVector<QAspectJobPtr> jobsToExecute(qint64 time) override;
+ void jobsDone(Qt3DCore::QAspectManager *manager) override;
QBackendNode *createBackendNode(const NodeTreeChange &change) const;
void clearBackendNode(const NodeTreeChange &change) const;
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index 426741a61..d28306197 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -55,12 +55,9 @@
#include <Qt3DCore/private/qpostman_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p.h>
#include <Qt3DCore/qt3dcore-config.h>
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <Qt3DCore/private/aspectcommanddebugger_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
namespace{
@@ -122,9 +119,6 @@ QAspectEnginePrivate::QAspectEnginePrivate()
, m_scene(nullptr)
, m_initialized(false)
, m_runMode(QAspectEngine::Automatic)
- #if QT_CONFIG(qt3d_profile_jobs)
- , m_commandDebugger(new Debug::AspectCommandDebugger(q_func()))
- #endif
{
qRegisterMetaType<Qt3DCore::QAbstractAspect *>();
qRegisterMetaType<Qt3DCore::QObserverInterface *>();
@@ -276,10 +270,6 @@ void QAspectEnginePrivate::initialize()
arbiter->setScene(m_scene);
m_initialized = true;
m_aspectManager->setPostConstructorInit(m_scene->postConstructorInit());
-#if QT_CONFIG(qt3d_profile_jobs)
- m_commandDebugger->setAspectEngine(q_func());
- m_commandDebugger->initialize();
-#endif
}
/*!
@@ -419,16 +409,8 @@ QVariant QAspectEngine::executeCommand(const QString &command)
if (d->m_aspects.isEmpty())
return QLatin1String("No loaded aspect");
- QString reply;
- reply += QLatin1String("Loaded aspects:");
- for (QAbstractAspect *aspect : qAsConst(d->m_aspects)) {
- const QString name = d->m_factory.aspectName(aspect);
- if (!name.isEmpty())
- reply += QLatin1String("\n * ") + name;
- else
- reply += QLatin1String("\n * <unnamed>");
- }
- return reply;
+ const QStringList names = d->m_aspectManager->serviceLocator()->systemInformation()->aspectNames();
+ return names.join(QLatin1String("\n"));
}
QStringList args = command.split(QLatin1Char(' '));
diff --git a/src/core/aspects/qaspectengine_p.h b/src/core/aspects/qaspectengine_p.h
index c83940435..8f3abcd38 100644
--- a/src/core/aspects/qaspectengine_p.h
+++ b/src/core/aspects/qaspectengine_p.h
@@ -69,12 +69,6 @@ class QAspectManager;
class QPostman;
class QScene;
-#if QT_CONFIG(qt3d_profile_jobs)
-namespace Debug {
-class AspectCommandDebugger;
-} // Debug
-#endif
-
class Q_3DCORE_PRIVATE_EXPORT QAspectEnginePrivate : public QObjectPrivate
{
public:
@@ -93,10 +87,6 @@ public:
bool m_initialized;
QAspectEngine::RunMode m_runMode;
-#if QT_CONFIG(qt3d_profile_jobs)
- Debug::AspectCommandDebugger *m_commandDebugger;
-#endif
-
void initialize();
void shutdown();
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index 71e05b34f..f276d633e 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -57,6 +57,7 @@
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/private/qscheduler_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p_p.h>
#include <Qt3DCore/private/qthreadpooler_p.h>
#include <Qt3DCore/private/qtickclock_p.h>
#include <Qt3DCore/private/qtickclockservice_p.h>
@@ -98,15 +99,18 @@ int RequestFrameEvent::requestEventType = QEvent::registerEventType();
\class Qt3DCore::QAspectManager
\internal
*/
-QAspectManager::QAspectManager(QObject *parent)
+QAspectManager::QAspectManager(QAspectEngine *parent)
: QObject(parent)
+ , m_engine(parent)
, m_root(nullptr)
, m_scheduler(new QScheduler(this))
, m_jobManager(new QAspectJobManager(this))
, m_changeArbiter(new QChangeArbiter(this))
- , m_serviceLocator(new QServiceLocator())
+ , m_serviceLocator(new QServiceLocator(parent))
, m_simulationLoopRunning(false)
, m_driveMode(QAspectEngine::Automatic)
+ , m_postConstructorInit(nullptr)
+ , m_jobsInLastFrame(0)
{
qRegisterMetaType<QSurface *>("QSurface*");
qCDebug(Aspects) << Q_FUNC_INFO;
@@ -413,6 +417,8 @@ bool QAspectManager::event(QEvent *e)
// the loop
if (m_simulationLoopRunning && m_driveMode == QAspectEngine::Automatic)
requestNextFrame();
+
+ return true;
}
return QObject::event(e);
@@ -423,7 +429,7 @@ void QAspectManager::requestNextFrame()
qCDebug(Aspects) << "Requesting new Frame";
// Post event in the event loop to force
// next frame to be processed
- qApp->postEvent(this, new RequestFrameEvent());
+ QCoreApplication::postEvent(this, new RequestFrameEvent());
}
void QAspectManager::processFrame()
@@ -435,6 +441,8 @@ void QAspectManager::processFrame()
m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService);
const qint64 t = frameAdvanceService->waitForNextFrame();
+ if (t < 0)
+ return;
// Distribute accumulated changes. This includes changes sent from the frontend
// to the backend nodes. We call this before the call to m_scheduler->update() to ensure
@@ -444,57 +452,49 @@ void QAspectManager::processFrame()
//
// Doing this as the first call in the new frame ensures the lock free approach works
// without any such data race.
-#if QT_CONFIG(qt3d_profile_jobs)
- const quint32 arbiterId = 4096;
- JobRunStats changeArbiterStats;
- changeArbiterStats.jobId.typeAndInstance[0] = arbiterId;
- changeArbiterStats.jobId.typeAndInstance[1] = 0;
- changeArbiterStats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
- changeArbiterStats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
-#endif
-
- // Tell the NodePostConstructorInit to process any pending nodes which will add them to our list of
- // tree changes
- m_postConstructorInit->processNodes();
-
- // Add and Remove Nodes
- const QVector<NodeTreeChange> nodeTreeChanges = std::move(m_nodeTreeChanges);
- for (const NodeTreeChange &change : nodeTreeChanges) {
- // Buckets ensure that even if we have intermingled node added / removed
- // buckets, we preserve the order of the sequences
-
- for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
- switch (change.type) {
- case NodeTreeChange::Added:
- aspect->d_func()->createBackendNode(change);
- break;
- case NodeTreeChange::Removed:
- aspect->d_func()->clearBackendNode(change);
- break;
+ {
+ // scope for QTaskLogger
+ QTaskLogger logger(m_serviceLocator->systemInformation(), 4096, 0);
+
+ // Tell the NodePostConstructorInit to process any pending nodes which will add them to our list of
+ // tree changes
+ m_postConstructorInit->processNodes();
+
+ // Add and Remove Nodes
+ const QVector<NodeTreeChange> nodeTreeChanges = std::move(m_nodeTreeChanges);
+ for (const NodeTreeChange &change : nodeTreeChanges) {
+ // Buckets ensure that even if we have intermingled node added / removed
+ // buckets, we preserve the order of the sequences
+
+ for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
+ switch (change.type) {
+ case NodeTreeChange::Added:
+ aspect->d_func()->createBackendNode(change);
+ break;
+ case NodeTreeChange::Removed:
+ aspect->d_func()->clearBackendNode(change);
+ break;
+ }
}
}
- }
-
- // Sync node / subnode relationship changes
- const auto dirtySubNodes = m_changeArbiter->takeDirtyFrontEndSubNodes();
- if (dirtySubNodes.size())
- for (QAbstractAspect *aspect : qAsConst(m_aspects))
- aspect->syncDirtyFrontEndSubNodes(dirtySubNodes);
- // Sync property updates
- const auto dirtyFrontEndNodes = m_changeArbiter->takeDirtyFrontEndNodes();
- if (dirtyFrontEndNodes.size())
- for (QAbstractAspect *aspect : qAsConst(m_aspects))
- aspect->syncDirtyFrontEndNodes(dirtyFrontEndNodes);
-
- // TO DO: Having this done in the main thread actually means aspects could just
- // as simply read info out of the Frontend classes without risk of introducing
- // races. This could therefore be removed for Qt 6.
- m_changeArbiter->syncChanges();
-#if QT_CONFIG(qt3d_profile_jobs)
- changeArbiterStats.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- QThreadPooler::addJobLogStatsEntry(changeArbiterStats);
-#endif
+ // Sync node / subnode relationship changes
+ const auto dirtySubNodes = m_changeArbiter->takeDirtyFrontEndSubNodes();
+ if (dirtySubNodes.size())
+ for (QAbstractAspect *aspect : qAsConst(m_aspects))
+ QAbstractAspectPrivate::get(aspect)->syncDirtyFrontEndSubNodes(dirtySubNodes);
+
+ // Sync property updates
+ const auto dirtyFrontEndNodes = m_changeArbiter->takeDirtyFrontEndNodes();
+ if (dirtyFrontEndNodes.size())
+ for (QAbstractAspect *aspect : qAsConst(m_aspects))
+ QAbstractAspectPrivate::get(aspect)->syncDirtyFrontEndNodes(dirtyFrontEndNodes);
+
+ // TO DO: Having this done in the main thread actually means aspects could just
+ // as simply read info out of the Frontend classes without risk of introducing
+ // races. This could therefore be removed for Qt 6.
+ m_changeArbiter->syncChanges();
+ }
// For each Aspect
// Ask them to launch set of jobs for the current frame
@@ -503,12 +503,10 @@ void QAspectManager::processFrame()
QElapsedTimer timer;
timer.start();
#endif
- m_scheduler->scheduleAndWaitForFrameAspectJobs(t);
+ m_jobsInLastFrame = m_scheduler->scheduleAndWaitForFrameAspectJobs(t);
#if defined(QT3D_CORE_JOB_TIMING)
qDebug() << "Jobs took" << timer.nsecsElapsed() / 1.0e6;
#endif
-
- // TODO sync backend changes to frontend
}
} // namespace Qt3DCore
diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h
index d9a6c41ec..ed04b314f 100644
--- a/src/core/aspects/qaspectmanager_p.h
+++ b/src/core/aspects/qaspectmanager_p.h
@@ -73,6 +73,7 @@ class QScheduler;
class QChangeArbiter;
class QAbstractAspect;
class QAbstractAspectJobManager;
+class QAspectEngine;
class QServiceLocator;
class NodePostConstructorInit;
struct NodeTreeChange;
@@ -81,7 +82,7 @@ class Q_3DCORE_PRIVATE_EXPORT QAspectManager : public QObject
{
Q_OBJECT
public:
- explicit QAspectManager(QObject *parent = nullptr);
+ explicit QAspectManager(QAspectEngine *parent = nullptr);
~QAspectManager();
void setRunMode(QAspectEngine::RunMode mode);
@@ -111,10 +112,13 @@ public:
QNode *lookupNode(QNodeId id) const;
QVector<QNode *> lookupNodes(const QVector<QNodeId> &ids) const;
+ int jobsInLastFrame() const { return m_jobsInLastFrame; }
+
private:
bool event(QEvent *event) override;
void requestNextFrame();
+ QAspectEngine *m_engine;
QVector<QAbstractAspect *> m_aspects;
QEntity *m_root;
QVariantMap m_data;
@@ -122,12 +126,11 @@ private:
QAbstractAspectJobManager *m_jobManager;
QChangeArbiter *m_changeArbiter;
QScopedPointer<QServiceLocator> m_serviceLocator;
- bool m_mainLoopRunning;
bool m_simulationLoopRunning;
QAspectEngine::RunMode m_driveMode;
QVector<NodeTreeChange> m_nodeTreeChanges;
NodePostConstructorInit* m_postConstructorInit;
-
+ int m_jobsInLastFrame;
};
} // namespace Qt3DCore
diff --git a/src/core/changes/qcomponentaddedchange.h b/src/core/changes/qcomponentaddedchange.h
index ef2f6a227..9e1522024 100644
--- a/src/core/changes/qcomponentaddedchange.h
+++ b/src/core/changes/qcomponentaddedchange.h
@@ -53,10 +53,10 @@ class QComponentAddedChangePrivate;
class Q_3DCORESHARED_EXPORT QComponentAddedChange : public QSceneChange
{
public:
- explicit QComponentAddedChange(const QEntity *entity,
- const QComponent *component);
- explicit QComponentAddedChange(const QComponent *component,
- const QEntity *entity);
+ Q3D_DECL_DEPRECATED explicit QComponentAddedChange(const QEntity *entity,
+ const QComponent *component);
+ Q3D_DECL_DEPRECATED explicit QComponentAddedChange(const QComponent *component,
+ const QEntity *entity);
~QComponentAddedChange();
QNodeId entityId() const Q_DECL_NOTHROW;
@@ -67,7 +67,7 @@ private:
Q_DECLARE_PRIVATE(QComponentAddedChange)
};
-typedef QSharedPointer<QComponentAddedChange> QComponentAddedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QComponentAddedChange> QComponentAddedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qcomponentremovedchange.h b/src/core/changes/qcomponentremovedchange.h
index 8108b33d5..e0b039780 100644
--- a/src/core/changes/qcomponentremovedchange.h
+++ b/src/core/changes/qcomponentremovedchange.h
@@ -53,10 +53,10 @@ class QComponentRemovedChangePrivate;
class Q_3DCORESHARED_EXPORT QComponentRemovedChange : public QSceneChange
{
public:
- explicit QComponentRemovedChange(const QEntity *entity,
- const QComponent *component);
- explicit QComponentRemovedChange(const QComponent *component,
- const QEntity *entity);
+ Q3D_DECL_DEPRECATED explicit QComponentRemovedChange(const QEntity *entity,
+ const QComponent *component);
+ Q3D_DECL_DEPRECATED explicit QComponentRemovedChange(const QComponent *component,
+ const QEntity *entity);
~QComponentRemovedChange();
QNodeId entityId() const Q_DECL_NOTHROW;
@@ -67,7 +67,7 @@ private:
Q_DECLARE_PRIVATE(QComponentRemovedChange)
};
-typedef QSharedPointer<QComponentRemovedChange> QComponentRemovedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QComponentRemovedChange> QComponentRemovedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qdynamicpropertyupdatedchange.h b/src/core/changes/qdynamicpropertyupdatedchange.h
index 0509582b0..7009e1fe7 100644
--- a/src/core/changes/qdynamicpropertyupdatedchange.h
+++ b/src/core/changes/qdynamicpropertyupdatedchange.h
@@ -51,7 +51,7 @@ class QDynamicPropertyUpdatedChangePrivate;
class Q_3DCORESHARED_EXPORT QDynamicPropertyUpdatedChange : public QPropertyUpdatedChangeBase
{
public:
- explicit QDynamicPropertyUpdatedChange(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QDynamicPropertyUpdatedChange(QNodeId subjectId);
~QDynamicPropertyUpdatedChange();
QByteArray propertyName() const;
@@ -65,7 +65,7 @@ protected:
QDynamicPropertyUpdatedChange(QDynamicPropertyUpdatedChangePrivate &dd, QNodeId subjectId);
};
-typedef QSharedPointer<QDynamicPropertyUpdatedChange> QDynamicPropertyUpdatedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QDynamicPropertyUpdatedChange> QDynamicPropertyUpdatedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qnodecommand.h b/src/core/changes/qnodecommand.h
index 3622f7421..83d7caf4f 100644
--- a/src/core/changes/qnodecommand.h
+++ b/src/core/changes/qnodecommand.h
@@ -57,7 +57,7 @@ public:
typedef quint32 CommandId;
#endif
- explicit QNodeCommand(QNodeId id);
+ Q3D_DECL_DEPRECATED explicit QNodeCommand(QNodeId id);
~QNodeCommand();
CommandId commandId() const;
@@ -76,7 +76,7 @@ private:
Q_DECLARE_PRIVATE(QNodeCommand)
};
-typedef QSharedPointer<QNodeCommand> QNodeCommandPtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeCommand> QNodeCommandPtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qnodecreatedchange.h b/src/core/changes/qnodecreatedchange.h
index f46e8abee..359cdb917 100644
--- a/src/core/changes/qnodecreatedchange.h
+++ b/src/core/changes/qnodecreatedchange.h
@@ -51,7 +51,7 @@ class QNodeCreatedChangeBasePrivate;
class Q_3DCORESHARED_EXPORT QNodeCreatedChangeBase : public QSceneChange
{
public:
- explicit QNodeCreatedChangeBase(const QNode *node);
+ Q3D_DECL_DEPRECATED explicit QNodeCreatedChangeBase(const QNode *node);
~QNodeCreatedChangeBase();
QNodeId parentId() const Q_DECL_NOTHROW;
@@ -65,7 +65,7 @@ private:
Q_DECLARE_PRIVATE(QNodeCreatedChangeBase)
};
-typedef QSharedPointer<QNodeCreatedChangeBase> QNodeCreatedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeCreatedChangeBase> QNodeCreatedChangeBasePtr;
template<typename T>
class QNodeCreatedChange : public QNodeCreatedChangeBase
@@ -81,7 +81,7 @@ public:
};
template<typename T>
-using QNodeCreatedChangePtr = QSharedPointer<QNodeCreatedChange<T>>;
+using QNodeCreatedChangePtr Q3D_DECL_DEPRECATED = QSharedPointer<QNodeCreatedChange<T>>;
} // namespace Qt3DCore
diff --git a/src/core/changes/qnodedestroyedchange.h b/src/core/changes/qnodedestroyedchange.h
index c072dd412..dce6da59e 100644
--- a/src/core/changes/qnodedestroyedchange.h
+++ b/src/core/changes/qnodedestroyedchange.h
@@ -50,7 +50,7 @@ class QNodeDestroyedChangePrivate;
class Q_3DCORESHARED_EXPORT QNodeDestroyedChange : public QSceneChange
{
public:
- explicit QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes);
+ Q3D_DECL_DEPRECATED explicit QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes);
~QNodeDestroyedChange();
QVector<QNodeIdTypePair> subtreeIdsAndTypes() const;
@@ -59,7 +59,7 @@ private:
Q_DECLARE_PRIVATE(QNodeDestroyedChange)
};
-typedef QSharedPointer<QNodeDestroyedChange> QNodeDestroyedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeDestroyedChange> QNodeDestroyedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertynodeaddedchange.h b/src/core/changes/qpropertynodeaddedchange.h
index ce3288a65..062244f88 100644
--- a/src/core/changes/qpropertynodeaddedchange.h
+++ b/src/core/changes/qpropertynodeaddedchange.h
@@ -53,7 +53,7 @@ class QPropertyNodeAddedChangePrivate;
class Q_3DCORESHARED_EXPORT QPropertyNodeAddedChange : public QStaticPropertyValueAddedChangeBase
{
public:
- explicit QPropertyNodeAddedChange(QNodeId subjectId, QNode *node);
+ Q3D_DECL_DEPRECATED explicit QPropertyNodeAddedChange(QNodeId subjectId, QNode *node);
~QPropertyNodeAddedChange();
QNodeId addedNodeId() const;
@@ -63,7 +63,7 @@ private:
Q_DECLARE_PRIVATE(QPropertyNodeAddedChange)
};
-typedef QSharedPointer<QPropertyNodeAddedChange> QPropertyNodeAddedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyNodeAddedChange> QPropertyNodeAddedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertynoderemovedchange.h b/src/core/changes/qpropertynoderemovedchange.h
index 1a4db8f1c..a8ea9d6c4 100644
--- a/src/core/changes/qpropertynoderemovedchange.h
+++ b/src/core/changes/qpropertynoderemovedchange.h
@@ -53,7 +53,7 @@ class QPropertyNodeRemovedChangePrivate;
class Q_3DCORESHARED_EXPORT QPropertyNodeRemovedChange : public QStaticPropertyValueRemovedChangeBase
{
public:
- explicit QPropertyNodeRemovedChange(QNodeId subjectId, QNode *node);
+ Q3D_DECL_DEPRECATED explicit QPropertyNodeRemovedChange(QNodeId subjectId, QNode *node);
~QPropertyNodeRemovedChange();
QNodeId removedNodeId() const;
@@ -63,7 +63,7 @@ private:
Q_DECLARE_PRIVATE(QPropertyNodeRemovedChange)
};
-typedef QSharedPointer<QPropertyNodeRemovedChange> QPropertyNodeRemovedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyNodeRemovedChange> QPropertyNodeRemovedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyupdatedchange.h b/src/core/changes/qpropertyupdatedchange.h
index e0c12f13d..aa0dd9364 100644
--- a/src/core/changes/qpropertyupdatedchange.h
+++ b/src/core/changes/qpropertyupdatedchange.h
@@ -51,7 +51,7 @@ class QPropertyUpdatedChangePrivate;
class Q_3DCORESHARED_EXPORT QPropertyUpdatedChange : public QStaticPropertyUpdatedChangeBase
{
public:
- explicit QPropertyUpdatedChange(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyUpdatedChange(QNodeId subjectId);
virtual ~QPropertyUpdatedChange();
QVariant value() const;
@@ -62,7 +62,7 @@ protected:
QPropertyUpdatedChange(QPropertyUpdatedChangePrivate &dd, QNodeId subjectId);
};
-typedef QSharedPointer<QPropertyUpdatedChange> QPropertyUpdatedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyUpdatedChange> QPropertyUpdatedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyupdatedchangebase.h b/src/core/changes/qpropertyupdatedchangebase.h
index 800abb477..5a0f6c87f 100644
--- a/src/core/changes/qpropertyupdatedchangebase.h
+++ b/src/core/changes/qpropertyupdatedchangebase.h
@@ -56,12 +56,12 @@ public:
~QPropertyUpdatedChangeBase();
protected:
- explicit QPropertyUpdatedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyUpdatedChangeBase(QNodeId subjectId);
QPropertyUpdatedChangeBase(QPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId);
Q_DECLARE_PRIVATE(QPropertyUpdatedChangeBase)
};
-typedef QSharedPointer<QPropertyUpdatedChangeBase> QPropertyUpdatedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyUpdatedChangeBase> QPropertyUpdatedChangeBasePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyvalueaddedchange.h b/src/core/changes/qpropertyvalueaddedchange.h
index d85720246..e70d78b7e 100644
--- a/src/core/changes/qpropertyvalueaddedchange.h
+++ b/src/core/changes/qpropertyvalueaddedchange.h
@@ -53,7 +53,7 @@ class QPropertyValueAddedChangePrivate;
class Q_3DCORESHARED_EXPORT QPropertyValueAddedChange : public QStaticPropertyValueAddedChangeBase
{
public:
- explicit QPropertyValueAddedChange(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChange(QNodeId subjectId);
~QPropertyValueAddedChange();
void setAddedValue(const QVariant &value);
@@ -63,7 +63,7 @@ private:
Q_DECLARE_PRIVATE(QPropertyValueAddedChange)
};
-typedef QSharedPointer<QPropertyValueAddedChange> QPropertyValueAddedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueAddedChange> QPropertyValueAddedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyvalueaddedchangebase.h b/src/core/changes/qpropertyvalueaddedchangebase.h
index 2be39ad47..148411de8 100644
--- a/src/core/changes/qpropertyvalueaddedchangebase.h
+++ b/src/core/changes/qpropertyvalueaddedchangebase.h
@@ -56,12 +56,12 @@ public:
~QPropertyValueAddedChangeBase();
protected:
- explicit QPropertyValueAddedChangeBase(QNodeId subjectId);
- explicit QPropertyValueAddedChangeBase(QPropertyValueAddedChangeBasePrivate &dd, QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChangeBase(QPropertyValueAddedChangeBasePrivate &dd, QNodeId subjectId);
Q_DECLARE_PRIVATE(QPropertyValueAddedChangeBase)
};
-typedef QSharedPointer<QPropertyValueAddedChangeBase> QPropertyValueAddedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueAddedChangeBase> QPropertyValueAddedChangeBasePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyvalueremovedchange.h b/src/core/changes/qpropertyvalueremovedchange.h
index 2bd781ed5..70eb42db4 100644
--- a/src/core/changes/qpropertyvalueremovedchange.h
+++ b/src/core/changes/qpropertyvalueremovedchange.h
@@ -53,7 +53,7 @@ class QPropertyValueRemovedChangePrivate;
class Q_3DCORESHARED_EXPORT QPropertyValueRemovedChange : public QStaticPropertyValueRemovedChangeBase
{
public:
- explicit QPropertyValueRemovedChange(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChange(QNodeId subjectId);
~QPropertyValueRemovedChange();
void setRemovedValue(const QVariant &value);
@@ -63,7 +63,7 @@ private:
Q_DECLARE_PRIVATE(QPropertyValueRemovedChange)
};
-typedef QSharedPointer<QPropertyValueRemovedChange> QPropertyValueRemovedChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueRemovedChange> QPropertyValueRemovedChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qpropertyvalueremovedchangebase.h b/src/core/changes/qpropertyvalueremovedchangebase.h
index 233354078..b5ead7d22 100644
--- a/src/core/changes/qpropertyvalueremovedchangebase.h
+++ b/src/core/changes/qpropertyvalueremovedchangebase.h
@@ -57,11 +57,11 @@ public:
protected:
Q_DECLARE_PRIVATE(QPropertyValueRemovedChangeBase)
- explicit QPropertyValueRemovedChangeBase(QNodeId subjectId);
- explicit QPropertyValueRemovedChangeBase(QPropertyValueRemovedChangeBasePrivate &dd, QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChangeBase(QPropertyValueRemovedChangeBasePrivate &dd, QNodeId subjectId);
};
-typedef QSharedPointer<QPropertyValueRemovedChangeBase> QPropertyValueRemovedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueRemovedChangeBase> QPropertyValueRemovedChangeBasePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qscenechange.cpp b/src/core/changes/qscenechange.cpp
index 87bf06ea0..822451b5f 100644
--- a/src/core/changes/qscenechange.cpp
+++ b/src/core/changes/qscenechange.cpp
@@ -48,6 +48,7 @@ namespace Qt3DCore {
/*!
* \enum Qt3DCore::ChangeFlag
* \relates Qt3DCore::QSceneChange
+ * \obsolete
*
* The types of change that can be sent and received by Qt3D's change notification system.
*
diff --git a/src/core/changes/qscenechange.h b/src/core/changes/qscenechange.h
index e8c0ea748..792c00d0a 100644
--- a/src/core/changes/qscenechange.h
+++ b/src/core/changes/qscenechange.h
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-enum ChangeFlag {
+enum Q3D_DECL_DEPRECATED ChangeFlag {
NodeCreated = 1 << 0,
NodeDeleted = 1 << 1,
PropertyUpdated = 1 << 2,
@@ -64,14 +64,6 @@ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(ChangeFlags)
class QNode;
-//! internal
-struct NodeRelationshipChange {
- QNode *node;
- QNode *subNode;
- ChangeFlag change;
- const char *property;
-};
-
class QSceneChangePrivate;
class Q_3DCORESHARED_EXPORT QSceneChange
@@ -95,9 +87,9 @@ public:
protected:
Q_DECLARE_PRIVATE(QSceneChange)
- explicit QSceneChange(ChangeFlag type, QNodeId subjectId);
- explicit QSceneChange(QSceneChangePrivate &dd,
- ChangeFlag type, QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QSceneChange(ChangeFlag type, QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QSceneChange(QSceneChangePrivate &dd,
+ ChangeFlag type, QNodeId subjectId);
QSceneChangePrivate *d_ptr;
private:
@@ -106,7 +98,7 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QSceneChange::DeliveryFlags)
-typedef QSharedPointer<QSceneChange> QSceneChangePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QSceneChange> QSceneChangePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qscenechange_p.h b/src/core/changes/qscenechange_p.h
index d32f6eec3..32006807c 100644
--- a/src/core/changes/qscenechange_p.h
+++ b/src/core/changes/qscenechange_p.h
@@ -63,6 +63,13 @@ namespace Qt3DCore {
class QSceneChange;
class QNodeId;
+struct NodeRelationshipChange {
+ QNode *node;
+ QNode *subNode;
+ ChangeFlag change;
+ const char *property;
+};
+
class Q_3DCORE_PRIVATE_EXPORT QSceneChangePrivate
{
public :
diff --git a/src/core/changes/qskeletoncreatedchange_p.h b/src/core/changes/qskeletoncreatedchange_p.h
index 09b37d545..c20bcae85 100644
--- a/src/core/changes/qskeletoncreatedchange_p.h
+++ b/src/core/changes/qskeletoncreatedchange_p.h
@@ -60,7 +60,7 @@ class QSkeletonCreatedChangeBasePrivate;
class Q_3DCORESHARED_EXPORT QSkeletonCreatedChangeBase : public QNodeCreatedChangeBase
{
public:
- explicit QSkeletonCreatedChangeBase(const QAbstractSkeleton *skeleton);
+ Q3D_DECL_DEPRECATED explicit QSkeletonCreatedChangeBase(const QAbstractSkeleton *skeleton);
~QSkeletonCreatedChangeBase();
enum SkeletonType {
@@ -74,7 +74,7 @@ private:
Q_DECLARE_PRIVATE(QSkeletonCreatedChangeBase)
};
-typedef QSharedPointer<QSkeletonCreatedChangeBase> QSkeletonCreatedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QSkeletonCreatedChangeBase> QSkeletonCreatedChangeBasePtr;
template<typename T>
class QSkeletonCreatedChange : public QSkeletonCreatedChangeBase
@@ -90,7 +90,7 @@ public:
};
template<typename T>
-using QSkeletonCreatedChangePtr = QSharedPointer<QSkeletonCreatedChange<T>>;
+using QSkeletonCreatedChangePtr Q3D_DECL_DEPRECATED = QSharedPointer<QSkeletonCreatedChange<T>>;
} // namespace Qt3DCore
diff --git a/src/core/changes/qstaticpropertyupdatedchangebase.h b/src/core/changes/qstaticpropertyupdatedchangebase.h
index b698d1f06..c59a87a20 100644
--- a/src/core/changes/qstaticpropertyupdatedchangebase.h
+++ b/src/core/changes/qstaticpropertyupdatedchangebase.h
@@ -57,12 +57,12 @@ public:
void setPropertyName(const char *name);
protected:
- explicit QStaticPropertyUpdatedChangeBase(QNodeId subjectId);
- explicit QStaticPropertyUpdatedChangeBase(QStaticPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QStaticPropertyUpdatedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QStaticPropertyUpdatedChangeBase(QStaticPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId);
Q_DECLARE_PRIVATE(QStaticPropertyUpdatedChangeBase)
};
-typedef QSharedPointer<QStaticPropertyUpdatedChangeBase> QStaticPropertyUpdatedChangeBasePtr;
+Q3D_DECL_DEPRECATED typedef QSharedPointer<QStaticPropertyUpdatedChangeBase> QStaticPropertyUpdatedChangeBasePtr;
} // namespace Qt3DCore
diff --git a/src/core/changes/qstaticpropertyvalueaddedchangebase.h b/src/core/changes/qstaticpropertyvalueaddedchangebase.h
index e56e8f18a..7e6807764 100644
--- a/src/core/changes/qstaticpropertyvalueaddedchangebase.h
+++ b/src/core/changes/qstaticpropertyvalueaddedchangebase.h
@@ -59,7 +59,7 @@ public:
protected:
Q_DECLARE_PRIVATE(QStaticPropertyValueAddedChangeBase)
- explicit QStaticPropertyValueAddedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QStaticPropertyValueAddedChangeBase(QNodeId subjectId);
QStaticPropertyValueAddedChangeBase(QStaticPropertyValueAddedChangeBasePrivate &dd,
QNodeId subjectId);
};
diff --git a/src/core/changes/qstaticpropertyvalueremovedchangebase.h b/src/core/changes/qstaticpropertyvalueremovedchangebase.h
index e9f53fb12..d1b96f83e 100644
--- a/src/core/changes/qstaticpropertyvalueremovedchangebase.h
+++ b/src/core/changes/qstaticpropertyvalueremovedchangebase.h
@@ -59,7 +59,7 @@ public:
protected:
Q_DECLARE_PRIVATE(QStaticPropertyValueRemovedChangeBase)
- explicit QStaticPropertyValueRemovedChangeBase(QNodeId subjectId);
+ Q3D_DECL_DEPRECATED explicit QStaticPropertyValueRemovedChangeBase(QNodeId subjectId);
QStaticPropertyValueRemovedChangeBase(QStaticPropertyValueRemovedChangeBasePrivate &dd,
QNodeId subjectId);
};
diff --git a/src/core/configure.json b/src/core/configure.json
index 2ba205530..2e13d9027 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -44,7 +44,7 @@
"output": [ "privateFeature" ]
},
"qt3d-profile-jobs": {
- "label": "Output Qt3D Job traces",
+ "label": "Output Qt3D Job traces (deprecated)",
"autoDetect": false,
"output": [ "privateFeature" ]
},
@@ -112,7 +112,6 @@
"entries": [
"assimp",
"system-assimp",
- "qt3d-profile-jobs",
"qt3d-profile-gl",
"qt3d-simd-sse2",
"qt3d-simd-avx2",
diff --git a/src/core/jobs/qaspectjob_p.h b/src/core/jobs/qaspectjob_p.h
index b16c3cad2..ddad09c86 100644
--- a/src/core/jobs/qaspectjob_p.h
+++ b/src/core/jobs/qaspectjob_p.h
@@ -54,6 +54,7 @@
#include <QtCore/QWeakPointer>
#include <Qt3DCore/private/qt3dcore_global_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p_p.h>
#include <Qt3DCore/qt3dcore-config.h>
QT_BEGIN_NAMESPACE
@@ -63,47 +64,6 @@ namespace Qt3DCore {
class QAspectJob;
class QAspectManager;
-#if QT_CONFIG(qt3d_profile_jobs)
-struct FrameHeader
-{
- FrameHeader()
- : frameId(0)
- , jobCount(0)
- , frameType(WorkerJob)
- {
- }
-
- enum FrameType {
- WorkerJob = 0,
- Submission
- };
-
- quint32 frameId;
- quint16 jobCount;
- quint16 frameType; // Submission or worker job
-};
-
-union JobId
-{
- quint32 typeAndInstance[2];
- quint64 id;
-};
-
-struct JobRunStats
-{
- JobRunStats()
- {
- jobId.id = 0;
- }
-
- qint64 startTime;
- qint64 endTime;
- JobId jobId;
- // QAspectJob subclasses should properly populate the jobId
- quint64 threadId;
-};
-#endif
-
class Q_3DCORE_PRIVATE_EXPORT QAspectJobPrivate
{
public:
@@ -115,29 +75,16 @@ public:
virtual void postFrame(QAspectManager *aspectManager);
QVector<QWeakPointer<QAspectJob> > m_dependencies;
-#if QT_CONFIG(qt3d_profile_jobs)
- JobRunStats m_stats;
-#endif
+ JobId m_jobId;
};
-
} // Qt3D
-#if QT_CONFIG(qt3d_profile_jobs)
-
-#include <Qt3DCore/private/qaspectjob_p.h>
-
#define SET_JOB_RUN_STAT_TYPE(job, type, instance) \
- Qt3DCore::QAspectJobPrivate::get(job)->m_stats.jobId.typeAndInstance[0] = type; \
- Qt3DCore::QAspectJobPrivate::get(job)->m_stats.jobId.typeAndInstance[1] = instance;
-
-#else
-
-#define SET_JOB_RUN_STAT_TYPE(job, type, instance) \
- Q_UNUSED(job) \
- Q_UNUSED(type) \
- Q_UNUSED(instance)
-
-#endif
+ { \
+ auto &jobId = Qt3DCore::QAspectJobPrivate::get(job)->m_jobId; \
+ jobId.typeAndInstance[0] = type; \
+ jobId.typeAndInstance[1] = instance; \
+ }
QT_END_NAMESPACE
diff --git a/src/core/jobs/qaspectjobmanager.cpp b/src/core/jobs/qaspectjobmanager.cpp
index 91394924f..be7942359 100644
--- a/src/core/jobs/qaspectjobmanager.cpp
+++ b/src/core/jobs/qaspectjobmanager.cpp
@@ -44,7 +44,7 @@
#include <QtCore/QDebug>
#include <QtCore/QThread>
#include <QtCore/QFuture>
-
+#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qthreadpooler_p.h>
#include <Qt3DCore/private/task_p.h>
@@ -52,9 +52,10 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-QAspectJobManager::QAspectJobManager(QObject *parent)
+QAspectJobManager::QAspectJobManager(QAspectManager *parent)
: QAbstractAspectJobManager(parent)
, m_threadPooler(new QThreadPooler(this))
+ , m_aspectManager(parent)
{
}
@@ -69,12 +70,16 @@ void QAspectJobManager::initialize()
// Adds all Aspect Jobs to be processed for a frame
void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue)
{
+ auto systemService = m_aspectManager ? m_aspectManager->serviceLocator()->systemInformation() : nullptr;
+ if (systemService)
+ systemService->writePreviousFrameTraces();
+
// Convert QJobs to Tasks
QHash<QAspectJob *, AspectTaskRunnable *> tasksMap;
QVector<RunnableInterface *> taskList;
taskList.reserve(jobQueue.size());
for (const QAspectJobPtr &job : jobQueue) {
- AspectTaskRunnable *task = new AspectTaskRunnable();
+ AspectTaskRunnable *task = new AspectTaskRunnable(systemService);
task->m_job = job;
tasksMap.insert(job.data(), task);
@@ -99,9 +104,6 @@ void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue)
taskDepender->m_dependerCount += dependerCount;
}
-#if QT_CONFIG(qt3d_profile_jobs)
- QThreadPooler::writeFrameJobLogStats();
-#endif
m_threadPooler->mapDependables(taskList);
}
diff --git a/src/core/jobs/qaspectjobmanager_p.h b/src/core/jobs/qaspectjobmanager_p.h
index 77e535491..acbd0263e 100644
--- a/src/core/jobs/qaspectjobmanager_p.h
+++ b/src/core/jobs/qaspectjobmanager_p.h
@@ -63,12 +63,13 @@ namespace Qt3DCore {
class QThreadPooler;
class DependencyHandler;
+class QAspectManager;
class Q_3DCORE_PRIVATE_EXPORT QAspectJobManager : public QAbstractAspectJobManager
{
Q_OBJECT
public:
- explicit QAspectJobManager(QObject *parent = 0);
+ explicit QAspectJobManager(QAspectManager *parent = nullptr);
~QAspectJobManager();
void initialize() override;
@@ -81,6 +82,7 @@ public:
private:
QThreadPooler *m_threadPooler;
+ QAspectManager *m_aspectManager;
};
} // namespace Qt3DCore
diff --git a/src/core/jobs/qaspectjobproviderinterface_p.h b/src/core/jobs/qaspectjobproviderinterface_p.h
index 29b44b3c1..b521fea68 100644
--- a/src/core/jobs/qaspectjobproviderinterface_p.h
+++ b/src/core/jobs/qaspectjobproviderinterface_p.h
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
class QScheduler;
+class QAspectManager;
class QAspectJobProviderInterface
{
@@ -69,6 +70,7 @@ public:
private:
virtual QVector<QAspectJobPtr> jobsToExecute(qint64 time) = 0;
+ virtual void jobsDone(QAspectManager *manager) = 0;
friend class QScheduler;
};
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index a9f4e7a31..f5c50062a 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -40,45 +40,27 @@
#include "qthreadpooler_p.h"
#include <QtCore/QDebug>
-#if QT_CONFIG(qt3d_profile_jobs)
-
-#ifdef Q_OS_ANDROID
-#include <QtCore/QStandardPaths>
-#endif
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QFile>
-#include <QtCore/QThreadStorage>
-#include <QtCore/QDateTime>
-#include <QtCore/QCoreApplication>
-#endif
-
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-#if QT_CONFIG(qt3d_profile_jobs)
-QElapsedTimer QThreadPooler::m_jobsStatTimer;
-#endif
-
QThreadPooler::QThreadPooler(QObject *parent)
: QObject(parent)
, m_futureInterface(nullptr)
, m_mutex()
, m_taskCount(0)
+ , m_threadPool(QThreadPool::globalInstance())
{
const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT");
if (!maxThreadCount.isEmpty()) {
bool conversionOK = false;
const int maxThreadCountValue = maxThreadCount.toInt(&conversionOK);
if (conversionOK)
- m_threadPool.setMaxThreadCount(maxThreadCountValue);
+ m_threadPool->setMaxThreadCount(maxThreadCountValue);
}
+
// Ensures that threads will never be recycled
- m_threadPool.setExpiryTimeout(-1);
-#if QT_CONFIG(qt3d_profile_jobs)
- QThreadPooler::m_jobsStatTimer.start();
-#endif
+ m_threadPool->setExpiryTimeout(-1);
}
QThreadPooler::~QThreadPooler()
@@ -105,7 +87,7 @@ void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks)
if (!hasDependencies(*it) && !(*it)->reserved()) {
(*it)->setReserved(true);
(*it)->setPooler(this);
- m_threadPool.start((*it));
+ m_threadPool->start((*it));
}
}
}
@@ -125,7 +107,7 @@ void QThreadPooler::taskFinished(RunnableInterface *task)
if (!aspectTask->reserved()) {
aspectTask->setReserved(true);
aspectTask->setPooler(this);
- m_threadPool.start(aspectTask);
+ m_threadPool->start(aspectTask);
}
}
}
@@ -188,105 +170,9 @@ int QThreadPooler::currentCount() const
int QThreadPooler::maxThreadCount() const
{
- return m_threadPool.maxThreadCount();
-}
-
-#if QT_CONFIG(qt3d_profile_jobs)
-
-QThreadStorage<QVector<JobRunStats> *> jobStatsCached;
-
-QVector<QVector<JobRunStats> *> localStorages;
-QVector<JobRunStats> *submissionStorage = nullptr;
-
-QMutex localStoragesMutex;
-
-// Called by the jobs
-void QThreadPooler::addJobLogStatsEntry(JobRunStats &stats)
-{
- if (!jobStatsCached.hasLocalData()) {
- auto jobVector = new QVector<JobRunStats>;
- jobStatsCached.setLocalData(jobVector);
- QMutexLocker lock(&localStoragesMutex);
- localStorages.push_back(jobVector);
- }
- jobStatsCached.localData()->push_back(stats);
-}
-
-// Called after jobs have been executed (MainThread QAspectJobManager::enqueueJobs)
-void QThreadPooler::writeFrameJobLogStats()
-{
- static QScopedPointer<QFile> traceFile;
- static quint32 frameId = 0;
- if (!traceFile) {
- const QString fileName = QStringLiteral("trace_") + QCoreApplication::applicationName() + QDateTime::currentDateTime().toString(QStringLiteral("_ddd_dd_MM_yy-hh_mm_ss_"))+ QSysInfo::productType() + QStringLiteral("_") + QSysInfo::buildAbi() + QStringLiteral(".qt3d");
-#ifdef Q_OS_ANDROID
- traceFile.reset(new QFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/") + fileName));
-#else
- traceFile.reset(new QFile(fileName));
-#endif
- if (!traceFile->open(QFile::WriteOnly|QFile::Truncate))
- qCritical("Failed to open trace file");
- }
-
- // Write Aspect + Job threads
- {
- FrameHeader header;
- header.frameId = frameId;
- header.jobCount = 0;
-
- for (const QVector<JobRunStats> *storage : qAsConst(localStorages))
- header.jobCount += storage->size();
-
- traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader));
-
- for (QVector<JobRunStats> *storage : qAsConst(localStorages)) {
- for (const JobRunStats &stat : *storage)
- traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats));
- storage->clear();
- }
- }
-
- // Write submission thread
- {
- QMutexLocker lock(&localStoragesMutex);
- const int submissionJobSize = submissionStorage != nullptr ? submissionStorage->size() : 0;
- if (submissionJobSize > 0) {
- FrameHeader header;
- header.frameId = frameId;
- header.jobCount = submissionJobSize;
- header.frameType = FrameHeader::Submission;
-
- traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader));
-
- for (const JobRunStats &stat : *submissionStorage)
- traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats));
- submissionStorage->clear();
- }
- }
-
- traceFile->flush();
- ++frameId;
-}
-
-// Called from Submission thread (which can be main thread in Manual drive mode)
-void QThreadPooler::addSubmissionLogStatsEntry(JobRunStats &stats)
-{
- QMutexLocker lock(&localStoragesMutex);
- if (!jobStatsCached.hasLocalData()) {
- submissionStorage = new QVector<JobRunStats>;
- jobStatsCached.setLocalData(submissionStorage);
- }
-
- // Handle the case where submission thread is also the main thread (Scene/Manual drive modes with no RenderThread)
- if (submissionStorage == nullptr && jobStatsCached.hasLocalData())
- submissionStorage = new QVector<JobRunStats>;
-
- // When having no submission thread this can be null
- submissionStorage->push_back(stats);
+ return m_threadPool->maxThreadCount();
}
-#endif
-
} // namespace Qt3DCore
QT_END_NAMESPACE
diff --git a/src/core/jobs/qthreadpooler_p.h b/src/core/jobs/qthreadpooler_p.h
index 65459efba..1970641b8 100644
--- a/src/core/jobs/qthreadpooler_p.h
+++ b/src/core/jobs/qthreadpooler_p.h
@@ -60,10 +60,6 @@
#include <Qt3DCore/private/qaspectjob_p.h>
#include <Qt3DCore/private/task_p.h>
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <QtCore/QElapsedTimer>
-#endif
-
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
@@ -81,17 +77,6 @@ public:
QFuture<void> future();
int maxThreadCount() const;
-#if QT_CONFIG(qt3d_profile_jobs)
- static QElapsedTimer m_jobsStatTimer;
-
- // Aspects + Job threads
- static void addJobLogStatsEntry(JobRunStats &stats);
- static void writeFrameJobLogStats();
-
- // Submission thread
- static void addSubmissionLogStatsEntry(JobRunStats &stats);
-
-#endif
private:
void enqueueTasks(const QVector<RunnableInterface *> &tasks);
@@ -103,7 +88,7 @@ private:
QFutureInterface<void> *m_futureInterface;
QMutex m_mutex;
QAtomicInt m_taskCount;
- QThreadPool m_threadPool;
+ QThreadPool *m_threadPool;
};
} // namespace Qt3DCore
diff --git a/src/core/jobs/task.cpp b/src/core/jobs/task.cpp
index 091aabfd6..1dd5712c9 100644
--- a/src/core/jobs/task.cpp
+++ b/src/core/jobs/task.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QMutexLocker>
#include <Qt3DCore/private/qthreadpooler_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p_p.h>
QT_BEGIN_NAMESPACE
@@ -55,8 +56,10 @@ RunnableInterface::~RunnableInterface()
// Aspect task
-AspectTaskRunnable::AspectTaskRunnable()
- : m_pooler(nullptr)
+AspectTaskRunnable::AspectTaskRunnable(QSystemInformationService *service)
+ : m_service(service)
+ , m_pooler(nullptr)
+ , m_id(0)
, m_reserved(false)
{
}
@@ -68,21 +71,9 @@ AspectTaskRunnable::~AspectTaskRunnable()
void AspectTaskRunnable::run()
{
if (m_job) {
-#if QT_CONFIG(qt3d_profile_jobs)
QAspectJobPrivate *jobD = QAspectJobPrivate::get(m_job.data());
- if (m_pooler) {
- jobD->m_stats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- jobD->m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
- }
-#endif
+ QTaskLogger logger(m_pooler ? m_service : nullptr, jobD->m_jobId, QTaskLogger::AspectJob);
m_job->run();
-#if QT_CONFIG(qt3d_profile_jobs)
- if (m_pooler) {
- jobD->m_stats.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- // Add current job's stats to log output
- QThreadPooler::addJobLogStatsEntry(jobD->m_stats);
- }
-#endif
}
// We could have an append sub task or something in here
diff --git a/src/core/jobs/task_p.h b/src/core/jobs/task_p.h
index c81882719..ff411539f 100644
--- a/src/core/jobs/task_p.h
+++ b/src/core/jobs/task_p.h
@@ -65,6 +65,7 @@ namespace Qt3DCore {
class JobRunner;
class DependencyHandler;
class QThreadPooler;
+class QSystemInformationService;
class RunnableInterface : public QRunnable
{
@@ -92,7 +93,7 @@ public:
class AspectTaskRunnable : public RunnableInterface
{
public:
- AspectTaskRunnable();
+ AspectTaskRunnable(QSystemInformationService *service);
~AspectTaskRunnable();
void run() override;
@@ -113,6 +114,7 @@ public:
int m_dependerCount = 0;
private:
+ QSystemInformationService *m_service;
QThreadPooler *m_pooler;
int m_id; // For testing purposes for now
bool m_reserved;
diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp
index e5f93e96f..4138ea060 100644
--- a/src/core/nodes/qbackendnode.cpp
+++ b/src/core/nodes/qbackendnode.cpp
@@ -220,6 +220,7 @@ QBackendNode::QBackendNode(QBackendNodePrivate &dd)
/*!
* Notifies observers of scene change \a e.
+ * \obsolete
*/
void QBackendNode::notifyObservers(const QSceneChangePtr &e)
{
@@ -228,6 +229,8 @@ void QBackendNode::notifyObservers(const QSceneChangePtr &e)
}
/*!
+ \obsolete
+
Send the command named \a name with contents \a data,
and specify \a replyTo as the command id to which the
reply needs to be sent.
@@ -247,6 +250,7 @@ QNodeCommand::CommandId QBackendNode::sendCommand(const QString &name,
/*!
Send the reply to \a command.
+ \obsolete
*/
void QBackendNode::sendReply(const QNodeCommandPtr &command)
{
@@ -254,9 +258,12 @@ void QBackendNode::sendReply(const QNodeCommandPtr &command)
notifyObservers(command);
}
+/*!
+ * \obsolete
+ */
void QBackendNode::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
{
- Q_UNUSED(change);
+ Q_UNUSED(change)
qCDebug(Nodes) << Q_FUNC_INFO << change->metaObject()->className() << "does not override";
}
@@ -270,8 +277,7 @@ void QBackendNode::setEnabled(bool enabled) Q_DECL_NOTHROW
}
/*!
- * TODO
- * \a e
+ * \obsolete
*/
void QBackendNode::sceneChangeEvent(const QSceneChangePtr &e)
{
diff --git a/src/core/nodes/qbackendnode.h b/src/core/nodes/qbackendnode.h
index 550ced04f..691375999 100644
--- a/src/core/nodes/qbackendnode.h
+++ b/src/core/nodes/qbackendnode.h
@@ -90,18 +90,18 @@ public:
protected:
Q_DECLARE_PRIVATE(QBackendNode)
explicit QBackendNode(QBackendNodePrivate &dd);
- void notifyObservers(const QSceneChangePtr &e);
- QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data,
- QNodeCommand::CommandId replyTo = QNodeCommand::CommandId());
- void sendReply(const QNodeCommandPtr &command);
- virtual void sceneChangeEvent(const QSceneChangePtr &e);
+ Q3D_DECL_DEPRECATED void notifyObservers(const QSceneChangePtr &e);
+ Q3D_DECL_DEPRECATED QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data,
+ QNodeCommand::CommandId replyTo = QNodeCommand::CommandId());
+ Q3D_DECL_DEPRECATED void sendReply(const QNodeCommandPtr &command);
+ Q3D_DECL_DEPRECATED virtual void sceneChangeEvent(const QSceneChangePtr &e);
QBackendNodePrivate *d_ptr;
private:
Q_DISABLE_COPY(QBackendNode)
void setPeerId(QNodeId id) Q_DECL_NOEXCEPT;
- virtual void initializeFromPeer(const QNodeCreatedChangeBasePtr &change);
+ Q3D_DECL_DEPRECATED virtual void initializeFromPeer(const QNodeCreatedChangeBasePtr &change);
friend class QBackendNodePropertyChange;
friend class QAbstractAspectPrivate;
diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp
index 024991387..93601901f 100644
--- a/src/core/nodes/qentity.cpp
+++ b/src/core/nodes/qentity.cpp
@@ -75,7 +75,7 @@ namespace Qt3DCore {
*/
/*!
- \fn template<typename T> QVector<T *> QEntity::componentsOfType() const
+ \fn template<typename T> QVector<T *> Qt3DCore::QEntity::componentsOfType() const
Returns all the components added to this entity that can be cast to
type T or an empty vector if there are no such components.
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index cfe83f4db..ad084242f 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -382,7 +382,7 @@ void QNodePrivate::unregisterNotifiedProperties()
void QNodePrivate::propertyChanged(int propertyIndex)
{
- Q_UNUSED(propertyIndex);
+ Q_UNUSED(propertyIndex)
// Bail out early if we can to avoid the cost below
if (m_blockNotifications)
@@ -539,6 +539,8 @@ void QNode::notifyObservers(const QSceneChangePtr &change)
}
/*!
+ \obsolete
+
Called when one or more backend aspects sends a notification \a change to the
current Qt3DCore::QNode instance.
@@ -547,7 +549,7 @@ void QNode::notifyObservers(const QSceneChangePtr &change)
*/
void QNode::sceneChangeEvent(const QSceneChangePtr &change)
{
- Q_UNUSED(change);
+ Q_UNUSED(change)
if (change->type() == Qt3DCore::PropertyUpdated) {
// TODO: Do this more efficiently. We could pass the metaobject and property
// index to the animation aspect via the QChannelMapping. This would
@@ -594,8 +596,8 @@ QScene *QNodePrivate::scene() const
*/
void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value)
{
- Q_UNUSED(name);
- Q_UNUSED(value);
+ Q_UNUSED(name)
+ Q_UNUSED(value)
// Bail out early if we can to avoid operator new
if (m_blockNotifications)
@@ -606,8 +608,8 @@ void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value)
void QNodePrivate::notifyDynamicPropertyChange(const QByteArray &name, const QVariant &value)
{
- Q_UNUSED(name);
- Q_UNUSED(value);
+ Q_UNUSED(name)
+ Q_UNUSED(value)
// Bail out early if we can to avoid operator new
if (m_blockNotifications)
@@ -683,6 +685,11 @@ void QNodePrivate::update()
void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change)
{
if (m_changeArbiter) {
+ // Ensure node has its postConstructorInit called if we reach this
+ // point, we could otherwise endup referencing a node that has yet
+ // to be created in the backend
+ QNodePrivate::get(node)->_q_ensureBackendNodeCreated();
+
Q_Q(QNode);
m_changeArbiter->addDirtyFrontEndNode(q, node, property, change);
}
@@ -787,10 +794,9 @@ QNode::~QNode()
{
Q_D(QNode);
// Disconnect each connection that was stored
- for (auto it = d->m_destructionConnections.begin(), end = d->m_destructionConnections.end(); it != end; ++it)
- QObject::disconnect(it.value());
+ for (const auto &nodeConnectionPair : qAsConst(d->m_destructionConnections))
+ QObject::disconnect(nodeConnectionPair.second);
d->m_destructionConnections.clear();
-
Q_EMIT nodeDestroyed();
// Notify the backend that the parent lost this node as a child and
@@ -993,6 +999,9 @@ void QNode::clearPropertyTrackings()
d->updatePropertyTrackMode();
}
+/*!
+ * \obsolete
+ */
QNodeCreatedChangeBasePtr QNode::createNodeCreationChange() const
{
// Uncomment this when implementing new frontend and backend types.
@@ -1045,6 +1054,7 @@ QNodeCreatedChangeBasePtr QNode::createNodeCreationChange() const
*/
/*!
* \brief Sends a command message to the backend node
+ * \obsolete
*
* Creates a QNodeCommand message and dispatches it to the backend node. The
* command is given and a \a name and some \a data which can be used in the
@@ -1075,6 +1085,7 @@ QNodeCommand::CommandId QNode::sendCommand(const QString &name,
/*!
* \brief Send a \a command back to the backend node.
+ * \obsolete
*
* Assumes the command is to be to sent back in reply to itself to the backend node.
*
diff --git a/src/core/nodes/qnode.h b/src/core/nodes/qnode.h
index 9ca817fb6..efdec8da5 100644
--- a/src/core/nodes/qnode.h
+++ b/src/core/nodes/qnode.h
@@ -99,9 +99,9 @@ public:
void clearPropertyTracking(const QString &propertyName);
void clearPropertyTrackings();
- QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data = QVariant(),
- QNodeCommand::CommandId replyTo = QNodeCommand::CommandId());
- void sendReply(const QNodeCommandPtr &command);
+ Q3D_DECL_DEPRECATED QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data = QVariant(),
+ QNodeCommand::CommandId replyTo = QNodeCommand::CommandId());
+ Q3D_DECL_DEPRECATED void sendReply(const QNodeCommandPtr &command);
public Q_SLOTS:
void setParent(QNode *parent);
@@ -116,12 +116,12 @@ Q_SIGNALS:
protected:
explicit QNode(QNodePrivate &dd, QNode *parent = nullptr);
- void notifyObservers(const QSceneChangePtr &change);
- virtual void sceneChangeEvent(const QSceneChangePtr &change);
+ Q3D_DECL_DEPRECATED void notifyObservers(const QSceneChangePtr &change);
+ Q3D_DECL_DEPRECATED virtual void sceneChangeEvent(const QSceneChangePtr &change);
private:
Q_DECLARE_PRIVATE(QNode)
- virtual QNodeCreatedChangeBasePtr createNodeCreationChange() const;
+ Q3D_DECL_DEPRECATED virtual QNodeCreatedChangeBasePtr createNodeCreationChange() const;
// We only want setParent(QNode *) to be callable
// when dealing with QNode objects
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index a7a300a5e..61aa81c81 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -124,7 +124,7 @@ public:
// If the node is destoyed, we make sure not to keep a dangling pointer to it
Q_Q(QNode);
auto f = [q, func]() { (static_cast<Caller *>(q)->*func)(nullptr); };
- m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)});
}
template<typename Caller, typename NodeType>
@@ -133,7 +133,7 @@ public:
// If the node is destoyed, we make sure not to keep a dangling pointer to it
Q_Q(QNode);
auto f = [q, func, node]() { (static_cast<Caller *>(q)->*func)(node); };
- m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)});
}
template<typename Caller, typename ValueType>
@@ -146,7 +146,7 @@ public:
// If the node is destoyed, we make sure not to keep a dangling pointer to it
Q_Q(QNode);
auto f = [q, func, resetValue]() { (static_cast<Caller *>(q)->*func)(resetValue); };
- m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)});
}
template<typename Caller, typename NodeType>
@@ -154,12 +154,21 @@ public:
{
// If the node is destoyed, we make sure not to keep a dangling pointer to it
auto f = [this, func, node]() { (static_cast<Caller *>(this)->*func)(node); };
- m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f));
+ m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)});
}
void unregisterDestructionHelper(QNode *node)
{
- QObject::disconnect(m_destructionConnections.take(node));
+ m_destructionConnections.erase(std::remove_if(m_destructionConnections.begin(),
+ m_destructionConnections.end(),
+ [node] (const QPair<QNode *, QMetaObject::Connection> &nodeConnectionPair) {
+ if (nodeConnectionPair.first == node) {
+ QObject::disconnect(nodeConnectionPair.second);
+ return true;
+ }
+ return false;
+ }),
+ m_destructionConnections.end());
}
static const QMetaObject *findStaticMetaObject(const QMetaObject *metaObject);
@@ -184,7 +193,7 @@ private:
friend class PropertyChangeHandler<QNodePrivate>;
bool m_propertyChangesSetup;
PropertyChangeHandler<QNodePrivate> m_signals;
- QHash<QNode *, QMetaObject::Connection> m_destructionConnections;
+ QVector<QPair<QNode *, QMetaObject::Connection>> m_destructionConnections;
};
class NodePostConstructorInit : public QObject
diff --git a/src/core/qchangearbiter_p.h b/src/core/qchangearbiter_p.h
index f31480685..7d48c390a 100644
--- a/src/core/qchangearbiter_p.h
+++ b/src/core/qchangearbiter_p.h
@@ -64,6 +64,7 @@
#include <Qt3DCore/private/qlockableobserverinterface_p.h>
#include <Qt3DCore/private/qt3dcore_global_p.h>
+#include <Qt3DCore/private/qscenechange_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/core/qpostman_p.h b/src/core/qpostman_p.h
index 23c638239..3e5f91742 100644
--- a/src/core/qpostman_p.h
+++ b/src/core/qpostman_p.h
@@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QPostman final
{
Q_OBJECT
public:
- explicit QPostman(QObject *parent = 0);
+ explicit QPostman(QObject *parent = nullptr);
~QPostman();
void setScene(QScene *sceneLookup) final;
diff --git a/src/core/qscheduler.cpp b/src/core/qscheduler.cpp
index edfbb391c..2294976ca 100644
--- a/src/core/qscheduler.cpp
+++ b/src/core/qscheduler.cpp
@@ -43,6 +43,7 @@
#include <Qt3DCore/private/qabstractaspect_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DCore/private/qaspectjob_p.h>
#include <Qt3DCore/private/qabstractaspectjobmanager_p.h>
QT_BEGIN_NAMESPACE
@@ -69,7 +70,7 @@ QAspectManager *QScheduler::aspectManager() const
return m_aspectManager;
}
-void QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time)
+int QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time)
{
QVector<QAspectJobPtr> jobQueue;
@@ -92,8 +93,17 @@ void QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time)
m_aspectManager->jobManager()->waitForAllJobs();
- for (auto &job : qAsConst(jobQueue))
- job->postFrame(m_aspectManager);
+ {
+ QTaskLogger logger(m_aspectManager->serviceLocator()->systemInformation(), 4097, 0);
+
+ for (auto &job : qAsConst(jobQueue))
+ QAspectJobPrivate::get(job.data())->postFrame(m_aspectManager);
+
+ for (QAbstractAspect *aspect : aspects)
+ QAbstractAspectPrivate::get(aspect)->jobsDone(m_aspectManager);
+ }
+
+ return jobQueue.size();
}
} // namespace Qt3DCore
diff --git a/src/core/qscheduler_p.h b/src/core/qscheduler_p.h
index 9b1685e54..dd4101ef2 100644
--- a/src/core/qscheduler_p.h
+++ b/src/core/qscheduler_p.h
@@ -64,13 +64,13 @@ class QScheduler : public QObject
{
Q_OBJECT
public:
- explicit QScheduler(QObject *parent = 0);
+ explicit QScheduler(QObject *parent = nullptr);
~QScheduler();
void setAspectManager(QAspectManager *aspectManager);
QAspectManager *aspectManager() const;
- virtual void scheduleAndWaitForFrameAspectJobs(qint64 time);
+ virtual int scheduleAndWaitForFrameAspectJobs(qint64 time);
private:
QAspectManager *m_aspectManager;
diff --git a/src/core/qt3dcore_global.h b/src/core/qt3dcore_global.h
index b2ad787c0..e932b02ba 100644
--- a/src/core/qt3dcore_global.h
+++ b/src/core/qt3dcore_global.h
@@ -55,6 +55,12 @@ QT_BEGIN_NAMESPACE
# define Q_3DCORESHARED_EXPORT
#endif
+#ifdef BUILD_QT3D_MODULE
+#define Q3D_DECL_DEPRECATED
+#else
+#define Q3D_DECL_DEPRECATED Q_DECL_DEPRECATED
+#endif
+
#define QT3D_DECLARE_TYPEINFO(NS, Class, Flags) \
} /* NS */ \
Q_DECLARE_TYPEINFO(NS :: Class, Flags); \
diff --git a/src/core/resources/qframeallocator.cpp b/src/core/resources/qframeallocator.cpp
index 61a82a2b4..e85ae4057 100644
--- a/src/core/resources/qframeallocator.cpp
+++ b/src/core/resources/qframeallocator.cpp
@@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
QFrameAllocatorPrivate::QFrameAllocatorPrivate()
+ : m_maxObjectSize(0U)
+ , m_alignment(0U)
{
}
diff --git a/src/core/resources/qloadgltf_p.h b/src/core/resources/qloadgltf_p.h
new file mode 100644
index 000000000..be7ee0d5f
--- /dev/null
+++ b/src/core/resources/qloadgltf_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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 QT3DCORE_QLOADGLTF_P_H
+#define QT3DCORE_QLOADGLTF_P_H
+
+#include <QtCore/qcborarray.h>
+#include <QtCore/qcbormap.h>
+#include <QtCore/qcborvalue.h>
+#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qjsonobject.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+inline QJsonDocument qLoadGLTF(const QByteArray &gltfData)
+{
+#if QT_CONFIG(binaryjson)
+ {
+ QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(gltfData);
+ if (!sceneDocument.isNull())
+ return sceneDocument;
+ }
+#endif
+ {
+ const QCborValue cbor = QCborValue::fromCbor(gltfData);
+ if (cbor.isMap())
+ return QJsonDocument(cbor.toMap().toJsonObject());
+ if (cbor.isArray())
+ return QJsonDocument(cbor.toArray().toJsonArray());
+ }
+ return QJsonDocument::fromJson(gltfData);
+}
+
+#endif // QT3DCORE_QLOADGLTF_P_H
diff --git a/src/core/resources/resources.pri b/src/core/resources/resources.pri
index 7f3ce4bdc..89540a36d 100644
--- a/src/core/resources/resources.pri
+++ b/src/core/resources/resources.pri
@@ -1,4 +1,5 @@
HEADERS += \
+ $$PWD/qloadgltf_p.h \
$$PWD/qresourcemanager_p.h \
$$PWD/qcircularbuffer_p.h \
$$PWD/qboundedcircularbuffer_p.h \
diff --git a/src/core/services/nullservices_p.h b/src/core/services/nullservices_p.h
index 30dc2d543..6b2d1b029 100644
--- a/src/core/services/nullservices_p.h
+++ b/src/core/services/nullservices_p.h
@@ -54,25 +54,11 @@
#include <Qt3DCore/qt3dcore_global.h>
#include <Qt3DCore/private/qopenglinformationservice_p.h>
-#include <Qt3DCore/private/qsysteminformationservice_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-class NullSystemInformationService : public QSystemInformationService
-{
-public:
- NullSystemInformationService()
- : QSystemInformationService(QStringLiteral("Null System Information Service"))
- {}
- ~NullSystemInformationService() {}
-
- QStringList aspectNames() const final { return QStringList(); }
- int threadPoolThreadCount() const final { return 0; }
-};
-
-
class NullOpenGLInformationService : public QOpenGLInformationService
{
public:
diff --git a/src/core/services/qservicelocator.cpp b/src/core/services/qservicelocator.cpp
index bdcb4a521..73a40c2e4 100644
--- a/src/core/services/qservicelocator.cpp
+++ b/src/core/services/qservicelocator.cpp
@@ -46,6 +46,7 @@
#include <Qt3DCore/private/qdownloadhelperservice_p.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <Qt3DCore/private/qtickclockservice_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p.h>
QT_BEGIN_NAMESPACE
@@ -85,16 +86,19 @@ QString QAbstractServiceProvider::description() const
}
+class QAspectEngine;
+
class QServiceLocatorPrivate
{
public:
- QServiceLocatorPrivate()
- : m_nonNullDefaultServices(0)
+ QServiceLocatorPrivate(QAspectEngine *aspectEngine)
+ : m_systemInfo(aspectEngine)
+ , m_nonNullDefaultServices(0)
{}
QHash<int, QAbstractServiceProvider *> m_services;
- NullSystemInformationService m_nullSystemInfo;
+ QSystemInformationService m_systemInfo;
NullOpenGLInformationService m_nullOpenGLInfo;
QTickClockService m_defaultFrameAdvanceService;
QEventFilterService m_eventFilterService;
@@ -128,8 +132,8 @@ public:
/*
Creates an instance of QServiceLocator.
*/
-QServiceLocator::QServiceLocator()
- : d_ptr(new QServiceLocatorPrivate)
+QServiceLocator::QServiceLocator(QAspectEngine *aspectEngine)
+ : d_ptr(new QServiceLocatorPrivate(aspectEngine))
{
}
@@ -196,7 +200,7 @@ int QServiceLocator::serviceCount() const
QSystemInformationService *QServiceLocator::systemInformation()
{
Q_D(QServiceLocator);
- return static_cast<QSystemInformationService *>(d->m_services.value(SystemInformation, &d->m_nullSystemInfo));
+ return static_cast<QSystemInformationService *>(d->m_services.value(SystemInformation, &d->m_systemInfo));
}
/*
diff --git a/src/core/services/qservicelocator_p.h b/src/core/services/qservicelocator_p.h
index 9111a14ab..5bf71a996 100644
--- a/src/core/services/qservicelocator_p.h
+++ b/src/core/services/qservicelocator_p.h
@@ -85,11 +85,12 @@ class QSystemInformationService;
class QServiceLocatorPrivate;
class QEventFilterService;
class QDownloadHelperService;
+class QAspectEngine;
class Q_3DCORESHARED_EXPORT QServiceLocator
{
public:
- QServiceLocator();
+ QServiceLocator(QAspectEngine *aspectEngine = nullptr);
~QServiceLocator();
enum ServiceType {
diff --git a/src/core/services/qsysteminformationservice.cpp b/src/core/services/qsysteminformationservice.cpp
index f11e0c3d1..40f3594fb 100644
--- a/src/core/services/qsysteminformationservice.cpp
+++ b/src/core/services/qsysteminformationservice.cpp
@@ -40,10 +40,220 @@
#include "qsysteminformationservice_p.h"
#include "qsysteminformationservice_p_p.h"
+#ifdef Q_OS_ANDROID
+#include <QtCore/QStandardPaths>
+#endif
+
+#include <QtCore/QThreadPool>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QDateTime>
+#include <QtCore/QCoreApplication>
+
+#include <Qt3DCore/QAspectEngine>
+#include <Qt3DCore/QAbstractAspect>
+#include <Qt3DCore/private/qaspectengine_p.h>
+#include <Qt3DCore/private/aspectcommanddebugger_p.h>
+
QT_BEGIN_NAMESPACE
+namespace {
+
+struct FrameHeader
+{
+ FrameHeader()
+ : frameId(0)
+ , jobCount(0)
+ , frameType(WorkerJob)
+ {
+ }
+
+ enum FrameType {
+ WorkerJob = 0,
+ Submission
+ };
+
+ quint32 frameId;
+ quint16 jobCount;
+ quint16 frameType; // Submission or worker job
+};
+
+}
namespace Qt3DCore {
+QSystemInformationServicePrivate::QSystemInformationServicePrivate(QAspectEngine *aspectEngine,
+ const QString &description)
+ : QAbstractServiceProviderPrivate(QServiceLocator::SystemInformation, description)
+ , m_aspectEngine(aspectEngine)
+ , m_submissionStorage(nullptr)
+ , m_frameId(0)
+ , m_commandDebugger(nullptr)
+{
+ m_traceEnabled = qEnvironmentVariableIsSet("QT3D_TRACE_ENABLED");
+ if (m_traceEnabled)
+ m_jobsStatTimer.start();
+
+ const bool commandServerEnabled = qEnvironmentVariableIsSet("QT3D_COMMAND_SERVER_ENABLED");
+ if (commandServerEnabled) {
+ m_commandDebugger = new Debug::AspectCommandDebugger(q_func());
+ m_commandDebugger->initialize();
+ }
+}
+
+QSystemInformationServicePrivate::~QSystemInformationServicePrivate() = default;
+
+QSystemInformationServicePrivate *QSystemInformationServicePrivate::get(QSystemInformationService *q)
+{
+ return q->d_func();
+}
+
+// Called by the jobs
+void QSystemInformationServicePrivate::addJobLogStatsEntry(QSystemInformationServicePrivate::JobRunStats &stats)
+{
+ if (!m_traceEnabled)
+ return;
+
+ if (!m_jobStatsCached.hasLocalData()) {
+ auto jobVector = new QVector<JobRunStats>;
+ m_jobStatsCached.setLocalData(jobVector);
+ QMutexLocker lock(&m_localStoragesMutex);
+ m_localStorages.push_back(jobVector);
+ }
+ m_jobStatsCached.localData()->push_back(stats);
+}
+
+// Called from Submission thread (which can be main thread in Manual drive mode)
+void QSystemInformationServicePrivate::addSubmissionLogStatsEntry(QSystemInformationServicePrivate::JobRunStats &stats)
+{
+ if (!m_traceEnabled)
+ return;
+
+ QMutexLocker lock(&m_localStoragesMutex);
+ if (!m_jobStatsCached.hasLocalData()) {
+ m_submissionStorage = new QVector<JobRunStats>;
+ m_jobStatsCached.setLocalData(m_submissionStorage);
+ }
+
+ // Handle the case where submission thread is also the main thread (Scene/Manual drive modes with no RenderThread)
+ if (m_submissionStorage == nullptr && m_jobStatsCached.hasLocalData())
+ m_submissionStorage = new QVector<JobRunStats>;
+
+ // When having no submission thread this can be null
+ m_submissionStorage->push_back(stats);
+}
+
+// Called after jobs have been executed (MainThread QAspectJobManager::enqueueJobs)
+void QSystemInformationServicePrivate::writeFrameJobLogStats()
+{
+ if (!m_traceEnabled)
+ return;
+
+ using JobRunStats = QSystemInformationServicePrivate::JobRunStats;
+
+ if (!m_traceFile) {
+ const QString fileName = QStringLiteral("trace_") + QCoreApplication::applicationName() + QDateTime::currentDateTime().toString(QStringLiteral("_ddd_dd_MM_yy-hh_mm_ss_"))+ QSysInfo::productType() + QStringLiteral("_") + QSysInfo::buildAbi() + QStringLiteral(".qt3d");
+#ifdef Q_OS_ANDROID
+ m_traceFile.reset(new QFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/") + fileName));
+#else
+ // TODO fix for iOS
+ m_traceFile.reset(new QFile(fileName));
+#endif
+ if (!m_traceFile->open(QFile::WriteOnly|QFile::Truncate))
+ qCritical("Failed to open trace file");
+ }
+
+ // Write Aspect + Job threads
+ {
+ FrameHeader header;
+ header.frameId = m_frameId;
+ header.jobCount = 0;
+
+ for (const QVector<JobRunStats> *storage : qAsConst(m_localStorages))
+ header.jobCount += storage->size();
+
+ m_traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader));
+
+ for (QVector<JobRunStats> *storage : qAsConst(m_localStorages)) {
+ for (const JobRunStats &stat : *storage)
+ m_traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats));
+ storage->clear();
+ }
+ }
+
+ // Write submission thread
+ {
+ QMutexLocker lock(&m_localStoragesMutex);
+ const int submissionJobSize = m_submissionStorage != nullptr ? m_submissionStorage->size() : 0;
+ if (submissionJobSize > 0) {
+ FrameHeader header;
+ header.frameId = m_frameId;
+ header.jobCount = submissionJobSize;
+ header.frameType = FrameHeader::Submission;
+
+ m_traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader));
+
+ for (const JobRunStats &stat : *m_submissionStorage)
+ m_traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats));
+ m_submissionStorage->clear();
+ }
+ }
+
+ m_traceFile->flush();
+ ++m_frameId;
+}
+
+
+QTaskLogger::QTaskLogger(QSystemInformationService *service, const JobId &jobId, Type type)
+ : m_service(service && service->isTraceEnabled() ? service : nullptr)
+ , m_type(type)
+{
+ m_stats.jobId = jobId;
+ if (m_service) {
+ m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed();
+ m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
+ }
+}
+
+QTaskLogger::QTaskLogger(QSystemInformationService *service,
+ const quint32 jobType,
+ const quint32 instance,
+ QTaskLogger::Type type)
+ : m_service(service && service->isTraceEnabled() ? service : nullptr)
+ , m_type(type)
+{
+ m_stats.jobId.typeAndInstance[0] = jobType;
+ m_stats.jobId.typeAndInstance[1] = instance;
+ if (m_service) {
+ m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed();
+ m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
+ }
+}
+
+QTaskLogger::~QTaskLogger() {
+ if (m_service) {
+ auto dservice = QSystemInformationServicePrivate::get(m_service);
+ if (m_stats.endTime == 0L)
+ m_stats.endTime = dservice->m_jobsStatTimer.nsecsElapsed();
+ switch (m_type) {
+ case AspectJob: dservice->addJobLogStatsEntry(m_stats); break;
+ case Submission: dservice->addSubmissionLogStatsEntry(m_stats); break;
+ }
+ }
+}
+
+void QTaskLogger::end(qint64 t)
+{
+ m_stats.endTime = t > 0 || !m_service ? t : QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed();
+}
+
+qint64 QTaskLogger::restart()
+{
+ if (m_service)
+ m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed();
+ return m_stats.startTime;
+}
+
+
/* !\internal
\class Qt3DCore::QSystemInformationService
\inmodule Qt3DCore
@@ -58,8 +268,14 @@ namespace Qt3DCore {
the new service. This constructor is protected so only subclasses can
instantiate a QSystemInformationService object.
*/
-QSystemInformationService::QSystemInformationService(const QString &description)
- : QAbstractServiceProvider(*new QSystemInformationServicePrivate(description))
+
+QSystemInformationService::QSystemInformationService(QAspectEngine *aspectEngine)
+ : QAbstractServiceProvider(*new QSystemInformationServicePrivate(aspectEngine, QLatin1String("Default System Information Service")))
+{
+}
+
+QSystemInformationService::QSystemInformationService(QAspectEngine *aspectEngine, const QString &description)
+ : QAbstractServiceProvider(*new QSystemInformationServicePrivate(aspectEngine, description))
{
}
@@ -71,19 +287,93 @@ QSystemInformationService::QSystemInformationService(QSystemInformationServicePr
{
}
+bool QSystemInformationService::isTraceEnabled() const
+{
+ Q_D(const QSystemInformationService);
+ return d->m_traceEnabled;
+}
+
+bool QSystemInformationService::isCommandServerEnabled() const
+{
+ Q_D(const QSystemInformationService);
+ return d->m_commandDebugger != nullptr;
+}
+
+void QSystemInformationService::setTraceEnabled(bool traceEnabled)
+{
+ Q_D(QSystemInformationService);
+ if (d->m_traceEnabled != traceEnabled) {
+ d->m_traceEnabled = traceEnabled;
+ emit traceEnabledChanged(d->m_traceEnabled);
+ if (d->m_traceEnabled) {
+ if (!d->m_jobsStatTimer.isValid())
+ d->m_jobsStatTimer.start();
+ } else {
+ d->m_traceFile.reset();
+ }
+ }
+}
+
/*
\fn QStringList Qt3DCore::QSystemInformationService::aspectNames() const
- Subclasses should override this function and return a string list containing the
- names of all registered aspects.
+ Returns a string list containing the names of all registered aspects.
*/
+QStringList QSystemInformationService::aspectNames() const
+{
+ Q_D(const QSystemInformationService);
+ if (!d->m_aspectEngine)
+ return {};
+
+ QStringList res;
+ const auto aspects = d->m_aspectEngine->aspects();
+ if (aspects.isEmpty())
+ return { QLatin1String("No loaded aspects") };
+
+ QAspectEnginePrivate *dengine = QAspectEnginePrivate::get(d->m_aspectEngine);
+ for (auto aspect: aspects) {
+ const QString name = dengine->m_factory.aspectName(aspect);
+ if (!name.isEmpty())
+ res << name;
+ else
+ res << QLatin1String("<unnamed>");
+ }
+
+ return res;
+}
/*
\fn int Qt3DCore::QSystemInformationService::threadPoolThreadCount() const
- Subclasses should override this function and return the number of threads in the
- Qt3D task manager's threadpool.
+ Returns the maximum number of threads in the Qt3D task manager's threadpool.
*/
+int QSystemInformationService::threadPoolThreadCount() const
+{
+ return QThreadPool::globalInstance()->maxThreadCount();
+}
+
+void QSystemInformationService::writePreviousFrameTraces()
+{
+ Q_D(QSystemInformationService);
+ d->writeFrameJobLogStats();
+}
+
+QVariant QSystemInformationService::executeCommand(const QString &command)
+{
+ Q_D(QSystemInformationService);
+
+ if (command == QLatin1String("tracing on")) {
+ setTraceEnabled(true);
+ return {isTraceEnabled()};
+ }
+
+ if (command == QLatin1String("tracing off")) {
+ setTraceEnabled(false);
+ return {isTraceEnabled()};
+ }
+
+ return d->m_aspectEngine->executeCommand(command);
+}
}
diff --git a/src/core/services/qsysteminformationservice_p.h b/src/core/services/qsysteminformationservice_p.h
index a8a83701b..64e6c779e 100644
--- a/src/core/services/qsysteminformationservice_p.h
+++ b/src/core/services/qsysteminformationservice_p.h
@@ -61,16 +61,34 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
class QSystemInformationServicePrivate;
+struct JobRunStats;
class Q_3DCORESHARED_EXPORT QSystemInformationService : public QAbstractServiceProvider
{
Q_OBJECT
+ Q_PROPERTY(bool traceEnabled READ isTraceEnabled WRITE setTraceEnabled NOTIFY traceEnabledChanged)
+ Q_PROPERTY(bool commandServerEnabled READ isCommandServerEnabled CONSTANT)
public:
- virtual QStringList aspectNames() const = 0;
- virtual int threadPoolThreadCount() const = 0;
+ QSystemInformationService(QAspectEngine *aspectEngine);
+
+ bool isTraceEnabled() const;
+ bool isCommandServerEnabled() const;
+
+ void setTraceEnabled(bool traceEnabled);
+
+ QStringList aspectNames() const;
+ int threadPoolThreadCount() const;
+
+ void writePreviousFrameTraces();
+
+ QVariant executeCommand(const QString &command);
+
+signals:
+ void traceEnabledChanged(bool traceEnabled);
protected:
- QSystemInformationService(const QString &description = QString());
+ Q_DECLARE_PRIVATE(QSystemInformationService)
+ QSystemInformationService(QAspectEngine *aspectEngine, const QString &description);
QSystemInformationService(QSystemInformationServicePrivate &dd);
};
diff --git a/src/core/services/qsysteminformationservice_p_p.h b/src/core/services/qsysteminformationservice_p_p.h
index e3ce9fe49..222f4e1af 100644
--- a/src/core/services/qsysteminformationservice_p_p.h
+++ b/src/core/services/qsysteminformationservice_p_p.h
@@ -51,21 +51,98 @@
// We mean it.
//
-#include <Qt3DCore/qt3dcore_global.h>
+#include <QtCore/QThreadStorage>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QFile>
+#include <QtCore/QMutex>
+#include <Qt3DCore/qt3dcore_global.h>
+#include <Qt3DCore/private/qt3dcore_global_p.h>
#include <Qt3DCore/private/qabstractserviceprovider_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-class QSystemInformationServicePrivate : public QAbstractServiceProviderPrivate
+namespace Debug {
+class AspectCommandDebugger;
+} // Debug
+
+union Q_3DCORE_PRIVATE_EXPORT JobId
+{
+ JobId() : id(0L) { }
+ JobId(quint32 t, quint32 i) { typeAndInstance[0] = t; typeAndInstance[1] = i; }
+
+ quint32 typeAndInstance[2];
+ quint64 id;
+};
+
+class Q_3DCORE_PRIVATE_EXPORT QSystemInformationServicePrivate : public QAbstractServiceProviderPrivate
{
public:
- QSystemInformationServicePrivate(const QString &description)
- : QAbstractServiceProviderPrivate(QServiceLocator::SystemInformation, description)
- {}
+ struct JobRunStats
+ {
+ JobRunStats() { jobId.id = 0; startTime = 0L; endTime = 0L; }
+
+ qint64 startTime;
+ qint64 endTime;
+ JobId jobId; // QAspectJob subclasses should properly populate the jobId
+ quint64 threadId;
+ };
+
+ QSystemInformationServicePrivate(QAspectEngine *aspectEngine, const QString &description);
+ ~QSystemInformationServicePrivate();
+
+ static QSystemInformationServicePrivate *get(QSystemInformationService *q);
+
+ // Aspects + Job threads
+ void addJobLogStatsEntry(JobRunStats &stats);
+
+ // Submission thread
+ void addSubmissionLogStatsEntry(JobRunStats &stats);
+
+ void writeFrameJobLogStats();
+
+ QAspectEngine *m_aspectEngine;
+ bool m_traceEnabled;
+
+ QElapsedTimer m_jobsStatTimer;
+ QThreadStorage<QVector<JobRunStats> *> m_jobStatsCached;
+
+ QVector<QVector<JobRunStats> *> m_localStorages;
+ QVector<JobRunStats> *m_submissionStorage;
+
+ QMutex m_localStoragesMutex;
+
+ QScopedPointer<QFile> m_traceFile;
+ quint32 m_frameId;
+
+ Debug::AspectCommandDebugger *m_commandDebugger;
+
+ Q_DECLARE_PUBLIC(QSystemInformationService)
+};
+
+class Q_3DCORE_PRIVATE_EXPORT QTaskLogger {
+public:
+ enum Type {
+ AspectJob,
+ Submission
+ };
+
+ QTaskLogger(QSystemInformationService *service, const JobId &jobId, Type type);
+ QTaskLogger(QSystemInformationService *service, const quint32 jobType, const quint32 instance, Type type = Submission);
+
+ ~QTaskLogger();
+
+ void end(qint64 t = 0L);
+ qint64 restart();
+
+private:
+ QSystemInformationService *m_service;
+ QSystemInformationServicePrivate::JobRunStats m_stats;
+ Type m_type;
};
}
diff --git a/src/core/transforms/qabstractskeleton.cpp b/src/core/transforms/qabstractskeleton.cpp
index 5f3b05eb8..4a30d0710 100644
--- a/src/core/transforms/qabstractskeleton.cpp
+++ b/src/core/transforms/qabstractskeleton.cpp
@@ -39,7 +39,6 @@
#include "qabstractskeleton.h"
#include "qabstractskeleton_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -47,6 +46,7 @@ namespace Qt3DCore {
QAbstractSkeletonPrivate::QAbstractSkeletonPrivate()
: Qt3DCore::QNodePrivate()
+ , m_type(QSkeletonCreatedChangeBase::Skeleton)
, m_jointCount(0)
{
}
@@ -105,6 +105,13 @@ QAbstractSkeleton::~QAbstractSkeleton()
{
}
+/*! \internal */
+void QAbstractSkeleton::sceneChangeEvent(const QSceneChangePtr &change)
+{
+ // TODO Unused remove in Qt6
+ Q_UNUSED(change)
+}
+
/*!
\property Qt3DCore::QAbstractSkeleton::jointCount
@@ -127,16 +134,6 @@ void QAbstractSkeletonPrivate::setJointCount(int jointCount)
q->blockNotifications(block);
}
-void QAbstractSkeleton::sceneChangeEvent(const QSceneChangePtr &change)
-{
- Q_D(QAbstractSkeleton);
- if (change->type() == Qt3DCore::PropertyUpdated) {
- const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
- if (e->propertyName() == QByteArrayLiteral("jointCount"))
- d->setJointCount(e->value().toInt());
- }
-}
-
} // namespace Qt3DCore
QT_END_NAMESPACE
diff --git a/src/core/transforms/qabstractskeleton.h b/src/core/transforms/qabstractskeleton.h
index 902def9f8..1c2eba08f 100644
--- a/src/core/transforms/qabstractskeleton.h
+++ b/src/core/transforms/qabstractskeleton.h
@@ -64,7 +64,8 @@ Q_SIGNALS:
protected:
QAbstractSkeleton(QAbstractSkeletonPrivate &dd, Qt3DCore::QNode *parent = nullptr);
- void sceneChangeEvent(const QSceneChangePtr &change) override;
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QAbstractSkeleton)
diff --git a/src/core/transforms/qskeletonloader.cpp b/src/core/transforms/qskeletonloader.cpp
index d5296ecc9..b1a311a0c 100644
--- a/src/core/transforms/qskeletonloader.cpp
+++ b/src/core/transforms/qskeletonloader.cpp
@@ -68,6 +68,27 @@ void QSkeletonLoaderPrivate::setStatus(QSkeletonLoader::Status status)
}
}
+void QSkeletonLoaderPrivate::setRootJoint(QJoint *rootJoint)
+{
+ Q_Q(QSkeletonLoader);
+ if (rootJoint == m_rootJoint)
+ return;
+
+ if (m_rootJoint)
+ unregisterDestructionHelper(m_rootJoint);
+
+ if (rootJoint && !rootJoint->parent())
+ rootJoint->setParent(q);
+
+ m_rootJoint = rootJoint;
+
+ // Ensures proper bookkeeping
+ if (m_rootJoint)
+ registerPrivateDestructionHelper(m_rootJoint, &QSkeletonLoaderPrivate::setRootJoint);
+
+ emit q->rootJointChanged(m_rootJoint);
+}
+
/*!
\qmltype SkeletonLoader
\inqmlmodule Qt3D.Core
@@ -217,39 +238,12 @@ void QSkeletonLoader::setCreateJointsEnabled(bool createJoints)
void QSkeletonLoader::setRootJoint(QJoint *rootJoint)
{
Q_D(QSkeletonLoader);
- if (rootJoint == d->m_rootJoint)
- return;
-
- if (d->m_rootJoint)
- d->unregisterDestructionHelper(d->m_rootJoint);
-
- if (rootJoint && !rootJoint->parent())
- rootJoint->setParent(this);
-
- d->m_rootJoint = rootJoint;
-
- // Ensures proper bookkeeping
- if (d->m_rootJoint)
- d->registerDestructionHelper(d->m_rootJoint, &QSkeletonLoader::setRootJoint, d->m_rootJoint);
-
- emit rootJointChanged(d->m_rootJoint);
+ d->setRootJoint(rootJoint);
}
/*! \internal */
void QSkeletonLoader::sceneChangeEvent(const QSceneChangePtr &change)
{
- Q_D(QSkeletonLoader);
- if (change->type() == Qt3DCore::PropertyUpdated) {
- auto propertyChange = qSharedPointerCast<QStaticPropertyUpdatedChangeBase>(change);
- if (propertyChange->propertyName() == QByteArrayLiteral("status")) {
- const auto e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
- d->setStatus(static_cast<QSkeletonLoader::Status>(e->value().toInt()));
- } else if (propertyChange->propertyName() == QByteArrayLiteral("rootJoint")) {
- auto typedChange = qSharedPointerCast<QJointChange>(propertyChange);
- auto rootJoint = std::move(typedChange->data);
- setRootJoint(rootJoint.release());
- }
- }
QAbstractSkeleton::sceneChangeEvent(change);
}
diff --git a/src/core/transforms/qskeletonloader_p.h b/src/core/transforms/qskeletonloader_p.h
index 5c415745b..6bd4e1eef 100644
--- a/src/core/transforms/qskeletonloader_p.h
+++ b/src/core/transforms/qskeletonloader_p.h
@@ -70,6 +70,7 @@ public:
QSkeletonLoaderPrivate();
void setStatus(QSkeletonLoader::Status status);
+ void setRootJoint(QJoint *rootJoint);
Q_DECLARE_PUBLIC(QSkeletonLoader)
diff --git a/src/core/transforms/qtransform.cpp b/src/core/transforms/qtransform.cpp
index e5902f11f..d41b87f79 100644
--- a/src/core/transforms/qtransform.cpp
+++ b/src/core/transforms/qtransform.cpp
@@ -237,6 +237,7 @@ QTransform::QTransform(QTransformPrivate &dd, QNode *parent)
/*!
\internal
*/
+// TODO Unused remove in Qt6
void QTransform::sceneChangeEvent(const QSceneChangePtr &change)
{
Q_D(QTransform);
diff --git a/src/core/transforms/qtransform.h b/src/core/transforms/qtransform.h
index 503ea4d4a..ce6bf42fa 100644
--- a/src/core/transforms/qtransform.h
+++ b/src/core/transforms/qtransform.h
@@ -119,6 +119,7 @@ Q_SIGNALS:
protected:
explicit QTransform(QTransformPrivate &dd, QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
diff --git a/src/core/transforms/sqt_p.h b/src/core/transforms/sqt_p.h
index 5fdefccc8..e602cc71e 100644
--- a/src/core/transforms/sqt_p.h
+++ b/src/core/transforms/sqt_p.h
@@ -71,7 +71,9 @@ struct Sqt
Sqt()
: rotation()
, scale(1.0f, 1.0f, 1.0f)
+ , pad1(0.f)
, translation()
+ , pad2(0.f)
{}
inline QMatrix4x4 toMatrix() const
diff --git a/src/doc/src/qmlextramaterials.qdoc b/src/doc/src/qmlextramaterials.qdoc
index e0a2e9edf..338bada09 100644
--- a/src/doc/src/qmlextramaterials.qdoc
+++ b/src/doc/src/qmlextramaterials.qdoc
@@ -544,6 +544,41 @@
The default value is 0.5.
*/
+/*!
+ \qmlproperty BlendEquationArguments::Blending PhongAlphaMaterial::sourceRgbArg
+
+ Holds the blend equation source RGB blending argument.
+
+ \sa Qt3DRender::QBlendEquationArguments::Blending
+*/
+/*!
+ \qmlproperty BlendEquationArguments::Blending PhongAlphaMaterial::destinationRgbArg
+
+ Holds the blend equation destination RGB blending argument.
+
+ \sa Qt3DRender::QBlendEquationArguments::Blending
+*/
+/*!
+ \qmlproperty BlendEquationArguments::Blending PhongAlphaMaterial::sourceAlphaArg
+
+ Holds the blend equation source alpha blending argument.
+
+ \sa Qt3DRender::QBlendEquationArguments::Blending
+*/
+/*!
+ \qmlproperty BlendEquationArguments::Blending PhongAlphaMaterial::destinationAlphaArg
+
+ Holds the blend equation destination alpha blending argument.
+
+ \sa Qt3DRender::QBlendEquationArguments::Blending
+*/
+/*!
+ \qmlproperty BlendEquation::BlendFunction PhongAlphaMaterial::blendFunctionArg
+
+ Holds the blend equation function argument.
+
+ \sa Qt3DRender::QBlendEquation::BlendFunction
+*/
/*!
\qmltype PhongMaterial
diff --git a/src/extras/defaults/qabstractspritesheet.cpp b/src/extras/defaults/qabstractspritesheet.cpp
index 640e600c7..2cf134f7c 100644
--- a/src/extras/defaults/qabstractspritesheet.cpp
+++ b/src/extras/defaults/qabstractspritesheet.cpp
@@ -100,7 +100,7 @@ QAbstractSpriteSheet::~QAbstractSpriteSheet()
}
/*!
- \property QAbstractSpriteSheet::texture
+ \property Qt3DExtras::QAbstractSpriteSheet::texture
Holds the current texture used by the material.
*/
diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp
index ace40c3c1..04b8554f1 100644
--- a/src/extras/defaults/qt3dwindow.cpp
+++ b/src/extras/defaults/qt3dwindow.cpp
@@ -237,7 +237,7 @@ void Qt3DWindow::showEvent(QShowEvent *e)
void Qt3DWindow::resizeEvent(QResizeEvent *)
{
Q_D(Qt3DWindow);
- d->m_defaultCamera->setAspectRatio(float(width()) / float(height()));
+ d->m_defaultCamera->setAspectRatio(float(width()) / std::max(1.f, static_cast<float>(height())));
}
/*!
diff --git a/src/extras/shaders/es2/distancefieldtext.frag b/src/extras/shaders/es2/distancefieldtext.frag
index d2db2e306..b7563e397 100644
--- a/src/extras/shaders/es2/distancefieldtext.frag
+++ b/src/extras/shaders/es2/distancefieldtext.frag
@@ -33,5 +33,5 @@ void main()
FP float maxAlpha = threshold + range;
FP float distVal = texture2D(distanceFieldTexture, texCoord).r;
- gl_FragColor = color * smoothstep(minAlpha, maxAlpha, distVal);
+ gl_FragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal));
}
diff --git a/src/extras/shaders/gl3/distancefieldtext.frag b/src/extras/shaders/gl3/distancefieldtext.frag
index 23dff8e0f..8e0684adc 100644
--- a/src/extras/shaders/gl3/distancefieldtext.frag
+++ b/src/extras/shaders/gl3/distancefieldtext.frag
@@ -34,6 +34,6 @@ void main()
float maxAlpha = threshold + range;
float distVal = texture(distanceFieldTexture, texCoord).r;
- fragColor = color * smoothstep(minAlpha, maxAlpha, distVal);
+ fragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal));
gl_FragDepth = gl_FragCoord.z - zValue * 0.00001;
}
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index aa4785fe7..897672782 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -217,9 +217,6 @@ struct RenderData {
void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
{
- if (runs.isEmpty())
- return;
-
// For each distinct texture, we need a separate DistanceFieldTextRenderer,
// for which we need vertex and index data
QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData;
@@ -294,6 +291,11 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
}
}
+ // de-ref all glyphs for previous QGlyphRuns
+ for (int i = 0; i < m_currentGlyphRuns.size(); i++)
+ m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
+ m_currentGlyphRuns = runs;
+
// make sure we have the correct number of DistanceFieldTextRenderers
// TODO: we might keep one renderer at all times, so we won't delete and
// re-allocate one every time the text changes from an empty to a non-empty string
@@ -314,11 +316,6 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
for (auto it = renderData.begin(); it != renderData.end(); ++it) {
m_renderers[rendererIdx++]->setGlyphData(it.key(), it.value().vertex, it.value().index);
}
-
- // de-ref all glyphs for previous QGlyphRuns
- for (int i = 0; i < m_currentGlyphRuns.size(); i++)
- m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
- m_currentGlyphRuns = runs;
}
void QText2DEntityPrivate::clearCurrentGlyphRuns()
diff --git a/src/input/backend/keyboardeventfilter.cpp b/src/input/backend/keyboardeventfilter.cpp
index bd3bac5a7..e4f47f08e 100644
--- a/src/input/backend/keyboardeventfilter.cpp
+++ b/src/input/backend/keyboardeventfilter.cpp
@@ -53,6 +53,7 @@ namespace Input {
KeyboardEventFilter::KeyboardEventFilter(QObject *parent)
: QObject(parent)
+ , m_inputHandler(nullptr)
{
}
diff --git a/src/input/backend/keyboardhandler.cpp b/src/input/backend/keyboardhandler.cpp
index 66af527c9..026012e52 100644
--- a/src/input/backend/keyboardhandler.cpp
+++ b/src/input/backend/keyboardhandler.cpp
@@ -41,7 +41,6 @@
#include <Qt3DInput/qkeyboarddevice.h>
#include <Qt3DInput/qkeyboardhandler.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <QtCore/QVariant>
#include <Qt3DInput/private/inputhandler_p.h>
diff --git a/src/input/backend/mouseeventfilter.cpp b/src/input/backend/mouseeventfilter.cpp
index 618a64b15..48b30725a 100644
--- a/src/input/backend/mouseeventfilter.cpp
+++ b/src/input/backend/mouseeventfilter.cpp
@@ -53,6 +53,7 @@ namespace Input {
MouseEventFilter::MouseEventFilter(QObject *parent)
: QObject(parent)
+ , m_inputHandler(nullptr)
{
}
diff --git a/src/input/backend/mousehandler.cpp b/src/input/backend/mousehandler.cpp
index 46bd273d6..9c7ff9817 100644
--- a/src/input/backend/mousehandler.cpp
+++ b/src/input/backend/mousehandler.cpp
@@ -41,7 +41,6 @@
#include <Qt3DInput/qmousehandler.h>
#include <Qt3DInput/qmousedevice.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DInput/private/inputmanagers_p.h>
#include <Qt3DInput/private/inputhandler_p.h>
diff --git a/src/input/frontend/qabstractphysicaldeviceproxy.cpp b/src/input/frontend/qabstractphysicaldeviceproxy.cpp
index a7930ed76..4ed116440 100644
--- a/src/input/frontend/qabstractphysicaldeviceproxy.cpp
+++ b/src/input/frontend/qabstractphysicaldeviceproxy.cpp
@@ -41,7 +41,6 @@
#include "qabstractphysicaldeviceproxy_p_p.h"
#include <Qt3DInput/qphysicaldevicecreatedchange.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
diff --git a/src/input/frontend/qaction.cpp b/src/input/frontend/qaction.cpp
index c835062a2..8cceaab51 100644
--- a/src/input/frontend/qaction.cpp
+++ b/src/input/frontend/qaction.cpp
@@ -41,7 +41,6 @@
#include "qaction_p.h"
#include <Qt3DInput/qabstractactioninput.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qnodecreatedchange.h>
#include <Qt3DCore/private/qnode_p.h>
@@ -149,6 +148,11 @@ QVector<QAbstractActionInput *> QAction::inputs() const
return d->m_inputs;
}
+// TODO Unused remove in Qt6
+void QAction::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QAction::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QActionData>::create(this);
diff --git a/src/input/frontend/qaction.h b/src/input/frontend/qaction.h
index 8175bab8e..ef74debe5 100644
--- a/src/input/frontend/qaction.h
+++ b/src/input/frontend/qaction.h
@@ -67,6 +67,10 @@ public:
Q_SIGNALS:
void activeChanged(bool isActive);
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
private:
Q_DECLARE_PRIVATE(QAction)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
diff --git a/src/input/frontend/qactioninput.cpp b/src/input/frontend/qactioninput.cpp
index 9f32f57cc..f013147f2 100644
--- a/src/input/frontend/qactioninput.cpp
+++ b/src/input/frontend/qactioninput.cpp
@@ -181,7 +181,7 @@ QAbstractPhysicalDevice *QActionInput::sourceDevice() const
/*!
\qmlsignal Qt3D.Input::ActionInput::buttonsChanged(const QVector<int> &buttons)
- This signal is emitted when the buttons associated with the action input is changed.
+ This signal is emitted when the \a buttons associated with the action input is changed.
The corresponding handler is \c onbuttonsChanged
*/
diff --git a/src/input/frontend/qaxis.cpp b/src/input/frontend/qaxis.cpp
index b6018c887..d76135fd7 100644
--- a/src/input/frontend/qaxis.cpp
+++ b/src/input/frontend/qaxis.cpp
@@ -40,7 +40,6 @@
#include "qaxis_p.h"
#include <Qt3DInput/qabstractaxisinput.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qnodecreatedchange.h>
QT_BEGIN_NAMESPACE
@@ -168,6 +167,11 @@ float QAxis::value() const
return d->m_value;
}
+// TODO Unused remove in Qt6
+void QAxis::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QAxis::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAxisData>::create(this);
diff --git a/src/input/frontend/qaxis.h b/src/input/frontend/qaxis.h
index 1a542cf22..3dbe54a4f 100644
--- a/src/input/frontend/qaxis.h
+++ b/src/input/frontend/qaxis.h
@@ -66,6 +66,10 @@ public:
Q_SIGNALS:
void valueChanged(float value);
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
private:
Q_DECLARE_PRIVATE(QAxis)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
diff --git a/src/input/frontend/qaxisaccumulator.cpp b/src/input/frontend/qaxisaccumulator.cpp
index 7e9930f66..a7bb14441 100644
--- a/src/input/frontend/qaxisaccumulator.cpp
+++ b/src/input/frontend/qaxisaccumulator.cpp
@@ -42,7 +42,6 @@
#include <Qt3DInput/qaxis.h>
#include <Qt3DCore/qnodecreatedchange.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -290,6 +289,11 @@ void QAxisAccumulator::setScale(float scale)
emit scaleChanged(scale);
}
+// TODO Unused remove in Qt6
+void QAxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
/*! \internal */
Qt3DCore::QNodeCreatedChangeBasePtr QAxisAccumulator::createNodeCreationChange() const
{
diff --git a/src/input/frontend/qaxisaccumulator.h b/src/input/frontend/qaxisaccumulator.h
index bb2e2696b..e711b0691 100644
--- a/src/input/frontend/qaxisaccumulator.h
+++ b/src/input/frontend/qaxisaccumulator.h
@@ -87,6 +87,10 @@ Q_SIGNALS:
void velocityChanged(float value);
void scaleChanged(float scale);
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
private:
Q_DECLARE_PRIVATE(QAxisAccumulator)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
diff --git a/src/input/frontend/qkeyboarddevice.cpp b/src/input/frontend/qkeyboarddevice.cpp
index 257a5be8c..1ec1f8ead 100644
--- a/src/input/frontend/qkeyboarddevice.cpp
+++ b/src/input/frontend/qkeyboarddevice.cpp
@@ -41,7 +41,6 @@
#include "qkeyboarddevice_p.h"
#include <Qt3DInput/qkeyboardhandler.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qscene_p.h>
@@ -310,16 +309,11 @@ QKeyboardDevice::QKeyboardDevice(QKeyboardDevicePrivate &dd, QNode *parent)
{
}
-/*! \internal */
-void QKeyboardDevice::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
+// TODO Unused remove in Qt6
+void QKeyboardDevice::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
{
- Q_D(QKeyboardDevice);
- Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
- if (e->type() == Qt3DCore::PropertyUpdated && e->propertyName() == QByteArrayLiteral("activeInput")) {
- Qt3DCore::QNodeId activeInputId = e->value().value<Qt3DCore::QNodeId>();
- setActiveInput(qobject_cast<QKeyboardHandler *>(d->scene()->lookupNode(activeInputId)));
- }
}
+
/*!
* Set the active input to \a activeInput
*/
diff --git a/src/input/frontend/qkeyboarddevice.h b/src/input/frontend/qkeyboarddevice.h
index c3478ec27..df2f47020 100644
--- a/src/input/frontend/qkeyboarddevice.h
+++ b/src/input/frontend/qkeyboarddevice.h
@@ -71,6 +71,7 @@ public:
protected:
explicit QKeyboardDevice(QKeyboardDevicePrivate &dd, QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
Q_SIGNALS:
diff --git a/src/input/frontend/qkeyboardhandler.cpp b/src/input/frontend/qkeyboardhandler.cpp
index aff136a04..92ce39c31 100644
--- a/src/input/frontend/qkeyboardhandler.cpp
+++ b/src/input/frontend/qkeyboardhandler.cpp
@@ -41,7 +41,6 @@
#include "qkeyboardhandler_p.h"
#include <Qt3DInput/qkeyboarddevice.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -238,6 +237,11 @@ void QKeyboardHandler::setFocus(bool focus)
}
}
+// TODO Unused remove in Qt6
+void QKeyboardHandler::sceneChangeEvent(const QSceneChangePtr &)
+{
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QKeyboardHandler::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QKeyboardHandlerData>::create(this);
diff --git a/src/input/frontend/qkeyboardhandler.h b/src/input/frontend/qkeyboardhandler.h
index d69476286..b4425de72 100644
--- a/src/input/frontend/qkeyboardhandler.h
+++ b/src/input/frontend/qkeyboardhandler.h
@@ -115,6 +115,10 @@ Q_SIGNALS:
void pressed(Qt3DInput::QKeyEvent *event);
void released(Qt3DInput::QKeyEvent *event);
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
private:
Q_DECLARE_PRIVATE(QKeyboardHandler)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
diff --git a/src/input/frontend/qkeyevent.cpp b/src/input/frontend/qkeyevent.cpp
index a70a2970b..efbddc771 100644
--- a/src/input/frontend/qkeyevent.cpp
+++ b/src/input/frontend/qkeyevent.cpp
@@ -160,7 +160,7 @@ QKeyEvent::~QKeyEvent()
/*!
\qmlmethod bool Qt3D.Input::KeyEvent::matches(StandardKey key)
- Returns \c true if the key event matches the given standard key; otherwise
+ Returns \c true if the key event matches the given standard \a key; otherwise
returns \c false.
\sa QKeySequence::StandardKey
@@ -174,7 +174,7 @@ QKeyEvent::~QKeyEvent()
See \l [CPP] {Qt::Key}{Qt.Key} for the list of keyboard codes.
- \sa {QKeyEvent::key}
+ \b {See also} \l [QtGui] {QKeyEvent::key()}.
*/
/*!
@@ -194,7 +194,7 @@ QKeyEvent::~QKeyEvent()
This property holds the keyboard modifier flags that existed immediately
before the event occurred.
- \sa {QKeyEvent::modifiers}
+ \b {See also} \l [QtGui] {QKeyEvent::modifiers()}.
*/
/*!
diff --git a/src/input/frontend/qmouseevent.cpp b/src/input/frontend/qmouseevent.cpp
index 2033eed36..2b06c824d 100644
--- a/src/input/frontend/qmouseevent.cpp
+++ b/src/input/frontend/qmouseevent.cpp
@@ -49,7 +49,7 @@ template<typename EventClass, typename QtEventClass>
typename EventClass::Modifiers modifiersForEvent(const QtEventClass &event)
{
const Qt::KeyboardModifiers eventModifiers = event.modifiers();
- typename EventClass::Modifiers modifiers = EventClass::NoModifier;
+ int modifiers = EventClass::NoModifier;
if (eventModifiers & Qt::ShiftModifier)
modifiers |= EventClass::ShiftModifier;
@@ -66,7 +66,9 @@ typename EventClass::Modifiers modifiersForEvent(const QtEventClass &event)
if (eventModifiers & Qt::KeypadModifier)
modifiers |= EventClass::KeypadModifier;
- return modifiers;
+ // Abuse the int used to store an enum to store multiple
+ // modifiers into one
+ return static_cast<typename EventClass::Modifiers>(modifiers);
}
} // anonymous
diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h
index 1402d8210..ae44d9365 100644
--- a/src/input/frontend/qmouseevent.h
+++ b/src/input/frontend/qmouseevent.h
@@ -70,7 +70,7 @@ public:
};
Q_ENUM(Buttons) // LCOV_EXCL_LINE
- enum Modifier {
+ enum Modifiers {
NoModifier = Qt::NoModifier,
ShiftModifier = Qt::ShiftModifier,
ControlModifier = Qt::ControlModifier,
@@ -78,8 +78,8 @@ public:
MetaModifier = Qt::MetaModifier,
KeypadModifier = Qt::KeypadModifier
};
- Q_DECLARE_FLAGS(Modifiers, Modifier)
- Q_FLAG(Modifiers)
+ Q_ENUM(Modifiers) // LCOV_EXCL_LINE
+ // TO DO Qt6 Modifiers -> Modifier and add Q_FLAG(Modifiers)
explicit QMouseEvent(const QT_PREPEND_NAMESPACE(QMouseEvent) &e);
~QMouseEvent();
@@ -128,7 +128,7 @@ public:
};
Q_ENUM(Buttons) // LCOV_EXCL_LINE
- enum Modifier {
+ enum Modifiers {
NoModifier = Qt::NoModifier,
ShiftModifier = Qt::ShiftModifier,
ControlModifier = Qt::ControlModifier,
@@ -136,8 +136,8 @@ public:
MetaModifier = Qt::MetaModifier,
KeypadModifier = Qt::KeypadModifier
};
- Q_DECLARE_FLAGS(Modifiers, Modifier)
- Q_FLAG(Modifiers)
+ Q_ENUM(Modifiers) // LCOV_EXCL_LINE
+ // TO DO Qt6 Modifiers -> Modifier and add Q_FLAG(Modifiers)
explicit QWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &e);
~QWheelEvent();
@@ -161,9 +161,6 @@ typedef QSharedPointer<QWheelEvent> QWheelEventPtr;
} // namespace Qt3DInput
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt3DInput::QMouseEvent::Modifiers)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt3DInput::QWheelEvent::Modifiers)
-
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Qt3DInput::QMouseEvent*) // LCOV_EXCL_LINE
diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp
index 944ca391a..89d76a057 100644
--- a/src/input/frontend/qmousehandler.cpp
+++ b/src/input/frontend/qmousehandler.cpp
@@ -42,7 +42,6 @@
#include <Qt3DInput/qmousedevice.h>
#include <Qt3DInput/qmouseevent.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE
@@ -198,21 +197,21 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
\qmlsignal Qt3D.Input::MouseHandler::wheel(MouseEvent mouse)
This signal is emitted when the mouse wheel is used with the event details
- being contained within \a wheel
+ being contained within \a mouse.
*/
/*!
\fn Qt3DInput::QMouseHandler::clicked(Qt3DInput::QMouseEvent *mouse)
This signal is emitted when a mouse button is clicked with the event details
- being contained within \a mouse
+ being contained within \a mouse.
*/
/*!
\fn Qt3DInput::QMouseHandler::doubleClicked(Qt3DInput::QMouseEvent *mouse)
This signal is emitted when a mouse button is double clicked with the event
- details being contained within \a mouse
+ details being contained within \a mouse.
*/
/*!
@@ -299,6 +298,11 @@ void QMouseHandler::setSourceDevice(QMouseDevice *mouseDevice)
}
}
+// TODO Unused remove in Qt6
+void QMouseHandler::sceneChangeEvent(const QSceneChangePtr &)
+{
+}
+
/*!
* \property Qt3DInput::QMouseHandler::sourceDevice
*
diff --git a/src/input/frontend/qmousehandler.h b/src/input/frontend/qmousehandler.h
index 5331893b2..d95dbf4c3 100644
--- a/src/input/frontend/qmousehandler.h
+++ b/src/input/frontend/qmousehandler.h
@@ -87,6 +87,8 @@ Q_SIGNALS:
#endif
protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
void setContainsMouse(bool contains);
private:
diff --git a/src/input/frontend/qphysicaldevicecreatedchange.cpp b/src/input/frontend/qphysicaldevicecreatedchange.cpp
index c14770d80..905633b7f 100644
--- a/src/input/frontend/qphysicaldevicecreatedchange.cpp
+++ b/src/input/frontend/qphysicaldevicecreatedchange.cpp
@@ -54,7 +54,7 @@ QPhysicalDeviceCreatedChangeBasePrivate::QPhysicalDeviceCreatedChangeBasePrivate
}
/*!
- \class QPhysicalDeviceCreatedChangeBase
+ \class Qt3DInput::QPhysicalDeviceCreatedChangeBase
\inmodule Qt3DInput
\brief Base class for handling changes in physical devices.
*/
diff --git a/src/logic/callbackjob.cpp b/src/logic/callbackjob.cpp
index 5c04d8838..5dfc74f02 100644
--- a/src/logic/callbackjob.cpp
+++ b/src/logic/callbackjob.cpp
@@ -51,7 +51,7 @@ CallbackJob::CallbackJob()
: QAspectJob()
, m_logicManager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::Callback, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::Callback, 0)
}
void CallbackJob::setManager(Manager *manager)
diff --git a/src/logic/manager.cpp b/src/logic/manager.cpp
index 3d096a342..db90e6ad9 100644
--- a/src/logic/manager.cpp
+++ b/src/logic/manager.cpp
@@ -56,6 +56,8 @@ namespace Logic {
Manager::Manager()
: m_logicHandlerManager(new HandlerManager)
+ , m_logicAspect(nullptr)
+ , m_executor(nullptr)
, m_dt(0.0f)
{
}
diff --git a/src/plugins/geometryloaders/gltf/gltfgeometryloader.cpp b/src/plugins/geometryloaders/gltf/gltfgeometryloader.cpp
index ddb950f86..8adb70f96 100644
--- a/src/plugins/geometryloaders/gltf/gltfgeometryloader.cpp
+++ b/src/plugins/geometryloaders/gltf/gltfgeometryloader.cpp
@@ -48,6 +48,7 @@
#include <Qt3DRender/QGeometry>
#include <Qt3DRender/private/renderlogging_p.h>
+#include <Qt3DCore/private/qloadgltf_p.h>
QT_BEGIN_NAMESPACE
@@ -102,12 +103,7 @@ bool GLTFGeometryLoader::load(QIODevice *ioDev, const QString &subMesh)
{
Q_UNUSED(subMesh);
- QByteArray jsonData = ioDev->readAll();
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(jsonData);
-
- if (Q_UNLIKELY(!setJSON(sceneDocument))) {
+ if (Q_UNLIKELY(!setJSON(qLoadGLTF(ioDev->readAll())))) {
qCWarning(GLTFGeometryLoaderLog, "not a JSON document");
return false;
}
@@ -139,7 +135,8 @@ GLTFGeometryLoader::BufferData::BufferData(const QJsonObject &json)
}
GLTFGeometryLoader::AccessorData::AccessorData()
- : type(QAttribute::Float)
+ : bufferViewIndex(0)
+ , type(QAttribute::Float)
, dataSize(0)
, count(0)
, offset(0)
diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
index a10a83cca..860dec3e7 100644
--- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp
+++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
@@ -108,6 +108,7 @@
#include <Qt3DExtras/qtorusmesh.h>
#include <private/qurlhelper_p.h>
+#include <private/qloadgltf_p.h>
/**
* glTF 2.0 conformance report
@@ -410,12 +411,7 @@ void GLTFImporter::setSource(const QUrl &source)
QFile f(path);
f.open(QIODevice::ReadOnly);
- QByteArray jsonData = f.readAll();
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(jsonData);
-
- if (Q_UNLIKELY(!setJSON(sceneDocument))) {
+ if (Q_UNLIKELY(!setJSON(qLoadGLTF(f.readAll())))) {
qCWarning(GLTFImporterLog, "not a JSON document");
return;
}
@@ -430,11 +426,7 @@ void GLTFImporter::setSource(const QUrl &source)
*/
void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
{
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(data);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(data);
-
- if (Q_UNLIKELY(!setJSON(sceneDocument))) {
+ if (Q_UNLIKELY(!setJSON(qLoadGLTF(data)))) {
qCWarning(GLTFImporterLog, "not a JSON document");
return;
}
diff --git a/src/quick3d/imports/animation/plugins.qmltypes b/src/quick3d/imports/animation/plugins.qmltypes
index a8f207245..aff5ccb9c 100644
--- a/src/quick3d/imports/animation/plugins.qmltypes
+++ b/src/quick3d/imports/animation/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Animation 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Animation 2.14'
Module {
dependencies: ["Qt3D.Core 2.0"]
@@ -699,4 +699,57 @@ Module {
isReadonly: true
}
}
+ Component {
+ name: "Qt3DCore::QNode"
+ defaultProperty: "data"
+ prototype: "QObject"
+ exports: ["Qt3D.Animation/Node 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [209]
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
+ Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
+ Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
+ Signal {
+ name: "parentChanged"
+ Parameter { name: "parent"; type: "QObject"; isPointer: true }
+ }
+ Signal {
+ name: "enabledChanged"
+ Parameter { name: "enabled"; type: "bool" }
+ }
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ Signal { name: "nodeDestroyed" }
+ Method {
+ name: "setParent"
+ Parameter { name: "parent"; type: "QNode"; isPointer: true }
+ }
+ Method {
+ name: "setEnabled"
+ Parameter { name: "isEnabled"; type: "bool" }
+ }
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ Property { name: "propertyTrackingOverrides"; revision: 209; type: "QJSValue" }
+ Property { name: "data"; revision: 209; type: "QObject"; isList: true; isReadonly: true }
+ Property {
+ name: "childNodes"
+ revision: 209
+ type: "Qt3DCore::QNode"
+ isList: true
+ isReadonly: true
+ }
+ }
}
diff --git a/src/quick3d/imports/core/plugins.qmltypes b/src/quick3d/imports/core/plugins.qmltypes
index 390fd78fb..476bb99a7 100644
--- a/src/quick3d/imports/core/plugins.qmltypes
+++ b/src/quick3d/imports/core/plugins.qmltypes
@@ -4,11 +4,73 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt3D.Core 2.13'
+// 'qmlplugindump -nonrelocatable Qt3D.Core 2.14'
Module {
dependencies: ["QtQuick 2.0"]
Component {
+ name: "QQmlEasingValueType"
+ exports: ["Qt3D.Core/Easing 2.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Type"
+ values: {
+ "Linear": 0,
+ "InQuad": 1,
+ "OutQuad": 2,
+ "InOutQuad": 3,
+ "OutInQuad": 4,
+ "InCubic": 5,
+ "OutCubic": 6,
+ "InOutCubic": 7,
+ "OutInCubic": 8,
+ "InQuart": 9,
+ "OutQuart": 10,
+ "InOutQuart": 11,
+ "OutInQuart": 12,
+ "InQuint": 13,
+ "OutQuint": 14,
+ "InOutQuint": 15,
+ "OutInQuint": 16,
+ "InSine": 17,
+ "OutSine": 18,
+ "InOutSine": 19,
+ "OutInSine": 20,
+ "InExpo": 21,
+ "OutExpo": 22,
+ "InOutExpo": 23,
+ "OutInExpo": 24,
+ "InCirc": 25,
+ "OutCirc": 26,
+ "InOutCirc": 27,
+ "OutInCirc": 28,
+ "InElastic": 29,
+ "OutElastic": 30,
+ "InOutElastic": 31,
+ "OutInElastic": 32,
+ "InBack": 33,
+ "OutBack": 34,
+ "InOutBack": 35,
+ "OutInBack": 36,
+ "InBounce": 37,
+ "OutBounce": 38,
+ "InOutBounce": 39,
+ "OutInBounce": 40,
+ "InCurve": 41,
+ "OutCurve": 42,
+ "SineCurve": 43,
+ "CosineCurve": 44,
+ "Bezier": 45
+ }
+ }
+ Property { name: "type"; type: "Type" }
+ Property { name: "amplitude"; type: "double" }
+ Property { name: "overshoot"; type: "double" }
+ Property { name: "period"; type: "double" }
+ Property { name: "bezierCurve"; type: "QVariantList" }
+ }
+ Component {
name: "Qt3DCore::QAbstractSkeleton"
prototype: "Qt3DCore::QNode"
exports: ["Qt3D.Core/AbstractSkeleton 2.10"]
@@ -266,8 +328,8 @@ Module {
Component {
name: "Qt3DCore::QTransform"
prototype: "Qt3DCore::QComponent"
- exports: ["Qt3D.Core/Transform 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["Qt3D.Core/Transform 2.0", "Qt3D.Core/Transform 2.14"]
+ exportMetaObjectRevisions: [0, 14]
Property { name: "matrix"; type: "QMatrix4x4" }
Property { name: "scale"; type: "float" }
Property { name: "scale3D"; type: "QVector3D" }
@@ -276,6 +338,7 @@ Module {
Property { name: "rotationX"; type: "float" }
Property { name: "rotationY"; type: "float" }
Property { name: "rotationZ"; type: "float" }
+ Property { name: "worldMatrix"; revision: 14; type: "QMatrix4x4"; isReadonly: true }
Signal {
name: "scaleChanged"
Parameter { name: "scale"; type: "float" }
@@ -304,6 +367,10 @@ Module {
name: "rotationZChanged"
Parameter { name: "rotationZ"; type: "float" }
}
+ Signal {
+ name: "worldMatrixChanged"
+ Parameter { name: "worldMatrix"; type: "QMatrix4x4" }
+ }
Method {
name: "setScale"
Parameter { name: "scale"; type: "float" }
diff --git a/src/quick3d/imports/extras/plugins.qmltypes b/src/quick3d/imports/extras/plugins.qmltypes
index 72857d402..fcc15e022 100644
--- a/src/quick3d/imports/extras/plugins.qmltypes
+++ b/src/quick3d/imports/extras/plugins.qmltypes
@@ -4,10 +4,51 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Extras 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Extras 2.14'
Module {
dependencies: ["Qt3D.Logic 2.0", "Qt3D.Render 2.0"]
+ Component { name: "Qt3DCore::QEntity"; prototype: "Qt3DCore::QNode" }
+ Component {
+ name: "Qt3DCore::QNode"
+ prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
+ Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
+ Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
+ Signal {
+ name: "parentChanged"
+ Parameter { name: "parent"; type: "QObject"; isPointer: true }
+ }
+ Signal {
+ name: "enabledChanged"
+ Parameter { name: "enabled"; type: "bool" }
+ }
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ Signal { name: "nodeDestroyed" }
+ Method {
+ name: "setParent"
+ Parameter { name: "parent"; type: "QNode"; isPointer: true }
+ }
+ Method {
+ name: "setEnabled"
+ Parameter { name: "isEnabled"; type: "bool" }
+ }
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ }
Component {
name: "Qt3DExtras::Extras::Quick::Quick3DLevelOfDetailLoader"
prototype: "Qt3DCore::QEntity"
@@ -758,13 +799,15 @@ Module {
prototype: "Qt3DRender::QTechniqueFilter"
exports: [
"Qt3D.Extras/ForwardRenderer 2.0",
+ "Qt3D.Extras/ForwardRenderer 2.14",
"Qt3D.Extras/ForwardRenderer 2.9"
]
- exportMetaObjectRevisions: [0, 9]
+ exportMetaObjectRevisions: [0, 14, 9]
Property { name: "surface"; type: "QObject"; isPointer: true }
Property { name: "window"; type: "QObject"; isPointer: true }
Property { name: "viewportRect"; type: "QRectF" }
Property { name: "clearColor"; type: "QColor" }
+ Property { name: "buffersToClear"; revision: 14; type: "Qt3DRender::QClearBuffers::BufferType" }
Property { name: "camera"; type: "Qt3DCore::QEntity"; isPointer: true }
Property { name: "externalRenderTargetSize"; type: "QSize" }
Property { name: "frustumCulling"; type: "bool" }
@@ -778,6 +821,10 @@ Module {
Parameter { name: "clearColor"; type: "QColor" }
}
Signal {
+ name: "buffersToClearChanged"
+ Parameter { type: "Qt3DRender::QClearBuffers::BufferType" }
+ }
+ Signal {
name: "cameraChanged"
Parameter { name: "camera"; type: "Qt3DCore::QEntity"; isPointer: true }
}
@@ -806,6 +853,10 @@ Module {
Parameter { name: "clearColor"; type: "QColor" }
}
Method {
+ name: "setBuffersToClear"
+ Parameter { type: "Qt3DRender::QClearBuffers::BufferType" }
+ }
+ Method {
name: "setCamera"
Parameter { name: "camera"; type: "Qt3DCore::QEntity"; isPointer: true }
}
diff --git a/src/quick3d/imports/input/plugins.qmltypes b/src/quick3d/imports/input/plugins.qmltypes
index 8e9cac4d1..0a70b97c3 100644
--- a/src/quick3d/imports/input/plugins.qmltypes
+++ b/src/quick3d/imports/input/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Input 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Input 2.14'
Module {
dependencies: ["Qt3D.Core 2.0"]
diff --git a/src/quick3d/imports/logic/plugins.qmltypes b/src/quick3d/imports/logic/plugins.qmltypes
index 294f6b068..1ad7b1f58 100644
--- a/src/quick3d/imports/logic/plugins.qmltypes
+++ b/src/quick3d/imports/logic/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Logic 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Logic 2.14'
Module {
dependencies: ["Qt3D.Core 2.0"]
diff --git a/src/quick3d/imports/render/plugins.qmltypes b/src/quick3d/imports/render/plugins.qmltypes
index f5f5b3c61..6408abb27 100644
--- a/src/quick3d/imports/render/plugins.qmltypes
+++ b/src/quick3d/imports/render/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Render 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt3D.Render 2.14'
Module {
dependencies: ["Qt3D.Core 2.0"]
@@ -362,7 +362,8 @@ Module {
"R5G6B5": 36194,
"RGB5A1": 32855,
"RGBA4": 32854,
- "RGB10A2": 36975,
+ "RGB10A2": 32857,
+ "RGB10A2U": 36975,
"D16": 33189,
"D24": 33190,
"D24S8": 35056,
@@ -588,6 +589,10 @@ Module {
name: "setSamples"
Parameter { name: "samples"; type: "int" }
}
+ Method {
+ name: "updateData"
+ Parameter { name: "update"; type: "QTextureDataUpdate" }
+ }
}
Component {
name: "Qt3DRender::QAbstractTextureImage"
@@ -1068,8 +1073,12 @@ Module {
Component {
name: "Qt3DRender::QCamera"
prototype: "Qt3DCore::QEntity"
- exports: ["Qt3D.Render/Camera 2.0", "Qt3D.Render/Camera 2.9"]
- exportMetaObjectRevisions: [0, 9]
+ exports: [
+ "Qt3D.Render/Camera 2.0",
+ "Qt3D.Render/Camera 2.14",
+ "Qt3D.Render/Camera 2.9"
+ ]
+ exportMetaObjectRevisions: [0, 14, 9]
Enum {
name: "CameraTranslationOption"
values: {
@@ -1093,6 +1102,20 @@ Module {
Property { name: "viewCenter"; type: "QVector3D" }
Property { name: "viewVector"; type: "QVector3D"; isReadonly: true }
Property { name: "viewMatrix"; type: "QMatrix4x4"; isReadonly: true }
+ Property {
+ name: "lens"
+ revision: 14
+ type: "Qt3DRender::QCameraLens"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "transform"
+ revision: 14
+ type: "Qt3DCore::QTransform"
+ isReadonly: true
+ isPointer: true
+ }
Signal {
name: "projectionTypeChanged"
Parameter { name: "projectionType"; type: "QCameraLens::ProjectionType" }
@@ -1666,6 +1689,30 @@ Module {
}
}
Component {
+ name: "Qt3DRender::QDepthRange"
+ prototype: "Qt3DRender::QRenderState"
+ exports: ["Qt3D.Render/DepthRange 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "nearValue"; type: "double" }
+ Property { name: "farValue"; type: "double" }
+ Signal {
+ name: "nearValueChanged"
+ Parameter { name: "nearValue"; type: "double" }
+ }
+ Signal {
+ name: "farValueChanged"
+ Parameter { name: "farValue"; type: "double" }
+ }
+ Method {
+ name: "setNearValue"
+ Parameter { name: "value"; type: "double" }
+ }
+ Method {
+ name: "setFarValue"
+ Parameter { name: "value"; type: "double" }
+ }
+ }
+ Component {
name: "Qt3DRender::QDepthTest"
prototype: "Qt3DRender::QRenderState"
exports: ["Qt3D.Render/DepthTest 2.0"]
@@ -2335,6 +2382,12 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "Qt3DRender::QNoPicking"
+ prototype: "Qt3DRender::QFrameGraphNode"
+ exports: ["Qt3D.Render/NoPicking 2.14"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
name: "Qt3DRender::QObjectPicker"
prototype: "Qt3DCore::QComponent"
exports: [
@@ -2429,9 +2482,9 @@ Module {
Component {
name: "Qt3DRender::QPickEvent"
prototype: "QObject"
- exports: ["Qt3D.Render/PickEvent 2.0"]
+ exports: ["Qt3D.Render/PickEvent 2.0", "Qt3D.Render/PickEvent 2.14"]
isCreatable: false
- exportMetaObjectRevisions: [0]
+ exportMetaObjectRevisions: [0, 14]
Enum {
name: "Buttons"
values: {
@@ -2461,6 +2514,20 @@ Module {
Property { name: "button"; type: "Qt3DRender::QPickEvent::Buttons"; isReadonly: true }
Property { name: "buttons"; type: "int"; isReadonly: true }
Property { name: "modifiers"; type: "int"; isReadonly: true }
+ Property {
+ name: "viewport"
+ revision: 14
+ type: "Qt3DRender::QViewport"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "entity"
+ revision: 14
+ type: "Qt3DCore::QEntity"
+ isReadonly: true
+ isPointer: true
+ }
Signal {
name: "acceptedChanged"
Parameter { name: "accepted"; type: "bool" }
@@ -2654,6 +2721,46 @@ Module {
}
}
Component {
+ name: "Qt3DRender::QRasterMode"
+ prototype: "Qt3DRender::QRenderState"
+ exports: ["Qt3D.Render/RasterMode 2.13"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "RasterMode"
+ values: {
+ "Points": 6912,
+ "Lines": 6913,
+ "Fill": 6914
+ }
+ }
+ Enum {
+ name: "FaceMode"
+ values: {
+ "Front": 1028,
+ "Back": 1029,
+ "FrontAndBack": 1032
+ }
+ }
+ Property { name: "rasterMode"; type: "RasterMode" }
+ Property { name: "faceMode"; type: "FaceMode" }
+ Signal {
+ name: "rasterModeChanged"
+ Parameter { name: "rasterMode"; type: "RasterMode" }
+ }
+ Signal {
+ name: "faceModeChanged"
+ Parameter { name: "faceMode"; type: "FaceMode" }
+ }
+ Method {
+ name: "setRasterMode"
+ Parameter { name: "rasterMode"; type: "RasterMode" }
+ }
+ Method {
+ name: "setFaceMode"
+ Parameter { name: "faceMode"; type: "FaceMode" }
+ }
+ }
+ Component {
name: "Qt3DRender::QRayCaster"
prototype: "Qt3DRender::QAbstractRayCaster"
Property { name: "origin"; type: "QVector3D" }
@@ -3151,6 +3258,120 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "Qt3DRender::QShaderImage"
+ prototype: "Qt3DCore::QNode"
+ exports: ["Qt3D.Render/ShaderImage 2.14"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Access"
+ values: {
+ "ReadOnly": 0,
+ "WriteOnly": 1,
+ "ReadWrite": 2
+ }
+ }
+ Enum {
+ name: "ImageFormat"
+ values: {
+ "NoFormat": 0,
+ "Automatic": 1,
+ "R8_UNorm": 33321,
+ "RG8_UNorm": 33323,
+ "RGBA8_UNorm": 32856,
+ "R16_UNorm": 33322,
+ "RG16_UNorm": 33324,
+ "RGBA16_UNorm": 32859,
+ "R8_SNorm": 36756,
+ "RG8_SNorm": 36757,
+ "RGBA8_SNorm": 36759,
+ "R16_SNorm": 36760,
+ "RG16_SNorm": 36761,
+ "RGBA16_SNorm": 36763,
+ "R8U": 33330,
+ "RG8U": 33336,
+ "RGBA8U": 36220,
+ "R16U": 33332,
+ "RG16U": 33338,
+ "RGBA16U": 36214,
+ "R32U": 33334,
+ "RG32U": 33340,
+ "RGBA32U": 36208,
+ "R8I": 33329,
+ "RG8I": 33335,
+ "RGBA8I": 36238,
+ "R16I": 33331,
+ "RG16I": 33337,
+ "RGBA16I": 36232,
+ "R32I": 33333,
+ "RG32I": 33339,
+ "RGBA32I": 36226,
+ "R16F": 33325,
+ "RG16F": 33327,
+ "RGBA16F": 34842,
+ "R32F": 33326,
+ "RG32F": 33328,
+ "RGBA32F": 34836,
+ "RG11B10F": 35898,
+ "RGB10A2": 32857,
+ "RGB10A2U": 36975
+ }
+ }
+ Property { name: "texture"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ Property { name: "layered"; type: "bool" }
+ Property { name: "mipLevel"; type: "int" }
+ Property { name: "layer"; type: "int" }
+ Property { name: "access"; type: "Access" }
+ Property { name: "format"; type: "ImageFormat" }
+ Signal {
+ name: "textureChanged"
+ Parameter { name: "texture"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ }
+ Signal {
+ name: "layeredChanged"
+ Parameter { name: "layered"; type: "bool" }
+ }
+ Signal {
+ name: "mipLevelChanged"
+ Parameter { name: "mipLevel"; type: "int" }
+ }
+ Signal {
+ name: "layerChanged"
+ Parameter { name: "layer"; type: "int" }
+ }
+ Signal {
+ name: "accessChanged"
+ Parameter { name: "access"; type: "Access" }
+ }
+ Signal {
+ name: "formatChanged"
+ Parameter { name: "format"; type: "ImageFormat" }
+ }
+ Method {
+ name: "setTexture"
+ Parameter { name: "texture"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ }
+ Method {
+ name: "setLayered"
+ Parameter { name: "layered"; type: "bool" }
+ }
+ Method {
+ name: "setMipLevel"
+ Parameter { name: "mipLevel"; type: "int" }
+ }
+ Method {
+ name: "setLayer"
+ Parameter { name: "layer"; type: "int" }
+ }
+ Method {
+ name: "setAccess"
+ Parameter { name: "access"; type: "Access" }
+ }
+ Method {
+ name: "setFormat"
+ Parameter { name: "format"; type: "ImageFormat" }
+ }
+ }
+ Component {
name: "Qt3DRender::QShaderProgram"
prototype: "Qt3DCore::QNode"
exports: [
@@ -3400,7 +3621,8 @@ Module {
"StateChangeCost": 1,
"BackToFront": 2,
"Material": 4,
- "FrontToBack": 8
+ "FrontToBack": 8,
+ "Texture": 16
}
}
Property { name: "sortTypes"; type: "QVector<int>" }
@@ -3653,6 +3875,25 @@ Module {
}
}
Component {
+ name: "Qt3DRender::QSubtreeEnabler"
+ prototype: "Qt3DRender::QFrameGraphNode"
+ exports: ["Qt3D.Render/SubtreeEnabler 2.14"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Enablement"
+ values: {
+ "Persistent": 0,
+ "SingleShot": 1
+ }
+ }
+ Property { name: "enablement"; type: "Enablement" }
+ Signal {
+ name: "enablementChanged"
+ Parameter { name: "enablement"; type: "Qt3DRender::QSubtreeEnabler::Enablement" }
+ }
+ Method { name: "requestUpdate" }
+ }
+ Component {
name: "Qt3DRender::QTechnique"
defaultProperty: "data"
prototype: "Qt3DCore::QNode"
diff --git a/src/quick3d/imports/scene2d/plugins.qmltypes b/src/quick3d/imports/scene2d/plugins.qmltypes
index 9d2c855a6..32fb8122f 100644
--- a/src/quick3d/imports/scene2d/plugins.qmltypes
+++ b/src/quick3d/imports/scene2d/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene2D 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene2D 2.14'
Module {
dependencies: ["Qt3D.Core 2.0", "Qt3D.Render 2.0"]
diff --git a/src/quick3d/imports/scene3d/plugins.qmltypes b/src/quick3d/imports/scene3d/plugins.qmltypes
index da3d7ec3e..aca01ac25 100644
--- a/src/quick3d/imports/scene3d/plugins.qmltypes
+++ b/src/quick3d/imports/scene3d/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene3D 2.13'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Scene3D 2.14'
Module {
dependencies: ["Qt3D.Core 2.0", "QtQuick 2.0"]
@@ -12,8 +12,11 @@ Module {
name: "Qt3DRender::Scene3DItem"
defaultProperty: "entity"
prototype: "QQuickItem"
- exports: ["QtQuick.Scene3D/Scene3D 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Scene3D/Scene3D 2.0",
+ "QtQuick.Scene3D/Scene3D 2.14"
+ ]
+ exportMetaObjectRevisions: [0, 14]
Enum {
name: "CameraAspectRatioMode"
values: {
@@ -21,11 +24,19 @@ Module {
"UserAspectRatio": 1
}
}
+ Enum {
+ name: "CompositingMode"
+ values: {
+ "FBO": 0,
+ "Underlay": 1
+ }
+ }
Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
Property { name: "aspects"; type: "QStringList" }
Property { name: "multisample"; type: "bool" }
Property { name: "cameraAspectRatioMode"; type: "CameraAspectRatioMode" }
Property { name: "hoverEnabled"; type: "bool" }
+ Property { name: "compositingMode"; revision: 14; type: "CompositingMode" }
Signal {
name: "cameraAspectRatioModeChanged"
Parameter { name: "mode"; type: "CameraAspectRatioMode" }
@@ -47,9 +58,30 @@ Module {
Parameter { name: "enabled"; type: "bool" }
}
Method {
+ name: "setCompositingMode"
+ Parameter { name: "mode"; type: "CompositingMode" }
+ }
+ Method {
name: "setItemAreaAndDevicePixelRatio"
Parameter { name: "area"; type: "QSize" }
Parameter { name: "devicePixelRatio"; type: "double" }
}
}
+ Component {
+ name: "Qt3DRender::Scene3DView"
+ defaultProperty: "entity"
+ prototype: "QQuickItem"
+ exports: ["QtQuick.Scene3D/Scene3DView 2.14"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ Property { name: "scene3D"; type: "Qt3DRender::Scene3DItem"; isPointer: true }
+ Method {
+ name: "setEntity"
+ Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ }
+ Method {
+ name: "setScene3D"
+ Parameter { name: "scene3D"; type: "Scene3DItem"; isPointer: true }
+ }
+ }
}
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp
index f3f7acd71..f824d2c4e 100644
--- a/src/quick3d/imports/scene3d/scene3ditem.cpp
+++ b/src/quick3d/imports/scene3d/scene3ditem.cpp
@@ -137,6 +137,11 @@ namespace Qt3DRender {
\li The Scene3D instance is instantiated prior to any Scene3DView
\li The Scene3D entity property is left unset
\endlist
+
+ \note Åšetting the visibility of the Scene3D element to false will halt the
+ Qt 3D simulation loop. This means that binding the visible property to an
+ expression that depends on property updates driven by the Qt 3D simulation
+ loop (FrameAction) will never reavaluates.
*/
Scene3DItem::Scene3DItem(QQuickItem *parent)
: QQuickItem(parent)
@@ -154,6 +159,7 @@ Scene3DItem::Scene3DItem(QQuickItem *parent)
, m_disableClearWindow(false)
, m_cameraAspectRatioMode(AutomaticAspectRatio)
, m_compositingMode(FBO)
+ , m_dummySurface(nullptr)
{
setFlag(QQuickItem::ItemHasContents, true);
setAcceptedMouseButtons(Qt::MouseButtonMask);
@@ -427,12 +433,26 @@ void Scene3DItem::applyRootEntityChange()
bool Scene3DItem::needsRender()
{
+ // We need the dirty flag which is connected to the change arbiter
+ // receiving updates to know whether something in the scene has changed
+
+ // Ideally we would use shouldRender() alone but given that it becomes true
+ // only after the arbiter has sync the changes and might be reset before
+ // process jobs is completed, we cannot fully rely on it. It would require
+ // splitting processFrame in 2 parts.
+
+ // We only use it for cases where Qt3D render may require several loops of
+ // the simulation to fully process a frame (e.g shaders are loaded in frame
+ // n and we can only build render commands for the new shader at frame n +
+ // This is where renderer->shouldRender() comes into play as it knows
+ // whether some states remain dirty or not (even after processFrame is
+ // called)
+
auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect));
const bool dirty = m_dirty
|| (renderAspectPriv
&& renderAspectPriv->m_renderer
- && renderAspectPriv->m_renderer->settings()
- && renderAspectPriv->m_renderer->settings()->renderPolicy() == QRenderSettings::Always);
+ && renderAspectPriv->m_renderer->shouldRender());
m_dirty = false;
return dirty;
}
@@ -454,8 +474,12 @@ bool Scene3DItem::needsRender()
// processFrame will block and wait for renderer to have been finished
void Scene3DItem::onBeforeSync()
{
- // Has anything in the 3D scene actually changed that requires us to render?
- if (!needsRender())
+ static bool dontRenderWhenHidden = !qgetenv("QT3D_SCENE3D_STOP_RENDER_HIDDEN").isEmpty();
+
+ // If we are not visible, don't processFrame changes as we would end up
+ // waiting forever for the scene to be rendered which won't happen
+ // if the Scene3D item is not visible
+ if (!isVisible() && dontRenderWhenHidden)
return;
Q_ASSERT(QThread::currentThread() == thread());
@@ -498,6 +522,7 @@ void Scene3DItem::onBeforeSync()
// start rendering before this function has been called
// We add in a safety to skip such frames as this could otherwise
// make Qt3D enter a locked state
+ m_renderer->setSkipFrame(!needsRender());
m_renderer->allowRender();
// Note: it's too early to request an update at this point as
@@ -546,7 +571,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject)
/*!
\qmlmethod void Scene3D::setItemAreaAndDevicePixelRatio(size area, real devicePixelRatio)
- \brief \TODO
+ Sets the item area to \a area and the pixel ratio to \a devicePixelRatio.
*/
void Scene3DItem::setItemAreaAndDevicePixelRatio(QSize area, qreal devicePixelRatio)
{
@@ -569,25 +594,45 @@ bool Scene3DItem::isHoverEnabled() const
void Scene3DItem::setCameraAspectModeHelper()
{
- switch (m_cameraAspectRatioMode) {
- case AutomaticAspectRatio:
- connect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
- connect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
- // Update the aspect ratio the first time the surface is set
- updateCameraAspectRatio();
- break;
- case UserAspectRatio:
- disconnect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
- disconnect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
- break;
+ if (m_compositingMode == FBO) {
+ switch (m_cameraAspectRatioMode) {
+ case AutomaticAspectRatio:
+ connect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ connect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ // Update the aspect ratio the first time the surface is set
+ updateCameraAspectRatio();
+ break;
+ case UserAspectRatio:
+ disconnect(this, &Scene3DItem::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ disconnect(this, &Scene3DItem::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ break;
+ }
+ } else {
+ // In Underlay mode, we rely on the window for aspect ratio and not the size of the Scene3DItem
+ switch (m_cameraAspectRatioMode) {
+ case AutomaticAspectRatio:
+ connect(window(), &QWindow::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ connect(window(), &QWindow::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ // Update the aspect ratio the first time the surface is set
+ updateCameraAspectRatio();
+ break;
+ case UserAspectRatio:
+ disconnect(window(), &QWindow::widthChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ disconnect(window(), &QWindow::heightChanged, this, &Scene3DItem::updateCameraAspectRatio);
+ break;
+ }
}
}
void Scene3DItem::updateCameraAspectRatio()
{
if (m_camera) {
- m_camera->setAspectRatio(static_cast<float>(width()) /
- static_cast<float>(height()));
+ if (m_compositingMode == FBO)
+ m_camera->setAspectRatio(static_cast<float>(width()) /
+ static_cast<float>(height()));
+ else
+ m_camera->setAspectRatio(static_cast<float>(window()->width()) /
+ static_cast<float>(window()->height()));
}
}
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index 1e375ccbb..fafeeedf4 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -161,7 +161,9 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_forceRecreate(false)
, m_shouldRender(false)
, m_dirtyViews(false)
+ , m_skipFrame(false)
, m_allowRendering(0)
+ , m_compositingMode(Scene3DItem::FBO)
{
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
@@ -277,6 +279,19 @@ void Scene3DRenderer::beforeSynchronize()
// We could otherwise enter a deadlock state
if (!m_allowRendering.tryAcquire(std::max(m_allowRendering.available(), 1)))
return;
+
+ // In the case of OnDemand rendering, we still need to get to this
+ // point to ensure we have processed jobs for all aspects.
+ // We also still need to call render() to allow proceeding with the
+ // next frame. However it won't be performing any 3d rendering at all
+ // so we do it here and return early. This prevents a costly QtQuick
+ // SceneGraph update for nothing
+ if (m_skipFrame) {
+ m_skipFrame = false;
+ static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(false);
+ return;
+ }
+
m_shouldRender = true;
// Check size / multisampling
@@ -359,6 +374,11 @@ void Scene3DRenderer::setCompositingMode(Scene3DItem::CompositingMode mode)
m_compositingMode = mode;
}
+void Scene3DRenderer::setSkipFrame(bool skip)
+{
+ m_skipFrame = skip;
+}
+
// Main Thread, Render Thread locked
void Scene3DRenderer::setScene3DViews(const QVector<Scene3DView *> views)
{
@@ -422,7 +442,8 @@ void Scene3DRenderer::render()
// Only show the node once Qt3D has rendered to it
// Avoids showing garbage on the first frame
- m_node->show();
+ if (m_node)
+ m_node->show();
}
// Reset the state used by the Qt Quick scenegraph to avoid any
diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h
index 4f3651cd3..08a2c60a3 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer_p.h
+++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h
@@ -87,7 +87,7 @@ public:
void setCleanerHelper(Scene3DCleaner *cleaner);
void allowRender();
void setCompositingMode(Scene3DItem::CompositingMode mode);
-
+ void setSkipFrame(bool skip);
void setScene3DViews(const QVector<Scene3DView *> views);
public Q_SLOTS:
@@ -119,6 +119,7 @@ private:
bool m_forceRecreate;
bool m_shouldRender;
bool m_dirtyViews;
+ bool m_skipFrame;
QSemaphore m_allowRendering;
Scene3DItem::CompositingMode m_compositingMode;
QVector<Scene3DView *> m_views;
diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
index 55538ad1f..cfe39e8c7 100644
--- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
+++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp
@@ -76,6 +76,7 @@ Scene3DSGMaterialShader::Scene3DSGMaterialShader()
: QSGMaterialShader()
, m_matrixId(-1)
, m_opacityId(-1)
+ , m_visibleId(-1)
{
}
diff --git a/src/quick3d/imports/scene3d/scene3dview.cpp b/src/quick3d/imports/scene3d/scene3dview.cpp
index 9d298b435..f38d135f0 100644
--- a/src/quick3d/imports/scene3d/scene3dview.cpp
+++ b/src/quick3d/imports/scene3d/scene3dview.cpp
@@ -278,6 +278,8 @@ QSGNode *Scene3DView::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
if (m_dirtyFlags & DirtyTexture) {
fboNode->setTexture(m_texture);
m_dirtyFlags.setFlag(DirtyTexture, false);
+ // Show FBO Node at this point
+ fboNode->show();
}
if (m_dirtyFlags & DirtyNode) {
fboNode->markDirty(QSGNode::DirtyMaterial);
diff --git a/src/quick3d/quick3d/qquaternionanimation.cpp b/src/quick3d/quick3d/qquaternionanimation.cpp
index 22cc905f7..933a08ee4 100644
--- a/src/quick3d/quick3d/qquaternionanimation.cpp
+++ b/src/quick3d/quick3d/qquaternionanimation.cpp
@@ -144,7 +144,7 @@ void QQuaternionAnimation::setType(Type type)
switch (type) {
case Nlerp:
QT_WARNING_PUSH
-QT_WARNING_DISABLE_GCC(-Wcast-function-type)
+QT_WARNING_DISABLE_GCC("-Wcast-function-type")
d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&q_quaternionNlerpInterpolator);
QT_WARNING_POP
break;
diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp
index d67dfdc71..043aca8b9 100644
--- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp
+++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp
@@ -276,7 +276,7 @@ void Qt3DQuickWindow::updateCameraAspectRatio()
Q_D(Qt3DQuickWindow);
if (d->m_camera) {
d->m_camera->setAspectRatio(static_cast<float>(width()) /
- static_cast<float>(height()));
+ std::max(1.f, static_cast<float>(height())));
}
}
diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp
index cbdc83e7d..b12adb8ed 100644
--- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp
@@ -52,6 +52,12 @@ namespace Qt3DRender {
namespace Quick {
/*!
+ \namespace Qt3DRender::Quick
+ \inmodule Qt3DScene2D
+ \brief Internal namespace to import QML types.
+*/
+
+/*!
\class Qt3DRender::Quick::QScene2D
\inheaderfile Qt3DQuickScene2D/QScene2D
\inmodule Qt3DScene2D
diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.h b/src/quick3d/quick3dscene2d/items/qscene2d.h
index 2f5c1010e..38eaf7359 100644
--- a/src/quick3d/quick3dscene2d/items/qscene2d.h
+++ b/src/quick3d/quick3dscene2d/items/qscene2d.h
@@ -51,11 +51,6 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
-/*!
- \namespace Qt3DRender::Quick
-
- \brief Internal namespace to import QML types.
-*/
namespace Quick {
class QScene2DPrivate;
diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp
index 981b290e2..a2247705e 100644
--- a/src/quick3d/quick3dscene2d/items/scene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp
@@ -208,11 +208,16 @@ void Scene2D::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
if (!entity)
return;
- registerObjectPickerEvents(entity);
+ if (registerObjectPickerEvents(entity))
+ m_entities.push_back(id);
+ else
+ Qt3DCore::QNodePrivate::get(const_cast<Qt3DCore::QNode *>(frontEnd))->update();
}
- for (const auto &id: removedEntities)
+ for (const auto &id: removedEntities) {
+ m_entities.removeOne(id);
unregisterObjectPickerEvents(id);
- m_entities = ids;
+ }
+ std::sort(std::begin(m_entities), std::end(m_entities));
if (firstTime)
setSharedObject(dnode->m_renderManager->m_sharedObject);
@@ -428,8 +433,11 @@ bool Scene2D::registerObjectPickerEvents(Qt3DCore::QEntity *qentity)
{
Entity *entity = nullptr;
if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
- qentity->id(), (void**)&entity, nullptr))
+ qentity->id(), (void**)&entity, nullptr)) {
+ qCWarning(Qt3DRender::Quick::Scene2D) << Q_FUNC_INFO
+ << "Entity not yet available in backend";
return false;
+ }
if (!entity->containsComponentsOfType<ObjectPicker>() ||
!entity->containsComponentsOfType<GeometryRenderer>()) {
diff --git a/src/quick3d/quick3dscene2d/items/scene2dsharedobject.cpp b/src/quick3d/quick3dscene2d/items/scene2dsharedobject.cpp
index cb9973f0a..aed624501 100644
--- a/src/quick3d/quick3dscene2d/items/scene2dsharedobject.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2dsharedobject.cpp
@@ -59,6 +59,7 @@ Scene2DSharedObject::Scene2DSharedObject(Scene2DManager *manager)
, m_quickWindow(nullptr)
, m_renderManager(manager)
, m_surface(nullptr)
+ , m_renderThread(nullptr)
, m_renderObject(nullptr)
, m_disallowed(false)
, m_quit(false)
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index b618eda55..8bbfcd548 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -71,6 +71,7 @@ class QAbstractFrameAdvanceService;
class QEventFilterService;
class QAbstractAspectJobManager;
class QServiceLocator;
+class QAspectManager;
}
namespace Qt3DRender {
@@ -151,8 +152,9 @@ public:
#if defined(QT_BUILD_INTERNAL)
virtual void clearDirtyBits(BackendNodeDirtySet changes) = 0;
#endif
- virtual bool shouldRender() = 0;
+ virtual bool shouldRender() const = 0;
virtual void skipNextFrame() = 0;
+ virtual void jobsDone(Qt3DCore::QAspectManager *manager) = 0;
virtual QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() = 0;
virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0;
diff --git a/src/render/backend/bufferutils_p.h b/src/render/backend/bufferutils_p.h
index 2bb35fac6..ea783df0d 100644
--- a/src/render/backend/bufferutils_p.h
+++ b/src/render/backend/bufferutils_p.h
@@ -74,6 +74,8 @@ struct BufferInfo
, count(0)
, byteStride(0)
, byteOffset(0)
+ , restartEnabled(false)
+ , restartIndexValue(-1)
{}
QByteArray data;
@@ -82,6 +84,8 @@ struct BufferInfo
uint count;
uint byteStride;
uint byteOffset;
+ bool restartEnabled;
+ int restartIndexValue;
};
diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp
index 85c5e9656..e1d72efda 100644
--- a/src/render/backend/cameralens.cpp
+++ b/src/render/backend/cameralens.cpp
@@ -46,8 +46,10 @@
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/sphere_p.h>
#include <Qt3DRender/private/computefilteredboundingvolumejob_p.h>
+#include <Qt3DRender/private/renderlogging_p.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
QT_BEGIN_NAMESPACE
@@ -62,21 +64,21 @@ namespace {
class GetBoundingVolumeWithoutCameraJob : public ComputeFilteredBoundingVolumeJob
{
public:
- GetBoundingVolumeWithoutCameraJob(CameraLens *lens,
- QNodeCommand::CommandId commandId)
- : m_lens(lens), m_commandId(commandId)
+ GetBoundingVolumeWithoutCameraJob(CameraLens *lens, QNodeId commandId)
+ : m_lens(lens), m_requestId(commandId)
{
}
protected:
- void finished(const Sphere &sphere) override
+ // called in main thread
+ void finished(Qt3DCore::QAspectManager *aspectManager, const Sphere &sphere) override
{
- m_lens->notifySceneBoundingVolume(sphere, m_commandId);
+ m_lens->processViewAllResult(aspectManager, sphere, m_requestId);
}
private:
CameraLens *m_lens;
- QNodeCommand::CommandId m_commandId;
+ QNodeId m_requestId;
};
} // namespace
@@ -114,6 +116,9 @@ Matrix4x4 CameraLens::viewMatrix(const Matrix4x4 &worldTransform)
m.lookAt(convertToQVector3D(Vector3D(position)),
convertToQVector3D(Vector3D(position + viewDirection)),
convertToQVector3D(Vector3D(upVector)));
+
+ qDebug(Jobs) << Q_FUNC_INFO << "Transform Matrix" << worldTransform << "View Matrix" << m;
+
return Matrix4x4(m);
}
@@ -131,34 +136,23 @@ void CameraLens::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTim
markDirty(AbstractRenderer::AllDirty);
}
- if (node->exposure() != m_exposure) {
+ if (!qFuzzyCompare(node->exposure(), m_exposure)) {
m_exposure = node->exposure();
markDirty(AbstractRenderer::AllDirty);
}
const QCameraLensPrivate *d = static_cast<const QCameraLensPrivate *>(QNodePrivate::get(node));
- if (d->m_pendingViewAllCommand != m_pendingViewAllCommand) {
- m_pendingViewAllCommand = d->m_pendingViewAllCommand;
-
- if (m_pendingViewAllCommand) {
- const QVariant v = m_pendingViewAllCommand.data;
- const QNodeCommand::CommandId commandId = m_pendingViewAllCommand.commandId;
-
- if (m_pendingViewAllCommand.name == QLatin1String("QueryRootBoundingVolume")) {
- const QNodeId id = v.value<QNodeId>();
- computeSceneBoundingVolume({}, id, commandId);
- } else if (m_pendingViewAllCommand.name == QLatin1String("QueryEntityBoundingVolume")) {
- const QVector<QNodeId> ids = v.value<QVector<QNodeId>>();
- if (ids.size() == 2)
- computeSceneBoundingVolume(ids[0], ids[1], commandId);
- }
- }
+ if (d->m_pendingViewAllRequest != m_pendingViewAllRequest) {
+ m_pendingViewAllRequest = d->m_pendingViewAllRequest;
+
+ if (m_pendingViewAllRequest)
+ computeSceneBoundingVolume(m_pendingViewAllRequest.entityId, m_pendingViewAllRequest.cameraId, m_pendingViewAllRequest.requestId);
}
}
void CameraLens::computeSceneBoundingVolume(QNodeId entityId,
QNodeId cameraId,
- QNodeCommand::CommandId commandId)
+ QNodeId requestId)
{
if (!m_renderer || !m_renderAspect)
return;
@@ -171,7 +165,7 @@ void CameraLens::computeSceneBoundingVolume(QNodeId entityId,
return;
Entity *camNode = nodeManagers->renderNodesManager()->lookupResource(cameraId);
- ComputeFilteredBoundingVolumeJobPtr job(new GetBoundingVolumeWithoutCameraJob(this, commandId));
+ ComputeFilteredBoundingVolumeJobPtr job(new GetBoundingVolumeWithoutCameraJob(this, requestId));
job->addDependency(m_renderer->expandBoundingVolumeJob());
job->setRoot(root);
job->setManagers(nodeManagers);
@@ -179,18 +173,18 @@ void CameraLens::computeSceneBoundingVolume(QNodeId entityId,
m_renderAspect->scheduleSingleShotJob(job);
}
-void CameraLens::notifySceneBoundingVolume(const Sphere &sphere, QNodeCommand::CommandId commandId)
+void CameraLens::processViewAllResult(QAspectManager *aspectManager, const Sphere &sphere, QNodeId commandId)
{
- if (!m_pendingViewAllCommand || m_pendingViewAllCommand.commandId != commandId)
+ if (!m_pendingViewAllRequest || m_pendingViewAllRequest.requestId != commandId)
return;
if (sphere.radius() > 0.f) {
- QVector<float> data = { sphere.center().x(), sphere.center().y(), sphere.center().z(),
- sphere.radius() };
- QVariant v;
- v.setValue(data);
- sendCommand(QLatin1String("ViewAll"), v, m_pendingViewAllCommand.commandId);
+ QCameraLens *lens = qobject_cast<QCameraLens *>(aspectManager->lookupNode(peerId()));
+ if (lens) {
+ QCameraLensPrivate *dlens = static_cast<QCameraLensPrivate *>(QCameraLensPrivate::get(lens));
+ dlens->processViewAllResult(m_pendingViewAllRequest.requestId, { sphere.center().x(), sphere.center().y(), sphere.center().z() }, sphere.radius());
+ }
}
- m_pendingViewAllCommand = {};
+ m_pendingViewAllRequest = {};
}
void CameraLens::setProjection(const Matrix4x4 &projection)
diff --git a/src/render/backend/cameralens_p.h b/src/render/backend/cameralens_p.h
index bd721d5e9..4afa38620 100644
--- a/src/render/backend/cameralens_p.h
+++ b/src/render/backend/cameralens_p.h
@@ -52,7 +52,6 @@
//
#include <Qt3DRender/private/backendnode_p.h>
-#include <Qt3DCore/private/qnodecommand_p.h>
#include <Qt3DCore/private/matrix4x4_p.h>
#include <Qt3DRender/private/qcameralens_p.h>
#include <QRectF>
@@ -99,7 +98,7 @@ public:
inline float exposure() const { return m_exposure; }
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
- void notifySceneBoundingVolume(const Sphere &sphere, Qt3DCore::QNodeCommand::CommandId commandId);
+ void processViewAllResult(Qt3DCore::QAspectManager *aspectManager, const Sphere &sphere, Qt3DCore::QNodeId commandId);
static bool viewMatrixForCamera(EntityManager *manager, Qt3DCore::QNodeId cameraId,
Matrix4x4 &viewMatrix, Matrix4x4 &projectionMatrix);
@@ -107,10 +106,10 @@ public:
private:
void computeSceneBoundingVolume(Qt3DCore::QNodeId entityId,
Qt3DCore::QNodeId cameraId,
- Qt3DCore::QNodeCommand::CommandId commandId);
+ Qt3DCore::QNodeId requestId);
QRenderAspect *m_renderAspect;
- CameraLensCommand m_pendingViewAllCommand;
+ CameraLensRequest m_pendingViewAllRequest;
Matrix4x4 m_projection;
float m_exposure;
};
diff --git a/src/render/backend/commandexecuter.cpp b/src/render/backend/commandexecuter.cpp
index 8bccb1437..5ed0c970d 100644
--- a/src/render/backend/commandexecuter.cpp
+++ b/src/render/backend/commandexecuter.cpp
@@ -248,10 +248,10 @@ QJsonObject parameterPackToJson(const Render::ShaderParameterPack &pack)
const Render::PackUniformHash &uniforms = pack.uniforms();
QJsonArray uniformsArray;
- for (auto it = uniforms.cbegin(), end = uniforms.cend(); it != end; ++it) {
+ for (int i = 0, m = uniforms.keys.size(); i < m; ++i) {
QJsonObject uniformObj;
- uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(it.key()));
- const Render::UniformValue::ValueType type = it.value().valueType();
+ uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i)));
+ const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType();
uniformObj.insert(QLatin1String("type"),
type == Render::UniformValue::ScalarValue
? QLatin1String("value")
@@ -346,15 +346,15 @@ void CommandExecuter::performAsynchronousCommandExecution(const QVector<Render::
viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue());
QJsonArray renderCommandsArray;
- for (Render::RenderCommand *c : v->commands()) {
+ for (const Render::RenderCommand &c : v->commands()) {
QJsonObject commandObj;
Render::NodeManagers *nodeManagers = m_renderer->nodeManagers();
- commandObj.insert(QLatin1String("shader"), backendNodeToJSon(c->m_shader, nodeManagers->shaderManager()));
- commandObj.insert(QLatin1String("vao"), double(c->m_vao.handle()));
- commandObj.insert(QLatin1String("instanceCount"), c->m_instanceCount);
- commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c->m_geometry, nodeManagers->geometryManager()));
- commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c->m_geometryRenderer, nodeManagers->geometryRendererManager()));
- commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c->m_parameterPack));
+ commandObj.insert(QLatin1String("shader"), backendNodeToJSon(c.m_shader, nodeManagers->shaderManager()));
+ commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle()));
+ commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount);
+ commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager()));
+ commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager()));
+ commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack));
renderCommandsArray.push_back(commandObj);
}
diff --git a/src/render/backend/computecommand.cpp b/src/render/backend/computecommand.cpp
index df79dcbe8..bc82291f0 100644
--- a/src/render/backend/computecommand.cpp
+++ b/src/render/backend/computecommand.cpp
@@ -53,6 +53,7 @@ ComputeCommand::ComputeCommand()
: BackendNode(ReadWrite)
, m_frameCount(0)
, m_runType(QComputeCommand::Continuous)
+ , m_hasReachedFrameCount(false)
{
m_workGroups[0] = 1;
m_workGroups[1] = 1;
@@ -71,6 +72,7 @@ void ComputeCommand::cleanup()
m_workGroups[2] = 1;
m_frameCount = 0;
m_runType = QComputeCommand::Continuous;
+ m_hasReachedFrameCount = false;
}
void ComputeCommand::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
@@ -98,8 +100,12 @@ void ComputeCommand::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firs
markDirty(AbstractRenderer::ComputeDirty);
}
const QComputeCommandPrivate *d = static_cast<const QComputeCommandPrivate *>(Qt3DCore::QNodePrivate::get(node));
- if (d->m_frameCount != m_frameCount) {
+ // Check frame count only if frontend is enabled
+ // If disabled that means we might have disabled the frontend because
+ // framecount reached 0
+ if (d->m_enabled && d->m_frameCount != m_frameCount) {
m_frameCount = d->m_frameCount;
+ m_hasReachedFrameCount = m_frameCount <= 0;
markDirty(AbstractRenderer::ComputeDirty);
}
@@ -112,14 +118,19 @@ void ComputeCommand::updateFrameCount()
{
// Disable frontend node when reaching 0
--m_frameCount;
- if (m_frameCount <= 0) {
- setEnabled(false);
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("enabled");
- e->setValue(false);
- notifyObservers(e);
- }
+ if (m_frameCount <= 0)
+ m_hasReachedFrameCount = true;
+ // Backend will be disabled on the next sync
+}
+
+void ComputeCommand::resetHasReachedFrameCount()
+{
+ m_hasReachedFrameCount = false;
+}
+
+bool ComputeCommand::hasReachedFrameCount() const
+{
+ return m_hasReachedFrameCount;
}
} // Render
diff --git a/src/render/backend/computecommand_p.h b/src/render/backend/computecommand_p.h
index dc2069928..5012930ae 100644
--- a/src/render/backend/computecommand_p.h
+++ b/src/render/backend/computecommand_p.h
@@ -79,11 +79,14 @@ public:
// Called from a job
void updateFrameCount();
+ bool hasReachedFrameCount() const;
+ void resetHasReachedFrameCount();
private:
int m_workGroups[3];
int m_frameCount;
QComputeCommand::RunType m_runType;
+ bool m_hasReachedFrameCount;
};
} // Render
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index 9510b9530..c910adfe4 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -37,7 +37,8 @@ HEADERS += \
$$PWD/resourceaccessor_p.h \
$$PWD/visitorutils_p.h \
$$PWD/segmentsvisitor_p.h \
- $$PWD/pointsvisitor_p.h
+ $$PWD/pointsvisitor_p.h \
+ $$PWD/commandexecuter_p.h
SOURCES += \
$$PWD/renderthread.cpp \
@@ -67,11 +68,5 @@ SOURCES += \
$$PWD/offscreensurfacehelper.cpp \
$$PWD/resourceaccessor.cpp \
$$PWD/segmentsvisitor.cpp \
- $$PWD/pointsvisitor.cpp
-
-include($$QT3D_BUILD_ROOT/src/core/qt3dcore-config.pri)
-QT_FOR_CONFIG += 3dcore-private
-qtConfig(qt3d-profile-jobs): {
- HEADERS += $$PWD/commandexecuter_p.h
- SOURCES += $$PWD/commandexecuter.cpp
-}
+ $$PWD/pointsvisitor.cpp \
+ $$PWD/commandexecuter.cpp
diff --git a/src/render/backend/rendersettings.cpp b/src/render/backend/rendersettings.cpp
index 487f6e11a..5aeaa2563 100644
--- a/src/render/backend/rendersettings.cpp
+++ b/src/render/backend/rendersettings.cpp
@@ -42,7 +42,6 @@
#include <Qt3DRender/QFrameGraphNode>
#include <Qt3DRender/private/abstractrenderer_p.h>
#include <Qt3DRender/private/qrendersettings_p.h>
-#include <Qt3DCore/qnodecommand.h>
QT_BEGIN_NAMESPACE
@@ -79,20 +78,21 @@ void RenderSettings::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firs
m_renderPolicy = node->renderPolicy();
}
- if (node->pickingSettings()->pickMethod() != m_pickMethod) {
- m_pickMethod = node->pickingSettings()->pickMethod();
+ auto ncnode = const_cast<QRenderSettings *>(node);
+ if (ncnode->pickingSettings()->pickMethod() != m_pickMethod) {
+ m_pickMethod = ncnode->pickingSettings()->pickMethod();
}
- if (node->pickingSettings()->pickResultMode() != m_pickResultMode) {
- m_pickResultMode = node->pickingSettings()->pickResultMode();
+ if (ncnode->pickingSettings()->pickResultMode() != m_pickResultMode) {
+ m_pickResultMode = ncnode->pickingSettings()->pickResultMode();
}
- if (node->pickingSettings()->worldSpaceTolerance() != m_pickWorldSpaceTolerance) {
- m_pickWorldSpaceTolerance = node->pickingSettings()->worldSpaceTolerance();
+ if (ncnode->pickingSettings()->worldSpaceTolerance() != m_pickWorldSpaceTolerance) {
+ m_pickWorldSpaceTolerance = ncnode->pickingSettings()->worldSpaceTolerance();
}
- if (node->pickingSettings()->faceOrientationPickingMode() != m_faceOrientationPickingMode) {
- m_faceOrientationPickingMode = node->pickingSettings()->faceOrientationPickingMode();
+ if (ncnode->pickingSettings()->faceOrientationPickingMode() != m_faceOrientationPickingMode) {
+ m_faceOrientationPickingMode = ncnode->pickingSettings()->faceOrientationPickingMode();
}
// Either because something above as changed or if QRenderSettingsPrivate::invalidFrame()
diff --git a/src/render/backend/segmentsvisitor.cpp b/src/render/backend/segmentsvisitor.cpp
index a3a5d059c..d9f2d79ec 100644
--- a/src/render/backend/segmentsvisitor.cpp
+++ b/src/render/backend/segmentsvisitor.cpp
@@ -135,34 +135,44 @@ void traverseSegmentStripIndexed(Index *indices,
bool loop)
{
uint i = 0;
+ uint stripStartIndex = 0;
+
const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
Vector3D abc[2];
- ndx[0] = indices[0];
- uint idx = ndx[0] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[0][j] = vertices[idx + j];
- while (i < indexInfo.count - 1) {
- ndx[1] = indices[i + 1];
- if (ndx[0] != ndx[1]) {
- idx = ndx[1] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[1][j] = vertices[idx + j];
- visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ while (i < indexInfo.count) {
+ if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i])) {
+ ++i;
+ continue;
}
+ stripStartIndex = i;
+ ndx[0] = indices[stripStartIndex];
+ uint idx = ndx[0] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[0][j] = vertices[idx + j];
++i;
- ndx[0] = ndx[1];
- abc[0] = abc[1];
- }
- if (loop) {
- ndx[1] = indices[0];
- if (ndx[0] != ndx[1]) {
- idx = ndx[1] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[1][j] = vertices[idx + j];
- visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ while (i < indexInfo.count && (!indexInfo.restartEnabled || indexInfo.restartIndexValue != static_cast<int>(indices[i]))) {
+ ndx[1] = indices[i];
+ if (ndx[0] != ndx[1]) {
+ idx = ndx[1] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[1][j] = vertices[idx + j];
+ visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ }
+ ++i;
+ ndx[0] = ndx[1];
+ abc[0] = abc[1];
+ }
+ if (loop) {
+ ndx[1] = indices[stripStartIndex];
+ if (ndx[0] != ndx[1]) {
+ idx = ndx[1] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[1][j] = vertices[idx + j];
+ visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ }
}
}
}
diff --git a/src/render/backend/stringtoint.cpp b/src/render/backend/stringtoint.cpp
index 5659da394..0e0d38c9c 100644
--- a/src/render/backend/stringtoint.cpp
+++ b/src/render/backend/stringtoint.cpp
@@ -50,9 +50,18 @@ namespace Render {
namespace {
-QReadWriteLock lock;
-QHash<QString, int> map = QHash<QString, int>();
-QVector<QString> reverseMap = QVector<QString>();
+struct StringToIntCache
+{
+ QReadWriteLock lock;
+ QHash<QString, int> map = QHash<QString, int>();
+ QVector<QString> reverseMap = QVector<QString>();
+
+ static StringToIntCache& instance()
+ {
+ static StringToIntCache c;
+ return c;
+ }
+};
} // anonymous
@@ -64,20 +73,21 @@ int StringToInt::lookupId(QLatin1String str)
int StringToInt::lookupId(const QString &str)
{
+ auto& cache = StringToIntCache::instance();
int idx;
{
- QReadLocker readLocker(&lock);
- idx = map.value(str, -1);
+ QReadLocker readLocker(&cache.lock);
+ idx = cache.map.value(str, -1);
}
if (Q_UNLIKELY(idx < 0)) {
- QWriteLocker writeLocker(&lock);
- idx = map.value(str, -1);
+ QWriteLocker writeLocker(&cache.lock);
+ idx = cache.map.value(str, -1);
if (idx < 0) {
- idx = reverseMap.size();
- Q_ASSERT(map.size() == reverseMap.size());
- map.insert(str, idx);
- reverseMap.append(str);
+ idx = cache.reverseMap.size();
+ Q_ASSERT(cache.map.size() == cache.reverseMap.size());
+ cache.map.insert(str, idx);
+ cache.reverseMap.append(str);
}
}
return idx;
@@ -85,9 +95,10 @@ int StringToInt::lookupId(const QString &str)
QString StringToInt::lookupString(int idx)
{
- QReadLocker readLocker(&lock);
- if (Q_LIKELY(reverseMap.size() > idx))
- return reverseMap.at(idx);
+ auto& cache = StringToIntCache::instance();
+ QReadLocker readLocker(&cache.lock);
+ if (Q_LIKELY(cache.reverseMap.size() > idx))
+ return cache.reverseMap.at(idx);
return QString();
}
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 8e98801b7..9e78bc96f 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -39,7 +39,6 @@
#include "transform_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/qtransform.h>
#include <Qt3DCore/private/qtransform_p.h>
diff --git a/src/render/backend/trianglesvisitor.cpp b/src/render/backend/trianglesvisitor.cpp
index 87ba7bde9..a58f2d20b 100644
--- a/src/render/backend/trianglesvisitor.cpp
+++ b/src/render/backend/trianglesvisitor.cpp
@@ -153,6 +153,10 @@ void traverseTriangleStripIndexed(index *indices,
uint ndx[3];
Vector3D abc[3];
while (i < indexInfo.count - 2) {
+ if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 2])) {
+ i += 3;
+ continue;
+ }
bool degenerate = false;
for (uint u = 0; u < 3; ++u) {
ndx[u] = indices[i + u];
@@ -216,6 +220,11 @@ void traverseTriangleFanIndexed(index *indices,
ndx[0] = indices[0];
uint i = 1;
while (i < indexInfo.count - 1) {
+ if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 1])) {
+ ndx[0] = indices[i + 2];
+ i += 3;
+ continue;
+ }
for (uint u = 0; u < 2; ++u) {
ndx[u + 1] = indices[i + u];
uint idx = ndx[u + 1] * verticesStride;
@@ -224,7 +233,7 @@ void traverseTriangleFanIndexed(index *indices,
}
}
visitor->visit(ndx[2], abc[2], ndx[1], abc[1], ndx[0], abc[0]);
- i += 1;
+ ++i;
}
}
diff --git a/src/render/backend/uniform_p.h b/src/render/backend/uniform_p.h
index 09575a077..c8731637c 100644
--- a/src/render/backend/uniform_p.h
+++ b/src/render/backend/uniform_p.h
@@ -227,9 +227,9 @@ public:
return !(*this == other);
}
private:
- // Allocate 4 floats on stack
+ // Allocate 16 floats on stack
// For larger elements, heap allocation will be used
- QVarLengthArray<float, 4> m_data;
+ QVarLengthArray<float, 16> m_data;
ValueType m_valueType = ScalarValue;
diff --git a/src/render/backend/visitorutils_p.h b/src/render/backend/visitorutils_p.h
index 6a5c7b4ff..14183e11b 100644
--- a/src/render/backend/visitorutils_p.h
+++ b/src/render/backend/visitorutils_p.h
@@ -149,6 +149,8 @@ void visitPrimitives(NodeManagers *manager, const GeometryRenderer *renderer, Vi
indexBufferInfo.byteOffset = indexAttribute->byteOffset();
indexBufferInfo.byteStride = indexAttribute->byteStride();
indexBufferInfo.count = indexAttribute->count();
+ indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled();
+ indexBufferInfo.restartIndexValue = renderer->restartIndexValue();
IndexExecutor executor;
executor.m_vertexBufferInfo = vertexBufferInfo;
diff --git a/src/render/framegraph/qblitframebuffer.cpp b/src/render/framegraph/qblitframebuffer.cpp
index 3a26e3d56..252758af4 100644
--- a/src/render/framegraph/qblitframebuffer.cpp
+++ b/src/render/framegraph/qblitframebuffer.cpp
@@ -70,6 +70,10 @@ namespace Qt3DRender {
Specifies the interpolation applied if the image is stretched.
+ \value Nearest
+ Nearest-neighbor interpolation.
+ \value Linear
+ Linear interpolation.
*/
/*!
\property Qt3DRender::QBlitFramebuffer::destination
diff --git a/src/render/framegraph/qbuffercapture.cpp b/src/render/framegraph/qbuffercapture.cpp
index 0c12a3aff..3eaa5dfd2 100644
--- a/src/render/framegraph/qbuffercapture.cpp
+++ b/src/render/framegraph/qbuffercapture.cpp
@@ -39,8 +39,8 @@
#include <Qt3DRender/qbuffercapture.h>
#include <Qt3DRender/private/qbuffercapture_p.h>
-#include <Qt3DCore/QSceneChange>
-#include <Qt3DRender/QFrameGraphNodeCreatedChange>
+#include <Qt3DCore/qscenechange.h>
+#include <Qt3DRender/qframegraphnodecreatedchange.h>
QT_BEGIN_NAMESPACE
@@ -62,6 +62,14 @@ QBufferCapturePrivate::QBufferCapturePrivate()
\inmodule Qt3DRender
\brief Exchanges buffer data between GPU and CPU.
*/
+
+/*!
+ \qmltype BufferCapture
+ \inqmlmodule Qt3D.Render
+ \instantiates Qt3DRender::QBufferCapture
+ \brief Exchanges buffer data between GPU and CPU.
+*/
+
QBufferCapture::QBufferCapture(Qt3DCore::QNode *parent)
: QFrameGraphNode(*new QBufferCapturePrivate, parent)
{
diff --git a/src/render/framegraph/qrendercapture.cpp b/src/render/framegraph/qrendercapture.cpp
index cc74553b2..a10083374 100644
--- a/src/render/framegraph/qrendercapture.cpp
+++ b/src/render/framegraph/qrendercapture.cpp
@@ -36,8 +36,8 @@
#include <Qt3DRender/qrendercapture.h>
#include <Qt3DRender/private/qrendercapture_p.h>
-#include <Qt3DCore/QSceneChange>
-#include <Qt3DCore/QPropertyUpdatedChange>
+#include <Qt3DCore/qscenechange.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DRender/qframegraphnodecreatedchange.h>
#include <QPointer>
diff --git a/src/render/framegraph/qsetfence.cpp b/src/render/framegraph/qsetfence.cpp
index 5cb82f3db..262dbd4ad 100644
--- a/src/render/framegraph/qsetfence.cpp
+++ b/src/render/framegraph/qsetfence.cpp
@@ -54,7 +54,8 @@ QSetFencePrivate::QSetFencePrivate()
}
/*!
- \class QSetFence
+ \class Qt3DRender::QSetFence
+ \inmodule Qt3DRender
\brief FrameGraphNode used to insert a fence in the graphics command stream.
Fence allow to synchronosize GPU and CPU workloads. GPU commands usually
@@ -100,7 +101,7 @@ QSetFence::QSetFence(QSetFencePrivate &dd, Qt3DCore::QNode *parent)
are supported.
*/
/*!
- \property QSetFence::handleType
+ \property Qt3DRender::QSetFence::handleType
Specifies the type of handle being used. Currently only OpenGL Fence ids
are supported.
@@ -123,12 +124,12 @@ void QSetFencePrivate::setHandleType(QSetFence::HandleType type)
}
/*!
- \qmlproperty variant AbstractFence::handle
+ \qmlproperty variant SetFence::handle
Holds the underlying fence handle wrapped in a variant.
*/
/*!
- \property QAbstractFence::handle
+ \property Qt3DRender::QSetFence::handle
Holds the underlying fence handle wrapped in a QVariant.
*/
diff --git a/src/render/framegraph/qwaitfence.cpp b/src/render/framegraph/qwaitfence.cpp
index 5195653ce..737f4e54d 100644
--- a/src/render/framegraph/qwaitfence.cpp
+++ b/src/render/framegraph/qwaitfence.cpp
@@ -56,8 +56,8 @@ QWaitFencePrivate::QWaitFencePrivate()
}
/*!
- \class QWaitFence
-
+ \class Qt3DRender::QWaitFence
+ \inmodule Qt3DRender
\brief FrameGraphNode used to wait for a fence in the graphics command
stream to become signaled.
@@ -98,7 +98,7 @@ QWaitFence::~QWaitFence()
become signaled. This is false by default.
*/
/*!
- \property QWaitFence::waitOnCPU
+ \property Qt3DRender::QWaitFence::waitOnCPU
Specifies whether the CPU should be block while waiting for the fence to
become signaled. This is false by default.
@@ -125,7 +125,7 @@ void QWaitFence::setWaitOnCPU(bool waitOnCPU)
to become signaled.
*/
/*!
- \property QWaitFence::timeout
+ \property Qt3DRender::QWaitFence::timeout
Specifies the maximum amount of time in nanoseconds to wait for the fence
to become signaled.
@@ -157,7 +157,7 @@ QWaitFence::QWaitFence(QWaitFencePrivate &dd, Qt3DCore::QNode *parent)
are supported.
*/
/*!
- \property QWaitFence::handleType
+ \property Qt3DRender::QWaitFence::handleType
Specifies the type of handle being used. Currently only OpenGL Fence ids
are supported.
@@ -183,7 +183,7 @@ void QWaitFence::setHandleType(QWaitFence::HandleType type)
Holds the underlying fence handle wrapped in a variant.
*/
/*!
- \property QWaitFence::handle
+ \property Qt3DRender::QWaitFence::handle
Holds the underlying fence handle wrapped in a QVariant.
*/
diff --git a/src/render/framegraph/rendercapture.cpp b/src/render/framegraph/rendercapture.cpp
index 68d62b6a5..73d8770a7 100644
--- a/src/render/framegraph/rendercapture.cpp
+++ b/src/render/framegraph/rendercapture.cpp
@@ -37,6 +37,8 @@
#include <Qt3DRender/private/qrendercapture_p.h>
#include <Qt3DRender/private/rendercapture_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DCore/private/qaspectjobmanager_p.h>
QT_BEGIN_NAMESPACE
@@ -99,17 +101,25 @@ void RenderCapture::addRenderCapture(int captureId, const QImage &image)
m_renderCaptureData.push_back(data);
}
-// called by send render capture job thread
-void RenderCapture::sendRenderCaptures()
+// called to send render capture in main thread
+void RenderCapture::syncRenderCapturesToFrontend(Qt3DCore::QAspectManager *manager)
{
- QMutexLocker lock(&m_mutex);
+ auto *frontend = manager->lookupNode(peerId());
+ if (!frontend)
+ return;
+ QRenderCapturePrivate *dfrontend = static_cast<QRenderCapturePrivate *>(Qt3DCore::QNodePrivate::get(frontend));
+ QMutexLocker lock(&m_mutex);
for (const RenderCaptureDataPtr &data : qAsConst(m_renderCaptureData)) {
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("renderCaptureData");
- e->setValue(QVariant::fromValue(data));
- notifyObservers(e);
+ QPointer<QRenderCaptureReply> reply = dfrontend->takeReply(data.data()->captureId);
+ if (reply) {
+ dfrontend->setImage(reply, data.data()->image);
+ emit reply->completed();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ emit reply->completeChanged(true);
+QT_WARNING_POP
+ }
}
m_renderCaptureData.clear();
}
diff --git a/src/render/framegraph/rendercapture_p.h b/src/render/framegraph/rendercapture_p.h
index 4560c525d..5714fb44d 100644
--- a/src/render/framegraph/rendercapture_p.h
+++ b/src/render/framegraph/rendercapture_p.h
@@ -66,9 +66,9 @@ public:
bool wasCaptureRequested() const;
QRenderCaptureRequest takeCaptureRequest();
void addRenderCapture(int captureId, const QImage &image);
- void sendRenderCaptures();
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+ void syncRenderCapturesToFrontend(Qt3DCore::QAspectManager *manager);
private:
diff --git a/src/render/framegraph/subtreeenabler.cpp b/src/render/framegraph/subtreeenabler.cpp
index 160e1a5b5..4d912dc1d 100644
--- a/src/render/framegraph/subtreeenabler.cpp
+++ b/src/render/framegraph/subtreeenabler.cpp
@@ -52,30 +52,12 @@ SubtreeEnabler::SubtreeEnabler()
{
}
-void SubtreeEnabler::sendDisableToFrontend()
-{
- if (m_enablement != QSubtreeEnabler::SingleShot)
- return;
-
- if (isEnabled())
- return;
-
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("enabled");
- e->setValue(false);
- notifyObservers(e);
-}
-
void SubtreeEnabler::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
const QSubtreeEnabler *node = qobject_cast<const QSubtreeEnabler *>(frontEnd);
if (!node)
return;
- if (node->isEnabled() != isEnabled())
- markDirty(AbstractRenderer::AllDirty);
-
FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
const auto enablement = node->enablement();
diff --git a/src/render/frontend/qcamera.cpp b/src/render/frontend/qcamera.cpp
index 2dcec7ed6..b0fd16182 100644
--- a/src/render/frontend/qcamera.cpp
+++ b/src/render/frontend/qcamera.cpp
@@ -235,7 +235,7 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
* \qmlmethod void Qt3D.Render::Camera::viewEntity(Entity entity)
*
* Rotates and moves the camera so that it's viewCenter is the center of the entity's bounding volume
- * and the entire entity fits in the view port.
+ * and the entire \a entity fits in the view port.
*
* \note Only works if the lens is in perspective projection mode.
* \sa Qt3D.Render::Camera::projectionType
diff --git a/src/render/frontend/qcameralens.cpp b/src/render/frontend/qcameralens.cpp
index cf30b714a..1d8059f45 100644
--- a/src/render/frontend/qcameralens.cpp
+++ b/src/render/frontend/qcameralens.cpp
@@ -233,11 +233,7 @@ void QCameraLens::viewAll(Qt3DCore::QNodeId cameraId)
{
Q_D(QCameraLens);
if (d->m_projectionType == PerspectiveProjection) {
- QVariant v;
- v.setValue(cameraId);
- d->m_pendingViewAllCommand = {QLatin1String("QueryRootBoundingVolume"),
- v,
- id()};
+ d->m_pendingViewAllRequest = {Qt3DCore::QNodeId::createId(), cameraId, {}};
d->update();
}
}
@@ -246,30 +242,19 @@ void QCameraLens::viewEntity(Qt3DCore::QNodeId entityId, Qt3DCore::QNodeId camer
{
Q_D(QCameraLens);
if (d->m_projectionType == PerspectiveProjection) {
- QVector<Qt3DCore::QNodeId> ids = {entityId, cameraId};
- QVariant v;
- v.setValue(ids);
- d->m_pendingViewAllCommand = {QLatin1String("QueryEntityBoundingVolume"),
- v,
- id()};
+ d->m_pendingViewAllRequest = {Qt3DCore::QNodeId::createId(), cameraId, entityId};
d->update();
}
}
-void QCameraLensPrivate::processViewAllCommand(Qt3DCore::QNodeCommand::CommandId commandId,
- const QVariant &data)
+void QCameraLensPrivate::processViewAllResult(Qt3DCore::QNodeId requestId, const QVector3D &center, float radius)
{
Q_Q(QCameraLens);
- if (!m_pendingViewAllCommand || m_pendingViewAllCommand.commandId != commandId)
+ if (!m_pendingViewAllRequest || m_pendingViewAllRequest.requestId != requestId)
return;
- QVector<float> boundingVolumeData = data.value< QVector<float> >();
- if (boundingVolumeData.size() != 4)
- return;
- QVector3D center(boundingVolumeData[0], boundingVolumeData[1], boundingVolumeData[2]);
- float radius = boundingVolumeData[3];
Q_EMIT q->viewSphere(center, radius);
- m_pendingViewAllCommand = {};
+ m_pendingViewAllRequest = {};
}
/*!
@@ -643,18 +628,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QCameraLens::createNodeCreationChange() cons
void QCameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
{
- Q_D(QCameraLens);
- switch (change->type()) {
- case Qt3DCore::CommandRequested: {
- Qt3DCore::QNodeCommandPtr command = qSharedPointerCast<Qt3DCore::QNodeCommand>(change);
-
- if (command->name() == QLatin1String("ViewAll"))
- d->processViewAllCommand(command->inReplyTo(), command->data());
- }
- break;
- default:
- break;
- }
+ Q_UNUSED(change)
}
} // Qt3DRender
diff --git a/src/render/frontend/qcameralens_p.h b/src/render/frontend/qcameralens_p.h
index 5c5a6a42a..eca01b890 100644
--- a/src/render/frontend/qcameralens_p.h
+++ b/src/render/frontend/qcameralens_p.h
@@ -53,7 +53,6 @@
#include <Qt3DRender/private/qt3drender_global_p.h>
#include <Qt3DCore/private/qcomponent_p.h>
-#include <Qt3DCore/private/qnodecommand_p.h>
#include "qcameralens.h"
@@ -63,21 +62,21 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
-struct CameraLensCommand
+struct CameraLensRequest
{
- QString name;
- QVariant data;
- Qt3DCore::QNodeCommand::CommandId commandId;
+ Qt3DCore::QNodeId requestId;
+ Qt3DCore::QNodeId cameraId;
+ Qt3DCore::QNodeId entityId;
- inline operator bool() const { return !name.isEmpty(); }
+ inline operator bool() const { return !requestId.isNull(); }
};
-inline bool operator ==(const CameraLensCommand &a, const CameraLensCommand &b) noexcept
+inline bool operator ==(const CameraLensRequest &a, const CameraLensRequest &b) noexcept
{
- return a.name == b.name && a.data == b.data && a.commandId == b.commandId;
+ return a.cameraId == b.cameraId && a.entityId == b.entityId && a.requestId == b.requestId;
}
-inline bool operator !=(const CameraLensCommand &a, const CameraLensCommand &b) noexcept
+inline bool operator !=(const CameraLensRequest &a, const CameraLensRequest &b) noexcept
{
return !(a == b);
}
@@ -123,8 +122,8 @@ public:
float m_exposure;
- CameraLensCommand m_pendingViewAllCommand;
- void processViewAllCommand(Qt3DCore::QNodeCommand::CommandId commandId, const QVariant &data);
+ CameraLensRequest m_pendingViewAllRequest;
+ void processViewAllResult(Qt3DCore::QNodeId requestId, const QVector3D &center, float radius);
private:
inline void updatePerpectiveProjection()
diff --git a/src/render/frontend/qcomputecommand.cpp b/src/render/frontend/qcomputecommand.cpp
index d0c9f5805..dfd9c2033 100644
--- a/src/render/frontend/qcomputecommand.cpp
+++ b/src/render/frontend/qcomputecommand.cpp
@@ -92,15 +92,15 @@ namespace Qt3DRender {
*/
/*!
- \qmlproperty QComputeCommand::runType
+ \qmlproperty enumeration ComputeCommand::runType
Specifies whether the compute command should be performed every frame or
manually triggered.
- \value Continuous Compute command is executed everyframe. This is the
+ \value ComputeCommand.Continuous Compute command is executed everyframe. This is the
default.
- \value Manual CompouteCommand is executed for a given number of frames and
+ \value ComputeCommand.Manual CompouteCommand is executed for a given number of frames and
then the component disables itself.
*/
diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp
index 3d0cb9553..ced0604c7 100644
--- a/src/render/frontend/qlevelofdetail.cpp
+++ b/src/render/frontend/qlevelofdetail.cpp
@@ -325,6 +325,11 @@ Qt3DCore::QNodeCreatedChangeBasePtr QLevelOfDetail::createNodeCreationChange() c
return creationChange;
}
+// TODO Unused remove in Qt6
+void QLevelOfDetail::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
QCamera *QLevelOfDetail::camera() const
{
Q_D(const QLevelOfDetail);
diff --git a/src/render/frontend/qlevelofdetail.h b/src/render/frontend/qlevelofdetail.h
index f6c09a287..81fcf3235 100644
--- a/src/render/frontend/qlevelofdetail.h
+++ b/src/render/frontend/qlevelofdetail.h
@@ -97,6 +97,8 @@ Q_SIGNALS:
protected:
explicit QLevelOfDetail(QLevelOfDetailPrivate &dd, Qt3DCore::QNode *parent = nullptr);
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QLevelOfDetail)
diff --git a/src/render/frontend/qlevelofdetailswitch.cpp b/src/render/frontend/qlevelofdetailswitch.cpp
index 7b888fe98..c07d4c4b1 100644
--- a/src/render/frontend/qlevelofdetailswitch.cpp
+++ b/src/render/frontend/qlevelofdetailswitch.cpp
@@ -42,7 +42,6 @@
#include "qlevelofdetail_p.h"
#include "qglobal.h"
#include <Qt3DCore/QEntity>
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -134,6 +133,11 @@ QLevelOfDetailSwitch::QLevelOfDetailSwitch(QLevelOfDetailPrivate &dd, QNode *par
{
}
+// TODO Unused remove in Qt6
+void QLevelOfDetailSwitch::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/frontend/qlevelofdetailswitch.h b/src/render/frontend/qlevelofdetailswitch.h
index 90f4ee3e2..325b885ed 100644
--- a/src/render/frontend/qlevelofdetailswitch.h
+++ b/src/render/frontend/qlevelofdetailswitch.h
@@ -57,6 +57,8 @@ public:
protected:
explicit QLevelOfDetailSwitch(QLevelOfDetailPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QLevelOfDetailSwitch)
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 271eb9c11..7a51fa0e7 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -170,10 +170,8 @@
#include <Qt3DCore/QAspectEngine>
#include <Qt3DCore/private/qservicelocator_p.h>
-#include <QDebug>
-#include <QOffscreenSurface>
#include <QThread>
-#include <QWindow>
+#include <QOpenGLContext>
QT_BEGIN_NAMESPACE
@@ -202,11 +200,16 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
, m_nodeManagers(nullptr)
, m_renderer(nullptr)
, m_initialized(false)
+ , m_renderAfterJobs(false)
, m_renderType(type)
, m_offscreenHelper(nullptr)
{
m_instances.append(this);
loadSceneParsers();
+ if (m_renderType == QRenderAspect::Threaded && !QOpenGLContext::supportsThreadedOpenGL()) {
+ m_renderType = QRenderAspect::Synchronous;
+ m_renderAfterJobs = true;
+ }
}
/*! \internal */
@@ -239,6 +242,13 @@ void QRenderAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *back
renderBackend->syncFromFrontEnd(node, firstTime);
}
+void QRenderAspectPrivate::jobsDone(QAspectManager *manager)
+{
+ m_renderer->jobsDone(manager);
+ if (m_renderAfterJobs)
+ m_renderer->doRender(true);
+}
+
/*! \internal */
void QRenderAspectPrivate::registerBackendTypes()
{
@@ -546,6 +556,8 @@ QVariant QRenderAspect::executeCommand(const QStringList &args)
void QRenderAspect::onEngineStartup()
{
Q_D(QRenderAspect);
+ if (d->m_renderAfterJobs) // synchronous rendering but using QWindow
+ d->m_renderer->initialize();
Render::NodeManagers *managers = d->m_renderer->nodeManagers();
Render::Entity *rootEntity = managers->lookupResource<Render::Entity, Render::EntityManager>(rootEntityId());
Q_ASSERT(rootEntity);
diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h
index 62e373b11..8723180ab 100644
--- a/src/render/frontend/qrenderaspect_p.h
+++ b/src/render/frontend/qrenderaspect_p.h
@@ -87,6 +87,7 @@ public:
static QRenderAspectPrivate* findPrivate(Qt3DCore::QAspectEngine *engine);
void syncDirtyFrontEndNode(Qt3DCore::QNode *node, Qt3DCore::QBackendNode *backend, bool firstTime) const override;
+ void jobsDone(Qt3DCore::QAspectManager *manager) override;
void registerBackendTypes();
void unregisterBackendTypes();
@@ -102,6 +103,7 @@ public:
Render::AbstractRenderer *m_renderer;
bool m_initialized;
+ bool m_renderAfterJobs;
QList<QSceneImporter *> m_sceneImporter;
QVector<QString> m_loadedPlugins;
QVector<Render::QRenderPlugin *> m_renderPlugins;
diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp
index d106e4205..491d3e442 100644
--- a/src/render/frontend/qrendersettings.cpp
+++ b/src/render/frontend/qrendersettings.cpp
@@ -104,25 +104,25 @@ void QRenderSettingsPrivate::invalidateFrame()
/*! \internal */
void QRenderSettingsPrivate::_q_onPickingMethodChanged(QPickingSettings::PickMethod pickMethod)
{
- notifyPropertyChange("pickMethod", pickMethod);// TODOSYNC
+ notifyPropertyChange("pickMethod", pickMethod);
}
/*! \internal */
void QRenderSettingsPrivate::_q_onPickResultModeChanged(QPickingSettings::PickResultMode pickResultMode)
{
- notifyPropertyChange("pickResultMode", pickResultMode);// TODOSYNC
+ notifyPropertyChange("pickResultMode", pickResultMode);
}
/*! \internal */
void QRenderSettingsPrivate::_q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode)
{
- notifyPropertyChange("faceOrientationPickingMode", faceOrientationPickingMode);// TODOSYNC
+ notifyPropertyChange("faceOrientationPickingMode", faceOrientationPickingMode);
}
/*! \internal */
void QRenderSettingsPrivate::_q_onWorldSpaceToleranceChanged(float worldSpaceTolerance)
{
- notifyPropertyChange("pickWorldSpaceTolerance", worldSpaceTolerance);// TODOSYNC
+ notifyPropertyChange("pickWorldSpaceTolerance", worldSpaceTolerance);
}
QRenderSettings::QRenderSettings(Qt3DCore::QNode *parent)
@@ -161,12 +161,6 @@ QPickingSettings *QRenderSettings::pickingSettings()
return &(d->m_pickingSettings);
}
-const QPickingSettings *QRenderSettings::pickingSettings() const
-{
- Q_D(const QRenderSettings);
- return &(d->m_pickingSettings);
-}
-
/*!
\qmlproperty FrameGraphNode RenderSettings::activeFrameGraph
diff --git a/src/render/frontend/qrendersettings.h b/src/render/frontend/qrendersettings.h
index c8771a8fa..9d2baa58b 100644
--- a/src/render/frontend/qrendersettings.h
+++ b/src/render/frontend/qrendersettings.h
@@ -71,7 +71,6 @@ public:
Q_ENUM(RenderPolicy) // LCOV_EXCL_LINE
QPickingSettings* pickingSettings();
- const QPickingSettings* pickingSettings() const;
QFrameGraphNode *activeFrameGraph() const;
RenderPolicy renderPolicy() const;
diff --git a/src/render/frontend/sphere.cpp b/src/render/frontend/sphere.cpp
index 470dbfe59..0caeed9f1 100644
--- a/src/render/frontend/sphere.cpp
+++ b/src/render/frontend/sphere.cpp
@@ -93,54 +93,6 @@ bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRen
return true;
}
-inline QPair<int, int> findExtremePoints(const QVector<Vector3D> &points)
-{
- // Find indices of extreme points along x, y, and z axes
- int xMin = 0, xMax = 0, yMin = 0, yMax = 0, zMin = 0, zMax = 0;
- for (int i = 1; i < points.size(); ++i) {
- const Vector3D &p = points.at(i);
- if (p.x() < points[xMin].x())
- xMin = i;
- if (p.x() > points[xMax].x())
- xMax = i;
- if (p.y() < points[yMin].y())
- yMin = i;
- if (p.y() > points[yMax].y())
- yMax = i;
- if (p.z() < points[zMin].z())
- zMin = i;
- if (p.z() > points[zMax].z())
- zMax = i;
- }
-
- // Calculate squared distance for the pairs of points
- const float xDist2 = (points.at(xMax) - points.at(xMin)).lengthSquared();
- const float yDist2 = (points.at(yMax) - points.at(yMin)).lengthSquared();
- const float zDist2 = (points.at(zMax) - points.at(zMin)).lengthSquared();
-
- // Select most distant pair
- QPair<int, int> extremeIndices(xMin, xMax);
- if (yDist2 > xDist2 && yDist2 > zDist2)
- extremeIndices = qMakePair(yMin, yMax);
- if (zDist2 > xDist2 && zDist2 > yDist2)
- extremeIndices = qMakePair(zMin, zMax);
-
- return extremeIndices;
-}
-
-inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
-{
- // Find two most separated points on any of the basis vectors
- QPair<int, int> extremeIndices = findExtremePoints(points);
-
- // Construct sphere to contain these two points
- const Vector3D &p = points.at(extremeIndices.first);
- const Vector3D &q = points.at(extremeIndices.second);
- const Vector3D c = 0.5f * (p + q);
- s.setCenter(c);
- s.setRadius((q - c).length());
-}
-
inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
{
//def bounding_sphere(points):
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index 0ce81efc1..6db3bab44 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -88,15 +88,6 @@ void Buffer::executeFunctor()
m_data = (*m_functor)();
// Request data to be loaded
forceDataUpload();
-
- if (m_syncData) {
- // Send data back to the frontend
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("data");
- e->setValue(QVariant::fromValue(m_data));
- notifyObservers(e);
- }
}
//Called from th sendBufferJob
@@ -105,12 +96,6 @@ void Buffer::updateDataFromGPUToCPU(QByteArray data)
// Note: when this is called, data is what's currently in GPU memory
// so m_data shouldn't be reuploaded
m_data = data;
- // Send data back to the frontend
- auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
- e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
- e->setPropertyName("downloadedData");
- e->setValue(QVariant::fromValue(m_data));
- notifyObservers(e);
}
void Buffer::forceDataUpload()
@@ -152,20 +137,31 @@ void Buffer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
m_manager->addDirtyBuffer(peerId());
}
{
- QVariant v = node->property("QT3D_updateData");
- if (v.isValid()) {
+ const QVariant v = node->property("QT3D_updateData");
+
+ // Make sure we record data if it's the first time we are called
+ // or if we have no partial updates
+ if (firstTime || !v.isValid()){
+ const QByteArray newData = node->data();
+ const bool dirty = m_data != newData;
+ m_bufferDirty |= dirty;
+ m_data = newData;
+
+ // Since frontend applies partial updates to its m_data
+ // if we enter this code block, there's no problem in actually
+ // ignoring the partial updates
+ if (v.isValid())
+ const_cast<QBuffer *>(node)->setProperty("QT3D_updateData", {});
+
+ if (dirty && !m_data.isEmpty())
+ forceDataUpload();
+ } else if (v.isValid()) {
+ // Apply partial updates and record them to allow partial upload to the GPU
Qt3DRender::QBufferUpdate updateData = v.value<Qt3DRender::QBufferUpdate>();
m_data.replace(updateData.offset, updateData.data.size(), updateData.data);
m_bufferUpdates.push_back(updateData);
m_bufferDirty = true;
const_cast<QBuffer *>(node)->setProperty("QT3D_updateData", {});
- } else {
- QByteArray newData = node->data();
- bool dirty = m_data != newData;
- m_bufferDirty |= dirty;
- m_data = newData;
- if (dirty && !m_data.isEmpty())
- forceDataUpload();
}
}
markDirty(AbstractRenderer::BuffersDirty);
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index 3b460f48c..881c0f66b 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -139,8 +139,16 @@ void GeometryRenderer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
if (functorDirty) {
m_dirty = true;
m_geometryFactory = newFunctor;
- if (m_geometryFactory && m_manager != nullptr)
+ if (m_geometryFactory && m_manager != nullptr) {
m_manager->addDirtyGeometryRenderer(peerId());
+
+ const bool isQMeshFunctor = m_geometryFactory->id() == Qt3DRender::functorTypeId<MeshLoaderFunctor>();
+ if (isQMeshFunctor) {
+ const QMesh *meshNode = static_cast<const QMesh *>(node);
+ QMeshPrivate *dmeshNode = QMeshPrivate::get(const_cast<QMesh *>(meshNode));
+ dmeshNode->setStatus(QMesh::Loading);
+ }
+ }
}
markDirty(AbstractRenderer::GeometryDirty);
diff --git a/src/render/geometry/gltfskeletonloader.cpp b/src/render/geometry/gltfskeletonloader.cpp
index 56144747c..07789cd84 100644
--- a/src/render/geometry/gltfskeletonloader.cpp
+++ b/src/render/geometry/gltfskeletonloader.cpp
@@ -48,6 +48,7 @@
#include <Qt3DRender/private/renderlogging_p.h>
#include <Qt3DCore/private/qmath3d_p.h>
+#include <Qt3DCore/private/qloadgltf_p.h>
QT_BEGIN_NAMESPACE
@@ -316,12 +317,7 @@ GLTFSkeletonLoader::GLTFSkeletonLoader()
bool GLTFSkeletonLoader::load(QIODevice *ioDev)
{
- QByteArray jsonData = ioDev->readAll();
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(jsonData);
-
- if (Q_UNLIKELY(!setJSON(sceneDocument))) {
+ if (Q_UNLIKELY(!setJSON(qLoadGLTF(ioDev->readAll())))) {
qCWarning(Jobs, "not a JSON document");
return false;
}
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index d27da25c7..8399bdd7c 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -58,6 +58,15 @@ QBufferPrivate::QBufferPrivate()
{
}
+void QBufferPrivate::setData(const QByteArray &data)
+{
+ Q_Q(QBuffer);
+ const bool blocked = q->blockNotifications(true);
+ m_data = data;
+ emit q->dataChanged(data);
+ q->blockNotifications(blocked);
+}
+
/*!
* \qmltype Buffer
* \instantiates Qt3DRender::QBuffer
@@ -301,36 +310,14 @@ QBuffer::~QBuffer()
}
/*!
- * \internal
- */
-void QBuffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
-{
- if (change->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr e = qSharedPointerCast<QPropertyUpdatedChange>(change);
- const QByteArray propertyName = e->propertyName();
- if (propertyName == QByteArrayLiteral("data")) {
- const bool blocked = blockNotifications(true);
- setData(e->value().toByteArray());
- blockNotifications(blocked);
- } else if (propertyName == QByteArrayLiteral("downloadedData")) {
- const bool blocked = blockNotifications(true);
- setData(e->value().toByteArray());
- blockNotifications(blocked);
- Q_EMIT dataAvailable();
- }
- }
-}
-
-/*!
* Sets \a bytes as data.
*/
void QBuffer::setData(const QByteArray &bytes)
{
Q_D(QBuffer);
if (bytes != d->m_data) {
- d->m_data = bytes;
+ d->setData(bytes);
d->update();
- emit dataChanged(bytes);
}
}
@@ -446,6 +433,13 @@ void QBuffer::setAccessType(QBuffer::AccessType access)
}
}
+/*! \internal */
+void QBuffer::sceneChangeEvent(const QSceneChangePtr &change)
+{
+ // TODO Unused remove in Qt6
+ Q_UNUSED(change)
+}
+
bool QBuffer::isSyncData() const
{
Q_D(const QBuffer);
diff --git a/src/render/geometry/qbuffer.h b/src/render/geometry/qbuffer.h
index 1bd1aa8fd..aa6ebca66 100644
--- a/src/render/geometry/qbuffer.h
+++ b/src/render/geometry/qbuffer.h
@@ -118,9 +118,6 @@ public Q_SLOTS:
void setSyncData(bool syncData);
void setAccessType(AccessType access);
-protected:
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
-
Q_SIGNALS:
void dataChanged(const QByteArray &bytes);
void typeChanged(BufferType type);
@@ -129,6 +126,10 @@ Q_SIGNALS:
void accessTypeChanged(AccessType access);
void dataAvailable();
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
private:
Q_DECLARE_PRIVATE(QBuffer)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override;
diff --git a/src/render/geometry/qbuffer_p.h b/src/render/geometry/qbuffer_p.h
index 7a0ffdfb9..6da28e88b 100644
--- a/src/render/geometry/qbuffer_p.h
+++ b/src/render/geometry/qbuffer_p.h
@@ -75,6 +75,8 @@ public:
QBufferDataGeneratorPtr m_functor;
bool m_syncData;
QBuffer::AccessType m_access;
+
+ void setData(const QByteArray &data);
};
struct QBufferData
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index 6e0a24f61..64f3e058e 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -218,6 +218,11 @@ QGeometryRenderer::QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent
{
}
+// TODO Unused remove in Qt6
+void QGeometryRenderer::sceneChangeEvent(const QSceneChangePtr &)
+{
+}
+
/*!
\property QGeometryRenderer::instanceCount
diff --git a/src/render/geometry/qgeometryrenderer.h b/src/render/geometry/qgeometryrenderer.h
index eceeb9173..14de40d0b 100644
--- a/src/render/geometry/qgeometryrenderer.h
+++ b/src/render/geometry/qgeometryrenderer.h
@@ -134,6 +134,8 @@ Q_SIGNALS:
protected:
explicit QGeometryRenderer(QGeometryRendererPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QGeometryRenderer)
diff --git a/src/render/geometry/qmesh.cpp b/src/render/geometry/qmesh.cpp
index 1d7d33f9a..1f05a71f6 100644
--- a/src/render/geometry/qmesh.cpp
+++ b/src/render/geometry/qmesh.cpp
@@ -148,17 +148,6 @@ void QMeshPrivate::setStatus(QMesh::Status status)
*/
/*!
- \enum QMesh::Status
-
- This enum identifies the status of shader used.
-
- \value None A source mesh hasn't been assigned a source yet
- \value Loading The mesh geometry is loading
- \value Ready The mesh geometry was successfully loaded
- \value Error An error occurred while loading the mesh
-*/
-
-/*!
\qmlproperty enumeration Mesh::status
Holds the status of the mesh loading.
@@ -197,6 +186,17 @@ void QMeshPrivate::setStatus(QMesh::Status status)
*/
/*!
+ \enum Qt3DRender::QMesh::Status
+
+ This enum identifies the status of shader used.
+
+ \value None A source mesh hasn't been assigned a source yet
+ \value Loading The mesh geometry is loading
+ \value Ready The mesh geometry was successfully loaded
+ \value Error An error occurred while loading the mesh
+*/
+
+/*!
* Constructs a new QMesh with \a parent.
*/
QMesh::QMesh(QNode *parent)
@@ -215,6 +215,11 @@ QMesh::QMesh(QMeshPrivate &dd, QNode *parent)
{
}
+// TODO Unused remove in Qt6
+void QMesh::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
void QMesh::setSource(const QUrl& source)
{
Q_D(QMesh);
diff --git a/src/render/geometry/qmesh.h b/src/render/geometry/qmesh.h
index 04fdedc20..e8ff52b35 100644
--- a/src/render/geometry/qmesh.h
+++ b/src/render/geometry/qmesh.h
@@ -88,6 +88,8 @@ Q_SIGNALS:
protected:
explicit QMesh(QMeshPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QMesh)
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index 839a1a056..0452c020b 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -60,6 +60,8 @@ namespace Render {
Skeleton::Skeleton()
: BackendNode(Qt3DCore::QBackendNode::ReadWrite)
, m_status(Qt3DCore::QSkeletonLoader::NotReady)
+ , m_createJoints(false)
+ , m_dataType(Unknown)
, m_skeletonManager(nullptr)
, m_jointManager(nullptr)
{
diff --git a/src/render/io/qsceneloader.cpp b/src/render/io/qsceneloader.cpp
index cf1e45355..2d53702f6 100644
--- a/src/render/io/qsceneloader.cpp
+++ b/src/render/io/qsceneloader.cpp
@@ -41,7 +41,6 @@
#include "qsceneloader_p.h"
#include <Qt3DCore/private/qscene_p.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
#include <Qt3DRender/qgeometryrenderer.h>
@@ -253,6 +252,11 @@ QSceneLoader::~QSceneLoader()
{
}
+// TODO Unused remove in Qt6
+void QSceneLoader::sceneChangeEvent(const QSceneChangePtr &)
+{
+}
+
/*! \internal */
QSceneLoader::QSceneLoader(QSceneLoaderPrivate &dd, QNode *parent)
: Qt3DCore::QComponent(dd, parent)
@@ -313,7 +317,7 @@ QStringList QSceneLoader::entityNames() const
/*!
\qmlmethod Entity SceneLoader::component(string entityName, enumeration componentType)
- Returns a component matching \a componentType of a loaded entity with an \a objectName matching
+ Returns a component matching \a componentType of a loaded entity with an \e objectName matching
the \a entityName.
If the entity has multiple matching components, the first match in the component list of
the entity is returned.
diff --git a/src/render/io/qsceneloader.h b/src/render/io/qsceneloader.h
index 6842a6926..51ba42de7 100644
--- a/src/render/io/qsceneloader.h
+++ b/src/render/io/qsceneloader.h
@@ -60,6 +60,8 @@ public:
explicit QSceneLoader(Qt3DCore::QNode *parent = nullptr);
~QSceneLoader();
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
enum Status {
None = 0,
Loading,
diff --git a/src/render/io/scene.cpp b/src/render/io/scene.cpp
index 089091701..1a2000bbb 100644
--- a/src/render/io/scene.cpp
+++ b/src/render/io/scene.cpp
@@ -39,7 +39,6 @@
#include "scene_p.h"
#include <Qt3DCore/qentity.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qdownloadhelperservice_p.h>
@@ -80,6 +79,9 @@ void Scene::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
m_sceneManager->addSceneData(m_source, peerId());
else
m_sceneManager->startSceneDownload(m_source, peerId());
+
+ const auto d = static_cast<const QSceneLoaderPrivate *>(Qt3DCore::QNodePrivate::get(node));
+ const_cast<QSceneLoaderPrivate *>(d)->setStatus(QSceneLoader::Loading);
}
markDirty(AbstractRenderer::AllDirty);
}
diff --git a/src/render/jobs/abstractpickingjob.cpp b/src/render/jobs/abstractpickingjob.cpp
index 35e658535..092ab7d3b 100644
--- a/src/render/jobs/abstractpickingjob.cpp
+++ b/src/render/jobs/abstractpickingjob.cpp
@@ -63,6 +63,7 @@ AbstractPickingJob::AbstractPickingJob()
, m_node(nullptr)
, m_frameGraphRoot(nullptr)
, m_renderSettings(nullptr)
+ , m_oneEnabledAtLeast(false)
{
}
@@ -72,6 +73,7 @@ AbstractPickingJob::AbstractPickingJob(Qt3DCore::QAspectJobPrivate &dd)
, m_node(nullptr)
, m_frameGraphRoot(nullptr)
, m_renderSettings(nullptr)
+ , m_oneEnabledAtLeast(false)
{
}
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index 9af2f4f38..172c4ddca 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -354,7 +354,7 @@ CalculateBoundingVolumeJob::CalculateBoundingVolumeJob()
: m_manager(nullptr)
, m_node(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::CalcBoundingVolume, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::CalcBoundingVolume, 0)
}
void CalculateBoundingVolumeJob::run()
diff --git a/src/render/jobs/calcgeometrytrianglevolumes.cpp b/src/render/jobs/calcgeometrytrianglevolumes.cpp
index d2b12e09c..eb31a25a6 100644
--- a/src/render/jobs/calcgeometrytrianglevolumes.cpp
+++ b/src/render/jobs/calcgeometrytrianglevolumes.cpp
@@ -53,7 +53,7 @@ CalcGeometryTriangleVolumes::CalcGeometryTriangleVolumes(const Qt3DCore::QNodeId
, m_geometryRendererId(geometryRendererId)
, m_manager(manager)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::CalcTriangleVolume, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::CalcTriangleVolume, 0)
}
void CalcGeometryTriangleVolumes::run()
diff --git a/src/render/jobs/computefilteredboundingvolumejob.cpp b/src/render/jobs/computefilteredboundingvolumejob.cpp
index 02852685c..0cdbc8b6d 100644
--- a/src/render/jobs/computefilteredboundingvolumejob.cpp
+++ b/src/render/jobs/computefilteredboundingvolumejob.cpp
@@ -74,12 +74,25 @@ void expandWorldBoundingVolume(NodeManagers *manager,
} // namespace
+class ComputeFilteredBoundingVolumeJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ ComputeFilteredBoundingVolumeJobPrivate(ComputeFilteredBoundingVolumeJob *job) : Qt3DCore::QAspectJobPrivate(), m_job(job) {}
+ ~ComputeFilteredBoundingVolumeJobPrivate() {}
+
+ void postFrame(Qt3DCore::QAspectManager *aspectManager) override;
+
+ ComputeFilteredBoundingVolumeJob *m_job;
+ Qt3DRender::Render::Sphere m_sphere;
+};
+
ComputeFilteredBoundingVolumeJob::ComputeFilteredBoundingVolumeJob()
- : m_root(nullptr)
+ : Qt3DCore::QAspectJob(*new ComputeFilteredBoundingVolumeJobPrivate(this))
+ , m_root(nullptr)
, m_ignoreSubTree(nullptr)
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::ExpandBoundingVolume, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::ExpandBoundingVolume, 0)
}
void ComputeFilteredBoundingVolumeJob::setRoot(Entity *root)
@@ -100,11 +113,13 @@ void ComputeFilteredBoundingVolumeJob::ignoreSubTree(Entity *node)
void ComputeFilteredBoundingVolumeJob::run()
{
qCDebug(Jobs) << "Entering" << Q_FUNC_INFO << QThread::currentThread();
+ Q_D(ComputeFilteredBoundingVolumeJob);
+ d->m_sphere = {};
if (!m_root)
return;
if (!m_ignoreSubTree) {
- finished(*m_root->worldBoundingVolumeWithChildren());
+ d->m_sphere = *m_root->worldBoundingVolumeWithChildren();
return;
}
@@ -118,20 +133,24 @@ void ComputeFilteredBoundingVolumeJob::run()
parent = parent->parent();
}
if (!isFilterChildOfRoot) {
- finished(*m_root->worldBoundingVolumeWithChildren());
+ d->m_sphere = *m_root->worldBoundingVolumeWithChildren();
return;
}
- Qt3DRender::Render::Sphere sphere;
- expandWorldBoundingVolume(m_manager, &sphere, m_root, m_ignoreSubTree);
- finished(sphere);
+ expandWorldBoundingVolume(m_manager, &d->m_sphere, m_root, m_ignoreSubTree);
qCDebug(Jobs) << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
}
-void ComputeFilteredBoundingVolumeJob::finished(const Qt3DRender::Render::Sphere &sphere)
+void ComputeFilteredBoundingVolumeJob::finished(Qt3DCore::QAspectManager *aspectManager, const Qt3DRender::Render::Sphere &sphere)
+{
+ Q_UNUSED(aspectManager)
+ Q_UNUSED(sphere)
+}
+
+void ComputeFilteredBoundingVolumeJobPrivate::postFrame(Qt3DCore::QAspectManager *aspectManager)
{
- Q_UNUSED(sphere);
+ m_job->finished(aspectManager, m_sphere);
}
} // namespace Render
diff --git a/src/render/jobs/computefilteredboundingvolumejob_p.h b/src/render/jobs/computefilteredboundingvolumejob_p.h
index d2aca575c..0f804e647 100644
--- a/src/render/jobs/computefilteredboundingvolumejob_p.h
+++ b/src/render/jobs/computefilteredboundingvolumejob_p.h
@@ -64,6 +64,7 @@ namespace Render {
class Entity;
class NodeManagers;
class Sphere;
+class ComputeFilteredBoundingVolumeJobPrivate;
class Q_3DRENDERSHARED_PRIVATE_EXPORT ComputeFilteredBoundingVolumeJob : public Qt3DCore::QAspectJob
{
@@ -76,9 +77,10 @@ public:
void run() override;
protected:
- virtual void finished(const Qt3DRender::Render::Sphere &sphere);
+ virtual void finished(Qt3DCore::QAspectManager *aspectManager, const Qt3DRender::Render::Sphere &sphere); // called in main thread
private:
+ Q_DECLARE_PRIVATE(ComputeFilteredBoundingVolumeJob)
Entity *m_root;
Entity *m_ignoreSubTree;
NodeManagers *m_manager;
diff --git a/src/render/jobs/expandboundingvolumejob.cpp b/src/render/jobs/expandboundingvolumejob.cpp
index d63934b54..8587634cb 100644
--- a/src/render/jobs/expandboundingvolumejob.cpp
+++ b/src/render/jobs/expandboundingvolumejob.cpp
@@ -62,7 +62,7 @@ void expandWorldBoundingVolume(NodeManagers *manager, Entity *node)
const auto childrenHandles = node->childrenHandles();
for (const HEntity &handle : childrenHandles) {
Entity *c = manager->renderNodesManager()->data(handle);
- if (c)
+ if (c && c->isEnabled())
expandWorldBoundingVolume(manager, c);
}
@@ -72,7 +72,7 @@ void expandWorldBoundingVolume(NodeManagers *manager, Entity *node)
Qt3DRender::Render::Sphere *parentBoundingVolume = node->worldBoundingVolumeWithChildren();
for (const HEntity &handle : childrenHandles) {
Entity *c = manager->renderNodesManager()->data(handle);
- if (c)
+ if (c && c->isEnabled())
parentBoundingVolume->expandToContain(*c->worldBoundingVolumeWithChildren());
}
}
@@ -84,7 +84,7 @@ ExpandBoundingVolumeJob::ExpandBoundingVolumeJob()
: m_node(nullptr)
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::ExpandBoundingVolume, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::ExpandBoundingVolume, 0)
}
void ExpandBoundingVolumeJob::setRoot(Entity *root)
diff --git a/src/render/jobs/filterentitybycomponentjob_p.h b/src/render/jobs/filterentitybycomponentjob_p.h
index dd64e50a7..cefcdd296 100644
--- a/src/render/jobs/filterentitybycomponentjob_p.h
+++ b/src/render/jobs/filterentitybycomponentjob_p.h
@@ -74,7 +74,7 @@ public:
: Qt3DCore::QAspectJob()
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::EntityComponentTypeFiltering, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::EntityComponentTypeFiltering, 0)
}
inline void setManager(EntityManager *manager) Q_DECL_NOTHROW { m_manager = manager; }
@@ -97,10 +97,6 @@ private:
QVector<Entity *> m_filteredEntities;
};
-template<typename T, typename ... Ts>
-using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>;
-
-
} // Render
} // Qt3DRender
diff --git a/src/render/jobs/filterlayerentityjob.cpp b/src/render/jobs/filterlayerentityjob.cpp
index e206ef968..032004422 100644
--- a/src/render/jobs/filterlayerentityjob.cpp
+++ b/src/render/jobs/filterlayerentityjob.cpp
@@ -58,7 +58,7 @@ FilterLayerEntityJob::FilterLayerEntityJob()
: Qt3DCore::QAspectJob()
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LayerFiltering, layerFilterJobCounter++);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::LayerFiltering, layerFilterJobCounter++)
}
diff --git a/src/render/jobs/filterproximitydistancejob.cpp b/src/render/jobs/filterproximitydistancejob.cpp
index a25e88508..02b712fc2 100644
--- a/src/render/jobs/filterproximitydistancejob.cpp
+++ b/src/render/jobs/filterproximitydistancejob.cpp
@@ -43,8 +43,10 @@ namespace Render {
FilterProximityDistanceJob::FilterProximityDistanceJob()
: m_manager(nullptr)
+ , m_targetEntity(nullptr)
+ , m_distanceThresholdSquared(0.)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::ProximityFiltering, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::ProximityFiltering, 0)
}
void FilterProximityDistanceJob::run()
@@ -55,9 +57,9 @@ void FilterProximityDistanceJob::run()
// Fill m_filteredEntities
// If no filtering needs to be done, this will be the output value
// otherwise it will be used as the base list of entities to filter
- selectAllEntities();
if (hasProximityFilter()) {
+ selectAllEntities();
QVector<Entity *> entitiesToFilter = std::move(m_filteredEntities);
FrameGraphManager *frameGraphManager = m_manager->frameGraphManager();
EntityManager *entityManager = m_manager->renderNodesManager();
diff --git a/src/render/jobs/framecleanupjob.cpp b/src/render/jobs/framecleanupjob.cpp
index 17ca60bff..fb63f005b 100644
--- a/src/render/jobs/framecleanupjob.cpp
+++ b/src/render/jobs/framecleanupjob.cpp
@@ -55,7 +55,7 @@ FrameCleanupJob::FrameCleanupJob()
: m_managers(nullptr)
, m_root(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::FrameCleanup, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::FrameCleanup, 0)
}
FrameCleanupJob::~FrameCleanupJob()
diff --git a/src/render/jobs/frustumcullingjob.cpp b/src/render/jobs/frustumcullingjob.cpp
index 0922fb0cb..e22d625df 100644
--- a/src/render/jobs/frustumcullingjob.cpp
+++ b/src/render/jobs/frustumcullingjob.cpp
@@ -58,7 +58,7 @@ FrustumCullingJob::FrustumCullingJob()
, m_manager(nullptr)
, m_active(false)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::FrustumCulling, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::FrustumCulling, 0)
}
void FrustumCullingJob::run()
diff --git a/src/render/jobs/genericlambdajob_p.h b/src/render/jobs/genericlambdajob_p.h
index 4d93f0f8d..8cf4276f6 100644
--- a/src/render/jobs/genericlambdajob_p.h
+++ b/src/render/jobs/genericlambdajob_p.h
@@ -68,7 +68,7 @@ public:
: Qt3DCore::QAspectJob()
, m_callable(callable)
{
- SET_JOB_RUN_STAT_TYPE(this, type, 0);
+ SET_JOB_RUN_STAT_TYPE(this, type, 0)
}
// QAspectJob interface
@@ -111,7 +111,7 @@ public:
: Qt3DCore::QAspectJob(*new GenericLambdaJobAndPostFramePrivate<T, U>(postFrameCallable))
, m_runCallable(runCallable)
{
- SET_JOB_RUN_STAT_TYPE(this, type, 0);
+ SET_JOB_RUN_STAT_TYPE(this, type, 0)
}
// QAspectJob interface
diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h
index 7aa6f64ba..c3b581277 100644
--- a/src/render/jobs/job_common_p.h
+++ b/src/render/jobs/job_common_p.h
@@ -80,7 +80,7 @@ namespace JobTypes {
LayerFiltering,
EntityComponentTypeFiltering,
MaterialParameterGathering,
- RenderViewBuilder,
+ RenderCommandUpdater,
GenericLambda,
FrustumCulling,
LightGathering,
@@ -92,9 +92,9 @@ namespace JobTypes {
DirtyShaderGathering,
SendRenderCapture,
SendBufferCapture,
- SyncRenderViewCommandBuilding,
+ SyncRenderViewPreCommandUpdate,
SyncRenderViewInitialization,
- SyncRenderViewCommandBuilder,
+ SyncRenderViewPostCommandUpdate,
SyncFrustumCulling,
ClearBufferDrawIndex,
UpdateMeshTriangleList,
@@ -109,7 +109,9 @@ namespace JobTypes {
UpdateLayerEntity,
SendTextureChangesToFrontend,
SendSetFenceHandlesToFrontend,
- SendDisablesToFrontend
+ SendDisablesToFrontend,
+ RenderViewCommandBuilder,
+ SyncRenderViewPreCommandBuilding
};
} // JobTypes
diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri
index 2181e4a95..eb89ab35e 100644
--- a/src/render/jobs/jobs.pri
+++ b/src/render/jobs/jobs.pri
@@ -18,7 +18,6 @@ HEADERS += \
$$PWD/lightgatherer_p.h \
$$PWD/expandboundingvolumejob_p.h \
$$PWD/updateworldboundingvolumejob_p.h \
- $$PWD/sendrendercapturejob_p.h \
$$PWD/updateshaderdatatransformjob_p.h \
$$PWD/updatelevelofdetailjob_p.h \
$$PWD/updatemeshtrianglelistjob_p.h \
@@ -47,7 +46,6 @@ SOURCES += \
$$PWD/lightgatherer.cpp \
$$PWD/expandboundingvolumejob.cpp \
$$PWD/updateworldboundingvolumejob.cpp \
- $$PWD/sendrendercapturejob.cpp \
$$PWD/updateshaderdatatransformjob.cpp \
$$PWD/updatemeshtrianglelistjob.cpp \
$$PWD/updatelevelofdetailjob.cpp \
diff --git a/src/render/jobs/lightgatherer.cpp b/src/render/jobs/lightgatherer.cpp
index b76cd4d73..b79976aef 100644
--- a/src/render/jobs/lightgatherer.cpp
+++ b/src/render/jobs/lightgatherer.cpp
@@ -53,11 +53,14 @@ LightGatherer::LightGatherer()
, m_manager(nullptr)
, m_environmentLight(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LightGathering, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::LightGathering, 0)
}
void LightGatherer::run()
{
+ m_lights.clear();
+ m_environmentLight = nullptr;
+
const QVector<HEntity> handles = m_manager->activeHandles();
int envLightCount = 0;
diff --git a/src/render/jobs/loadbufferjob.cpp b/src/render/jobs/loadbufferjob.cpp
index 49f271df5..0f4feb5d4 100644
--- a/src/render/jobs/loadbufferjob.cpp
+++ b/src/render/jobs/loadbufferjob.cpp
@@ -39,9 +39,11 @@
#include "loadbufferjob_p.h"
#include <Qt3DRender/private/buffer_p.h>
+#include <Qt3DRender/private/qbuffer_p.h>
#include <Qt3DRender/private/buffermanager_p.h>
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/job_common_p.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
QT_BEGIN_NAMESPACE
@@ -49,13 +51,24 @@ namespace Qt3DRender {
namespace Render {
+class LoadBufferJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ LoadBufferJobPrivate() {}
+ ~LoadBufferJobPrivate() {}
+
+ void postFrame(Qt3DCore::QAspectManager *aspectManager) override;
+
+ Buffer *m_bufferToUpdate = nullptr;
+};
+
LoadBufferJob::LoadBufferJob(const HBuffer &handle)
- : QAspectJob()
+ : QAspectJob(*new LoadBufferJobPrivate)
, m_handle(handle)
, m_nodeManagers(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadBuffer, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadBuffer, 0)
}
LoadBufferJob::~LoadBufferJob()
@@ -64,10 +77,25 @@ LoadBufferJob::~LoadBufferJob()
void LoadBufferJob::run()
{
+ Q_D(LoadBufferJob);
// Let's leave it for the moment until this has been properly tested
qCDebug(Jobs) << Q_FUNC_INFO;
Buffer *buffer = m_nodeManagers->data<Buffer, BufferManager>(m_handle);
buffer->executeFunctor();
+ if (buffer->isSyncData())
+ d->m_bufferToUpdate = buffer;
+}
+
+void LoadBufferJobPrivate::postFrame(Qt3DCore::QAspectManager *aspectManager)
+{
+ if (m_bufferToUpdate == nullptr)
+ return;
+ QBuffer *frontendBuffer = static_cast<decltype(frontendBuffer)>(aspectManager->lookupNode(m_bufferToUpdate->peerId()));
+ QBufferPrivate *dFrontend = static_cast<decltype(dFrontend)>(Qt3DCore::QNodePrivate::get(frontendBuffer));
+ // Calling frontendBuffer->setData would result in forcing a sync against the backend
+ // which isn't necessary
+ dFrontend->setData(m_bufferToUpdate->data());
+ m_bufferToUpdate = nullptr;
}
} // namespace Render
diff --git a/src/render/jobs/loadbufferjob_p.h b/src/render/jobs/loadbufferjob_p.h
index 6a221c7e0..e86e4f835 100644
--- a/src/render/jobs/loadbufferjob_p.h
+++ b/src/render/jobs/loadbufferjob_p.h
@@ -63,6 +63,7 @@ namespace Qt3DRender {
namespace Render {
class NodeManagers;
+class LoadBufferJobPrivate;
class Q_AUTOTEST_EXPORT LoadBufferJob : public Qt3DCore::QAspectJob
{
@@ -76,6 +77,9 @@ public:
protected:
HBuffer m_handle;
NodeManagers *m_nodeManagers;
+
+private:
+ Q_DECLARE_PRIVATE(LoadBufferJob)
};
typedef QSharedPointer<LoadBufferJob> LoadBufferJobPtr;
diff --git a/src/render/jobs/loadgeometryjob.cpp b/src/render/jobs/loadgeometryjob.cpp
index 88930038a..2069336cd 100644
--- a/src/render/jobs/loadgeometryjob.cpp
+++ b/src/render/jobs/loadgeometryjob.cpp
@@ -66,7 +66,7 @@ LoadGeometryJob::LoadGeometryJob(const HGeometryRenderer &handle)
, m_handle(handle)
, m_nodeManagers(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadGeometry, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadGeometry, 0)
}
LoadGeometryJob::~LoadGeometryJob()
diff --git a/src/render/jobs/loadscenejob.cpp b/src/render/jobs/loadscenejob.cpp
index f858f82e3..be855c608 100644
--- a/src/render/jobs/loadscenejob.cpp
+++ b/src/render/jobs/loadscenejob.cpp
@@ -63,7 +63,7 @@ LoadSceneJob::LoadSceneJob(const QUrl &source, Qt3DCore::QNodeId sceneComponent)
, m_sceneComponent(sceneComponent)
, m_managers(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadScene, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadScene, 0)
}
void LoadSceneJob::setData(const QByteArray &data)
diff --git a/src/render/jobs/loadskeletonjob.cpp b/src/render/jobs/loadskeletonjob.cpp
index 8d0d47fb9..e696cc434 100644
--- a/src/render/jobs/loadskeletonjob.cpp
+++ b/src/render/jobs/loadskeletonjob.cpp
@@ -288,7 +288,7 @@ void LoadSkeletonJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
dloaderNode->setStatus(m_backendSkeleton->status());
if (m_loadedRootJoint) {
- dloaderNode->m_rootJoint = m_loadedRootJoint;
+ dloaderNode->setRootJoint(m_loadedRootJoint);
m_loadedRootJoint = nullptr;
}
}
diff --git a/src/render/jobs/sendbuffercapturejob.cpp b/src/render/jobs/sendbuffercapturejob.cpp
index 8683ea9f2..2ccb72337 100644
--- a/src/render/jobs/sendbuffercapturejob.cpp
+++ b/src/render/jobs/sendbuffercapturejob.cpp
@@ -39,11 +39,12 @@
#include "sendbuffercapturejob_p.h"
-
-#include "Qt3DRender/private/renderer_p.h"
-#include "Qt3DRender/private/nodemanagers_p.h"
+#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/job_common_p.h>
#include <Qt3DRender/private/buffer_p.h>
+#include <Qt3DRender/private/buffermanager_p.h>
+#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DRender/private/qbuffer_p.h>
QT_BEGIN_NAMESPACE
@@ -51,36 +52,75 @@ namespace Qt3DRender {
namespace Render {
+class SendBufferCaptureJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ SendBufferCaptureJobPrivate() {}
+ ~SendBufferCaptureJobPrivate() {}
+
+ void postFrame(Qt3DCore::QAspectManager *aspectManager) override;
+
+ mutable QMutex m_mutex;
+ QVector<QPair<Qt3DCore::QNodeId, QByteArray>> m_buffersToCapture;
+ QVector<QPair<Qt3DCore::QNodeId, QByteArray>> m_buffersToNotify;
+};
+
SendBufferCaptureJob::SendBufferCaptureJob()
- : Qt3DCore::QAspectJob()
+ : Qt3DCore::QAspectJob(*new SendBufferCaptureJobPrivate)
+ , m_nodeManagers(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::SendBufferCapture, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::SendBufferCapture, 0)
}
SendBufferCaptureJob::~SendBufferCaptureJob()
{
}
-void SendBufferCaptureJob::addRequest(QPair<Buffer *, QByteArray> request)
+// Called from SubmitRenderView while rendering
+void SendBufferCaptureJob::addRequest(QPair<Qt3DCore::QNodeId, QByteArray> request)
{
- QMutexLocker locker(&m_mutex);
- m_pendingSendBufferCaptures.push_back(request);
+ Q_D(SendBufferCaptureJob);
+ QMutexLocker locker(&d->m_mutex);
+ d->m_buffersToCapture.push_back(request);
}
-// Called by aspect thread jobs to execute (no concurrency at that point)
+// Called by aspect thread jobs to execute (we may still be rendering at this point)
bool SendBufferCaptureJob::hasRequests() const
{
- return m_pendingSendBufferCaptures.size() > 0;
+ Q_D(const SendBufferCaptureJob);
+ QMutexLocker locker(&d->m_mutex);
+ return d->m_buffersToCapture.size() > 0;
}
void SendBufferCaptureJob::run()
{
- QMutexLocker locker(&m_mutex);
- for (const QPair<Buffer*, QByteArray> &pendingCapture : qAsConst(m_pendingSendBufferCaptures)) {
- pendingCapture.first->updateDataFromGPUToCPU(pendingCapture.second);
+ Q_ASSERT(m_nodeManagers);
+ Q_D(SendBufferCaptureJob);
+ QMutexLocker locker(&d->m_mutex);
+ for (const QPair<Qt3DCore::QNodeId, QByteArray> &pendingCapture : qAsConst(d->m_buffersToCapture)) {
+ Buffer *buffer = m_nodeManagers->bufferManager()->lookupResource(pendingCapture.first);
+ // Buffer might have been destroyed between the time addRequest is made and this job gets run
+ // If it exists however, it cannot be destroyed before this job is done running
+ if (buffer != nullptr)
+ buffer->updateDataFromGPUToCPU(pendingCapture.second);
}
+ d->m_buffersToNotify = std::move(d->m_buffersToCapture);
+}
- m_pendingSendBufferCaptures.clear();
+void SendBufferCaptureJobPrivate::postFrame(Qt3DCore::QAspectManager *aspectManager)
+{
+ QMutexLocker locker(&m_mutex);
+ const QVector<QPair<Qt3DCore::QNodeId, QByteArray>> pendingSendBufferCaptures = std::move(m_buffersToNotify);
+ for (const auto &bufferDataPair : pendingSendBufferCaptures) {
+ QBuffer *frontendBuffer = static_cast<decltype(frontendBuffer)>(aspectManager->lookupNode(bufferDataPair.first));
+ if (!frontendBuffer)
+ continue;
+ QBufferPrivate *dFrontend = static_cast<decltype(dFrontend)>(Qt3DCore::QNodePrivate::get(frontendBuffer));
+ // Calling frontendBuffer->setData would result in forcing a sync against the backend
+ // which isn't necessary
+ dFrontend->setData(bufferDataPair.second);
+ Q_EMIT frontendBuffer->dataAvailable();
+ }
}
} // Render
diff --git a/src/render/jobs/sendbuffercapturejob_p.h b/src/render/jobs/sendbuffercapturejob_p.h
index f47c556df..3b9f5d12b 100644
--- a/src/render/jobs/sendbuffercapturejob_p.h
+++ b/src/render/jobs/sendbuffercapturejob_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DCore/qnodeid.h>
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DRender/private/qt3drender_global_p.h>
#include <QMutex>
@@ -67,6 +68,7 @@ class NodeManagers;
class Entity;
class Renderer;
class Buffer;
+class SendBufferCaptureJobPrivate;
class Q_3DRENDERSHARED_PRIVATE_EXPORT SendBufferCaptureJob : public Qt3DCore::QAspectJob
{
@@ -74,15 +76,15 @@ public:
explicit SendBufferCaptureJob();
~SendBufferCaptureJob();
- void addRequest(QPair<Buffer*, QByteArray> request);
+ void setManagers(NodeManagers *nodeManagers) { m_nodeManagers = nodeManagers; }
+ void addRequest(QPair<Qt3DCore::QNodeId, QByteArray> request);
bool hasRequests() const;
void run() final;
private:
- QMutex m_mutex;
-
- QVector<QPair<Buffer*, QByteArray> > m_pendingSendBufferCaptures;
+ Q_DECLARE_PRIVATE(SendBufferCaptureJob)
+ NodeManagers *m_nodeManagers;
};
typedef QSharedPointer<SendBufferCaptureJob> SendBufferCaptureJobPtr;
diff --git a/src/render/jobs/sendrendercapturejob.cpp b/src/render/jobs/sendrendercapturejob.cpp
deleted file mode 100644
index f622c347a..000000000
--- a/src/render/jobs/sendrendercapturejob.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "sendrendercapturejob_p.h"
-
-#include "Qt3DRender/private/renderer_p.h"
-#include "Qt3DRender/private/nodemanagers_p.h"
-#include "Qt3DRender/private/rendercapture_p.h"
-#include <Qt3DRender/private/job_common_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-SendRenderCaptureJob::SendRenderCaptureJob()
- : Qt3DCore::QAspectJob()
- , m_managers(nullptr)
-{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::SendRenderCapture, 0);
-}
-
-SendRenderCaptureJob::~SendRenderCaptureJob()
-{
-
-}
-
-void SendRenderCaptureJob::setPendingCaptureRequests(const QVector<Qt3DCore::QNodeId> &requests)
-{
- m_pendingCaptures = requests;
-}
-
-void SendRenderCaptureJob::setManagers(NodeManagers *managers)
-{
- m_managers = managers;
-}
-
-void SendRenderCaptureJob::run()
-{
- for (const Qt3DCore::QNodeId id : qAsConst(m_pendingCaptures)) {
- auto *node = static_cast<Qt3DRender::Render::RenderCapture *>
- (m_managers->frameGraphManager()->lookupNode(id));
- node->sendRenderCaptures();
- }
- m_pendingCaptures.clear();
-}
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/jobs/sendrendercapturejob_p.h b/src/render/jobs/sendrendercapturejob_p.h
deleted file mode 100644
index 8bc1e2fb0..000000000
--- a/src/render/jobs/sendrendercapturejob_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SENDRENDERCAPTUREJOB_P_H
-#define SENDRENDERCAPTUREJOB_P_H
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DCore/qnodeid.h>
-#include <Qt3DRender/qt3drender_global.h>
-#include <Qt3DRender/private/qt3drender_global_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class NodeManagers;
-class Entity;
-
-class Q_3DRENDERSHARED_PRIVATE_EXPORT SendRenderCaptureJob : public Qt3DCore::QAspectJob
-{
-public:
- SendRenderCaptureJob();
- ~SendRenderCaptureJob();
-
- void setPendingCaptureRequests(const QVector<Qt3DCore::QNodeId> &requests);
- void setManagers(NodeManagers *managers);
-
- void run() final;
-
-private:
- NodeManagers *m_managers;
- QVector<Qt3DCore::QNodeId> m_pendingCaptures;
-};
-
-typedef QSharedPointer<SendRenderCaptureJob> SendRenderCaptureJobPtr;
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // SENDRENDERCAPTUREJOB_P_H
diff --git a/src/render/jobs/updateentitylayersjob.cpp b/src/render/jobs/updateentitylayersjob.cpp
index 2c5e38364..b8c50c179 100644
--- a/src/render/jobs/updateentitylayersjob.cpp
+++ b/src/render/jobs/updateentitylayersjob.cpp
@@ -52,7 +52,7 @@ namespace Render {
UpdateEntityLayersJob::UpdateEntityLayersJob()
: m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateLayerEntity, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateLayerEntity, 0)
}
diff --git a/src/render/jobs/updatemeshtrianglelistjob.cpp b/src/render/jobs/updatemeshtrianglelistjob.cpp
index 1c61d1c90..4837dcad6 100644
--- a/src/render/jobs/updatemeshtrianglelistjob.cpp
+++ b/src/render/jobs/updatemeshtrianglelistjob.cpp
@@ -60,7 +60,7 @@ namespace Render {
UpdateMeshTriangleListJob::UpdateMeshTriangleListJob()
: m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateMeshTriangleList, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateMeshTriangleList, 0)
}
UpdateMeshTriangleListJob::~UpdateMeshTriangleListJob()
diff --git a/src/render/jobs/updateshaderdatatransformjob.cpp b/src/render/jobs/updateshaderdatatransformjob.cpp
index c29a827e3..11fe91932 100644
--- a/src/render/jobs/updateshaderdatatransformjob.cpp
+++ b/src/render/jobs/updateshaderdatatransformjob.cpp
@@ -61,7 +61,7 @@ namespace Render {
UpdateShaderDataTransformJob::UpdateShaderDataTransformJob()
: m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateShaderDataTransform, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateShaderDataTransform, 0)
}
UpdateShaderDataTransformJob::~UpdateShaderDataTransformJob()
diff --git a/src/render/jobs/updateskinningpalettejob.cpp b/src/render/jobs/updateskinningpalettejob.cpp
index 0f5d3d6d6..b77707f15 100644
--- a/src/render/jobs/updateskinningpalettejob.cpp
+++ b/src/render/jobs/updateskinningpalettejob.cpp
@@ -50,7 +50,7 @@ UpdateSkinningPaletteJob::UpdateSkinningPaletteJob()
, m_nodeManagers(nullptr)
, m_root()
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateSkinningPalette, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateSkinningPalette, 0)
}
UpdateSkinningPaletteJob::~UpdateSkinningPaletteJob()
diff --git a/src/render/jobs/updatetreeenabledjob.cpp b/src/render/jobs/updatetreeenabledjob.cpp
index e97fc6414..22d6f6083 100644
--- a/src/render/jobs/updatetreeenabledjob.cpp
+++ b/src/render/jobs/updatetreeenabledjob.cpp
@@ -71,8 +71,9 @@ void updateTreeEnabled(NodeManagers *manager, Entity *node, bool parentEnabled)
UpdateTreeEnabledJob::UpdateTreeEnabledJob()
: Qt3DCore::QAspectJob()
, m_node(nullptr)
+ , m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateTreeEnabled, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateTreeEnabled, 0)
}
void UpdateTreeEnabledJob::setRoot(Entity *root)
diff --git a/src/render/jobs/updateworldboundingvolumejob.cpp b/src/render/jobs/updateworldboundingvolumejob.cpp
index 40dd919bc..65a3ec75d 100644
--- a/src/render/jobs/updateworldboundingvolumejob.cpp
+++ b/src/render/jobs/updateworldboundingvolumejob.cpp
@@ -52,7 +52,7 @@ UpdateWorldBoundingVolumeJob::UpdateWorldBoundingVolumeJob()
: Qt3DCore::QAspectJob()
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateWorldBoundingVolume, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateWorldBoundingVolume, 0)
}
void UpdateWorldBoundingVolumeJob::run()
@@ -61,6 +61,8 @@ void UpdateWorldBoundingVolumeJob::run()
for (const HEntity &handle : handles) {
Entity *node = m_manager->data(handle);
+ if (!node->isEnabled())
+ continue;
*(node->worldBoundingVolume()) = node->localBoundingVolume()->transformed(*(node->worldTransform()));
*(node->worldBoundingVolumeWithChildren()) = *(node->worldBoundingVolume()); // expanded in UpdateBoundingVolumeJob
}
diff --git a/src/render/jobs/updateworldtransformjob.cpp b/src/render/jobs/updateworldtransformjob.cpp
index 13e14442f..e3c8077f4 100644
--- a/src/render/jobs/updateworldtransformjob.cpp
+++ b/src/render/jobs/updateworldtransformjob.cpp
@@ -65,11 +65,13 @@ struct TransformUpdate
QMatrix4x4 worldTransformMatrix;
};
-QVector<TransformUpdate> updateWorldTransformAndBounds(NodeManagers *manager, Entity *node, const Matrix4x4 &parentTransform)
+void updateWorldTransformAndBounds(NodeManagers *manager, Entity *node, const Matrix4x4 &parentTransform, QVector<TransformUpdate> &updatedTransforms)
{
+ if (!node->isEnabled())
+ return;
+
Matrix4x4 worldTransform(parentTransform);
Transform *nodeTransform = node->renderComponent<Transform>();
- QVector<TransformUpdate> updatedTransforms;
const bool hasTransformComponent = nodeTransform != nullptr && nodeTransform->isEnabled();
if (hasTransformComponent)
@@ -85,9 +87,8 @@ QVector<TransformUpdate> updateWorldTransformAndBounds(NodeManagers *manager, En
for (const HEntity &handle : childrenHandles) {
Entity *child = manager->renderNodesManager()->data(handle);
if (child)
- updatedTransforms += updateWorldTransformAndBounds(manager, child, worldTransform);
+ updateWorldTransformAndBounds(manager, child, worldTransform, updatedTransforms);
}
- return updatedTransforms;
}
}
@@ -108,7 +109,7 @@ UpdateWorldTransformJob::UpdateWorldTransformJob()
, m_node(nullptr)
, m_manager(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateTransform, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateTransform, 0)
}
void UpdateWorldTransformJob::setRoot(Entity *root)
@@ -137,7 +138,7 @@ void UpdateWorldTransformJob::run()
Entity *parent = m_node->parent();
if (parent != nullptr)
parentTransform = *(parent->worldTransform());
- d->m_updatedTransforms = updateWorldTransformAndBounds(m_manager, m_node, parentTransform);
+ updateWorldTransformAndBounds(m_manager, m_node, parentTransform, d->m_updatedTransforms);
qCDebug(Jobs) << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
}
diff --git a/src/render/lights/qdirectionallight.cpp b/src/render/lights/qdirectionallight.cpp
index 13fb78843..51827b644 100644
--- a/src/render/lights/qdirectionallight.cpp
+++ b/src/render/lights/qdirectionallight.cpp
@@ -115,12 +115,18 @@ QDirectionalLight::QDirectionalLight(QDirectionalLightPrivate &dd, QNode *parent
/*!
\qmlproperty vector3d Qt3D.Render::DirectionalLight::worldDirection
- Specifies the world direction of the directional light
+ Specifies the world direction of the directional light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QDirectionalLight::worldDirection
- Specifies the world direction of the directional light
+ Specifies the world direction of the directional light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
void QDirectionalLight::setWorldDirection(const QVector3D &direction)
{
diff --git a/src/render/lights/qenvironmentlight.cpp b/src/render/lights/qenvironmentlight.cpp
index 86ef04f95..977e117db 100644
--- a/src/render/lights/qenvironmentlight.cpp
+++ b/src/render/lights/qenvironmentlight.cpp
@@ -158,6 +158,9 @@ QEnvironmentLight::~QEnvironmentLight()
Holds the current environment irradiance map texture.
By default, the environment irradiance texture is null.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
@@ -166,6 +169,9 @@ QEnvironmentLight::~QEnvironmentLight()
Holds the current environment irradiance map texture.
By default, the environment irradiance texture is null.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
QAbstractTexture *QEnvironmentLight::irradiance() const
{
@@ -179,6 +185,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const
Holds the current environment specular map texture.
By default, the environment specular texture is null.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
@@ -187,6 +196,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const
Holds the current environment specular map texture.
By default, the environment specular texture is null.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
QAbstractTexture *QEnvironmentLight::specular() const
{
diff --git a/src/render/lights/qpointlight.cpp b/src/render/lights/qpointlight.cpp
index 2b042c91d..c16291709 100644
--- a/src/render/lights/qpointlight.cpp
+++ b/src/render/lights/qpointlight.cpp
@@ -135,12 +135,18 @@ QPointLight::QPointLight(QPointLightPrivate &dd, QNode *parent)
/*!
\qmlproperty float Qt3D.Render::PointLight::constantAttenuation
- Specifies the constant attenuation of the point light
+ Specifies the constant attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QPointLight::constantAttenuation
- Specifies the constant attenuation of the point light
+ Specifies the constant attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QPointLight::constantAttenuation() const
{
@@ -159,12 +165,18 @@ void QPointLight::setConstantAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::PointLight::linearAttenuation
- Specifies the linear attenuation of the point light
+ Specifies the linear attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QPointLight::linearAttenuation
- Specifies the linear attenuation of the point light
+ Specifies the linear attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QPointLight::linearAttenuation() const
{
@@ -183,12 +195,18 @@ void QPointLight::setLinearAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::PointLight::quadraticAttenuation
- Specifies the quadratic attenuation of the point light
+ Specifies the quadratic attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QPointLight::quadraticAttenuation
- Specifies the quadratic attenuation of the point light
+ Specifies the quadratic attenuation of the point light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QPointLight::quadraticAttenuation() const
{
diff --git a/src/render/lights/qspotlight.cpp b/src/render/lights/qspotlight.cpp
index eddafbe61..c725a6baf 100644
--- a/src/render/lights/qspotlight.cpp
+++ b/src/render/lights/qspotlight.cpp
@@ -140,12 +140,18 @@ QSpotLight::QSpotLight(QSpotLightPrivate &dd, QNode *parent)
/*!
\qmlproperty float Qt3D.Render::SpotLight::constantAttenuation
- Specifies the constant attenuation of the spot light
+ Specifies the constant attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::constantAttenuation
- Specifies the constant attenuation of the spot light
+ Specifies the constant attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QSpotLight::constantAttenuation() const
{
@@ -164,12 +170,18 @@ void QSpotLight::setConstantAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::SpotLight::linearAttenuation
- Specifies the linear attenuation of the spot light
+ Specifies the linear attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::linearAttenuation
- Specifies the linear attenuation of the spot light
+ Specifies the linear attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QSpotLight::linearAttenuation() const
{
@@ -188,12 +200,18 @@ void QSpotLight::setLinearAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::SpotLight::quadraticAttenuation
- Specifies the quadratic attenuation of the spot light
+ Specifies the quadratic attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::quadraticAttenuation
- Specifies the quadratic attenuation of the spot light
+ Specifies the quadratic attenuation of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QSpotLight::quadraticAttenuation() const
{
@@ -212,12 +230,18 @@ void QSpotLight::setQuadraticAttenuation(float value)
/*!
\qmlproperty vector3d Qt3D.Render::SpotLight::localDirection
- Specifies the local direction of the spot light
+ Specifies the local direction of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::localDirection
- Specifies the local direction of the spot light
+ Specifies the local direction of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
QVector3D QSpotLight::localDirection() const
{
@@ -227,12 +251,18 @@ QVector3D QSpotLight::localDirection() const
/*!
\qmlproperty float Qt3D.Render::SpotLight::cutOffAngle
- Specifies the cut off angle of the spot light
+ Specifies the cut off angle of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::cutOffAngle
- Specifies the cut off angle of the spot light
+ Specifies the cut off angle of the spot light.
+
+ \note The exact meaning and use of this property is up to the
+ material implementation.
*/
float QSpotLight::cutOffAngle() const
{
diff --git a/src/render/materialsystem/qshaderimage.cpp b/src/render/materialsystem/qshaderimage.cpp
index f2ce04c3d..508cf44f2 100644
--- a/src/render/materialsystem/qshaderimage.cpp
+++ b/src/render/materialsystem/qshaderimage.cpp
@@ -342,7 +342,7 @@ QShaderImagePrivate::~QShaderImagePrivate()
*/
/*!
- \qmlproperty Qt3DRender::QShaderImage::mipLevel
+ \qmlproperty int Qt3D.Render::ShaderImage::mipLevel
Holds which mipLevel out of the referenced texture should be used for the
ShaderImage.
@@ -351,7 +351,7 @@ QShaderImagePrivate::~QShaderImagePrivate()
*/
/*!
- \qmlproperty Qt3DRender::QShaderImage::layer
+ \qmlproperty int Qt3D.Render::ShaderImage::layer
Holds which layer out of the referenced texture should be used for the
ShaderImage. This property does nothing if \a layered is set to true or if
@@ -365,11 +365,11 @@ QShaderImagePrivate::~QShaderImagePrivate()
cubeMapFace = layer - (cubeMapLayer * 6)
\endcode
- \default 0
+ Default value is 0.
*/
/*!
- * \qmlproperty Qt3DRender::QShaderImage::layered
+ * \qmlproperty bool Qt3D.Render::ShaderImage::layered
If set to true, if the referenced texture is a one-dimensional array,
two-dimensional array, three-dimensional, cube map, cube map array, or
@@ -377,21 +377,28 @@ QShaderImagePrivate::~QShaderImagePrivate()
for all layers. If set to false, only the single layer specified by the \a
layer property will be bound.
- \default false
+ Default value is \c false.
*/
/*!
- \qmlproperty Qt3DRender::QShaderImage::access
+ \qmlproperty enumeration Qt3D.Render::ShaderImage::access
Specifies the type of access we want to allow from our shader instances to
the image. If a shader tries to write or read from an image that has
incompatible access, the behavior is undefined.
- \default ShaderImage.ReadWrite
+ \value ShaderImage.ReadOnly
+ Read-only access.
+ \value ShaderImage.WriteOnly
+ Write-only access.
+ \value ShaderImage.ReadWrite
+ Read-write access.
+
+ Default value is ShaderImage.ReadWrite.
*/
/*!
- \qmlproperty Qt3DRender::QShaderImage::format
+ \qmlproperty enumeration Qt3D.Render::ShaderImage::format
Specifies the image format, which is essentially important when storing values
in the ShaderImage from a shader.
@@ -407,7 +414,7 @@ QShaderImagePrivate::~QShaderImagePrivate()
By default Qt3D will try to set the image format to match that of the
referenced texture.
- \default ShaderImage.Automatic
+ Default value is ShaderImage.Automatic.
*/
/*!
diff --git a/src/render/materialsystem/qshaderprogrambuilder.cpp b/src/render/materialsystem/qshaderprogrambuilder.cpp
index 6613661d1..7f98fbf5e 100644
--- a/src/render/materialsystem/qshaderprogrambuilder.cpp
+++ b/src/render/materialsystem/qshaderprogrambuilder.cpp
@@ -135,6 +135,11 @@ QShaderProgramBuilder::QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Q
{
}
+// TODO Unused remove in Qt6
+void QShaderProgramBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
/*!
\qmlproperty string ShaderProgramBuilder::shaderProgram
diff --git a/src/render/materialsystem/qshaderprogrambuilder.h b/src/render/materialsystem/qshaderprogrambuilder.h
index 5dc6b54ff..48e189c8c 100644
--- a/src/render/materialsystem/qshaderprogrambuilder.h
+++ b/src/render/materialsystem/qshaderprogrambuilder.h
@@ -117,6 +117,8 @@ Q_SIGNALS:
protected:
explicit QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QShaderProgramBuilder)
diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp
index 58709b37e..0d4b5edba 100644
--- a/src/render/materialsystem/shader.cpp
+++ b/src/render/materialsystem/shader.cpp
@@ -57,11 +57,35 @@ using namespace Qt3DCore;
namespace Qt3DRender {
namespace Render {
+const int Shader::modelMatrixNameId = StringToInt::lookupId(QLatin1String("modelMatrix"));
+const int Shader::viewMatrixNameId = StringToInt::lookupId(QLatin1String("viewMatrix"));
+const int Shader::projectionMatrixNameId = StringToInt::lookupId(QLatin1String("projectionMatrix"));
+const int Shader::modelViewMatrixNameId = StringToInt::lookupId(QLatin1String("modelView"));
+const int Shader::viewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("viewProjectionMatrix"));
+const int Shader::modelViewProjectionNameId = StringToInt::lookupId(QLatin1String("modelViewProjection"));
+const int Shader::mvpNameId = StringToInt::lookupId(QLatin1String("mvp"));
+const int Shader::inverseModelMatrixNameId = StringToInt::lookupId(QLatin1String("inverseModelMatrix"));
+const int Shader::inverseViewMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewMatrix"));
+const int Shader::inverseProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseProjectionMatrix"));
+const int Shader::inverseModelViewNameId = StringToInt::lookupId(QLatin1String("inverseModelView"));
+const int Shader::inverseViewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix"));
+const int Shader::inverseModelViewProjectionNameId = StringToInt::lookupId(QLatin1String("inverseModelViewProjection"));
+const int Shader::modelNormalMatrixNameId = StringToInt::lookupId(QLatin1String("modelNormalMatrix"));
+const int Shader::modelViewNormalNameId = StringToInt::lookupId(QLatin1String("modelViewNormal"));
+const int Shader::viewportMatrixNameId = StringToInt::lookupId(QLatin1String("viewportMatrix"));
+const int Shader::inverseViewportMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewportMatrix"));
+const int Shader::aspectRatioNameId = StringToInt::lookupId(QLatin1String("aspectRatio"));
+const int Shader::exposureNameId = StringToInt::lookupId(QLatin1String("exposure"));
+const int Shader::gammaNameId = StringToInt::lookupId(QLatin1String("gamma"));
+const int Shader::timeNameId = StringToInt::lookupId(QLatin1String("time"));
+const int Shader::eyePositionNameId = StringToInt::lookupId(QLatin1String("eyePosition"));
+const int Shader::skinningPaletteNameId = StringToInt::lookupId(QLatin1String("skinningPalette[0]"));
Shader::Shader()
: BackendNode(ReadWrite)
, m_isLoaded(false)
, m_dna(0)
+ , m_oldDna(0)
, m_graphicsContext(nullptr)
, m_status(QShaderProgram::NotReady)
, m_requiresFrontendSync(false)
@@ -243,13 +267,13 @@ void Shader::prepareUniforms(ShaderParameterPack &pack)
{
const PackUniformHash &values = pack.uniforms();
- auto it = values.cbegin();
- const auto end = values.cend();
+ auto it = values.keys.cbegin();
+ const auto end = values.keys.cend();
while (it != end) {
// Find if there's a uniform with the same name id
for (const ShaderUniform &uniform : qAsConst(m_uniforms)) {
- if (uniform.m_nameId == it.key()) {
+ if (uniform.m_nameId == *it) {
pack.setSubmissionUniform(uniform);
break;
}
@@ -307,13 +331,47 @@ void Shader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescriptio
{
m_uniforms = uniformsDescription;
m_uniformsNames.resize(uniformsDescription.size());
- m_uniformsNamesIds.resize(uniformsDescription.size());
+ m_uniformsNamesIds.reserve(uniformsDescription.size());
+ m_standardUniformNamesIds.reserve(5);
QHash<QString, ShaderUniform> activeUniformsInDefaultBlock;
+ static const QVector<int> standardUniformNameIds = {
+ modelMatrixNameId,
+ viewMatrixNameId,
+ projectionMatrixNameId,
+ modelViewMatrixNameId,
+ viewProjectionMatrixNameId,
+ modelViewProjectionNameId,
+ mvpNameId,
+ inverseModelMatrixNameId,
+ inverseViewMatrixNameId,
+ inverseProjectionMatrixNameId,
+ inverseModelViewNameId,
+ inverseViewProjectionMatrixNameId,
+ inverseModelViewProjectionNameId,
+ modelNormalMatrixNameId,
+ modelViewNormalNameId,
+ viewportMatrixNameId,
+ inverseViewportMatrixNameId,
+ aspectRatioNameId,
+ exposureNameId,
+ gammaNameId,
+ timeNameId,
+ eyePositionNameId,
+ skinningPaletteNameId,
+ };
+
for (int i = 0, m = uniformsDescription.size(); i < m; i++) {
m_uniformsNames[i] = m_uniforms[i].m_name;
- m_uniforms[i].m_nameId = StringToInt::lookupId(m_uniformsNames[i]);
- m_uniformsNamesIds[i] = m_uniforms[i].m_nameId;
+ const int nameId = StringToInt::lookupId(m_uniformsNames[i]);
+ m_uniforms[i].m_nameId = nameId;
+
+ // Is the uniform a Qt3D "Standard" uniform or a user defined one?
+ if (standardUniformNameIds.contains(nameId))
+ m_standardUniformNamesIds.push_back(nameId);
+ else
+ m_uniformsNamesIds.push_back(nameId);
+
if (uniformsDescription[i].m_blockIndex == -1) { // Uniform is in default block
qCDebug(Shaders) << "Active Uniform in Default Block " << uniformsDescription[i].m_name << uniformsDescription[i].m_blockIndex;
activeUniformsInDefaultBlock.insert(uniformsDescription[i].m_name, uniformsDescription[i]);
@@ -393,6 +451,7 @@ void Shader::initializeFromReference(const Shader &other)
{
Q_ASSERT(m_dna == other.m_dna);
m_uniformsNamesIds = other.m_uniformsNamesIds;
+ m_standardUniformNamesIds = other.m_standardUniformNamesIds;
m_uniformsNames = other.m_uniformsNames;
m_uniforms = other.m_uniforms;
m_attributesNames = other.m_attributesNames;
diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h
index 1c9731e50..4c5bc5ea1 100644
--- a/src/render/materialsystem/shader_p.h
+++ b/src/render/materialsystem/shader_p.h
@@ -75,6 +75,30 @@ typedef uint ProgramDNA;
class Q_AUTOTEST_EXPORT Shader : public BackendNode
{
public:
+ static const int modelMatrixNameId;
+ static const int viewMatrixNameId;
+ static const int projectionMatrixNameId;
+ static const int modelViewMatrixNameId;
+ static const int viewProjectionMatrixNameId;
+ static const int modelViewProjectionNameId;
+ static const int mvpNameId;
+ static const int inverseModelMatrixNameId;
+ static const int inverseViewMatrixNameId;
+ static const int inverseProjectionMatrixNameId;
+ static const int inverseModelViewNameId;
+ static const int inverseViewProjectionMatrixNameId;
+ static const int inverseModelViewProjectionNameId;
+ static const int modelNormalMatrixNameId;
+ static const int modelViewNormalNameId;
+ static const int viewportMatrixNameId;
+ static const int inverseViewportMatrixNameId;
+ static const int aspectRatioNameId;
+ static const int exposureNameId;
+ static const int gammaNameId;
+ static const int timeNameId;
+ static const int eyePositionNameId;
+ static const int skinningPaletteNameId;
+
Shader();
~Shader();
@@ -88,6 +112,7 @@ public:
const QHash<QString, int> fragOutputs() const;
inline QVector<int> uniformsNamesIds() const { return m_uniformsNamesIds; }
+ inline QVector<int> standardUniformNameIds() const { return m_standardUniformNamesIds; }
inline QVector<int> uniformBlockNamesIds() const { return m_uniformBlockNamesIds; }
inline QVector<int> storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; }
inline QVector<int> attributeNamesIds() const { return m_attributeNamesIds; }
@@ -128,6 +153,7 @@ public:
private:
QVector<QString> m_uniformsNames;
QVector<int> m_uniformsNamesIds;
+ QVector<int> m_standardUniformNamesIds;
QVector<ShaderUniform> m_uniforms;
QVector<QString> m_attributesNames;
diff --git a/src/render/picking/qabstractraycaster.cpp b/src/render/picking/qabstractraycaster.cpp
index ab0916401..5f4c4c490 100644
--- a/src/render/picking/qabstractraycaster.cpp
+++ b/src/render/picking/qabstractraycaster.cpp
@@ -58,10 +58,6 @@ QAbstractRayCasterPrivate::QAbstractRayCasterPrivate()
m_shareable = false;
}
-/*!
- \property Qt3DRender::QAbstractRayCaster::Hits
-*/
-
QAbstractRayCasterPrivate *QAbstractRayCasterPrivate::get(QAbstractRayCaster *obj)
{
return obj->d_func();
diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp
index 7d9741f21..4f039b361 100644
--- a/src/render/picking/qobjectpicker.cpp
+++ b/src/render/picking/qobjectpicker.cpp
@@ -152,7 +152,7 @@ namespace Qt3DRender {
This signal is emitted when the bounding volume defined by the
pickAttribute property intersects with a ray on a mouse click. Intersection
- information are accessible through the pick \a parameter.
+ information are accessible through the \a pick parameter.
*/
/*!
@@ -292,6 +292,11 @@ void QObjectPicker::setPriority(int priority)
}
}
+// TODO Unused remove in Qt6
+void QObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{
+}
+
/*!
\qmlproperty bool Qt3D.Render::ObjectPicker::dragEnabled
*/
diff --git a/src/render/picking/qobjectpicker.h b/src/render/picking/qobjectpicker.h
index ee63c9418..ea65040ba 100644
--- a/src/render/picking/qobjectpicker.h
+++ b/src/render/picking/qobjectpicker.h
@@ -77,6 +77,10 @@ public Q_SLOTS:
void setDragEnabled(bool dragEnabled);
Q_REVISION(13) void setPriority(int priority);
+protected:
+ // TODO Unused remove in Qt6
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
+
Q_SIGNALS:
void pressed(Qt3DRender::QPickEvent *pick);
void released(Qt3DRender::QPickEvent *pick);
diff --git a/src/render/picking/qobjectpicker_p.h b/src/render/picking/qobjectpicker_p.h
index 69cee529d..61f8a3d94 100644
--- a/src/render/picking/qobjectpicker_p.h
+++ b/src/render/picking/qobjectpicker_p.h
@@ -50,7 +50,6 @@
#include <Qt3DCore/private/qcomponent_p.h>
#include <Qt3DCore/qnodeid.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DRender/private/qt3drender_global_p.h>
#include <Qt3DRender/private/objectpicker_p.h>
diff --git a/src/render/picking/raycaster.cpp b/src/render/picking/raycaster.cpp
index 3a79204c7..8d3456595 100644
--- a/src/render/picking/raycaster.cpp
+++ b/src/render/picking/raycaster.cpp
@@ -44,7 +44,6 @@
#include <Qt3DRender/qlayer.h>
#include <Qt3DRender/private/qabstractraycaster_p.h>
#include <Qt3DRender/private/raycastingjob_p.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
diff --git a/src/render/raycasting/qcollisionqueryresult.cpp b/src/render/raycasting/qcollisionqueryresult.cpp
index 9d1e484b6..d2a443691 100644
--- a/src/render/raycasting/qcollisionqueryresult.cpp
+++ b/src/render/raycasting/qcollisionqueryresult.cpp
@@ -46,6 +46,7 @@ namespace RayCasting {
QCollisionQueryResultPrivate::QCollisionQueryResultPrivate()
: QSharedData()
+ , m_handle(0)
{
}
diff --git a/src/render/raycasting/qcollisionqueryresult_p.h b/src/render/raycasting/qcollisionqueryresult_p.h
index 67f6a34d0..d8e2056eb 100644
--- a/src/render/raycasting/qcollisionqueryresult_p.h
+++ b/src/render/raycasting/qcollisionqueryresult_p.h
@@ -86,8 +86,10 @@ public:
Hit(Qt3DCore::QNodeId entity, const Vector3D &intersection, float distance, const Vector3D &uvw)
: m_entityId(entity)
+ , m_type(Entity)
, m_intersection(intersection)
, m_distance(distance)
+ , m_primitiveIndex(0U)
, m_uvw(uvw)
{
}
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
index 333453ac7..71edc1c74 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
@@ -265,17 +265,15 @@ QOpenGLShaderProgram *GraphicsContext::createShaderProgram(Shader *shaderNode)
return shaderProgram.take();
}
-// Called by GL Command Thread (can't use global glHelpers)
// That assumes that the shaderProgram in Shader stays the same
void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderProgram *shaderProgram)
{
- QScopedPointer<GraphicsHelperInterface> glHelper(resolveHighestOpenGLFunctions());
- shader->initializeUniforms(glHelper->programUniformsAndLocations(shaderProgram->programId()));
- shader->initializeAttributes(glHelper->programAttributesAndLocations(shaderProgram->programId()));
+ shader->initializeUniforms(m_glHelper->programUniformsAndLocations(shaderProgram->programId()));
+ shader->initializeAttributes(m_glHelper->programAttributesAndLocations(shaderProgram->programId()));
if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject))
- shader->initializeUniformBlocks(glHelper->programUniformBlocks(shaderProgram->programId()));
+ shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId()));
if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject))
- shader->initializeShaderStorageBlocks(glHelper->programShaderStorageBlocks(shaderProgram->programId()));
+ shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId()));
}
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index 4b4199820..47779dded 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -538,9 +538,9 @@ GLuint SubmissionContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeI
// ### TODO QTBUG-64757 this check is insufficient since the
// texture may have changed to another one with the same size. That
// case is not handled atm.
- needsResize |= (rTex != nullptr && rTex->size() != s);
- if (isActiveRenderTarget) {
- if (attachment.m_point == QRenderTargetOutput::Color0)
+ if (rTex) {
+ needsResize |= rTex->size() != s;
+ if (isActiveRenderTarget && attachment.m_point == QRenderTargetOutput::Color0)
m_renderTargetFormat = rTex->properties().format;
}
}
@@ -687,8 +687,8 @@ QImage SubmissionContext::readFramebuffer(const QRect &rect)
GLint samples = 0;
m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples);
if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) {
- qWarning () << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; "
- "Required feature BlitFramebuffer is missing.";
+ qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; "
+ "Required feature BlitFramebuffer is missing.";
return img;
}
@@ -711,7 +711,7 @@ QImage SubmissionContext::readFramebuffer(const QRect &rect)
if (status != GL_FRAMEBUFFER_COMPLETE) {
gl->glDeleteRenderbuffers(1, &rb);
gl->glDeleteFramebuffers(1, &fbo);
- qWarning () << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status;
+ qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status;
return img;
}
@@ -797,7 +797,7 @@ bool SubmissionContext::activateShader(ProgramDNA shaderDNA)
m_activeShaderDNA = shaderDNA;
} else {
m_glHelper->useProgram(0);
- qWarning() << "No shader program found for DNA";
+ qCWarning(Backend) << "No shader program found for DNA";
m_activeShaderDNA = 0;
return false;
}
@@ -855,7 +855,7 @@ void SubmissionContext::activateDrawBuffers(const AttachmentPack &attachments)
}
}
} else {
- qWarning() << "FBO incomplete";
+ qCWarning(Backend) << "FBO incomplete";
}
}
@@ -1171,7 +1171,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
if (uniformValues.contains(namedTex.glslNameId)) {
GLTexture *t = manager->glTextureManager()->lookupResource(namedTex.nodeId);
if (t != nullptr) {
- UniformValue &texUniform = uniformValues[namedTex.glslNameId];
+ UniformValue &texUniform = uniformValues.value(namedTex.glslNameId);
if (texUniform.valueType() == UniformValue::TextureValue) {
const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t);
texUniform.data<int>()[namedTex.uniformArrayIndex] = texUnit;
@@ -1179,7 +1179,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
if (namedTex.glslNameId != irradianceId &&
namedTex.glslNameId != specularId) {
// Only return false if we are not dealing with env light textures
- qWarning() << "Unable to find suitable Texture Unit";
+ qCWarning(Backend) << "Unable to find suitable Texture Unit";
return false;
}
}
@@ -1198,15 +1198,15 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
if (img != nullptr) {
GLTexture *t = manager->glTextureManager()->lookupResource(img->textureId());
if (t == nullptr) {
- qWarning() << "Shader Image referencing invalid texture";
+ qCWarning(Backend) << "Shader Image referencing invalid texture";
continue;
} else {
- UniformValue &imgUniform = uniformValues[namedTex.glslNameId];
+ UniformValue &imgUniform = uniformValues.value(namedTex.glslNameId);
if (imgUniform.valueType() == UniformValue::ShaderImageValue) {
const int imgUnit = m_imageContext.activateImage(img, t);
imgUniform.data<int>()[namedTex.uniformArrayIndex] = imgUnit;
if (imgUnit == -1) {
- qWarning() << "Unable to bind Image to Texture";
+ qCWarning(Backend) << "Unable to bind Image to Texture";
return false;
}
}
@@ -1260,7 +1260,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
for (const ShaderUniform &uniform : activeUniforms) {
// We can use [] as we are sure the the uniform wouldn't
// be un activeUniforms if there wasn't a matching value
- const UniformValue &v = values[uniform.m_nameId];
+ const UniformValue &v = values.value(uniform.m_nameId);
// skip invalid textures/images
if ((v.valueType() == UniformValue::TextureValue ||
diff --git a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp b/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp
index 342fd3dad..d2a01eef4 100644
--- a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp
+++ b/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp
@@ -53,7 +53,7 @@ FilterCompatibleTechniqueJob::FilterCompatibleTechniqueJob()
: m_manager(nullptr)
, m_renderer(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::FilterCompatibleTechniques, 0);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::FilterCompatibleTechniques, 0)
}
void FilterCompatibleTechniqueJob::setManager(TechniqueManager *manager)
diff --git a/src/render/renderers/opengl/jobs/jobs.pri b/src/render/renderers/opengl/jobs/jobs.pri
index 021cd3242..d80b8bfd9 100644
--- a/src/render/renderers/opengl/jobs/jobs.pri
+++ b/src/render/renderers/opengl/jobs/jobs.pri
@@ -3,13 +3,15 @@ INCLUDEPATH += $$PWD
SOURCES += \
$$PWD/filtercompatibletechniquejob.cpp \
$$PWD/materialparametergathererjob.cpp \
- $$PWD/renderviewbuilderjob.cpp \
+ $$PWD/renderviewcommandbuilderjob.cpp \
+ $$PWD/renderviewcommandupdaterjob.cpp \
$$PWD/renderviewinitializerjob.cpp \
$$PWD/renderviewjobutils.cpp
HEADERS += \
$$PWD/filtercompatibletechniquejob_p.h \
$$PWD/materialparametergathererjob_p.h \
- $$PWD/renderviewbuilderjob_p.h \
+ $$PWD/renderviewcommandbuilderjob_p.h \
+ $$PWD/renderviewcommandupdaterjob_p.h \
$$PWD/renderviewinitializerjob_p.h \
$$PWD/renderviewjobutils_p.h
diff --git a/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp b/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp
index 5e56e817f..e1f8aa403 100644
--- a/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp
+++ b/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp
@@ -63,7 +63,7 @@ MaterialParameterGathererJob::MaterialParameterGathererJob()
, m_techniqueFilter(nullptr)
, m_renderPassFilter(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, materialParameterGathererCounter++);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, materialParameterGathererCounter++)
}
// TechniqueFilter / RenderPassFilter
diff --git a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp
new file mode 100644
index 000000000..091d49ef5
--- /dev/null
+++ b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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 "renderviewcommandbuilderjob_p.h"
+#include <Qt3DRender/private/job_common_p.h>
+#include <Qt3DRender/private/renderview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+namespace Render {
+
+namespace {
+int renderViewInstanceCounter = 0;
+} // anonymous
+
+RenderViewCommandBuilderJob::RenderViewCommandBuilderJob()
+ : Qt3DCore::QAspectJob()
+ , m_offset(0)
+ , m_count(0)
+ , m_renderView(nullptr)
+{
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, renderViewInstanceCounter++)
+}
+
+void RenderViewCommandBuilderJob::run()
+{
+ if (!m_renderView->noDraw()) {
+ if (m_count == 0)
+ return;
+
+ const bool isDraw = !m_renderView->isCompute();
+ if (isDraw)
+ m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count);
+ else
+ m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count);
+ }
+}
+
+} // Render
+
+} // Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/render/renderers/opengl/jobs/renderviewbuilderjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h
index c38f788b0..556c7f241 100644
--- a/src/render/renderers/opengl/jobs/renderviewbuilderjob_p.h
+++ b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Paul Lemire
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QT3DRENDER_RENDER_RENDERVIEWBUILDERJOB_P_H
-#define QT3DRENDER_RENDER_RENDERVIEWBUILDERJOB_P_H
+#ifndef QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H
+#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H
//
// W A R N I N G
@@ -53,6 +53,7 @@
#include <Qt3DCore/qaspectjob.h>
#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/rendercommand_p.h>
QT_BEGIN_NAMESPACE
@@ -60,32 +61,31 @@ namespace Qt3DRender {
namespace Render {
-class RenderView;
-class Renderer;
-class RenderCommand;
-
-class Q_AUTOTEST_EXPORT RenderViewBuilderJob : public Qt3DCore::QAspectJob
+class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob
{
public:
- RenderViewBuilderJob();
+ RenderViewCommandBuilderJob();
inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; }
- inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; }
- inline void setIndex(int index) Q_DECL_NOTHROW { m_index = index; }
- inline void setRenderables(const QVector<Entity *> &renderables) Q_DECL_NOTHROW { m_renderables = renderables; }
- QVector<RenderCommand *> &commands() Q_DECL_NOTHROW { return m_commands; }
+ inline void setEntities(const QVector<Entity *> &entities, int offset, int count)
+ {
+ m_offset = offset;
+ m_count = count;
+ m_entities = entities;
+ }
+ inline EntityRenderCommandData &commandData() { return m_commandData; }
void run() final;
private:
+ int m_offset;
+ int m_count;
RenderView *m_renderView;
- Renderer *m_renderer;
- int m_index;
- QVector<Entity *> m_renderables;
- QVector<RenderCommand *> m_commands;
+ QVector<Entity *> m_entities;
+ EntityRenderCommandData m_commandData;
};
-typedef QSharedPointer<RenderViewBuilderJob> RenderViewBuilderJobPtr;
+typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr;
} // Render
@@ -93,4 +93,4 @@ typedef QSharedPointer<RenderViewBuilderJob> RenderViewBuilderJobPtr;
QT_END_NAMESPACE
-#endif // QT3DRENDER_RENDER_RENDERVIEWBUILDERJOB_P_H
+#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H
diff --git a/src/render/renderers/opengl/jobs/renderviewbuilderjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp
index 15154641e..6772279d7 100644
--- a/src/render/renderers/opengl/jobs/renderviewbuilderjob.cpp
+++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "renderviewbuilderjob_p.h"
+#include "renderviewcommandupdaterjob_p.h"
#include <Qt3DRender/private/job_common_p.h>
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/renderview_p.h>
@@ -52,22 +52,26 @@ namespace {
int renderViewInstanceCounter = 0;
} // anonymous
-RenderViewBuilderJob::RenderViewBuilderJob()
- : Qt3DCore::QAspectJob(),
- m_renderView(nullptr)
+RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob()
+ : Qt3DCore::QAspectJob()
+ , m_offset(0)
+ , m_count(0)
+ , m_renderView(nullptr)
+ , m_renderer(nullptr)
+ , m_renderables()
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewBuilder, renderViewInstanceCounter++);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++)
}
-void RenderViewBuilderJob::run()
+void RenderViewCommandUpdaterJob::run()
{
// Build RenderCommand should perform the culling as we have no way to determine
// if a child has a mesh in the view frustum while its parent isn't contained in it.
if (!m_renderView->noDraw()) {
- if (!m_renderView->isCompute())
- m_commands = m_renderView->buildDrawRenderCommands(m_renderables);
- else
- m_commands = m_renderView->buildComputeRenderCommands(m_renderables);
+ if (m_count == 0)
+ return;
+ // Update Render Commands (Uniform Change, Depth Change)
+ m_renderView->updateRenderCommand(m_renderables.data(), m_offset, m_count);
}
}
diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h
new file mode 100644
index 000000000..d7f424966
--- /dev/null
+++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Paul Lemire
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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 QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H
+#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/rendercommand_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+namespace Render {
+
+class RenderView;
+class Renderer;
+
+class Q_AUTOTEST_EXPORT RenderViewCommandUpdaterJob : public Qt3DCore::QAspectJob
+{
+public:
+ RenderViewCommandUpdaterJob();
+
+ inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; }
+ inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; }
+ inline void setRenderables(const EntityRenderCommandDataPtr &renderables, int offset, int count) Q_DECL_NOTHROW
+ {
+ m_offset = offset;
+ m_count = count;
+ m_renderables = renderables;
+ }
+ EntityRenderCommandDataPtr renderables() const { return m_renderables; }
+
+ QVector<RenderCommand> &commands() Q_DECL_NOTHROW { return m_commands; }
+
+ void run() final;
+
+private:
+ int m_offset;
+ int m_count;
+ RenderView *m_renderView;
+ Renderer *m_renderer;
+ EntityRenderCommandDataPtr m_renderables;
+ QVector<RenderCommand> m_commands;
+};
+
+typedef QSharedPointer<RenderViewCommandUpdaterJob> RenderViewCommandUpdaterJobPtr;
+
+} // Render
+
+} // Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H
diff --git a/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp b/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp
index 7bf55be40..f0f72803c 100644
--- a/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp
+++ b/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp
@@ -65,7 +65,7 @@ RenderViewInitializerJob::RenderViewInitializerJob()
, m_index(0)
, m_renderView(nullptr)
{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, renderViewInstanceCounter++);
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, renderViewInstanceCounter++)
}
RenderViewInitializerJob::~RenderViewInitializerJob()
diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
index cc211ba68..39917fb58 100644
--- a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
+++ b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
@@ -232,6 +232,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
= static_cast<const Render::RenderSurfaceSelector *>(node);
rv->setSurface(surfaceSelector->surface());
rv->setSurfaceSize(surfaceSelector->renderTargetSize() * surfaceSelector->devicePixelRatio());
+ rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio());
}
break;
}
@@ -487,7 +488,12 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
}
}
} else { // Array of scalar/vec qmlPropertyName[0]
- QString varName = blockName + QLatin1String(".") + qmlPropertyName + QLatin1String("[0]");
+ QString varName;
+ varName.reserve(blockName.length() + 1 + qmlPropertyName.length() + 3);
+ varName.append(blockName);
+ varName.append(QLatin1String("."));
+ varName.append(qmlPropertyName);
+ varName.append(QLatin1String("[0]"));
if (uniforms.contains(varName)) {
qCDebug(Shaders) << "UBO array member " << varName << " set for update";
activeUniformNamesToValue.insert(StringToInt::lookupId(varName), value);
@@ -505,7 +511,11 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
activeUniformNamesToValue.insert(varId, value);
}
} else { // Scalar / Vec
- QString varName = blockName + QLatin1Char('.') + qmlPropertyName;
+ QString varName;
+ varName.reserve(blockName.length() + 1 + qmlPropertyName.length());
+ varName.append(blockName);
+ varName.append(QLatin1String("."));
+ varName.append(qmlPropertyName);
if (uniforms.contains(varName)) {
qCDebug(Shaders) << "UBO scalar member " << varName << " set for update";
@@ -525,11 +535,15 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(Shader
const auto end = properties.end();
while (it != end) {
- const auto prefix = qmlPropertyName.isEmpty() ? QLatin1String("") : QLatin1String(".");
- buildActiveUniformNameValueMapHelper(rShaderData,
- blockName + prefix + qmlPropertyName,
- it.key(),
- it.value().value);
+ QString fullBlockName;
+ fullBlockName.reserve(blockName.length() + 1 + qmlPropertyName.length());
+ fullBlockName.append(blockName);
+ if (!qmlPropertyName.isEmpty()) {
+ fullBlockName.append(QLatin1String("."));
+ fullBlockName.append(qmlPropertyName);
+ }
+ buildActiveUniformNameValueMapHelper(rShaderData, fullBlockName,
+ it.key(), it.value().value);
++it;
}
}
diff --git a/src/render/renderers/opengl/renderer/rendercommand.cpp b/src/render/renderers/opengl/renderer/rendercommand.cpp
index e60b17668..072127391 100644
--- a/src/render/renderers/opengl/renderer/rendercommand.cpp
+++ b/src/render/renderers/opengl/renderer/rendercommand.cpp
@@ -48,6 +48,7 @@ RenderCommand::RenderCommand()
: m_stateSet(nullptr)
, m_depth(0.0f)
, m_changeCost(0)
+ , m_shaderDna(0)
, m_type(RenderCommand::Draw)
, m_primitiveCount(0)
, m_primitiveType(QGeometryRenderer::Triangles)
@@ -70,6 +71,20 @@ RenderCommand::RenderCommand()
m_workGroups[2] = 0;
}
+bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept
+{
+ return (a.m_vao == b.m_vao && a.m_shader == b.m_shader && a.m_material == b.m_material &&
+ a.m_stateSet == b.m_stateSet && a.m_geometry == b.m_geometry && a.m_geometryRenderer == b.m_geometryRenderer &&
+ a.m_indirectDrawBuffer == b.m_indirectDrawBuffer && a.m_activeAttributes == b.m_activeAttributes &&
+ a.m_depth == b.m_depth && a.m_changeCost == b.m_changeCost && a.m_shaderDna == b.m_shaderDna &&
+ a.m_workGroups[0] == b.m_workGroups[0] && a.m_workGroups[1] == b.m_workGroups[1] && a.m_workGroups[2] == b.m_workGroups[2] &&
+ a.m_primitiveCount == b.m_primitiveCount && a.m_primitiveType == b.m_primitiveType && a.m_restartIndexValue == b.m_restartIndexValue &&
+ a.m_firstInstance == b.m_firstInstance && a.m_firstVertex == b.m_firstVertex && a.m_verticesPerPatch == b.m_verticesPerPatch &&
+ a.m_instanceCount == b.m_instanceCount && a.m_indexOffset == b.m_indexOffset && a.m_indexAttributeByteOffset == b.m_indexAttributeByteOffset &&
+ a.m_drawIndexed == b.m_drawIndexed && a.m_drawIndirect == b.m_drawIndirect && a.m_primitiveRestartEnabled == b.m_primitiveRestartEnabled &&
+ a.m_isValid == b.m_isValid && a.m_computeCommand == b.m_computeCommand);
+}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/renderers/opengl/renderer/rendercommand_p.h b/src/render/renderers/opengl/renderer/rendercommand_p.h
index 61cc6d17d..be00fb753 100644
--- a/src/render/renderers/opengl/renderer/rendercommand_p.h
+++ b/src/render/renderers/opengl/renderer/rendercommand_p.h
@@ -55,6 +55,7 @@
#include <qglobal.h>
#include <Qt3DRender/private/shaderparameterpack_p.h>
#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/renderviewjobutils_p.h>
#include <Qt3DRender/qgeometryrenderer.h>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
@@ -69,6 +70,7 @@ namespace Qt3DRender {
namespace Render {
class RenderStateSet;
+using RenderStateSetPtr = QSharedPointer<RenderStateSet>;
class Q_AUTOTEST_EXPORT RenderCommand
{
@@ -80,12 +82,13 @@ public:
HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes ....)
ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the
// Texture while submission is happening.
- RenderStateSet *m_stateSet;
+ RenderStateSetPtr m_stateSet;
HGeometry m_geometry;
HGeometryRenderer m_geometryRenderer;
HBuffer m_indirectDrawBuffer; // Reference to indirect draw buffer (valid only m_drawIndirect == true)
+ HComputeCommand m_computeCommand;
// A QAttribute pack might be interesting
// This is a temporary fix in the meantime, to remove the hacked methods in Technique
@@ -121,6 +124,53 @@ public:
bool m_isValid;
};
+Q_AUTOTEST_EXPORT bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept;
+
+inline bool operator!=(const RenderCommand &lhs, const RenderCommand &rhs) noexcept
+{ return !operator==(lhs, rhs); }
+
+struct EntityRenderCommandData
+{
+ QVector<Entity *> entities;
+ QVector<RenderCommand> commands;
+ QVector<RenderPassParameterData> passesData;
+
+ void reserve(int size)
+ {
+ entities.reserve(size);
+ commands.reserve(size);
+ passesData.reserve(size);
+ }
+
+ inline int size() const { return entities.size(); }
+
+ inline void push_back(Entity *e, const RenderCommand &c, const RenderPassParameterData &p)
+ {
+ entities.push_back(e);
+ commands.push_back(c);
+ passesData.push_back(p);
+ }
+
+ inline void push_back(Entity *e, RenderCommand &&c, RenderPassParameterData &&p)
+ {
+ entities.push_back(e);
+ commands.push_back(std::move(c));
+ passesData.push_back(std::move(p));
+ }
+
+ EntityRenderCommandData &operator+=(EntityRenderCommandData &&t)
+ {
+ entities += std::move(t.entities);
+ commands += std::move(t.commands);
+ passesData += std::move(t.passesData);
+ return *this;
+ }
+
+};
+
+using EntityRenderCommandDataPtr = QSharedPointer<EntityRenderCommandData>;
+
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index 121a6aa8f..ddf57f4fe 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -93,15 +93,15 @@
#include <Qt3DRender/private/subtreeenabler_p.h>
#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
#include <Qt3DRender/private/qshaderprogram_p.h>
+#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
+#include <Qt3DRender/private/commandexecuter_p.h>
#include <Qt3DRender/qcameralens.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <Qt3DCore/private/qabstractaspectjobmanager_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
-
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <Qt3DCore/private/aspectcommanddebugger_p.h>
-#endif
+#include <Qt3DCore/private/qsysteminformationservice_p.h>
+#include <Qt3DCore/private/qsysteminformationservice_p_p.h>
#include <QStack>
#include <QOffscreenSurface>
@@ -114,19 +114,9 @@
#include <QUrl>
#include <QOffscreenSurface>
#include <QWindow>
-
-#include <QtGui/private/qopenglcontext_p.h>
-
-// For Debug purposes only
#include <QThread>
-
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <Qt3DCore/private/qthreadpooler_p.h>
-#include <Qt3DRender/private/job_common_p.h>
-#include <Qt3DRender/private/commandexecuter_p.h>
-#endif
-
+#include <QtGui/private/qopenglcontext_p.h>
#include <Qt3DRender/private/frameprofiler_p.h>
QT_BEGIN_NAMESPACE
@@ -138,6 +128,82 @@ using namespace Qt3DCore;
namespace Qt3DRender {
namespace Render {
+
+namespace {
+
+class SyncLightsGatherer
+{
+public:
+ explicit SyncLightsGatherer(LightGathererPtr gatherJob,
+ RendererCache *cache)
+ : m_gatherJob(gatherJob)
+ , m_cache(cache)
+ {
+ }
+
+ void operator()()
+ {
+ QMutexLocker lock(m_cache->mutex());
+ m_cache->gatheredLights = m_gatherJob->lights();
+ m_cache->environmentLight = m_gatherJob->takeEnvironmentLight();
+ }
+
+private:
+ LightGathererPtr m_gatherJob;
+ RendererCache *m_cache;
+};
+
+class SyncRenderableEntities
+{
+public:
+ explicit SyncRenderableEntities(RenderableEntityFilterPtr gatherJob,
+ RendererCache *cache)
+ : m_gatherJob(gatherJob)
+ , m_cache(cache)
+ {
+ }
+
+ void operator()()
+ {
+ QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
+ std::sort(selectedEntities.begin(), selectedEntities.end());
+
+ QMutexLocker lock(m_cache->mutex());
+ m_cache->renderableEntities = selectedEntities;
+ }
+
+private:
+ RenderableEntityFilterPtr m_gatherJob;
+ RendererCache *m_cache;
+};
+
+class SyncComputableEntities
+{
+public:
+ explicit SyncComputableEntities(ComputableEntityFilterPtr gatherJob,
+ RendererCache *cache)
+ : m_gatherJob(gatherJob)
+ , m_cache(cache)
+ {
+ }
+
+ void operator()()
+ {
+ QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
+ std::sort(selectedEntities.begin(), selectedEntities.end());
+
+ QMutexLocker lock(m_cache->mutex());
+ m_cache->computeEntities = selectedEntities;
+ }
+
+private:
+ ComputableEntityFilterPtr m_gatherJob;
+ RendererCache *m_cache;
+};
+
+} // anonymous
+
+
/*!
\internal
@@ -186,31 +252,33 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create())
, m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create())
, m_updateTreeEnabledJob(Render::UpdateTreeEnabledJobPtr::create())
- , m_sendRenderCaptureJob(Render::SendRenderCaptureJobPtr::create())
, m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create())
, m_updateSkinningPaletteJob(Render::UpdateSkinningPaletteJobPtr::create())
, m_updateLevelOfDetailJob(Render::UpdateLevelOfDetailJobPtr::create())
, m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
, m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create())
, m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create())
+ , m_lightGathererJob(Render::LightGathererPtr::create())
+ , m_renderableEntityFilterJob(Render::RenderableEntityFilterPtr::create())
+ , m_computableEntityFilterJob(Render::ComputableEntityFilterPtr::create())
, m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
, m_vaoGathererJob(SynchronizerJobPtr::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
- , m_sendTextureChangesToFrontendJob(SynchronizerPostFramePtr::create([] {},
- [this] (Qt3DCore::QAspectManager *m) { sendTextureChangesToFrontend(m); },
- JobTypes::SendTextureChangesToFrontend))
, m_sendSetFenceHandlesToFrontendJob(SynchronizerJobPtr::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend))
- , m_sendDisablesToFrontendJob(SynchronizerJobPtr::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend))
, m_introspectShaderJob(SynchronizerPostFramePtr::create([this] { reloadDirtyShaders(); },
[this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); },
JobTypes::DirtyShaderGathering))
, m_syncLoadingJobs(SynchronizerJobPtr::create([] {}, JobTypes::SyncLoadingJobs))
+ , m_cacheRenderableEntitiesJob(SynchronizerJobPtr::create(SyncRenderableEntities(m_renderableEntityFilterJob, &m_cache),
+ JobTypes::EntityComponentTypeFiltering))
+ , m_cacheComputableEntitiesJob(SynchronizerJobPtr::create(SyncComputableEntities(m_computableEntityFilterJob, &m_cache),
+ JobTypes::EntityComponentTypeFiltering))
+ , m_cacheLightsJob(SynchronizerJobPtr::create(SyncLightsGatherer(m_lightGathererJob, &m_cache),
+ JobTypes::EntityComponentTypeFiltering))
, m_ownedContext(false)
, m_offscreenHelper(nullptr)
- , m_shouldSwapBuffers(true)
- #if QT_CONFIG(qt3d_profile_jobs)
, m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this))
- #endif
+ , m_shouldSwapBuffers(true)
{
// Set renderer as running - it will wait in the context of the
// RenderThread for RenderViews to be submitted
@@ -238,6 +306,10 @@ Renderer::Renderer(QRenderAspect::RenderType type)
m_introspectShaderJob->addDependency(m_filterCompatibleTechniqueJob);
+ m_cacheLightsJob->addDependency(m_lightGathererJob);
+ m_cacheRenderableEntitiesJob->addDependency(m_renderableEntityFilterJob);
+ m_cacheComputableEntitiesJob->addDependency(m_computableEntityFilterJob);
+
m_filterCompatibleTechniqueJob->setRenderer(this);
m_defaultRenderStateSet = new RenderStateSet;
@@ -299,13 +371,16 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_pickBoundingVolumeJob->setManagers(m_nodesManager);
m_rayCastingJob->setManagers(m_nodesManager);
m_updateWorldBoundingVolumeJob->setManager(m_nodesManager->renderNodesManager());
- m_sendRenderCaptureJob->setManagers(m_nodesManager);
m_updateLevelOfDetailJob->setManagers(m_nodesManager);
m_updateSkinningPaletteJob->setManagers(m_nodesManager);
m_updateMeshTriangleListJob->setManagers(m_nodesManager);
m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager());
m_updateEntityLayersJob->setManager(m_nodesManager);
m_updateTreeEnabledJob->setManagers(m_nodesManager);
+ m_sendBufferCaptureJob->setManagers(m_nodesManager);
+ m_lightGathererJob->setManager(m_nodesManager->renderNodesManager());
+ m_renderableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
+ m_computableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
}
void Renderer::setServices(QServiceLocator *services)
@@ -338,7 +413,7 @@ QOpenGLContext *Renderer::shareContext() const
// Executed in the reloadDirtyShader job
void Renderer::loadShader(Shader *shader, HShader shaderHandle)
{
- Q_UNUSED(shader);
+ Q_UNUSED(shader)
m_dirtyShaders.push_back(shaderHandle);
}
@@ -432,6 +507,9 @@ void Renderer::initialize()
m_waitForInitializationToBeCompleted.release(1);
// Allow the aspect manager to proceed
m_vsyncFrameAdvanceService->proceedToNextFrame();
+
+ // Force initial refresh
+ markDirty(AllDirty, nullptr);
}
/*!
@@ -653,19 +731,12 @@ void Renderer::doRender(bool swapBuffers)
// RenderQueue is complete (but that means it may be of size 0)
if (canSubmit && (queueIsComplete && !queueIsEmpty)) {
const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue();
-
-#if QT_CONFIG(qt3d_profile_jobs)
- // Save start of frame
- JobRunStats submissionStatsPart1;
- JobRunStats submissionStatsPart2;
- submissionStatsPart1.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart1;
- submissionStatsPart1.jobId.typeAndInstance[1] = 0;
- submissionStatsPart1.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
- submissionStatsPart1.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart2.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart2;
- submissionStatsPart2.jobId.typeAndInstance[1] = 0;
- submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
-#endif
+ QTaskLogger submissionStatsPart1(m_services->systemInformation(),
+ {JobTypes::FrameSubmissionPart1, 0},
+ QTaskLogger::Submission);
+ QTaskLogger submissionStatsPart2(m_services->systemInformation(),
+ {JobTypes::FrameSubmissionPart2, 0},
+ QTaskLogger::Submission);
if (canRender()) {
{ // Scoped to destroy surfaceLock
@@ -698,15 +769,11 @@ void Renderer::doRender(bool swapBuffers)
m_vsyncFrameAdvanceService->proceedToNextFrame();
hasCleanedQueueAndProceeded = true;
-#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- submissionStatsPart2.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart1.endTime = submissionStatsPart2.startTime;
- }
-#endif
// Only try to submit the RenderViews if the preprocessing was successful
// This part of the submission is happening in parallel to the RV building for the next frame
if (preprocessingComplete) {
+ submissionStatsPart1.end(submissionStatsPart2.restart());
+
// 3) Submit the render commands for frame n (making sure we never reference something that could be changing)
// Render using current device state and renderer configuration
submissionData = submitRenderViews(renderViews);
@@ -716,33 +783,18 @@ void Renderer::doRender(bool swapBuffers)
}
}
-#if QT_CONFIG(qt3d_profile_jobs)
// Execute the pending shell commands
m_commandExecuter->performAsynchronousCommandExecution(renderViews);
-#endif
// Delete all the RenderViews which will clear the allocators
// that were used for their allocation
qDeleteAll(renderViews);
-
-#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- // Save submission elapsed time
- submissionStatsPart2.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- // Note this is safe since proceedToNextFrame is the one going to trigger
- // the write to the file, and this is performed after this step
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart1);
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart2);
- Profiling::GLTimeRecorder::writeResults();
- }
-#endif
}
// If hasCleanedQueueAndProceeded isn't true this implies that something went wrong
// with the rendering and/or the renderqueue is incomplete from some reason
// or alternatively it could be complete but empty (RenderQueue of size 0)
-
if (!hasCleanedQueueAndProceeded) {
// RenderQueue was full but something bad happened when
// trying to render it and therefore proceedToNextFrame was not called
@@ -830,12 +882,7 @@ bool Renderer::isReadyToSubmit()
// Main thread
QVariant Renderer::executeCommand(const QStringList &args)
{
-#if QT_CONFIG(qt3d_profile_jobs)
return m_commandExecuter->executeCommand(args);
-#else
- Q_UNUSED(args);
-#endif
- return QVariant();
}
/*!
@@ -860,13 +907,13 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
QHash<HVao, bool> updatedTable;
for (RenderView *rv: renderViews) {
- const QVector<RenderCommand *> commands = rv->commands();
- for (RenderCommand *command : commands) {
+ QVector<RenderCommand> &commands = rv->commands();
+ for (RenderCommand &command : commands) {
// Update/Create VAO
- if (command->m_type == RenderCommand::Draw) {
- Geometry *rGeometry = m_nodesManager->data<Geometry, GeometryManager>(command->m_geometry);
- GeometryRenderer *rGeometryRenderer = m_nodesManager->data<GeometryRenderer, GeometryRendererManager>(command->m_geometryRenderer);
- Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command->m_shader);
+ if (command.m_type == RenderCommand::Draw) {
+ Geometry *rGeometry = m_nodesManager->data<Geometry, GeometryManager>(command.m_geometry);
+ GeometryRenderer *rGeometryRenderer = m_nodesManager->data<GeometryRenderer, GeometryRendererManager>(command.m_geometryRenderer);
+ Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command.m_shader);
// We should never have inserted a command for which these are null
// in the first place
@@ -879,15 +926,15 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
// Create VAO or return already created instance associated with command shader/geometry
// (VAO is emulated if not supported)
- createOrUpdateVAO(command, &vaoHandle, &vao);
- command->m_vao = vaoHandle;
+ createOrUpdateVAO(&command, &vaoHandle, &vao);
+ command.m_vao = vaoHandle;
// Avoids redoing the same thing for the same VAO
if (!updatedTable.contains(vaoHandle)) {
updatedTable.insert(vaoHandle, true);
// Do we have any attributes that are dirty ?
- const bool requiresPartialVAOUpdate = requiresVAOAttributeUpdate(rGeometry, command);
+ const bool requiresPartialVAOUpdate = requiresVAOAttributeUpdate(rGeometry, &command);
// If true, we need to reupload all attributes to set the VAO
// Otherwise only dirty attributes will be updates
@@ -898,7 +945,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
if (rGeometry->isDirty())
m_dirtyGeometry.push_back(rGeometry);
- if (!command->m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) {
+ if (!command.m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) {
Profiling::GLTimeRecorder recorder(Profiling::VAOUpload);
// Activate shader
m_submissionContext->activateShader(shader->dna());
@@ -906,7 +953,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
vao->bind();
// Update or set Attributes and Buffers for the given rGeometry and Command
// Note: this fills m_dirtyAttributes as well
- if (updateVAOWithAttributes(rGeometry, command, shader, requiresFullVAOUpdate))
+ if (updateVAOWithAttributes(rGeometry, &command, shader, requiresFullVAOUpdate))
vao->setSpecified(true);
}
}
@@ -918,82 +965,14 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
rGeometryRenderer->unsetDirty();
// Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command->m_parameterPack);
-
- { // Scoped to show extent
- command->m_isValid = !command->m_activeAttributes.empty();
- if (!command->m_isValid)
- continue;
-
- // Update the draw command with what's going to be needed for the drawing
- uint primitiveCount = rGeometryRenderer->vertexCount();
- uint estimatedCount = 0;
- Attribute *indexAttribute = nullptr;
- Attribute *indirectAttribute = nullptr;
-
- const QVector<Qt3DCore::QNodeId> attributeIds = rGeometry->attributes();
- for (Qt3DCore::QNodeId attributeId : attributeIds) {
- Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
- switch (attribute->attributeType()) {
- case QAttribute::IndexAttribute:
- indexAttribute = attribute;
- break;
- case QAttribute::DrawIndirectAttribute:
- indirectAttribute = attribute;
- break;
- case QAttribute::VertexAttribute: {
- if (command->m_activeAttributes.contains(attribute->nameId()))
- estimatedCount = qMax(attribute->count(), estimatedCount);
- break;
- }
- default:
- Q_UNREACHABLE();
- break;
- }
- }
-
- command->m_drawIndexed = (indexAttribute != nullptr);
- command->m_drawIndirect = (indirectAttribute != nullptr);
-
- // Update the draw command with all the information required for the drawing
- if (command->m_drawIndexed) {
- command->m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType());
- command->m_indexAttributeByteOffset = indexAttribute->byteOffset() + rGeometryRenderer->indexBufferByteOffset();
- }
-
- // Note: we only care about the primitiveCount when using direct draw calls
- // For indirect draw calls it is assumed the buffer was properly set already
- if (command->m_drawIndirect) {
- command->m_indirectAttributeByteOffset = indirectAttribute->byteOffset();
- command->m_indirectDrawBuffer = m_nodesManager->bufferManager()->lookupHandle(indirectAttribute->bufferId());
- } else {
- // Use the count specified by the GeometryRender
- // If not specify use the indexAttribute count if present
- // Otherwise tries to use the count from the attribute with the highest count
- if (primitiveCount == 0) {
- if (indexAttribute)
- primitiveCount = indexAttribute->count();
- else
- primitiveCount = estimatedCount;
- }
- }
+ shader->prepareUniforms(command.m_parameterPack);
- command->m_primitiveCount = primitiveCount;
- command->m_primitiveType = rGeometryRenderer->primitiveType();
- command->m_primitiveRestartEnabled = rGeometryRenderer->primitiveRestartEnabled();
- command->m_restartIndexValue = rGeometryRenderer->restartIndexValue();
- command->m_firstInstance = rGeometryRenderer->firstInstance();
- command->m_instanceCount = rGeometryRenderer->instanceCount();
- command->m_firstVertex = rGeometryRenderer->firstVertex();
- command->m_indexOffset = rGeometryRenderer->indexOffset();
- command->m_verticesPerPatch = rGeometryRenderer->verticesPerPatch();
- } // scope
- } else if (command->m_type == RenderCommand::Compute) {
- Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command->m_shader);
+ } else if (command.m_type == RenderCommand::Compute) {
+ Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command.m_shader);
Q_ASSERT(shader);
// Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command->m_parameterPack);
+ shader->prepareUniforms(command.m_parameterPack);
}
}
}
@@ -1042,6 +1021,7 @@ void Renderer::lookForDirtyBuffers()
}
}
+// Called in prepareSubmission
void Renderer::lookForDownloadableBuffers()
{
m_downloadableBuffers.clear();
@@ -1049,7 +1029,7 @@ void Renderer::lookForDownloadableBuffers()
for (const HBuffer &handle : activeBufferHandles) {
Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
if (buffer->access() & QBuffer::Read)
- m_downloadableBuffers.push_back(handle);
+ m_downloadableBuffers.push_back(buffer->peerId());
}
}
@@ -1106,7 +1086,7 @@ void Renderer::reloadDirtyShaders()
// If api of the renderer matches the one from the technique
if (technique->isCompatibleWithRenderer()) {
const auto passIds = technique->renderPasses();
- for (const QNodeId passId : passIds) {
+ for (const QNodeId &passId : passIds) {
RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId);
HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram());
Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle);
@@ -1146,7 +1126,7 @@ void Renderer::reloadDirtyShaders()
}
}
-// Executed in job postFrame
+// Executed in job (in main thread when jobs are done)
void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager)
{
Q_ASSERT(isRunning());
@@ -1173,14 +1153,13 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager)
}
}
-// Executed in a job (as postFrame)
+// Executed in a job (in main thread when jobs are done)
void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager)
{
const QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> updateTextureProperties = std::move(m_updatedTextureProperties);
for (const auto &pair : updateTextureProperties) {
const Qt3DCore::QNodeIdVector targetIds = pair.second;
- for (const Qt3DCore::QNodeId targetId: targetIds) {
-
+ for (const Qt3DCore::QNodeId &targetId: targetIds) {
// Lookup texture
Texture *t = m_nodesManager->textureManager()->lookupResource(targetId);
// If backend texture is Dirty, some property has changed and the properties we are
@@ -1226,17 +1205,24 @@ void Renderer::sendSetFenceHandlesToFrontend()
}
}
-// Executed in a job
-void Renderer::sendDisablesToFrontend()
+// Executed in a job (in main thread when jobs done)
+void Renderer::sendDisablesToFrontend(Qt3DCore::QAspectManager *manager)
{
- const auto updatedDisables = std::move(m_updatedDisables);
- FrameGraphManager *fgManager = m_nodesManager->frameGraphManager();
+ // SubtreeEnabled
+ const auto updatedDisables = std::move(m_updatedDisableSubtreeEnablers);
for (const auto &nodeId : updatedDisables) {
- FrameGraphNode *fgNode = fgManager->lookupNode(nodeId);
- if (fgNode != nullptr) { // Node could have been deleted before we got a chance to notify it
- Q_ASSERT(fgNode->nodeType() == FrameGraphNode::SubtreeEnabler);
- SubtreeEnabler *enabler = static_cast<SubtreeEnabler *>(fgNode);
- enabler->sendDisableToFrontend();
+ QSubtreeEnabler *frontend = static_cast<decltype(frontend)>(manager->lookupNode(nodeId));
+ frontend->setEnabled(false);
+ }
+
+ // Compute Commands
+ const QVector<HComputeCommand> activeCommands = m_nodesManager->computeJobManager()->activeHandles();
+ for (const HComputeCommand &handle :activeCommands) {
+ ComputeCommand *c = m_nodesManager->computeJobManager()->data(handle);
+ if (c->hasReachedFrameCount()) {
+ QComputeCommand *frontend = static_cast<decltype(frontend)>(manager->lookupNode(c->peerId()));
+ frontend->setEnabled(false);
+ c->resetHasReachedFrameCount();
}
}
}
@@ -1355,6 +1341,9 @@ void Renderer::updateGLResources()
// Record ids of texture to cleanup while we are still blocking the aspect thread
m_textureIdsToCleanup += m_nodesManager->textureManager()->takeTexturesIdsToCleanup();
}
+
+ // Record list of buffer that might need uploading
+ lookForDownloadableBuffers();
}
// Render Thread
@@ -1437,12 +1426,18 @@ void Renderer::cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId)
// Called by SubmitRenderView
void Renderer::downloadGLBuffers()
{
- lookForDownloadableBuffers();
- const QVector<HBuffer> downloadableHandles = std::move(m_downloadableBuffers);
- for (const HBuffer &handle : downloadableHandles) {
- Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- QByteArray content = m_submissionContext->downloadBufferContent(buffer);
- m_sendBufferCaptureJob->addRequest(QPair<Buffer*, QByteArray>(buffer, content));
+ const QVector<Qt3DCore::QNodeId> downloadableHandles = std::move(m_downloadableBuffers);
+ for (const Qt3DCore::QNodeId &bufferId : downloadableHandles) {
+ BufferManager *bufferManager = m_nodesManager->bufferManager();
+ BufferManager::ReadLocker locker(const_cast<const BufferManager *>(bufferManager));
+ Buffer *buffer = bufferManager->lookupResource(bufferId);
+ // Buffer could have been destroyed at this point
+ if (!buffer)
+ continue;
+ // locker is protecting us from the buffer being destroy while we're looking
+ // up its content
+ const QByteArray content = m_submissionContext->downloadBufferContent(buffer);
+ m_sendBufferCaptureJob->addRequest(QPair<Qt3DCore::QNodeId, QByteArray>(bufferId, content));
}
}
@@ -1606,7 +1601,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
}
// Set the Viewport
- m_submissionContext->setViewport(renderView->viewport(), renderView->surfaceSize() * renderView->devicePixelRatio());
+ m_submissionContext->setViewport(renderView->viewport(), renderView->surfaceSize());
// Execute the render commands
if (!executeCommandsSubmission(renderView))
@@ -1617,7 +1612,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// renderViewStateSet or m_defaultRenderStateSet)
if (!renderView->renderCaptureNodeId().isNull()) {
const QRenderCaptureRequest request = renderView->renderCaptureRequest();
- const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize() * renderView->devicePixelRatio());
+ const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize());
QRect rect(QPoint(0, 0), size);
if (!request.rect.isEmpty())
rect = rect.intersected(request.rect);
@@ -1632,7 +1627,8 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
Render::RenderCapture *renderCapture =
static_cast<Render::RenderCapture*>(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId()));
renderCapture->addRenderCapture(request.captureId, image);
- addRenderCaptureSendRequest(renderView->renderCaptureNodeId());
+ if (!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId()))
+ m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId());
}
if (renderView->isDownloadBuffersEnable())
@@ -1688,7 +1684,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node)
{
- Q_UNUSED(node);
+ Q_UNUSED(node)
m_dirtyBits.marked |= changes;
}
@@ -1705,12 +1701,11 @@ void Renderer::clearDirtyBits(BackendNodeDirtySet changes)
}
#endif
-bool Renderer::shouldRender()
+bool Renderer::shouldRender() const
{
// Only render if something changed during the last frame, or the last frame
// was not rendered successfully (or render-on-demand is disabled)
return (m_settings->renderPolicy() == QRenderSettings::Always
- || m_renderThread == nullptr // <==> we use Scene3D
|| m_dirtyBits.marked != 0
|| m_dirtyBits.remaining != 0
|| !m_lastFrameCorrect.loadRelaxed());
@@ -1725,24 +1720,34 @@ void Renderer::skipNextFrame()
m_submitRenderViewsSemaphore.release(1);
}
-// Jobs we may have to run even if no rendering will happen
-QVector<QAspectJobPtr> Renderer::preRenderingJobs()
+void Renderer::jobsDone(Qt3DCore::QAspectManager *manager)
{
- QVector<QAspectJobPtr> jobs;
+ // called in main thread once all jobs are done running
+
+ // sync captured renders to frontend
+ const QVector<Qt3DCore::QNodeId> pendingCaptureIds = std::move(m_pendingRenderCaptureSendRequests);
+ for (const Qt3DCore::QNodeId &id : qAsConst(pendingCaptureIds)) {
+ auto *backend = static_cast<Qt3DRender::Render::RenderCapture *>
+ (m_nodesManager->frameGraphManager()->lookupNode(id));
+ backend->syncRenderCapturesToFrontend(manager);
+ }
// Do we need to notify any texture about property changes?
if (m_updatedTextureProperties.size() > 0)
- jobs.push_back(m_sendTextureChangesToFrontendJob);
+ sendTextureChangesToFrontend(manager);
+
+ sendDisablesToFrontend(manager);
+}
+
+// Jobs we may have to run even if no rendering will happen
+QVector<QAspectJobPtr> Renderer::preRenderingJobs()
+{
+ QVector<QAspectJobPtr> jobs;
// Do we need to notify frontend about fence change?
if (m_updatedSetFences.size() > 0)
jobs.push_back(m_sendSetFenceHandlesToFrontendJob);
- const QVector<Qt3DCore::QNodeId> pendingCaptureIds = takePendingRenderCaptureSendRequests();
- if (pendingCaptureIds.size() > 0) {
- m_sendRenderCaptureJob->setPendingCaptureRequests(pendingCaptureIds);
- jobs.push_back(m_sendRenderCaptureJob);
- }
if (m_sendBufferCaptureJob->hasRequests())
jobs.push_back(m_sendBufferCaptureJob);
@@ -1759,7 +1764,6 @@ QVector<QAspectJobPtr> Renderer::preRenderingJobs()
QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
{
QVector<QAspectJobPtr> renderBinJobs;
-
// Create the jobs to build the frame
const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
@@ -1774,9 +1778,9 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
- m_dirtyBits.marked = 0;
- m_dirtyBits.remaining = 0;
- BackendNodeDirtySet notCleared = 0;
+ m_dirtyBits.marked = {};
+ m_dirtyBits.remaining = {};
+ BackendNodeDirtySet notCleared = {};
// Add jobs
const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
@@ -1810,7 +1814,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
renderBinJobs.push_back(m_updateSkinningPaletteJob);
renderBinJobs.push_back(m_updateLevelOfDetailJob);
renderBinJobs.push_back(m_cleanupJob);
-
renderBinJobs.append(bufferJobs);
// Jobs to prepare GL Resource upload
@@ -1834,11 +1837,27 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
const bool computeableDirty = dirtyBitsForFrame & AbstractRenderer::ComputeDirty;
const bool renderableDirty = dirtyBitsForFrame & AbstractRenderer::GeometryDirty;
const bool materialCacheNeedsToBeRebuilt = shadersDirty || materialDirty || frameGraphDirty;
+ const bool renderCommandsDirty = materialCacheNeedsToBeRebuilt || renderableDirty || computeableDirty;
// Rebuild Entity Layers list if layers are dirty
if (layersDirty)
renderBinJobs.push_back(m_updateEntityLayersJob);
+ if (renderableDirty) {
+ renderBinJobs.push_back(m_renderableEntityFilterJob);
+ renderBinJobs.push_back(m_cacheRenderableEntitiesJob);
+ }
+
+ if (computeableDirty) {
+ renderBinJobs.push_back(m_computableEntityFilterJob);
+ renderBinJobs.push_back(m_cacheComputableEntitiesJob);
+ }
+
+ if (lightsDirty) {
+ renderBinJobs.push_back(m_lightGathererJob);
+ renderBinJobs.push_back(m_cacheLightsJob);
+ }
+
QMutexLocker lock(m_renderQueue->mutex());
if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case)
// Traverse the current framegraph. For each leaf node create a
@@ -1859,20 +1878,18 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Handle single shot subtree enablers
const auto subtreeEnablers = visitor.takeEnablersToDisable();
for (auto *node : subtreeEnablers)
- m_updatedDisables.push_back(node->peerId());
- if (m_updatedDisables.size() > 0)
- renderBinJobs.push_back(m_sendDisablesToFrontendJob);
+ m_updatedDisableSubtreeEnablers.push_back(node->peerId());
}
const int fgBranchCount = m_frameGraphLeaves.size();
for (int i = 0; i < fgBranchCount; ++i) {
- RenderViewBuilder builder(m_frameGraphLeaves.at(i), i, this);
- builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt);
- builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty);
- builder.setComputableCacheNeedsToBeRebuilt(computeableDirty);
- builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty);
- builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt);
- builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty);
+ FrameGraphNode *leaf = m_frameGraphLeaves.at(i);
+ RenderViewBuilder builder(leaf, i, this);
+ // If we have a new RV (wasn't in the cache before, then it contains no cached data)
+ const bool isNewRV = !m_cache.leafNodeCache.contains(leaf);
+ builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt || isNewRV);
+ builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt || isNewRV);
+ builder.setRenderCommandCacheNeedsToBeRebuilt(renderCommandsDirty || isNewRV);
builder.prepareJobs();
renderBinJobs.append(builder.buildJobHierachy());
@@ -2075,7 +2092,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
bool allCommandsIssued = true;
// Render drawing commands
- const QVector<RenderCommand *> commands = rv->commands();
+ QVector<RenderCommand> commands = rv->commands();
// Use the graphicscontext to submit the commands to the underlying
// graphics API (OpenGL)
@@ -2084,18 +2101,18 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
RenderStateSet *globalState = m_submissionContext->currentStateSet();
OpenGLVertexArrayObject *vao = nullptr;
- for (RenderCommand *command : qAsConst(commands)) {
+ for (RenderCommand &command : commands) {
- if (command->m_type == RenderCommand::Compute) { // Compute Call
- performCompute(rv, command);
+ if (command.m_type == RenderCommand::Compute) { // Compute Call
+ performCompute(rv, &command);
} else { // Draw Command
// Check if we have a valid command that can be drawn
- if (!command->m_isValid) {
+ if (!command.m_isValid) {
allCommandsIssued = false;
continue;
}
- vao = m_nodesManager->vaoManager()->data(command->m_vao);
+ vao = m_nodesManager->vaoManager()->data(command.m_vao);
// something may have went wrong when initializing the VAO
if (!vao->isSpecified()) {
@@ -2106,7 +2123,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
{
Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate);
//// We activate the shader here
- if (!m_submissionContext->activateShader(command->m_shaderDna)) {
+ if (!m_submissionContext->activateShader(command.m_shaderDna)) {
allCommandsIssued = false;
continue;
}
@@ -2121,7 +2138,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
{
Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate);
//// Update program uniforms
- if (!m_submissionContext->setParameters(command->m_parameterPack)) {
+ if (!m_submissionContext->setParameters(command.m_parameterPack)) {
allCommandsIssued = false;
// If we have failed to set uniform (e.g unable to bind a texture)
// we won't perform the draw call which could show invalid content
@@ -2132,7 +2149,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
//// OpenGL State
// TO DO: Make states not dependendent on their backend node for this step
// Set state
- RenderStateSet *localState = command->m_stateSet;
+ RenderStateSet *localState = command.m_stateSet.data();
{
@@ -2140,8 +2157,8 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
// Merge the RenderCommand state with the globalState of the RenderView
// Or restore the globalState if no stateSet for the RenderCommand
if (localState != nullptr) {
- command->m_stateSet->merge(globalState);
- m_submissionContext->setCurrentStateSet(command->m_stateSet);
+ command.m_stateSet->merge(globalState);
+ m_submissionContext->setCurrentStateSet(localState);
} else {
m_submissionContext->setCurrentStateSet(globalState);
}
@@ -2151,7 +2168,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
// at that point
//// Draw Calls
- performDraw(command);
+ performDraw(&command);
}
} // end of RenderCommands loop
@@ -2167,7 +2184,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
}
bool Renderer::updateVAOWithAttributes(Geometry *geometry,
- RenderCommand *command,
+ const RenderCommand *command,
Shader *shader,
bool forceUpdate)
{
@@ -2227,7 +2244,7 @@ bool Renderer::updateVAOWithAttributes(Geometry *geometry,
}
bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry,
- RenderCommand *command) const
+ const RenderCommand *command) const
{
const auto attributeIds = geometry->attributes();
@@ -2295,17 +2312,6 @@ SubmissionContext *Renderer::submissionContext() const
return m_submissionContext.data();
}
-void Renderer::addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId)
-{
- if (!m_pendingRenderCaptureSendRequests.contains(nodeId))
- m_pendingRenderCaptureSendRequests.push_back(nodeId);
-}
-
-const QVector<Qt3DCore::QNodeId> Renderer::takePendingRenderCaptureSendRequests()
-{
- return std::move(m_pendingRenderCaptureSendRequests);
-}
-
// Returns a vector of jobs to be performed for dirty buffers
// 1 dirty buffer == 1 job, all job can be performed in parallel
QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBufferJobs() const
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index b1cd4aac5..e770b8280 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -71,7 +71,6 @@
#include <Qt3DRender/private/updateworldboundingvolumejob_p.h>
#include <Qt3DRender/private/updatetreeenabledjob_p.h>
#include <Qt3DRender/private/platformsurfacefilter_p.h>
-#include <Qt3DRender/private/sendrendercapturejob_p.h>
#include <Qt3DRender/private/sendbuffercapturejob_p.h>
#include <Qt3DRender/private/genericlambdajob_p.h>
#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h>
@@ -82,6 +81,7 @@
#include <Qt3DRender/private/texture_p.h>
#include <Qt3DRender/private/glfence_p.h>
#include <Qt3DRender/private/shaderbuilder_p.h>
+#include <Qt3DRender/private/lightgatherer_p.h>
#include <QHash>
#include <QMatrix4x4>
@@ -125,11 +125,9 @@ class QAbstractShapeMesh;
struct GraphicsApiFilterData;
class QSceneImporter;
-#if QT_CONFIG(qt3d_profile_jobs)
namespace Debug {
class CommandExecuter;
}
-#endif
namespace Render {
@@ -158,6 +156,13 @@ typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr;
using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>;
+template<typename T, typename ... Ts>
+class FilterEntityByComponentJob;
+template<typename T, typename ... Ts>
+using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>;
+using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
+using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
+
class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer
{
public:
@@ -199,8 +204,9 @@ public:
#if defined(QT_BUILD_INTERNAL)
void clearDirtyBits(BackendNodeDirtySet changes) override;
#endif
- bool shouldRender() override;
+ bool shouldRender() const override;
void skipNextFrame() override;
+ void jobsDone(Qt3DCore::QAspectManager *manager) override;
QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override;
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
@@ -225,8 +231,13 @@ public:
inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; }
inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; }
inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; }
- inline Qt3DCore::QAspectJobPtr sendTextureChangesToFrontendJob() const { return m_sendTextureChangesToFrontendJob; }
inline UpdateEntityLayersJobPtr updateEntityLayersJob() const { return m_updateEntityLayersJob; }
+ inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; }
+ inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; }
+ inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; }
+ inline SynchronizerJobPtr cacheLightJob() const { return m_cacheLightsJob; }
+ inline SynchronizerJobPtr cacheRenderableEntitiesJob() const { return m_cacheRenderableEntitiesJob; }
+ inline SynchronizerJobPtr cacheComputableEntitiesJob() const { return m_cacheComputableEntitiesJob; }
Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
@@ -254,12 +265,12 @@ public:
void prepareCommandsSubmission(const QVector<RenderView *> &renderViews);
bool executeCommandsSubmission(const RenderView *rv);
bool updateVAOWithAttributes(Geometry *geometry,
- RenderCommand *command,
+ const RenderCommand *command,
Shader *shader,
bool forceUpdate);
bool requiresVAOAttributeUpdate(Geometry *geometry,
- RenderCommand *command) const;
+ const RenderCommand *command) const;
void setOpenGLContext(QOpenGLContext *context) override;
const GraphicsApiFilterData *contextInfo() const;
@@ -270,9 +281,6 @@ public:
QList<QPair<QObject*, QMouseEvent>> pendingPickingEvents() const;
QList<QKeyEvent> pendingKeyEvents() const;
- void addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId);
- const QVector<Qt3DCore::QNodeId> takePendingRenderCaptureSendRequests();
-
void enqueueRenderView(RenderView *renderView, int submitOrder);
bool isReadyToSubmit();
@@ -338,8 +346,8 @@ private:
QAtomicInt m_exposed;
struct DirtyBits {
- BackendNodeDirtySet marked = 0; // marked dirty since last job build
- BackendNodeDirtySet remaining = 0; // remaining dirty after jobs have finished
+ BackendNodeDirtySet marked; // marked dirty since last job build
+ BackendNodeDirtySet remaining; // remaining dirty after jobs have finished
};
DirtyBits m_dirtyBits;
@@ -362,13 +370,15 @@ private:
CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob;
UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob;
UpdateTreeEnabledJobPtr m_updateTreeEnabledJob;
- SendRenderCaptureJobPtr m_sendRenderCaptureJob;
SendBufferCaptureJobPtr m_sendBufferCaptureJob;
UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob;
UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob;
UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob;
FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
UpdateEntityLayersJobPtr m_updateEntityLayersJob;
+ LightGathererPtr m_lightGathererJob;
+ RenderableEntityFilterPtr m_renderableEntityFilterJob;
+ ComputableEntityFilterPtr m_computableEntityFilterJob;
QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests;
@@ -381,11 +391,12 @@ private:
SynchronizerJobPtr m_bufferGathererJob;
SynchronizerJobPtr m_vaoGathererJob;
SynchronizerJobPtr m_textureGathererJob;
- SynchronizerPostFramePtr m_sendTextureChangesToFrontendJob;
SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob;
- SynchronizerJobPtr m_sendDisablesToFrontendJob;
SynchronizerPostFramePtr m_introspectShaderJob;
SynchronizerJobPtr m_syncLoadingJobs;
+ SynchronizerJobPtr m_cacheRenderableEntitiesJob;
+ SynchronizerJobPtr m_cacheComputableEntitiesJob;
+ SynchronizerJobPtr m_cacheLightsJob;
void lookForAbandonedVaos();
void lookForDirtyBuffers();
@@ -395,18 +406,18 @@ private:
void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager);
void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager);
void sendSetFenceHandlesToFrontend();
- void sendDisablesToFrontend();
+ void sendDisablesToFrontend(Qt3DCore::QAspectManager *manager);
QMutex m_abandonedVaosMutex;
QVector<HVao> m_abandonedVaos;
QVector<HBuffer> m_dirtyBuffers;
- QVector<HBuffer> m_downloadableBuffers;
+ QVector<Qt3DCore::QNodeId> m_downloadableBuffers;
QVector<HShader> m_dirtyShaders;
QVector<HTexture> m_dirtyTextures;
QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties;
QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences;
- QVector<Qt3DCore::QNodeId> m_updatedDisables;
+ QVector<Qt3DCore::QNodeId> m_updatedDisableSubtreeEnablers;
Qt3DCore::QNodeIdVector m_textureIdsToCleanup;
QVector<ShaderBuilderUpdate> m_shaderBuilderUpdates;
@@ -415,10 +426,7 @@ private:
OffscreenSurfaceHelper *m_offscreenHelper;
QMutex m_offscreenSurfaceMutex;
-#if QT_CONFIG(qt3d_profile_jobs)
QScopedPointer<Qt3DRender::Debug::CommandExecuter> m_commandExecuter;
- friend class Qt3DRender::Debug::CommandExecuter;
-#endif
#ifdef QT_BUILD_INTERNAL
friend class ::tst_Renderer;
diff --git a/src/render/renderers/opengl/renderer/renderercache_p.h b/src/render/renderers/opengl/renderer/renderercache_p.h
index 0e9c5d3cd..02fe4ff41 100644
--- a/src/render/renderers/opengl/renderer/renderercache_p.h
+++ b/src/render/renderers/opengl/renderer/renderercache_p.h
@@ -56,6 +56,7 @@
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/renderviewjobutils_p.h>
#include <Qt3DRender/private/lightsource_p.h>
+#include <Qt3DRender/private/rendercommand_p.h>
QT_BEGIN_NAMESPACE
@@ -69,12 +70,16 @@ struct RendererCache
{
QVector<Entity *> filterEntitiesByLayer;
MaterialParameterGathererData materialParameterGatherer;
- QVector<LightSource> gatheredLights;
- QVector<Entity *> renderableEntities;
- QVector<Entity *> computeEntities;
- EnvironmentLight* environmentLight;
+ EntityRenderCommandData renderCommandData;
};
+ // Shared amongst all RV cache
+ QVector<Entity *> renderableEntities;
+ QVector<Entity *> computeEntities;
+ QVector<LightSource> gatheredLights;
+ EnvironmentLight* environmentLight;
+
+ // Per RV cache
QHash<FrameGraphNode *, LeafNodeData> leafNodeCache;
QMutex *mutex() { return &m_mutex; }
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index aa9f4d1a5..c00a92629 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -119,29 +119,29 @@ RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniform
{
RenderView::StandardUniformsNameToTypeHash setters;
- setters.insert(StringToInt::lookupId(QLatin1String("modelMatrix")), ModelMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewMatrix")), ViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("projectionMatrix")), ProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelView")), ModelViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewProjectionMatrix")), ViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelViewProjection")), ModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("mvp")), ModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelMatrix")), InverseModelMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewMatrix")), InverseViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")), InverseProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelView")), InverseModelViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")), InverseViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelViewProjection")), InverseModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelNormalMatrix")), ModelNormalMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio);
- setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure);
- setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma);
- setters.insert(StringToInt::lookupId(QLatin1String("time")), Time);
- setters.insert(StringToInt::lookupId(QLatin1String("eyePosition")), EyePosition);
- setters.insert(StringToInt::lookupId(QLatin1String("skinningPalette[0]")), SkinningPalette);
+ setters.insert(Shader::modelMatrixNameId, ModelMatrix);
+ setters.insert(Shader::viewMatrixNameId, ViewMatrix);
+ setters.insert(Shader::projectionMatrixNameId, ProjectionMatrix);
+ setters.insert(Shader::modelViewMatrixNameId, ModelViewMatrix);
+ setters.insert(Shader::viewProjectionMatrixNameId, ViewProjectionMatrix);
+ setters.insert(Shader::modelViewProjectionNameId, ModelViewProjectionMatrix);
+ setters.insert(Shader::mvpNameId, ModelViewProjectionMatrix);
+ setters.insert(Shader::inverseModelMatrixNameId, InverseModelMatrix);
+ setters.insert(Shader::inverseViewMatrixNameId, InverseViewMatrix);
+ setters.insert(Shader::inverseProjectionMatrixNameId, InverseProjectionMatrix);
+ setters.insert(Shader::inverseModelViewNameId, InverseModelViewMatrix);
+ setters.insert(Shader::inverseViewProjectionMatrixNameId, InverseViewProjectionMatrix);
+ setters.insert(Shader::inverseModelViewProjectionNameId, InverseModelViewProjectionMatrix);
+ setters.insert(Shader::modelNormalMatrixNameId, ModelNormalMatrix);
+ setters.insert(Shader::modelViewNormalNameId, ModelViewNormalMatrix);
+ setters.insert(Shader::viewportMatrixNameId, ViewportMatrix);
+ setters.insert(Shader::inverseViewportMatrixNameId, InverseViewportMatrix);
+ setters.insert(Shader::aspectRatioNameId, AspectRatio);
+ setters.insert(Shader::exposureNameId, Exposure);
+ setters.insert(Shader::gammaNameId, Gamma);
+ setters.insert(Shader::timeNameId, Time);
+ setters.insert(Shader::eyePositionNameId, EyePosition);
+ setters.insert(Shader::skinningPaletteNameId, SkinningPalette);
return setters;
}
@@ -211,7 +211,7 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa
return UniformValue(Matrix4x4(viewportMatrix.inverted()));
}
case AspectRatio:
- return float(m_surfaceSize.width()) / float(m_surfaceSize.height());
+ return float(m_surfaceSize.width()) / std::max(1.f, float(m_surfaceSize.height()));
case Exposure:
return UniformValue(m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f);
case Gamma:
@@ -238,11 +238,14 @@ RenderView::RenderView()
: m_isDownloadBuffersEnable(false)
, m_hasBlitFramebufferInfo(false)
, m_renderer(nullptr)
+ , m_manager(nullptr)
, m_devicePixelRatio(1.)
- , m_viewport(QRectF(0.0f, 0.0f, 1.0f, 1.0f))
+ , m_viewport(QRectF(0., 0., 1., 1.))
, m_gamma(2.2f)
, m_surface(nullptr)
, m_clearBuffer(QClearBuffers::None)
+ , m_clearDepthValue(1.f)
+ , m_clearStencilValue(0)
, m_stateSet(nullptr)
, m_noDraw(false)
, m_compute(false)
@@ -280,10 +283,6 @@ RenderView::RenderView()
RenderView::~RenderView()
{
delete m_stateSet;
- for (RenderCommand *command : qAsConst(m_commands)) {
- delete command->m_stateSet;
- delete command;
- }
}
namespace {
@@ -291,7 +290,7 @@ namespace {
template<int SortType>
struct AdjacentSubRangeFinder
{
- static bool adjacentSubRange(RenderCommand *, RenderCommand *)
+ static bool adjacentSubRange(const RenderCommand &, const RenderCommand &)
{
Q_UNREACHABLE();
return false;
@@ -301,47 +300,47 @@ struct AdjacentSubRangeFinder
template<>
struct AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>
{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b)
{
- return a->m_changeCost == b->m_changeCost;
+ return a.m_changeCost == b.m_changeCost;
}
};
template<>
struct AdjacentSubRangeFinder<QSortPolicy::BackToFront>
{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b)
{
- return a->m_depth == b->m_depth;
+ return a.m_depth == b.m_depth;
}
};
template<>
struct AdjacentSubRangeFinder<QSortPolicy::Material>
{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b)
{
- return a->m_shaderDna == b->m_shaderDna;
+ return a.m_shaderDna == b.m_shaderDna;
}
};
template<>
struct AdjacentSubRangeFinder<QSortPolicy::FrontToBack>
{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b)
{
- return a->m_depth == b->m_depth;
+ return a.m_depth == b.m_depth;
}
};
template<>
struct AdjacentSubRangeFinder<QSortPolicy::Texture>
{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b)
{
// Two renderCommands are adjacent if one contains all the other command's textures
- QVector<ShaderParameterPack::NamedResource> texturesA = a->m_parameterPack.textures();
- QVector<ShaderParameterPack::NamedResource> texturesB = b->m_parameterPack.textures();
+ QVector<ShaderParameterPack::NamedResource> texturesA = a.m_parameterPack.textures();
+ QVector<ShaderParameterPack::NamedResource> texturesB = b.m_parameterPack.textures();
if (texturesB.size() > texturesA.size())
qSwap(texturesA, texturesB);
@@ -356,7 +355,7 @@ struct AdjacentSubRangeFinder<QSortPolicy::Texture>
};
template<typename Predicate>
-int advanceUntilNonAdjacent(const QVector<RenderCommand *> &commands,
+int advanceUntilNonAdjacent(const QVector<RenderCommand> &commands,
const int beg, const int end, Predicate pred)
{
int i = beg + 1;
@@ -369,7 +368,7 @@ int advanceUntilNonAdjacent(const QVector<RenderCommand *> &commands,
}
-using CommandIt = QVector<RenderCommand *>::iterator;
+using CommandIt = QVector<RenderCommand>::iterator;
template<int SortType>
struct SubRangeSorter
@@ -387,8 +386,8 @@ struct SubRangeSorter<QSortPolicy::StateChangeCost>
{
static void sortSubRange(CommandIt begin, const CommandIt end)
{
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_changeCost > b->m_changeCost;
+ std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
+ return a.m_changeCost > b.m_changeCost;
});
}
};
@@ -398,8 +397,8 @@ struct SubRangeSorter<QSortPolicy::BackToFront>
{
static void sortSubRange(CommandIt begin, const CommandIt end)
{
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_depth > b->m_depth;
+ std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
+ return a.m_depth > b.m_depth;
});
}
};
@@ -410,8 +409,8 @@ struct SubRangeSorter<QSortPolicy::Material>
static void sortSubRange(CommandIt begin, const CommandIt end)
{
// First we sort by shaderDNA
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_shaderDna > b->m_shaderDna;
+ std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
+ return a.m_shaderDna > b.m_shaderDna;
});
}
};
@@ -421,8 +420,8 @@ struct SubRangeSorter<QSortPolicy::FrontToBack>
{
static void sortSubRange(CommandIt begin, const CommandIt end)
{
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_depth < b->m_depth;
+ std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
+ return a.m_depth < b.m_depth;
});
}
};
@@ -432,9 +431,9 @@ struct SubRangeSorter<QSortPolicy::Texture>
{
static void sortSubRange(CommandIt begin, const CommandIt end)
{
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- QVector<ShaderParameterPack::NamedResource> texturesA = a->m_parameterPack.textures();
- QVector<ShaderParameterPack::NamedResource> texturesB = b->m_parameterPack.textures();
+ std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
+ QVector<ShaderParameterPack::NamedResource> texturesA = a.m_parameterPack.textures();
+ QVector<ShaderParameterPack::NamedResource> texturesB = b.m_parameterPack.textures();
const int originalTextureASize = texturesA.size();
@@ -453,7 +452,7 @@ struct SubRangeSorter<QSortPolicy::Texture>
}
};
-int findSubRange(const QVector<RenderCommand *> &commands,
+int findSubRange(const QVector<RenderCommand> &commands,
const int begin, const int end,
const QSortPolicy::SortType sortType)
{
@@ -474,14 +473,14 @@ int findSubRange(const QVector<RenderCommand *> &commands,
}
}
-void sortByMaterial(QVector<RenderCommand *> &commands, int begin, const int end)
+void sortByMaterial(QVector<RenderCommand> &commands, int begin, const int end)
{
// We try to arrange elements so that their rendering cost is minimized for a given shader
int rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
while (begin != end) {
if (begin + 1 < rangeEnd) {
- std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (RenderCommand *a, RenderCommand *b){
- return a->m_material.handle() < b->m_material.handle();
+ std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (const RenderCommand &a, const RenderCommand &b){
+ return a.m_material.handle() < b.m_material.handle();
});
}
begin = rangeEnd;
@@ -489,7 +488,7 @@ void sortByMaterial(QVector<RenderCommand *> &commands, int begin, const int end
}
}
-void sortCommandRange(QVector<RenderCommand *> &commands, int begin, const int end, const int level,
+void sortCommandRange(QVector<RenderCommand> &commands, int begin, const int end, const int level,
const QVector<Qt3DRender::QSortPolicy::SortType> &sortingTypes)
{
if (level >= sortingTypes.size())
@@ -539,24 +538,23 @@ void RenderView::sort()
// Minimize uniform changes
int i = 0;
- while (i < m_commands.size()) {
+ const int commandSize = m_commands.size();
+ while (i < commandSize) {
int j = i;
// Advance while commands share the same shader
- while (i < m_commands.size() && m_commands[j]->m_shaderDna == m_commands[i]->m_shaderDna)
+ while (i < commandSize && m_commands[j].m_shaderDna == m_commands[i].m_shaderDna)
++i;
if (i - j > 0) { // Several commands have the same shader, so we minimize uniform changes
- PackUniformHash cachedUniforms = m_commands[j++]->m_parameterPack.uniforms();
+ PackUniformHash cachedUniforms = m_commands[j++].m_parameterPack.uniforms();
while (j < i) {
// We need the reference here as we are modifying the original container
// not the copy
- PackUniformHash &uniforms = m_commands.at(j)->m_parameterPack.m_uniforms;
- PackUniformHash::iterator it = uniforms.begin();
- const PackUniformHash::iterator end = uniforms.end();
+ PackUniformHash &uniforms = m_commands[j].m_parameterPack.m_uniforms;
- while (it != end) {
+ for (int u = 0; u < uniforms.keys.size();) {
// We are comparing the values:
// - raw uniform values
// - the texture Node id if the uniform represents a texture
@@ -564,12 +562,17 @@ void RenderView::sort()
// sharing the same material (shader) are rendered, we can't have the case
// where two uniforms, referencing the same texture eventually have 2 different
// texture unit values
- const UniformValue refValue = cachedUniforms.value(it.key());
- if (it.value() == refValue) {
- it = uniforms.erase(it);
+ const int uniformNameId = uniforms.keys.at(u);
+ const UniformValue &refValue = cachedUniforms.value(uniformNameId);
+ const UniformValue &newValue = uniforms.values.at(u);
+ if (newValue == refValue) {
+ uniforms.erase(u);
} else {
- cachedUniforms.insert(it.key(), it.value());
- ++it;
+ // Record updated value so that subsequent comparison
+ // for the next command will be made againts latest
+ // uniform value
+ cachedUniforms.insert(uniformNameId, newValue);
+ ++u;
}
}
++j;
@@ -619,20 +622,16 @@ void RenderView::addClearBuffers(const ClearBuffers *cb) {
}
// If we are there, we know that entity had a GeometryRenderer + Material
-QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities) const
+EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities,
+ int offset, int count) const
{
- // Note: since many threads can be building render commands
- // we need to ensure that the UniformBlockValueBuilder they are using
- // is only accessed from the same thread
- UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
- builder->shaderDataManager = m_manager->shaderDataManager();
- builder->textureManager = m_manager->textureManager();
- m_localData.setLocalData(builder);
+ EntityRenderCommandData commands;
- QVector<RenderCommand *> commands;
- commands.reserve(entities.size());
+ commands.reserve(count);
- for (Entity *entity : entities) {
+ for (int i = 0; i < count; ++i) {
+ const int idx = offset + i;
+ Entity *entity = entities.at(idx);
GeometryRenderer *geometryRenderer = nullptr;
HGeometryRenderer geometryRendererHandle = entity->componentHandle<GeometryRenderer>();
@@ -645,135 +644,226 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
const HMaterial materialHandle = entity->componentHandle<Material>();
const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
+ HGeometry geometryHandle = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId());
+ Geometry *geometry = m_manager->geometryManager()->data(geometryHandle);
+
// 1 RenderCommand per RenderPass pass on an Entity with a Mesh
for (const RenderPassParameterData &passData : renderPassData) {
// Add the RenderPass Parameters
- RenderCommand *command = new RenderCommand();
- command->m_geometryRenderer = geometryRendererHandle;
- command->m_geometry = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId());
-
- // Project the camera-to-object-center vector onto the camera
- // view vector. This gives a depth value suitable as the key
- // for BackToFront sorting.
- command->m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir);
- command->m_material = materialHandle;
+ RenderCommand command = {};
+ command.m_geometryRenderer = geometryRendererHandle;
+ command.m_geometry = geometryHandle;
+
+ command.m_material = materialHandle;
// For RenderPass based states we use the globally set RenderState
// if no renderstates are defined as part of the pass. That means:
// RenderPass { renderStates: [] } will use the states defined by
// StateSet in the FrameGraph
RenderPass *pass = passData.pass;
if (pass->hasRenderStates()) {
- command->m_stateSet = new RenderStateSet();
- addStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
+ command.m_stateSet = RenderStateSetPtr::create();
+ addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager());
if (m_stateSet != nullptr)
- command->m_stateSet->merge(m_stateSet);
- command->m_changeCost = m_renderer->defaultRenderState()->changeCost(command->m_stateSet);
+ command.m_stateSet->merge(m_stateSet);
+ command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data());
}
+ command.m_shader = m_manager->lookupHandle<Shader, ShaderManager, HShader>(pass->shaderProgram());
+
+ { // Scoped to show extent
+
+ // Update the draw command with what's going to be needed for the drawing
+ int primitiveCount = geometryRenderer->vertexCount();
+ int estimatedCount = 0;
+ Attribute *indexAttribute = nullptr;
+ Attribute *indirectAttribute = nullptr;
+
+ const QVector<Qt3DCore::QNodeId> attributeIds = geometry->attributes();
+ for (Qt3DCore::QNodeId attributeId : attributeIds) {
+ Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId);
+ switch (attribute->attributeType()) {
+ case QAttribute::IndexAttribute:
+ indexAttribute = attribute;
+ break;
+ case QAttribute::DrawIndirectAttribute:
+ indirectAttribute = attribute;
+ break;
+ case QAttribute::VertexAttribute:
+ estimatedCount = std::max(int(attribute->count()), estimatedCount);
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ }
- // Pick which lights to take in to account.
- // For now decide based on the distance by taking the MAX_LIGHTS closest lights.
- // Replace with more sophisticated mechanisms later.
- // Copy vector so that we can sort it concurrently and we only want to sort the one for the current command
- QVector<LightSource> lightSources = m_lightSources;
- if (lightSources.size() > 1) {
- const Vector3D entityCenter = entity->worldBoundingVolume()->center();
- std::sort(lightSources.begin(), lightSources.end(),
- [&] (const LightSource &a, const LightSource &b) {
- const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center());
- const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center());
- return distA < distB;
- });
- }
+ command.m_drawIndexed = (indexAttribute != nullptr);
+ command.m_drawIndirect = (indirectAttribute != nullptr);
+
+ // Update the draw command with all the information required for the drawing
+ if (command.m_drawIndexed) {
+ command.m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType());
+ command.m_indexAttributeByteOffset = indexAttribute->byteOffset() + geometryRenderer->indexBufferByteOffset();
+ }
+
+ // Note: we only care about the primitiveCount when using direct draw calls
+ // For indirect draw calls it is assumed the buffer was properly set already
+ if (command.m_drawIndirect) {
+ command.m_indirectAttributeByteOffset = indirectAttribute->byteOffset();
+ command.m_indirectDrawBuffer = m_manager->bufferManager()->lookupHandle(indirectAttribute->bufferId());
+ } else {
+ // Use the count specified by the GeometryRender
+ // If not specify use the indexAttribute count if present
+ // Otherwise tries to use the count from the attribute with the highest count
+ if (primitiveCount == 0) {
+ if (indexAttribute)
+ primitiveCount = indexAttribute->count();
+ else
+ primitiveCount = estimatedCount;
+ }
+ }
- ParameterInfoList globalParameters = passData.parameterInfo;
- // setShaderAndUniforms can initialize a localData
- // make sure this is cleared before we leave this function
- setShaderAndUniforms(command,
- pass,
- globalParameters,
- entity,
- lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)),
- m_environmentLight);
-
- commands.append(command);
+ command.m_primitiveCount = primitiveCount;
+ command.m_primitiveType = geometryRenderer->primitiveType();
+ command.m_primitiveRestartEnabled = geometryRenderer->primitiveRestartEnabled();
+ command.m_restartIndexValue = geometryRenderer->restartIndexValue();
+ command.m_firstInstance = geometryRenderer->firstInstance();
+ command.m_instanceCount = geometryRenderer->instanceCount();
+ command.m_firstVertex = geometryRenderer->firstVertex();
+ command.m_indexOffset = geometryRenderer->indexOffset();
+ command.m_verticesPerPatch = geometryRenderer->verticesPerPatch();
+ } // scope
+
+
+ commands.push_back(entity,
+ std::move(command),
+ std::move(passData));
}
}
}
- // We reset the local data once we are done with it
- m_localData.setLocalData(nullptr);
-
return commands;
}
-QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities) const
+EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities,
+ int offset, int count) const
{
- // Note: since many threads can be building render commands
- // we need to ensure that the UniformBlockValueBuilder they are using
- // is only accessed from the same thread
- UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
- builder->shaderDataManager = m_manager->shaderDataManager();
- builder->textureManager = m_manager->textureManager();
- m_localData.setLocalData(builder);
-
// If the RenderView contains only a ComputeDispatch then it cares about
// A ComputeDispatch is also implicitely a NoDraw operation
// enabled flag
// layer component
// material/effect/technique/parameters/filters/
- QVector<RenderCommand *> commands;
- commands.reserve(entities.size());
- for (Entity *entity : entities) {
+ EntityRenderCommandData commands;
+
+ commands.reserve(count);
+
+ for (int i = 0; i < count; ++i) {
+ const int idx = offset + i;
+ Entity *entity = entities.at(idx);
ComputeCommand *computeJob = nullptr;
- if ((computeJob = entity->renderComponent<ComputeCommand>()) != nullptr
+ HComputeCommand computeCommandHandle = entity->componentHandle<ComputeCommand>();
+ if ((computeJob = nodeManagers()->computeJobManager()->data(computeCommandHandle)) != nullptr
&& computeJob->isEnabled()) {
- // Note: if frameCount has reached 0 in the previous frame, isEnabled
- // would be false
- if (computeJob->runType() == QComputeCommand::Manual)
- computeJob->updateFrameCount();
-
const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>();
const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
// 1 RenderCommand per RenderPass pass on an Entity with a Mesh
for (const RenderPassParameterData &passData : renderPassData) {
// Add the RenderPass Parameters
- RenderCommand *command = new RenderCommand();
+ RenderCommand command = {};
RenderPass *pass = passData.pass;
if (pass->hasRenderStates()) {
- command->m_stateSet = new RenderStateSet();
- addStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
+ command.m_stateSet = RenderStateSetPtr::create();
+ addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager());
// Merge per pass stateset with global stateset
// so that the local stateset only overrides
if (m_stateSet != nullptr)
- command->m_stateSet->merge(m_stateSet);
- command->m_changeCost = m_renderer->defaultRenderState()->changeCost(command->m_stateSet);
+ command.m_stateSet->merge(m_stateSet);
+ command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data());
}
+ command.m_shader = m_manager->lookupHandle<Shader, ShaderManager, HShader>(pass->shaderProgram());
+ command.m_computeCommand = computeCommandHandle;
+ command.m_type = RenderCommand::Compute;
+ command.m_workGroups[0] = std::max(m_workGroups[0], computeJob->x());
+ command.m_workGroups[1] = std::max(m_workGroups[1], computeJob->y());
+ command.m_workGroups[2] = std::max(m_workGroups[2], computeJob->z());
+
+ commands.push_back(entity,
+ std::move(command),
+ std::move(passData));
+ }
+ }
+ }
- command->m_type = RenderCommand::Compute;
- command->m_workGroups[0] = std::max(m_workGroups[0], computeJob->x());
- command->m_workGroups[1] = std::max(m_workGroups[1], computeJob->y());
- command->m_workGroups[2] = std::max(m_workGroups[2], computeJob->z());
-
- ParameterInfoList globalParameters = passData.parameterInfo;
- setShaderAndUniforms(command,
- pass,
- globalParameters,
- entity,
- QVector<LightSource>(),
- nullptr);
- commands.append(command);
+ return commands;
+}
+
+void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData,
+ int offset,
+ int count)
+{
+ // Note: since many threads can be building render commands
+ // we need to ensure that the UniformBlockValueBuilder they are using
+ // is only accessed from the same thread
+ UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
+ builder->shaderDataManager = m_manager->shaderDataManager();
+ builder->textureManager = m_manager->textureManager();
+ m_localData.setLocalData(builder);
+
+ for (int i = 0, m = count; i < m; ++i) {
+ const int idx = offset + i;
+ Entity *entity = renderCommandData->entities.at(idx);
+ const RenderPassParameterData passData = renderCommandData->passesData.at(idx);
+ RenderCommand &command = renderCommandData->commands[idx];
+
+ // Pick which lights to take in to account.
+ // For now decide based on the distance by taking the MAX_LIGHTS closest lights.
+ // Replace with more sophisticated mechanisms later.
+ // Copy vector so that we can sort it concurrently and we only want to sort the one for the current command
+ QVector<LightSource> lightSources;
+ EnvironmentLight *environmentLight = nullptr;
+
+ if (command.m_type == RenderCommand::Draw) {
+ // Project the camera-to-object-center vector onto the camera
+ // view vector. This gives a depth value suitable as the key
+ // for BackToFront sorting.
+ command.m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir);
+
+ environmentLight = m_environmentLight;
+ lightSources = m_lightSources;
+
+ if (lightSources.size() > 1) {
+ const Vector3D entityCenter = entity->worldBoundingVolume()->center();
+ std::sort(lightSources.begin(), lightSources.end(),
+ [&] (const LightSource &a, const LightSource &b) {
+ const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center());
+ const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center());
+ return distA < distB;
+ });
}
+ lightSources = lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS));
+ } else { // Compute
+ // Note: if frameCount has reached 0 in the previous frame, isEnabled
+ // would be false
+ ComputeCommand *computeJob = m_manager->computeJobManager()->data(command.m_computeCommand);
+ if (computeJob->runType() == QComputeCommand::Manual)
+ computeJob->updateFrameCount();
}
+
+ ParameterInfoList globalParameters = passData.parameterInfo;
+ // setShaderAndUniforms can initialize a localData
+ // make sure this is cleared before we leave this function
+ setShaderAndUniforms(&command,
+ globalParameters,
+ entity,
+ lightSources,
+ environmentLight);
}
// We reset the local data once we are done with it
m_localData.setLocalData(nullptr);
-
- return commands;
}
void RenderView::updateMatrices()
@@ -908,7 +998,6 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
}
void RenderView::setShaderAndUniforms(RenderCommand *command,
- RenderPass *rPass,
ParameterInfoList &parameters,
Entity *entity,
const QVector<LightSource> &activeLightSources,
@@ -924,163 +1013,163 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
// For each ParameterBinder in the RenderPass -> create a QUniformPack
// Once that works, improve that to try and minimize QUniformPack updates
- if (rPass != nullptr) {
- // Index Shader by Shader UUID
- command->m_shader = m_manager->lookupHandle<Shader, ShaderManager, HShader>(rPass->shaderProgram());
- Shader *shader = m_manager->data<Shader, ShaderManager>(command->m_shader);
- if (shader != nullptr && shader->isLoaded()) {
- command->m_shaderDna = shader->dna();
-
- // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings
- // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name
- // equals to the parameter name
- const QVector<int> uniformNamesIds = shader->uniformsNamesIds();
- const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
- const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
- const QVector<int> attributeNamesIds = shader->attributeNamesIds();
-
- // Set fragData Name and index
- // Later on we might want to relink the shader if attachments have changed
- // But for now we set them once and for all
+ // Index Shader by Shader UUID
+ Shader *shader = m_manager->data<Shader, ShaderManager>(command->m_shader);
+ if (shader != nullptr && shader->isLoaded()) {
+ command->m_shaderDna = shader->dna();
+
+ // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings
+ // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name
+ // equals to the parameter name
+ const QVector<int> uniformNamesIds = shader->uniformsNamesIds();
+ const QVector<int> standardUniformNamesIds = shader->standardUniformNameIds();
+ const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
+ const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
+ const QVector<int> attributeNamesIds = shader->attributeNamesIds();
+
+ // Set fragData Name and index
+ // Later on we might want to relink the shader if attachments have changed
+ // But for now we set them once and for all
+ if (!m_renderTarget.isNull() && !shader->isLoaded()) {
QHash<QString, int> fragOutputs;
- if (!m_renderTarget.isNull() && !shader->isLoaded()) {
- const auto atts = m_attachmentPack.attachments();
- for (const Attachment &att : atts) {
- if (att.m_point <= QRenderTargetOutput::Color15)
- fragOutputs.insert(att.m_name, att.m_point);
- }
+ const auto atts = m_attachmentPack.attachments();
+ for (const Attachment &att : atts) {
+ if (att.m_point <= QRenderTargetOutput::Color15)
+ fragOutputs.insert(att.m_name, att.m_point);
}
+ // Set frag outputs in the shaders if hash not empty
+ if (!fragOutputs.isEmpty())
+ shader->setFragOutputs(fragOutputs);
+ }
- if (!uniformNamesIds.isEmpty() || !attributeNamesIds.isEmpty() ||
- !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
-
- // Set default standard uniforms without bindings
- const Matrix4x4 worldTransform = *(entity->worldTransform());
- for (const int uniformNameId : uniformNamesIds) {
- if (ms_standardUniformSetters.contains(uniformNameId))
- setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
- }
-
- // Set default attributes
- for (const int attributeNameId : attributeNamesIds)
- command->m_activeAttributes.push_back(attributeNameId);
-
- // Parameters remaining could be
- // -> uniform scalar / vector
- // -> uniform struct / arrays
- // -> uniform block / array (4.3)
- // -> ssbo block / array (4.3)
-
- ParameterInfoList::const_iterator it = parameters.cbegin();
- const ParameterInfoList::const_iterator parametersEnd = parameters.cend();
-
- while (it != parametersEnd) {
- Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
- const UniformValue &uniformValue = param->uniformValue();
- if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform
- setUniformValue(command->m_parameterPack, it->nameId, uniformValue);
- } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block
- setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue);
- } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
- setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue);
- } else { // Parameter is a struct
- ShaderData *shaderData = nullptr;
- if (uniformValue.valueType() == UniformValue::NodeId &&
- (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
- // Try to check if we have a struct or array matching a QShaderData parameter
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId));
- }
- // Otherwise: param unused by current shader
+ if (!uniformNamesIds.isEmpty() || !standardUniformNamesIds.isEmpty() ||
+ !attributeNamesIds.isEmpty() ||
+ !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
+
+ // Set default standard uniforms without bindings
+ const Matrix4x4 worldTransform = *(entity->worldTransform());
+
+ for (const int uniformNameId : standardUniformNamesIds)
+ setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
+
+ // Set default attributes
+ command->m_activeAttributes = attributeNamesIds;
+
+ // At this point we know whether the command is a valid draw command or not
+ // We still need to process the uniforms as the command could be a compute command
+ command->m_isValid = !command->m_activeAttributes.empty();
+
+ // Parameters remaining could be
+ // -> uniform scalar / vector
+ // -> uniform struct / arrays
+ // -> uniform block / array (4.3)
+ // -> ssbo block / array (4.3)
+
+ ParameterInfoList::const_iterator it = parameters.cbegin();
+ const ParameterInfoList::const_iterator parametersEnd = parameters.cend();
+
+ while (it != parametersEnd) {
+ Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
+ const UniformValue &uniformValue = param->uniformValue();
+ if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform
+ setUniformValue(command->m_parameterPack, it->nameId, uniformValue);
+ } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block
+ setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue);
+ } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
+ setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue);
+ } else { // Parameter is a struct
+ ShaderData *shaderData = nullptr;
+ if (uniformValue.valueType() == UniformValue::NodeId &&
+ (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
+ // Try to check if we have a struct or array matching a QShaderData parameter
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId));
}
- ++it;
+ // Otherwise: param unused by current shader
}
+ ++it;
+ }
- // Lights
-
- int lightIdx = 0;
- for (const LightSource &lightSource : activeLightSources) {
- if (lightIdx == MAX_LIGHTS)
- break;
- Entity *lightEntity = lightSource.entity;
- const Vector3D worldPos = lightEntity->worldBoundingVolume()->center();
- for (Light *light : lightSource.lights) {
- if (!light->isEnabled())
- continue;
-
- ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData());
- if (!shaderData)
- continue;
+ // Lights
- if (lightIdx == MAX_LIGHTS)
- break;
+ int lightIdx = 0;
+ for (const LightSource &lightSource : activeLightSources) {
+ if (lightIdx == MAX_LIGHTS)
+ break;
+ Entity *lightEntity = lightSource.entity;
+ const Matrix4x4 lightWorldTransform = *(lightEntity->worldTransform());
+ const Vector3D worldPos = lightWorldTransform * Vector3D(0.0f, 0.0f, 0.0f);
+ for (Light *light : lightSource.lights) {
+ if (!light->isEnabled())
+ continue;
- // Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
-
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[lightIdx], worldPos);
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[lightIdx], 0.5f);
-
- // There is no risk in doing that even if multithreaded
- // since we are sure that a shaderData is unique for a given light
- // and won't ever be referenced as a Component either
- Matrix4x4 *worldTransform = lightEntity->worldTransform();
- if (worldTransform)
- shaderData->updateWorldTransform(*worldTransform);
-
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]);
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_UNROLL_NAMES[lightIdx]);
- ++lightIdx;
- }
- }
+ ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData());
+ if (!shaderData)
+ continue;
- if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
- setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx)));
+ if (lightIdx == MAX_LIGHTS)
+ break;
- // If no active light sources and no environment light, add a default light
- if (activeLightSources.isEmpty() && !environmentLight) {
// Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f);
-
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[0], 0.5f);
+ setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
+ setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
+
+ setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[lightIdx], worldPos);
+ setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[lightIdx], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[lightIdx], 0.5f);
+
+
+ // There is no risk in doing that even if multithreaded
+ // since we are sure that a shaderData is unique for a given light
+ // and won't ever be referenced as a Component either
+ Matrix4x4 *worldTransform = lightEntity->worldTransform();
+ if (worldTransform)
+ shaderData->updateWorldTransform(*worldTransform);
+
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]);
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_UNROLL_NAMES[lightIdx]);
+ ++lightIdx;
}
+ }
- // Environment Light
- int envLightCount = 0;
- if (environmentLight && environmentLight->isEnabled()) {
- ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData());
- if (shaderData) {
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight"));
- envLightCount = 1;
- }
- } else {
- // with some drivers, samplers (like the envbox sampler) need to be bound even though
- // they may not be actually used, otherwise draw calls can fail
- static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance"));
- static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular"));
- setUniformValue(command->m_parameterPack, irradianceId, m_renderer->submissionContext()->maxTextureUnitsCount());
- setUniformValue(command->m_parameterPack, specularId, m_renderer->submissionContext()->maxTextureUnitsCount());
+ if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
+ setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx)));
+
+ // If no active light sources and no environment light, add a default light
+ if (activeLightSources.isEmpty() && !environmentLight) {
+ // Note: implicit conversion of values to UniformValue
+ setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f);
+
+ setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[0], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[0], 0.5f);
+ }
+
+ // Environment Light
+ int envLightCount = 0;
+ if (environmentLight && environmentLight->isEnabled()) {
+ ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData());
+ if (shaderData) {
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight"));
+ envLightCount = 1;
}
- setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount);
+ } else {
+ // with some drivers, samplers (like the envbox sampler) need to be bound even though
+ // they may not be actually used, otherwise draw calls can fail
+ static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance"));
+ static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular"));
+ setUniformValue(command->m_parameterPack, irradianceId, m_renderer->submissionContext()->maxTextureUnitsCount());
+ setUniformValue(command->m_parameterPack, specularId, m_renderer->submissionContext()->maxTextureUnitsCount());
}
- // Set frag outputs in the shaders if hash not empty
- if (!fragOutputs.isEmpty())
- shader->setFragOutputs(fragOutputs);
+ setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount);
}
}
- else {
- qCWarning(Render::Backend) << Q_FUNC_INFO << "Using default effect as none was provided";
- }
}
bool RenderView::hasBlitFramebufferInfo() const
diff --git a/src/render/renderers/opengl/renderer/renderview_p.h b/src/render/renderers/opengl/renderer/renderview_p.h
index 7ebcdb6bd..c7dc37a2c 100644
--- a/src/render/renderers/opengl/renderer/renderview_p.h
+++ b/src/render/renderers/opengl/renderer/renderview_p.h
@@ -227,10 +227,19 @@ public:
RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true);
- QVector<RenderCommand *> buildDrawRenderCommands(const QVector<Entity *> &entities) const;
- QVector<RenderCommand *> buildComputeRenderCommands(const QVector<Entity *> &entities) const;
- void setCommands(QVector<RenderCommand *> &commands) Q_DECL_NOTHROW { m_commands = commands; }
- QVector<RenderCommand *> commands() const Q_DECL_NOTHROW { return m_commands; }
+ EntityRenderCommandData buildDrawRenderCommands(const QVector<Entity *> &entities,
+ int offset, int count) const;
+ EntityRenderCommandData buildComputeRenderCommands(const QVector<Entity *> &entities,
+ int offset, int count) const;
+
+
+ void updateRenderCommand(EntityRenderCommandData *renderCommandData,
+ int offset, int count);
+
+
+ void setCommands(const QVector<RenderCommand> &commands) Q_DECL_NOTHROW { m_commands = commands; }
+ QVector<RenderCommand> &commands() { return m_commands; }
+ QVector<RenderCommand> commands() const { return m_commands; }
void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; }
const AttachmentPack &attachmentPack() const { return m_attachmentPack; }
@@ -291,7 +300,6 @@ public:
private:
void setShaderAndUniforms(RenderCommand *command,
- RenderPass *pass,
ParameterInfoList &parameters,
Entity *entity,
const QVector<LightSource> &activeLightSources,
@@ -331,10 +339,7 @@ private:
QVector<Qt3DCore::QNodeId> m_insertFenceIds;
QVector<QWaitFenceData> m_waitFences;
- // We do not use pointers to RenderNodes or Drawable's here so that the
- // render aspect is free to change the drawables on the next frame whilst
- // the render thread is submitting these commands.
- QVector<RenderCommand *> m_commands;
+ QVector<RenderCommand> m_commands;
mutable QVector<LightSource> m_lightSources;
EnvironmentLight *m_environmentLight;
diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
index 83fab301a..8f1b17119 100644
--- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
+++ b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
@@ -50,18 +50,73 @@ namespace Render {
// In some cases having less jobs is better (especially on fast cpus where
// splitting just adds more overhead). Ideally, we should try to set the value
// depending on the platform/CPU/nbr of cores
-const int RenderViewBuilder::m_optimalParallelJobCount = std::max(std::min(4, QThread::idealThreadCount()), 2);
+const int RenderViewBuilder::m_optimalParallelJobCount = QThread::idealThreadCount();
namespace {
-class SyncRenderViewCommandBuilders
+int findIdealNumberOfWorkers(int elementCount, int packetSize = 100)
+{
+ if (elementCount == 0 || packetSize == 0)
+ return 0;
+ return std::min(std::max(elementCount / packetSize, 1), RenderViewBuilder::optimalJobCount());
+}
+
+
+class SyncPreCommandBuilding
{
public:
- explicit SyncRenderViewCommandBuilders(const RenderViewInitializerJobPtr &renderViewJob,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
- Renderer *renderer)
+ explicit SyncPreCommandBuilding(RenderViewInitializerJobPtr renderViewInitializerJob,
+ const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs,
+ Renderer *renderer,
+ FrameGraphNode *leafNode)
+ : m_renderViewInitializer(renderViewInitializerJob)
+ , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs)
+ , m_renderer(renderer)
+ , m_leafNode(leafNode)
+ {
+ }
+
+ void operator()()
+ {
+ // Split commands to build among jobs
+ QMutexLocker lock(m_renderer->cache()->mutex());
+ // Rebuild RenderCommands for all entities in RV (ignoring filtering)
+ RendererCache *cache = m_renderer->cache();
+ const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode];
+ RenderView *rv = m_renderViewInitializer->renderView();
+ const auto entities = !rv->isCompute() ? cache->renderableEntities : cache->computeEntities;
+
+ rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer);
+
+ lock.unlock();
+
+ // Split among the ideal number of command builders
+ const int idealPacketSize = std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), entities.size());
+ // Try to split work into an ideal number of workers
+ const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize);
+
+ for (int i = 0; i < m; ++i) {
+ const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = m_renderViewCommandBuilderJobs.at(i);
+ const int count = (i == m - 1) ? entities.size() - (i * idealPacketSize) : idealPacketSize;
+ renderViewCommandBuilder->setEntities(entities, i * idealPacketSize, count);
+ }
+ }
+
+private:
+ RenderViewInitializerJobPtr m_renderViewInitializer;
+ QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs;
+ Renderer *m_renderer;
+ FrameGraphNode *m_leafNode;
+};
+
+class SyncRenderViewPostCommandUpdate
+{
+public:
+ explicit SyncRenderViewPostCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob,
+ const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdateJobs,
+ Renderer *renderer)
: m_renderViewJob(renderViewJob)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
+ , m_renderViewCommandUpdaterJobs(renderViewCommandUpdateJobs)
, m_renderer(renderer)
{}
@@ -70,20 +125,16 @@ public:
// Append all the commands and sort them
RenderView *rv = m_renderViewJob->renderView();
- int totalCommandCount = 0;
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
- totalCommandCount += renderViewCommandBuilder->commands().size();
-
- QVector<RenderCommand *> commands;
- commands.reserve(totalCommandCount);
+ const EntityRenderCommandDataPtr commandData = m_renderViewCommandUpdaterJobs.first()->renderables();
- // Reduction
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
- commands += std::move(renderViewCommandBuilder->commands());
- rv->setCommands(commands);
+ if (commandData) {
+ const QVector<RenderCommand> commands = std::move(commandData->commands);
+ rv->setCommands(commands);
- // Sort the commands
- rv->sort();
+ // TO DO: Find way to store commands once or at least only when required
+ // Sort the commands
+ rv->sort();
+ }
// Enqueue our fully populated RenderView with the RenderThread
m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex());
@@ -91,15 +142,15 @@ public:
private:
RenderViewInitializerJobPtr m_renderViewJob;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs;
Renderer *m_renderer;
};
-class SyncFrustumCulling
+class SyncPreFrustumCulling
{
public:
- explicit SyncFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCulling)
+ explicit SyncPreFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob,
+ const FrustumCullingJobPtr &frustumCulling)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCulling)
{}
@@ -120,21 +171,23 @@ private:
FrustumCullingJobPtr m_frustumCullingJob;
};
-class SyncRenderViewInitialization
+class SyncRenderViewPostInitialization
{
public:
- explicit SyncRenderViewInitialization(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCullingJob,
- const FilterLayerEntityJobPtr &filterEntityByLayerJob,
- const FilterProximityDistanceJobPtr &filterProximityJob,
- const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs)
+ explicit SyncRenderViewPostInitialization(const RenderViewInitializerJobPtr &renderViewJob,
+ const FrustumCullingJobPtr &frustumCullingJob,
+ const FilterLayerEntityJobPtr &filterEntityByLayerJob,
+ const FilterProximityDistanceJobPtr &filterProximityJob,
+ const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
+ const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs,
+ const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterEntityByLayerJob(filterEntityByLayerJob)
, m_filterProximityJob(filterProximityJob)
, m_materialGathererJobs(materialGathererJobs)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
+ , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs)
+ , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs)
{}
void operator()()
@@ -154,8 +207,10 @@ public:
materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter()));
}
- // Command builders
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
+ // Command builders and updates
+ for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs))
+ renderViewCommandUpdater->setRenderView(rv);
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs))
renderViewCommandBuilder->setRenderView(rv);
// Set whether frustum culling is enabled or not
@@ -168,26 +223,31 @@ private:
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs;
+ QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs;
};
-class SyncRenderCommandBuilding
+class SyncRenderViewPreCommandUpdate
{
public:
- explicit SyncRenderCommandBuilding(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCullingJob,
- const FilterProximityDistanceJobPtr &filterProximityJob,
- const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
- Renderer *renderer,
- FrameGraphNode *leafNode)
+ explicit SyncRenderViewPreCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob,
+ const FrustumCullingJobPtr &frustumCullingJob,
+ const FilterProximityDistanceJobPtr &filterProximityJob,
+ const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
+ const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs,
+ const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs,
+ Renderer *renderer,
+ FrameGraphNode *leafNode,
+ bool fullCommandRebuild)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterProximityJob(filterProximityJob)
, m_materialGathererJobs(materialGathererJobs)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
+ , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs)
+ , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs)
, m_renderer(renderer)
, m_leafNode(leafNode)
+ , m_fullRebuild(fullCommandRebuild)
{}
void operator()()
@@ -197,21 +257,44 @@ public:
RenderView *rv = m_renderViewJob->renderView();
if (!rv->noDraw()) {
- QVector<Entity *> renderableEntities;
- const bool isDraw = !rv->isCompute();
- QMutexLocker lock(m_renderer->cache()->mutex());
- const auto& cacheData = m_renderer->cache()->leafNodeCache.value(m_leafNode);
+ ///////// CACHE LOCKED ////////////
+ // Retrieve Data from Cache
+ RendererCache *cache = m_renderer->cache();
+ QMutexLocker lock(cache->mutex());
+ Q_ASSERT(cache->leafNodeCache.contains(m_leafNode));
- if (isDraw)
- renderableEntities = cacheData.renderableEntities;
- else
- renderableEntities = cacheData.computeEntities;
-
- const QVector<Entity *> filteredEntities = cacheData.filterEntitiesByLayer;
- QVector<LightSource> lightSources = cacheData.gatheredLights;
- rv->setEnvironmentLight(cacheData.environmentLight);
+ const bool isDraw = !rv->isCompute();
+ const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode];
+
+ // Rebuild RenderCommands if required
+ // This should happen fairly infrequently (FrameGraph Change, Geometry/Material change)
+ // and allow to skip that step most of the time
+ if (m_fullRebuild) {
+ EntityRenderCommandData commandData;
+ // Reduction
+ {
+ int totalCommandCount = 0;
+ for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs))
+ totalCommandCount += renderViewCommandBuilder->commandData().size();
+ commandData.reserve(totalCommandCount);
+ for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs))
+ commandData += std::move(renderViewCommandBuilder->commandData());
+ }
+
+
+ // Store new cache
+ RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode];
+ writableCacheForLeaf.renderCommandData = std::move(commandData);
+ }
+ const EntityRenderCommandData commandData = dataCacheForLeaf.renderCommandData;
+ const QVector<Entity *> filteredEntities = dataCacheForLeaf.filterEntitiesByLayer;
+ QVector<Entity *> renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities;
+ QVector<LightSource> lightSources = cache->gatheredLights;
+ rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer);
+ rv->setEnvironmentLight(cache->environmentLight);
lock.unlock();
+ ///////// END OF CACHE LOCKED ////////////
// Filter out entities that weren't selected by the layer filters
// Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
@@ -229,22 +312,52 @@ public:
if (rv->frustumCulling())
renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities());
// Filter out entities which didn't satisfy proximity filtering
- renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities());
+ if (!rv->proximityFilterIds().empty())
+ renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities());
}
- // Split among the number of command builders
- int i = 0;
- const int m = RenderViewBuilder::optimalJobCount() - 1;
- const int packetSize = renderableEntities.size() / RenderViewBuilder::optimalJobCount();
- while (i < m) {
- const RenderViewBuilderJobPtr renderViewCommandBuilder = m_renderViewBuilderJobs.at(i);
- renderViewCommandBuilder->setRenderables(renderableEntities.mid(i * packetSize, packetSize));
- ++i;
+ // Early return in case we have nothing to filter
+ if (renderableEntities.size() == 0)
+ return;
+
+ // Filter out Render commands for which the Entity wasn't selected because
+ // of frustum, proximity or layer filtering
+ EntityRenderCommandDataPtr filteredCommandData = EntityRenderCommandDataPtr::create();
+ filteredCommandData->reserve(renderableEntities.size());
+ // Because dataCacheForLeaf.renderableEntities or computeEntities are sorted
+ // What we get out of EntityRenderCommandData is also sorted by Entity
+ auto eIt = std::cbegin(renderableEntities);
+ const auto eEnd = std::cend(renderableEntities);
+ int cIt = 0;
+ const int cEnd = commandData.size();
+
+ while (eIt != eEnd) {
+ const Entity *targetEntity = *eIt;
+ // Advance until we have commands whose Entity has a lower address
+ // than the selected filtered entity
+ while (cIt != cEnd && commandData.entities.at(cIt) < targetEntity)
+ ++cIt;
+
+ // Push pointers to command data for all commands that match the
+ // entity
+ while (cIt != cEnd && commandData.entities.at(cIt) == targetEntity) {
+ filteredCommandData->push_back(commandData.entities.at(cIt),
+ commandData.commands.at(cIt),
+ commandData.passesData.at(cIt));
+ ++cIt;
+ }
+ ++eIt;
}
- m_renderViewBuilderJobs.at(i)->setRenderables(renderableEntities.mid(i * packetSize, packetSize + renderableEntities.size() % (m + 1)));
- {
- QMutexLocker rendererCacheLock(m_renderer->cache()->mutex());
- rv->setMaterialParameterTable(m_renderer->cache()->leafNodeCache.value(m_leafNode).materialParameterGatherer);
+
+ // Split among the number of command builders
+ // The idealPacketSize is at least 100 entities per worker
+ const int idealPacketSize = std::min(std::max(100, filteredCommandData->size() / RenderViewBuilder::optimalJobCount()), filteredCommandData->size());
+ const int m = findIdealNumberOfWorkers(filteredCommandData->size(), idealPacketSize);
+
+ for (int i = 0; i < m; ++i) {
+ const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i);
+ const int count = (i == m - 1) ? filteredCommandData->size() - (i * idealPacketSize) : idealPacketSize;
+ renderViewCommandBuilder->setRenderables(filteredCommandData, i * idealPacketSize, count);
}
}
}
@@ -254,9 +367,11 @@ private:
FrustumCullingJobPtr m_frustumCullingJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs;
+ QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs;
Renderer *m_renderer;
FrameGraphNode *m_leafNode;
+ bool m_fullRebuild;
};
class SetClearDrawBufferIndex
@@ -335,84 +450,6 @@ private:
FrameGraphNode *m_leafNode;
};
-class SyncLightsGatherer
-{
-public:
- explicit SyncLightsGatherer(LightGathererPtr gatherJob,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_gatherJob(gatherJob)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {
- }
-
- void operator()()
- {
- QMutexLocker lock(m_renderer->cache()->mutex());
- RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
- dataCacheForLeaf.gatheredLights = m_gatherJob->lights();
- dataCacheForLeaf.environmentLight = m_gatherJob->takeEnvironmentLight();
- }
-
-private:
- LightGathererPtr m_gatherJob;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
-class SyncRenderableEntities
-{
-public:
- explicit SyncRenderableEntities(RenderableEntityFilterPtr gatherJob,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_gatherJob(gatherJob)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {
- }
-
- void operator()()
- {
- QMutexLocker lock(m_renderer->cache()->mutex());
- RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
- dataCacheForLeaf.renderableEntities = m_gatherJob->filteredEntities();
- std::sort(dataCacheForLeaf.renderableEntities.begin(), dataCacheForLeaf.renderableEntities.end());
- }
-
-private:
- RenderableEntityFilterPtr m_gatherJob;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
-class SyncComputableEntities
-{
-public:
- explicit SyncComputableEntities(ComputableEntityFilterPtr gatherJob,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_gatherJob(gatherJob)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {
- }
-
- void operator()()
- {
- QMutexLocker lock(m_renderer->cache()->mutex());
- RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
- dataCacheForLeaf.computeEntities = m_gatherJob->filteredEntities();
- std::sort(dataCacheForLeaf.computeEntities.begin(), dataCacheForLeaf.computeEntities.end());
- }
-
-private:
- ComputableEntityFilterPtr m_gatherJob;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
} // anonymous
RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer)
@@ -421,13 +458,11 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
, m_renderer(renderer)
, m_layerCacheNeedsToBeRebuilt(false)
, m_materialGathererCacheNeedsToBeRebuilt(false)
- , m_lightsCacheNeedsToBeRebuilt(false)
- , m_renderableCacheNeedsToBeRebuilt(false)
- , m_computableCacheNeedsToBeRebuilt(false)
+ , m_renderCommandCacheNeedsToBeRebuilt(false)
, m_renderViewJob(RenderViewInitializerJobPtr::create())
, m_filterEntityByLayerJob()
, m_frustumCullingJob(new Render::FrustumCullingJob())
- , m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
+ , m_syncPreFrustumCullingJob(SynchronizerJobPtr::create(SyncPreFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
, m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex))
, m_syncFilterEntityByLayerJob()
, m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create())
@@ -444,54 +479,49 @@ FilterLayerEntityJobPtr RenderViewBuilder::filterEntityByLayerJob() const
return m_filterEntityByLayerJob;
}
-LightGathererPtr RenderViewBuilder::lightGathererJob() const
-{
- return m_lightGathererJob;
-}
-
-RenderableEntityFilterPtr RenderViewBuilder::renderableEntityFilterJob() const
+FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const
{
- return m_renderableEntityFilterJob;
+ return m_frustumCullingJob;
}
-ComputableEntityFilterPtr RenderViewBuilder::computableEntityFilterJob() const
+QVector<RenderViewCommandUpdaterJobPtr> RenderViewBuilder::renderViewCommandUpdaterJobs() const
{
- return m_computableEntityFilterJob;
+ return m_renderViewCommandUpdaterJobs;
}
-FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const
+QVector<RenderViewCommandBuilderJobPtr> RenderViewBuilder::renderViewCommandBuilderJobs() const
{
- return m_frustumCullingJob;
+ return m_renderViewCommandBuilderJobs;
}
-QVector<RenderViewBuilderJobPtr> RenderViewBuilder::renderViewBuilderJobs() const
+QVector<MaterialParameterGathererJobPtr> RenderViewBuilder::materialGathererJobs() const
{
- return m_renderViewBuilderJobs;
+ return m_materialGathererJobs;
}
-QVector<MaterialParameterGathererJobPtr> RenderViewBuilder::materialGathererJobs() const
+SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostInitializationJob() const
{
- return m_materialGathererJobs;
+ return m_syncRenderViewPostInitializationJob;
}
-SynchronizerJobPtr RenderViewBuilder::syncRenderViewInitializationJob() const
+SynchronizerJobPtr RenderViewBuilder::syncPreFrustumCullingJob() const
{
- return m_syncRenderViewInitializationJob;
+ return m_syncPreFrustumCullingJob;
}
-SynchronizerJobPtr RenderViewBuilder::syncFrustumCullingJob() const
+SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandBuildingJob() const
{
- return m_syncFrustumCullingJob;
+ return m_syncRenderViewPreCommandBuildingJob;
}
-SynchronizerJobPtr RenderViewBuilder::syncRenderCommandBuildingJob() const
+SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandUpdateJob() const
{
- return m_syncRenderCommandBuildingJob;
+ return m_syncRenderViewPreCommandUpdateJob;
}
-SynchronizerJobPtr RenderViewBuilder::syncRenderViewCommandBuildersJob() const
+SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostCommandUpdateJob() const
{
- return m_syncRenderViewCommandBuildersJob;
+ return m_syncRenderViewPostCommandUpdateJob;
}
SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const
@@ -517,37 +547,21 @@ FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const
void RenderViewBuilder::prepareJobs()
{
// Init what we can here
- EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager();
m_filterProximityJob->setManager(m_renderer->nodeManagers());
m_frustumCullingJob->setRoot(m_renderer->sceneRoot());
- if (m_lightsCacheNeedsToBeRebuilt) {
- m_lightGathererJob = Render::LightGathererPtr::create();
- m_lightGathererJob->setManager(entityManager);
-
- m_cacheLightsJob = SynchronizerJobPtr::create(SyncLightsGatherer(m_lightGathererJob, m_renderer, m_leafNode),
- JobTypes::EntityComponentTypeFiltering);
- m_cacheLightsJob->addDependency(m_lightGathererJob);
- }
-
- if (m_renderableCacheNeedsToBeRebuilt) {
- m_renderableEntityFilterJob = RenderableEntityFilterPtr::create();
- m_renderableEntityFilterJob->setManager(entityManager);
-
- m_cacheRenderableEntitiesJob = SynchronizerJobPtr::create(
- SyncRenderableEntities(m_renderableEntityFilterJob, m_renderer, m_leafNode),
- JobTypes::EntityComponentTypeFiltering);
- m_cacheRenderableEntitiesJob->addDependency(m_renderableEntityFilterJob);
- }
-
- if (m_computableCacheNeedsToBeRebuilt) {
- m_computableEntityFilterJob = ComputableEntityFilterPtr::create();
- m_computableEntityFilterJob->setManager(entityManager);
+ if (m_renderCommandCacheNeedsToBeRebuilt) {
- m_cacheComputableEntitiesJob = SynchronizerJobPtr::create(
- SyncComputableEntities(m_computableEntityFilterJob, m_renderer, m_leafNode),
- JobTypes::EntityComponentTypeFiltering);
- m_cacheComputableEntitiesJob->addDependency(m_computableEntityFilterJob);
+ m_renderViewCommandBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
+ for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
+ auto renderViewCommandBuilder = Render::RenderViewCommandBuilderJobPtr::create();
+ m_renderViewCommandBuilderJobs.push_back(renderViewCommandBuilder);
+ }
+ m_syncRenderViewPreCommandBuildingJob = SynchronizerJobPtr::create(SyncPreCommandBuilding(m_renderViewJob,
+ m_renderViewCommandBuilderJobs,
+ m_renderer,
+ m_leafNode),
+ JobTypes::SyncRenderViewPreCommandBuilding);
}
m_renderViewJob->setRenderer(m_renderer);
@@ -556,12 +570,11 @@ void RenderViewBuilder::prepareJobs()
// RenderCommand building is the most consuming task -> split it
// Estimate the number of jobs to create based on the number of entities
- m_renderViewBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
+ m_renderViewCommandUpdaterJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
- auto renderViewCommandBuilder = Render::RenderViewBuilderJobPtr::create();
- renderViewCommandBuilder->setIndex(m_renderViewIndex);
- renderViewCommandBuilder->setRenderer(m_renderer);
- m_renderViewBuilderJobs.push_back(renderViewCommandBuilder);
+ auto renderViewCommandUpdater = Render::RenderViewCommandUpdaterJobPtr::create();
+ renderViewCommandUpdater->setRenderer(m_renderer);
+ m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater);
}
if (m_materialGathererCacheNeedsToBeRebuilt) {
@@ -582,7 +595,7 @@ void RenderViewBuilder::prepareJobs()
m_syncMaterialGathererJob = SynchronizerJobPtr::create(SyncMaterialParameterGatherer(m_materialGathererJobs,
m_renderer,
m_leafNode),
- JobTypes::SyncMaterialGatherer);
+ JobTypes::SyncMaterialGatherer);
}
if (m_layerCacheNeedsToBeRebuilt) {
@@ -594,34 +607,37 @@ void RenderViewBuilder::prepareJobs()
JobTypes::SyncFilterEntityByLayer);
}
- m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob,
- m_frustumCullingJob,
- m_filterProximityJob,
- m_materialGathererJobs,
- m_renderViewBuilderJobs,
- m_renderer,
- m_leafNode),
- JobTypes::SyncRenderViewCommandBuilding);
-
- m_syncRenderViewCommandBuildersJob = SynchronizerJobPtr::create(SyncRenderViewCommandBuilders(m_renderViewJob,
- m_renderViewBuilderJobs,
- m_renderer),
- JobTypes::SyncRenderViewCommandBuilder);
-
- m_syncRenderViewInitializationJob = SynchronizerJobPtr::create(SyncRenderViewInitialization(m_renderViewJob,
- m_frustumCullingJob,
- m_filterEntityByLayerJob,
- m_filterProximityJob,
- m_materialGathererJobs,
- m_renderViewBuilderJobs),
- JobTypes::SyncRenderViewInitialization);
+ m_syncRenderViewPreCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPreCommandUpdate(m_renderViewJob,
+ m_frustumCullingJob,
+ m_filterProximityJob,
+ m_materialGathererJobs,
+ m_renderViewCommandUpdaterJobs,
+ m_renderViewCommandBuilderJobs,
+ m_renderer,
+ m_leafNode,
+ m_renderCommandCacheNeedsToBeRebuilt),
+ JobTypes::SyncRenderViewPreCommandUpdate);
+
+ m_syncRenderViewPostCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPostCommandUpdate(m_renderViewJob,
+ m_renderViewCommandUpdaterJobs,
+ m_renderer),
+ JobTypes::SyncRenderViewPostCommandUpdate);
+
+ m_syncRenderViewPostInitializationJob = SynchronizerJobPtr::create(SyncRenderViewPostInitialization(m_renderViewJob,
+ m_frustumCullingJob,
+ m_filterEntityByLayerJob,
+ m_filterProximityJob,
+ m_materialGathererJobs,
+ m_renderViewCommandUpdaterJobs,
+ m_renderViewCommandBuilderJobs),
+ JobTypes::SyncRenderViewInitialization);
}
QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
{
QVector<Qt3DCore::QAspectJobPtr> jobs;
- jobs.reserve(m_materialGathererJobs.size() + m_renderViewBuilderJobs.size() + 11);
+ jobs.reserve(m_materialGathererJobs.size() + m_renderViewCommandUpdaterJobs.size() + 11);
// Set dependencies
@@ -629,97 +645,97 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
// TODO: Maybe only update skinning palettes for non-culled entities
m_renderViewJob->addDependency(m_renderer->updateSkinningPaletteJob());
- m_syncFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob());
- m_syncFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob());
- m_syncFrustumCullingJob->addDependency(m_syncRenderViewInitializationJob);
+ m_syncPreFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob());
+ m_syncPreFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob());
+ m_syncPreFrustumCullingJob->addDependency(m_syncRenderViewPostInitializationJob);
m_frustumCullingJob->addDependency(m_renderer->expandBoundingVolumeJob());
- m_frustumCullingJob->addDependency(m_syncFrustumCullingJob);
+ m_frustumCullingJob->addDependency(m_syncPreFrustumCullingJob);
- m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewInitializationJob);
+ m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewPostInitializationJob);
- m_syncRenderViewInitializationJob->addDependency(m_renderViewJob);
+ m_syncRenderViewPostInitializationJob->addDependency(m_renderViewJob);
m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob());
- m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob);
+ m_filterProximityJob->addDependency(m_syncRenderViewPostInitializationJob);
- m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
- m_syncRenderCommandBuildingJob->addDependency(m_filterProximityJob);
- m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncRenderViewPostInitializationJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_filterProximityJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_frustumCullingJob);
// Ensure the RenderThread won't be able to process dirtyResources
// before they have been completely gathered
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->introspectShadersJob());
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->bufferGathererJob());
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->textureGathererJob());
-
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) {
- renderViewCommandBuilder->addDependency(m_syncRenderCommandBuildingJob);
- m_syncRenderViewCommandBuildersJob->addDependency(renderViewCommandBuilder);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->introspectShadersJob());
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->bufferGathererJob());
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->textureGathererJob());
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->cacheLightJob());
+
+ for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) {
+ renderViewCommandUpdater->addDependency(m_syncRenderViewPreCommandUpdateJob);
+ m_syncRenderViewPostCommandUpdateJob->addDependency(renderViewCommandUpdater);
}
- m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewCommandBuildersJob);
+ m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewPostCommandUpdateJob);
m_renderer->frameCleanupJob()->addDependency(m_setClearDrawBufferIndexJob);
// Add jobs
jobs.push_back(m_renderViewJob); // Step 1
- if (m_lightsCacheNeedsToBeRebuilt) {
- jobs.push_back(m_lightGathererJob); // Step 1
- jobs.push_back(m_cacheLightsJob);
- m_syncRenderCommandBuildingJob->addDependency(m_cacheLightsJob);
- }
+ jobs.push_back(m_syncRenderViewPostInitializationJob); // Step 2
- if (m_renderableCacheNeedsToBeRebuilt) {
- jobs.push_back(m_renderableEntityFilterJob); // Step 1
- jobs.push_back(m_cacheRenderableEntitiesJob);
- m_syncRenderCommandBuildingJob->addDependency(m_cacheRenderableEntitiesJob);
- }
+ if (m_renderCommandCacheNeedsToBeRebuilt) { // Step 3
+ m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheComputableEntitiesJob());
+ m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheRenderableEntitiesJob());
+ m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncRenderViewPostInitializationJob);
- if (m_computableCacheNeedsToBeRebuilt) {
- // Note: do it only if OpenGL 4.3+ available
- jobs.push_back(m_computableEntityFilterJob); // Step 1
- jobs.push_back(m_cacheComputableEntitiesJob);
- m_syncRenderCommandBuildingJob->addDependency(m_cacheComputableEntitiesJob);
- }
+ if (m_materialGathererCacheNeedsToBeRebuilt)
+ m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncMaterialGathererJob);
+
+ jobs.push_back(m_syncRenderViewPreCommandBuildingJob);
- jobs.push_back(m_syncRenderViewInitializationJob); // Step 2
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) {
+ renderViewCommandBuilder->addDependency(m_syncRenderViewPreCommandBuildingJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(renderViewCommandBuilder);
+ jobs.push_back(renderViewCommandBuilder);
+ }
+ }
if (m_layerCacheNeedsToBeRebuilt) {
m_filterEntityByLayerJob->addDependency(m_renderer->updateEntityLayersJob());
- m_filterEntityByLayerJob->addDependency(m_syncRenderViewInitializationJob);
+ m_filterEntityByLayerJob->addDependency(m_syncRenderViewPostInitializationJob);
m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob());
m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob);
- m_syncRenderCommandBuildingJob->addDependency(m_syncFilterEntityByLayerJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncFilterEntityByLayerJob);
jobs.push_back(m_filterEntityByLayerJob); // Step 3
jobs.push_back(m_syncFilterEntityByLayerJob); // Step 4
}
- jobs.push_back(m_syncFrustumCullingJob); // Step 3
+ jobs.push_back(m_syncPreFrustumCullingJob); // Step 3
jobs.push_back(m_filterProximityJob); // Step 3
jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3
if (m_materialGathererCacheNeedsToBeRebuilt) {
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
- materialGatherer->addDependency(m_syncRenderViewInitializationJob);
+ materialGatherer->addDependency(m_syncRenderViewPostInitializationJob);
materialGatherer->addDependency(m_renderer->introspectShadersJob());
materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob());
jobs.push_back(materialGatherer); // Step3
m_syncMaterialGathererJob->addDependency(materialGatherer);
}
- m_syncRenderCommandBuildingJob->addDependency(m_syncMaterialGathererJob);
+ m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncMaterialGathererJob);
jobs.push_back(m_syncMaterialGathererJob); // Step 3
}
jobs.push_back(m_frustumCullingJob); // Step 4
- jobs.push_back(m_syncRenderCommandBuildingJob); // Step 5
+ jobs.push_back(m_syncRenderViewPreCommandUpdateJob); // Step 5
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 6
+ // Build RenderCommands or Update RenderCommand Uniforms
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandUpdaterJobs)) // Step 6
jobs.push_back(renderViewCommandBuilder);
- jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 7
+ jobs.push_back(m_syncRenderViewPostCommandUpdateJob); // Step 7
return jobs;
}
@@ -754,34 +770,14 @@ bool RenderViewBuilder::materialGathererCacheNeedsToBeRebuilt() const
return m_materialGathererCacheNeedsToBeRebuilt;
}
-void RenderViewBuilder::setRenderableCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
-{
- m_renderableCacheNeedsToBeRebuilt = needsToBeRebuilt;
-}
-
-bool RenderViewBuilder::renderableCacheNeedsToBeRebuilt() const
-{
- return m_renderableCacheNeedsToBeRebuilt;
-}
-
-void RenderViewBuilder::setComputableCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
-{
- m_computableCacheNeedsToBeRebuilt = needsToBeRebuilt;
-}
-
-bool RenderViewBuilder::computableCacheNeedsToBeRebuilt() const
-{
- return m_computableCacheNeedsToBeRebuilt;
-}
-
-void RenderViewBuilder::setLightGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
+void RenderViewBuilder::setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
{
- m_lightsCacheNeedsToBeRebuilt = needsToBeRebuilt;
+ m_renderCommandCacheNeedsToBeRebuilt = needsToBeRebuilt;
}
-bool RenderViewBuilder::lightGathererCacheNeedsToBeRebuilt() const
+bool RenderViewBuilder::renderCommandCacheNeedsToBeRebuilt() const
{
- return m_lightsCacheNeedsToBeRebuilt;
+ return m_renderCommandCacheNeedsToBeRebuilt;
}
int RenderViewBuilder::optimalJobCount()
diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h b/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
index e223a5f1e..a2ab80e7e 100644
--- a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
+++ b/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
@@ -53,15 +53,14 @@
#include <functional>
#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
#include <Qt3DRender/private/filterlayerentityjob_p.h>
#include <Qt3DRender/private/genericlambdajob_p.h>
#include <Qt3DRender/private/materialparametergathererjob_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/renderviewbuilderjob_p.h>
+#include <Qt3DRender/private/renderviewcommandbuilderjob_p.h>
+#include <Qt3DRender/private/renderviewcommandupdaterjob_p.h>
#include <Qt3DRender/private/renderview_p.h>
#include <Qt3DRender/private/frustumcullingjob_p.h>
-#include <Qt3DRender/private/lightgatherer_p.h>
#include <Qt3DRender/private/filterproximitydistancejob_p.h>
QT_BEGIN_NAMESPACE
@@ -73,8 +72,6 @@ namespace Render {
class Renderer;
using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
-using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
-using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
class Q_AUTOTEST_EXPORT RenderViewBuilder
{
@@ -83,16 +80,15 @@ public:
RenderViewInitializerJobPtr renderViewJob() const;
FilterLayerEntityJobPtr filterEntityByLayerJob() const;
- LightGathererPtr lightGathererJob() const;
- RenderableEntityFilterPtr renderableEntityFilterJob() const;
- ComputableEntityFilterPtr computableEntityFilterJob() const;
FrustumCullingJobPtr frustumCullingJob() const;
- QVector<RenderViewBuilderJobPtr> renderViewBuilderJobs() const;
+ QVector<RenderViewCommandBuilderJobPtr> renderViewCommandBuilderJobs() const;
+ QVector<RenderViewCommandUpdaterJobPtr> renderViewCommandUpdaterJobs() const;
QVector<MaterialParameterGathererJobPtr> materialGathererJobs() const;
- SynchronizerJobPtr syncRenderViewInitializationJob() const;
- SynchronizerJobPtr syncFrustumCullingJob() const;
- SynchronizerJobPtr syncRenderCommandBuildingJob() const;
- SynchronizerJobPtr syncRenderViewCommandBuildersJob() const;
+ SynchronizerJobPtr syncRenderViewPostInitializationJob() const;
+ SynchronizerJobPtr syncPreFrustumCullingJob() const;
+ SynchronizerJobPtr syncRenderViewPreCommandBuildingJob() const;
+ SynchronizerJobPtr syncRenderViewPreCommandUpdateJob() const;
+ SynchronizerJobPtr syncRenderViewPostCommandUpdateJob() const;
SynchronizerJobPtr setClearDrawBufferIndexJob() const;
SynchronizerJobPtr syncFilterEntityByLayerJob() const;
FilterProximityDistanceJobPtr filterProximityJob() const;
@@ -108,15 +104,8 @@ public:
bool layerCacheNeedsToBeRebuilt() const;
void setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
bool materialGathererCacheNeedsToBeRebuilt() const;
-
- void setRenderableCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
- bool renderableCacheNeedsToBeRebuilt() const;
-
- void setComputableCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
- bool computableCacheNeedsToBeRebuilt() const;
-
- void setLightGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
- bool lightGathererCacheNeedsToBeRebuilt() const;
+ void setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
+ bool renderCommandCacheNeedsToBeRebuilt() const;
static int optimalJobCount();
static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset);
@@ -127,32 +116,25 @@ private:
Renderer *m_renderer;
bool m_layerCacheNeedsToBeRebuilt;
bool m_materialGathererCacheNeedsToBeRebuilt;
- bool m_lightsCacheNeedsToBeRebuilt;
- bool m_renderableCacheNeedsToBeRebuilt;
- bool m_computableCacheNeedsToBeRebuilt;
+ bool m_renderCommandCacheNeedsToBeRebuilt;
RenderViewInitializerJobPtr m_renderViewJob;
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
- LightGathererPtr m_lightGathererJob;
- RenderableEntityFilterPtr m_renderableEntityFilterJob;
- ComputableEntityFilterPtr m_computableEntityFilterJob;
FrustumCullingJobPtr m_frustumCullingJob;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs;
+ QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
- SynchronizerJobPtr m_syncRenderViewInitializationJob;
- SynchronizerJobPtr m_syncFrustumCullingJob;
- SynchronizerJobPtr m_syncRenderCommandBuildingJob;
- SynchronizerJobPtr m_syncRenderViewCommandBuildersJob;
+ SynchronizerJobPtr m_syncRenderViewPostInitializationJob;
+ SynchronizerJobPtr m_syncPreFrustumCullingJob;
+ SynchronizerJobPtr m_syncRenderViewPreCommandBuildingJob;
+ SynchronizerJobPtr m_syncRenderViewPreCommandUpdateJob;
+ SynchronizerJobPtr m_syncRenderViewPostCommandUpdateJob;
SynchronizerJobPtr m_setClearDrawBufferIndexJob;
SynchronizerJobPtr m_syncFilterEntityByLayerJob;
SynchronizerJobPtr m_syncMaterialGathererJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
- SynchronizerJobPtr m_cacheRenderableEntitiesJob;
- SynchronizerJobPtr m_cacheComputableEntitiesJob;
- SynchronizerJobPtr m_cacheLightsJob;
-
static const int m_optimalParallelJobCount;
};
diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack.cpp b/src/render/renderers/opengl/renderer/shaderparameterpack.cpp
index 13d05cac1..1cfb59343 100644
--- a/src/render/renderers/opengl/renderer/shaderparameterpack.cpp
+++ b/src/render/renderers/opengl/renderer/shaderparameterpack.cpp
@@ -57,7 +57,6 @@ namespace Render {
ShaderParameterPack::~ShaderParameterPack()
{
- m_uniforms.clear();
}
void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val)
diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
index a5aee6ac4..cb599124c 100644
--- a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
+++ b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
@@ -89,7 +89,56 @@ struct BlockToSSBO {
QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE)
-typedef QHash<int, UniformValue> PackUniformHash;
+struct PackUniformHash
+{
+ QVector<int> keys;
+ QVector<UniformValue> values;
+
+ PackUniformHash()
+ {
+ keys.reserve(10);
+ values.reserve(10);
+ }
+
+ void insert(int key, const UniformValue &value)
+ {
+ const int idx = keys.indexOf(key);
+ if (idx != -1) {
+ values[idx] = value;
+ } else {
+ keys.push_back(key);
+ values.push_back(value);
+ }
+ }
+
+ UniformValue value(int key) const
+ {
+ const int idx = keys.indexOf(key);
+ if (idx != -1)
+ return values.at(idx);
+ return UniformValue();
+ }
+
+ UniformValue& value(int key)
+ {
+ const int idx = keys.indexOf(key);
+ if (idx != -1)
+ return values[idx];
+ insert(key, UniformValue());
+ return value(key);
+ }
+
+ void erase(int idx)
+ {
+ keys.removeAt(idx);
+ values.removeAt(idx);
+ }
+
+ bool contains(int key) const
+ {
+ return keys.contains(key);
+ }
+};
class Q_AUTOTEST_EXPORT ShaderParameterPack
{
diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp
index 1b5a972ec..20e6007a0 100644
--- a/src/render/renderers/opengl/textures/gltexture.cpp
+++ b/src/render/renderers/opengl/textures/gltexture.cpp
@@ -232,11 +232,9 @@ void GLTexture::loadTextureDataFromImages()
GLTexture::TextureUpdateInfo GLTexture::createOrUpdateGLTexture()
{
TextureUpdateInfo textureInfo;
- m_properties.status = QAbstractTexture::Error;
m_wasTextureRecreated = false;
const bool hasSharedTextureId = m_sharedTextureId > 0;
-
// Only load texture data if we are not using a sharedTextureId
// Check if dataFunctor or images have changed
if (!hasSharedTextureId) {
@@ -269,17 +267,17 @@ GLTexture::TextureUpdateInfo GLTexture::createOrUpdateGLTexture()
// Reset image flag
setDirtyFlag(TextureImageData, false);
}
- }
- // Don't try to create the texture if the target or format was still not set
- // Format should either be set by user or if Automatic
- // by either the dataGenerator of the texture or the first Image
- // Target should explicitly be set by the user or the dataGenerator
- if (m_properties.target == QAbstractTexture::TargetAutomatic ||
- m_properties.format == QAbstractTexture::Automatic ||
- m_properties.format == QAbstractTexture::NoFormat) {
- textureInfo.properties.status = QAbstractTexture::Error;
- return textureInfo;
+ // Don't try to create the texture if the target or format was still not set
+ // Format should either be set by user or if Automatic
+ // by either the dataGenerator of the texture or the first Image
+ // Target should explicitly be set by the user or the dataGenerator
+ if (m_properties.target == QAbstractTexture::TargetAutomatic ||
+ m_properties.format == QAbstractTexture::Automatic ||
+ m_properties.format == QAbstractTexture::NoFormat) {
+ textureInfo.properties.status = QAbstractTexture::Error;
+ return textureInfo;
+ }
}
// If the properties changed or texture has become a shared texture from a
diff --git a/src/render/renderstates/qrastermode.cpp b/src/render/renderstates/qrastermode.cpp
index c432f1063..648872a84 100644
--- a/src/render/renderstates/qrastermode.cpp
+++ b/src/render/renderstates/qrastermode.cpp
@@ -48,7 +48,7 @@ namespace Qt3DRender {
/*!
\class Qt3DRender::QRasterMode
\brief The QRasterMode render state allows to control the type of
- rasterization to be performed
+ rasterization to be performed.
\since 5.14
\inmodule Qt3DRender
\ingroup renderstates
@@ -65,7 +65,7 @@ namespace Qt3DRender {
/*!
\qmltype RasterMode
\brief The RasterMode render state allows to control the type of
- rasterization to be performed
+ rasterization to be performed.
\since 5.14
\inqmlmodule Qt3D.Render
\inherits RenderState
diff --git a/src/render/services/vsyncframeadvanceservice.cpp b/src/render/services/vsyncframeadvanceservice.cpp
index b49870e68..d7398e2ce 100644
--- a/src/render/services/vsyncframeadvanceservice.cpp
+++ b/src/render/services/vsyncframeadvanceservice.cpp
@@ -62,7 +62,7 @@ public:
QSemaphore m_semaphore;
QElapsedTimer m_elapsed;
- quint64 m_elapsedTimeSincePreviousFrame;
+ qint64 m_elapsedTimeSincePreviousFrame;
bool m_drivenByRenderThread;
};
@@ -75,14 +75,19 @@ VSyncFrameAdvanceService::~VSyncFrameAdvanceService()
{
}
-// Aspect Thread
+// Main Thread
qint64 VSyncFrameAdvanceService::waitForNextFrame()
{
Q_D(VSyncFrameAdvanceService);
+#ifdef Q_OS_MACOS
+ if (!d->m_semaphore.tryAcquire(std::max(d->m_semaphore.available(), 1), 4))
+ return -1;
+#else
d->m_semaphore.acquire(std::max(d->m_semaphore.available(), 1));
+#endif
- const quint64 currentTime = d->m_elapsed.nsecsElapsed();
+ const qint64 currentTime = d->m_elapsed.nsecsElapsed();
qCDebug(VSyncAdvanceService) << "Elapsed nsecs since last call " << currentTime - d->m_elapsedTimeSincePreviousFrame;
d->m_elapsedTimeSincePreviousFrame = currentTime;
return currentTime;
diff --git a/src/render/texture/qabstracttexture.cpp b/src/render/texture/qabstracttexture.cpp
index 7fca2ba3f..258ab44dc 100644
--- a/src/render/texture/qabstracttexture.cpp
+++ b/src/render/texture/qabstracttexture.cpp
@@ -977,7 +977,7 @@ float QAbstractTexture::maximumAnisotropy() const
}
/*!
- \property Qt3DRender::QAbstractTexture::ComparisonFunction
+ \property Qt3DRender::QAbstractTexture::comparisonFunction
Holds the comparison function of the texture provider.
*/
@@ -1008,7 +1008,7 @@ QAbstractTexture::ComparisonFunction QAbstractTexture::comparisonFunction() cons
}
/*!
- \property Qt3DRender::QAbstractTexture::ComparisonMode
+ \property Qt3DRender::QAbstractTexture::comparisonMode
Holds the comparison mode of the texture provider.
*/
@@ -1055,9 +1055,12 @@ QTextureGeneratorPtr QAbstractTexture::dataGenerator() const
*/
/*!
- * \qmlproperty handleType
+ * \qmlproperty enumeration AbstractTexture::handleType
*
* Holds the current texture handle type.
+ *
+ * \value AbstractTexture.NoHandle
+ * \value AbstractTexture.OpenGLTextureId
*/
/*!
@@ -1070,7 +1073,6 @@ QAbstractTexture::HandleType QAbstractTexture::handleType() const
return d->m_handleType;
}
-
/*!
* \property Qt3DRender::QAbstractTexture::handle
*
@@ -1079,7 +1081,7 @@ QAbstractTexture::HandleType QAbstractTexture::handleType() const
*/
/*!
- * \qmlproperty handle
+ * \qmlproperty var AbstractTexture::handle
*
* Holds the current texture handle, if Qt 3D is using the OpenGL renderer,
* handle is a texture id integer.
@@ -1098,8 +1100,8 @@ QVariant QAbstractTexture::handle() const
}
/*!
- * Allow to update a sub region of the texture without having to change the data
- * generator or rely on adding or removing texture images.
+ * Updates a sub region of the texture, defined by \a update, without having
+ * to change the data generator or rely on adding or removing texture images.
* \since 5.14
*/
void QAbstractTexture::updateData(const QTextureDataUpdate &update)
@@ -1135,7 +1137,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange()
data.dataFunctor = d->m_dataFunctor;
data.sharedTextureId = d->m_sharedTextureId;
data.initialDataUpdates = d->m_pendingDataUpdates;
- return std::move(creationChange);
+ return creationChange;
}
/*!
diff --git a/src/render/texture/qabstracttextureimage.cpp b/src/render/texture/qabstracttextureimage.cpp
index 9ca4599c5..6f68221fd 100644
--- a/src/render/texture/qabstracttextureimage.cpp
+++ b/src/render/texture/qabstracttextureimage.cpp
@@ -131,8 +131,8 @@ QTextureImageDataGeneratorPtr QAbstractTextureImagePrivate::dataGenerator() cons
/*!
\fn Qt3DRender::QTextureImageDataGeneratorPtr Qt3DRender::QAbstractTextureImage::dataGenerator() const
- Implement this method to return the \l QTextureImageDataGeneratorPtr, which will
- provide the data for the texture image.
+ Implement this method to return the QTextureImageDataGeneratorPtr instance,
+ which will provide the data for the texture image.
*/
/*!
diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp
index bca66e630..84a228428 100644
--- a/src/render/texture/qtexture.cpp
+++ b/src/render/texture/qtexture.cpp
@@ -1125,7 +1125,7 @@ TextureDownloadRequest::TextureDownloadRequest(const QTextureFromSourceGenerator
}
-// Executed in aspect thread
+// Executed in main thread
void TextureDownloadRequest::onCompleted()
{
if (cancelled() || !succeeded())
@@ -1142,16 +1142,11 @@ void TextureDownloadRequest::onCompleted()
QTextureFromSourceGeneratorPtr oldGenerator = qSharedPointerCast<QTextureFromSourceGenerator>(texture->dataGenerator());
- // We create a new functor
- // Which is a copy of the old one + the downloaded sourceData
- auto newGenerator = QTextureFromSourceGeneratorPtr::create(*oldGenerator);
-
// Set raw data on functor so that it can really load something
- newGenerator->m_sourceData = m_data;
+ oldGenerator->m_sourceData = m_data;
- // Set new generator on texture
- // it implictely marks the texture as dirty so that the functor runs again with the downloaded data
- texture->setDataGenerator(newGenerator);
+ // Mark the texture as dirty so that the functor runs again with the downloaded data
+ texture->addDirtyFlag(Render::Texture::DirtyDataGenerator);
}
/*!
@@ -1520,7 +1515,10 @@ QTextureLoader::QTextureLoader(QNode *parent)
// Regenerate the texture functor when properties we support overriding
// from QAbstractTexture get changed.
Q_D(QTextureLoader);
- auto regenerate = [=] () { d->updateGenerator(); };
+ auto regenerate = [=] () {
+ if (!notificationsBlocked()) // check the change doesn't come from the backend
+ d->updateGenerator();
+ };
connect(this, &QAbstractTexture::formatChanged, regenerate);
}
diff --git a/src/render/texture/qtexturegenerator.cpp b/src/render/texture/qtexturegenerator.cpp
index 5e350af2d..36b5f6498 100644
--- a/src/render/texture/qtexturegenerator.cpp
+++ b/src/render/texture/qtexturegenerator.cpp
@@ -52,8 +52,7 @@ QTextureGenerator::~QTextureGenerator()
}
/*!
- \class QTextureGenerator
- \inherits QAbstractFunctor
+ \class Qt3DRender::QTextureGenerator
\inmodule Qt3DRender
\brief Provides the image data for a texture.
*/
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index d120c2b39..1414cd337 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -149,6 +149,8 @@ void Texture::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
auto newGenerator = node->dataGenerator();
if (newGenerator != m_dataFunctor) {
setDataGenerator(newGenerator);
+ QAbstractTexturePrivate *dTexture = static_cast<QAbstractTexturePrivate *>(QNodePrivate::get(const_cast<QNode *>(frontEnd)));
+ dTexture->setStatus(QAbstractTexture::Loading);
}
QAbstractTexturePrivate *dnode = dynamic_cast<QAbstractTexturePrivate *>(QAbstractTexturePrivate::get(const_cast<QAbstractTexture *>(node)));
@@ -163,11 +165,11 @@ void Texture::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
m_textureImageIds = ids;
addDirtyFlag(DirtyImageGenerators);
}
- }
- if (dnode->m_sharedTextureId != m_sharedTextureId) {
- m_sharedTextureId = dnode->m_sharedTextureId;
- addDirtyFlag(DirtySharedTextureId);
+ if (dnode->m_sharedTextureId != m_sharedTextureId) {
+ m_sharedTextureId = dnode->m_sharedTextureId;
+ addDirtyFlag(DirtySharedTextureId);
+ }
}
}