summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl
diff options
context:
space:
mode:
authorJames Turner <zakalawe@mac.com>2018-11-14 13:22:28 +0000
committerJames Turner <james.turner@kdab.com>2019-04-10 14:57:40 +0000
commit1fcdee0f313845f4e06b294cf520ab477191774b (patch)
tree0ac12fcf01f81f4d39a3ee26fdb3537228abce08 /src/render/renderers/opengl
parent88b521ffa8d3dd9210251f2ab84721db1e10ef35 (diff)
Cache light/renderable/computable vectors
This avoids running these jobs when lights / renderables have not changed in a frame Change-Id: I604180fe3442ab67648c4ba5d9effb8639c68ef7 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp7
-rw-r--r--src/render/renderers/opengl/renderer/renderercache_p.h5
-rw-r--r--src/render/renderers/opengl/renderer/renderviewbuilder.cpp206
-rw-r--r--src/render/renderers/opengl/renderer/renderviewbuilder_p.h16
4 files changed, 197 insertions, 37 deletions
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index a023b82f9..e9c582458 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -1735,6 +1735,9 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty || frameGraphDirty;
const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty;
const bool materialCacheNeedsToBeRebuilt = materialDirty || frameGraphDirty;
+ const bool lightsDirty = dirtyBitsForFrame & AbstractRenderer::LightsDirty;
+ const bool computeableDirty = dirtyBitsForFrame & AbstractRenderer::ComputeDirty;
+ const bool renderableDirty = dirtyBitsForFrame & AbstractRenderer::GeometryDirty;
// Rebuild Entity Hierarchy if dirty
if (entityHierarchyNeedsToBeRebuilt)
@@ -1766,6 +1769,10 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
RenderViewBuilder builder(fgLeaves.at(i), i, this);
builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt);
builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt);
+ builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty);
+ builder.setComputableCacheNeedsToBeRebuilt(computeableDirty);
+ builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty);
+
builder.prepareJobs();
renderBinJobs.append(builder.buildJobHierachy());
}
diff --git a/src/render/renderers/opengl/renderer/renderercache_p.h b/src/render/renderers/opengl/renderer/renderercache_p.h
index 2aa50d131..0e9c5d3cd 100644
--- a/src/render/renderers/opengl/renderer/renderercache_p.h
+++ b/src/render/renderers/opengl/renderer/renderercache_p.h
@@ -55,6 +55,7 @@
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/renderviewjobutils_p.h>
+#include <Qt3DRender/private/lightsource_p.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +69,10 @@ struct RendererCache
{
QVector<Entity *> filterEntitiesByLayer;
MaterialParameterGathererData materialParameterGatherer;
+ QVector<LightSource> gatheredLights;
+ QVector<Entity *> renderableEntities;
+ QVector<Entity *> computeEntities;
+ EnvironmentLight* environmentLight;
};
QHash<FrameGraphNode *, LeafNodeData> leafNodeCache;
diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
index d3d2d2dc4..83fab301a 100644
--- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
+++ b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp
@@ -177,9 +177,6 @@ public:
explicit SyncRenderCommandBuilding(const RenderViewInitializerJobPtr &renderViewJob,
const FrustumCullingJobPtr &frustumCullingJob,
const FilterProximityDistanceJobPtr &filterProximityJob,
- const LightGathererPtr &lightGathererJob,
- const RenderableEntityFilterPtr &renderableEntityFilterJob,
- const ComputableEntityFilterPtr &computableEntityFilterJob,
const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
Renderer *renderer,
@@ -187,9 +184,6 @@ public:
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterProximityJob(filterProximityJob)
- , m_lightGathererJob(lightGathererJob)
- , m_renderableEntityFilterJob(renderableEntityFilterJob)
- , m_computableEntityFilterJob(computableEntityFilterJob)
, m_materialGathererJobs(materialGathererJobs)
, m_renderViewBuilderJobs(renderViewBuilderJobs)
, m_renderer(renderer)
@@ -203,28 +197,27 @@ public:
RenderView *rv = m_renderViewJob->renderView();
if (!rv->noDraw()) {
- rv->setEnvironmentLight(m_lightGathererJob->takeEnvironmentLight());
-
- // We sort the vector so that the removal can then be performed linearly
-
QVector<Entity *> renderableEntities;
const bool isDraw = !rv->isCompute();
+ QMutexLocker lock(m_renderer->cache()->mutex());
+ const auto& cacheData = m_renderer->cache()->leafNodeCache.value(m_leafNode);
+
if (isDraw)
- renderableEntities = std::move(m_renderableEntityFilterJob->filteredEntities());
+ renderableEntities = cacheData.renderableEntities;
else
- renderableEntities = std::move(m_computableEntityFilterJob->filteredEntities());
+ renderableEntities = cacheData.computeEntities;
- // Filter out entities that weren't selected by the layer filters
- std::sort(renderableEntities.begin(), renderableEntities.end());
+ const QVector<Entity *> filteredEntities = cacheData.filterEntitiesByLayer;
+ QVector<LightSource> lightSources = cacheData.gatheredLights;
+ rv->setEnvironmentLight(cacheData.environmentLight);
- QMutexLocker lock(m_renderer->cache()->mutex());
- const QVector<Entity *> filteredEntities = m_renderer->cache()->leafNodeCache.value(m_leafNode).filterEntitiesByLayer;
lock.unlock();
+
+ // Filter out entities that weren't selected by the layer filters
// Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
renderableEntities = RenderViewBuilder::entitiesInSubset(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 (!filteredEntities.contains(lightSources[i].entity))
lightSources.removeAt(i--);
@@ -260,9 +253,6 @@ private:
RenderViewInitializerJobPtr m_renderViewJob;
FrustumCullingJobPtr m_frustumCullingJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
- LightGathererPtr m_lightGathererJob;
- RenderableEntityFilterPtr m_renderableEntityFilterJob;
- ComputableEntityFilterPtr m_computableEntityFilterJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
Renderer *m_renderer;
@@ -345,6 +335,84 @@ private:
FrameGraphNode *m_leafNode;
};
+class SyncLightsGatherer
+{
+public:
+ explicit SyncLightsGatherer(LightGathererPtr gatherJob,
+ Renderer *renderer,
+ FrameGraphNode *leafNode)
+ : m_gatherJob(gatherJob)
+ , m_renderer(renderer)
+ , m_leafNode(leafNode)
+ {
+ }
+
+ void operator()()
+ {
+ QMutexLocker lock(m_renderer->cache()->mutex());
+ RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
+ dataCacheForLeaf.gatheredLights = m_gatherJob->lights();
+ dataCacheForLeaf.environmentLight = m_gatherJob->takeEnvironmentLight();
+ }
+
+private:
+ LightGathererPtr m_gatherJob;
+ Renderer *m_renderer;
+ FrameGraphNode *m_leafNode;
+};
+
+class SyncRenderableEntities
+{
+public:
+ explicit SyncRenderableEntities(RenderableEntityFilterPtr gatherJob,
+ Renderer *renderer,
+ FrameGraphNode *leafNode)
+ : m_gatherJob(gatherJob)
+ , m_renderer(renderer)
+ , m_leafNode(leafNode)
+ {
+ }
+
+ void operator()()
+ {
+ QMutexLocker lock(m_renderer->cache()->mutex());
+ RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
+ dataCacheForLeaf.renderableEntities = m_gatherJob->filteredEntities();
+ std::sort(dataCacheForLeaf.renderableEntities.begin(), dataCacheForLeaf.renderableEntities.end());
+ }
+
+private:
+ RenderableEntityFilterPtr m_gatherJob;
+ Renderer *m_renderer;
+ FrameGraphNode *m_leafNode;
+};
+
+class SyncComputableEntities
+{
+public:
+ explicit SyncComputableEntities(ComputableEntityFilterPtr gatherJob,
+ Renderer *renderer,
+ FrameGraphNode *leafNode)
+ : m_gatherJob(gatherJob)
+ , m_renderer(renderer)
+ , m_leafNode(leafNode)
+ {
+ }
+
+ void operator()()
+ {
+ QMutexLocker lock(m_renderer->cache()->mutex());
+ RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
+ dataCacheForLeaf.computeEntities = m_gatherJob->filteredEntities();
+ std::sort(dataCacheForLeaf.computeEntities.begin(), dataCacheForLeaf.computeEntities.end());
+ }
+
+private:
+ ComputableEntityFilterPtr m_gatherJob;
+ Renderer *m_renderer;
+ FrameGraphNode *m_leafNode;
+};
+
} // anonymous
RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer)
@@ -353,11 +421,11 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
, m_renderer(renderer)
, m_layerCacheNeedsToBeRebuilt(false)
, m_materialGathererCacheNeedsToBeRebuilt(false)
+ , m_lightsCacheNeedsToBeRebuilt(false)
+ , m_renderableCacheNeedsToBeRebuilt(false)
+ , m_computableCacheNeedsToBeRebuilt(false)
, m_renderViewJob(RenderViewInitializerJobPtr::create())
, m_filterEntityByLayerJob()
- , m_lightGathererJob(Render::LightGathererPtr::create())
- , m_renderableEntityFilterJob(RenderableEntityFilterPtr::create())
- , m_computableEntityFilterJob(ComputableEntityFilterPtr::create())
, m_frustumCullingJob(new Render::FrustumCullingJob())
, m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
, m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex))
@@ -451,10 +519,37 @@ 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);
+
+ if (m_lightsCacheNeedsToBeRebuilt) {
+ m_lightGathererJob = Render::LightGathererPtr::create();
+ m_lightGathererJob->setManager(entityManager);
+
+ m_cacheLightsJob = SynchronizerJobPtr::create(SyncLightsGatherer(m_lightGathererJob, m_renderer, m_leafNode),
+ JobTypes::EntityComponentTypeFiltering);
+ m_cacheLightsJob->addDependency(m_lightGathererJob);
+ }
+
+ if (m_renderableCacheNeedsToBeRebuilt) {
+ m_renderableEntityFilterJob = RenderableEntityFilterPtr::create();
+ m_renderableEntityFilterJob->setManager(entityManager);
+
+ m_cacheRenderableEntitiesJob = SynchronizerJobPtr::create(
+ SyncRenderableEntities(m_renderableEntityFilterJob, m_renderer, m_leafNode),
+ JobTypes::EntityComponentTypeFiltering);
+ m_cacheRenderableEntitiesJob->addDependency(m_renderableEntityFilterJob);
+ }
+
+ if (m_computableCacheNeedsToBeRebuilt) {
+ m_computableEntityFilterJob = ComputableEntityFilterPtr::create();
+ m_computableEntityFilterJob->setManager(entityManager);
+
+ m_cacheComputableEntitiesJob = SynchronizerJobPtr::create(
+ SyncComputableEntities(m_computableEntityFilterJob, m_renderer, m_leafNode),
+ JobTypes::EntityComponentTypeFiltering);
+ m_cacheComputableEntitiesJob->addDependency(m_computableEntityFilterJob);
+ }
+
m_renderViewJob->setRenderer(m_renderer);
m_renderViewJob->setFrameGraphLeafNode(m_leafNode);
m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex);
@@ -502,9 +597,6 @@ void RenderViewBuilder::prepareJobs()
m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob,
m_frustumCullingJob,
m_filterProximityJob,
- m_lightGathererJob,
- m_renderableEntityFilterJob,
- m_computableEntityFilterJob,
m_materialGathererJobs,
m_renderViewBuilderJobs,
m_renderer,
@@ -523,7 +615,6 @@ void RenderViewBuilder::prepareJobs()
m_materialGathererJobs,
m_renderViewBuilderJobs),
JobTypes::SyncRenderViewInitialization);
-
}
QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
@@ -553,10 +644,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob);
m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
- m_syncRenderCommandBuildingJob->addDependency(m_renderableEntityFilterJob);
- m_syncRenderCommandBuildingJob->addDependency(m_computableEntityFilterJob);
m_syncRenderCommandBuildingJob->addDependency(m_filterProximityJob);
- m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob);
m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
// Ensure the RenderThread won't be able to process dirtyResources
@@ -575,11 +663,25 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
// Add jobs
jobs.push_back(m_renderViewJob); // Step 1
- jobs.push_back(m_renderableEntityFilterJob); // Step 1
- jobs.push_back(m_lightGathererJob); // Step 1
- // Note: do it only if OpenGL 4.3+ available
- jobs.push_back(m_computableEntityFilterJob); // Step 1
+ if (m_lightsCacheNeedsToBeRebuilt) {
+ jobs.push_back(m_lightGathererJob); // Step 1
+ jobs.push_back(m_cacheLightsJob);
+ m_syncRenderCommandBuildingJob->addDependency(m_cacheLightsJob);
+ }
+
+ if (m_renderableCacheNeedsToBeRebuilt) {
+ jobs.push_back(m_renderableEntityFilterJob); // Step 1
+ jobs.push_back(m_cacheRenderableEntitiesJob);
+ m_syncRenderCommandBuildingJob->addDependency(m_cacheRenderableEntitiesJob);
+ }
+
+ if (m_computableCacheNeedsToBeRebuilt) {
+ // Note: do it only if OpenGL 4.3+ available
+ jobs.push_back(m_computableEntityFilterJob); // Step 1
+ jobs.push_back(m_cacheComputableEntitiesJob);
+ m_syncRenderCommandBuildingJob->addDependency(m_cacheComputableEntitiesJob);
+ }
jobs.push_back(m_syncRenderViewInitializationJob); // Step 2
@@ -652,6 +754,36 @@ bool RenderViewBuilder::materialGathererCacheNeedsToBeRebuilt() const
return m_materialGathererCacheNeedsToBeRebuilt;
}
+void RenderViewBuilder::setRenderableCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
+{
+ m_renderableCacheNeedsToBeRebuilt = needsToBeRebuilt;
+}
+
+bool RenderViewBuilder::renderableCacheNeedsToBeRebuilt() const
+{
+ return m_renderableCacheNeedsToBeRebuilt;
+}
+
+void RenderViewBuilder::setComputableCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
+{
+ m_computableCacheNeedsToBeRebuilt = needsToBeRebuilt;
+}
+
+bool RenderViewBuilder::computableCacheNeedsToBeRebuilt() const
+{
+ return m_computableCacheNeedsToBeRebuilt;
+}
+
+void RenderViewBuilder::setLightGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
+{
+ m_lightsCacheNeedsToBeRebuilt = needsToBeRebuilt;
+}
+
+bool RenderViewBuilder::lightGathererCacheNeedsToBeRebuilt() const
+{
+ return m_lightsCacheNeedsToBeRebuilt;
+}
+
int RenderViewBuilder::optimalJobCount()
{
return RenderViewBuilder::m_optimalParallelJobCount;
diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h b/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
index 818313500..e223a5f1e 100644
--- a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
+++ b/src/render/renderers/opengl/renderer/renderviewbuilder_p.h
@@ -109,6 +109,15 @@ public:
void setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
bool materialGathererCacheNeedsToBeRebuilt() const;
+ void setRenderableCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
+ bool renderableCacheNeedsToBeRebuilt() const;
+
+ void setComputableCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
+ bool computableCacheNeedsToBeRebuilt() const;
+
+ void setLightGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
+ bool lightGathererCacheNeedsToBeRebuilt() const;
+
static int optimalJobCount();
static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset);
@@ -118,6 +127,9 @@ private:
Renderer *m_renderer;
bool m_layerCacheNeedsToBeRebuilt;
bool m_materialGathererCacheNeedsToBeRebuilt;
+ bool m_lightsCacheNeedsToBeRebuilt;
+ bool m_renderableCacheNeedsToBeRebuilt;
+ bool m_computableCacheNeedsToBeRebuilt;
RenderViewInitializerJobPtr m_renderViewJob;
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
@@ -137,6 +149,10 @@ private:
SynchronizerJobPtr m_syncMaterialGathererJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
+ SynchronizerJobPtr m_cacheRenderableEntitiesJob;
+ SynchronizerJobPtr m_cacheComputableEntitiesJob;
+ SynchronizerJobPtr m_cacheLightsJob;
+
static const int m_optimalParallelJobCount;
};