summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-04-03 18:32:10 +0100
committerMike Krus <mike.krus@kdab.com>2019-05-25 09:38:51 +0100
commit95df2e71cd943ea21eba2ee99b1d77b26a84e580 (patch)
tree373f662c003d42a1c140e8b043a1980c3401af12
parent09daf5451c03a96514d7d96cc12aaa279d99fa3e (diff)
Clean up bounding box updates
Use EntityAccumulator to collect all entities and use a single map/reduce call. This avoid allocations due to getting entity children and locking due to using one map/reduce per entity previously. Change-Id: Iac8eb315bfb302bc68dbdfc961bbc48beb8cd19a Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp78
1 files changed, 41 insertions, 37 deletions
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index 68eb308c5..113dc34ce 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -51,6 +51,7 @@
#include <Qt3DRender/private/buffer_p.h>
#include <Qt3DRender/private/sphere_p.h>
#include <Qt3DRender/private/buffervisitor_p.h>
+#include <Qt3DRender/private/entityaccumulator_p.h>
#include <QtCore/qmath.h>
#if QT_CONFIG(concurrent)
@@ -65,28 +66,6 @@ namespace Render {
namespace {
-QVector<Geometry*> calculateLocalBoundingVolume(NodeManagers *manager, Entity *node);
-
-struct UpdateBoundFunctor
-{
- NodeManagers *manager;
-
- // This define is required to work with QtConcurrent
- typedef QVector<Geometry *> result_type;
- QVector<Geometry *> operator ()(Qt3DRender::Render::Entity *node)
- {
- return calculateLocalBoundingVolume(manager, node);
- }
-};
-
-struct ReduceUpdateBoundFunctor
-{
- void operator ()(QVector<Geometry *> &result, const QVector<Geometry *> &values)
- {
- result += values;
- }
-};
-
class BoundingVolumeCalculator
{
public:
@@ -318,23 +297,29 @@ QVector<Geometry *> calculateLocalBoundingVolume(NodeManagers *manager, Entity *
}
}
-#if QT_CONFIG(concurrent)
- const QVector<Qt3DRender::Render::Entity *> children = node->children();
- if (children.size() > 1) {
- UpdateBoundFunctor functor;
- functor.manager = manager;
- ReduceUpdateBoundFunctor reduceFunctor;
- updatedGeometries += QtConcurrent::blockingMappedReduced<decltype(updatedGeometries)>(children, functor, reduceFunctor);
- } else
-#endif
- {
- const auto children = node->children();
- for (Entity *child : children)
- updatedGeometries += calculateLocalBoundingVolume(manager, child);
- }
return updatedGeometries;
}
+struct UpdateBoundFunctor
+{
+ NodeManagers *manager;
+
+ // This define is required to work with QtConcurrent
+ typedef QVector<Geometry *> result_type;
+ QVector<Geometry *> operator ()(Qt3DRender::Render::Entity *node)
+ {
+ return calculateLocalBoundingVolume(manager, node);
+ }
+};
+
+struct ReduceUpdateBoundFunctor
+{
+ void operator ()(QVector<Geometry *> &result, const QVector<Geometry *> &values)
+ {
+ result += values;
+ }
+};
+
} // anonymous
CalculateBoundingVolumeJob::CalculateBoundingVolumeJob()
@@ -346,7 +331,26 @@ CalculateBoundingVolumeJob::CalculateBoundingVolumeJob()
void CalculateBoundingVolumeJob::run()
{
- const QVector<Geometry *> updatedGeometries = calculateLocalBoundingVolume(m_manager, m_node);
+ EntityAccumulator accumulator([](Entity *entity) {
+ return !entity->componentUuid<GeometryRenderer>().isNull();
+ }, m_manager);
+ auto entities = accumulator.apply(m_node);
+
+ QVector<Geometry *> updatedGeometries;
+ updatedGeometries.reserve(entities.size());
+
+#if QT_CONFIG(concurrent)
+ if (entities.size() > 1) {
+ UpdateBoundFunctor functor;
+ functor.manager = m_manager;
+ ReduceUpdateBoundFunctor reduceFunctor;
+ updatedGeometries += QtConcurrent::blockingMappedReduced<decltype(updatedGeometries)>(entities, functor, reduceFunctor);
+ } else
+#endif
+ {
+ for (Entity *child : entities)
+ updatedGeometries += calculateLocalBoundingVolume(m_manager, child);
+ }
// Send extent updates to frontend
for (Geometry *geometry : updatedGeometries)