summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/backend/abstractrenderer_p.h4
-rw-r--r--src/render/backend/backendnode.cpp8
-rw-r--r--src/render/backend/backendnode_p.h2
-rw-r--r--src/render/backend/entity.cpp162
-rw-r--r--src/render/backend/entity_p.h13
-rw-r--r--src/render/backend/transform.cpp33
-rw-r--r--src/render/backend/transform_p.h3
-rw-r--r--src/render/framegraph/blitframebuffer.cpp76
-rw-r--r--src/render/framegraph/blitframebuffer_p.h4
-rw-r--r--src/render/framegraph/cameraselectornode.cpp26
-rw-r--r--src/render/framegraph/cameraselectornode_p.h5
-rw-r--r--src/render/framegraph/clearbuffers.cpp64
-rw-r--r--src/render/framegraph/clearbuffers_p.h5
-rw-r--r--src/render/framegraph/dispatchcompute.cpp40
-rw-r--r--src/render/framegraph/dispatchcompute_p.h4
-rw-r--r--src/render/framegraph/framegraphnode.cpp49
-rw-r--r--src/render/framegraph/framegraphnode_p.h3
-rw-r--r--src/render/framegraph/layerfilternode.cpp48
-rw-r--r--src/render/framegraph/layerfilternode_p.h6
-rw-r--r--src/render/framegraph/memorybarrier.cpp26
-rw-r--r--src/render/framegraph/memorybarrier_p.h3
-rw-r--r--src/render/framegraph/proximityfilter.cpp35
-rw-r--r--src/render/framegraph/proximityfilter_p.h4
-rw-r--r--src/render/framegraph/qblitframebuffer.cpp1
-rw-r--r--src/render/framegraph/qframegraphnode.cpp10
-rw-r--r--src/render/framegraph/qlayerfilter.cpp12
-rw-r--r--src/render/framegraph/qrendercapture.cpp12
-rw-r--r--src/render/framegraph/qrendercapture_p.h14
-rw-r--r--src/render/framegraph/qrenderpassfilter.cpp24
-rw-r--r--src/render/framegraph/qrenderstateset.cpp12
-rw-r--r--src/render/framegraph/qrendersurfaceselector.cpp18
-rw-r--r--src/render/framegraph/qrendertargetselector.cpp8
-rw-r--r--src/render/framegraph/qsortpolicy.cpp3
-rw-r--r--src/render/framegraph/qtechniquefilter.cpp24
-rw-r--r--src/render/framegraph/rendercapture.cpp23
-rw-r--r--src/render/framegraph/rendercapture_p.h3
-rw-r--r--src/render/framegraph/renderpassfilternode.cpp65
-rw-r--r--src/render/framegraph/renderpassfilternode_p.h4
-rw-r--r--src/render/framegraph/rendersurfaceselector.cpp59
-rw-r--r--src/render/framegraph/rendersurfaceselector_p.h5
-rw-r--r--src/render/framegraph/rendertargetselectornode.cpp35
-rw-r--r--src/render/framegraph/rendertargetselectornode_p.h4
-rw-r--r--src/render/framegraph/sortpolicy.cpp29
-rw-r--r--src/render/framegraph/sortpolicy_p.h4
-rw-r--r--src/render/framegraph/statesetnode.cpp40
-rw-r--r--src/render/framegraph/statesetnode_p.h4
-rw-r--r--src/render/framegraph/techniquefilternode.cpp62
-rw-r--r--src/render/framegraph/techniquefilternode_p.h4
-rw-r--r--src/render/framegraph/viewportnode.cpp49
-rw-r--r--src/render/framegraph/viewportnode_p.h4
-rw-r--r--src/render/framegraph/waitfence.cpp47
-rw-r--r--src/render/framegraph/waitfence_p.h4
-rw-r--r--src/render/frontend/qcamera.cpp20
-rw-r--r--src/render/frontend/qrenderaspect.cpp89
-rw-r--r--src/render/frontend/qrenderaspect_p.h2
-rw-r--r--src/render/geometry/armature.cpp32
-rw-r--r--src/render/geometry/armature_p.h4
-rw-r--r--src/render/geometry/attribute.cpp114
-rw-r--r--src/render/geometry/attribute_p.h4
-rw-r--r--src/render/geometry/buffer.cpp86
-rw-r--r--src/render/geometry/buffer_p.h3
-rw-r--r--src/render/geometry/geometry.cpp56
-rw-r--r--src/render/geometry/geometry_p.h4
-rw-r--r--src/render/geometry/geometryrenderer.cpp122
-rw-r--r--src/render/geometry/geometryrenderer_p.h4
-rw-r--r--src/render/geometry/joint.cpp71
-rw-r--r--src/render/geometry/joint_p.h3
-rw-r--r--src/render/geometry/qattribute.cpp13
-rw-r--r--src/render/geometry/qbuffer.cpp16
-rw-r--r--src/render/geometry/qgeometry.cpp12
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp7
-rw-r--r--src/render/geometry/skeleton.cpp100
-rw-r--r--src/render/geometry/skeleton_p.h2
-rw-r--r--src/render/jobs/job_common_p.h1
-rw-r--r--src/render/jobs/jobs.pri2
-rw-r--r--src/render/jobs/updateentityhierarchyjob.cpp80
-rw-r--r--src/render/jobs/updateentityhierarchyjob_p.h91
-rw-r--r--src/render/lights/environmentlight.cpp14
-rw-r--r--src/render/lights/environmentlight_p.h3
-rw-r--r--src/render/lights/light.cpp16
-rw-r--r--src/render/lights/light_p.h4
-rw-r--r--src/render/lights/qenvironmentlight.cpp34
-rw-r--r--src/render/materialsystem/effect.cpp53
-rw-r--r--src/render/materialsystem/effect_p.h4
-rw-r--r--src/render/materialsystem/material.cpp59
-rw-r--r--src/render/materialsystem/material_p.h4
-rw-r--r--src/render/materialsystem/parameter.cpp47
-rw-r--r--src/render/materialsystem/parameter_p.h5
-rw-r--r--src/render/materialsystem/qeffect.cpp25
-rw-r--r--src/render/materialsystem/qgraphicsapifilter.cpp5
-rw-r--r--src/render/materialsystem/qgraphicsapifilter_p.h1
-rw-r--r--src/render/materialsystem/qmaterial.cpp12
-rw-r--r--src/render/materialsystem/qrenderpass.cpp42
-rw-r--r--src/render/materialsystem/qtechnique.cpp50
-rw-r--r--src/render/materialsystem/qtechnique.h3
-rw-r--r--src/render/materialsystem/renderpass.cpp69
-rw-r--r--src/render/materialsystem/renderpass_p.h4
-rw-r--r--src/render/materialsystem/technique.cpp90
-rw-r--r--src/render/materialsystem/technique_p.h4
-rw-r--r--src/render/picking/qpickevent.cpp8
-rw-r--r--src/render/picking/qpickevent.h4
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp2
-rw-r--r--src/render/renderers/opengl/jobs/renderviewjobutils.cpp10
-rw-r--r--src/render/renderers/opengl/jobs/renderviewjobutils_p.h6
-rw-r--r--src/render/renderers/opengl/renderer/commandthread.cpp2
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp42
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h6
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp5
-rw-r--r--src/render/renderers/opengl/renderstates/renderstateset.cpp15
-rw-r--r--src/render/renderers/opengl/renderstates/renderstateset_p.h8
-rw-r--r--src/render/renderers/opengl/textures/gltexture.cpp12
-rw-r--r--src/render/renderstates/qdepthrange.cpp4
-rw-r--r--src/render/texture/qabstracttexture.cpp36
-rw-r--r--src/render/texture/qabstracttexture_p.h2
-rw-r--r--src/render/texture/qabstracttextureimage.cpp7
-rw-r--r--src/render/texture/qtexturedataupdate.cpp1
-rw-r--r--src/render/texture/texture.cpp122
-rw-r--r--src/render/texture/texture_p.h1
118 files changed, 1193 insertions, 1792 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index 6e6f4898c..006919512 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -67,7 +67,6 @@ class QSize;
namespace Qt3DCore {
class QAbstractFrameAdvanceService;
-class QBackendNodeFactory;
class QEventFilterService;
class QAbstractAspectJobManager;
class QServiceLocator;
@@ -114,7 +113,6 @@ public:
JointDirty = 1 << 11,
LayersDirty = 1 << 12,
TechniquesDirty = 1 << 13,
- EntityHierarchyDirty= 1 << 14,
LightsDirty = 1 << 15,
AllDirty = 0xffffff
};
@@ -162,7 +160,7 @@ public:
virtual Qt3DCore::QAspectJobPtr syncLoadingJobs() = 0;
virtual Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() = 0;
- virtual void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Entity *root) = 0;
+ virtual void setSceneRoot(Entity *root) = 0;
virtual Entity *sceneRoot() const = 0;
virtual FrameGraphNode *frameGraphRoot() const = 0;
diff --git a/src/render/backend/backendnode.cpp b/src/render/backend/backendnode.cpp
index 0dc8da237..188e017e6 100644
--- a/src/render/backend/backendnode.cpp
+++ b/src/render/backend/backendnode.cpp
@@ -41,6 +41,7 @@
#include <private/renderer_p.h>
#include <private/resourceaccessor_p.h>
#include <private/nodemanagers_p.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +82,13 @@ QSharedPointer<RenderBackendResourceAccessor> BackendNode::resourceAccessor()
return r->nodeManagers()->resourceAccessor();
}
+void BackendNode::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
+{
+ Q_UNUSED(firstTime);
+
+ d_ptr->setEnabled(frontEnd->isEnabled());
+}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/backend/backendnode_p.h b/src/render/backend/backendnode_p.h
index f94033c1a..167cb87f2 100644
--- a/src/render/backend/backendnode_p.h
+++ b/src/render/backend/backendnode_p.h
@@ -70,6 +70,8 @@ public:
BackendNode(Qt3DCore::QBackendNode::Mode mode = ReadOnly);
~BackendNode();
+ virtual void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime);
+
void setRenderer(AbstractRenderer *renderer);
AbstractRenderer *renderer() const;
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index bf128b508..8be58dd46 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -95,11 +95,19 @@ void Entity::cleanup()
if (m_nodeManagers != nullptr) {
m_nodeManagers->worldMatrixManager()->releaseResource(peerId());
qCDebug(Render::RenderNodes) << Q_FUNC_INFO;
+
+ removeFromParentChildHandles();
+
+ for (auto &childHandle : qAsConst(m_childrenHandles)) {
+ auto child = m_nodeManagers->renderNodesManager()->data(childHandle);
+ // children should always exist and have this as parent
+ // if they were destroyed, they would have removed themselves from our m_childrenHandles
+ Q_ASSERT(child);
+ Q_ASSERT(child->m_parentHandle == m_handle);
+ child->m_parentHandle = {};
+ }
}
- if (!m_parentEntityId.isNull())
- markDirty(AbstractRenderer::EntityHierarchyDirty);
- m_parentEntityId = Qt3DCore::QNodeId();
m_worldTransform = HMatrix();
// Release all component will have to perform their own release when they receive the
// NodeDeleted notification
@@ -122,6 +130,7 @@ void Entity::cleanup()
m_localBoundingVolume.reset();
m_worldBoundingVolume.reset();
m_worldBoundingVolumeWithChildren.reset();
+ m_parentHandle = {};
m_boundingDirty = false;
QBackendNode::setEnabled(false);
}
@@ -129,6 +138,12 @@ void Entity::cleanup()
void Entity::setParentHandle(HEntity parentHandle)
{
Q_ASSERT(m_nodeManagers);
+
+ if (parentHandle == m_parentHandle)
+ return;
+
+ removeFromParentChildHandles();
+
m_parentHandle = parentHandle;
auto parent = m_nodeManagers->renderNodesManager()->data(parentHandle);
if (parent != nullptr && !parent->m_childrenHandles.contains(m_handle))
@@ -145,44 +160,6 @@ void Entity::setHandle(HEntity handle)
m_handle = handle;
}
-void Entity::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<QNodeCreatedChange<Qt3DCore::QEntityData>>(change);
- const auto &data = typedChange->data;
-
- // Note this is *not* the parentId as that is the ID of the parent QNode, which is not
- // necessarily the same as the parent QEntity (which may be further up the tree).
- m_parentEntityId = data.parentEntityId;
- qCDebug(Render::RenderNodes) << "Creating Entity id =" << peerId() << "parentId =" << m_parentEntityId;
-
- // TODO: Store string id instead and only in debug mode
- //m_objectName = peer->objectName();
- m_worldTransform = m_nodeManagers->worldMatrixManager()->getOrAcquireHandle(peerId());
-
- // TODO: Suboptimal -> Maybe have a Hash<QComponent, QEntityList> instead
- m_transformComponent = QNodeId();
- m_materialComponent = QNodeId();
- m_cameraComponent = QNodeId();
- m_geometryRendererComponent = QNodeId();
- m_objectPickerComponent = QNodeId();
- m_boundingVolumeDebugComponent = QNodeId();
- m_computeComponent = QNodeId();
- m_layerComponents.clear();
- m_levelOfDetailComponents.clear();
- m_rayCasterComponents.clear();
- m_shaderDataComponents.clear();
- m_lightComponents.clear();
- m_environmentLightComponents.clear();
- m_localBoundingVolume = QSharedPointer<Sphere>::create(peerId());
- m_worldBoundingVolume = QSharedPointer<Sphere>::create(peerId());
- m_worldBoundingVolumeWithChildren = QSharedPointer<Sphere>::create(peerId());
-
- for (const auto &idAndType : qAsConst(data.componentIdsAndTypes))
- addComponent(idAndType);
-
- markDirty(AbstractRenderer::EntityHierarchyDirty);
-}
-
void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
switch (e->type()) {
@@ -192,7 +169,6 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const auto componentIdAndType = QNodeIdTypePair(change->componentId(), change->componentMetaObject());
addComponent(componentIdAndType);
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Added. Id =" << change->componentId();
- markDirty(AbstractRenderer::AllDirty);
break;
}
@@ -200,27 +176,6 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QComponentRemovedChangePtr change = qSharedPointerCast<QComponentRemovedChange>(e);
removeComponent(change->componentId());
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Removed. Id =" << change->componentId();
- markDirty(AbstractRenderer::AllDirty);
- break;
- }
-
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("enabled")) {
- // We only mark as dirty the renderer
- markDirty(AbstractRenderer::EntityEnabledDirty);
- // We let QBackendNode::sceneChangeEvent change the enabled property
- } else if (change->propertyName() == QByteArrayLiteral("parentEntityUpdated")) {
- auto newParent = change->value().value<Qt3DCore::QNodeId>();
- qCDebug(Render::RenderNodes) << "Setting parent for " << peerId() << ", new parentId =" << newParent;
- if (m_parentEntityId != newParent) {
- m_parentEntityId = newParent;
- // TODO: change to EventHierarchyDirty and update renderer to
- // ensure all jobs are run that depend on Entity hierarchy.
- markDirty(AbstractRenderer::AllDirty);
- }
- }
-
break;
}
@@ -230,6 +185,62 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Entity::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QEntity *node = qobject_cast<const Qt3DCore::QEntity *>(frontEnd);
+ if (!node)
+ return;
+
+ if (this->isEnabled() != node->isEnabled()) {
+ markDirty(AbstractRenderer::EntityEnabledDirty);
+ // We let QBackendNode::syncFromFrontEnd change the enabled property
+ }
+
+ const auto parentID = node->parentEntity() ? node->parentEntity()->id() : Qt3DCore::QNodeId();
+ auto parentHandle = m_nodeManagers->renderNodesManager()->lookupHandle(parentID);
+
+ // All entity creation is done from top-down and always during the same frame, so
+ // we if we have a valid parent node, we should always be able to resolve the
+ // backend parent at this time
+ Q_ASSERT(!node->parentEntity() || (!parentHandle.isNull() && m_nodeManagers->renderNodesManager()->data(parentHandle)));
+
+ if (parentHandle != m_parentHandle) {
+ markDirty(AbstractRenderer::AllDirty);
+ }
+
+ setParentHandle(parentHandle);
+
+ if (firstTime) {
+ m_worldTransform = m_nodeManagers->worldMatrixManager()->getOrAcquireHandle(peerId());
+
+ // TODO: Suboptimal -> Maybe have a Hash<QComponent, QEntityList> instead
+ m_transformComponent = QNodeId();
+ m_materialComponent = QNodeId();
+ m_cameraComponent = QNodeId();
+ m_geometryRendererComponent = QNodeId();
+ m_objectPickerComponent = QNodeId();
+ m_boundingVolumeDebugComponent = QNodeId();
+ m_computeComponent = QNodeId();
+ m_layerComponents.clear();
+ m_levelOfDetailComponents.clear();
+ m_rayCasterComponents.clear();
+ m_shaderDataComponents.clear();
+ m_lightComponents.clear();
+ m_environmentLightComponents.clear();
+ m_localBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolumeWithChildren = QSharedPointer<Sphere>::create(peerId());
+
+ const QComponentVector &components = node->components();
+ for (QComponent *c : components) {
+ const auto idAndType = QNodeIdTypePair(c->id(), QNodePrivate::findStaticMetaObject(c->metaObject()));
+ addComponent(idAndType);
+ }
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
void Entity::dump() const
{
static int depth = 0;
@@ -246,25 +257,12 @@ Entity *Entity::parent() const
return m_nodeManagers->renderNodesManager()->data(m_parentHandle);
}
-
-// clearEntityHierarchy and rebuildEntityHierarchy should only be called
-// from UpdateEntityHierarchyJob to update the entity hierarchy for the
-// entire scene at once
-void Entity::clearEntityHierarchy()
-{
- m_childrenHandles.clear();
- m_parentHandle = HEntity();
-}
-
-// clearEntityHierarchy and rebuildEntityHierarchy should only be called
-// from UpdateEntityHierarchyJob to update the entity hierarchy for the
-// entire scene at once
-void Entity::rebuildEntityHierarchy()
+void Entity::removeFromParentChildHandles()
{
- if (!m_parentEntityId.isNull())
- setParentHandle(m_nodeManagers->renderNodesManager()->lookupHandle(m_parentEntityId));
- else
- qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "No parent entity found for Entity" << peerId();
+ // remove ourself from our parent's list of children.
+ auto p = parent();
+ if (p)
+ p->removeChildHandle(m_handle);
}
void Entity::appendChildHandle(HEntity childHandle)
@@ -358,6 +356,7 @@ void Entity::addComponent(Qt3DCore::QNodeIdTypePair idAndType)
} else if (type->inherits(&QArmature::staticMetaObject)) {
m_armatureComponent = id;
}
+ markDirty(AbstractRenderer::AllDirty);
}
void Entity::removeComponent(Qt3DCore::QNodeId nodeId)
@@ -392,6 +391,7 @@ void Entity::removeComponent(Qt3DCore::QNodeId nodeId)
} else if (m_armatureComponent == nodeId) {
m_armatureComponent = QNodeId();
}
+ markDirty(AbstractRenderer::AllDirty);
}
bool Entity::isBoundingVolumeDirty() const
diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h
index b4c9541f2..403f5568c 100644
--- a/src/render/backend/entity_p.h
+++ b/src/render/backend/entity_p.h
@@ -90,6 +90,7 @@ public:
void setParentHandle(HEntity parentHandle);
void setNodeManagers(NodeManagers *manager);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void dump() const;
@@ -97,11 +98,8 @@ public:
HEntity handle() const { return m_handle; }
Entity *parent() const;
HEntity parentHandle() const { return m_parentHandle; }
- Qt3DCore::QNodeId parentEntityId() const { return m_parentEntityId; }
-
- void clearEntityHierarchy();
- void rebuildEntityHierarchy();
+ void removeFromParentChildHandles();
void appendChildHandle(HEntity childHandle);
void removeChildHandle(HEntity childHandle) { m_childrenHandles.removeOne(childHandle); }
QVector<HEntity> childrenHandles() const { return m_childrenHandles; }
@@ -178,17 +176,12 @@ public:
return containsComponentsOfType<T>() && containsComponentsOfType<Ts, Ts2...>();
}
-
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
NodeManagers *m_nodeManagers;
HEntity m_handle;
HEntity m_parentHandle;
QVector<HEntity > m_childrenHandles;
- Qt3DCore::QNodeId m_parentEntityId;
-
HMatrix m_worldTransform;
QSharedPointer<Sphere> m_localBoundingVolume;
QSharedPointer<Sphere> m_worldBoundingVolume;
@@ -306,7 +299,7 @@ ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(ShaderData, HShaderData)
ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(Light, HLight)
ENTITY_COMPONENT_LIST_TEMPLATE_SPECIALIZATION(EnvironmentLight, HEnvironmentLight)
-class RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper
+class Q_AUTOTEST_EXPORT RenderEntityFunctor : public Qt3DCore::QBackendNodeMapper
{
public:
explicit RenderEntityFunctor(AbstractRenderer *renderer, NodeManagers *manager);
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 390ed4f05..6659657fa 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -68,17 +68,6 @@ void Transform::cleanup()
QBackendNode::setEnabled(false);
}
-void Transform::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QTransformData>>(change);
- const auto &data = typedChange->data;
- m_rotation = data.rotation;
- m_scale = data.scale;
- m_translation = data.translation;
- updateMatrix();
- markDirty(AbstractRenderer::TransformDirty);
-}
-
Matrix4x4 Transform::transformMatrix() const
{
return m_transformMatrix;
@@ -99,6 +88,7 @@ QVector3D Transform::translation() const
return m_translation;
}
+// TODOSYNC remove once we've found a way to propagate animation changes
void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
// TODO: Flag the matrix as dirty and update all matrices batched in a job
@@ -120,6 +110,27 @@ void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Transform::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QTransform *transform = qobject_cast<const Qt3DCore::QTransform *>(frontEnd);
+ if (!transform)
+ return;
+
+ bool dirty = m_rotation != transform->rotation();
+ m_rotation = transform->rotation();
+ dirty |= m_scale != transform->scale3D();
+ m_scale = transform->scale3D();
+ dirty |= m_translation != transform->translation();
+ m_translation = transform->translation();
+
+ if (dirty || firstTime) {
+ updateMatrix();
+ markDirty(AbstractRenderer::TransformDirty);
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
void Transform::notifyWorldTransformChanged(const Matrix4x4 &worldMatrix)
{
auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
diff --git a/src/render/backend/transform_p.h b/src/render/backend/transform_p.h
index e3bcad317..50857ac94 100644
--- a/src/render/backend/transform_p.h
+++ b/src/render/backend/transform_p.h
@@ -77,12 +77,11 @@ public:
QVector3D translation() const;
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) final;
void notifyWorldTransformChanged(const Matrix4x4 &worldMatrix);
private:
void updateMatrix();
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Matrix4x4 m_transformMatrix;
QQuaternion m_rotation;
QVector3D m_scale;
diff --git a/src/render/framegraph/blitframebuffer.cpp b/src/render/framegraph/blitframebuffer.cpp
index 342594baf..c45d3fdbc 100644
--- a/src/render/framegraph/blitframebuffer.cpp
+++ b/src/render/framegraph/blitframebuffer.cpp
@@ -60,48 +60,44 @@ BlitFramebuffer::BlitFramebuffer()
{
}
-void BlitFramebuffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void BlitFramebuffer::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("sourceRenderTarget")) {
- m_sourceRenderTargetId = propertyChange->value().value<QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationRenderTarget")) {
- m_destinationRenderTargetId = propertyChange->value().value<QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("sourceRect")) {
- m_sourceRect = propertyChange->value().toRect();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationRect")) {
- m_destinationRect = propertyChange->value().toRect();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("sourceAttachmentPoint")) {
- m_sourceAttachmentPoint = propertyChange->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationAttachmentPoint")) {
- m_destinationAttachmentPoint = propertyChange->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("interpolationMethod")) {
- m_interpolationMethod = propertyChange->value().value<QBlitFramebuffer::InterpolationMethod>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
+ const QBlitFramebuffer *node = qobject_cast<const QBlitFramebuffer *>(frontEnd);
+ if (!node)
+ return;
-void BlitFramebuffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBlitFramebufferData> >(change);
- const auto &data = typedChange->data;
- m_sourceRect = data.m_sourceRect;
- m_destinationRect = data.m_destinationRect;
- m_sourceRenderTargetId = data.m_sourceRenderTargetId;
- m_destinationRenderTargetId = data.m_destinationRenderTargetId;
- m_sourceAttachmentPoint = data.m_sourceAttachmentPoint;
- m_destinationAttachmentPoint = data.m_destinationAttachmentPoint;
- m_interpolationMethod = data.m_interpolationMethod;
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (node->sourceRect().toRect() != m_sourceRect) {
+ m_sourceRect = node->sourceRect().toRect();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->destinationRect().toRect() != m_destinationRect) {
+ m_destinationRect = node->destinationRect().toRect();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->sourceAttachmentPoint() != m_sourceAttachmentPoint) {
+ m_sourceAttachmentPoint = node->sourceAttachmentPoint();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->destinationAttachmentPoint() != m_destinationAttachmentPoint) {
+ m_destinationAttachmentPoint = node->destinationAttachmentPoint();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->interpolationMethod() != m_interpolationMethod) {
+ m_interpolationMethod = node->interpolationMethod();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ const QNodeId destinationNodeId = qIdForNode(node->destination());
+ if (destinationNodeId != m_destinationRenderTargetId) {
+ m_destinationRenderTargetId = destinationNodeId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ const QNodeId sourceNodeId = qIdForNode(node->source());
+ if (sourceNodeId != m_sourceRenderTargetId) {
+ m_sourceRenderTargetId = sourceNodeId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
Qt3DRender::QRenderTargetOutput::AttachmentPoint BlitFramebuffer::destinationAttachmentPoint() const
diff --git a/src/render/framegraph/blitframebuffer_p.h b/src/render/framegraph/blitframebuffer_p.h
index 796c223ca..fa9ddacd9 100644
--- a/src/render/framegraph/blitframebuffer_p.h
+++ b/src/render/framegraph/blitframebuffer_p.h
@@ -65,7 +65,7 @@ class Q_AUTOTEST_EXPORT BlitFramebuffer : public FrameGraphNode
public:
BlitFramebuffer();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::QNodeId sourceRenderTargetId() const;
@@ -82,8 +82,6 @@ public:
QBlitFramebuffer::InterpolationMethod interpolationMethod() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_sourceRenderTargetId;
Qt3DCore::QNodeId m_destinationRenderTargetId;
QRect m_sourceRect;
diff --git a/src/render/framegraph/cameraselectornode.cpp b/src/render/framegraph/cameraselectornode.cpp
index 357611c7c..482429b00 100644
--- a/src/render/framegraph/cameraselectornode.cpp
+++ b/src/render/framegraph/cameraselectornode.cpp
@@ -57,25 +57,19 @@ CameraSelector::CameraSelector()
{
}
-void CameraSelector::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void CameraSelector::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QCameraSelectorData>>(change);
- const auto &data = typedChange->data;
- m_cameraUuid = data.cameraId;
-}
+ const QCameraSelector *node = qobject_cast<const QCameraSelector *>(frontEnd);
+ if (!node)
+ return;
-void CameraSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- qCDebug(Render::Framegraph) << Q_FUNC_INFO;
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("camera")) {
- m_cameraUuid = propertyChange->value().value<QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const QNodeId cameraId = qIdForNode(node->camera());
+ if (m_cameraUuid != cameraId) {
+ m_cameraUuid = cameraId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
QNodeId CameraSelector::cameraUuid() const
diff --git a/src/render/framegraph/cameraselectornode_p.h b/src/render/framegraph/cameraselectornode_p.h
index 0e532d68f..dd7e050d0 100644
--- a/src/render/framegraph/cameraselectornode_p.h
+++ b/src/render/framegraph/cameraselectornode_p.h
@@ -69,12 +69,11 @@ class CameraSelector : public FrameGraphNode
public:
CameraSelector();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
Qt3DCore::QNodeId cameraUuid() const;
-private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+private:
Qt3DCore::QNodeId m_cameraUuid;
};
diff --git a/src/render/framegraph/clearbuffers.cpp b/src/render/framegraph/clearbuffers.cpp
index ab6225a4b..98de30906 100644
--- a/src/render/framegraph/clearbuffers.cpp
+++ b/src/render/framegraph/clearbuffers.cpp
@@ -61,42 +61,40 @@ ClearBuffers::ClearBuffers()
{
}
-void ClearBuffers::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void ClearBuffers::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QClearBuffersData>>(change);
- const auto &data = typedChange->data;
- m_type = data.buffersType;
- m_clearColorAsColor = data.clearColor;
- m_clearColor = vec4dFromColor(m_clearColorAsColor);
- m_clearDepthValue = data.clearDepthValue;
- m_clearStencilValue = data.clearStencilValue;
- m_colorBufferId = data.bufferId;
-}
+ const QClearBuffers *node = qobject_cast<const QClearBuffers *>(frontEnd);
+ if (!node)
+ return;
-void ClearBuffers::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("buffers")) {
- m_type = static_cast<QClearBuffers::BufferType>(propertyChange->value().toInt());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("clearColor")) {
- m_clearColorAsColor = propertyChange->value().value<QColor>();
- m_clearColor = vec4dFromColor(m_clearColorAsColor);
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("clearDepthValue")) {
- m_clearDepthValue = propertyChange->value().toFloat();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("clearStencilValue")) {
- m_clearStencilValue = propertyChange->value().toInt();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("colorBuffer")) {
- m_colorBufferId = propertyChange->value().value<QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (m_clearColorAsColor != node->clearColor()) {
+ m_clearColorAsColor = node->clearColor();
+ m_clearColor = vec4dFromColor(node->clearColor());
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (m_clearDepthValue != node->clearDepthValue()) {
+ m_clearDepthValue = node->clearDepthValue();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (m_clearStencilValue != node->clearStencilValue()) {
+ m_clearStencilValue = node->clearStencilValue();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ const QNodeId colorBufferId = qIdForNode(node->colorBuffer());
+ if (m_colorBufferId != colorBufferId) {
+ m_colorBufferId = colorBufferId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (m_type != node->buffers()) {
+ m_type = node->buffers();
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
QClearBuffers::BufferType ClearBuffers::type() const
diff --git a/src/render/framegraph/clearbuffers_p.h b/src/render/framegraph/clearbuffers_p.h
index e3c56c165..ca55d2a98 100644
--- a/src/render/framegraph/clearbuffers_p.h
+++ b/src/render/framegraph/clearbuffers_p.h
@@ -67,8 +67,6 @@ class ClearBuffers : public FrameGraphNode
public:
ClearBuffers();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
-
QClearBuffers::BufferType type() const;
float clearDepthValue() const;
int clearStencilValue() const;
@@ -85,10 +83,9 @@ public:
QColor clearColorAsColor() const;
bool clearsAllColorBuffers() const;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QClearBuffers::BufferType m_type;
QVector4D m_clearColor;
QColor m_clearColorAsColor;
diff --git a/src/render/framegraph/dispatchcompute.cpp b/src/render/framegraph/dispatchcompute.cpp
index f7e9dcff4..5eae75bc6 100644
--- a/src/render/framegraph/dispatchcompute.cpp
+++ b/src/render/framegraph/dispatchcompute.cpp
@@ -66,32 +66,26 @@ void DispatchCompute::cleanup()
m_workGroups[2] = 1;
}
-void DispatchCompute::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void DispatchCompute::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QDispatchComputeData>>(change);
- const auto &data = typedChange->data;
- m_workGroups[0] = data.workGroupX;
- m_workGroups[1] = data.workGroupY;
- m_workGroups[2] = data.workGroupZ;
-}
+ const QDispatchCompute *node = qobject_cast<const QDispatchCompute *>(frontEnd);
+ if (!node)
+ return;
-void DispatchCompute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("workGroupX")) {
- m_workGroups[0] = propertyChange->value().toInt();
- markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("workGroupY")) {
- m_workGroups[1] = propertyChange->value().toInt();
- markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("workGroupZ")) {
- m_workGroups[2] = propertyChange->value().toInt();
- markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (m_workGroups[0] != node->workGroupX()) {
+ m_workGroups[0] = node->workGroupX();
+ markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
+ }
+ if (m_workGroups[1] != node->workGroupY()) {
+ m_workGroups[1] = node->workGroupY();
+ markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
+ }
+ if (m_workGroups[2] != node->workGroupZ()) {
+ m_workGroups[2] = node->workGroupZ();
+ markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::ComputeDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
} // Render
diff --git a/src/render/framegraph/dispatchcompute_p.h b/src/render/framegraph/dispatchcompute_p.h
index aa88a35c5..24a641938 100644
--- a/src/render/framegraph/dispatchcompute_p.h
+++ b/src/render/framegraph/dispatchcompute_p.h
@@ -68,13 +68,13 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
inline int x() const Q_DECL_NOTHROW { return m_workGroups[0]; }
inline int y() const Q_DECL_NOTHROW { return m_workGroups[1]; }
inline int z() const Q_DECL_NOTHROW { return m_workGroups[2]; }
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
int m_workGroups[3];
};
diff --git a/src/render/framegraph/framegraphnode.cpp b/src/render/framegraph/framegraphnode.cpp
index 458d96d4b..93531fd7d 100644
--- a/src/render/framegraph/framegraphnode.cpp
+++ b/src/render/framegraph/framegraphnode.cpp
@@ -66,14 +66,6 @@ FrameGraphNode::~FrameGraphNode()
{
}
-void FrameGraphNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- // Set up the parent child relationship and enabled state
- const auto creationChange = qSharedPointerCast<QFrameGraphNodeCreatedChangeBase>(change);
- setParentId(creationChange->parentFrameGraphNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
-}
-
void FrameGraphNode::setFrameGraphManager(FrameGraphManager *manager)
{
if (m_manager != manager)
@@ -129,34 +121,33 @@ QVector<FrameGraphNode *> FrameGraphNode::children() const
return children;
}
-void FrameGraphNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void FrameGraphNode::cleanup()
{
- switch (e->type()) {
-
- case Qt3DCore::PropertyUpdated: {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) {
- d_func()->m_enabled = propertyChange->value().toBool();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("parentFrameGraphUpdated")) {
- auto newParent = propertyChange->value().value<Qt3DCore::QNodeId>();
- setParentId(newParent);
- markDirty(AbstractRenderer::AllDirty);
- }
- break;
- }
- default:
- markDirty(AbstractRenderer::AllDirty);
- break;
- }
+ setParentId({});
}
-void FrameGraphNode::cleanup()
+void FrameGraphNode::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- setParentId({});
+ const QFrameGraphNode *node = qobject_cast<const QFrameGraphNode *>(frontEnd);
+
+ const auto parentId = Qt3DCore::qIdForNode(node->parentFrameGraphNode());
+ if (parentId != m_parentId) {
+ setParentId(parentId);
+ // TO DO: Check if FrameGraphDirty wouldn't be enough here
+ markDirty(AbstractRenderer::AllDirty);
+ }
+
+ if (node->isEnabled() != d_func()->m_enabled) {
+ d_func()->m_enabled = node->isEnabled();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (firstTime)
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h
index 3edd4f57d..846dc8060 100644
--- a/src/render/framegraph/framegraphnode_p.h
+++ b/src/render/framegraph/framegraphnode_p.h
@@ -121,11 +121,10 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
protected:
FrameGraphNode(FrameGraphNodeType nodeType, QBackendNode::Mode mode = QBackendNode::ReadOnly);
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override;
private:
FrameGraphNodeType m_nodeType;
diff --git a/src/render/framegraph/layerfilternode.cpp b/src/render/framegraph/layerfilternode.cpp
index f9881be0d..5c53fa681 100644
--- a/src/render/framegraph/layerfilternode.cpp
+++ b/src/render/framegraph/layerfilternode.cpp
@@ -43,6 +43,7 @@
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -57,48 +58,25 @@ LayerFilterNode::LayerFilterNode()
{
}
-void LayerFilterNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void LayerFilterNode::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QLayerFilterData>>(change);
- const auto &data = typedChange->data;
- setLayerIds(data.layerIds);
- m_filterMode = data.filterMode;
-}
+ const QLayerFilter *node = qobject_cast<const QLayerFilter *>(frontEnd);
+ if (!node)
+ return;
-void LayerFilterNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("layer"))
- m_layerIds.append(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::LayersDirty);
- break;
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("layer"))
- m_layerIds.removeOne(change->removedNodeId());
+ if (m_filterMode != node->filterMode()) {
+ m_filterMode = node->filterMode();
markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::LayersDirty);
- break;
}
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("filterMode")) {
- m_filterMode = static_cast<QLayerFilter::FilterMode>(change->value().value<int>());
- markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::LayersDirty);
- break;
- }
- }
-
- default:
- break;
+ auto layerIds = qIdsForNodes(node->layers());
+ std::sort(std::begin(layerIds), std::end(layerIds));
+ if (m_layerIds != layerIds) {
+ m_layerIds = layerIds;
+ markDirty(AbstractRenderer::FrameGraphDirty|AbstractRenderer::LayersDirty);
}
-
- FrameGraphNode::sceneChangeEvent(e);
}
QNodeIdVector LayerFilterNode::layerIds() const
diff --git a/src/render/framegraph/layerfilternode_p.h b/src/render/framegraph/layerfilternode_p.h
index 18ba4ee7a..27cdc49d3 100644
--- a/src/render/framegraph/layerfilternode_p.h
+++ b/src/render/framegraph/layerfilternode_p.h
@@ -53,6 +53,7 @@
#include <Qt3DRender/private/framegraphnode_p.h>
#include <Qt3DRender/QLayerFilter>
+#include <Qt3DRender/QLayer>
#include <QStringList>
QT_BEGIN_NAMESPACE
@@ -68,15 +69,14 @@ class LayerFilterNode : public FrameGraphNode
public:
LayerFilterNode();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+
Qt3DCore::QNodeIdVector layerIds() const;
void setLayerIds(const Qt3DCore::QNodeIdVector &list);
QLayerFilter::FilterMode filterMode() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeIdVector m_layerIds;
QLayerFilter::FilterMode m_filterMode;
};
diff --git a/src/render/framegraph/memorybarrier.cpp b/src/render/framegraph/memorybarrier.cpp
index 59b3071ab..6bfaedda7 100644
--- a/src/render/framegraph/memorybarrier.cpp
+++ b/src/render/framegraph/memorybarrier.cpp
@@ -62,24 +62,18 @@ QMemoryBarrier::Operations MemoryBarrier::waitOperations() const
return m_waitOperations;
}
-void MemoryBarrier::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void MemoryBarrier::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("waitOperations")) {
- m_waitOperations = propertyChange->value().value<QMemoryBarrier::Operations>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
+ const QMemoryBarrier *node = qobject_cast<const QMemoryBarrier *>(frontEnd);
+ if (!node)
+ return;
-void MemoryBarrier::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QMemoryBarrierData>>(change);
- const QMemoryBarrierData &data = typedChange->data;
- m_waitOperations = data.waitOperations;
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (node->waitOperations() != m_waitOperations) {
+ m_waitOperations = node->waitOperations();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
} // Render
diff --git a/src/render/framegraph/memorybarrier_p.h b/src/render/framegraph/memorybarrier_p.h
index e0fd3e9cd..ce545cd09 100644
--- a/src/render/framegraph/memorybarrier_p.h
+++ b/src/render/framegraph/memorybarrier_p.h
@@ -67,10 +67,9 @@ public:
~MemoryBarrier();
QMemoryBarrier::Operations waitOperations() const;
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
QMemoryBarrier::Operations m_waitOperations;
};
diff --git a/src/render/framegraph/proximityfilter.cpp b/src/render/framegraph/proximityfilter.cpp
index cdfd7e51e..593e541bc 100644
--- a/src/render/framegraph/proximityfilter.cpp
+++ b/src/render/framegraph/proximityfilter.cpp
@@ -53,29 +53,24 @@ ProximityFilter::ProximityFilter()
{
}
-void ProximityFilter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void ProximityFilter::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QProximityFilterData>>(change);
- const QProximityFilterData &data = typedChange->data;
- m_entityId = data.entityId;
- m_distanceThreshold = data.distanceThreshold;
-}
+ const QProximityFilter *node = qobject_cast<const QProximityFilter *>(frontEnd);
+ if (!node)
+ return;
-void ProximityFilter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- qCDebug(Render::Framegraph) << Q_FUNC_INFO;
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("entity")) {
- m_entityId = propertyChange->value().value<Qt3DCore::QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("distanceThreshold")) {
- m_distanceThreshold = propertyChange->value().toFloat();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const auto entityId = Qt3DCore::qIdForNode(node->entity());
+ if (entityId != m_entityId) {
+ m_entityId = entityId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (node->distanceThreshold() != m_distanceThreshold) {
+ m_distanceThreshold = node->distanceThreshold();
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
} // namespace Render
diff --git a/src/render/framegraph/proximityfilter_p.h b/src/render/framegraph/proximityfilter_p.h
index e57b53dea..5c2f7ad66 100644
--- a/src/render/framegraph/proximityfilter_p.h
+++ b/src/render/framegraph/proximityfilter_p.h
@@ -64,7 +64,7 @@ class Q_AUTOTEST_EXPORT ProximityFilter : public FrameGraphNode
public:
ProximityFilter();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
float distanceThreshold() const { return m_distanceThreshold; }
Qt3DCore::QNodeId entityId() const { return m_entityId; }
@@ -76,8 +76,6 @@ public:
#endif
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
float m_distanceThreshold;
Qt3DCore::QNodeId m_entityId;
};
diff --git a/src/render/framegraph/qblitframebuffer.cpp b/src/render/framegraph/qblitframebuffer.cpp
index d0e1bdbf3..bf9e547cb 100644
--- a/src/render/framegraph/qblitframebuffer.cpp
+++ b/src/render/framegraph/qblitframebuffer.cpp
@@ -364,6 +364,7 @@ void QBlitFramebuffer::setDestination(QRenderTarget *destination)
}
}
+// TO DO Qt6: convert QRectF to QRect
/*!
Sets the source rectangle to \a inputRect. The coordinates are assumed to
follow the normal Qt coordinate system, meaning Y runs from top to bottom.
diff --git a/src/render/framegraph/qframegraphnode.cpp b/src/render/framegraph/qframegraphnode.cpp
index d52b728a8..1ef81a081 100644
--- a/src/render/framegraph/qframegraphnode.cpp
+++ b/src/render/framegraph/qframegraphnode.cpp
@@ -258,13 +258,9 @@ Qt3DCore::QNodeCreatedChangeBasePtr QFrameGraphNode::createNodeCreationChange()
void QFrameGraphNode::onParentChanged(QObject *)
{
- const auto parentID = parentFrameGraphNode() ? parentFrameGraphNode()->id() : Qt3DCore::QNodeId();
- auto parentChange = Qt3DCore::QPropertyUpdatedChangePtr::create(id());
- parentChange->setPropertyName("parentFrameGraphUpdated");
- parentChange->setValue(QVariant::fromValue(parentID));
- const bool blocked = blockNotifications(false);
- notifyObservers(parentChange);
- blockNotifications(blocked);
+ // Direct sync update request
+ Q_D(QFrameGraphNode);
+ d->update();
}
} // namespace Qt3DRender
diff --git a/src/render/framegraph/qlayerfilter.cpp b/src/render/framegraph/qlayerfilter.cpp
index 04ebca572..8b0dd5669 100644
--- a/src/render/framegraph/qlayerfilter.cpp
+++ b/src/render/framegraph/qlayerfilter.cpp
@@ -206,11 +206,7 @@ void QLayerFilter::addLayer(QLayer *layer)
if (!layer->parent())
layer->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), layer);
- change->setPropertyName("layer");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -221,11 +217,7 @@ void QLayerFilter::removeLayer(QLayer *layer)
{
Q_ASSERT(layer);
Q_D(QLayerFilter);
- if (d->m_changeArbiter != nullptr) {
- const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), layer);
- change->setPropertyName("layer");
- d->notifyObservers(change);
- }
+ d->update();
d->m_layers.removeOne(layer);
// Remove bookkeeping connection
d->unregisterDestructionHelper(layer);
diff --git a/src/render/framegraph/qrendercapture.cpp b/src/render/framegraph/qrendercapture.cpp
index 21eee51f6..cc74553b2 100644
--- a/src/render/framegraph/qrendercapture.cpp
+++ b/src/render/framegraph/qrendercapture.cpp
@@ -330,11 +330,9 @@ QRenderCaptureReply *QRenderCapture::requestCapture(int captureId)
d->replyDestroyed(reply);
});
- Qt3DCore::QPropertyUpdatedChangePtr change(new Qt3DCore::QPropertyUpdatedChange(id()));
- change->setPropertyName(QByteArrayLiteral("renderCaptureRequest"));
const QRenderCaptureRequest request = { captureId, QRect() };
- change->setValue(QVariant::fromValue(request));
- d->notifyObservers(change);
+ d->m_pendingRequests.push_back(request);
+ d->update();
return reply;
}
@@ -355,11 +353,9 @@ QRenderCaptureReply *QRenderCapture::requestCapture(const QRect &rect)
d->replyDestroyed(reply);
});
- Qt3DCore::QPropertyUpdatedChangePtr change(new Qt3DCore::QPropertyUpdatedChange(id()));
- change->setPropertyName(QByteArrayLiteral("renderCaptureRequest"));
const QRenderCaptureRequest request = { captureId, rect };
- change->setValue(QVariant::fromValue(request));
- d->notifyObservers(change);
+ d->m_pendingRequests.push_back(request);
+ d->update();
captureId++;
diff --git a/src/render/framegraph/qrendercapture_p.h b/src/render/framegraph/qrendercapture_p.h
index 4e509cc59..3dec4d280 100644
--- a/src/render/framegraph/qrendercapture_p.h
+++ b/src/render/framegraph/qrendercapture_p.h
@@ -57,6 +57,12 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+struct QRenderCaptureRequest
+{
+ int captureId;
+ QRect rect;
+};
+
class QRenderCapturePrivate : public QFrameGraphNodePrivate
{
public:
@@ -64,6 +70,7 @@ public:
~QRenderCapturePrivate();
QVector<QRenderCaptureReply *> m_waitingReplies;
QMutex m_mutex;
+ mutable QVector<QRenderCaptureRequest> m_pendingRequests;
QRenderCaptureReply *createReply(int captureId);
QRenderCaptureReply *takeReply(int captureId);
@@ -82,6 +89,7 @@ public:
int m_captureId;
bool m_complete;
+
Q_DECLARE_PUBLIC(QRenderCaptureReply)
};
@@ -100,12 +108,6 @@ struct RenderCaptureData
typedef QSharedPointer<RenderCaptureData> RenderCaptureDataPtr;
-struct QRenderCaptureRequest
-{
- int captureId;
- QRect rect;
-};
-
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/framegraph/qrenderpassfilter.cpp b/src/render/framegraph/qrenderpassfilter.cpp
index 56c229d9c..4ef7e6d2d 100644
--- a/src/render/framegraph/qrenderpassfilter.cpp
+++ b/src/render/framegraph/qrenderpassfilter.cpp
@@ -142,11 +142,7 @@ void QRenderPassFilter::addMatch(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("match");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -158,11 +154,7 @@ void QRenderPassFilter::removeMatch(QFilterKey *filterKey)
Q_ASSERT(filterKey);
Q_D(QRenderPassFilter);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("match");
- d->notifyObservers(change);
- }
+ d->update();
d->m_matchList.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -188,11 +180,7 @@ void QRenderPassFilter::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -204,11 +192,7 @@ void QRenderPassFilter::removeParameter(QParameter *parameter)
Q_ASSERT(parameter);
Q_D(QRenderPassFilter);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
diff --git a/src/render/framegraph/qrenderstateset.cpp b/src/render/framegraph/qrenderstateset.cpp
index 6f70456ab..d558a939e 100644
--- a/src/render/framegraph/qrenderstateset.cpp
+++ b/src/render/framegraph/qrenderstateset.cpp
@@ -194,11 +194,7 @@ void QRenderStateSet::addRenderState(QRenderState *state)
if (!state->parent())
state->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -210,11 +206,7 @@ void QRenderStateSet::removeRenderState(QRenderState *state)
Q_ASSERT(state);
Q_D(QRenderStateSet);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
d->m_renderStates.removeOne(state);
// Remove bookkeeping connection
d->unregisterDestructionHelper(state);
diff --git a/src/render/framegraph/qrendersurfaceselector.cpp b/src/render/framegraph/qrendersurfaceselector.cpp
index 848d86f53..765aa1824 100644
--- a/src/render/framegraph/qrendersurfaceselector.cpp
+++ b/src/render/framegraph/qrendersurfaceselector.cpp
@@ -253,24 +253,10 @@ void QRenderSurfaceSelector::setSurface(QObject *surfaceObject)
if (window) {
d->m_widthConn = QObject::connect(window, &QWindow::widthChanged, [=] (int width) {
- if (d->m_changeArbiter != nullptr) {
- Qt3DCore::QPropertyUpdatedChangePtr change(
- new Qt3DCore::QPropertyUpdatedChange(id()));
-
- change->setPropertyName("width");
- change->setValue(QVariant::fromValue(width));
- d->notifyObservers(change);
- }
+ d->update();
});
d->m_heightConn = QObject::connect(window, &QWindow::heightChanged, [=] (int height) {
- if (d->m_changeArbiter != nullptr) {
- Qt3DCore::QPropertyUpdatedChangePtr change(
- new Qt3DCore::QPropertyUpdatedChange(id()));
-
- change->setPropertyName("height");
- change->setValue(QVariant::fromValue(height));
- d->notifyObservers(change);
- }
+ d->update();
});
d->m_screenConn = QObject::connect(window, &QWindow::screenChanged, [=] (QScreen *screen) {
if (screen && surfacePixelRatio() != screen->devicePixelRatio())
diff --git a/src/render/framegraph/qrendertargetselector.cpp b/src/render/framegraph/qrendertargetselector.cpp
index 1b4afc7e6..f4d95d507 100644
--- a/src/render/framegraph/qrendertargetselector.cpp
+++ b/src/render/framegraph/qrendertargetselector.cpp
@@ -153,13 +153,7 @@ void QRenderTargetSelector::setOutputs(const QVector<QRenderTargetOutput::Attach
Q_D(QRenderTargetSelector);
if (buffers != d->m_outputs) {
d->m_outputs = buffers;
-
- if (d->m_changeArbiter) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("outputs");
- change->setValue(QVariant::fromValue(d->m_outputs));
- d->notifyObservers(change);
- }
+ d->update();
}
}
diff --git a/src/render/framegraph/qsortpolicy.cpp b/src/render/framegraph/qsortpolicy.cpp
index 6f852afbd..c8e3d23c5 100644
--- a/src/render/framegraph/qsortpolicy.cpp
+++ b/src/render/framegraph/qsortpolicy.cpp
@@ -178,7 +178,10 @@ void QSortPolicy::setSortTypes(const QVector<SortType> &sortTypes)
if (sortTypes != d->m_sortTypes) {
d->m_sortTypes = sortTypes;
emit sortTypesChanged(sortTypes);
+
+ const bool wasBlocked = blockNotifications(true);
emit sortTypesChanged(sortTypesInt());
+ blockNotifications(wasBlocked);
}
}
diff --git a/src/render/framegraph/qtechniquefilter.cpp b/src/render/framegraph/qtechniquefilter.cpp
index 404ad6991..28b151fc7 100644
--- a/src/render/framegraph/qtechniquefilter.cpp
+++ b/src/render/framegraph/qtechniquefilter.cpp
@@ -147,11 +147,7 @@ void QTechniqueFilter::addMatch(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("matchAll");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -162,11 +158,7 @@ void QTechniqueFilter::removeMatch(QFilterKey *filterKey)
{
Q_ASSERT(filterKey);
Q_D(QTechniqueFilter);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("matchAll");
- d->notifyObservers(change);
- }
+ d->update();
d->m_matchList.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -192,11 +184,7 @@ void QTechniqueFilter::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -207,11 +195,7 @@ void QTechniqueFilter::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QTechniqueFilter);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
diff --git a/src/render/framegraph/rendercapture.cpp b/src/render/framegraph/rendercapture.cpp
index 166294889..68d62b6a5 100644
--- a/src/render/framegraph/rendercapture.cpp
+++ b/src/render/framegraph/rendercapture.cpp
@@ -70,16 +70,23 @@ QRenderCaptureRequest RenderCapture::takeCaptureRequest()
return m_requestedCaptures.takeFirst();
}
-void RenderCapture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void RenderCapture::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("renderCaptureRequest")) {
- requestCapture(propertyChange->value().value<QRenderCaptureRequest>());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ const QRenderCapture *node = qobject_cast<const QRenderCapture *>(frontEnd);
+ if (!node)
+ return;
+
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const QRenderCapturePrivate *d = static_cast<const QRenderCapturePrivate *>(QFrameGraphNodePrivate::get(node));
+ const auto newPendingsCaptures = std::move(d->m_pendingRequests);
+ if (newPendingsCaptures.size() > 0) {
+ m_requestedCaptures.append(newPendingsCaptures);
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
+
+ if (firstTime)
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
// called by render thread
diff --git a/src/render/framegraph/rendercapture_p.h b/src/render/framegraph/rendercapture_p.h
index 71fa01ec1..4560c525d 100644
--- a/src/render/framegraph/rendercapture_p.h
+++ b/src/render/framegraph/rendercapture_p.h
@@ -68,8 +68,7 @@ public:
void addRenderCapture(int captureId, const QImage &image);
void sendRenderCaptures();
-protected:
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) final;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
diff --git a/src/render/framegraph/renderpassfilternode.cpp b/src/render/framegraph/renderpassfilternode.cpp
index e3da1e36d..afc49a563 100644
--- a/src/render/framegraph/renderpassfilternode.cpp
+++ b/src/render/framegraph/renderpassfilternode.cpp
@@ -58,16 +58,33 @@ RenderPassFilter::RenderPassFilter()
{
}
-void RenderPassFilter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void RenderPassFilter::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderPassFilterData>>(change);
- const auto &data = typedChange->data;
- m_filters = data.matchIds;
- m_parameterPack.clear();
- m_parameterPack.setParameters(data.parameterIds);
+ const QRenderPassFilter *node = qobject_cast<const QRenderPassFilter *>(frontEnd);
+ if (!node)
+ return;
+
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (firstTime)
+ m_parameterPack.clear();
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters) {
+ m_parameterPack.setParameters(parameters);
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ auto filterIds = qIdsForNodes(node->matchAny());
+ std::sort(std::begin(filterIds), std::end(filterIds));
+ if (m_filters != filterIds) {
+ m_filters = filterIds;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
+
QVector<Qt3DCore::QNodeId> RenderPassFilter::filters() const
{
return m_filters;
@@ -89,40 +106,6 @@ QVector<Qt3DCore::QNodeId> RenderPassFilter::parameters() const
return m_parameterPack.parameters();
}
-void RenderPassFilter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
-
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("match")) {
- appendFilter(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.appendParameter(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("match")) {
- removeFilter(change->removedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.removeParameter(change->removedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
-
- default:
- break;
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
-
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/framegraph/renderpassfilternode_p.h b/src/render/framegraph/renderpassfilternode_p.h
index 398d42049..157a162bb 100644
--- a/src/render/framegraph/renderpassfilternode_p.h
+++ b/src/render/framegraph/renderpassfilternode_p.h
@@ -76,11 +76,9 @@ public:
QVector<Qt3DCore::QNodeId> parameters() const;
void appendFilter(Qt3DCore::QNodeId criterionId);
void removeFilter(Qt3DCore::QNodeId criterionId);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DCore::QNodeId> m_filters;
ParameterPack m_parameterPack;
};
diff --git a/src/render/framegraph/rendersurfaceselector.cpp b/src/render/framegraph/rendersurfaceselector.cpp
index 16a1199b5..173da77d6 100644
--- a/src/render/framegraph/rendersurfaceselector.cpp
+++ b/src/render/framegraph/rendersurfaceselector.cpp
@@ -73,6 +73,7 @@ namespace Render {
RenderSurfaceSelector::RenderSurfaceSelector()
: FrameGraphNode(FrameGraphNode::Surface)
+ , m_surfaceObj(nullptr)
, m_surface(nullptr)
, m_width(0)
, m_height(0)
@@ -80,45 +81,41 @@ RenderSurfaceSelector::RenderSurfaceSelector()
{
}
-void RenderSurfaceSelector::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void RenderSurfaceSelector::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderSurfaceSelectorData>>(change);
- const auto &data = typedChange->data;
- m_surface = surfaceFromQObject(data.surface);
- m_renderTargetSize = data.externalRenderTargetSize;
- m_devicePixelRatio = data.surfacePixelRatio;
+ const QRenderSurfaceSelector *node = qobject_cast<const QRenderSurfaceSelector *>(frontEnd);
+ if (!node)
+ return;
- if (m_surface && m_surface->surfaceClass() == QSurface::Window) {
- QWindow *window = static_cast<QWindow *>(m_surface);
- m_width = window->width();
- m_height = window->height();
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (node->surface() != m_surfaceObj) {
+ m_surfaceObj = node->surface();
+ m_surface = surfaceFromQObject(m_surfaceObj);
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
-}
-void RenderSurfaceSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- qCDebug(Render::Framegraph) << Q_FUNC_INFO;
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("surface")) {
- m_surface = surfaceFromQObject(propertyChange->value().value<QObject *>());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("externalRenderTargetSize")) {
- setRenderTargetSize(propertyChange->value().toSize());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("width")) {
- m_width = propertyChange->value().toInt();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("height")) {
- m_height = propertyChange->value().toInt();
+ if (m_surface && m_surface->surfaceClass() == QSurface::Window) {
+ QWindow *window = static_cast<QWindow *>(m_surface);
+ if (window->width() != m_width) {
+ m_width = window->width();
markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("surfacePixelRatio")) {
- m_devicePixelRatio = propertyChange->value().toFloat();
+ }
+ if (window->height() != m_height) {
+ m_height = window->height();
markDirty(AbstractRenderer::FrameGraphDirty);
}
}
- FrameGraphNode::sceneChangeEvent(e);
+
+ if (node->externalRenderTargetSize() != m_renderTargetSize) {
+ m_renderTargetSize = node->externalRenderTargetSize();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (node->surfacePixelRatio() != m_devicePixelRatio) {
+ m_devicePixelRatio = node->surfacePixelRatio();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
QSize RenderSurfaceSelector::renderTargetSize() const
diff --git a/src/render/framegraph/rendersurfaceselector_p.h b/src/render/framegraph/rendersurfaceselector_p.h
index 74863aa36..f1a139e84 100644
--- a/src/render/framegraph/rendersurfaceselector_p.h
+++ b/src/render/framegraph/rendersurfaceselector_p.h
@@ -68,7 +68,7 @@ public:
QSize renderTargetSize() const;
void setRenderTargetSize(const QSize &size) { m_renderTargetSize = size; }
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QSurface *surface() const { return m_surface; }
inline int width() const Q_DECL_NOTHROW { return m_width; }
@@ -76,8 +76,7 @@ public:
inline float devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
+ QObject *m_surfaceObj;
QSurface *m_surface;
QSize m_renderTargetSize;
int m_width;
diff --git a/src/render/framegraph/rendertargetselectornode.cpp b/src/render/framegraph/rendertargetselectornode.cpp
index 615608bd2..871a00154 100644
--- a/src/render/framegraph/rendertargetselectornode.cpp
+++ b/src/render/framegraph/rendertargetselectornode.cpp
@@ -59,29 +59,24 @@ RenderTargetSelector::RenderTargetSelector() :
{
}
-void RenderTargetSelector::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void RenderTargetSelector::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderTargetSelectorData>>(change);
- const auto &data = typedChange->data;
- m_renderTargetUuid = data.targetId;
- m_outputs = data.outputs;
-}
+ const QRenderTargetSelector *node = qobject_cast<const QRenderTargetSelector *>(frontEnd);
+ if (!node)
+ return;
-void RenderTargetSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- qCDebug(Render::Framegraph) << Q_FUNC_INFO;
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("target")) {
- m_renderTargetUuid = propertyChange->value().value<QNodeId>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("outputs")) {
- m_outputs = propertyChange->value().value<QVector<Qt3DRender::QRenderTargetOutput::AttachmentPoint> >();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const QNodeId renderTargetId = qIdForNode(node->target());
+ if (renderTargetId != m_renderTargetUuid) {
+ m_renderTargetUuid = renderTargetId;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (node->outputs() != m_outputs) {
+ m_outputs = node->outputs();
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
} // namespace Render
diff --git a/src/render/framegraph/rendertargetselectornode_p.h b/src/render/framegraph/rendertargetselectornode_p.h
index 81ac8a3d3..232ee9ecc 100644
--- a/src/render/framegraph/rendertargetselectornode_p.h
+++ b/src/render/framegraph/rendertargetselectornode_p.h
@@ -66,14 +66,12 @@ class RenderTargetSelector : public FrameGraphNode
public:
RenderTargetSelector();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::QNodeId renderTargetUuid() const { return m_renderTargetUuid; }
QVector<QRenderTargetOutput::AttachmentPoint> outputs() const { return m_outputs; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_renderTargetUuid;
QVector<QRenderTargetOutput::AttachmentPoint> m_outputs;
};
diff --git a/src/render/framegraph/sortpolicy.cpp b/src/render/framegraph/sortpolicy.cpp
index b81d1f6cb..3c7975945 100644
--- a/src/render/framegraph/sortpolicy.cpp
+++ b/src/render/framegraph/sortpolicy.cpp
@@ -53,18 +53,19 @@ SortPolicy::SortPolicy()
{
}
-void SortPolicy::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void SortPolicy::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("sortTypes")) {
- auto sortTypesInt = propertyChange->value().value<QVector<int>>();
- m_sortTypes.clear();
- transformVector(sortTypesInt, m_sortTypes);
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
+ const QSortPolicy *node = qobject_cast<const QSortPolicy *>(frontEnd);
+ if (!node)
+ return;
+
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const auto sortTypes = node->sortTypes();
+ if (sortTypes != m_sortTypes) {
+ m_sortTypes = sortTypes;
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
QVector<QSortPolicy::SortType> SortPolicy::sortTypes() const
@@ -72,14 +73,6 @@ QVector<QSortPolicy::SortType> SortPolicy::sortTypes() const
return m_sortTypes;
}
-void SortPolicy::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
-{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QSortPolicyData>>(change);
- const QSortPolicyData &data = typedChange->data;
- m_sortTypes = data.sortTypes;
-}
-
} // namepace Render
} // namespace Qt3DRender
diff --git a/src/render/framegraph/sortpolicy_p.h b/src/render/framegraph/sortpolicy_p.h
index ef928af7b..8d572ead7 100644
--- a/src/render/framegraph/sortpolicy_p.h
+++ b/src/render/framegraph/sortpolicy_p.h
@@ -65,13 +65,11 @@ class Q_AUTOTEST_EXPORT SortPolicy : public FrameGraphNode
public:
SortPolicy();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QVector<Qt3DRender::QSortPolicy::SortType> sortTypes() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DRender::QSortPolicy::SortType> m_sortTypes;
};
diff --git a/src/render/framegraph/statesetnode.cpp b/src/render/framegraph/statesetnode.cpp
index 96551684e..32ac5e569 100644
--- a/src/render/framegraph/statesetnode.cpp
+++ b/src/render/framegraph/statesetnode.cpp
@@ -68,40 +68,20 @@ QVector<QNodeId> StateSetNode::renderStates() const
return m_renderStates;
}
-void StateSetNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void StateSetNode::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderStateSetData>>(change);
- const auto &data = typedChange->data;
- for (const auto &stateId : qAsConst(data.renderStateIds))
- addRenderState(stateId);
-}
+ const QRenderStateSet *node = qobject_cast<const QRenderStateSet *>(frontEnd);
+ if (!node)
+ return;
-void StateSetNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("renderState")) {
- addRenderState(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
-
- case PropertyValueRemoved: {
- const auto propertyChange = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("renderState")) {
- removeRenderState(propertyChange->removedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
- default:
- break;
+ auto stateIds = qIdsForNodes(node->renderStates());
+ std::sort(std::begin(stateIds), std::end(stateIds));
+ if (m_renderStates != stateIds) {
+ m_renderStates = stateIds;
+ markDirty(AbstractRenderer::FrameGraphDirty);
}
- FrameGraphNode::sceneChangeEvent(e);
}
void StateSetNode::addRenderState(QNodeId renderStateId)
diff --git a/src/render/framegraph/statesetnode_p.h b/src/render/framegraph/statesetnode_p.h
index d33e118cb..5081f3215 100644
--- a/src/render/framegraph/statesetnode_p.h
+++ b/src/render/framegraph/statesetnode_p.h
@@ -68,13 +68,13 @@ public:
inline bool hasRenderStates() const { return !m_renderStates.empty(); }
QVector<Qt3DCore::QNodeId> renderStates() const;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+
protected:
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
void addRenderState(Qt3DCore::QNodeId renderStateId);
void removeRenderState(Qt3DCore::QNodeId renderStateId);
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
QVector<Qt3DCore::QNodeId> m_renderStates;
};
diff --git a/src/render/framegraph/techniquefilternode.cpp b/src/render/framegraph/techniquefilternode.cpp
index 8816984ee..8739143e6 100644
--- a/src/render/framegraph/techniquefilternode.cpp
+++ b/src/render/framegraph/techniquefilternode.cpp
@@ -59,13 +59,30 @@ TechniqueFilter::TechniqueFilter()
{
}
-void TechniqueFilter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void TechniqueFilter::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QTechniqueFilterData>>(change);
- const auto &data = typedChange->data;
- m_filters = data.matchIds;
- m_parameterPack.setParameters(data.parameterIds);
+ const QTechniqueFilter *node = qobject_cast<const QTechniqueFilter *>(frontEnd);
+ if (!node)
+ return;
+
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (firstTime)
+ m_parameterPack.clear();
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters) {
+ m_parameterPack.setParameters(parameters);
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ auto filterIds = qIdsForNodes(node->matchAll());
+ std::sort(std::begin(filterIds), std::end(filterIds));
+ if (m_filters != filterIds) {
+ m_filters = filterIds;
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
QVector<Qt3DCore::QNodeId> TechniqueFilter::parameters() const
@@ -89,39 +106,6 @@ void TechniqueFilter::removeFilter(Qt3DCore::QNodeId criterionId)
m_filters.removeOne(criterionId);
}
-void TechniqueFilter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("matchAll")) {
- appendFilter(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.appendParameter(change->addedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("matchAll")) {
- removeFilter(change->removedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.removeParameter(change->removedNodeId());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- break;
- }
-
- default:
- break;
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
-
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/framegraph/techniquefilternode_p.h b/src/render/framegraph/techniquefilternode_p.h
index d7e6c1508..e424e37e5 100644
--- a/src/render/framegraph/techniquefilternode_p.h
+++ b/src/render/framegraph/techniquefilternode_p.h
@@ -79,11 +79,9 @@ public:
QVector<Qt3DCore::QNodeId> parameters() const;
QVector<Qt3DCore::QNodeId> filters() const;
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
void appendFilter(Qt3DCore::QNodeId criterionId);
void removeFilter(Qt3DCore::QNodeId criterionId);
diff --git a/src/render/framegraph/viewportnode.cpp b/src/render/framegraph/viewportnode.cpp
index b3b53b0f9..c37278817 100644
--- a/src/render/framegraph/viewportnode.cpp
+++ b/src/render/framegraph/viewportnode.cpp
@@ -59,16 +59,28 @@ ViewportNode::ViewportNode()
{
}
-void ViewportNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+
+void ViewportNode::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QViewportData>>(change);
- const auto &data = typedChange->data;
- m_xMin = data.normalizedRect.x();
- m_xMax = data.normalizedRect.width();
- m_yMin = data.normalizedRect.y();
- m_yMax = data.normalizedRect.height();
- m_gamma = data.gamma;
+ const QViewport *node = qobject_cast<const QViewport *>(frontEnd);
+ if (!node)
+ return;
+
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ const QRectF oldRect(m_xMin, m_yMin, m_xMax, m_yMax);
+ if (oldRect != node->normalizedRect()) {
+ m_xMin = node->normalizedRect().x();
+ m_yMin = node->normalizedRect().y();
+ m_xMax = node->normalizedRect().width();
+ m_yMax = node->normalizedRect().height();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+
+ if (node->gamma() != m_gamma) {
+ m_gamma = node->gamma();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
float ViewportNode::xMin() const
@@ -118,25 +130,6 @@ void ViewportNode::setGamma(float gamma)
m_gamma = gamma;
}
-void ViewportNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("normalizedRect")) {
- QRectF normalizedRect = propertyChange->value().toRectF();
- setXMin(normalizedRect.x());
- setYMin(normalizedRect.y());
- setXMax(normalizedRect.width());
- setYMax(normalizedRect.height());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("gamma")) {
- setGamma(propertyChange->value().toFloat());
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
-
QRectF ViewportNode::computeViewport(const QRectF &childViewport, const ViewportNode *parentViewport)
{
QRectF vp(parentViewport->xMin(),
diff --git a/src/render/framegraph/viewportnode_p.h b/src/render/framegraph/viewportnode_p.h
index 799b9b3dc..3e291a9da 100644
--- a/src/render/framegraph/viewportnode_p.h
+++ b/src/render/framegraph/viewportnode_p.h
@@ -84,13 +84,11 @@ public:
float gamma() const;
void setGamma(float gamma);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
static QRectF computeViewport(const QRectF &childViewport, const ViewportNode *parentViewport);
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
float m_xMin;
float m_yMin;
float m_xMax;
diff --git a/src/render/framegraph/waitfence.cpp b/src/render/framegraph/waitfence.cpp
index 9480fb7a0..68ddda3d7 100644
--- a/src/render/framegraph/waitfence.cpp
+++ b/src/render/framegraph/waitfence.cpp
@@ -71,33 +71,30 @@ WaitFence::~WaitFence()
{
}
-void WaitFence::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void WaitFence::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{
- if (e->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("handle")) {
- m_data.handle = propertyChange->value();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("handleType")) {
- m_data.handleType = static_cast<QWaitFence::HandleType>(propertyChange->value().toInt());
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("timeout")) {
- m_data.timeout = propertyChange->value().value<quint64>();
- markDirty(AbstractRenderer::FrameGraphDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("waitOnCPU")) {
- m_data.waitOnCPU = propertyChange->value().toBool();
- markDirty(AbstractRenderer::FrameGraphDirty);
- }
- }
- FrameGraphNode::sceneChangeEvent(e);
-}
+ const QWaitFence *node = qobject_cast<const QWaitFence *>(frontEnd);
+ if (!node)
+ return;
-void WaitFence::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- FrameGraphNode::initializeFromPeer(change);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QWaitFenceData>>(change);
- const QWaitFenceData &data = typedChange->data;
- m_data = data;
+ FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (node->handleType() != m_data.handleType) {
+ m_data.handleType = node->handleType();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->handle() != m_data.handle) {
+ m_data.handle = node->handle();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->timeout() != m_data.timeout) {
+ m_data.timeout = node->timeout();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
+ if (node->waitOnCPU() != m_data.waitOnCPU) {
+ m_data.waitOnCPU = node->waitOnCPU();
+ markDirty(AbstractRenderer::FrameGraphDirty);
+ }
}
} // namespace Render
diff --git a/src/render/framegraph/waitfence_p.h b/src/render/framegraph/waitfence_p.h
index dd48e0efa..811fc80a2 100644
--- a/src/render/framegraph/waitfence_p.h
+++ b/src/render/framegraph/waitfence_p.h
@@ -68,11 +68,9 @@ public:
~WaitFence();
inline QWaitFenceData data() const { return m_data; }
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override;
-
QWaitFenceData m_data;
};
diff --git a/src/render/frontend/qcamera.cpp b/src/render/frontend/qcamera.cpp
index 1bf8caad9..2dcec7ed6 100644
--- a/src/render/frontend/qcamera.cpp
+++ b/src/render/frontend/qcamera.cpp
@@ -348,6 +348,18 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
* Holds the current projection matrix of the camera.
*/
+/*!
+ * \qmlproperty real Qt3D.Render::Camera::exposure
+ * Holds the current exposure of the camera.
+ *
+ * The default value is 0.0.
+ *
+ * The MetalRoughMaterial in Qt 3D Extras is currently the only provided
+ * material that makes use of camera exposure. Negative values will cause
+ * the material to be darker, and positive values will cause it to be lighter.
+ *
+ * Custom materials may choose to interpret the value differently.
+ */
/*!
* \qmlproperty vector3d Qt3D.Render::Camera::position
@@ -493,6 +505,14 @@ void QCameraPrivate::updateViewMatrixAndTransform(bool doEmit)
/*!
* \property QCamera::exposure
* Holds the current exposure of the camera.
+ *
+ * The default value is 0.0.
+ *
+ * The MetalRoughMaterial in Qt 3D Extras is currently the only provided
+ * material that makes use of camera exposure. Negative values will cause
+ * the material to be darker, and positive values will cause it to be lighter.
+ *
+ * Custom materials may choose to interpret the value differently.
*/
/*!
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 8a0defceb..67bcb6c02 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -96,6 +96,7 @@
#include <Qt3DCore/qjoint.h>
#include <Qt3DCore/qskeletonloader.h>
+#include <Qt3DRender/private/backendnode_p.h>
#include <Qt3DRender/private/cameraselectornode_p.h>
#include <Qt3DRender/private/layerfilternode_p.h>
#include <Qt3DRender/private/cameralens_p.h>
@@ -232,6 +233,12 @@ QRenderAspectPrivate *QRenderAspectPrivate::findPrivate(Qt3DCore::QAspectEngine
return nullptr;
}
+void QRenderAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const
+{
+ Render::BackendNode *renderBackend = static_cast<Render::BackendNode *>(backend);
+ renderBackend->syncFromFrontEnd(node, firstTime);
+}
+
/*! \internal */
void QRenderAspectPrivate::registerBackendTypes()
{
@@ -245,8 +252,8 @@ void QRenderAspectPrivate::registerBackendTypes()
qRegisterMetaType<Qt3DRender::QViewport*>();
qRegisterMetaType<Qt3DCore::QJoint*>();
- q->registerBackendType<Qt3DCore::QEntity>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
- q->registerBackendType<Qt3DCore::QTransform>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer));
+ q->registerBackendType<Qt3DCore::QEntity, true>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<Qt3DCore::QTransform, true>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer));
q->registerBackendType<Qt3DRender::QCameraLens>(QSharedPointer<Render::CameraLensFunctor>::create(m_renderer, q));
q->registerBackendType<QLayer>(QSharedPointer<Render::NodeFunctor<Render::Layer, Render::LayerManager> >::create(m_renderer));
@@ -259,58 +266,58 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QRenderState>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer));
// Geometry + Compute
- q->registerBackendType<QAttribute>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer));
- q->registerBackendType<QBuffer>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager()));
+ q->registerBackendType<QAttribute, true>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer));
+ q->registerBackendType<QBuffer, true>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager()));
q->registerBackendType<QComputeCommand>(QSharedPointer<Render::NodeFunctor<Render::ComputeCommand, Render::ComputeCommandManager> >::create(m_renderer));
- q->registerBackendType<QGeometry>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer));
- q->registerBackendType<QGeometryRenderer>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager()));
- q->registerBackendType<Qt3DCore::QArmature>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer));
- q->registerBackendType<Qt3DCore::QAbstractSkeleton>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager(), m_nodeManagers->jointManager()));
- q->registerBackendType<Qt3DCore::QJoint>(QSharedPointer<Render::JointFunctor>::create(m_renderer, m_nodeManagers->jointManager(), m_nodeManagers->skeletonManager()));
+ q->registerBackendType<QGeometry, true>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer));
+ q->registerBackendType<QGeometryRenderer, true>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager()));
+ q->registerBackendType<Qt3DCore::QArmature, true>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer));
+ q->registerBackendType<Qt3DCore::QAbstractSkeleton, true>(QSharedPointer<Render::SkeletonFunctor>::create(m_renderer, m_nodeManagers->skeletonManager(), m_nodeManagers->jointManager()));
+ q->registerBackendType<Qt3DCore::QJoint, true>(QSharedPointer<Render::JointFunctor>::create(m_renderer, m_nodeManagers->jointManager(), m_nodeManagers->skeletonManager()));
// Textures
- q->registerBackendType<QAbstractTexture>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager()));
+ q->registerBackendType<QAbstractTexture, true>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager()));
q->registerBackendType<QAbstractTextureImage>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer,
m_nodeManagers->textureImageManager()));
// Material system
- q->registerBackendType<QEffect>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer));
+ q->registerBackendType<QEffect, true>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer));
q->registerBackendType<QFilterKey>(QSharedPointer<Render::NodeFunctor<Render::FilterKey, Render::FilterKeyManager> >::create(m_renderer));
- q->registerBackendType<QAbstractLight>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers));
- q->registerBackendType<QEnvironmentLight>(QSharedPointer<Render::NodeFunctor<Render::EnvironmentLight, Render::EnvironmentLightManager> >::create(m_renderer));
- q->registerBackendType<QMaterial>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer));
- q->registerBackendType<QParameter>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer));
- q->registerBackendType<QRenderPass>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer));
+ q->registerBackendType<QAbstractLight, true>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QEnvironmentLight, true>(QSharedPointer<Render::NodeFunctor<Render::EnvironmentLight, Render::EnvironmentLightManager> >::create(m_renderer));
+ q->registerBackendType<QMaterial, true>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer));
+ q->registerBackendType<QParameter, true>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer));
+ q->registerBackendType<QRenderPass, true>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer));
q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer));
q->registerBackendType<QShaderProgramBuilder>(QSharedPointer<Render::NodeFunctor<Render::ShaderBuilder, Render::ShaderBuilderManager> >::create(m_renderer));
- q->registerBackendType<QTechnique>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QTechnique, true>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderImage>(QSharedPointer<Render::NodeFunctor<Render::ShaderImage, Render::ShaderImageManager>>::create(m_renderer));
// Framegraph
- q->registerBackendType<QFrameGraphNode>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrameGraphNode, QFrameGraphNode> >::create(m_renderer));
- q->registerBackendType<QCameraSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector> >::create(m_renderer));
- q->registerBackendType<QClearBuffers>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ClearBuffers, QClearBuffers> >::create(m_renderer));
- q->registerBackendType<QDispatchCompute>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute> >::create(m_renderer));
- q->registerBackendType<QFrustumCulling>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrustumCulling, QFrustumCulling> >::create(m_renderer));
- q->registerBackendType<QLayerFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::LayerFilterNode, QLayerFilter> >::create(m_renderer));
- q->registerBackendType<QNoDraw>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoDraw, QNoDraw> >::create(m_renderer));
- q->registerBackendType<QRenderPassFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderPassFilter, QRenderPassFilter> >::create(m_renderer));
- q->registerBackendType<QRenderStateSet>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::StateSetNode, QRenderStateSet> >::create(m_renderer));
- q->registerBackendType<QRenderSurfaceSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderSurfaceSelector, QRenderSurfaceSelector> >::create(m_renderer));
- q->registerBackendType<QRenderTargetSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderTargetSelector, QRenderTargetSelector> >::create(m_renderer));
- q->registerBackendType<QSortPolicy>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SortPolicy, QSortPolicy> >::create(m_renderer));
- q->registerBackendType<QTechniqueFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter> >::create(m_renderer));
- q->registerBackendType<QViewport>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport> >::create(m_renderer));
- q->registerBackendType<QRenderCapture>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderCapture, QRenderCapture> >::create(m_renderer));
- q->registerBackendType<QBufferCapture>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BufferCapture, QBufferCapture> >::create(m_renderer));
- q->registerBackendType<QMemoryBarrier>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::MemoryBarrier, QMemoryBarrier> >::create(m_renderer));
- q->registerBackendType<QProximityFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ProximityFilter, QProximityFilter> >::create(m_renderer));
- q->registerBackendType<QBlitFramebuffer>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BlitFramebuffer, QBlitFramebuffer> >::create(m_renderer));
- q->registerBackendType<QSetFence>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SetFence, QSetFence> >::create(m_renderer));
- q->registerBackendType<QWaitFence>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::WaitFence, QWaitFence> >::create(m_renderer));
- q->registerBackendType<QNoPicking>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoPicking, QNoPicking> >::create(m_renderer));
- q->registerBackendType<QSubtreeEnabler>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SubtreeEnabler, QSubtreeEnabler> >::create(m_renderer));
+ q->registerBackendType<QFrameGraphNode, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrameGraphNode, QFrameGraphNode> >::create(m_renderer));
+ q->registerBackendType<QCameraSelector, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector> >::create(m_renderer));
+ q->registerBackendType<QClearBuffers, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ClearBuffers, QClearBuffers> >::create(m_renderer));
+ q->registerBackendType<QDispatchCompute, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute> >::create(m_renderer));
+ q->registerBackendType<QFrustumCulling, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrustumCulling, QFrustumCulling> >::create(m_renderer));
+ q->registerBackendType<QLayerFilter, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::LayerFilterNode, QLayerFilter> >::create(m_renderer));
+ q->registerBackendType<QNoDraw, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoDraw, QNoDraw> >::create(m_renderer));
+ q->registerBackendType<QRenderPassFilter, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderPassFilter, QRenderPassFilter> >::create(m_renderer));
+ q->registerBackendType<QRenderStateSet, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::StateSetNode, QRenderStateSet> >::create(m_renderer));
+ q->registerBackendType<QRenderSurfaceSelector, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderSurfaceSelector, QRenderSurfaceSelector> >::create(m_renderer));
+ q->registerBackendType<QRenderTargetSelector, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderTargetSelector, QRenderTargetSelector> >::create(m_renderer));
+ q->registerBackendType<QSortPolicy, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SortPolicy, QSortPolicy> >::create(m_renderer));
+ q->registerBackendType<QTechniqueFilter, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter> >::create(m_renderer));
+ q->registerBackendType<QViewport, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport> >::create(m_renderer));
+ q->registerBackendType<QRenderCapture, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderCapture, QRenderCapture> >::create(m_renderer));
+ q->registerBackendType<QBufferCapture, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BufferCapture, QBufferCapture> >::create(m_renderer));
+ q->registerBackendType<QMemoryBarrier, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::MemoryBarrier, QMemoryBarrier> >::create(m_renderer));
+ q->registerBackendType<QProximityFilter, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ProximityFilter, QProximityFilter> >::create(m_renderer));
+ q->registerBackendType<QBlitFramebuffer, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BlitFramebuffer, QBlitFramebuffer> >::create(m_renderer));
+ q->registerBackendType<QSetFence, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SetFence, QSetFence> >::create(m_renderer));
+ q->registerBackendType<QWaitFence, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::WaitFence, QWaitFence> >::create(m_renderer));
+ q->registerBackendType<QNoPicking, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoPicking, QNoPicking> >::create(m_renderer));
+ q->registerBackendType<QSubtreeEnabler, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SubtreeEnabler, QSubtreeEnabler> >::create(m_renderer));
// Picking
q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer));
@@ -542,7 +549,7 @@ void QRenderAspect::onEngineStartup()
Render::NodeManagers *managers = d->m_renderer->nodeManagers();
Render::Entity *rootEntity = managers->lookupResource<Render::Entity, Render::EntityManager>(rootEntityId());
Q_ASSERT(rootEntity);
- d->m_renderer->setSceneRoot(d, rootEntity);
+ d->m_renderer->setSceneRoot(rootEntity);
}
void QRenderAspect::onRegistered()
diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h
index 657e6a301..8ef4ecd12 100644
--- a/src/render/frontend/qrenderaspect_p.h
+++ b/src/render/frontend/qrenderaspect_p.h
@@ -85,6 +85,8 @@ public:
static QRenderAspectPrivate* findPrivate(Qt3DCore::QAspectEngine *engine);
+ void syncDirtyFrontEndNode(Qt3DCore::QNode *node, Qt3DCore::QBackendNode *backend, bool firstTime) const override;
+
void registerBackendTypes();
void unregisterBackendTypes();
void loadSceneParsers();
diff --git a/src/render/geometry/armature.cpp b/src/render/geometry/armature.cpp
index 15a26c9ec..cfa2e572a 100644
--- a/src/render/geometry/armature.cpp
+++ b/src/render/geometry/armature.cpp
@@ -36,6 +36,8 @@
#include "armature_p.h"
+#include <Qt3DCore/qarmature.h>
+#include <Qt3DCore/qabstractskeleton.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qarmature_p.h>
@@ -52,32 +54,20 @@ Armature::Armature()
{
}
-void Armature::cleanup()
+void Armature::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- m_skeletonId = Qt3DCore::QNodeId();
- setEnabled(false);
-}
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QArmature *node = qobject_cast<const QArmature *>(frontEnd);
+ if (!node)
+ return;
-void Armature::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<QNodeCreatedChange<QArmatureData>>(change);
- m_skeletonId = typedChange->data.skeletonId;
+ m_skeletonId = node->skeleton() ? node->skeleton()->id() : QNodeId{};
}
-void Armature::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Armature::cleanup()
{
- switch (e->type()) {
- case Qt3DCore::PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("skeleton"))
- m_skeletonId = change->value().value<QNodeId>();
- break;
- }
-
- default:
- break;
- }
- QBackendNode::sceneChangeEvent(e);
+ m_skeletonId = Qt3DCore::QNodeId();
+ setEnabled(false);
}
} // namespace Render
diff --git a/src/render/geometry/armature_p.h b/src/render/geometry/armature_p.h
index 3e6e52a3f..39baa4a79 100644
--- a/src/render/geometry/armature_p.h
+++ b/src/render/geometry/armature_p.h
@@ -63,7 +63,7 @@ class Q_AUTOTEST_EXPORT Armature : public BackendNode
public:
Armature();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void cleanup();
Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; }
@@ -73,8 +73,6 @@ public:
const UniformValue &skinningPaletteUniform() const { return m_skinningPaletteUniform; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_skeletonId;
UniformValue m_skinningPaletteUniform;
};
diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp
index bc6b27851..f241a85e5 100644
--- a/src/render/geometry/attribute.cpp
+++ b/src/render/geometry/attribute.cpp
@@ -83,78 +83,54 @@ void Attribute::cleanup()
m_nameId = 0;
}
-void Attribute::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Attribute::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QAttributeData>>(change);
- const auto &data = typedChange->data;
- m_bufferId = data.bufferId;
- m_name = data.name;
- m_nameId = StringToInt::lookupId(m_name);
- m_vertexBaseType = data.vertexBaseType;
- m_vertexSize = data.vertexSize;
- m_count = data.count;
- m_byteStride = data.byteStride;
- m_byteOffset = data.byteOffset;
- m_divisor = data.divisor;
- m_attributeType = data.attributeType;
- m_attributeDirty = true;
-}
-
-/*!
- \fn Qt3DRender::QAttribute::dataSizeChanged(uint vertexSize)
-
- The signal is emitted with \a vertexSize when the dataSize changes.
-
-*/
-/*!
- \fn Qt3DRender::QAttribute::dataTypeChanged(Qt3DRender::QAttribute::VertexBaseType vertexBaseType)
-
- The signal is emitted with \a vertexBaseType when the dataType changed.
-*/
-void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
-
- if (propertyName == QByteArrayLiteral("name")) {
- m_name = propertyChange->value().toString();
- m_nameId = StringToInt::lookupId(m_name);
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexBaseType")) {
- m_vertexBaseType = static_cast<QAttribute::VertexBaseType>(propertyChange->value().value<int>());
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexSize")) {
- m_vertexSize = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("count")) {
- m_count = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("byteStride")) {
- m_byteStride = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("byteOffset")) {
- m_byteOffset = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("divisor")) {
- m_divisor = propertyChange->value().value<uint>();
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("attributeType")) {
- m_attributeType = static_cast<QAttribute::AttributeType>(propertyChange->value().value<int>());
- m_attributeDirty = true;
- } else if (propertyName == QByteArrayLiteral("buffer")) {
- m_bufferId = propertyChange->value().value<QNodeId>();
- m_attributeDirty = true;
- }
- markDirty(AbstractRenderer::AllDirty);
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAttribute *node = qobject_cast<const QAttribute *>(frontEnd);
+ if (!node)
+ return;
+
+ m_attributeDirty = firstTime;
+ if (m_name != node->name()) {
+ m_name = node->name();
+ m_nameId = StringToInt::lookupId(m_name);
+ m_attributeDirty = true;
}
-
- default:
- break;
+ if (m_vertexBaseType != node->vertexBaseType()) {
+ m_vertexBaseType = node->vertexBaseType();
+ m_attributeDirty = true;
}
- BackendNode::sceneChangeEvent(e);
+ if (m_vertexSize != node->vertexSize()) {
+ m_vertexSize = node->vertexSize();
+ m_attributeDirty = true;
+ }
+ if (m_count != node->count()) {
+ m_count = node->count();
+ m_attributeDirty = true;
+ }
+ if (m_byteStride != node->byteStride()) {
+ m_byteStride = node->byteStride();
+ m_attributeDirty = true;
+ }
+ if (m_byteOffset != node->byteOffset()) {
+ m_byteOffset = node->byteOffset();
+ m_attributeDirty = true;
+ }
+ if (m_divisor != node->divisor()) {
+ m_divisor = node->divisor();
+ m_attributeDirty = true;
+ }
+ if (m_attributeType != node->attributeType()) {
+ m_attributeType = node->attributeType();
+ m_attributeDirty = true;
+ }
+ const auto bufferId = node->buffer() ? node->buffer()->id() : QNodeId{};
+ if (bufferId != m_bufferId) {
+ m_bufferId = bufferId;
+ m_attributeDirty = true;
+ }
+
+ markDirty(AbstractRenderer::AllDirty);
}
void Attribute::unsetDirty()
diff --git a/src/render/geometry/attribute_p.h b/src/render/geometry/attribute_p.h
index e01537605..4b47146e1 100644
--- a/src/render/geometry/attribute_p.h
+++ b/src/render/geometry/attribute_p.h
@@ -68,7 +68,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline Qt3DCore::QNodeId bufferId() const { return m_bufferId; }
inline QString name() const { return m_name; }
@@ -84,8 +84,6 @@ public:
void unsetDirty();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_bufferId;
QString m_name;
int m_nameId;
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index d60f89c7d..998db3640 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -113,28 +113,6 @@ void Buffer::updateDataFromGPUToCPU(QByteArray data)
notifyObservers(e);
}
-void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBufferData>>(change);
- const auto &data = typedChange->data;
- m_data = data.data;
- m_usage = data.usage;
- m_syncData = data.syncData;
- m_access = data.access;
- m_bufferDirty = true;
-
- if (!m_data.isEmpty())
- forceDataUpload();
-
- m_functor = data.functor;
- Q_ASSERT(m_manager);
- if (m_functor)
- m_manager->addDirtyBuffer(peerId());
-
- m_manager->addBufferReference(peerId());
- markDirty(AbstractRenderer::BuffersDirty);
-}
-
void Buffer::forceDataUpload()
{
// We push back an update with offset = -1
@@ -145,40 +123,50 @@ void Buffer::forceDataUpload()
m_bufferUpdates.push_back(updateNewData);
}
-void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Buffer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
- if (propertyName == QByteArrayLiteral("data")) {
- QByteArray newData = propertyChange->value().toByteArray();
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QBuffer *node = qobject_cast<const QBuffer *>(frontEnd);
+ if (!node)
+ return;
+
+ if (firstTime && m_manager != nullptr)
+ m_manager->addBufferReference(peerId());
+
+ m_syncData = node->isSyncData();
+ m_access = node->accessType();
+ if (m_usage != node->usage()) {
+ m_usage = node->usage();
+ m_bufferDirty = true;
+ }
+ {
+ QBufferDataGeneratorPtr newGenerator = node->dataGenerator();
+ bool dirty = (newGenerator && m_functor && !(*newGenerator == *m_functor)) ||
+ (newGenerator.isNull() && !m_functor.isNull()) ||
+ (!newGenerator.isNull() && m_functor.isNull());
+ m_bufferDirty |= dirty;
+ m_functor = newGenerator;
+ if (m_functor && m_manager != nullptr)
+ m_manager->addDirtyBuffer(peerId());
+ }
+ {
+ QVariant v = node->property("QT3D_updateData");
+ if (v.isValid()) {
+ 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)
+ if (dirty && !m_data.isEmpty())
forceDataUpload();
- } else if (propertyName == QByteArrayLiteral("updateData")) {
- Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>();
- m_data.replace(updateData.offset, updateData.data.size(), updateData.data);
- m_bufferUpdates.push_back(updateData);
- m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("usage")) {
- m_usage = static_cast<QBuffer::UsageType>(propertyChange->value().value<int>());
- m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("accessType")) {
- m_access = static_cast<QBuffer::AccessType>(propertyChange->value().value<int>());
- } else if (propertyName == QByteArrayLiteral("dataGenerator")) {
- QBufferDataGeneratorPtr newGenerator = propertyChange->value().value<QBufferDataGeneratorPtr>();
- m_bufferDirty |= !(newGenerator && m_functor && *newGenerator == *m_functor);
- m_functor = newGenerator;
- if (m_functor && m_manager != nullptr)
- m_manager->addDirtyBuffer(peerId());
- } else if (propertyName == QByteArrayLiteral("syncData")) {
- m_syncData = propertyChange->value().toBool();
}
- markDirty(AbstractRenderer::BuffersDirty);
}
- BackendNode::sceneChangeEvent(e);
+ markDirty(AbstractRenderer::BuffersDirty);
}
// Called by Renderer once the buffer has been uploaded to OpenGL
diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h
index 9a171599d..a3f52d1b3 100644
--- a/src/render/geometry/buffer_p.h
+++ b/src/render/geometry/buffer_p.h
@@ -73,7 +73,7 @@ public:
~Buffer();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void setManager(BufferManager *manager);
void executeFunctor();
@@ -88,7 +88,6 @@ public:
void unsetDirty();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void forceDataUpload();
QBuffer::UsageType m_usage;
diff --git a/src/render/geometry/geometry.cpp b/src/render/geometry/geometry.cpp
index 4ee02a74d..cb401df5b 100644
--- a/src/render/geometry/geometry.cpp
+++ b/src/render/geometry/geometry.cpp
@@ -45,6 +45,8 @@
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -76,51 +78,29 @@ void Geometry::cleanup()
m_shouldNotifyMaxExtentChanged = false;
}
-void Geometry::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QGeometryData>>(change);
- const auto &data = typedChange->data;
- m_attributes = data.attributeIds;
- m_boundingPositionAttribute = data.boundingVolumePositionAttributeId;
- m_geometryDirty = true;
- markDirty(AbstractRenderer::GeometryDirty);
-}
-
-void Geometry::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void Geometry::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("attribute")) {
- m_attributes.push_back(change->addedNodeId());
- m_geometryDirty = true;
- }
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("attribute")) {
- m_attributes.removeOne(change->removedNodeId());
- m_geometryDirty = true;
- }
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QGeometry *node = qobject_cast<const QGeometry *>(frontEnd);
+ if (!node)
+ return;
+
+ m_geometryDirty |= firstTime;
+
+ QNodeIdVector attribs = qIdsForNodes(node->attributes());
+ std::sort(std::begin(attribs), std::end(attribs));
+ if (m_attributes != attribs) {
+ m_attributes = attribs;
+ m_geometryDirty = true;
}
- case PropertyUpdated: {
+ if ((node->boundingVolumePositionAttribute() && node->boundingVolumePositionAttribute()->id() != m_boundingPositionAttribute) ||
// Note: doesn't set dirtyness as this parameter changing doesn't need a new VAO update.
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("boundingVolumePositionAttribute")) {
- m_boundingPositionAttribute = change->value().value<QNodeId>();
- break;
- }
+ (!node->boundingVolumePositionAttribute() && !m_boundingPositionAttribute.isNull())) {
+ m_boundingPositionAttribute = node->boundingVolumePositionAttribute() ? node->boundingVolumePositionAttribute()->id() : QNodeId{};
}
- default:
- break;
- }
markDirty(AbstractRenderer::GeometryDirty);
- BackendNode::sceneChangeEvent(e);
}
void Geometry::unsetDirty()
diff --git a/src/render/geometry/geometry_p.h b/src/render/geometry/geometry_p.h
index e66524787..429a577b0 100644
--- a/src/render/geometry/geometry_p.h
+++ b/src/render/geometry/geometry_p.h
@@ -68,7 +68,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline QVector<Qt3DCore::QNodeId> attributes() const { return m_attributes; }
inline bool isDirty() const { return m_geometryDirty; }
@@ -82,8 +82,6 @@ public:
void notifyExtentChanged();
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DCore::QNodeId> m_attributes;
bool m_geometryDirty;
Qt3DCore::QNodeId m_boundingPositionAttribute;
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index ea059c6ee..b5c741659 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -105,95 +105,47 @@ void GeometryRenderer::setManager(GeometryRendererManager *manager)
m_manager = manager;
}
-void GeometryRenderer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void GeometryRenderer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QGeometryRendererData>>(change);
- const auto &data = typedChange->data;
- m_geometryId = data.geometryId;
- m_instanceCount = data.instanceCount;
- m_vertexCount = data.vertexCount;
- m_indexOffset = data.indexOffset;
- m_firstInstance = data.firstInstance;
- m_firstVertex = data.firstVertex;
- m_indexBufferByteOffset = data.indexBufferByteOffset;
- m_restartIndexValue = data.restartIndexValue;
- m_verticesPerPatch = data.verticesPerPatch;
- m_primitiveRestartEnabled = data.primitiveRestart;
- m_primitiveType = data.primitiveType;
-
- Q_ASSERT(m_manager);
- m_geometryFactory = data.geometryFactory;
- if (m_geometryFactory)
- m_manager->addDirtyGeometryRenderer(peerId());
-
- m_dirty = true;
- markDirty(AbstractRenderer::GeometryDirty);
-}
-
-void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- QByteArray propertyName = propertyChange->propertyName();
-
- if (propertyName == QByteArrayLiteral("instanceCount")) {
- m_instanceCount = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("vertexCount")) {
- m_vertexCount = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("indexOffset")) {
- m_indexOffset = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("firstInstance")) {
- m_firstInstance = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("firstVertex")) {
- m_firstVertex = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("indexBufferByteOffset")) {
- m_indexBufferByteOffset = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("restartIndexValue")) {
- m_restartIndexValue = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("verticesPerPatch")) {
- m_verticesPerPatch = propertyChange->value().value<int>();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("primitiveRestartEnabled")) {
- m_primitiveRestartEnabled = propertyChange->value().toBool();
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("primitiveType")) {
- m_primitiveType = static_cast<QGeometryRenderer::PrimitiveType>(propertyChange->value().value<int>());
- m_dirty = true;
- } else if (propertyName == QByteArrayLiteral("geometryFactory")) {
- QGeometryFactoryPtr newFunctor = propertyChange->value().value<QGeometryFactoryPtr>();
- const bool functorDirty = ((m_geometryFactory && !newFunctor)
- || (!m_geometryFactory && newFunctor)
- || (m_geometryFactory && newFunctor && !(*newFunctor == *m_geometryFactory)));
- m_dirty |= functorDirty;
- if (functorDirty) {
- m_geometryFactory = newFunctor;
- if (m_geometryFactory && m_manager != nullptr)
- m_manager->addDirtyGeometryRenderer(peerId());
- }
- } else if (propertyName == QByteArrayLiteral("geometry")) {
- m_geometryId = propertyChange->value().value<Qt3DCore::QNodeId>();
- m_dirty = true;
- }
- break;
- }
-
- default:
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QGeometryRenderer *node = qobject_cast<const QGeometryRenderer *>(frontEnd);
+ if (!node)
+ return;
+
+ m_dirty |= m_instanceCount != node->instanceCount();
+ m_instanceCount = node->instanceCount();
+ m_dirty |= m_vertexCount != node->vertexCount();
+ m_vertexCount = node->vertexCount();
+ m_dirty |= m_indexOffset != node->indexOffset();
+ m_indexOffset = node->indexOffset();
+ m_dirty |= m_firstInstance != node->firstInstance();
+ m_firstInstance = node->firstInstance();
+ m_dirty |= m_firstVertex != node->firstVertex();
+ m_firstVertex = node->firstVertex();
+ m_dirty |= m_indexBufferByteOffset != node->indexBufferByteOffset();
+ m_indexBufferByteOffset = node->indexBufferByteOffset();
+ m_dirty |= m_restartIndexValue != node->restartIndexValue();
+ m_restartIndexValue = node->restartIndexValue();
+ m_dirty |= m_verticesPerPatch != node->verticesPerPatch();
+ m_verticesPerPatch = node->verticesPerPatch();
+ m_dirty |= m_primitiveRestartEnabled != node->primitiveRestartEnabled();
+ m_primitiveRestartEnabled = node->primitiveRestartEnabled();
+ m_dirty |= m_primitiveType != node->primitiveType();
+ m_primitiveType = node->primitiveType();
+ m_dirty |= (node->geometry() && m_geometryId != node->geometry()->id()) || (!node->geometry() && !m_geometryId.isNull());
+ m_geometryId = node->geometry() ? node->geometry()->id() : Qt3DCore::QNodeId();
+ QGeometryFactoryPtr newFunctor = node->geometryFactory();
+ const bool functorDirty = ((m_geometryFactory && !newFunctor)
+ || (!m_geometryFactory && newFunctor)
+ || (m_geometryFactory && newFunctor && !(*newFunctor == *m_geometryFactory)));
+ if (functorDirty) {
+ m_dirty = true;
+ m_geometryFactory = newFunctor;
+ if (m_geometryFactory && m_manager != nullptr)
+ m_manager->addDirtyGeometryRenderer(peerId());
}
markDirty(AbstractRenderer::GeometryDirty);
-
- BackendNode::sceneChangeEvent(e);
-
- // Add to dirty list in manager
}
void GeometryRenderer::executeFunctor()
diff --git a/src/render/geometry/geometryrenderer_p.h b/src/render/geometry/geometryrenderer_p.h
index 57d1ca0be..da538a00d 100644
--- a/src/render/geometry/geometryrenderer_p.h
+++ b/src/render/geometry/geometryrenderer_p.h
@@ -74,7 +74,7 @@ public:
void cleanup();
void setManager(GeometryRendererManager *manager);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void executeFunctor();
inline Qt3DCore::QNodeId geometryId() const { return m_geometryId; }
@@ -98,8 +98,6 @@ public:
QVector<RayCasting::QBoundingVolume *> triangleData() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_geometryId;
int m_instanceCount;
int m_vertexCount;
diff --git a/src/render/geometry/joint.cpp b/src/render/geometry/joint.cpp
index c770564f9..86d583f51 100644
--- a/src/render/geometry/joint.cpp
+++ b/src/render/geometry/joint.cpp
@@ -39,11 +39,14 @@
#include "joint_p.h"
#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DCore/QJoint>
#include <Qt3DCore/private/qjoint_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -69,21 +72,7 @@ void Joint::cleanup()
setEnabled(false);
}
-void Joint::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- Q_ASSERT(m_jointManager);
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QJointData>>(change);
- const auto &data = typedChange->data;
- m_inverseBindMatrix = data.inverseBindMatrix;
- m_localPose.rotation = data.rotation;
- m_localPose.scale = data.scale;
- m_localPose.translation = data.translation;
- m_childJointIds = data.childJointIds;
- m_name = data.name;
- markDirty(AbstractRenderer::JointDirty);
- m_jointManager->addDirtyJoint(peerId());
-}
-
+// TODOSYNC remove once animation changes don't use messages anymore
void Joint::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
if (e->type() == PropertyUpdated) {
@@ -123,10 +112,60 @@ void Joint::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (removedChange->propertyName() == QByteArrayLiteral("childJoint"))
m_childJointIds.removeOne(removedChange->removedNodeId());
}
-
BackendNode::sceneChangeEvent(e);
}
+void Joint::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ const Qt3DCore::QJoint *joint = qobject_cast<const Qt3DCore::QJoint *>(frontEnd);
+ if (!joint)
+ return;
+
+ if (m_localPose.scale != joint->scale()) {
+ m_localPose.scale = joint->scale();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_localPose.rotation != joint->rotation()) {
+ m_localPose.rotation = joint->rotation();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_localPose.translation != joint->translation()) {
+ m_localPose.translation = joint->translation();
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+ if (m_inverseBindMatrix != joint->inverseBindMatrix()) {
+ // Setting the inverse bind matrix should be a rare operation. Usually it is
+ // set once and then remains constant for the duration of the skeleton. So just
+ // trigger a rebuild of the skeleton's SkeletonData which will include obtaining
+ // the inverse bind matrix.
+ m_inverseBindMatrix = joint->inverseBindMatrix();
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_owningSkeleton);
+ }
+ if (m_name != joint->name()) {
+ // Joint name doesn't affect anything in the render aspect so no need
+ // to mark anything as dirty.
+ m_name = joint->name();
+
+ // TODO: Notify other aspects (animation) about the name change.
+ }
+
+ Qt3DCore::QNodeIdVector childIds = qIdsForNodes(joint->childJoints());
+ std::sort(std::begin(childIds), std::end(childIds));
+ if (m_childJointIds != childIds) {
+ m_childJointIds = childIds;
+ }
+
+ if (firstTime) {
+ markDirty(AbstractRenderer::JointDirty);
+ m_jointManager->addDirtyJoint(peerId());
+ }
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+}
+
JointFunctor::JointFunctor(AbstractRenderer *renderer,
JointManager *jointManager,
diff --git a/src/render/geometry/joint_p.h b/src/render/geometry/joint_p.h
index e144ac489..d0530ac04 100644
--- a/src/render/geometry/joint_p.h
+++ b/src/render/geometry/joint_p.h
@@ -70,6 +70,7 @@ public:
void cleanup();
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::Sqt localPose() const { return m_localPose; }
QMatrix4x4 inverseBindMatrix() const { return m_inverseBindMatrix; }
@@ -90,8 +91,6 @@ public:
SkeletonManager *skeletonManager() const { return m_skeletonManager; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QMatrix4x4 m_inverseBindMatrix;
Qt3DCore::Sqt m_localPose;
QVector<Qt3DCore::QNodeId> m_childJointIds;
diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp
index ca467fda9..a28d0baa6 100644
--- a/src/render/geometry/qattribute.cpp
+++ b/src/render/geometry/qattribute.cpp
@@ -505,6 +505,19 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAttribute::createNodeCreationChange() const
return creationChange;
}
+
+/*!
+\fn Qt3DRender::QAttribute::dataSizeChanged(uint vertexSize)
+
+The signal is emitted with \a vertexSize when the dataSize changes.
+*/
+/*!
+\fn Qt3DRender::QAttribute::dataTypeChanged(Qt3DRender::QAttribute::VertexBaseType vertexBaseType)
+
+The signal is emitted with \a vertexBaseType when the dataType changed.
+*/
+
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index e0574a4c5..f27005f2b 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -329,7 +329,7 @@ void QBuffer::setData(const QByteArray &bytes)
Q_D(QBuffer);
if (bytes != d->m_data) {
d->m_data = bytes;
- Qt3DCore::QNodePrivate::get(this)->notifyPropertyChange("data", QVariant::fromValue(d->m_data));
+ Qt3DCore::QNodePrivate::get(this)->update();
emit dataChanged(bytes);
}
}
@@ -351,11 +351,8 @@ void QBuffer::updateData(int offset, const QByteArray &bytes)
QBufferUpdate updateData;
updateData.offset = offset;
updateData.data = bytes;
-
- auto e = QPropertyUpdatedChangePtr::create(id());
- e->setPropertyName("updateData");
- e->setValue(QVariant::fromValue(updateData));
- notifyObservers(e);
+ setProperty("QT3D_updateData", QVariant::fromValue(updateData));
+ d->update();
}
/*!
@@ -409,12 +406,7 @@ void QBuffer::setDataGenerator(const QBufferDataGeneratorPtr &functor)
if (functor && d->m_functor && *functor == *d->m_functor)
return;
d->m_functor = functor;
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("dataGenerator");
- change->setValue(QVariant::fromValue(d->m_functor));
- d->notifyObservers(change);
- }
+ d->update();
}
/*!
diff --git a/src/render/geometry/qgeometry.cpp b/src/render/geometry/qgeometry.cpp
index ec80e2657..47fad4302 100644
--- a/src/render/geometry/qgeometry.cpp
+++ b/src/render/geometry/qgeometry.cpp
@@ -196,11 +196,7 @@ void QGeometry::addAttribute(QAttribute *attribute)
if (!attribute->parent())
attribute->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), attribute);
- change->setPropertyName("attribute");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -212,14 +208,10 @@ void QGeometry::removeAttribute(QAttribute *attribute)
{
Q_ASSERT(attribute);
Q_D(QGeometry);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), attribute);
- change->setPropertyName("attribute");
- d->notifyObservers(change);
- }
d->m_attributes.removeOne(attribute);
// Remove bookkeeping connection
d->unregisterDestructionHelper(attribute);
+ d->update();
}
void QGeometry::setBoundingVolumePositionAttribute(QAttribute *boundingVolumePositionAttribute)
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index 6bff3462f..ddea873a7 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -480,12 +480,7 @@ void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory)
if (factory && d->m_geometryFactory && *factory == *d->m_geometryFactory)
return;
d->m_geometryFactory = factory;
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("geometryFactory");
- change->setValue(QVariant::fromValue(d->m_geometryFactory));
- d->notifyObservers(change);
- }
+ d->update();
}
/*!
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index 615b76c88..d4af1fe3c 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -80,39 +80,68 @@ void Skeleton::cleanup()
setEnabled(false);
}
-void Skeleton::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Skeleton::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- Q_ASSERT(m_skeletonManager);
- m_skeletonHandle = m_skeletonManager->lookupHandle(peerId());
-
- const auto skeletonCreatedChange = qSharedPointerCast<QSkeletonCreatedChangeBase>(change);
- switch (skeletonCreatedChange->type()) {
- case QSkeletonCreatedChangeBase::SkeletonLoader: {
- const auto loaderTypedChange = qSharedPointerCast<QSkeletonCreatedChange<QSkeletonLoaderData>>(change);
- const auto &data = loaderTypedChange->data;
- m_dataType = File;
- m_source = data.source;
- m_createJoints = data.createJoints;
- if (!m_source.isEmpty()) {
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractSkeleton *node = qobject_cast<const QAbstractSkeleton *>(frontEnd);
+ if (!node)
+ return;
+ const QSkeleton *skeletonNode = qobject_cast<const QSkeleton *>(frontEnd);
+ const QSkeletonLoader *loaderNode = qobject_cast<const QSkeletonLoader *>(frontEnd);
+
+ if (firstTime) {
+ m_skeletonHandle = m_skeletonManager->lookupHandle(peerId());
+
+ if (skeletonNode) {
+ m_dataType = Data;
+ m_rootJointId = skeletonNode->rootJoint()->id();
+ if (!m_rootJointId.isNull()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
+ }
+
+ if (loaderNode) {
+ m_dataType = File;
+ m_source = loaderNode->source();
+ if (!m_source.isEmpty()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
}
- break;
}
- case QSkeletonCreatedChangeBase::Skeleton:
- const auto typedChange = qSharedPointerCast<QSkeletonCreatedChange<QSkeletonData>>(change);
- const auto &data = typedChange->data;
- m_dataType = Data;
- m_rootJointId = data.rootJointId;
- if (!m_rootJointId.isNull()) {
+ if (loaderNode) {
+ if (loaderNode->source() != m_source) {
+ m_source = loaderNode->source();
markDirty(AbstractRenderer::SkeletonDataDirty);
m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
}
- break;
+ m_createJoints = loaderNode->isCreateJointsEnabled();
+
+ if ((loaderNode->rootJoint() && loaderNode->rootJoint()->id() != m_rootJointId) ||
+ (!loaderNode->rootJoint() && !m_rootJointId.isNull())) {
+ m_rootJointId = loaderNode->rootJoint() ? loaderNode->rootJoint()->id() : Qt3DCore::QNodeId{};
+
+ // If using a QSkeletonLoader to create frontend QJoints, when those joints are
+ // set on the skeleton, we end up here. In order to allow the subsequent call
+ // to loadSkeleton(), see below, to build the internal data from the frontend
+ // joints rather than from the source url again, we need to change the data type
+ // to Data.
+ m_dataType = Data;
+
+ // If the joint changes, we need to rebuild our internal SkeletonData and
+ // the relationships between joints and skeleton. Mark the skeleton data as
+ // dirty so that we get a loadSkeletonJob executed to process this skeleton.
+ if (!m_rootJointId.isNull()) {
+ markDirty(AbstractRenderer::SkeletonDataDirty);
+ m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
+ }
+ }
}
}
+// TODOSYNC remove once animation aspect no longer requires messages
void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
switch (e->type()) {
@@ -123,31 +152,6 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
// need to do is copy them into place. The existing jobs will then update
// the skinning matrix palette.
m_skeletonData.localPoses = change->value().value<QVector<Qt3DCore::Sqt>>();
- } else if (change->propertyName() == QByteArrayLiteral("source")) {
- Q_ASSERT(m_dataType == File);
- const auto source = change->value().toUrl();
- if (source != m_source) {
- m_source = source;
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
- }
- } else if (change->propertyName() == QByteArrayLiteral("createJointsEnabled")) {
- m_createJoints = change->value().toBool();
- } else if (change->propertyName() == QByteArrayLiteral("rootJoint")) {
- m_rootJointId = change->value().value<QNodeId>();
-
- // If using a QSkeletonLoader to create frontend QJoints, when those joints are
- // set on the skeleton, we end up here. In order to allow the subsequent call
- // to loadSkeleton(), see below, to build the internal data from the frontend
- // joints rather than from the source url again, we need to change the data type
- // to Data.
- m_dataType = Data;
-
- // If the joint changes, we need to rebuild our internal SkeletonData and
- // the relationships between joints and skeleton. Mark the skeleton data as
- // dirty so that we get a loadSkeletonJob executed to process this skeleton.
- markDirty(AbstractRenderer::SkeletonDataDirty);
- m_skeletonManager->addDirtySkeleton(SkeletonManager::SkeletonDataDirty, m_skeletonHandle);
}
break;
diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h
index 4a14e5c1c..d71b404e5 100644
--- a/src/render/geometry/skeleton_p.h
+++ b/src/render/geometry/skeleton_p.h
@@ -85,6 +85,7 @@ public:
void cleanup();
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void setStatus(Qt3DCore::QSkeletonLoader::Status status);
Qt3DCore::QSkeletonLoader::Status status() const { return m_status; }
@@ -120,7 +121,6 @@ public:
#endif
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void loadSkeletonFromUrl();
void loadSkeletonFromData();
Qt3DCore::QJoint *createFrontendJoints(const SkeletonData &skeletonData) const;
diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h
index 5fe16f933..9c83624b8 100644
--- a/src/render/jobs/job_common_p.h
+++ b/src/render/jobs/job_common_p.h
@@ -109,7 +109,6 @@ namespace JobTypes {
UpdateLayerEntity,
SendTextureChangesToFrontend,
SendSetFenceHandlesToFrontend,
- UpdateEntityHierarchy,
};
} // JobTypes
diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri
index 6cdf891fc..2181e4a95 100644
--- a/src/render/jobs/jobs.pri
+++ b/src/render/jobs/jobs.pri
@@ -30,7 +30,6 @@ HEADERS += \
$$PWD/filterproximitydistancejob_p.h \
$$PWD/abstractpickingjob_p.h \
$$PWD/raycastingjob_p.h \
- $$PWD/updateentityhierarchyjob_p.h \
$$PWD/updateentitylayersjob_p.h
SOURCES += \
@@ -60,6 +59,5 @@ SOURCES += \
$$PWD/filterproximitydistancejob.cpp \
$$PWD/abstractpickingjob.cpp \
$$PWD/raycastingjob.cpp \
- $$PWD/updateentityhierarchyjob.cpp \
$$PWD/updateentitylayersjob.cpp
diff --git a/src/render/jobs/updateentityhierarchyjob.cpp b/src/render/jobs/updateentityhierarchyjob.cpp
deleted file mode 100644
index 7c18514bb..000000000
--- a/src/render/jobs/updateentityhierarchyjob.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** 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 "updateentityhierarchyjob_p.h"
-#include <Qt3DRender/private/managers_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/entity_p.h>
-#include <Qt3DRender/private/job_common_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-UpdateEntityHierarchyJob::UpdateEntityHierarchyJob()
- : m_manager(nullptr)
-{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateEntityHierarchy, 0);
-}
-
-void UpdateEntityHierarchyJob::run()
-{
- Q_ASSERT(m_manager);
- EntityManager *entityManager = m_manager->renderNodesManager();
-
- const QVector<HEntity> handles = entityManager->activeHandles();
-
- // Clear the parents and children
- for (const HEntity &handle : handles) {
- Entity *entity = entityManager->data(handle);
- entity->clearEntityHierarchy();
- }
- for (const HEntity &handle : handles) {
- Entity *entity = entityManager->data(handle);
- entity->rebuildEntityHierarchy();
- }
-}
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/jobs/updateentityhierarchyjob_p.h b/src/render/jobs/updateentityhierarchyjob_p.h
deleted file mode 100644
index fd2b13631..000000000
--- a/src/render/jobs/updateentityhierarchyjob_p.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-
-#ifndef QT3DRENDER_RENDER_UPDATEENTITYHIERARCHYJOB_P_H
-#define QT3DRENDER_RENDER_UPDATEENTITYHIERARCHYJOB_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 <Qt3DRender/private/qt3drender_global_p.h>
-#include <Qt3DCore/qaspectjob.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class Entity;
-class NodeManagers;
-
-class Q_3DRENDERSHARED_PRIVATE_EXPORT UpdateEntityHierarchyJob: public Qt3DCore::QAspectJob
-{
-public:
- UpdateEntityHierarchyJob();
-
- inline void setManager(NodeManagers *manager) { m_manager = manager; }
- inline NodeManagers *manager() const { return m_manager; }
-
- // QAspectJob interface
- void run() final;
-
-private:
- NodeManagers *m_manager;
-};
-
-
-using UpdateEntityHierarchyJobPtr = QSharedPointer<UpdateEntityHierarchyJob>;
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_UPDATEENTITYHIERARCHYJOB_P_H
diff --git a/src/render/lights/environmentlight.cpp b/src/render/lights/environmentlight.cpp
index d4245fb6e..20364fdfa 100644
--- a/src/render/lights/environmentlight.cpp
+++ b/src/render/lights/environmentlight.cpp
@@ -53,11 +53,17 @@ QNodeId EnvironmentLight::shaderData() const
return m_shaderDataId;
}
-void EnvironmentLight::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
+void EnvironmentLight::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEnvironmentLightData>>(change);
- const auto &data = typedChange->data;
- m_shaderDataId = data.shaderDataId;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QEnvironmentLight *node = qobject_cast<const QEnvironmentLight *>(frontEnd);
+ if (!node)
+ return;
+
+ if (firstTime) {
+ QEnvironmentLightPrivate *d = static_cast<QEnvironmentLightPrivate *>(QEnvironmentLightPrivate::get(const_cast<Qt3DCore::QNode *>(frontEnd)));
+ m_shaderDataId = d->m_shaderData ? d->m_shaderData->id() : QNodeId{};
+ }
}
} // namespace Render
diff --git a/src/render/lights/environmentlight_p.h b/src/render/lights/environmentlight_p.h
index 00d49d298..92f6ce100 100644
--- a/src/render/lights/environmentlight_p.h
+++ b/src/render/lights/environmentlight_p.h
@@ -63,10 +63,9 @@ class Q_AUTOTEST_EXPORT EnvironmentLight : public BackendNode
{
public:
Qt3DCore::QNodeId shaderData() const;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_shaderDataId;
};
diff --git a/src/render/lights/light.cpp b/src/render/lights/light.cpp
index e8474b728..30d71082b 100644
--- a/src/render/lights/light.cpp
+++ b/src/render/lights/light.cpp
@@ -58,14 +58,18 @@ QNodeId Light::shaderData() const
return m_shaderDataId;
}
-void Light::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
+void Light::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QAbstractLightData>>(change);
- const auto &data = typedChange->data;
- m_shaderDataId = data.shaderDataId;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractLight *node = qobject_cast<const QAbstractLight *>(frontEnd);
+ if (!node)
+ return;
- Q_ASSERT(m_renderer);
- BackendNode::markDirty(AbstractRenderer::LightsDirty);
+ if (firstTime) {
+ QAbstractLightPrivate *d = static_cast<QAbstractLightPrivate *>(QAbstractLightPrivate::get(const_cast<Qt3DCore::QNode *>(frontEnd)));
+ m_shaderDataId = d->m_shaderData ? d->m_shaderData->id() : QNodeId{};
+ BackendNode::markDirty(AbstractRenderer::LightsDirty);
+ }
}
RenderLightFunctor::RenderLightFunctor(AbstractRenderer *renderer, NodeManagers *managers)
diff --git a/src/render/lights/light_p.h b/src/render/lights/light_p.h
index 8ecc87585..5f5f8140e 100644
--- a/src/render/lights/light_p.h
+++ b/src/render/lights/light_p.h
@@ -66,9 +66,9 @@ class Q_AUTOTEST_EXPORT Light : public BackendNode
public:
Qt3DCore::QNodeId shaderData() const;
-private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+private:
Qt3DCore::QNodeId m_shaderDataId;
};
diff --git a/src/render/lights/qenvironmentlight.cpp b/src/render/lights/qenvironmentlight.cpp
index b3dac56ff..86ef04f95 100644
--- a/src/render/lights/qenvironmentlight.cpp
+++ b/src/render/lights/qenvironmentlight.cpp
@@ -55,7 +55,21 @@ namespace Qt3DRender
* \since 5.9
*
* EnvironmentLight uses cubemaps to implement image-based lighting (IBL), a technique
- * often used in conjunction with physically-based rendering (PBR).
+ * often used in conjunction with physically-based rendering (PBR). The cubemaps are
+ * typically expected be based on high dynamic range (HDR) images, with a suitable
+ * OpenGL format (such as RGBA16F) that can handle the increased range of values.
+ *
+ * There are a variety of tools that can be used to produce the cubemaps needed by
+ * EnvironmentLight. Some examples include
+ *
+ * \list
+ * \li \l {https://github.com/dariomanesku/cmftStudio}{cmftStudio}
+ * \li \l {https://github.com/derkreature/IBLBaker}{IBLBaker}
+ * \li \l {https://www.knaldtech.com/lys/}{Lys}
+ * \endlist
+ *
+ * \l {https://hdrihaven.com/hdris/}{HDRI Haven} provides many CC0-licensed HDR images
+ * that can be used as source material for the above tools.
*/
QEnvironmentLightPrivate::QEnvironmentLightPrivate()
@@ -101,8 +115,22 @@ Qt3DCore::QNodeCreatedChangeBasePtr QEnvironmentLight::createNodeCreationChange(
\brief Encapsulate an environment light object in a Qt 3D scene.
\since 5.9
- EnvironmentLight uses cubemaps to implement image-based lighting (IBL), a technique
- often used in conjunction with physically-based rendering (PBR).
+ QEnvironmentLight uses cubemaps to implement image-based lighting (IBL), a technique
+ often used in conjunction with physically-based rendering (PBR). The cubemaps are
+ typically expected be based on high dynamic range (HDR) images, with a suitable
+ OpenGL format (such as RGBA16F) that can handle the increased range of values.
+
+ There are a variety of tools that can be used to produce the cubemaps needed by
+ QEnvironmentLight. Some examples include
+
+ \list
+ \li \l {https://github.com/dariomanesku/cmftStudio}{cmftStudio}
+ \li \l {https://github.com/derkreature/IBLBaker}{IBLBaker}
+ \li \l {https://www.knaldtech.com/lys/}{Lys}
+ \endlist
+
+ \l {https://hdrihaven.com/hdris/}{HDRI Haven} provides many CC0-licensed HDR images
+ that can be used as source material for the above tools.
*/
QEnvironmentLight::QEnvironmentLight(Qt3DCore::QNode *parent)
diff --git a/src/render/materialsystem/effect.cpp b/src/render/materialsystem/effect.cpp
index 29d05ed01..76036bd1f 100644
--- a/src/render/materialsystem/effect.cpp
+++ b/src/render/materialsystem/effect.cpp
@@ -48,6 +48,7 @@
#include <Qt3DCore/qpropertynoderemovedchange.h>
#include <QVariant>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -73,41 +74,25 @@ void Effect::cleanup()
m_techniques.clear();
}
-void Effect::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Effect::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEffectData>>(change);
- const auto &data = typedChange->data;
- m_techniques = data.techniqueIds;
- m_parameterPack.setParameters(data.parameterIds);
-}
-
-void Effect::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("technique"))
- appendRenderTechnique(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("technique"))
- m_techniques.removeOne(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
-
- default:
- break;
- }
-
- markDirty(AbstractRenderer::AllDirty);
- BackendNode::sceneChangeEvent(e);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QEffect *node = qobject_cast<const QEffect *>(frontEnd);
+ if (!node)
+ return;
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
+
+ auto techniques = qIdsForNodes(node->techniques());
+ std::sort(std::begin(techniques), std::end(techniques));
+ if (m_techniques != techniques)
+ m_techniques = techniques;
+
+ if (!firstTime)
+ markDirty(AbstractRenderer::AllDirty);
}
void Effect::appendRenderTechnique(Qt3DCore::QNodeId technique)
diff --git a/src/render/materialsystem/effect_p.h b/src/render/materialsystem/effect_p.h
index 87ff4a803..e81be2b8d 100644
--- a/src/render/materialsystem/effect_p.h
+++ b/src/render/materialsystem/effect_p.h
@@ -70,15 +70,13 @@ public:
~Effect();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void appendRenderTechnique(Qt3DCore::QNodeId t);
QVector<Qt3DCore::QNodeId> techniques() const;
QVector<Qt3DCore::QNodeId> parameters() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<Qt3DCore::QNodeId> m_techniques;
ParameterPack m_parameterPack;
};
diff --git a/src/render/materialsystem/material.cpp b/src/render/materialsystem/material.cpp
index a69ff8a13..07764c207 100644
--- a/src/render/materialsystem/material.cpp
+++ b/src/render/materialsystem/material.cpp
@@ -73,47 +73,26 @@ void Material::cleanup()
m_parameterPack.clear();
}
-void Material::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Material::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QMaterialData>>(change);
- const auto &data = typedChange->data;
- m_effectUuid = data.effectId;
- m_parameterPack.setParameters(data.parameterIds);
-
- markDirty(AbstractRenderer::MaterialDirty);
-}
-
-void Material::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
-
- switch (e->type()) {
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("effect"))
- m_effectUuid = change->value().value<QNodeId>();
- break;
- }
-
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
- }
-
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
-
- default:
- break;
- }
- markDirty(AbstractRenderer::AllDirty);
-
- BackendNode::sceneChangeEvent(e);
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QMaterial *node = qobject_cast<const QMaterial *>(frontEnd);
+ if (!node)
+ return;
+
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
+
+ const auto effectId = node->effect() ? node->effect()->id() : QNodeId{};
+ if (effectId != m_effectUuid)
+ m_effectUuid = effectId;
+
+ if (firstTime)
+ markDirty(AbstractRenderer::MaterialDirty);
+ else
+ markDirty(AbstractRenderer::AllDirty);
}
QVector<Qt3DCore::QNodeId> Material::parameters() const
diff --git a/src/render/materialsystem/material_p.h b/src/render/materialsystem/material_p.h
index 3b55dc657..7a02c6691 100644
--- a/src/render/materialsystem/material_p.h
+++ b/src/render/materialsystem/material_p.h
@@ -79,14 +79,12 @@ public:
~Material();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QVector<Qt3DCore::QNodeId> parameters() const;
Qt3DCore::QNodeId effect() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
ParameterPack m_parameterPack;
Qt3DCore::QNodeId m_effectUuid;
};
diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp
index 86ca418aa..d32e60a2d 100644
--- a/src/render/materialsystem/parameter.cpp
+++ b/src/render/materialsystem/parameter.cpp
@@ -70,34 +70,33 @@ void Parameter::cleanup()
m_uniformValue = UniformValue();
}
-void Parameter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Parameter::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QParameterData>>(change);
- const auto &data = typedChange->data;
- m_name = data.name;
- m_nameId = StringToInt::lookupId(m_name);
- m_uniformValue = UniformValue::fromVariant(data.backendValue);
- markDirty(AbstractRenderer::ParameterDirty);
-}
+ const QParameter *node = qobject_cast<const QParameter *>(frontEnd);
+ if (!node)
+ return;
-void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
-
- if (e->type() == PropertyUpdated) {
- if (propertyChange->propertyName() == QByteArrayLiteral("name")) {
- m_name = propertyChange->value().toString();
- m_nameId = StringToInt::lookupId(m_name);
- markDirty(AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("value")) {
- m_uniformValue = UniformValue::fromVariant(propertyChange->value());
- markDirty(AbstractRenderer::ParameterDirty);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) {
- markDirty(AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
- }
+ AbstractRenderer::BackendNodeDirtySet dirty = firstTime ? AbstractRenderer::ParameterDirty : static_cast<AbstractRenderer::BackendNodeDirtyFlag>(0);
+ if (node->isEnabled() != isEnabled())
+ dirty |= (AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
+
+ if (node->name() != m_name) {
+ m_name = node->name();
+ m_nameId = StringToInt::lookupId(m_name);
+ dirty |= (AbstractRenderer::MaterialDirty | AbstractRenderer::ParameterDirty);
}
- BackendNode::sceneChangeEvent(e);
+ QParameterPrivate* d = static_cast<QParameterPrivate *>(QParameterPrivate::get(const_cast<QParameter *>(node)));
+ if (d->m_backendValue != m_backendValue) {
+ m_backendValue = d->m_backendValue;
+ m_uniformValue = UniformValue::fromVariant(m_backendValue);
+ dirty |= (AbstractRenderer::ParameterDirty);
+ }
+
+ if (dirty)
+ markDirty(dirty);
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
}
QString Parameter::name() const
diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h
index 4ab04bc8e..9deaa11f3 100644
--- a/src/render/materialsystem/parameter_p.h
+++ b/src/render/materialsystem/parameter_p.h
@@ -71,16 +71,15 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
QString name() const;
int nameId() const Q_DECL_NOTHROW { return m_nameId; }
const UniformValue &uniformValue() const { return m_uniformValue; }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QString m_name;
+ QVariant m_backendValue;
UniformValue m_uniformValue;
int m_nameId;
};
diff --git a/src/render/materialsystem/qeffect.cpp b/src/render/materialsystem/qeffect.cpp
index b611657c4..35ac662fb 100644
--- a/src/render/materialsystem/qeffect.cpp
+++ b/src/render/materialsystem/qeffect.cpp
@@ -192,11 +192,7 @@ void QEffect::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -207,14 +203,10 @@ void QEffect::removeParameter(QParameter *parameter)
{
Q_D(QEffect);
- if (parameter && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
+ d->update();
}
/*!
@@ -246,11 +238,7 @@ void QEffect::addTechnique(QTechnique *t)
if (!t->parent())
t->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), t);
- change->setPropertyName("technique");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -260,11 +248,8 @@ void QEffect::addTechnique(QTechnique *t)
void QEffect::removeTechnique(QTechnique *t)
{
Q_D(QEffect);
- if (t && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), t);
- change->setPropertyName("technique");
- d->notifyObservers(change);
- }
+ if (t)
+ d->update();
d->m_techniques.removeOne(t);
// Remove bookkeeping connection
d->unregisterDestructionHelper(t);
diff --git a/src/render/materialsystem/qgraphicsapifilter.cpp b/src/render/materialsystem/qgraphicsapifilter.cpp
index 70f329172..9b5557930 100644
--- a/src/render/materialsystem/qgraphicsapifilter.cpp
+++ b/src/render/materialsystem/qgraphicsapifilter.cpp
@@ -107,6 +107,11 @@ QGraphicsApiFilterPrivate *QGraphicsApiFilterPrivate::get(QGraphicsApiFilter *q)
return q->d_func();
}
+const QGraphicsApiFilterPrivate *QGraphicsApiFilterPrivate::get(const QGraphicsApiFilter *q)
+{
+ return q->d_func();
+}
+
/*!
\class Qt3DRender::QGraphicsApiFilter
\inmodule Qt3DRender
diff --git a/src/render/materialsystem/qgraphicsapifilter_p.h b/src/render/materialsystem/qgraphicsapifilter_p.h
index 3961d4f93..435451c27 100644
--- a/src/render/materialsystem/qgraphicsapifilter_p.h
+++ b/src/render/materialsystem/qgraphicsapifilter_p.h
@@ -84,6 +84,7 @@ public:
}
static QGraphicsApiFilterPrivate *get(QGraphicsApiFilter *q);
+ static const QGraphicsApiFilterPrivate *get(const QGraphicsApiFilter *q);
Q_DECLARE_PUBLIC(QGraphicsApiFilter)
GraphicsApiFilterData m_data;
diff --git a/src/render/materialsystem/qmaterial.cpp b/src/render/materialsystem/qmaterial.cpp
index c6913441e..db523a700 100644
--- a/src/render/materialsystem/qmaterial.cpp
+++ b/src/render/materialsystem/qmaterial.cpp
@@ -275,11 +275,7 @@ void QMaterial::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -290,11 +286,7 @@ void QMaterial::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QMaterial);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
}
diff --git a/src/render/materialsystem/qrenderpass.cpp b/src/render/materialsystem/qrenderpass.cpp
index 111bb7b5f..d0821c49c 100644
--- a/src/render/materialsystem/qrenderpass.cpp
+++ b/src/render/materialsystem/qrenderpass.cpp
@@ -231,12 +231,6 @@ void QRenderPass::setShaderProgram(QShaderProgram *shaderProgram)
Q_D(QRenderPass);
if (d->m_shader != shaderProgram) {
- if (d->m_shader != nullptr && d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), d->m_shader);
- change->setPropertyName("shaderProgram");
- d->notifyObservers(change);
- }
-
if (d->m_shader)
d->unregisterDestructionHelper(d->m_shader);
@@ -283,11 +277,7 @@ void QRenderPass::addFilterKey(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -298,11 +288,7 @@ void QRenderPass::removeFilterKey(QFilterKey *filterKey)
{
Q_ASSERT(filterKey);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
d->m_filterKeyList.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -339,11 +325,7 @@ void QRenderPass::addRenderState(QRenderState *state)
if (!state->parent())
state->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -354,11 +336,7 @@ void QRenderPass::removeRenderState(QRenderState *state)
{
Q_ASSERT(state);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), state);
- change->setPropertyName("renderState");
- d->notifyObservers(change);
- }
+ d->update();
d->m_renderStates.removeOne(state);
// Remove bookkeeping connection
d->unregisterDestructionHelper(state);
@@ -394,11 +372,7 @@ void QRenderPass::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -409,11 +383,7 @@ void QRenderPass::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QRenderPass);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
diff --git a/src/render/materialsystem/qtechnique.cpp b/src/render/materialsystem/qtechnique.cpp
index b668eb25f..dadeb98bd 100644
--- a/src/render/materialsystem/qtechnique.cpp
+++ b/src/render/materialsystem/qtechnique.cpp
@@ -234,12 +234,7 @@ QTechnique::QTechnique(QTechniquePrivate &dd, QNode *parent)
/*! \internal */
void QTechniquePrivate::_q_graphicsApiFilterChanged()
{
- if (m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(m_id);
- change->setPropertyName("graphicsApiFilterData");
- change->setValue(QVariant::fromValue(QGraphicsApiFilterPrivate::get(const_cast<QGraphicsApiFilter *>(&m_graphicsApiFilter))->m_data));
- notifyObservers(change);
- }
+ update();
}
/*!
@@ -262,11 +257,7 @@ void QTechnique::addFilterKey(QFilterKey *filterKey)
if (!filterKey->parent())
filterKey->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -277,11 +268,7 @@ void QTechnique::removeFilterKey(QFilterKey *filterKey)
{
Q_ASSERT(filterKey);
Q_D(QTechnique);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), filterKey);
- change->setPropertyName("filterKeys");
- d->notifyObservers(change);
- }
+ d->update();
d->m_filterKeys.removeOne(filterKey);
// Remove bookkeeping connection
d->unregisterDestructionHelper(filterKey);
@@ -317,11 +304,7 @@ void QTechnique::addParameter(QParameter *parameter)
if (!parameter->parent())
parameter->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -332,11 +315,7 @@ void QTechnique::removeParameter(QParameter *parameter)
{
Q_ASSERT(parameter);
Q_D(QTechnique);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), parameter);
- change->setPropertyName("parameter");
- d->notifyObservers(change);
- }
+ d->update();
d->m_parameters.removeOne(parameter);
// Remove bookkeeping connection
d->unregisterDestructionHelper(parameter);
@@ -362,11 +341,7 @@ void QTechnique::addRenderPass(QRenderPass *pass)
if (!pass->parent())
pass->setParent(this);
- if (d->m_changeArbiter != nullptr) {
- const auto change = QPropertyNodeAddedChangePtr::create(id(), pass);
- change->setPropertyName("pass");
- d->notifyObservers(change);
- }
+ d->update();
}
}
@@ -377,11 +352,7 @@ void QTechnique::removeRenderPass(QRenderPass *pass)
{
Q_ASSERT(pass);
Q_D(QTechnique);
- if (d->m_changeArbiter) {
- const auto change = QPropertyNodeRemovedChangePtr::create(id(), pass);
- change->setPropertyName("pass");
- d->notifyObservers(change);
- }
+ d->update();
d->m_renderPasses.removeOne(pass);
// Remove bookkeeping connection
d->unregisterDestructionHelper(pass);
@@ -405,12 +376,19 @@ QVector<QParameter *> QTechnique::parameters() const
return d->m_parameters;
}
+// TODO Qt 6 -> Remove
QGraphicsApiFilter *QTechnique::graphicsApiFilter()
{
Q_D(QTechnique);
return &d->m_graphicsApiFilter;
}
+const QGraphicsApiFilter *QTechnique::graphicsApiFilter() const
+{
+ Q_D(const QTechnique);
+ return &d->m_graphicsApiFilter;
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QTechnique::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QTechniqueData>::create(this);
diff --git a/src/render/materialsystem/qtechnique.h b/src/render/materialsystem/qtechnique.h
index 7711cd67f..f0c857c2b 100644
--- a/src/render/materialsystem/qtechnique.h
+++ b/src/render/materialsystem/qtechnique.h
@@ -76,7 +76,8 @@ public:
void removeRenderPass(QRenderPass *pass);
QVector<QRenderPass *> renderPasses() const;
- QGraphicsApiFilter *graphicsApiFilter();
+ Q_DECL_DEPRECATED QGraphicsApiFilter *graphicsApiFilter();
+ const QGraphicsApiFilter *graphicsApiFilter() const;
protected:
explicit QTechnique(QTechniquePrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/render/materialsystem/renderpass.cpp b/src/render/materialsystem/renderpass.cpp
index e0fadddd9..aaeca3bb4 100644
--- a/src/render/materialsystem/renderpass.cpp
+++ b/src/render/materialsystem/renderpass.cpp
@@ -52,6 +52,8 @@
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
@@ -77,58 +79,33 @@ void RenderPass::cleanup()
m_shaderUuid = Qt3DCore::QNodeId();
}
-void RenderPass::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
-{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QRenderPassData>>(change);
- const auto &data = typedChange->data;
- m_filterKeyList = data.filterKeyIds;
- m_parameterPack.setParameters(data.parameterIds);
- for (const auto &renderStateId : qAsConst(data.renderStateIds))
- addRenderState(renderStateId);
- m_shaderUuid = data.shaderId;
-}
-
-void RenderPass::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+void RenderPass::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- switch (e->type()) {
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("filterKeys"))
- appendFilterKey(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = change->addedNodeId();
- else if (change->propertyName() == QByteArrayLiteral("renderState"))
- addRenderState(change->addedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.appendParameter(change->addedNodeId());
- break;
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QRenderPass *node = qobject_cast<const QRenderPass *>(frontEnd);
+ if (!node)
+ return;
+
+ if ((node->shaderProgram() && node->shaderProgram()->id() != m_shaderUuid) ||
+ (!node->shaderProgram() && !m_shaderUuid.isNull())) {
+ m_shaderUuid = node->shaderProgram() ? node->shaderProgram()->id() : QNodeId{};
}
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = change->value().value<Qt3DCore::QNodeId>();
- break;
- }
+ auto filterList = qIdsForNodes(node->filterKeys());
+ std::sort(std::begin(filterList), std::end(filterList));
+ if (m_filterKeyList != filterList)
+ m_filterKeyList = filterList;
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("filterKeys"))
- removeFilterKey(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("shaderProgram"))
- m_shaderUuid = QNodeId();
- else if (change->propertyName() == QByteArrayLiteral("renderState"))
- removeRenderState(change->removedNodeId());
- else if (change->propertyName() == QByteArrayLiteral("parameter"))
- m_parameterPack.removeParameter(change->removedNodeId());
- break;
- }
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters)
+ m_parameterPack.setParameters(parameters);
- default:
- break;
- }
+ auto renderStates = qIdsForNodes(node->renderStates());
+ std::sort(std::begin(renderStates), std::end(renderStates));
+ if (m_renderStates != renderStates)
+ m_renderStates = renderStates;
- BackendNode::sceneChangeEvent(e);
markDirty(AbstractRenderer::AllDirty);
}
diff --git a/src/render/materialsystem/renderpass_p.h b/src/render/materialsystem/renderpass_p.h
index 1ca02b1ad..314386ad1 100644
--- a/src/render/materialsystem/renderpass_p.h
+++ b/src/render/materialsystem/renderpass_p.h
@@ -79,7 +79,7 @@ public:
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
Qt3DCore::QNodeId shaderProgram() const;
QVector<Qt3DCore::QNodeId> filterKeys() const;
@@ -95,8 +95,6 @@ private:
void addRenderState(Qt3DCore::QNodeId renderStateId);
void removeRenderState(Qt3DCore::QNodeId renderStateId);
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
Qt3DCore::QNodeId m_shaderUuid;
QVector<Qt3DCore::QNodeId> m_filterKeyList;
ParameterPack m_parameterPack;
diff --git a/src/render/materialsystem/technique.cpp b/src/render/materialsystem/technique.cpp
index 42430883e..d4199b7e3 100644
--- a/src/render/materialsystem/technique.cpp
+++ b/src/render/materialsystem/technique.cpp
@@ -85,72 +85,48 @@ void Technique::cleanup()
m_isCompatibleWithRenderer = false;
}
-void Technique::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Technique::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QTechniqueData>>(change);
- const QTechniqueData &data = typedChange->data;
-
- m_graphicsApiFilterData = data.graphicsApiFilterData;
- m_filterKeyList = data.filterKeyIds;
- m_parameterPack.setParameters(data.parameterIds);
- m_renderPasses = data.renderPassIds;
- m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
- markDirty(AbstractRenderer::TechniquesDirty);
-}
+ const QTechnique *node = qobject_cast<const QTechnique *>(frontEnd);
-void Technique::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
- case PropertyUpdated: {
- const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("enabled")) {
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("graphicsApiFilterData")) {
- GraphicsApiFilterData filterData = change->value().value<GraphicsApiFilterData>();
- m_graphicsApiFilterData = filterData;
- // Notify the manager that our graphicsApiFilterData has changed
- // and that we therefore need to be check for compatibility again
- m_isCompatibleWithRenderer = false;
- m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ if (!node)
+ return;
+
+ bool dirty = isEnabled() != frontEnd->isEnabled();
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ auto renderPasses = qIdsForNodes(node->renderPasses());
+ std::sort(std::begin(renderPasses), std::end(renderPasses));
+ if (m_renderPasses != renderPasses) {
+ m_renderPasses = renderPasses;
+ dirty = true;
}
- case PropertyValueAdded: {
- const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("pass")) {
- appendRenderPass(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.appendParameter(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("filterKeys")) {
- appendFilterKey(change->addedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ auto parameters = qIdsForNodes(node->parameters());
+ std::sort(std::begin(parameters), std::end(parameters));
+ if (m_parameterPack.parameters() != parameters) {
+ m_parameterPack.setParameters(parameters);
+ dirty = true;
}
- case PropertyValueRemoved: {
- const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("pass")) {
- removeRenderPass(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("parameter")) {
- m_parameterPack.removeParameter(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- } else if (change->propertyName() == QByteArrayLiteral("filterKeys")) {
- removeFilterKey(change->removedNodeId());
- markDirty(AbstractRenderer::TechniquesDirty);
- }
- break;
+ auto filterKeys = qIdsForNodes(node->filterKeys());
+ std::sort(std::begin(filterKeys), std::end(filterKeys));
+ if (m_filterKeyList != filterKeys) {
+ m_filterKeyList = filterKeys;
+ dirty = true;
+ }
+
+ auto graphicsApiFilterData = QGraphicsApiFilterPrivate::get(node->graphicsApiFilter())->m_data;
+ if (m_graphicsApiFilterData != graphicsApiFilterData) {
+ m_graphicsApiFilterData = graphicsApiFilterData;
+ m_isCompatibleWithRenderer = false;
+ dirty = true;
}
- default:
- break;
+ if (dirty) {
+ m_nodeManager->techniqueManager()->addDirtyTechnique(peerId());
+ markDirty(AbstractRenderer::TechniquesDirty);
}
- BackendNode::sceneChangeEvent(e);
}
QVector<Qt3DCore::QNodeId> Technique::parameters() const
diff --git a/src/render/materialsystem/technique_p.h b/src/render/materialsystem/technique_p.h
index d885c1b87..1d0d0a9dd 100644
--- a/src/render/materialsystem/technique_p.h
+++ b/src/render/materialsystem/technique_p.h
@@ -80,7 +80,8 @@ public:
~Technique();
void cleanup();
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
+
QVector<Qt3DCore::QNodeId> parameters() const;
void appendRenderPass(Qt3DCore::QNodeId renderPassId);
@@ -102,7 +103,6 @@ public:
NodeManagers *nodeManager() const;
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
GraphicsApiFilterData m_graphicsApiFilterData;
ParameterPack m_parameterPack;
diff --git a/src/render/picking/qpickevent.cpp b/src/render/picking/qpickevent.cpp
index a18c6ead8..ae5748082 100644
--- a/src/render/picking/qpickevent.cpp
+++ b/src/render/picking/qpickevent.cpp
@@ -309,14 +309,14 @@ int QPickEvent::modifiers() const
* The viewport in which this event originated. A null value means the event originated from a frame graph branch without a Viewport.
* If a frame graph branch has a Viewport inside a Viewport the property will contain the leaf viewport.
*
- * \since 5.13
+ * \since 5.14
*/
/*!
* \property Qt3DRender::QPickEvent::viewport
* The viewport in which this event originated. A null value means the event originated from a frame graph branch without a QViewport.
* If a frame graph branch has a Viewport inside a Viewport the property will contain the leaf viewport.
*
- * \since 5.13
+ * \since 5.14
*/
QViewport *QPickEvent::viewport() const
{
@@ -332,7 +332,7 @@ QViewport *QPickEvent::viewport() const
* If the object picker is not attached to a leaf node in the scene graph,
* this is useful to find which child entity was actually picked.
*
- * \since 5.13
+ * \since 5.14
*/
/*!
* \property Qt3DRender::QPickEvent::entity
@@ -341,7 +341,7 @@ QViewport *QPickEvent::viewport() const
* If the object picker is not attached to a leaf node in the scene graph,
* this is useful to find which child entity was actually picked.
*
- * \since 5.13
+ * \since 5.14
*/
Qt3DCore::QEntity *QPickEvent::entity() const
{
diff --git a/src/render/picking/qpickevent.h b/src/render/picking/qpickevent.h
index 21d072ffe..854008aaf 100644
--- a/src/render/picking/qpickevent.h
+++ b/src/render/picking/qpickevent.h
@@ -70,8 +70,8 @@ class Q_3DRENDERSHARED_EXPORT QPickEvent : public QObject
Q_PROPERTY(Qt3DRender::QPickEvent::Buttons button READ button CONSTANT)
Q_PROPERTY(int buttons READ buttons CONSTANT)
Q_PROPERTY(int modifiers READ modifiers CONSTANT)
- Q_PROPERTY(Qt3DRender::QViewport *viewport READ viewport CONSTANT)
- Q_PROPERTY(Qt3DCore::QEntity *entity READ entity CONSTANT)
+ Q_PROPERTY(Qt3DRender::QViewport *viewport READ viewport CONSTANT REVISION 14)
+ Q_PROPERTY(Qt3DCore::QEntity *entity READ entity CONSTANT REVISION 14)
public:
enum Buttons {
LeftButton = Qt::LeftButton,
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
index c9b04fa8f..f4bd8b871 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp
@@ -269,7 +269,7 @@ QOpenGLShaderProgram *GraphicsContext::createShaderProgram(Shader *shaderNode)
// That assumes that the shaderProgram in Shader stays the same
void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderProgram *shaderProgram)
{
- GraphicsHelperInterface *glHelper = resolveHighestOpenGLFunctions();
+ QScopedPointer<GraphicsHelperInterface> glHelper(resolveHighestOpenGLFunctions());
shader->initializeUniforms(glHelper->programUniformsAndLocations(shaderProgram->programId()));
shader->initializeAttributes(glHelper->programAttributesAndLocations(shaderProgram->programId()));
if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject))
diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
index 24978fd87..c70f82dea 100644
--- a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
+++ b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
@@ -197,7 +197,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
// Add states from new stateSet we might be missing
// but don' t override existing states (lower StateSetNode always has priority)
if (rStateSet->hasRenderStates())
- addUniqueStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager());
+ addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager());
break;
}
@@ -436,13 +436,13 @@ void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList,
}
// Only add states with types we don't already have
-void addUniqueStatesToRenderStateSet(RenderStateSet *stateSet,
- const QVector<Qt3DCore::QNodeId> stateIds,
- RenderStateManager *manager)
+void addStatesToRenderStateSet(RenderStateSet *stateSet,
+ const QVector<Qt3DCore::QNodeId> stateIds,
+ RenderStateManager *manager)
{
for (const Qt3DCore::QNodeId &stateId : stateIds) {
RenderStateNode *node = manager->lookupResource(stateId);
- if (node->isEnabled() && !stateSet->hasStateOfType(node->type())) {
+ if (node->isEnabled() && stateSet->canAddStateOfType(node->type())) {
stateSet->addState(node->impl());
}
}
diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h b/src/render/renderers/opengl/jobs/renderviewjobutils_p.h
index bd2e12534..b2fa59785 100644
--- a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h
+++ b/src/render/renderers/opengl/jobs/renderviewjobutils_p.h
@@ -150,9 +150,9 @@ void parametersFromParametersProvider(ParameterInfoList *infoList,
Q_AUTOTEST_EXPORT ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *infoList,
const int nameId);
-Q_AUTOTEST_EXPORT void addUniqueStatesToRenderStateSet(RenderStateSet *stateSet,
- const QVector<Qt3DCore::QNodeId> stateIds,
- RenderStateManager *manager);
+Q_AUTOTEST_EXPORT void addStatesToRenderStateSet(RenderStateSet *stateSet,
+ const QVector<Qt3DCore::QNodeId> stateIds,
+ RenderStateManager *manager);
typedef QHash<int, QVariant> UniformBlockValueBuilderHash;
diff --git a/src/render/renderers/opengl/renderer/commandthread.cpp b/src/render/renderers/opengl/renderer/commandthread.cpp
index dcaacadcc..a518d3b68 100644
--- a/src/render/renderers/opengl/renderer/commandthread.cpp
+++ b/src/render/renderers/opengl/renderer/commandthread.cpp
@@ -176,7 +176,7 @@ void CommandThread::run()
m_commandRequestedSemaphore.acquire();
// Are we still running?
- if (!m_running.load()) {
+ if (!m_running.loadRelaxed()) {
m_graphicsContext->doneCurrent();
// to prevent executeCommand being locked
m_commandExecutionSemaphore.release();
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index e7112b3f4..2df3d1270 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -192,7 +192,6 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
, m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create())
, m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create())
- , m_updateEntityHierarchyJob(Render::UpdateEntityHierarchyJobPtr::create())
, m_bufferGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
, m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
@@ -213,9 +212,6 @@ Renderer::Renderer(QRenderAspect::RenderType type)
if (m_renderThread)
m_renderThread->waitForStart();
- m_worldTransformJob->addDependency(m_updateEntityHierarchyJob);
- m_updateEntityLayersJob->addDependency(m_updateEntityHierarchyJob);
-
// Create jobs to update transforms and bounding volumes
// We can only update bounding volumes once all world transforms are known
m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
@@ -304,7 +300,6 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager());
m_updateEntityLayersJob->setManager(m_nodesManager);
m_updateTreeEnabledJob->setManagers(m_nodesManager);
- m_updateEntityHierarchyJob->setManager(m_nodesManager);
}
void Renderer::setServices(QServiceLocator *services)
@@ -448,7 +443,7 @@ void Renderer::shutdown()
QMutexLocker lock(&m_hasBeenInitializedMutex);
qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown";
- m_running.store(0);
+ m_running.storeRelaxed(0);
// We delete any renderqueue that we may not have had time to render
// before the surface was destroyed
@@ -559,10 +554,9 @@ Render::FrameGraphNode *Renderer::frameGraphRoot() const
// 2) setSceneRoot waits to acquire initialization
// 3) submitRenderView -> check for surface
// -> make surface current + create proper glHelper if needed
-void Renderer::setSceneRoot(QBackendNodeFactory *factory, Entity *sgRoot)
+void Renderer::setSceneRoot(Entity *sgRoot)
{
Q_ASSERT(sgRoot);
- Q_UNUSED(factory);
// If initialization hasn't been completed we must wait
m_waitForInitializationToBeCompleted.acquire();
@@ -620,7 +614,7 @@ void Renderer::render()
// One scene description
// One framegraph description
- while (m_running.load() > 0) {
+ while (m_running.loadRelaxed() > 0) {
doRender();
// TO DO: Restore windows exposed detection
// Probably needs to happens some place else though
@@ -790,7 +784,7 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder
const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder);
locker.unlock(); // We're done protecting the queue at this point
if (isQueueComplete) {
- if (m_renderThread && m_running.load())
+ if (m_renderThread && m_running.loadRelaxed())
Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0);
m_submitRenderViewsSemaphore.release(1);
}
@@ -799,7 +793,7 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder
bool Renderer::canRender() const
{
// Make sure that we've not been told to terminate
- if (m_renderThread && !m_running.load()) {
+ if (m_renderThread && !m_running.loadRelaxed()) {
qCDebug(Rendering) << "RenderThread termination requested whilst waiting";
return false;
}
@@ -818,7 +812,7 @@ bool Renderer::isReadyToSubmit()
m_submitRenderViewsSemaphore.acquire(1);
// Check if shutdown has been requested
- if (m_running.load() == 0)
+ if (m_running.loadRelaxed() == 0)
return false;
// The semaphore should only
@@ -1425,7 +1419,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
const int renderViewsCount = renderViews.size();
quint64 frameElapsed = queueElapsed;
- m_lastFrameCorrect.store(1); // everything fine until now.....
+ m_lastFrameCorrect.storeRelaxed(1); // everything fine until now.....
qCDebug(Memory) << Q_FUNC_INFO << "rendering frame ";
@@ -1458,7 +1452,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// to use when surface is null. Or if we should instead expose an
// offscreensurface to Qt3D.
if (!surface || !surfaceLock.isSurfaceValid()) {
- m_lastFrameCorrect.store(0);
+ m_lastFrameCorrect.storeRelaxed(0);
continue;
}
@@ -1478,7 +1472,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// next RenderView. We won't get the full frame but we may get something
if (!m_submissionContext->beginDrawing(surface)) {
qWarning() << "Failed to make OpenGL context current on surface";
- m_lastFrameCorrect.store(0);
+ m_lastFrameCorrect.storeRelaxed(0);
continue;
}
@@ -1579,7 +1573,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// Execute the render commands
if (!executeCommandsSubmission(renderView))
- m_lastFrameCorrect.store(0); // something went wrong; make sure to render the next frame!
+ m_lastFrameCorrect.storeRelaxed(0); // something went wrong; make sure to render the next frame!
// executeCommandsSubmission takes care of restoring the stateset to the value
// of gc->currentContext() at the moment it was called (either
@@ -1682,7 +1676,7 @@ bool Renderer::shouldRender()
|| m_renderThread == nullptr // <==> we use Scene3D
|| m_dirtyBits.marked != 0
|| m_dirtyBits.remaining != 0
- || !m_lastFrameCorrect.load());
+ || !m_lastFrameCorrect.loadRelaxed());
}
void Renderer::skipNextFrame()
@@ -1749,17 +1743,14 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Add jobs
const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
- const bool entityHierarchyNeedsToBeRebuilt = dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty;
- if (entitiesEnabledDirty || entityHierarchyNeedsToBeRebuilt) {
+ if (entitiesEnabledDirty) {
renderBinJobs.push_back(m_updateTreeEnabledJob);
// This dependency is added here because we clear all dependencies
// at the start of this function.
m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
- m_calculateBoundingVolumeJob->addDependency(m_updateEntityHierarchyJob);
}
- if (dirtyBitsForFrame & AbstractRenderer::TransformDirty ||
- dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty) {
+ if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
renderBinJobs.push_back(m_worldTransformJob);
renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
renderBinJobs.push_back(m_updateShaderDataTransformJob);
@@ -1772,7 +1763,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
}
if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
- dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty ||
dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
renderBinJobs.push_back(m_expandBoundingVolumeJob);
}
@@ -1799,7 +1789,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Layer cache is dependent on layers, layer filters (hence FG structure
// changes) and the enabled flag on entities
const bool frameGraphDirty = dirtyBitsForFrame & AbstractRenderer::FrameGraphDirty;
- const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty || entityHierarchyNeedsToBeRebuilt;
+ const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty || frameGraphDirty;
const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty;
const bool lightsDirty = dirtyBitsForFrame & AbstractRenderer::LightsDirty;
@@ -1807,10 +1797,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
const bool renderableDirty = dirtyBitsForFrame & AbstractRenderer::GeometryDirty;
const bool materialCacheNeedsToBeRebuilt = materialDirty || frameGraphDirty;
- // Rebuild Entity Hierarchy if dirty
- if (entityHierarchyNeedsToBeRebuilt)
- renderBinJobs.push_back(m_updateEntityHierarchyJob);
-
// Rebuild Entity Layers list if layers are dirty
if (layersDirty)
renderBinJobs.push_back(m_updateEntityLayersJob);
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index 5b566b3e7..bfab85e4f 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -78,7 +78,6 @@
#include <Qt3DRender/private/filtercompatibletechniquejob_p.h>
#include <Qt3DRender/private/updateskinningpalettejob_p.h>
#include <Qt3DRender/private/updateentitylayersjob_p.h>
-#include <Qt3DRender/private/updateentityhierarchyjob_p.h>
#include <Qt3DRender/private/renderercache_p.h>
#include <Qt3DRender/private/texture_p.h>
#include <Qt3DRender/private/glfence_p.h>
@@ -185,9 +184,9 @@ public:
void doRender(bool swapBuffers = true) override;
void cleanGraphicsResources() override;
- bool isRunning() const override { return m_running.load(); }
+ bool isRunning() const override { return m_running.loadRelaxed(); }
- void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Entity *sgRoot) override;
+ void setSceneRoot(Entity *sgRoot) override;
Entity *sceneRoot() const override { return m_renderSceneRoot; }
FrameGraphNode *frameGraphRoot() const override;
@@ -368,7 +367,6 @@ private:
UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob;
FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
UpdateEntityLayersJobPtr m_updateEntityLayersJob;
- UpdateEntityHierarchyJobPtr m_updateEntityHierarchyJob;
QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests;
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index 5845fe147..b00f2c473 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -425,7 +425,6 @@ struct SubRangeSorter<QSortPolicy::Texture>
QVector<ShaderParameterPack::NamedResource> texturesB = b->m_parameterPack.textures();
const int originalTextureASize = texturesA.size();
- const bool isSuperior = originalTextureASize > texturesB.size();
if (texturesB.size() > texturesA.size())
qSwap(texturesA, texturesB);
@@ -656,7 +655,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
RenderPass *pass = passData.pass;
if (pass->hasRenderStates()) {
command->m_stateSet = new RenderStateSet();
- addUniqueStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
+ addStatesToRenderStateSet(command->m_stateSet, 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);
@@ -781,7 +780,7 @@ QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<En
if (pass->hasRenderStates()) {
command->m_stateSet = new RenderStateSet();
- addUniqueStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
+ addStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
// Merge per pass stateset with global stateset
// so that the local stateset only overrides
diff --git a/src/render/renderers/opengl/renderstates/renderstateset.cpp b/src/render/renderers/opengl/renderstates/renderstateset.cpp
index b14695c77..d667d9c76 100644
--- a/src/render/renderers/opengl/renderstates/renderstateset.cpp
+++ b/src/render/renderers/opengl/renderstates/renderstateset.cpp
@@ -112,17 +112,28 @@ void RenderStateSet::merge(RenderStateSet *other)
// We only add states which are new (different type)
for (const StateVariant &otherState : otherStates) {
- const bool hasFoundStateOfSameType = hasStateOfType(otherState.type);
- if (!hasFoundStateOfSameType)
+ const bool canAdd = canAddStateOfType(otherState.type);
+ if (canAdd)
m_states.push_back(otherState);
}
}
+bool RenderStateSet::canAddStateOfType(StateMask type) const
+{
+ return !hasStateOfType(type) || allowMultipleStatesOfType(type);
+}
+
bool RenderStateSet::hasStateOfType(StateMask type) const
{
return (type & stateMask());
}
+bool RenderStateSet::allowMultipleStatesOfType(StateMask type) const
+{
+ return (type == BlendEquationArgumentsMask) ||
+ (type == ClipPlaneMask);
+}
+
bool RenderStateSet::contains(const StateVariant &ds) const
{
// trivial reject using the state mask bits
diff --git a/src/render/renderers/opengl/renderstates/renderstateset_p.h b/src/render/renderers/opengl/renderstates/renderstateset_p.h
index 29be4d2f1..c2f3a0219 100644
--- a/src/render/renderers/opengl/renderstates/renderstateset_p.h
+++ b/src/render/renderers/opengl/renderstates/renderstateset_p.h
@@ -93,8 +93,7 @@ public:
QVector<StateVariant> states() const { return m_states; }
- bool hasStateOfType(StateMask type) const;
-
+ bool canAddStateOfType(StateMask type) const;
/**
* @brief contains - check if this set contains a matching piece of state
@@ -102,6 +101,11 @@ public:
* @return
*/
bool contains(const StateVariant &ds) const;
+
+private:
+ bool hasStateOfType(StateMask type) const;
+ bool allowMultipleStatesOfType(StateMask type) const;
+
private:
StateMaskSet m_stateMask;
QVector<StateVariant> m_states;
diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp
index 93348d0b0..11d2c2be9 100644
--- a/src/render/renderers/opengl/textures/gltexture.cpp
+++ b/src/render/renderers/opengl/textures/gltexture.cpp
@@ -474,15 +474,15 @@ QOpenGLTexture *GLTexture::buildGLTexture()
QAbstractTexture::TextureFormat format = m_properties.format;
if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) {
switch (m_properties.format) {
- case QOpenGLTexture::RGBA8_UNorm:
- case QOpenGLTexture::RGBAFormat:
+ case QAbstractTexture::RGBA8_UNorm:
+ case QAbstractTexture::RGBAFormat:
format = QAbstractTexture::RGBAFormat;
break;
- case QOpenGLTexture::RGB8_UNorm:
- case QOpenGLTexture::RGBFormat:
+ case QAbstractTexture::RGB8_UNorm:
+ case QAbstractTexture::RGBFormat:
format = QAbstractTexture::RGBFormat;
break;
- case QOpenGLTexture::DepthFormat:
+ case QAbstractTexture::DepthFormat:
format = QAbstractTexture::DepthFormat;
break;
default:
@@ -682,8 +682,8 @@ void GLTexture::introspectPropertiesFromSharedTextureId()
const QPair<int, int> ctxGLVersion = ctx->format().version();
if (ctxGLVersion.first > 4 || (ctxGLVersion.first == 4 && ctxGLVersion.second >= 5)) {
// Only for GL 4.5+
- QOpenGLFunctions_4_5_Core *gl5 = ctx->versionFunctions<QOpenGLFunctions_4_5_Core>();
#ifdef GL_TEXTURE_TARGET
+ QOpenGLFunctions_4_5_Core *gl5 = ctx->versionFunctions<QOpenGLFunctions_4_5_Core>();
if (gl5 != nullptr)
gl5->glGetTextureParameteriv(m_sharedTextureId, GL_TEXTURE_TARGET, reinterpret_cast<int *>(&m_properties.target));
#endif
diff --git a/src/render/renderstates/qdepthrange.cpp b/src/render/renderstates/qdepthrange.cpp
index 58b8b744a..ec5bbce9f 100644
--- a/src/render/renderstates/qdepthrange.cpp
+++ b/src/render/renderstates/qdepthrange.cpp
@@ -48,7 +48,7 @@ namespace Qt3DRender {
/*!
\class Qt3DRender::QDepthRange
\inmodule Qt3DRender
- \since 5.13
+ \since 5.14
\ingroup renderstates
\brief Enables remapping depth values written into the depth buffer.
@@ -65,7 +65,7 @@ namespace Qt3DRender {
\inherits RenderState
\inqmlmodule Qt3D.Render
\ingroup renderstates
- \since 5.13
+ \since 5.14
\brief Enables remapping depth values written into the depth buffer.
By default, OpenGL writes scene depth information into the depth buffer in
diff --git a/src/render/texture/qabstracttexture.cpp b/src/render/texture/qabstracttexture.cpp
index 399314f24..229d773ad 100644
--- a/src/render/texture/qabstracttexture.cpp
+++ b/src/render/texture/qabstracttexture.cpp
@@ -81,10 +81,7 @@ void QAbstractTexturePrivate::setDataFunctor(const QTextureGeneratorPtr &generat
{
if (generator != m_dataFunctor) {
m_dataFunctor = generator;
- auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id);
- change->setPropertyName("generator");
- change->setValue(QVariant::fromValue(generator));
- notifyObservers(change);
+ update();
}
}
@@ -811,24 +808,15 @@ void QAbstractTexture::setWrapMode(const QTextureWrapMode &wrapMode)
Q_D(QAbstractTexture);
if (d->m_wrapMode.x() != wrapMode.x()) {
d->m_wrapMode.setX(wrapMode.x());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeX");
- e->setValue(static_cast<int>(d->m_wrapMode.x()));
- d->notifyObservers(e);
+ d->update();
}
if (d->m_wrapMode.y() != wrapMode.y()) {
d->m_wrapMode.setY(wrapMode.y());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeY");
- e->setValue(static_cast<int>(d->m_wrapMode.y()));
- d->notifyObservers(e);
+ d->update();
}
if (d->m_wrapMode.z() != wrapMode.z()) {
d->m_wrapMode.setZ(wrapMode.z());
- auto e = QPropertyUpdatedChangePtr::create(d->m_id);
- e->setPropertyName("wrapModeZ");
- e->setValue(static_cast<int>(d->m_wrapMode.z()));
- d->notifyObservers(e);
+ d->update();
}
}
@@ -983,16 +971,8 @@ void QAbstractTexture::updateData(const QTextureDataUpdate &update)
{
Q_D(QAbstractTexture);
- // Send update to backend if we have the changeArbiter
- if (d->m_changeArbiter != nullptr) {
- auto e = QPropertyUpdatedChangePtr::create(id());
- e->setPropertyName("updateData");
- e->setValue(QVariant::fromValue(update));
- notifyObservers(e);
- } else {
- // If we have no arbiter (no backend), record the update as part of the creation changes
- d->m_initialDataUpdates.push_back(update);
- }
+ d->m_pendingDataUpdates.push_back(update);
+ d->update();
}
Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange() const
@@ -1019,8 +999,8 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange()
data.samples = d->m_samples;
data.dataFunctor = d->m_dataFunctor;
data.sharedTextureId = d->m_sharedTextureId;
- data.initialDataUpdates = d->m_initialDataUpdates;
- return creationChange;
+ data.initialDataUpdates = d->m_pendingDataUpdates;
+ return std::move(creationChange);
}
/*!
diff --git a/src/render/texture/qabstracttexture_p.h b/src/render/texture/qabstracttexture_p.h
index 072bd8159..573eac8c7 100644
--- a/src/render/texture/qabstracttexture_p.h
+++ b/src/render/texture/qabstracttexture_p.h
@@ -96,7 +96,7 @@ public :
QTextureGeneratorPtr dataFunctor() const;
void setDataFunctor(const QTextureGeneratorPtr &generator);
- QVector<QTextureDataUpdate> m_initialDataUpdates;
+ QVector<QTextureDataUpdate> m_pendingDataUpdates;
private:
QTextureGeneratorPtr m_dataFunctor;
diff --git a/src/render/texture/qabstracttextureimage.cpp b/src/render/texture/qabstracttextureimage.cpp
index a95e1fffd..42f8eb747 100644
--- a/src/render/texture/qabstracttextureimage.cpp
+++ b/src/render/texture/qabstracttextureimage.cpp
@@ -255,12 +255,7 @@ void QAbstractTextureImage::setFace(QAbstractTexture::CubeMapFace face)
void QAbstractTextureImage::notifyDataGeneratorChanged()
{
Q_D(QAbstractTextureImage);
- if (d->m_changeArbiter != nullptr) {
- auto change = QPropertyUpdatedChangePtr::create(d->m_id);
- change->setPropertyName("dataGenerator");
- change->setValue(QVariant::fromValue(dataGenerator()));
- d->notifyObservers(change);
- }
+ d->update();
}
/*! \internal */
diff --git a/src/render/texture/qtexturedataupdate.cpp b/src/render/texture/qtexturedataupdate.cpp
index f196a6b7b..e3d5220f0 100644
--- a/src/render/texture/qtexturedataupdate.cpp
+++ b/src/render/texture/qtexturedataupdate.cpp
@@ -68,6 +68,7 @@ static bool operator==(const QTextureDataUpdatePrivate &lhs, const QTextureDataU
as well as the eventual layer, mipLevel and face.
\sa QAbstractTexture
+ \since 5.14
*/
QTextureDataUpdate::QTextureDataUpdate()
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index c7a739724..53216d27d 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -61,6 +61,7 @@ Texture::Texture()
// We need backend -> frontend notifications to update the status of the texture
: BackendNode(ReadWrite)
, m_dirty(DirtyImageGenerators|DirtyProperties|DirtyParameters|DirtyDataGenerator)
+ , m_sharedTextureId(-1)
{
}
@@ -130,67 +131,6 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
DirtyFlags dirty;
switch (e->type()) {
- case PropertyUpdated: {
- QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("width")) {
- m_properties.width = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("height")) {
- m_properties.height = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("depth")) {
- m_properties.depth = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("format")) {
- m_properties.format = static_cast<QAbstractTexture::TextureFormat>(propertyChange->value().toInt());
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("target")) {
- m_properties.target = static_cast<QAbstractTexture::Target>(propertyChange->value().toInt());
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("mipmaps")) {
- m_properties.generateMipMaps = propertyChange->value().toBool();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("minificationFilter")) {
- m_parameters.minificationFilter = static_cast<QAbstractTexture::Filter>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("magnificationFilter")) {
- m_parameters.magnificationFilter = static_cast<QAbstractTexture::Filter>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeX")) {
- m_parameters.wrapModeX = static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeY")) {
- m_parameters.wrapModeY = static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("wrapModeZ")) {
- m_parameters.wrapModeZ =static_cast<QTextureWrapMode::WrapMode>(propertyChange->value().toInt());
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("maximumAnisotropy")) {
- m_parameters.maximumAnisotropy = propertyChange->value().toFloat();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("comparisonFunction")) {
- m_parameters.comparisonFunction = propertyChange->value().value<QAbstractTexture::ComparisonFunction>();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("comparisonMode")) {
- m_parameters.comparisonMode = propertyChange->value().value<QAbstractTexture::ComparisonMode>();
- dirty = DirtyParameters;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("layers")) {
- m_properties.layers = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("samples")) {
- m_properties.samples = propertyChange->value().toInt();
- dirty = DirtyProperties;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("generator")) {
- setDataGenerator(propertyChange->value().value<QTextureGeneratorPtr>());
- } else if (propertyChange->propertyName() == QByteArrayLiteral("textureId")) {
- m_sharedTextureId = propertyChange->value().toInt();
- dirty = DirtySharedTextureId;
- } else if (propertyChange->propertyName() == QByteArrayLiteral("updateData")) {
- Qt3DRender::QTextureDataUpdate updateData = propertyChange->value().value<Qt3DRender::QTextureDataUpdate>();
- addTextureDataUpdate(updateData);
- }
- break;
- }
case PropertyValueAdded: {
const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
@@ -217,6 +157,62 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Texture::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
+{
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ const QAbstractTexture *node = qobject_cast<const QAbstractTexture *>(frontEnd);
+ if (!node)
+ return;
+
+ TextureProperties p = m_properties;
+ p.width = node->width();
+ p.height = node->height();
+ p.depth = node->depth();
+ p.format = node->format();
+ p.target = node->target();
+ p.generateMipMaps = node->generateMipMaps();
+ p.layers = node->layers();
+ p.samples = node->samples();
+ if (p != m_properties) {
+ m_properties = p;
+ addDirtyFlag(DirtyProperties);
+ }
+
+ TextureParameters q = m_parameters;
+ q.magnificationFilter = node->magnificationFilter();
+ q.minificationFilter = node->minificationFilter();
+ q.wrapModeX = const_cast<QAbstractTexture *>(node)->wrapMode()->x();
+ q.wrapModeY = const_cast<QAbstractTexture *>(node)->wrapMode()->y();
+ q.wrapModeZ = const_cast<QAbstractTexture *>(node)->wrapMode()->z();
+ q.maximumAnisotropy = node->maximumAnisotropy();
+ q.comparisonFunction = node->comparisonFunction();
+ q.comparisonMode = node->comparisonMode();
+ if (q != m_parameters) {
+ m_parameters = q;
+ addDirtyFlag(DirtyParameters);
+ }
+
+ auto newGenerator = node->dataGenerator();
+ if (newGenerator != m_dataFunctor) {
+ setDataGenerator(newGenerator);
+ }
+
+ QAbstractTexturePrivate *dnode = dynamic_cast<QAbstractTexturePrivate *>(QAbstractTexturePrivate::get(const_cast<QAbstractTexture *>(node)));
+ if (dnode) {
+ for (const QTextureDataUpdate &pendingUpdate : dnode->m_pendingDataUpdates)
+ addTextureDataUpdate(pendingUpdate);
+ dnode->m_pendingDataUpdates.clear();
+
+ for (const auto imgNode : dnode->m_textureImages)
+ addTextureImage(imgNode->id());
+ }
+
+ if (dnode->m_sharedTextureId != m_sharedTextureId) {
+ m_sharedTextureId = dnode->m_sharedTextureId;
+ addDirtyFlag(DirtySharedTextureId);
+ }
+}
+
// Called by sceneChangeEvent or TextureDownloadRequest (both in AspectThread context)
void Texture::setDataGenerator(const QTextureGeneratorPtr &generator)
{
@@ -308,7 +304,7 @@ void Texture::updatePropertiesAndNotify(const TextureUpdateInfo &updateInfo)
bool Texture::isValid(TextureImageManager *manager) const
{
- for (const QNodeId id : m_textureImageIds) {
+ for (const QNodeId &id : m_textureImageIds) {
TextureImage *img = manager->lookupResource(id);
if (img == nullptr)
return false;
@@ -340,7 +336,7 @@ void Texture::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chan
m_dataFunctor = data.dataFunctor;
m_sharedTextureId = data.sharedTextureId;
- for (const QNodeId imgId : data.textureImageIds)
+ for (const QNodeId &imgId : data.textureImageIds)
addTextureImage(imgId);
const QVector<QTextureDataUpdate> initialDataUpdates = data.initialDataUpdates;
diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h
index 28580c92a..967b2a44a 100644
--- a/src/render/texture/texture_p.h
+++ b/src/render/texture/texture_p.h
@@ -164,6 +164,7 @@ public:
QVector<QTextureDataUpdate> takePendingTextureDataUpdates() { return std::move(m_pendingTextureDataUpdates); }
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
inline const TextureProperties& properties() const { return m_properties; }
inline const TextureParameters& parameters() const { return m_parameters; }