summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2016-09-07 10:18:51 +0200
committerPaul Lemire <paul.lemire@kdab.com>2016-11-25 16:29:52 +0000
commit00cd8b93de47b97878422c3392412d2aa0dbbed5 (patch)
tree34ba954bbf967059da2a7b745d3a087a641eb669
parentd9615a73455069f77e1dcdee7cbc39413703f69f (diff)
Technique: add isCompatibleWithFilters function
Will allow to simplify technique filter filtering. Required to update the creation functor Change-Id: I7e6612e3c505ca57e5cc300335b3ba4fcc514638 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/frontend/qrenderaspect.cpp2
-rw-r--r--src/render/materialsystem/technique.cpp67
-rw-r--r--src/render/materialsystem/technique_p.h18
-rw-r--r--tests/auto/render/technique/tst_technique.cpp192
4 files changed, 278 insertions, 1 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index f1f67a034..c25de9654 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -208,7 +208,7 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QRenderPass>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer, m_nodeManagers->renderPassManager()));
q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer, m_nodeManagers->shaderManager()));
- q->registerBackendType<QTechnique>(QSharedPointer<Render::NodeFunctor<Render::Technique, Render::TechniqueManager> >::create(m_renderer, m_nodeManagers->techniqueManager()));
+ q->registerBackendType<QTechnique>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
// Framegraph
q->registerBackendType<QCameraSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
diff --git a/src/render/materialsystem/technique.cpp b/src/render/materialsystem/technique.cpp
index bf141ad28..6ab64c9d3 100644
--- a/src/render/materialsystem/technique.cpp
+++ b/src/render/materialsystem/technique.cpp
@@ -51,6 +51,8 @@
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
#include <QDebug>
@@ -64,6 +66,7 @@ namespace Render {
Technique::Technique()
: BackendNode()
, m_isCompatibleWithRenderer(false)
+ , m_nodeManager(nullptr)
{
}
@@ -177,6 +180,45 @@ void Technique::setCompatibleWithRenderer(bool compatible)
m_isCompatibleWithRenderer = compatible;
}
+bool Technique::isCompatibleWithFilters(const QNodeIdVector &filterKeyIds)
+{
+ // There is a technique filter so we need to check for a technique with suitable criteria.
+ // Check for early bail out if the technique doesn't have sufficient number of criteria and
+ // can therefore never satisfy the filter
+ if (m_filterKeyList.size() < filterKeyIds.size())
+ return false;
+
+ // Iterate through the filter criteria and for each one search for a criteria on the
+ // technique that satisfies it
+ for (const QNodeId filterKeyId : filterKeyIds) {
+ FilterKey *filterKey = m_nodeManager->filterKeyManager()->lookupResource(filterKeyId);
+
+ bool foundMatch = false;
+
+ for (const QNodeId techniqueFilterKeyId : qAsConst(m_filterKeyList)) {
+ FilterKey *techniqueFilterKey = m_nodeManager->filterKeyManager()->lookupResource(techniqueFilterKeyId);
+ if ((foundMatch = (*techniqueFilterKey == *filterKey)))
+ break;
+ }
+
+ // No match for TechniqueFilter criterion in any of the technique's criteria.
+ // So no way this can match. Don't bother checking the rest of the criteria.
+ if (!foundMatch)
+ return false;
+ }
+ return true;
+}
+
+void Technique::setNodeManager(NodeManagers *nodeManager)
+{
+ m_nodeManager = nodeManager;
+}
+
+NodeManagers *Technique::nodeManager() const
+{
+ return m_nodeManager;
+}
+
void Technique::appendFilterKey(Qt3DCore::QNodeId criterionId)
{
if (!m_filterKeyList.contains(criterionId))
@@ -188,6 +230,31 @@ void Technique::removeFilterKey(Qt3DCore::QNodeId criterionId)
m_filterKeyList.removeOne(criterionId);
}
+TechniqueFunctor::TechniqueFunctor(AbstractRenderer *renderer, NodeManagers *manager)
+ : m_manager(manager)
+ , m_renderer(renderer)
+{
+}
+
+QBackendNode *TechniqueFunctor::create(const QNodeCreatedChangeBasePtr &change) const
+{
+ Technique *technique = m_manager->techniqueManager()->getOrCreateResource(change->subjectId());
+ technique->setNodeManager(m_manager);
+ technique->setRenderer(m_renderer);
+ return technique;
+}
+
+QBackendNode *TechniqueFunctor::get(QNodeId id) const
+{
+ return m_manager->techniqueManager()->lookupResource(id);
+}
+
+void TechniqueFunctor::destroy(QNodeId id) const
+{
+ m_manager->techniqueManager()->releaseResource(id);
+
+}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/materialsystem/technique_p.h b/src/render/materialsystem/technique_p.h
index 61e27550a..85fa09c02 100644
--- a/src/render/materialsystem/technique_p.h
+++ b/src/render/materialsystem/technique_p.h
@@ -96,6 +96,11 @@ public:
bool isCompatibleWithRenderer() const;
void setCompatibleWithRenderer(bool compatible);
+ bool isCompatibleWithFilters(const Qt3DCore::QNodeIdVector &filterKeyIds);
+
+ void setNodeManager(NodeManagers *nodeManager);
+ NodeManagers *nodeManager() const;
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
@@ -104,6 +109,19 @@ private:
QVector<Qt3DCore::QNodeId> m_filterKeyList;
QVector<Qt3DCore::QNodeId> m_renderPasses;
bool m_isCompatibleWithRenderer;
+ NodeManagers *m_nodeManager;
+};
+
+class TechniqueFunctor : public Qt3DCore::QBackendNodeMapper
+{
+public:
+ explicit TechniqueFunctor(AbstractRenderer *renderer, NodeManagers *manager);
+ Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const Q_DECL_OVERRIDE;
+ Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const Q_DECL_OVERRIDE;
+ void destroy(Qt3DCore::QNodeId id) const Q_DECL_OVERRIDE;
+private:
+ NodeManagers *m_manager;
+ AbstractRenderer *m_renderer;
};
} // namespace Render
diff --git a/tests/auto/render/technique/tst_technique.cpp b/tests/auto/render/technique/tst_technique.cpp
index c5b8802ed..a2675fba7 100644
--- a/tests/auto/render/technique/tst_technique.cpp
+++ b/tests/auto/render/technique/tst_technique.cpp
@@ -35,6 +35,9 @@
#include <Qt3DRender/private/qtechnique_p.h>
#include <Qt3DRender/private/technique_p.h>
#include <Qt3DRender/private/shaderparameterpack_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/filterkey_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
@@ -66,6 +69,7 @@ private Q_SLOTS:
QCOMPARE(backendTechnique.filterKeys().size(), 0);
QCOMPARE(backendTechnique.renderPasses().size(), 0);
QCOMPARE(backendTechnique.isCompatibleWithRenderer(), false);
+ QVERIFY(backendTechnique.nodeManager() == nullptr);
}
void checkCleanupState()
@@ -263,6 +267,194 @@ private Q_SLOTS:
}
}
+ void checkIsCompatibleWithFilters()
+ {
+ // GIVEN
+ Qt3DRender::Render::Technique backendTechnique;
+ Qt3DRender::Render::NodeManagers nodeManagers;
+
+ backendTechnique.setNodeManager(&nodeManagers);
+
+ Qt3DRender::QFilterKey *filterKey1 = new Qt3DRender::QFilterKey();
+ Qt3DRender::QFilterKey *filterKey2 = new Qt3DRender::QFilterKey();
+ Qt3DRender::QFilterKey *filterKey3 = new Qt3DRender::QFilterKey();
+ Qt3DRender::QFilterKey *filterKey4 = new Qt3DRender::QFilterKey();
+ Qt3DRender::QFilterKey *filterKey5 = new Qt3DRender::QFilterKey();
+
+ filterKey1->setName(QStringLiteral("displacement"));
+ filterKey2->setName(QStringLiteral("diffRatio"));
+ filterKey3->setName(QStringLiteral("oil"));
+ filterKey4->setName(QStringLiteral("oil"));
+ filterKey5->setName(QStringLiteral("heads"));
+
+ filterKey1->setValue(QVariant(427.0f));
+ filterKey2->setValue(QVariant(4.11f));
+ filterKey3->setValue(QVariant(QStringLiteral("Valvoline-VR1")));
+ filterKey4->setValue(QVariant(QStringLiteral("Mobil-1")));
+ filterKey5->setName(QStringLiteral("AFR"));
+
+ // Create backend nodes
+ // WHEN
+ Qt3DRender::Render::FilterKey *backendFilterKey1 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey1->id());
+ Qt3DRender::Render::FilterKey *backendFilterKey2 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey2->id());
+ Qt3DRender::Render::FilterKey *backendFilterKey3 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey3->id());
+ Qt3DRender::Render::FilterKey *backendFilterKey4 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey4->id());
+ Qt3DRender::Render::FilterKey *backendFilterKey5 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey5->id());
+
+ simulateInitialization(filterKey1, backendFilterKey1);
+ simulateInitialization(filterKey2, backendFilterKey2);
+ simulateInitialization(filterKey3, backendFilterKey3);
+ simulateInitialization(filterKey4, backendFilterKey4);
+ simulateInitialization(filterKey5, backendFilterKey5);
+
+ // THEN
+ QCOMPARE(nodeManagers.filterKeyManager()->activeHandles().size(), 5);
+
+ {
+ // WHEN
+ backendTechnique.appendFilterKey(filterKey1->id());
+ backendTechnique.appendFilterKey(filterKey2->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 2);
+
+ // WHEN
+ Qt3DCore::QNodeIdVector techniqueFilters;
+ techniqueFilters.push_back(filterKey1->id());
+ techniqueFilters.push_back(filterKey2->id());
+ techniqueFilters.push_back(filterKey3->id());
+ techniqueFilters.push_back(filterKey5->id());
+
+ // THEN -> incompatible technique doesn't have enough filters
+ QCOMPARE(backendTechnique.isCompatibleWithFilters(techniqueFilters), false);
+
+ // WHEN
+ backendTechnique.removeFilterKey(filterKey1->id());
+ backendTechnique.removeFilterKey(filterKey2->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 0);
+ }
+
+ {
+ // WHEN
+ backendTechnique.appendFilterKey(filterKey1->id());
+ backendTechnique.appendFilterKey(filterKey2->id());
+ backendTechnique.appendFilterKey(filterKey3->id());
+ backendTechnique.appendFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 4);
+
+ // WHEN
+ Qt3DCore::QNodeIdVector techniqueFilters;
+ techniqueFilters.push_back(filterKey1->id());
+ techniqueFilters.push_back(filterKey2->id());
+ techniqueFilters.push_back(filterKey3->id());
+ techniqueFilters.push_back(filterKey5->id());
+
+ // THEN -> compatible same number
+ QCOMPARE(backendTechnique.isCompatibleWithFilters(techniqueFilters), true);
+
+ // WHEN
+ backendTechnique.removeFilterKey(filterKey1->id());
+ backendTechnique.removeFilterKey(filterKey2->id());
+ backendTechnique.removeFilterKey(filterKey3->id());
+ backendTechnique.removeFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 0);
+ }
+
+ {
+ // WHEN
+ backendTechnique.appendFilterKey(filterKey1->id());
+ backendTechnique.appendFilterKey(filterKey2->id());
+ backendTechnique.appendFilterKey(filterKey3->id());
+ backendTechnique.appendFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 4);
+
+ // WHEN
+ Qt3DCore::QNodeIdVector techniqueFilters;
+ techniqueFilters.push_back(filterKey1->id());
+ techniqueFilters.push_back(filterKey2->id());
+ techniqueFilters.push_back(filterKey4->id());
+ techniqueFilters.push_back(filterKey5->id());
+
+ // THEN -> compatible same number, one not matching
+ QCOMPARE(backendTechnique.isCompatibleWithFilters(techniqueFilters), false);
+
+ // WHEN
+ backendTechnique.removeFilterKey(filterKey1->id());
+ backendTechnique.removeFilterKey(filterKey2->id());
+ backendTechnique.removeFilterKey(filterKey3->id());
+ backendTechnique.removeFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 0);
+ }
+
+ {
+ // WHEN
+ backendTechnique.appendFilterKey(filterKey1->id());
+ backendTechnique.appendFilterKey(filterKey2->id());
+ backendTechnique.appendFilterKey(filterKey3->id());
+ backendTechnique.appendFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 4);
+
+ // WHEN
+ Qt3DCore::QNodeIdVector techniqueFilters;
+ techniqueFilters.push_back(filterKey1->id());
+ techniqueFilters.push_back(filterKey2->id());
+ techniqueFilters.push_back(filterKey3->id());
+
+ // THEN -> technique has more than necessary filters
+ QCOMPARE(backendTechnique.isCompatibleWithFilters(techniqueFilters), true);
+
+ // WHEN
+ backendTechnique.removeFilterKey(filterKey1->id());
+ backendTechnique.removeFilterKey(filterKey2->id());
+ backendTechnique.removeFilterKey(filterKey3->id());
+ backendTechnique.removeFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 0);
+ }
+
+ {
+ // WHEN
+ backendTechnique.appendFilterKey(filterKey1->id());
+ backendTechnique.appendFilterKey(filterKey2->id());
+ backendTechnique.appendFilterKey(filterKey3->id());
+ backendTechnique.appendFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 4);
+
+ // WHEN
+ Qt3DCore::QNodeIdVector techniqueFilters;
+ techniqueFilters.push_back(filterKey1->id());
+ techniqueFilters.push_back(filterKey2->id());
+ techniqueFilters.push_back(filterKey4->id());
+
+ // THEN -> technique has more than necessary filters
+ // but one is not matching
+ QCOMPARE(backendTechnique.isCompatibleWithFilters(techniqueFilters), false);
+
+ // WHEN
+ backendTechnique.removeFilterKey(filterKey1->id());
+ backendTechnique.removeFilterKey(filterKey2->id());
+ backendTechnique.removeFilterKey(filterKey3->id());
+ backendTechnique.removeFilterKey(filterKey5->id());
+
+ // THEN
+ QCOMPARE(backendTechnique.filterKeys().size(), 0);
+ }
+ }
};
QTEST_MAIN(tst_Technique)