summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2017-09-18 18:23:59 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-11-14 21:36:29 +0000
commite20de2c1fd9d2c022e85c45885585ddc52bd0219 (patch)
tree5e2d72de155b17da859d6d274b2480cee994f726
parent252d2e5f2a237862cc50f926f66184d499298239 (diff)
Add layer entity filter caching
Also add all dirty flag enums found in dev. Change-Id: Ib364773002a3170aef66e7b365a0a41d8e60bd92 Reviewed-by: Svenn-Arne Dragly <svenn-arne.dragly@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/render/backend/abstractrenderer_p.h19
-rw-r--r--src/render/backend/layer.cpp11
-rw-r--r--src/render/backend/layer_p.h2
-rw-r--r--src/render/backend/render-backend.pri3
-rw-r--r--src/render/backend/renderer.cpp8
-rw-r--r--src/render/backend/renderer_p.h3
-rw-r--r--src/render/backend/renderercache_p.h83
-rw-r--r--src/render/backend/renderviewbuilder.cpp26
-rw-r--r--src/render/framegraph/layerfilternode.cpp3
-rw-r--r--tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp4
10 files changed, 149 insertions, 13 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index f8d9850e7..ce56c04b9 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -95,11 +95,20 @@ public:
// Changes made to backend nodes are reported to the Renderer
enum BackendNodeDirtyFlag {
- TransformDirty = 1 << 0,
- MaterialDirty = 1 << 1,
- GeometryDirty = 1 << 2,
- ComputeDirty = 1 << 3,
- AllDirty = 1 << 15
+ TransformDirty = 1 << 0,
+ MaterialDirty = 1 << 1,
+ GeometryDirty = 1 << 2,
+ ComputeDirty = 1 << 3,
+ ParameterDirty = 1 << 4,
+ FrameGraphDirty = 1 << 5,
+ EntityEnabledDirty = 1 << 6,
+ BuffersDirty = 1 << 7,
+ TexturesDirty = 1 << 8,
+ ShadersDirty = 1 << 9,
+ SkeletonDataDirty = 1 << 10,
+ JointDirty = 1 << 11,
+ LayersDirty = 1 << 12,
+ AllDirty = 0xffffff
};
Q_DECLARE_FLAGS(BackendNodeDirtySet, BackendNodeDirtyFlag)
diff --git a/src/render/backend/layer.cpp b/src/render/backend/layer.cpp
index 14c0317f8..77987505f 100644
--- a/src/render/backend/layer.cpp
+++ b/src/render/backend/layer.cpp
@@ -66,6 +66,17 @@ void Layer::cleanup()
QBackendNode::setEnabled(false);
}
+void Layer::sceneChangeEvent(const QSceneChangePtr &e)
+{
+ if (e->type() == PropertyUpdated) {
+ QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
+ QByteArray propertyName = propertyChange->propertyName();
+ if (propertyName == QByteArrayLiteral("enabled"))
+ markDirty(AbstractRenderer::LayersDirty);
+ }
+ BackendNode::sceneChangeEvent(e);
+}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/backend/layer_p.h b/src/render/backend/layer_p.h
index b6a78a1cf..d047f0b3c 100644
--- a/src/render/backend/layer_p.h
+++ b/src/render/backend/layer_p.h
@@ -71,6 +71,8 @@ public:
Layer();
~Layer();
void cleanup();
+protected:
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
};
} // namespace Render
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index 5d515a173..1ec3305b8 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -41,7 +41,8 @@ HEADERS += \
$$PWD/frameprofiler_p.h \
$$PWD/offscreensurfacehelper_p.h \
$$PWD/resourceaccessor_p.h \
- $$PWD/commandthread_p.h
+ $$PWD/commandthread_p.h \
+ $$PWD/renderercache_p.h
SOURCES += \
$$PWD/renderthread.cpp \
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 19cc97dc5..7726e5ab7 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -1437,6 +1437,14 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
FrameGraphVisitor visitor(m_nodesManager->frameGraphManager());
const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
+ // Remove leaf nodes that no longer exist from cache
+ const auto keys = m_cache.leafNodeCache.keys();
+ for (auto *leafNode : keys) {
+ if (!fgLeaves.contains(leafNode)) {
+ m_cache.leafNodeCache.remove(leafNode);
+ }
+ }
+
const int fgBranchCount = fgLeaves.size();
for (int i = 0; i < fgBranchCount; ++i) {
RenderViewBuilder builder(fgLeaves.at(i), i, this);
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index af10108e9..0c6d2fd09 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -75,6 +75,7 @@
#include <Qt3DRender/private/genericlambdajob_p.h>
#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h>
#include <Qt3DRender/private/filtercompatibletechniquejob_p.h>
+#include <Qt3DRender/private/renderercache_p.h>
#include <QHash>
#include <QMatrix4x4>
@@ -261,6 +262,8 @@ public:
QMutex* mutex() { return &m_renderQueueMutex; }
+ RendererCache m_cache;
+
#ifdef QT3D_RENDER_UNIT_TESTS
public:
diff --git a/src/render/backend/renderercache_p.h b/src/render/backend/renderercache_p.h
new file mode 100644
index 000000000..35525492d
--- /dev/null
+++ b/src/render/backend/renderercache_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** 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_RENDERERCACHE_P_H
+#define QT3DRENDER_RENDER_RENDERERCACHE_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/QFrameGraphNode>
+
+#include <Qt3DRender/private/entity_p.h>
+#include <Qt3DRender/private/renderviewjobutils_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+namespace Render {
+
+struct RendererCache
+{
+ using FilterEntityByLayerData = QVector<Entity *>;
+
+ struct LeafNodeData
+ {
+ FilterEntityByLayerData filterEntityByLayerData;
+ };
+
+ QHash<FrameGraphNode *, LeafNodeData> leafNodeCache;
+};
+
+} // namespace Render
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_RENDERERCACHE_P_H
diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp
index f47c6f419..b6e2f02fa 100644
--- a/src/render/backend/renderviewbuilder.cpp
+++ b/src/render/backend/renderviewbuilder.cpp
@@ -170,7 +170,9 @@ public:
const RenderableEntityFilterPtr &renderableEntityFilterJob,
const ComputableEntityFilterPtr &computableEntityFilterJob,
const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs)
+ const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
+ Renderer *renderer,
+ FrameGraphNode *leafNode)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterEntityByLayerJob(filterEntityByLayerJob)
@@ -179,6 +181,8 @@ public:
, m_computableEntityFilterJob(computableEntityFilterJob)
, m_materialGathererJobs(materialGathererJobs)
, m_renderViewBuilderJobs(renderViewBuilderJobs)
+ , m_renderer(renderer)
+ , m_leafNode(leafNode)
{}
void operator()()
@@ -202,14 +206,18 @@ public:
// Filter out entities that weren't selected by the layer filters
std::sort(renderableEntities.begin(), renderableEntities.end());
+ auto &filterEntityByLayerCache = m_renderer->m_cache.leafNodeCache[m_leafNode].filterEntityByLayerData;
+
// Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
- QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities();
- RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities);
+ if (m_renderer->dirtyBits() & AbstractRenderer::LayersDirty)
+ filterEntityByLayerCache = m_filterEntityByLayerJob->filteredEntities();
+
+ RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filterEntityByLayerCache);
// Set the light sources, with layer filters applied.
QVector<LightSource> lightSources = m_lightGathererJob->lights();
for (int i = 0; i < lightSources.count(); ++i) {
- if (!filteredEntities.contains(lightSources[i].entity))
+ if (!filterEntityByLayerCache.contains(lightSources[i].entity))
lightSources.removeAt(i--);
}
rv->setLightSources(lightSources);
@@ -247,6 +255,8 @@ private:
ComputableEntityFilterPtr m_computableEntityFilterJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ Renderer *m_renderer;
+ FrameGraphNode *m_leafNode;
};
class SetClearDrawBufferIndex
@@ -335,7 +345,9 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
m_renderableEntityFilterJob,
m_computableEntityFilterJob,
m_materialGathererJobs,
- m_renderViewBuilderJobs),
+ m_renderViewBuilderJobs,
+ m_renderer,
+ leafNode),
JobTypes::SyncRenderViewCommandBuilding);
m_syncRenderViewCommandBuildersJob = SynchronizerJobPtr::create(SyncRenderViewCommandBuilders(m_renderViewJob,
@@ -461,7 +473,9 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
jobs.push_back(m_syncRenderViewInitializationJob); // Step 2
jobs.push_back(m_syncFrustumCullingJob); // Step 3
- jobs.push_back(m_filterEntityByLayerJob); // Step 3
+ if (m_renderer->dirtyBits() & AbstractRenderer::LayersDirty)
+ jobs.push_back(m_filterEntityByLayerJob); // Step 3
+
jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) // Step3
diff --git a/src/render/framegraph/layerfilternode.cpp b/src/render/framegraph/layerfilternode.cpp
index 17693eb83..08d0f9956 100644
--- a/src/render/framegraph/layerfilternode.cpp
+++ b/src/render/framegraph/layerfilternode.cpp
@@ -71,6 +71,7 @@ void LayerFilterNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
if (change->propertyName() == QByteArrayLiteral("layer"))
m_layerIds.append(change->addedNodeId());
+ markDirty(AbstractRenderer::LayersDirty);
break;
}
@@ -78,13 +79,13 @@ void LayerFilterNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
if (change->propertyName() == QByteArrayLiteral("layer"))
m_layerIds.removeOne(change->removedNodeId());
+ markDirty(AbstractRenderer::LayersDirty);
break;
}
default:
break;
}
- markDirty(AbstractRenderer::AllDirty);
FrameGraphNode::sceneChangeEvent(e);
}
diff --git a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
index 1ab687b34..c2544de6e 100644
--- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
+++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
@@ -199,6 +199,10 @@ private Q_SLOTS:
QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 10 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+
+ // mark jobs dirty and recheck
+ testAspect.renderer()->markDirty(Qt3DRender::Render::AbstractRenderer::LayersDirty, nullptr);
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}