summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-11-16 10:17:10 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-11-16 09:52:22 +0000
commitf2557d36835dcdcd669c68563c4892abd85fb053 (patch)
tree6572c32908e4aa1d37e72454b7a1ea81117bb8ce
parent728e5b1d80917c1ac1efaff62d0fbbf3b203550c (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.cpp37
-rw-r--r--src/render/backend/renderer_p.h4
-rw-r--r--src/render/backend/renderercache_p.h9
-rw-r--r--src/render/backend/renderviewbuilder.cpp228
-rw-r--r--src/render/backend/renderviewbuilder_p.h8
-rw-r--r--src/render/jobs/job_common_p.h3
-rw-r--r--tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp358
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();