diff options
author | Svenn-Arne Dragly <svenn-arne.dragly@qt.io> | 2017-09-18 18:23:59 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-11-14 21:36:29 +0000 |
commit | e20de2c1fd9d2c022e85c45885585ddc52bd0219 (patch) | |
tree | 5e2d72de155b17da859d6d274b2480cee994f726 | |
parent | 252d2e5f2a237862cc50f926f66184d499298239 (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.h | 19 | ||||
-rw-r--r-- | src/render/backend/layer.cpp | 11 | ||||
-rw-r--r-- | src/render/backend/layer_p.h | 2 | ||||
-rw-r--r-- | src/render/backend/render-backend.pri | 3 | ||||
-rw-r--r-- | src/render/backend/renderer.cpp | 8 | ||||
-rw-r--r-- | src/render/backend/renderer_p.h | 3 | ||||
-rw-r--r-- | src/render/backend/renderercache_p.h | 83 | ||||
-rw-r--r-- | src/render/backend/renderviewbuilder.cpp | 26 | ||||
-rw-r--r-- | src/render/framegraph/layerfilternode.cpp | 3 | ||||
-rw-r--r-- | tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp | 4 |
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()); } |