diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2017-11-16 10:17:10 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-11-16 09:52:22 +0000 |
commit | f2557d36835dcdcd669c68563c4892abd85fb053 (patch) | |
tree | 6572c32908e4aa1d37e72454b7a1ea81117bb8ce | |
parent | 728e5b1d80917c1ac1efaff62d0fbbf3b203550c (diff) |
Fix rendering following LayersDirty
The LayersDirty flag on the renderer was being checked within a running
QAspectJob, which resulted in broken rendering (since the flag is cleared
before running the jobs).
Also in the case of Scene3D we could end up resetting the LayersDirty flag
even though we hadn't really rebuilt the caches. Overhaul this part to make it
more robust. The render views now always look into the caches and we schedule
job to rebuilt the caches instead of doing both at the same time.
Updated unit tests accordining and removed the access of the renderer's dirty
bits within jobs.
Change-Id: Id6b415ba86c91754a960aec3fd88af1ddc21ebe0
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | src/render/backend/renderer.cpp | 37 | ||||
-rw-r--r-- | src/render/backend/renderer_p.h | 4 | ||||
-rw-r--r-- | src/render/backend/renderercache_p.h | 9 | ||||
-rw-r--r-- | src/render/backend/renderviewbuilder.cpp | 228 | ||||
-rw-r--r-- | src/render/backend/renderviewbuilder_p.h | 8 | ||||
-rw-r--r-- | src/render/jobs/job_common_p.h | 3 | ||||
-rw-r--r-- | tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp | 358 |
7 files changed, 432 insertions, 215 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 8056e8bef..e6d9c9d4b 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1484,25 +1484,27 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot()); + BackendNodeDirtySet changesToUnset = dirtyBits(); + // Add jobs - if (dirtyBits() & AbstractRenderer::EntityEnabledDirty) { + if (changesToUnset & AbstractRenderer::EntityEnabledDirty) { renderBinJobs.push_back(m_updateTreeEnabledJob); m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob); } - if (dirtyBits() & AbstractRenderer::TransformDirty) { + if (changesToUnset & AbstractRenderer::TransformDirty) { renderBinJobs.push_back(m_worldTransformJob); renderBinJobs.push_back(m_updateWorldBoundingVolumeJob); renderBinJobs.push_back(m_updateShaderDataTransformJob); } - if (dirtyBits() & AbstractRenderer::GeometryDirty) { + if (changesToUnset & AbstractRenderer::GeometryDirty) { renderBinJobs.push_back(m_calculateBoundingVolumeJob); renderBinJobs.push_back(m_updateMeshTriangleListJob); } - if (dirtyBits() & AbstractRenderer::GeometryDirty || - dirtyBits() & AbstractRenderer::TransformDirty) { + if (changesToUnset & AbstractRenderer::GeometryDirty || + changesToUnset & AbstractRenderer::TransformDirty) { renderBinJobs.push_back(m_expandBoundingVolumeJob); } @@ -1518,17 +1520,20 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() // Jobs to prepare GL Resource upload renderBinJobs.push_back(m_vaoGathererJob); - if (dirtyBits() & AbstractRenderer::BuffersDirty) + if (changesToUnset & AbstractRenderer::BuffersDirty) renderBinJobs.push_back(m_bufferGathererJob); - if (dirtyBits() & AbstractRenderer::ShadersDirty) + if (changesToUnset & AbstractRenderer::ShadersDirty) renderBinJobs.push_back(m_shaderGathererJob); - if (dirtyBits() & AbstractRenderer::TexturesDirty) { + if (changesToUnset & AbstractRenderer::TexturesDirty) { renderBinJobs.push_back(m_syncTextureLoadingJob); renderBinJobs.push_back(m_textureGathererJob); } + const bool layersCacheNeedsToBeRebuilt = changesToUnset & AbstractRenderer::LayersDirty; + bool layersCacheRebuilt = false; + QMutexLocker lock(m_renderQueue->mutex()); if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case) // Traverse the current framegraph. For each leaf node create a @@ -1540,25 +1545,31 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() 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)) { + const QList<FrameGraphNode *> keys = m_cache.leafNodeCache.keys(); + for (FrameGraphNode *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); + builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt); + builder.prepareJobs(); renderBinJobs.append(builder.buildJobHierachy()); + } + layersCacheRebuilt = true; // Set target number of RenderViews m_renderQueue->setTargetRenderViewCount(fgBranchCount); } + // Only reset LayersDirty flag once we have really rebuilt the caches + if (layersCacheNeedsToBeRebuilt && !layersCacheRebuilt) + changesToUnset.setFlag(AbstractRenderer::LayersDirty, false); + // Clear dirty bits - BackendNodeDirtySet changesToUnset = dirtyBits(); // TO DO: When secondary GL thread is integrated, the following line can be removed changesToUnset.setFlag(AbstractRenderer::ShadersDirty, false); diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 161c3c7ef..28e8711a8 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -267,8 +267,7 @@ public: ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews); - RendererCache m_cache; - + RendererCache *cache() { return &m_cache; } #ifdef QT3D_RENDER_UNIT_TESTS public: @@ -372,6 +371,7 @@ private: #endif QMetaObject::Connection m_contextConnection; + RendererCache m_cache; }; } // namespace Render diff --git a/src/render/backend/renderercache_p.h b/src/render/backend/renderercache_p.h index 35525492d..f14b965ee 100644 --- a/src/render/backend/renderercache_p.h +++ b/src/render/backend/renderercache_p.h @@ -64,14 +64,17 @@ namespace Render { struct RendererCache { - using FilterEntityByLayerData = QVector<Entity *>; - struct LeafNodeData { - FilterEntityByLayerData filterEntityByLayerData; + QVector<Entity *> filterEntitiesByLayer; }; QHash<FrameGraphNode *, LeafNodeData> leafNodeCache; + + QMutex *mutex() { return &m_mutex; } + +private: + QMutex m_mutex; }; } // namespace Render diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp index 7d2d7ab03..769eee29f 100644 --- a/src/render/backend/renderviewbuilder.cpp +++ b/src/render/backend/renderviewbuilder.cpp @@ -139,7 +139,8 @@ public: RenderView *rv = m_renderViewJob->renderView(); // Layer filtering - m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters()); + if (!m_filterEntityByLayerJob.isNull()) + m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters()); // Proximity filtering m_filterProximityJob->setProximityFilterIds(rv->proximityFilterIds()); @@ -172,7 +173,6 @@ class SyncRenderCommandBuilding public: explicit SyncRenderCommandBuilding(const RenderViewInitializerJobPtr &renderViewJob, const FrustumCullingJobPtr &frustumCullingJob, - const FilterLayerEntityJobPtr &filterEntityByLayerJob, const FilterProximityDistanceJobPtr &filterProximityJob, const LightGathererPtr &lightGathererJob, const RenderableEntityFilterPtr &renderableEntityFilterJob, @@ -183,7 +183,6 @@ public: FrameGraphNode *leafNode) : m_renderViewJob(renderViewJob) , m_frustumCullingJob(frustumCullingJob) - , m_filterEntityByLayerJob(filterEntityByLayerJob) , m_filterProximityJob(filterProximityJob) , m_lightGathererJob(lightGathererJob) , m_renderableEntityFilterJob(renderableEntityFilterJob) @@ -215,18 +214,16 @@ 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; - + QMutexLocker lock(m_renderer->cache()->mutex()); + const QVector<Entity *> filteredEntities = m_renderer->cache()->leafNodeCache.value(m_leafNode).filterEntitiesByLayer; + lock.unlock(); // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector - if (m_renderer->dirtyBits() & AbstractRenderer::LayersDirty) - filterEntityByLayerCache = m_filterEntityByLayerJob->filteredEntities(); - - RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filterEntityByLayerCache); + RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities); // Set the light sources, with layer filters applied. QVector<LightSource> lightSources = m_lightGathererJob->lights(); for (int i = 0; i < lightSources.count(); ++i) { - if (!filterEntityByLayerCache.contains(lightSources[i].entity)) + if (!filteredEntities.contains(lightSources[i].entity)) lightSources.removeAt(i--); } rv->setLightSources(lightSources); @@ -262,7 +259,6 @@ public: private: RenderViewInitializerJobPtr m_renderViewJob; FrustumCullingJobPtr m_frustumCullingJob; - FilterLayerEntityJobPtr m_filterEntityByLayerJob; FilterProximityDistanceJobPtr m_filterProximityJob; LightGathererPtr m_lightGathererJob; RenderableEntityFilterPtr m_renderableEntityFilterJob; @@ -294,84 +290,51 @@ private: RenderViewInitializerJobPtr m_renderViewJob; }; +class SyncFilterEntityByLayer +{ +public: + explicit SyncFilterEntityByLayer(const FilterLayerEntityJobPtr &filterEntityByLayerJob, + Renderer *renderer, + FrameGraphNode *leafNode) + : m_filterEntityByLayerJob(filterEntityByLayerJob) + , m_renderer(renderer) + , m_leafNode(leafNode) + { + } + + void operator()() + { + QMutexLocker lock(m_renderer->cache()->mutex()); + // Save the filtered by layer subset into the cache + const QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities(); + RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; + dataCacheForLeaf.filterEntitiesByLayer = filteredEntities; + } + +private: + FilterLayerEntityJobPtr m_filterEntityByLayerJob; + Renderer *m_renderer; + FrameGraphNode *m_leafNode; +}; + } // anonymous RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer) - : m_renderViewIndex(renderViewIndex) + : m_leafNode(leafNode) + , m_renderViewIndex(renderViewIndex) , m_renderer(renderer) + , m_layerCacheNeedsToBeRebuilt(false) , m_renderViewJob(RenderViewInitializerJobPtr::create()) - , m_filterEntityByLayerJob(Render::FilterLayerEntityJobPtr::create()) + , m_filterEntityByLayerJob() , m_lightGathererJob(Render::LightGathererPtr::create()) , m_renderableEntityFilterJob(RenderableEntityFilterPtr::create()) , m_computableEntityFilterJob(ComputableEntityFilterPtr::create()) , m_frustumCullingJob(Render::FrustumCullingJobPtr::create()) , m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling)) , m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex)) + , m_syncFilterEntityByLayerJob() , m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create()) { - // Init what we can here - EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager(); - m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers()); - m_filterProximityJob->setManager(m_renderer->nodeManagers()); - m_renderableEntityFilterJob->setManager(entityManager); - m_computableEntityFilterJob->setManager(entityManager); - m_frustumCullingJob->setRoot(m_renderer->sceneRoot()); - m_lightGathererJob->setManager(entityManager); - m_renderViewJob->setRenderer(m_renderer); - m_renderViewJob->setFrameGraphLeafNode(leafNode); - m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex); - - // RenderCommand building is the most consuming task -> split it - // Estimate the number of jobs to create based on the number of entities - m_renderViewBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto renderViewCommandBuilder = Render::RenderViewBuilderJobPtr::create(); - renderViewCommandBuilder->setIndex(m_renderViewIndex); - renderViewCommandBuilder->setRenderer(m_renderer); - m_renderViewBuilderJobs.push_back(renderViewCommandBuilder); - } - - // Since Material gathering is an heavy task, we split it - const QVector<HMaterial> materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles(); - const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount; - const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount; - m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto materialGatherer = Render::MaterialParameterGathererJobPtr::create(); - materialGatherer->setNodeManagers(m_renderer->nodeManagers()); - materialGatherer->setRenderer(m_renderer); - if (i == RenderViewBuilder::m_optimalParallelJobCount - 1) - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements)); - else - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob)); - m_materialGathererJobs.push_back(materialGatherer); - } - - m_syncRenderViewInitializationJob = SynchronizerJobPtr::create(SyncRenderViewInitialization(m_renderViewJob, - m_frustumCullingJob, - m_filterEntityByLayerJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewBuilderJobs), - JobTypes::SyncRenderViewInitialization); - - m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob, - m_frustumCullingJob, - m_filterEntityByLayerJob, - m_filterProximityJob, - m_lightGathererJob, - m_renderableEntityFilterJob, - m_computableEntityFilterJob, - m_materialGathererJobs, - m_renderViewBuilderJobs, - m_renderer, - leafNode), - JobTypes::SyncRenderViewCommandBuilding); - - m_syncRenderViewCommandBuildersJob = SynchronizerJobPtr::create(SyncRenderViewCommandBuilders(m_renderViewJob, - m_renderViewBuilderJobs, - m_renderer), - JobTypes::SyncRenderViewCommandBuilder); } RenderViewInitializerJobPtr RenderViewBuilder::renderViewJob() const @@ -439,11 +402,91 @@ SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const return m_setClearDrawBufferIndexJob; } +SynchronizerJobPtr RenderViewBuilder::syncFilterEntityByLayerJob() const +{ + return m_syncFilterEntityByLayerJob; +} + FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const { return m_filterProximityJob; } +void RenderViewBuilder::prepareJobs() +{ + // Init what we can here + EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager(); + m_filterProximityJob->setManager(m_renderer->nodeManagers()); + m_renderableEntityFilterJob->setManager(entityManager); + m_computableEntityFilterJob->setManager(entityManager); + m_frustumCullingJob->setRoot(m_renderer->sceneRoot()); + m_lightGathererJob->setManager(entityManager); + m_renderViewJob->setRenderer(m_renderer); + m_renderViewJob->setFrameGraphLeafNode(m_leafNode); + m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex); + + // RenderCommand building is the most consuming task -> split it + // Estimate the number of jobs to create based on the number of entities + m_renderViewBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); + for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { + auto renderViewCommandBuilder = Render::RenderViewBuilderJobPtr::create(); + renderViewCommandBuilder->setIndex(m_renderViewIndex); + renderViewCommandBuilder->setRenderer(m_renderer); + m_renderViewBuilderJobs.push_back(renderViewCommandBuilder); + } + + // Since Material gathering is an heavy task, we split it + const QVector<HMaterial> materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles(); + const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount; + const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount; + m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); + for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { + auto materialGatherer = Render::MaterialParameterGathererJobPtr::create(); + materialGatherer->setNodeManagers(m_renderer->nodeManagers()); + materialGatherer->setRenderer(m_renderer); + if (i == RenderViewBuilder::m_optimalParallelJobCount - 1) + materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements)); + else + materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob)); + m_materialGathererJobs.push_back(materialGatherer); + } + + if (m_layerCacheNeedsToBeRebuilt) { + m_filterEntityByLayerJob = Render::FilterLayerEntityJobPtr::create(); + m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers()); + m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create(SyncFilterEntityByLayer(m_filterEntityByLayerJob, + m_renderer, + m_leafNode), + JobTypes::SyncFilterEntityByLayer); + } + + m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob, + m_frustumCullingJob, + m_filterProximityJob, + m_lightGathererJob, + m_renderableEntityFilterJob, + m_computableEntityFilterJob, + m_materialGathererJobs, + m_renderViewBuilderJobs, + m_renderer, + m_leafNode), + JobTypes::SyncRenderViewCommandBuilding); + + m_syncRenderViewCommandBuildersJob = SynchronizerJobPtr::create(SyncRenderViewCommandBuilders(m_renderViewJob, + m_renderViewBuilderJobs, + m_renderer), + JobTypes::SyncRenderViewCommandBuilder); + + m_syncRenderViewInitializationJob = SynchronizerJobPtr::create(SyncRenderViewInitialization(m_renderViewJob, + m_frustumCullingJob, + m_filterEntityByLayerJob, + m_filterProximityJob, + m_materialGathererJobs, + m_renderViewBuilderJobs), + JobTypes::SyncRenderViewInitialization); + +} + QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const { QVector<Qt3DCore::QAspectJobPtr> jobs; @@ -467,9 +510,6 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const m_syncRenderViewInitializationJob->addDependency(m_renderViewJob); - m_filterEntityByLayerJob->addDependency(m_syncRenderViewInitializationJob); - m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob()); - m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob()); m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob); @@ -481,7 +521,6 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const } m_syncRenderCommandBuildingJob->addDependency(m_renderableEntityFilterJob); m_syncRenderCommandBuildingJob->addDependency(m_computableEntityFilterJob); - m_syncRenderCommandBuildingJob->addDependency(m_filterEntityByLayerJob); m_syncRenderCommandBuildingJob->addDependency(m_filterProximityJob); m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob); m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob); @@ -504,23 +543,30 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const jobs.push_back(m_syncRenderViewInitializationJob); // Step 2 - jobs.push_back(m_syncFrustumCullingJob); // Step 3 - if (m_renderer->dirtyBits() & AbstractRenderer::LayersDirty) + if (m_layerCacheNeedsToBeRebuilt) { + m_filterEntityByLayerJob->addDependency(m_syncRenderViewInitializationJob); + m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob()); + + m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob); + m_syncRenderCommandBuildingJob->addDependency(m_syncFilterEntityByLayerJob); + jobs.push_back(m_filterEntityByLayerJob); // Step 3 + jobs.push_back(m_syncFilterEntityByLayerJob); // Step 4 + } + jobs.push_back(m_syncFrustumCullingJob); // Step 3 jobs.push_back(m_filterProximityJob); // Step 3 - jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3 for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) // Step3 jobs.push_back(materialGatherer); jobs.push_back(m_frustumCullingJob); // Step 4 - jobs.push_back(m_syncRenderCommandBuildingJob); // Step 4 + jobs.push_back(m_syncRenderCommandBuildingJob); // Step 5 - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 5 + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 6 jobs.push_back(renderViewCommandBuilder); - jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 6 + jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 7 return jobs; } @@ -535,6 +581,16 @@ int RenderViewBuilder::renderViewIndex() const return m_renderViewIndex; } +void RenderViewBuilder::setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt) +{ + m_layerCacheNeedsToBeRebuilt = needsToBeRebuilt; +} + +bool RenderViewBuilder::layerCacheNeedsToBeRebuilt() const +{ + return m_layerCacheNeedsToBeRebuilt; +} + int RenderViewBuilder::optimalJobCount() { return RenderViewBuilder::m_optimalParallelJobCount; diff --git a/src/render/backend/renderviewbuilder_p.h b/src/render/backend/renderviewbuilder_p.h index 0aa2e035a..a1fb4eb8b 100644 --- a/src/render/backend/renderviewbuilder_p.h +++ b/src/render/backend/renderviewbuilder_p.h @@ -94,19 +94,26 @@ public: SynchronizerJobPtr syncRenderCommandBuildingJob() const; SynchronizerJobPtr syncRenderViewCommandBuildersJob() const; SynchronizerJobPtr setClearDrawBufferIndexJob() const; + SynchronizerJobPtr syncFilterEntityByLayerJob() const; FilterProximityDistanceJobPtr filterProximityJob() const; + void prepareJobs(); QVector<Qt3DCore::QAspectJobPtr> buildJobHierachy() const; Renderer *renderer() const; int renderViewIndex() const; + void setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt); + bool layerCacheNeedsToBeRebuilt() const; + static int optimalJobCount(); static void removeEntitiesNotInSubset(QVector<Entity *> &entities, QVector<Entity *> subset); private: + Render::FrameGraphNode *m_leafNode; const int m_renderViewIndex; Renderer *m_renderer; + bool m_layerCacheNeedsToBeRebuilt; RenderViewInitializerJobPtr m_renderViewJob; FilterLayerEntityJobPtr m_filterEntityByLayerJob; @@ -122,6 +129,7 @@ private: SynchronizerJobPtr m_syncRenderCommandBuildingJob; SynchronizerJobPtr m_syncRenderViewCommandBuildersJob; SynchronizerJobPtr m_setClearDrawBufferIndexJob; + SynchronizerJobPtr m_syncFilterEntityByLayerJob; FilterProximityDistanceJobPtr m_filterProximityJob; static const int m_optimalParallelJobCount; diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h index aa9828193..56c4346ed 100644 --- a/src/render/jobs/job_common_p.h +++ b/src/render/jobs/job_common_p.h @@ -102,7 +102,8 @@ namespace JobTypes { SyncTextureLoading, LoadSkeleton, UpdateSkinningPalette, - ProximityFiltering + ProximityFiltering, + SyncFilterEntityByLayer }; } // JobTypes diff --git a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp index 7a29c3ebd..23861f3a9 100644 --- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp +++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp @@ -179,31 +179,60 @@ private Q_SLOTS: Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id()); QVERIFY(leafNode != nullptr); - // WHEN - Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + + // THEN + QCOMPARE(renderViewBuilder.renderViewIndex(), 0); + QCOMPARE(renderViewBuilder.renderer(), testAspect.renderer()); + QCOMPARE(renderViewBuilder.layerCacheNeedsToBeRebuilt(), false); + QVERIFY(!renderViewBuilder.renderViewJob().isNull()); + QVERIFY(!renderViewBuilder.lightGathererJob().isNull()); + QVERIFY(!renderViewBuilder.renderableEntityFilterJob().isNull()); + QVERIFY(!renderViewBuilder.computableEntityFilterJob().isNull()); + QVERIFY(!renderViewBuilder.frustumCullingJob().isNull()); + QVERIFY(!renderViewBuilder.syncFrustumCullingJob().isNull()); + QVERIFY(!renderViewBuilder.setClearDrawBufferIndexJob().isNull()); + + QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull()); + QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull()); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob().isNull()); + QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob().isNull()); + QVERIFY(renderViewBuilder.syncRenderViewInitializationJob().isNull()); + + QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), 0); + QCOMPARE(renderViewBuilder.materialGathererJobs().size(), 0); + + // WHEN + renderViewBuilder.prepareJobs(); + + // THEN + QVERIFY(!renderViewBuilder.syncRenderCommandBuildingJob().isNull()); + QVERIFY(!renderViewBuilder.syncRenderViewCommandBuildersJob().isNull()); + QVERIFY(!renderViewBuilder.syncRenderViewInitializationJob().isNull()); + QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull()); + QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull()); + + QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); + QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); + QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); + } - // THEN - QCOMPARE(renderViewBuilder.renderViewIndex(), 0); - QCOMPARE(renderViewBuilder.renderer(), testAspect.renderer()); - QVERIFY(!renderViewBuilder.renderViewJob().isNull()); - QVERIFY(!renderViewBuilder.filterEntityByLayerJob().isNull()); - QVERIFY(!renderViewBuilder.lightGathererJob().isNull()); - QVERIFY(!renderViewBuilder.renderableEntityFilterJob().isNull()); - QVERIFY(!renderViewBuilder.computableEntityFilterJob().isNull()); - QVERIFY(!renderViewBuilder.frustumCullingJob().isNull()); - QVERIFY(!renderViewBuilder.syncRenderViewInitializationJob().isNull()); - QVERIFY(!renderViewBuilder.syncFrustumCullingJob().isNull()); - QVERIFY(!renderViewBuilder.syncRenderCommandBuildingJob().isNull()); - QVERIFY(!renderViewBuilder.syncRenderViewCommandBuildersJob().isNull()); - QVERIFY(!renderViewBuilder.setClearDrawBufferIndexJob().isNull()); - QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); - QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); - - QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); - - // mark jobs dirty and recheck - testAspect.renderer()->markDirty(Qt3DRender::Render::AbstractRenderer::LayersDirty, nullptr); - QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 12 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true); + renderViewBuilder.prepareJobs(); + + // THEN + QCOMPARE(renderViewBuilder.layerCacheNeedsToBeRebuilt(), true); + QVERIFY(!renderViewBuilder.filterEntityByLayerJob().isNull()); + QVERIFY(!renderViewBuilder.syncFilterEntityByLayerJob().isNull()); + + // mark jobs dirty and recheck + QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 13 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); + } } void checkCheckJobDependencies() @@ -217,70 +246,145 @@ private Q_SLOTS: Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id()); QVERIFY(leafNode != nullptr); - // WHEN - Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); - renderViewBuilder.buildJobHierachy(); - - // THEN - // Step 1 - QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update - QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0); - QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0); - QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0); - - // Step 2 - QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1); - QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data()); - - // Step 3 - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->dependencies().size(), 2); - QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); - QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob())); - - QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2); - QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); - QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); - - QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1); - QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data()); - - QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3); - QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); - QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob())); - QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob())); - - for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { - QCOMPARE(materialGatherer->dependencies().size(), 2); - QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); - QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob())); - } - - // Step 4 - QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2); - QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob())); - QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); - - QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob())); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob())); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterEntityByLayerJob())); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob())); - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob())); - for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { - QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer)); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); + renderViewBuilder.buildJobHierachy(); + + // THEN + // Step 1 + QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update + QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0); + QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0); + QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0); + + // Step 2 + QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1); + QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data()); + + // Step 3 + QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull()); + QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull()); + + QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2); + QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); + + QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1); + QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data()); + + QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob())); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob())); + + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QCOMPARE(materialGatherer->dependencies().size(), 2); + QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob())); + } + + // Step 4 + QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2); + QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob())); + QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); + + QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob())); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer)); + } + + // Step 5 + for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { + QCOMPARE(renderViewBuilderJob->dependencies().size(), 1); + QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data()); + } + + // Step 6 + QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size()); + for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { + QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob)); + } } - - // Step 5 - for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { - QCOMPARE(renderViewBuilderJob->dependencies().size(), 1); - QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data()); - } - - // Step 6 - QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size()); - for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { - QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob)); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true); + renderViewBuilder.prepareJobs(); + renderViewBuilder.buildJobHierachy(); + + // THEN + // Step 1 + QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update + QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0); + QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0); + QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0); + + // Step 2 + QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1); + QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data()); + + // Step 3 + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->dependencies().size(), 2); + QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob())); + + QCOMPARE(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().size(), 1); + QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().contains(renderViewBuilder.filterEntityByLayerJob())); + + QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2); + QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); + + QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1); + QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data()); + + QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob())); + QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob())); + + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QCOMPARE(materialGatherer->dependencies().size(), 2); + QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob())); + } + + // Step 4 + QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2); + QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob())); + QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); + + QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncFilterEntityByLayerJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob())); + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob())); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer)); + } + + // Step 5 + for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { + QCOMPARE(renderViewBuilderJob->dependencies().size(), 1); + QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data()); + } + + // Step 6 + QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size()); + for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) { + QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob)); + } } } @@ -297,6 +401,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); renderViewBuilder.buildJobHierachy(); renderViewBuilder.renderViewJob()->run(); @@ -317,6 +422,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); renderViewBuilder.buildJobHierachy(); renderViewBuilder.renderableEntityFilterJob()->run(); @@ -337,6 +443,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); renderViewBuilder.buildJobHierachy(); renderViewBuilder.computableEntityFilterJob()->run(); @@ -362,30 +469,58 @@ private Q_SLOTS: Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(renderPassFilter->id()); QVERIFY(leafNode != nullptr); - // WHEN - Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); - renderViewBuilder.buildJobHierachy(); - - // THEN - QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 0); - for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { - QVERIFY(materialGatherer->techniqueFilter() == nullptr); - QVERIFY(materialGatherer->renderPassFilter() == nullptr); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); + renderViewBuilder.buildJobHierachy(); + + // THEN + QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(materialGatherer->techniqueFilter() == nullptr); + QVERIFY(materialGatherer->renderPassFilter() == nullptr); + } + + // WHEN + renderViewBuilder.renderViewJob()->run(); + renderViewBuilder.syncRenderViewInitializationJob()->run(); + + // THEN + QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(materialGatherer->techniqueFilter() != nullptr); + QVERIFY(materialGatherer->renderPassFilter() != nullptr); + } } - - // WHEN - renderViewBuilder.renderViewJob()->run(); - renderViewBuilder.syncRenderViewInitializationJob()->run(); - - // THEN - QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 1); - for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { - QVERIFY(materialGatherer->techniqueFilter() != nullptr); - QVERIFY(materialGatherer->renderPassFilter() != nullptr); + { + // WHEN + Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true); + renderViewBuilder.prepareJobs(); + renderViewBuilder.buildJobHierachy(); + + // THEN + QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 0); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(materialGatherer->techniqueFilter() == nullptr); + QVERIFY(materialGatherer->renderPassFilter() == nullptr); + } + + // WHEN + renderViewBuilder.renderViewJob()->run(); + renderViewBuilder.syncRenderViewInitializationJob()->run(); + + // THEN + QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 1); + for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { + QVERIFY(materialGatherer->techniqueFilter() != nullptr); + QVERIFY(materialGatherer->renderPassFilter() != nullptr); + } } } @@ -407,6 +542,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.prepareJobs(); renderViewBuilder.buildJobHierachy(); // THEN @@ -436,6 +572,8 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer()); + renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true); + renderViewBuilder.prepareJobs(); renderViewBuilder.buildJobHierachy(); renderViewBuilder.renderViewJob()->run(); |