diff options
author | Mike Krus <mike.krus@kdab.com> | 2021-06-15 11:32:15 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-06-21 12:27:37 +0000 |
commit | 112554ecb0c9bfe817b95312970844e13c5a21b8 (patch) | |
tree | ef7025f982697ebbb59e50b8beb1c1c59b0e7033 /src/render | |
parent | ed86b51c5b190934d757f334a8ae07693af4cd4f (diff) |
Change bounding update propagation
Previously, bounding computation results from the core aspect were
propagated to the render aspect via the front end objects.
This introduces a job watcher which gets called with the results
and the render aspect can update it's backend data directly.
The watcher process method is called in the thread of the core
aspect job but the render aspect job will wait for that complete
anyway (since it depends on the core aspect job).
Change-Id: Ie59337f00025fd55fc723a7d105342e0b1e91d6c
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
(cherry picked from commit e378ebd0db6c06af7709498122912284852e6bc9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/frontend/qrenderaspect.cpp | 15 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect_p.h | 1 | ||||
-rw-r--r-- | src/render/jobs/calcboundingvolumejob.cpp | 52 | ||||
-rw-r--r-- | src/render/jobs/calcboundingvolumejob_p.h | 6 |
4 files changed, 46 insertions, 28 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index dab3b8c8f..13587fda6 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -183,6 +183,7 @@ #include <Qt3DCore/private/qentity_p.h> #include <Qt3DCore/private/qaspectmanager_p.h> #include <Qt3DCore/private/qeventfilterservice_p.h> +#include <Qt3DCore/private/calcboundingvolumejob_p.h> #include <QThread> #include <QOpenGLContext> @@ -402,6 +403,20 @@ void QRenderAspectPrivate::onEngineStartup() auto *coreAspect = qobject_cast<Qt3DCore::QCoreAspect *>(m_aspectManager->aspect(&Qt3DCore::QCoreAspect::staticMetaObject)); Q_ASSERT(coreAspect); m_calculateBoundingVolumeJob->addDependency(coreAspect->calculateBoundingVolumeJob()); + + auto bvJob = qSharedPointerCast<Qt3DCore::CalculateBoundingVolumeJob>(coreAspect->calculateBoundingVolumeJob()); + bvJob->addWatcher(m_calculateBoundingVolumeJob); + } +} + +void QRenderAspectPrivate::onEngineAboutToShutdown() +{ + if (m_aspectManager) { + auto *coreAspect = qobject_cast<Qt3DCore::QCoreAspect *>(m_aspectManager->aspect(&Qt3DCore::QCoreAspect::staticMetaObject)); + Q_ASSERT(coreAspect); + + auto bvJob = qSharedPointerCast<Qt3DCore::CalculateBoundingVolumeJob>(coreAspect->calculateBoundingVolumeJob()); + bvJob->removeWatcher(m_calculateBoundingVolumeJob); } } diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index b1b7bedc3..23a90e78f 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -108,6 +108,7 @@ public: void createNodeManagers(); void onEngineStartup(); + void onEngineAboutToShutdown() override; void registerBackendTypes(); void unregisterBackendTypes(); diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp index 02cdce0ca..becfded8d 100644 --- a/src/render/jobs/calcboundingvolumejob.cpp +++ b/src/render/jobs/calcboundingvolumejob.cpp @@ -401,32 +401,6 @@ public: if (data.valid()) { // only valid if front end is a QGeometryRenderer without a view. All other cases handled by core aspect m_entities.push_back(data); - } else { - // TODO: this means data is copied at every frame, should track dirty - // implicit or explicit objects and only copy data for those. - // Ultimately would be best to avoid traversal altogether. - if (!data.renderer || data.renderer->primitiveType() == QGeometryRenderer::Patches - || !data.renderer->hasView()) // should have been handled above - return Continue; - - // renderer has a view, we can pull the data from the front end - QBoundingVolume *frontEndBV = qobject_cast<QBoundingVolume *>(m_frontEndNodeManager->lookupNode(data.renderer->peerId())); - if (!frontEndBV) - return Continue; - auto dFrontEndBV = QGeometryRendererPrivate::get(frontEndBV); - - // copy data to the entity - if (dFrontEndBV->m_explicitPointsValid) { - const auto diagonal = dFrontEndBV->m_maxPoint - dFrontEndBV->m_minPoint; - entity->localBoundingVolume()->setCenter(Vector3D(dFrontEndBV->m_minPoint + diagonal * .5f)); - entity->localBoundingVolume()->setRadius(diagonal.length() * .5f); - } else { - entity->localBoundingVolume()->setCenter(Vector3D(dFrontEndBV->m_implicitCenter)); - entity->localBoundingVolume()->setRadius(std::max(dFrontEndBV->m_implicitRadius, 0.0f)); - entity->unsetBoundingVolumeDirty(); - // copy the data to the geometry - data.geometry->updateExtent(dFrontEndBV->m_implicitMinPoint, dFrontEndBV->m_implicitMaxPoint); - } } return Continue; @@ -436,6 +410,7 @@ public: std::vector<BoundingVolumeComputeData> m_entities; }; + } // anonymous @@ -506,6 +481,31 @@ void CalculateBoundingVolumeJob::postFrame(QAspectEngine *aspectEngine) m_updatedGeometries.clear(); } +void CalculateBoundingVolumeJob::process(const Qt3DCore::BoundingVolumeComputeResult &result, bool computedResult) +{ + // This gets called from the thread of the CalculateBoundingVolumeJob in the core aspect. + // We receive the data calculated there and update our backend nodes + + auto entity = m_manager->renderNodesManager()->lookupResource(result.entity->id()); + if (!entity) + return; + + // copy data to the entity + entity->localBoundingVolume()->setCenter(Vector3D(result.m_center)); + entity->localBoundingVolume()->setRadius(std::max(result.m_radius, 0.0f)); + entity->unsetBoundingVolumeDirty(); + // copy the data to the geometry + if (computedResult) { + auto renderer = entity->renderComponent<GeometryRenderer>(); + if (renderer) { + auto geometry = m_manager->geometryManager()->lookupResource(renderer->geometryId()); + + if (geometry) + geometry->updateExtent(result.m_min, result.m_max); + } + } +} + void CalculateBoundingVolumeJob::setRoot(Entity *node) { m_node = node; diff --git a/src/render/jobs/calcboundingvolumejob_p.h b/src/render/jobs/calcboundingvolumejob_p.h index 4b2352107..c3c89151e 100644 --- a/src/render/jobs/calcboundingvolumejob_p.h +++ b/src/render/jobs/calcboundingvolumejob_p.h @@ -54,7 +54,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/qt3drender_global_p.h> - +#include <Qt3DCore/private/calcboundingvolumejob_p.h> #include <QSharedPointer> QT_BEGIN_NAMESPACE @@ -70,7 +70,7 @@ class NodeManagers; class Entity; class Geometry; -class Q_3DRENDERSHARED_PRIVATE_EXPORT CalculateBoundingVolumeJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT CalculateBoundingVolumeJob : public Qt3DCore::QAspectJob, public Qt3DCore::BoundingVolumeJobProcessor { public: explicit CalculateBoundingVolumeJob(); @@ -83,6 +83,8 @@ public: void postFrame(Qt3DCore::QAspectEngine *aspectEngine) override; private: + void process(const Qt3DCore::BoundingVolumeComputeResult &result, bool computedResult) override; + NodeManagers *m_manager; Entity *m_node; Qt3DCore::QAbstractFrontEndNodeManager *m_frontEndNodeManager; |