diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/backend/abstractrenderer_p.h | 3 | ||||
-rw-r--r-- | src/render/backend/entity.cpp | 74 | ||||
-rw-r--r-- | src/render/backend/entity_p.h | 6 | ||||
-rw-r--r-- | src/render/backend/managers.cpp | 6 | ||||
-rw-r--r-- | src/render/configure.json | 4 | ||||
-rw-r--r-- | src/render/framegraph/framegraphnode.cpp | 52 | ||||
-rw-r--r-- | src/render/framegraph/framegraphnode_p.h | 4 | ||||
-rw-r--r-- | src/render/framegraph/qframegraphnode.cpp | 16 | ||||
-rw-r--r-- | src/render/framegraph/qframegraphnode.h | 3 | ||||
-rw-r--r-- | src/render/jobs/job_common_p.h | 1 | ||||
-rw-r--r-- | src/render/jobs/jobs.pri | 2 | ||||
-rw-r--r-- | src/render/jobs/updateentityhierarchyjob.cpp | 80 | ||||
-rw-r--r-- | src/render/jobs/updateentityhierarchyjob_p.h | 91 | ||||
-rw-r--r-- | src/render/jobs/updateentitylayersjob_p.h | 2 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer.cpp | 23 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer_p.h | 2 |
16 files changed, 284 insertions, 85 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index f9c8e29eb..8aa994eb2 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -114,7 +114,8 @@ public: JointDirty = 1 << 11, LayersDirty = 1 << 12, TechniquesDirty = 1 << 13, - LightsDirty = 1 << 14, + EntityHierarchyDirty= 1 << 14, + LightsDirty = 1 << 15, AllDirty = 0xffffff }; Q_DECLARE_FLAGS(BackendNodeDirtySet, BackendNodeDirtyFlag) diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp index 8d03cd75f..d8d04aef1 100644 --- a/src/render/backend/entity.cpp +++ b/src/render/backend/entity.cpp @@ -65,8 +65,6 @@ #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/qtransform.h> #include <Qt3DCore/private/qentity_p.h> -#include <Qt3DCore/qpropertynoderemovedchange.h> -#include <Qt3DCore/qpropertynodeaddedchange.h> #include <Qt3DCore/qnodecreatedchange.h> #include <QMatrix4x4> @@ -95,14 +93,13 @@ Entity::~Entity() void Entity::cleanup() { if (m_nodeManagers != nullptr) { - Entity *parentEntity = parent(); - if (parentEntity != nullptr) - parentEntity->removeChildHandle(m_handle); m_nodeManagers->worldMatrixManager()->releaseResource(peerId()); - qCDebug(Render::RenderNodes) << Q_FUNC_INFO; - } + 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 @@ -132,12 +129,8 @@ void Entity::cleanup() void Entity::setParentHandle(HEntity parentHandle) { Q_ASSERT(m_nodeManagers); - // Remove ourselves from previous parent children list - Entity *parent = m_nodeManagers->renderNodesManager()->data(parentHandle); - if (parent != nullptr && parent->m_childrenHandles.contains(m_handle)) - parent->m_childrenHandles.removeAll(m_handle); m_parentHandle = parentHandle; - parent = m_nodeManagers->renderNodesManager()->data(parentHandle); + auto parent = m_nodeManagers->renderNodesManager()->data(parentHandle); if (parent != nullptr && !parent->m_childrenHandles.contains(m_handle)) parent->m_childrenHandles.append(m_handle); } @@ -159,8 +152,8 @@ void Entity::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) // 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). - const QNodeId parentEntityId = data.parentEntityId; - qCDebug(Render::RenderNodes) << "Creating Entity id =" << peerId() << "parentId =" << parentEntityId; + 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(); @@ -187,10 +180,7 @@ void Entity::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) for (const auto &idAndType : qAsConst(data.componentIdsAndTypes)) addComponent(idAndType); - if (!parentEntityId.isNull()) - setParentHandle(m_nodeManagers->renderNodesManager()->lookupHandle(parentEntityId)); - else - qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "No parent entity found for Entity" << peerId(); + markDirty(AbstractRenderer::EntityHierarchyDirty); } void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -214,30 +204,21 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) break; } - case PropertyValueAdded: { - QPropertyNodeAddedChangePtr change = qSharedPointerCast<QPropertyNodeAddedChange>(e); - if (change->metaObject()->inherits(&QEntity::staticMetaObject)) { - appendChildHandle(m_nodeManagers->renderNodesManager()->lookupHandle(change->addedNodeId())); - markDirty(AbstractRenderer::AllDirty); - } - break; - } - - case PropertyValueRemoved: { - QPropertyNodeRemovedChangePtr change = qSharedPointerCast<QPropertyNodeRemovedChange>(e); - if (change->metaObject()->inherits(&QEntity::staticMetaObject)) { - removeChildHandle(m_nodeManagers->renderNodesManager()->lookupHandle(change->removedNodeId())); - 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; @@ -265,6 +246,27 @@ 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() +{ + 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(); +} + void Entity::appendChildHandle(HEntity childHandle) { if (!m_childrenHandles.contains(childHandle)) { diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h index 149ac1143..c170fd42d 100644 --- a/src/render/backend/entity_p.h +++ b/src/render/backend/entity_p.h @@ -97,6 +97,10 @@ 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 appendChildHandle(HEntity childHandle); void removeChildHandle(HEntity childHandle) { m_childrenHandles.removeOne(childHandle); } @@ -181,6 +185,8 @@ private: HEntity m_parentHandle; QVector<HEntity > m_childrenHandles; + Qt3DCore::QNodeId m_parentEntityId; + HMatrix m_worldTransform; QSharedPointer<Sphere> m_localBoundingVolume; QSharedPointer<Sphere> m_worldBoundingVolume; diff --git a/src/render/backend/managers.cpp b/src/render/backend/managers.cpp index 3b1f8e910..26fd68600 100644 --- a/src/render/backend/managers.cpp +++ b/src/render/backend/managers.cpp @@ -72,7 +72,11 @@ FrameGraphNode* FrameGraphManager::lookupNode(Qt3DCore::QNodeId id) const void FrameGraphManager::releaseNode(Qt3DCore::QNodeId id) { - delete m_nodes.take(id); + auto node = m_nodes.take(id); + if (node) { + node->cleanup(); + delete node; + } } void SkeletonManager::addDirtySkeleton(DirtyFlag dirtyFlag, HSkeleton skeletonHandle) diff --git a/src/render/configure.json b/src/render/configure.json index ee5002707..02a6e3747 100644 --- a/src/render/configure.json +++ b/src/render/configure.json @@ -1,5 +1,9 @@ { "module": "3drender", + "depends": [ + "3dcore" + ], + "condition": "module.3dcore", "testDir": "./config.tests", "commandline": { diff --git a/src/render/framegraph/framegraphnode.cpp b/src/render/framegraph/framegraphnode.cpp index 562548e46..41a94f0e3 100644 --- a/src/render/framegraph/framegraphnode.cpp +++ b/src/render/framegraph/framegraphnode.cpp @@ -40,9 +40,8 @@ #include "framegraphnode_p.h" #include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DCore/qpropertynoderemovedchange.h> -#include <Qt3DCore/qpropertynodeaddedchange.h> #include <Qt3DRender/qframegraphnodecreatedchange.h> +#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -101,28 +100,6 @@ void FrameGraphNode::setParentId(Qt3DCore::QNodeId parentId) } } -void FrameGraphNode::appendChildId(Qt3DCore::QNodeId childId) -{ - if (!m_childrenIds.contains(childId)) { - FrameGraphNode *child = m_manager->lookupNode(childId); - if (child != nullptr) { - m_childrenIds.append(childId); - child->m_parentId = peerId(); - } - } -} - -void FrameGraphNode::removeChildId(Qt3DCore::QNodeId childId) -{ - if (m_childrenIds.contains(childId)) { - FrameGraphNode *child = m_manager->lookupNode(childId); - if (child != nullptr) { - child->m_parentId = Qt3DCore::QNodeId(); - } - m_childrenIds.removeAll(childId); - } -} - Qt3DCore::QNodeId FrameGraphNode::parentId() const { return m_parentId; @@ -155,28 +132,15 @@ void FrameGraphNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { switch (e->type()) { - case Qt3DCore::PropertyValueAdded: { - Qt3DCore::QPropertyNodeAddedChangePtr change = qSharedPointerCast<Qt3DCore::QPropertyNodeAddedChange>(e); - if (change->metaObject()->inherits(&QFrameGraphNode::staticMetaObject)) { - appendChildId(change->addedNodeId()); - markDirty(AbstractRenderer::FrameGraphDirty); - } - break; - } - - case Qt3DCore::PropertyValueRemoved: { - Qt3DCore::QPropertyNodeRemovedChangePtr change = qSharedPointerCast<Qt3DCore::QPropertyNodeRemovedChange>(e); - if (change->metaObject()->inherits(&QFrameGraphNode::staticMetaObject)) { - removeChildId(change->removedNodeId()); - markDirty(AbstractRenderer::FrameGraphDirty); - } - break; - } 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; } @@ -185,6 +149,12 @@ void FrameGraphNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } } +void FrameGraphNode::cleanup() +{ + setParentId({}); +} + + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h index 5bd9b1b12..420abce56 100644 --- a/src/render/framegraph/framegraphnode_p.h +++ b/src/render/framegraph/framegraphnode_p.h @@ -112,8 +112,6 @@ public: FrameGraphManager *manager() const; void setParentId(Qt3DCore::QNodeId parentId); - void appendChildId(Qt3DCore::QNodeId childHandle); - void removeChildId(Qt3DCore::QNodeId childHandle); Qt3DCore::QNodeId parentId() const; QVector<Qt3DCore::QNodeId> childrenIds() const; @@ -121,6 +119,8 @@ public: FrameGraphNode *parent() const; QVector<FrameGraphNode *> children() const; + void cleanup(); + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; protected: diff --git a/src/render/framegraph/qframegraphnode.cpp b/src/render/framegraph/qframegraphnode.cpp index 9acfd1209..d52b728a8 100644 --- a/src/render/framegraph/qframegraphnode.cpp +++ b/src/render/framegraph/qframegraphnode.cpp @@ -40,6 +40,7 @@ #include "qframegraphnode.h" #include "qframegraphnode_p.h" #include <Qt3DRender/qframegraphnodecreatedchange.h> +#include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/QNode> @@ -248,9 +249,24 @@ QFrameGraphNode::QFrameGraphNode(QFrameGraphNodePrivate &dd, QNode *parent) Qt3DCore::QNodeCreatedChangeBasePtr QFrameGraphNode::createNodeCreationChange() const { + // connect to the parentChanged signal here rather than constructor because + // until now there's no backend node to notify when parent changes + connect(this, &QNode::parentChanged, this, &QFrameGraphNode::onParentChanged); + return QFrameGraphNodeCreatedChangeBasePtr::create(this); } +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); +} + } // namespace Qt3DRender QT_END_NAMESPACE diff --git a/src/render/framegraph/qframegraphnode.h b/src/render/framegraph/qframegraphnode.h index 9b08c98d3..826f01a1e 100644 --- a/src/render/framegraph/qframegraphnode.h +++ b/src/render/framegraph/qframegraphnode.h @@ -63,6 +63,9 @@ protected: explicit QFrameGraphNode(QFrameGraphNodePrivate &dd, Qt3DCore::QNode *parent = nullptr); Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; +private Q_SLOTS: + void onParentChanged(QObject *); + private: Q_DECLARE_PRIVATE(QFrameGraphNode) }; diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h index 9c83624b8..5fe16f933 100644 --- a/src/render/jobs/job_common_p.h +++ b/src/render/jobs/job_common_p.h @@ -109,6 +109,7 @@ namespace JobTypes { UpdateLayerEntity, SendTextureChangesToFrontend, SendSetFenceHandlesToFrontend, + UpdateEntityHierarchy, }; } // JobTypes diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri index 2181e4a95..6cdf891fc 100644 --- a/src/render/jobs/jobs.pri +++ b/src/render/jobs/jobs.pri @@ -30,6 +30,7 @@ HEADERS += \ $$PWD/filterproximitydistancejob_p.h \ $$PWD/abstractpickingjob_p.h \ $$PWD/raycastingjob_p.h \ + $$PWD/updateentityhierarchyjob_p.h \ $$PWD/updateentitylayersjob_p.h SOURCES += \ @@ -59,5 +60,6 @@ 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 new file mode 100644 index 000000000..7c18514bb --- /dev/null +++ b/src/render/jobs/updateentityhierarchyjob.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** 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 new file mode 100644 index 000000000..fd2b13631 --- /dev/null +++ b/src/render/jobs/updateentityhierarchyjob_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** 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/jobs/updateentitylayersjob_p.h b/src/render/jobs/updateentitylayersjob_p.h index 13cc2fc4c..5d36042c4 100644 --- a/src/render/jobs/updateentitylayersjob_p.h +++ b/src/render/jobs/updateentitylayersjob_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). +** 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. diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 012ec7056..4e40906a6 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -200,6 +200,7 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) , m_syncLoadingJobs(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncLoadingJobs)) + , m_updateEntityHierarchyJob(Render::UpdateEntityHierarchyJobPtr::create()) , m_ownedContext(false) , m_offscreenHelper(nullptr) #if QT_CONFIG(qt3d_profile_jobs) @@ -212,6 +213,9 @@ 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); @@ -297,6 +301,7 @@ void Renderer::setNodeManagers(NodeManagers *managers) m_updateMeshTriangleListJob->setManagers(m_nodesManager); m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager()); m_updateEntityLayersJob->setManager(m_nodesManager); + m_updateEntityHierarchyJob->setManager(m_nodesManager); } void Renderer::setServices(QServiceLocator *services) @@ -1752,14 +1757,17 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() // Add jobs const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty; - if (entitiesEnabledDirty) { + const bool entityHierarchyNeedsToBeRebuilt = dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty; + if (entitiesEnabledDirty || entityHierarchyNeedsToBeRebuilt) { 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) { + if (dirtyBitsForFrame & AbstractRenderer::TransformDirty || + dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty) { renderBinJobs.push_back(m_worldTransformJob); renderBinJobs.push_back(m_updateWorldBoundingVolumeJob); renderBinJobs.push_back(m_updateShaderDataTransformJob); @@ -1772,6 +1780,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() } if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty || + dirtyBitsForFrame & AbstractRenderer::EntityHierarchyDirty || dirtyBitsForFrame & AbstractRenderer::TransformDirty) { renderBinJobs.push_back(m_expandBoundingVolumeJob); } @@ -1798,7 +1807,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; + const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty || entityHierarchyNeedsToBeRebuilt; const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty || frameGraphDirty; const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty; const bool lightsDirty = dirtyBitsForFrame & AbstractRenderer::LightsDirty; @@ -1806,6 +1815,10 @@ 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); @@ -1835,6 +1848,10 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt); + builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty); + builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); + builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); + builder.prepareJobs(); renderBinJobs.append(builder.buildJobHierachy()); } diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 9a2c99c30..e82d18f77 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -78,6 +78,7 @@ #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> @@ -367,6 +368,7 @@ private: UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob; FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob; UpdateEntityLayersJobPtr m_updateEntityLayersJob; + UpdateEntityHierarchyJobPtr m_updateEntityHierarchyJob; QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests; |