summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-08-18 09:22:49 +0200
committerPaul Lemire <paul.lemire@kdab.com>2017-08-18 13:56:05 +0000
commit4b9ba03e0b8c5bb60410ea016d8436a57c02e6f8 (patch)
tree55024ff09acf981c4044125675b95e9460299085
parent10fcb22c79387b957fe3e6663b23f75d693531d6 (diff)
Fix and improve layer filtering
We now handle the case where multiple LayerFilter nodes are nested within the same FrameGraphBranch. We also have improved the Accept/Discard into Accept Any/All and Discard Any/All which should now handle all filtering cases. We now build a list of layerIds stored into Entity based on the recursive flags on the layers being set. This allows to make layer filtering simpler but the layerIds list building step will need to be improved as a follow up commit Unit tests updated Change-Id: I93451493e41c6c9486defa7e88eaee073a9bc932 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/entity.cpp11
-rw-r--r--src/render/backend/entity_p.h8
-rw-r--r--src/render/backend/renderview_p.h14
-rw-r--r--src/render/backend/renderviewbuilder.cpp4
-rw-r--r--src/render/framegraph/layerfilternode.cpp2
-rw-r--r--src/render/framegraph/qlayerfilter.cpp63
-rw-r--r--src/render/framegraph/qlayerfilter.h6
-rw-r--r--src/render/jobs/filterlayerentityjob.cpp262
-rw-r--r--src/render/jobs/filterlayerentityjob_p.h17
-rw-r--r--src/render/jobs/renderviewjobutils.cpp4
-rw-r--r--tests/auto/render/entity/tst_entity.cpp3
-rw-r--r--tests/auto/render/layerfiltering/tst_layerfiltering.cpp539
-rw-r--r--tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp4
-rw-r--r--tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp46
14 files changed, 688 insertions, 295 deletions
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index dc621512a..a0f052d06 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -411,6 +411,17 @@ void Entity::unsetBoundingVolumeDirty()
m_boundingDirty = false;
}
+void Entity::addRecursiveLayerId(const QNodeId layerId)
+{
+ if (!m_recursiveLayerComponents.contains(layerId) && !m_layerComponents.contains(layerId))
+ m_recursiveLayerComponents.push_back(layerId);
+}
+
+void Entity::removeRecursiveLayerId(const QNodeId layerId)
+{
+ m_recursiveLayerComponents.removeOne(layerId);
+}
+
// Handles
template<>
diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h
index 6f8a781e6..9516ee82b 100644
--- a/src/render/backend/entity_p.h
+++ b/src/render/backend/entity_p.h
@@ -120,6 +120,11 @@ public:
void setTreeEnabled(bool enabled) { m_treeEnabled = enabled; }
bool isTreeEnabled() const { return m_treeEnabled; }
+ Qt3DCore::QNodeIdVector layerIds() const { return m_layerComponents + m_recursiveLayerComponents; }
+ void addRecursiveLayerId(const Qt3DCore::QNodeId layerId);
+ void removeRecursiveLayerId(const Qt3DCore::QNodeId layerId);
+ void clearRecursiveLayerIds() { m_recursiveLayerComponents.clear(); }
+
template<class Backend, uint INDEXBITS>
Qt3DCore::QHandle<Backend, INDEXBITS> componentHandle() const
{
@@ -197,6 +202,9 @@ private:
Qt3DCore::QNodeId m_computeComponent;
Qt3DCore::QNodeId m_armatureComponent;
+ // Includes recursive layers
+ Qt3DCore::QNodeIdVector m_recursiveLayerComponents;
+
QString m_objectName;
bool m_boundingDirty;
// true only if this and all parent nodes are enabled
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index 1674db0a5..050dfb71e 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -150,12 +150,8 @@ public:
inline void setEyePosition(const QVector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; }
inline QVector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; }
- inline void setHasLayerFilter(bool filter) Q_DECL_NOTHROW { m_data.m_hasLayerFilter = filter; }
- inline bool hasLayerFilter() const Q_DECL_NOTHROW { return m_data.m_hasLayerFilter; }
- inline void appendLayerFilter(const Qt3DCore::QNodeIdVector &layerIds) Q_DECL_NOTHROW { m_data.m_layerIds << layerIds; }
- inline Qt3DCore::QNodeIdVector layerFilter() const Q_DECL_NOTHROW { return m_data.m_layerIds; }
- inline QLayerFilter::FilterMode layerFilterFilterMode() const Q_DECL_NOTHROW { return m_data.m_layerFilterFilterMode; }
- inline void setLayerFilterFilterMode(QLayerFilter::FilterMode filterMode) Q_DECL_NOTHROW { m_data.m_layerFilterFilterMode = filterMode; }
+ inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); }
+ inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; }
inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; }
inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; }
@@ -240,8 +236,6 @@ public:
, m_renderCameraNode(nullptr)
, m_techniqueFilter(nullptr)
, m_passFilter(nullptr)
- , m_hasLayerFilter(false)
- , m_layerFilterFilterMode(QLayerFilter::AcceptMatchingLayers)
{
}
CameraLens *m_renderCameraLens;
@@ -250,9 +244,7 @@ public:
const RenderPassFilter *m_passFilter;
QMatrix4x4 m_viewMatrix;
QMatrix4x4 m_viewProjectionMatrix;
- bool m_hasLayerFilter;
- QLayerFilter::FilterMode m_layerFilterFilterMode;
- Qt3DCore::QNodeIdVector m_layerIds;
+ Qt3DCore::QNodeIdVector m_layerFilterIds;
QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
QVector3D m_eyePos;
};
diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp
index e651ce180..9676fb32d 100644
--- a/src/render/backend/renderviewbuilder.cpp
+++ b/src/render/backend/renderviewbuilder.cpp
@@ -137,9 +137,7 @@ public:
RenderView *rv = m_renderViewJob->renderView();
// Layer filtering
- m_filterEntityByLayerJob->setHasLayerFilter(rv->hasLayerFilter());
- m_filterEntityByLayerJob->setLayers(rv->layerFilter());
- m_filterEntityByLayerJob->setFilterMode(rv->layerFilterFilterMode());
+ m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters());
// Material Parameter building
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
diff --git a/src/render/framegraph/layerfilternode.cpp b/src/render/framegraph/layerfilternode.cpp
index 6223543c6..b8fa5c075 100644
--- a/src/render/framegraph/layerfilternode.cpp
+++ b/src/render/framegraph/layerfilternode.cpp
@@ -53,7 +53,7 @@ namespace Render {
LayerFilterNode::LayerFilterNode()
: FrameGraphNode(FrameGraphNode::LayerFilter)
- , m_filterMode(QLayerFilter::AcceptMatchingLayers)
+ , m_filterMode(QLayerFilter::AcceptAnyMatchingLayers)
{
}
diff --git a/src/render/framegraph/qlayerfilter.cpp b/src/render/framegraph/qlayerfilter.cpp
index 4944fb6cc..04ebca572 100644
--- a/src/render/framegraph/qlayerfilter.cpp
+++ b/src/render/framegraph/qlayerfilter.cpp
@@ -51,7 +51,7 @@ namespace Qt3DRender {
QLayerFilterPrivate::QLayerFilterPrivate()
: QFrameGraphNodePrivate()
- , m_filterMode(QLayerFilter::AcceptMatchingLayers)
+ , m_filterMode(QLayerFilter::AcceptAnyMatchingLayers)
{
}
@@ -67,8 +67,17 @@ QLayerFilterPrivate::QLayerFilterPrivate()
the QLayerFilter and as components to Qt3DCore::QEntity.
QLayerFilter can be configured to select or discard entities with a
- specific QLayer depending on the filterMode property. By default, entities
- referencing a QLayer that is also added to the QLayerFilter are selected.
+ specific \l QLayer depending on the filterMode property. By default,
+ entities referencing one of the \l QLayer objects that are also being
+ referenced by the \l QLayerFilter are selected (AcceptAnyMatchingLayers).
+
+ Within the FrameGraph tree, multiple \l QLayerFilter nodes can be nested
+ within a branch going from root to a leaf. In that case the filtering will
+ first operate on all entities of the scene using the filtering method
+ specified by the first declared \l QLayerFilter. Then the filtered subset
+ of entities will be filtered again based on the filtering method set on the
+ second \l QLayerFilter declared. This is then repeated until all \l
+ QLayerFilter nodes of the branch have been consumed.
*/
/*!
@@ -76,11 +85,21 @@ QLayerFilterPrivate::QLayerFilterPrivate()
Specifies the rules for selecting entities to draw.
- \value AcceptMatchingLayers
- Accept entities that reference a QLayer added to this QLayerFilter
+ \value AcceptAnyMatchingLayers
+ Accept entities that reference one or more \l QLayer objects added to this
+ QLayerFilter. This is the default
- \value DiscardMatchingLayers
- Discard entities that reference a QLayer added to this QLayerFilter
+ \value AcceptAllMatchingLayers
+ Accept entities that reference all the \l QLayer objects added to this
+ QLayerFilter
+
+ \value DiscardAnyMatchingLayers
+ Discard entities that reference one or more \l QLayer objects added to this
+ QLayerFilter
+
+ \value DiscardAllMatchingLayers
+ Discard entities that reference all \l QLayer objects added to this
+ QLayerFilter
*/
/*!
@@ -106,8 +125,16 @@ QLayerFilterPrivate::QLayerFilterPrivate()
The LayerFilter can be configured to select or discard entities with a
specific \l Layer depending on the filterMode property. By default,
- entities referencing a \l Layer that is also added to the LayerFilter are
- selected.
+ entities referencing one of the \l Layer objects that are also being
+ referenced by the \l LayerFilter are selected (AcceptAnyMatchingLayers).
+
+ Within the FrameGraph tree, multiple \l LayerFilter nodes can be nested
+ within a branch going from root to a leaf. In that case the filtering will
+ first operate on all entities of the scene using the filtering method
+ specified by the first declared \l LayerFilter. Then the filtered subset of
+ entities will be filtered again based on the filtering method set on the
+ second \l LayerFilter declared. This is then repeated until all \l
+ LayerFilter nodes of the branch have been consumed.
*/
/*!
@@ -123,11 +150,21 @@ QLayerFilterPrivate::QLayerFilterPrivate()
The default value is \c {LayerFilter.AcceptMatchingLayers}.
- \value LayerFilter.AcceptMatchingLayers
- Accept entities that reference a \l Layer added to this LayerFilter
+ \value LayerFilter.AcceptAnyMatchingLayers
+ Accept entities that reference one or more \l Layer objects added to this
+ LayerFilter. This is the default
+
+ \value LayerFilter.AcceptAllMatchingLayers
+ Accept entities that reference all the \l Layer objects added to this
+ LayerFilter
+
+ \value LayerFilter.DiscardAnyMatchingLayers
+ Discard entities that reference one or more \l Layer objects added to this
+ LayerFilter
- \value LayerFilter.DiscardMatchingLayers
- Discard entities that reference a \l Layer added to this LayerFilter
+ \value LayerFilter.DiscardAllMatchingLayers
+ Discard entities that reference all \l Layer objects added to this
+ LayerFilter
*/
/*!
diff --git a/src/render/framegraph/qlayerfilter.h b/src/render/framegraph/qlayerfilter.h
index 243ae7165..68854c722 100644
--- a/src/render/framegraph/qlayerfilter.h
+++ b/src/render/framegraph/qlayerfilter.h
@@ -57,8 +57,10 @@ class QT3DRENDERSHARED_EXPORT QLayerFilter : public QFrameGraphNode
public:
enum FilterMode
{
- AcceptMatchingLayers = 0,
- DiscardMatchingLayers
+ AcceptAnyMatchingLayers = 0,
+ AcceptAllMatchingLayers,
+ DiscardAnyMatchingLayers,
+ DiscardAllMatchingLayers,
};
Q_ENUM(FilterMode) // LOVC_EXLC_LINE
diff --git a/src/render/jobs/filterlayerentityjob.cpp b/src/render/jobs/filterlayerentityjob.cpp
index 1193c4552..902338be7 100644
--- a/src/render/jobs/filterlayerentityjob.cpp
+++ b/src/render/jobs/filterlayerentityjob.cpp
@@ -42,6 +42,7 @@
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/job_common_p.h>
+#include <Qt3DRender/private/layerfilternode_p.h>
QT_BEGIN_NAMESPACE
@@ -51,144 +52,203 @@ namespace Render {
namespace {
int layerFilterJobCounter = 0;
+
+// TO DO: This will be moved to a dedicated job with smarter
+// heuristics in a later commit
+void addLayerIdToEntityChildren(const QVector<Entity *> &children,
+ const Qt3DCore::QNodeId layerId)
+{
+ for (Entity *child : children) {
+ child->addRecursiveLayerId(layerId);
+ addLayerIdToEntityChildren(child->children(), layerId);
+ }
+}
+
+void updateEntityLayers(NodeManagers *manager)
+{
+ EntityManager *entityManager = manager->renderNodesManager();
+
+ const QVector<HEntity> handles = entityManager->activeHandles();
+
+ // Clear list of recursive layerIds
+ for (const HEntity handle : handles) {
+ Entity *entity = entityManager->data(handle);
+ entity->clearRecursiveLayerIds();
+ }
+
+ LayerManager *layerManager = manager->layerManager();
+
+ // Set recursive layerIds on children
+ for (const HEntity handle : handles) {
+ Entity *entity = entityManager->data(handle);
+ const Qt3DCore::QNodeIdVector entityLayers = entity->componentsUuid<Layer>();
+
+ for (const Qt3DCore::QNodeId layerId : entityLayers) {
+ Layer *layer = layerManager->lookupResource(layerId);
+ if (layer->recursive()) {
+ // Find all children of the entity and add the layers to them
+ addLayerIdToEntityChildren(entity->children(), layerId);
+ }
+ }
+ }
+}
+
} // anonymous
FilterLayerEntityJob::FilterLayerEntityJob()
: Qt3DCore::QAspectJob()
, m_manager(nullptr)
- , m_hasLayerFilter(false)
- , m_filterMode(QLayerFilter::AcceptMatchingLayers)
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::LayerFiltering, layerFilterJobCounter++);
}
+
void FilterLayerEntityJob::run()
{
m_filteredEntities.clear();
- if (m_hasLayerFilter) { // LayerFilter set -> filter
- LayerManager *layerManager = m_manager->layerManager();
-
- // Remove layerIds which are not active/enabled
- for (auto i = m_layerIds.size() - 1; i >= 0; --i) {
- Layer *backendLayer = layerManager->lookupResource(m_layerIds.at(i));
- if (backendLayer == nullptr || !backendLayer->isEnabled())
- m_layerIds.removeAt(i);
- }
-
+ if (hasLayerFilter()) { // LayerFilter set -> filter
+ updateEntityLayers(m_manager);
filterLayerAndEntity();
} else { // No LayerFilter set -> retrieve all
selectAllEntities();
}
}
-void FilterLayerEntityJob::setFilterMode(QLayerFilter::FilterMode filterMode)
+// We accept the entity if it contains any of the layers that are in the layer filter
+void FilterLayerEntityJob::filterAcceptAnyMatchingLayers(Entity *entity,
+ const Qt3DCore::QNodeIdVector &layerIds)
{
- m_filterMode = filterMode;
+ const Qt3DCore::QNodeIdVector entityLayers = entity->layerIds();
+
+ for (const Qt3DCore::QNodeId id : entityLayers) {
+ const bool layerAccepted = layerIds.contains(id);
+
+ if (layerAccepted) {
+ m_filteredEntities.push_back(entity);
+ break;
+ }
+ }
+}
+
+// We accept the entity if it contains all the layers that are in the layer
+// filter
+void FilterLayerEntityJob::filterAcceptAllMatchingLayers(Entity *entity,
+ const Qt3DCore::QNodeIdVector &layerIds)
+{
+ const Qt3DCore::QNodeIdVector entityLayers = entity->layerIds();
+ int layersAccepted = 0;
+
+ for (const Qt3DCore::QNodeId id : entityLayers) {
+ if (layerIds.contains(id))
+ ++layersAccepted;
+ }
+
+ if (layersAccepted == layerIds.size())
+ m_filteredEntities.push_back(entity);
+}
+
+// We discard the entity if it contains any of the layers that are in the layer
+// filter
+// In other words that means we select an entity if one of its layers is not on
+// the layer filter
+void FilterLayerEntityJob::filterDiscardAnyMatchingLayers(Entity *entity,
+ const Qt3DCore::QNodeIdVector &layerIds)
+{
+ const Qt3DCore::QNodeIdVector entityLayers = entity->layerIds();
+ bool entityCanBeDiscarded = false;
+
+ for (const Qt3DCore::QNodeId id : entityLayers) {
+ if (layerIds.contains(id)) {
+ entityCanBeDiscarded = true;
+ break;
+ }
+ }
+
+ if (!entityCanBeDiscarded)
+ m_filteredEntities.push_back(entity);
+}
+
+// We discard the entity if it contains all of the layers that are in the layer
+// filter
+// In other words that means we select an entity if none of its layers are on
+// the layer filter
+void FilterLayerEntityJob::filterDiscardAllMatchingLayers(Entity *entity,
+ const Qt3DCore::QNodeIdVector &layerIds)
+{
+ const Qt3DCore::QNodeIdVector entityLayers = entity->layerIds();
+
+ int containedLayers = 0;
+
+ for (const Qt3DCore::QNodeId id : layerIds) {
+ if (entityLayers.contains(id))
+ ++containedLayers;
+ }
+
+ if (containedLayers != layerIds.size())
+ m_filteredEntities.push_back(entity);
}
-// Note: we assume that m_layerIds contains only enabled layers
-// -> meaning that if an Entity references such a layer, it's enabled
void FilterLayerEntityJob::filterLayerAndEntity()
{
EntityManager *entityManager = m_manager->renderNodesManager();
- LayerManager *layerManager = m_manager->layerManager();
const QVector<HEntity> handles = entityManager->activeHandles();
+ QVector<Entity *> entitiesToFilter;
+ entitiesToFilter.reserve(handles.size());
+
for (const HEntity handle : handles) {
Entity *entity = entityManager->data(handle);
- if (!entity->isTreeEnabled())
- continue;
+ if (entity->isTreeEnabled())
+ entitiesToFilter.push_back(entity);
+ }
- const Qt3DCore::QNodeIdVector entityLayers = entity->componentsUuid<Layer>();
+ FrameGraphManager *frameGraphManager = m_manager->frameGraphManager();
+ LayerManager *layerManager = m_manager->layerManager();
- // An Entity is positively filtered if it contains at least one Layer component with the same id as the
- // layers selected by the LayerFilter
-
- // If !discard, as soon as one entity layer is managed by the FilterLayer, accept the entity
- switch (m_filterMode) {
- case QLayerFilter::AcceptMatchingLayers: {
- // Be aware that the same entity may appear in the filteredEntities vector, is this a problem?
- for (const Qt3DCore::QNodeId id : entityLayers) {
- bool entityIsAlreadyAccepted = false;
- if (m_layerIds.contains(id)) {
- // When we found a layer in the entity that matches a layer in the LayerFilter
-
- // If the entity hasn't been already accepted, accept it
- if (!entityIsAlreadyAccepted) {
- m_filteredEntities.push_back(entity);
- entityIsAlreadyAccepted = true;
- }
-
- Layer *layer = layerManager->lookupResource(id);
-
- // If the found layer is recursive, accept children and break
- if (layer->recursive()) {
- QVector<Entity*> childEntities = entity->children();
- for (int i = 0; i < childEntities.size(); ++i) {
- Entity *childEntity = childEntities[i];
- if (childEntity->isTreeEnabled()) {
- m_filteredEntities.push_back(childEntity);
-
- // Add children of the child entity (so that is recursive in the tree)
- const QVector<Entity*> childChildEntities = childEntity->children();
- for (Entity *childChildEntity : childChildEntities)
- childEntities.push_back(childChildEntity);
- }
- }
- break;
- }
-
- // If the layer is not recursive, maybe another one in the same entity it is, so continue searching
- }
- }
- break;
+ for (const Qt3DCore::QNodeId layerFilterId : m_layerFilterIds) {
+ LayerFilterNode *layerFilter = static_cast<LayerFilterNode *>(frameGraphManager->lookupNode(layerFilterId));
+ Qt3DCore::QNodeIdVector layerIds = layerFilter->layerIds();
+
+ // Remove layerIds which are not active/enabled
+ for (int i = layerIds.size() - 1; i >= 0; --i) {
+ Layer *backendLayer = layerManager->lookupResource(layerIds.at(i));
+ if (backendLayer == nullptr || !backendLayer->isEnabled())
+ layerIds.removeAt(i);
}
- case QLayerFilter::DiscardMatchingLayers: {
- // If discard, the entity must not contain any of the layers managed by the FilterLayer
-
- // Bootstrap accepting the entity and the children
- bool acceptEntity = true;
- bool acceptRecursively = true;
- bool entityHasLayer = entityLayers.size() != 0;
-
- // Check if the entity must be dropped and if it must drop also its children
- for (const Qt3DCore::QNodeId id : entityLayers) {
- if (m_layerIds.contains(id)) {
- acceptEntity = false;
-
- Layer *layer = layerManager->lookupResource(id);
- if (layer->recursive()) {
- acceptRecursively = false;
- break;
- }
- }
- }
- if (entityHasLayer && acceptEntity)
- m_filteredEntities.push_back(entity);
-
- if (acceptRecursively) {
- QVector<Entity*> childEntities = entity->children();
- for (int i = 0; i < childEntities.size(); ++i) {
- Entity *childEntity = childEntities[i];
- if (childEntity->isTreeEnabled()) {
- m_filteredEntities.push_back(childEntity);
-
- // Add children of the child entity (so that is recursive in the tree)
- const QVector<Entity*> childChildEntities = childEntity->children();
- for (Entity *childChildEntity : childChildEntities)
- childEntities.push_back(childChildEntity);
- }
- }
+ const QLayerFilter::FilterMode filterMode = layerFilter->filterMode();
+
+ // Perform filtering
+ for (Entity *entity : entitiesToFilter) {
+ switch (filterMode) {
+ case QLayerFilter::AcceptAnyMatchingLayers: {
+ filterAcceptAnyMatchingLayers(entity, layerIds);
+ break;
+ }
+ case QLayerFilter::AcceptAllMatchingLayers: {
+ filterAcceptAllMatchingLayers(entity, layerIds);
+ break;
+ }
+ case QLayerFilter::DiscardAnyMatchingLayers: {
+ filterDiscardAnyMatchingLayers(entity, layerIds);
+ break;
+ }
+ case QLayerFilter::DiscardAllMatchingLayers: {
+ filterDiscardAllMatchingLayers(entity, layerIds);
+ break;
+ }
+ default:
+ Q_UNREACHABLE();
}
- break;
- }
- default:
- break;
}
+
+ // Entities to filter for the next frame are the filtered result of the
+ // current LayerFilter
+ entitiesToFilter = std::move(m_filteredEntities);
}
+ m_filteredEntities = std::move(entitiesToFilter);
}
// No layer filter -> retrieve all entities
diff --git a/src/render/jobs/filterlayerentityjob_p.h b/src/render/jobs/filterlayerentityjob_p.h
index 59be53a14..4e4619a25 100644
--- a/src/render/jobs/filterlayerentityjob_p.h
+++ b/src/render/jobs/filterlayerentityjob_p.h
@@ -71,28 +71,27 @@ public:
FilterLayerEntityJob();
inline void setManager(NodeManagers *manager) Q_DECL_NOEXCEPT { m_manager = manager; }
- inline void setLayers(const Qt3DCore::QNodeIdVector &layerIds) Q_DECL_NOEXCEPT { m_layerIds = layerIds; }
- inline void setHasLayerFilter(bool hasLayerFilter) Q_DECL_NOEXCEPT { m_hasLayerFilter = hasLayerFilter; }
+ inline void setLayerFilters(const Qt3DCore::QNodeIdVector &layerIds) Q_DECL_NOEXCEPT { m_layerFilterIds = layerIds; }
inline QVector<Entity *> filteredEntities() const Q_DECL_NOEXCEPT { return m_filteredEntities; }
- inline bool hasLayerFilter() const Q_DECL_NOTHROW { return m_hasLayerFilter; }
- inline Qt3DCore::QNodeIdVector layers() const { return m_layerIds; }
+ inline bool hasLayerFilter() const Q_DECL_NOTHROW { return !m_layerFilterIds.isEmpty(); }
+ inline Qt3DCore::QNodeIdVector layerFilters() const { return m_layerFilterIds; }
// QAspectJob interface
void run() Q_DECL_FINAL;
- void setFilterMode(QLayerFilter::FilterMode filterMode);
- bool filterMode() const {return m_filterMode;}
+ void filterAcceptAnyMatchingLayers(Entity *entity, const Qt3DCore::QNodeIdVector &layerIds);
+ void filterAcceptAllMatchingLayers(Entity *entity, const Qt3DCore::QNodeIdVector &layerIds);
+ void filterDiscardAnyMatchingLayers(Entity *entity, const Qt3DCore::QNodeIdVector &layerIds);
+ void filterDiscardAllMatchingLayers(Entity *entity, const Qt3DCore::QNodeIdVector &layerIds);
private:
void filterLayerAndEntity();
void selectAllEntities();
NodeManagers *m_manager;
- Qt3DCore::QNodeIdVector m_layerIds;
+ Qt3DCore::QNodeIdVector m_layerFilterIds;
QVector<Entity *> m_filteredEntities;
- bool m_hasLayerFilter;
- QLayerFilter::FilterMode m_filterMode;
};
typedef QSharedPointer<FilterLayerEntityJob> FilterLayerEntityJobPtr;
diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp
index b9959fe47..41b04190f 100644
--- a/src/render/jobs/renderviewjobutils.cpp
+++ b/src/render/jobs/renderviewjobutils.cpp
@@ -118,9 +118,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
break;
case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree
- rv->setHasLayerFilter(true);
- rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->layerIds());
- rv->setLayerFilterFilterMode(static_cast<const LayerFilterNode *>(node)->filterMode());
+ rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId());
break;
case FrameGraphNode::RenderPassFilter:
diff --git a/tests/auto/render/entity/tst_entity.cpp b/tests/auto/render/entity/tst_entity.cpp
index 96a9683d3..6ad958451 100644
--- a/tests/auto/render/entity/tst_entity.cpp
+++ b/tests/auto/render/entity/tst_entity.cpp
@@ -122,6 +122,7 @@ private slots:
QVERIFY(entity.componentUuid<Armature>().isNull());
QVERIFY(!entity.isBoundingVolumeDirty());
QVERIFY(entity.childrenHandles().isEmpty());
+ QVERIFY(entity.layerIds().isEmpty());
// WHEN
Q_FOREACH (QComponent *component, components) {
@@ -151,6 +152,7 @@ private slots:
QVERIFY(!entity.componentUuid<Armature>().isNull());
QVERIFY(entity.isBoundingVolumeDirty());
QVERIFY(!entity.childrenHandles().isEmpty());
+ QVERIFY(!entity.layerIds().isEmpty());
QVERIFY(renderer.dirtyBits() != 0);
bool containsAll = entity.containsComponentsOfType<Transform,
CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand, Armature>();
@@ -172,6 +174,7 @@ private slots:
QVERIFY(entity.componentUuid<Armature>().isNull());
QVERIFY(!entity.isBoundingVolumeDirty());
QVERIFY(entity.childrenHandles().isEmpty());
+ QVERIFY(entity.layerIds().isEmpty());
containsAll = entity.containsComponentsOfType<Transform,
CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand, Armature>();
QVERIFY(!containsAll);
diff --git a/tests/auto/render/layerfiltering/tst_layerfiltering.cpp b/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
index ed61fce87..c2651c477 100644
--- a/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
+++ b/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
@@ -51,18 +51,14 @@ private Q_SLOTS:
// THEN
QCOMPARE(filterJob.hasLayerFilter(), false);
QCOMPARE(filterJob.filteredEntities().size(), 0);
- QCOMPARE(filterJob.layers().size(), 0);
- QCOMPARE(filterJob.filterMode(), Qt3DRender::QLayerFilter::AcceptMatchingLayers);
+ QCOMPARE(filterJob.layerFilters().size(), 0);
QCOMPARE(frontendLayer.recursive(), false);
}
void filterEntities_data()
{
QTest::addColumn<Qt3DCore::QEntity *>("entitySubtree");
- QTest::addColumn<Qt3DCore::QNodeIdVector>("layerIds");
- QTest::addColumn<bool>("hasLayerFilter");
- QTest::addColumn<Qt3DRender::QLayerFilter::FilterMode>("filterMode");
- QTest::addColumn<bool>("recursive");
+ QTest::addColumn<Qt3DCore::QNodeIdVector>("layerFilterIds");
QTest::addColumn<Qt3DCore::QNodeIdVector>("expectedSelectedEntities");
@@ -77,16 +73,13 @@ private Q_SLOTS:
Q_UNUSED(childEntity3);
QTest::newRow("EntitiesNoLayerNoLayerFilterNoDiscardNoRecursive-ShouldSelectAll") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << false
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector()
- << rootEntity->id()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id()
- );
+ << Qt3DCore::QNodeIdVector()
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id()
+ );
}
{
@@ -95,21 +88,15 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+
Q_UNUSED(childEntity1);
Q_UNUSED(childEntity2);
Q_UNUSED(childEntity3);
- QTest::newRow("EntitiesNoLayerNoLayerFilterNoDiscardNoRecursive-ShouldSelectAll") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << false
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector()
- << rootEntity->id()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id()
- );
+ QTest::newRow("EntityNoLayerWithLayerFilterWithNoFilter-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << Qt3DCore::QNodeIdVector();
}
{
@@ -122,18 +109,16 @@ private Q_SLOTS:
Q_UNUSED(childEntity2);
Q_UNUSED(childEntity3);
- QTest::newRow("EntitiesNoLayerNoLayerFilterNoDiscardNoRecursive-ShouldSelectAll") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << false
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector()
- << rootEntity->id()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id()
- );
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+
+ QTest::newRow("AcceptAny-NoLayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << Qt3DCore::QNodeIdVector();
}
+
{
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
@@ -141,16 +126,17 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
- Q_UNUSED(childEntity1);
- Q_UNUSED(childEntity2);
- Q_UNUSED(childEntity3);
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ childEntity1->addComponent(layer);
+ childEntity2->addComponent(layer);
+ childEntity3->addComponent(layer);
- QTest::newRow("EntityNoLayerWithLayerFilterWithNoFilter-ShouldSelectNone") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << Qt3DCore::QNodeIdVector();
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectAllButRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity1->id() << childEntity2->id() << childEntity3->id());
}
{
@@ -159,19 +145,20 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
- Q_UNUSED(childEntity1);
- Q_UNUSED(childEntity2);
- Q_UNUSED(childEntity3);
+ Q_UNUSED(childEntity1)
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ childEntity2->addComponent(layer2);
+ childEntity3->addComponent(layer);
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer2);
- QTest::newRow("NoLayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << Qt3DCore::QNodeIdVector();
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectChild2And3") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
}
{
@@ -182,16 +169,17 @@ private Q_SLOTS:
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
childEntity1->addComponent(layer);
childEntity2->addComponent(layer);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectAllButRoot") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector() << childEntity1->id() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer2);
+
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << Qt3DCore::QNodeIdVector();
}
{
@@ -200,19 +188,41 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
- Q_UNUSED(childEntity1)
+ childEntity1->setEnabled(false);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
- Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
- childEntity2->addComponent(layer2);
+ childEntity1->addComponent(layer);
+ childEntity2->addComponent(layer);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectChild2And3") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id() << layer2->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-LayerWithEntityDisabled-ShouldSelectOnlyEntityEnabled") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-RecursiveLayerOnRoot-ShouldSelectAll") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id());
}
{
@@ -221,19 +231,104 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Q_UNUSED(childEntity1);
+ Q_UNUSED(childEntity2);
+ Q_UNUSED(childEntity3);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("DiscardAny-RecursiveLayerLayerFilterDiscardOnRoot-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("DiscardAny-LayerLayerFilterDiscardOnRoot-ShouldSelectAllButRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
- childEntity1->addComponent(layer);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+ childEntity3->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAny-LayerLayerFilterDiscardOnRoot-ShouldSelectRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
childEntity2->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
childEntity3->addComponent(layer);
+ childEntity3->addComponent(layer2);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer2->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << Qt3DCore::QNodeIdVector();
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersNonRecursive-ShouldSelectChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id());
}
{
@@ -242,19 +337,99 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
- childEntity1->setEnabled(false);
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersRecursive-ShouldSelectChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
- childEntity1->addComponent(layer);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
childEntity2->addComponent(layer);
- childEntity3->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
- QTest::newRow("LayerWithEntityDisabled-ShouldSelectOnlyEntityEnabled") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersRecursiveAndDirectReferenceToRecursiveLayer-ShouldSelectChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2Layers-ShouldSelectRootAndChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id());
}
{
@@ -265,18 +440,28 @@ private Q_SLOTS:
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
rootEntity->addComponent(layer);
- QTest::newRow("RecursiveLayerOnRoot-ShouldSelectAll") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::AcceptMatchingLayers
- << true
- << (Qt3DCore::QNodeIdVector()
- << rootEntity->id()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id());
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2LayersRecursive-ShouldSelectRootAndChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id());
}
{
@@ -285,20 +470,76 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
- Q_UNUSED(childEntity1);
- Q_UNUSED(childEntity2);
- Q_UNUSED(childEntity3);
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2LayersRecursiveAndDirectReference-ShouldSelectRootAndChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer4 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer5 = new Qt3DRender::QLayer(rootEntity);
+
rootEntity->addComponent(layer);
- QTest::newRow("RecursiveLayerLayerFilterDiscardOnRoot-ShouldSelectNone") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::DiscardMatchingLayers
- << true
- << (Qt3DCore::QNodeIdVector());
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer3);
+
+ childEntity2->addComponent(layer2);
+ childEntity2->addComponent(layer3);
+ childEntity2->addComponent(layer4);
+ childEntity2->addComponent(layer5);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+ childEntity3->addComponent(layer5);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter2 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter2->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter2->addLayer(layer4);
+ layerFilter2->addLayer(layer5);
+
+ QTest::newRow("NestedFiltering-SelectAllOfLayer123AndNoneOf45-ShouldChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id());
}
{
@@ -306,19 +547,73 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity4 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity5 = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer4 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer5 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer6 = new Qt3DRender::QLayer(rootEntity);
+
rootEntity->addComponent(layer);
- QTest::newRow("LayerLayerFilterDiscardOnRoot-ShouldSelectAllButRoot") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DRender::QLayerFilter::DiscardMatchingLayers
- << false
- << (Qt3DCore::QNodeIdVector()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id());
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer3);
+
+ childEntity2->addComponent(layer2);
+ childEntity2->addComponent(layer3);
+ childEntity2->addComponent(layer4);
+ childEntity2->addComponent(layer5);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer5);
+
+ childEntity4->addComponent(layer2);
+ childEntity4->addComponent(layer);
+ childEntity4->addComponent(layer3);
+ childEntity4->addComponent(layer6);
+
+ childEntity5->addComponent(layer3);
+ childEntity5->addComponent(layer4);
+ childEntity5->addComponent(layer6);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer5);
+ layerFilter->addLayer(layer4);
+
+ Qt3DRender::QLayerFilter *layerFilter2 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter2->setFilterMode(Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers);
+ layerFilter2->addLayer(layer2);
+ layerFilter2->addLayer(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter3 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter3->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter3->addLayer(layer);
+ layerFilter3->addLayer(layer6);
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity4->id()
+ );
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step2") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity4->id());
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step3") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id() << layerFilter3->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity4->id());
}
}
@@ -326,13 +621,9 @@ private Q_SLOTS:
{
//QSKIP("Skipping until TestAspect can be registered");
QFETCH(Qt3DCore::QEntity *, entitySubtree);
- QFETCH(Qt3DCore::QNodeIdVector, layerIds);
- QFETCH(bool, hasLayerFilter);
- QFETCH(Qt3DRender::QLayerFilter::FilterMode, filterMode);
- QFETCH(bool, recursive);
+ QFETCH(Qt3DCore::QNodeIdVector, layerFilterIds);
QFETCH(Qt3DCore::QNodeIdVector, expectedSelectedEntities);
- Q_UNUSED(recursive);
// GIVEN
QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(entitySubtree));
@@ -345,17 +636,15 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::FilterLayerEntityJob filterJob;
- filterJob.setHasLayerFilter(hasLayerFilter);
- filterJob.setLayers(layerIds);
- filterJob.setFilterMode(filterMode);
+ filterJob.setLayerFilters(layerFilterIds);
filterJob.setManager(aspect->nodeManagers());
filterJob.run();
// THEN
const QVector<Qt3DRender::Render::Entity *> filterEntities = filterJob.filteredEntities();
- QCOMPARE(expectedSelectedEntities.size(), filterEntities.size());
+ QCOMPARE(filterEntities.size(), expectedSelectedEntities.size());
for (auto i = 0, m = expectedSelectedEntities.size(); i < m; ++i)
- QCOMPARE(expectedSelectedEntities.at(i), filterEntities.at(i)->peerId());
+ QCOMPARE(filterEntities.at(i)->peerId(), expectedSelectedEntities.at(i));
}
};
diff --git a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
index 1f2f304df..18ad6357e 100644
--- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
+++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
@@ -361,7 +361,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false);
QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 0);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 0);
for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
QVERIFY(materialGatherer->techniqueFilter() == nullptr);
QVERIFY(materialGatherer->renderPassFilter() == nullptr);
@@ -374,7 +374,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true);
QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 1);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 1);
for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
QVERIFY(materialGatherer->techniqueFilter() != nullptr);
QVERIFY(materialGatherer->renderPassFilter() != nullptr);
diff --git a/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp b/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp
index cea52306f..d1ef468b2 100644
--- a/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp
+++ b/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp
@@ -38,6 +38,7 @@
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/filterlayerentityjob_p.h>
#include <Qt3DRender/qlayer.h>
+#include <Qt3DRender/qlayerfilter.h>
QT_BEGIN_NAMESPACE
@@ -85,19 +86,21 @@ namespace {
Qt3DCore::QEntity *buildTestScene(int layersCount,
int entityCount,
- QVector<Qt3DCore::QNodeId> &layerIds,
+ QVector<Qt3DCore::QNodeId> &layerFilterIds,
bool alwaysEnabled = true)
{
Qt3DCore::QEntity *root = new Qt3DCore::QEntity();
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(root);
+ layerFilterIds.push_back(layerFilter->id());
QVector<Qt3DRender::QLayer *> layers;
layers.reserve(layersCount);
- layerIds.reserve(layersCount);
+
for (int i = 0; i < layersCount; ++i) {
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(root);
layers.push_back(layer);
- layerIds.push_back(layer->id());
+ layerFilter->addLayer(layer);
}
for (int i = 0; i < entityCount; ++i) {
@@ -123,43 +126,38 @@ private Q_SLOTS:
void filterEntities_data()
{
QTest::addColumn<Qt3DCore::QEntity *>("entitySubtree");
- QTest::addColumn<Qt3DCore::QNodeIdVector>("layerIds");
- QTest::addColumn<bool>("hasLayerFilter");
+ QTest::addColumn<Qt3DCore::QNodeIdVector>("layerFilterIds");
{
- Qt3DCore::QNodeIdVector layerIds;
- Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerIds);
+ Qt3DCore::QNodeIdVector layerFilterIds;
+ Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerFilterIds);
QTest::newRow("Filter-NoLayerFilterAllEnabled") << rootEntity
- << layerIds
- << (layerIds.size() != 0);
+ << layerFilterIds;
}
{
- Qt3DCore::QNodeIdVector layerIds;
- Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerIds, false);
+ Qt3DCore::QNodeIdVector layerFilterIds;
+ Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerFilterIds, false);
QTest::newRow("Filter-NoLayerFilterSomeDisabled") << rootEntity
- << layerIds
- << (layerIds.size() != 0);
+ << layerFilterIds;
}
{
- Qt3DCore::QNodeIdVector layerIds;
- Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerIds);
+ Qt3DCore::QNodeIdVector layerFilterIds;
+ Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerFilterIds);
QTest::newRow("FilterLayerFilterAllEnabled") << rootEntity
- << layerIds
- << (layerIds.size() != 0);
+ << layerFilterIds;
}
{
- Qt3DCore::QNodeIdVector layerIds;
- Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerIds, false);
+ Qt3DCore::QNodeIdVector layerFilterIds;
+ Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerFilterIds, false);
QTest::newRow("FilterLayerFilterSomeDisabled") << rootEntity
- << layerIds
- << (layerIds.size() != 0);
+ << layerFilterIds;
}
}
@@ -167,16 +165,14 @@ private Q_SLOTS:
void filterEntities()
{
QFETCH(Qt3DCore::QEntity *, entitySubtree);
- QFETCH(Qt3DCore::QNodeIdVector, layerIds);
- QFETCH(bool, hasLayerFilter);
+ QFETCH(Qt3DCore::QNodeIdVector, layerFilterIds);
// GIVEN
QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(entitySubtree));
// WHEN
Qt3DRender::Render::FilterLayerEntityJob filterJob;
- filterJob.setHasLayerFilter(hasLayerFilter);
- filterJob.setLayers(layerIds);
+ filterJob.setLayerFilters(layerFilterIds);
filterJob.setManager(aspect->nodeManagers());
QBENCHMARK {