Compute renderables/computables/lights once instead of once per RV

All RV end up using exactly the same vector before filtering it down
on per RV specifics. No point in compute RV times the same thing.

Change-Id: Ia674095627771c8e9ada090fa47623cbbbd8a3f8
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
Paul Lemire 2019-10-16 15:55:42 +02:00
parent e5723fd820
commit 3c5848a923
8 changed files with 169 additions and 289 deletions

View File

@ -97,10 +97,6 @@ private:
QVector<Entity *> m_filteredEntities;
};
template<typename T, typename ... Ts>
using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>;
} // Render
} // Qt3DRender

View File

@ -93,6 +93,7 @@
#include <Qt3DRender/private/subtreeenabler_p.h>
#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
#include <Qt3DRender/private/qshaderprogram_p.h>
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
#include <Qt3DRender/qcameralens.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
@ -138,6 +139,82 @@ using namespace Qt3DCore;
namespace Qt3DRender {
namespace Render {
namespace {
class SyncLightsGatherer
{
public:
explicit SyncLightsGatherer(LightGathererPtr gatherJob,
RendererCache *cache)
: m_gatherJob(gatherJob)
, m_cache(cache)
{
}
void operator()()
{
QMutexLocker lock(m_cache->mutex());
m_cache->gatheredLights = m_gatherJob->lights();
m_cache->environmentLight = m_gatherJob->takeEnvironmentLight();
}
private:
LightGathererPtr m_gatherJob;
RendererCache *m_cache;
};
class SyncRenderableEntities
{
public:
explicit SyncRenderableEntities(RenderableEntityFilterPtr gatherJob,
RendererCache *cache)
: m_gatherJob(gatherJob)
, m_cache(cache)
{
}
void operator()()
{
QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
std::sort(selectedEntities.begin(), selectedEntities.end());
QMutexLocker lock(m_cache->mutex());
m_cache->renderableEntities = selectedEntities;
}
private:
RenderableEntityFilterPtr m_gatherJob;
RendererCache *m_cache;
};
class SyncComputableEntities
{
public:
explicit SyncComputableEntities(ComputableEntityFilterPtr gatherJob,
RendererCache *cache)
: m_gatherJob(gatherJob)
, m_cache(cache)
{
}
void operator()()
{
QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
std::sort(selectedEntities.begin(), selectedEntities.end());
QMutexLocker lock(m_cache->mutex());
m_cache->computeEntities = selectedEntities;
}
private:
ComputableEntityFilterPtr m_gatherJob;
RendererCache *m_cache;
};
} // anonymous
/*!
\internal
@ -193,6 +270,9 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
, m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create())
, m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create())
, m_lightGathererJob(Render::LightGathererPtr::create())
, m_renderableEntityFilterJob(Render::RenderableEntityFilterPtr::create())
, m_computableEntityFilterJob(Render::ComputableEntityFilterPtr::create())
, m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
, m_vaoGathererJob(SynchronizerJobPtr::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
@ -207,6 +287,12 @@ Renderer::Renderer(QRenderAspect::RenderType type)
[this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); },
JobTypes::DirtyShaderGathering))
, m_syncLoadingJobs(SynchronizerJobPtr::create([] {}, JobTypes::SyncLoadingJobs))
, m_cacheRenderableEntitiesJob(SynchronizerJobPtr::create(SyncRenderableEntities(m_renderableEntityFilterJob, &m_cache),
JobTypes::EntityComponentTypeFiltering))
, m_cacheComputableEntitiesJob(SynchronizerJobPtr::create(SyncComputableEntities(m_computableEntityFilterJob, &m_cache),
JobTypes::EntityComponentTypeFiltering))
, m_cacheLightsJob(SynchronizerJobPtr::create(SyncLightsGatherer(m_lightGathererJob, &m_cache),
JobTypes::EntityComponentTypeFiltering))
, m_ownedContext(false)
, m_offscreenHelper(nullptr)
, m_shouldSwapBuffers(true)
@ -240,6 +326,10 @@ Renderer::Renderer(QRenderAspect::RenderType type)
m_introspectShaderJob->addDependency(m_filterCompatibleTechniqueJob);
m_cacheLightsJob->addDependency(m_lightGathererJob);
m_cacheRenderableEntitiesJob->addDependency(m_renderableEntityFilterJob);
m_cacheComputableEntitiesJob->addDependency(m_computableEntityFilterJob);
m_filterCompatibleTechniqueJob->setRenderer(this);
m_defaultRenderStateSet = new RenderStateSet;
@ -309,6 +399,9 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_updateEntityLayersJob->setManager(m_nodesManager);
m_updateTreeEnabledJob->setManagers(m_nodesManager);
m_sendBufferCaptureJob->setManagers(m_nodesManager);
m_lightGathererJob->setManager(m_nodesManager->renderNodesManager());
m_renderableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
m_computableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
}
void Renderer::setServices(QServiceLocator *services)
@ -1862,6 +1955,21 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
if (layersDirty)
renderBinJobs.push_back(m_updateEntityLayersJob);
if (renderableDirty) {
renderBinJobs.push_back(m_renderableEntityFilterJob);
renderBinJobs.push_back(m_cacheRenderableEntitiesJob);
}
if (computeableDirty) {
renderBinJobs.push_back(m_computableEntityFilterJob);
renderBinJobs.push_back(m_cacheComputableEntitiesJob);
}
if (lightsDirty) {
renderBinJobs.push_back(m_lightGathererJob);
renderBinJobs.push_back(m_cacheLightsJob);
}
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
@ -1892,11 +2000,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// If we have a new RV (wasn't in the cache before, then it contains no cached data)
const bool isNewRV = !m_cache.leafNodeCache.contains(leaf);
builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt || isNewRV);
builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty || isNewRV);
builder.setComputableCacheNeedsToBeRebuilt(computeableDirty || isNewRV);
builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty || isNewRV);
builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt || isNewRV);
builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty || isNewRV);
builder.setRenderCommandCacheNeedsToBeRebuilt(renderCommandsDirty || isNewRV);
builder.prepareJobs();

View File

@ -82,6 +82,7 @@
#include <Qt3DRender/private/texture_p.h>
#include <Qt3DRender/private/glfence_p.h>
#include <Qt3DRender/private/shaderbuilder_p.h>
#include <Qt3DRender/private/lightgatherer_p.h>
#include <QHash>
#include <QMatrix4x4>
@ -158,6 +159,13 @@ typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr;
using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>;
template<typename T, typename ... Ts>
class FilterEntityByComponentJob;
template<typename T, typename ... Ts>
using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>;
using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer
{
public:
@ -227,6 +235,12 @@ public:
inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; }
inline Qt3DCore::QAspectJobPtr sendTextureChangesToFrontendJob() const { return m_sendTextureChangesToFrontendJob; }
inline UpdateEntityLayersJobPtr updateEntityLayersJob() const { return m_updateEntityLayersJob; }
inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; }
inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; }
inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; }
inline SynchronizerJobPtr cacheLightJob() const { return m_cacheLightsJob; }
inline SynchronizerJobPtr cacheRenderableEntitiesJob() const { return m_cacheRenderableEntitiesJob; }
inline SynchronizerJobPtr cacheComputableEntitiesJob() const { return m_cacheComputableEntitiesJob; }
Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
@ -369,6 +383,9 @@ private:
UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob;
FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
UpdateEntityLayersJobPtr m_updateEntityLayersJob;
LightGathererPtr m_lightGathererJob;
RenderableEntityFilterPtr m_renderableEntityFilterJob;
ComputableEntityFilterPtr m_computableEntityFilterJob;
QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests;
@ -386,6 +403,9 @@ private:
SynchronizerPostFramePtr m_sendDisablesToFrontendJob;
SynchronizerPostFramePtr m_introspectShaderJob;
SynchronizerJobPtr m_syncLoadingJobs;
SynchronizerJobPtr m_cacheRenderableEntitiesJob;
SynchronizerJobPtr m_cacheComputableEntitiesJob;
SynchronizerJobPtr m_cacheLightsJob;
void lookForAbandonedVaos();
void lookForDirtyBuffers();

View File

@ -70,13 +70,16 @@ struct RendererCache
{
QVector<Entity *> filterEntitiesByLayer;
MaterialParameterGathererData materialParameterGatherer;
QVector<LightSource> gatheredLights;
QVector<Entity *> renderableEntities;
QVector<Entity *> computeEntities;
EnvironmentLight* environmentLight;
QVector<EntityRenderCommandData> renderCommandData;
};
// Shared amongst all RV cache
QVector<Entity *> renderableEntities;
QVector<Entity *> computeEntities;
QVector<LightSource> gatheredLights;
EnvironmentLight* environmentLight;
// Per RV cache
QHash<FrameGraphNode *, LeafNodeData> leafNodeCache;
QMutex *mutex() { return &m_mutex; }

View File

@ -73,9 +73,10 @@ public:
// Split commands to build among jobs
QMutexLocker lock(m_renderer->cache()->mutex());
// Rebuild RenderCommands for all entities in RV (ignoring filtering)
const RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
RendererCache *cache = m_renderer->cache();
const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode];
RenderView *rv = m_renderViewInitializer->renderView();
const auto entities = !rv->isCompute() ? dataCacheForLeaf.renderableEntities : dataCacheForLeaf.computeEntities;
const auto entities = !rv->isCompute() ? cache->renderableEntities : cache->computeEntities;
rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer);
@ -256,18 +257,19 @@ public:
if (!rv->noDraw()) {
///////// CACHE LOCKED ////////////
// Retrieve Data from Cache
QMutexLocker lock(m_renderer->cache()->mutex());
Q_ASSERT(m_renderer->cache()->leafNodeCache.contains(m_leafNode));
RendererCache *cache = m_renderer->cache();
QMutexLocker lock(cache->mutex());
Q_ASSERT(cache->leafNodeCache.contains(m_leafNode));
const bool isDraw = !rv->isCompute();
const RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode];
// Rebuild RenderCommands if required
// This should happen fairly infrequently (FrameGraph Change, Geometry/Material change)
// and allow to skip that step most of the time
if (m_fullRebuild) {
// Clear previous cache
RendererCache::LeafNodeData &writableCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode];
writableCacheForLeaf.renderCommandData.clear();
QVector<EntityRenderCommandData> commandData;
@ -285,12 +287,12 @@ public:
}
const QVector<EntityRenderCommandData> commandData = dataCacheForLeaf.renderCommandData;
QVector<Entity *> renderableEntities = isDraw ? dataCacheForLeaf.renderableEntities : dataCacheForLeaf.computeEntities;
const QVector<Entity *> filteredEntities = dataCacheForLeaf.filterEntitiesByLayer;
QVector<LightSource> lightSources = dataCacheForLeaf.gatheredLights;
QVector<Entity *> renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities;
QVector<LightSource> lightSources = cache->gatheredLights;
rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer);
rv->setEnvironmentLight(dataCacheForLeaf.environmentLight);
rv->setEnvironmentLight(cache->environmentLight);
lock.unlock();
///////// END OF CACHE LOCKED ////////////
@ -441,88 +443,6 @@ 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()()
{
QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
std::sort(selectedEntities.begin(), selectedEntities.end());
QMutexLocker lock(m_renderer->cache()->mutex());
RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
dataCacheForLeaf.renderableEntities = selectedEntities;
}
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()()
{
QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities();
std::sort(selectedEntities.begin(), selectedEntities.end());
QMutexLocker lock(m_renderer->cache()->mutex());
RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
dataCacheForLeaf.computeEntities = selectedEntities;
}
private:
ComputableEntityFilterPtr m_gatherJob;
Renderer *m_renderer;
FrameGraphNode *m_leafNode;
};
} // anonymous
RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer)
@ -531,9 +451,6 @@ 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_renderCommandCacheNeedsToBeRebuilt(false)
, m_renderViewJob(RenderViewInitializerJobPtr::create())
, m_filterEntityByLayerJob()
@ -555,21 +472,6 @@ FilterLayerEntityJobPtr RenderViewBuilder::filterEntityByLayerJob() const
return m_filterEntityByLayerJob;
}
LightGathererPtr RenderViewBuilder::lightGathererJob() const
{
return m_lightGathererJob;
}
RenderableEntityFilterPtr RenderViewBuilder::renderableEntityFilterJob() const
{
return m_renderableEntityFilterJob;
}
ComputableEntityFilterPtr RenderViewBuilder::computableEntityFilterJob() const
{
return m_computableEntityFilterJob;
}
FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const
{
return m_frustumCullingJob;
@ -638,39 +540,9 @@ FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const
void RenderViewBuilder::prepareJobs()
{
// Init what we can here
EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager();
m_filterProximityJob->setManager(m_renderer->nodeManagers());
m_frustumCullingJob->setRoot(m_renderer->sceneRoot());
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);
}
if (m_renderCommandCacheNeedsToBeRebuilt) {
m_renderViewCommandBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
@ -789,6 +661,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->introspectShadersJob());
m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->bufferGathererJob());
m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->textureGathererJob());
m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->cacheLightJob());
for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) {
renderViewCommandUpdater->addDependency(m_syncRenderViewPreCommandUpdateJob);
@ -801,28 +674,11 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
// Add jobs
jobs.push_back(m_renderViewJob); // Step 1
if (m_lightsCacheNeedsToBeRebuilt) {
jobs.push_back(m_lightGathererJob); // Step 1
jobs.push_back(m_cacheLightsJob);
m_syncRenderViewPreCommandUpdateJob->addDependency(m_cacheLightsJob);
}
if (m_renderableCacheNeedsToBeRebuilt) {
jobs.push_back(m_renderableEntityFilterJob); // Step 1
jobs.push_back(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);
}
jobs.push_back(m_syncRenderViewPostInitializationJob); // Step 2
if (m_renderCommandCacheNeedsToBeRebuilt) { // Step 3
m_syncRenderViewPreCommandBuildingJob->addDependency(m_cacheComputableEntitiesJob);
m_syncRenderViewPreCommandBuildingJob->addDependency(m_cacheRenderableEntitiesJob);
m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheComputableEntitiesJob());
m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheRenderableEntitiesJob());
m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncRenderViewPostInitializationJob);
if (m_materialGathererCacheNeedsToBeRebuilt)
@ -907,36 +763,6 @@ 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;
}
void RenderViewBuilder::setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
{
m_renderCommandCacheNeedsToBeRebuilt = needsToBeRebuilt;

View File

@ -53,7 +53,6 @@
#include <functional>
#include <Qt3DCore/qaspectjob.h>
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
#include <Qt3DRender/private/filterlayerentityjob_p.h>
#include <Qt3DRender/private/genericlambdajob_p.h>
#include <Qt3DRender/private/materialparametergathererjob_p.h>
@ -62,7 +61,6 @@
#include <Qt3DRender/private/renderviewcommandupdaterjob_p.h>
#include <Qt3DRender/private/renderview_p.h>
#include <Qt3DRender/private/frustumcullingjob_p.h>
#include <Qt3DRender/private/lightgatherer_p.h>
#include <Qt3DRender/private/filterproximitydistancejob_p.h>
QT_BEGIN_NAMESPACE
@ -74,8 +72,6 @@ namespace Render {
class Renderer;
using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
class Q_AUTOTEST_EXPORT RenderViewBuilder
{
@ -84,9 +80,6 @@ public:
RenderViewInitializerJobPtr renderViewJob() const;
FilterLayerEntityJobPtr filterEntityByLayerJob() const;
LightGathererPtr lightGathererJob() const;
RenderableEntityFilterPtr renderableEntityFilterJob() const;
ComputableEntityFilterPtr computableEntityFilterJob() const;
FrustumCullingJobPtr frustumCullingJob() const;
QVector<RenderViewCommandBuilderJobPtr> renderViewCommandBuilderJobs() const;
QVector<RenderViewCommandUpdaterJobPtr> renderViewCommandUpdaterJobs() const;
@ -111,16 +104,6 @@ public:
bool layerCacheNeedsToBeRebuilt() const;
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;
void setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
bool renderCommandCacheNeedsToBeRebuilt() const;
@ -133,16 +116,10 @@ private:
Renderer *m_renderer;
bool m_layerCacheNeedsToBeRebuilt;
bool m_materialGathererCacheNeedsToBeRebuilt;
bool m_lightsCacheNeedsToBeRebuilt;
bool m_renderableCacheNeedsToBeRebuilt;
bool m_computableCacheNeedsToBeRebuilt;
bool m_renderCommandCacheNeedsToBeRebuilt;
RenderViewInitializerJobPtr m_renderViewJob;
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
LightGathererPtr m_lightGathererJob;
RenderableEntityFilterPtr m_renderableEntityFilterJob;
ComputableEntityFilterPtr m_computableEntityFilterJob;
FrustumCullingJobPtr m_frustumCullingJob;
QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs;
QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs;
@ -158,10 +135,6 @@ private:
SynchronizerJobPtr m_syncMaterialGathererJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
SynchronizerJobPtr m_cacheRenderableEntitiesJob;
SynchronizerJobPtr m_cacheComputableEntitiesJob;
SynchronizerJobPtr m_cacheLightsJob;
static const int m_optimalParallelJobCount;
};

View File

@ -223,12 +223,6 @@ private Q_SLOTS:
1 + // updateSkinningPaletteJob
1 + // SyncLoadingJobs
1 + // sendDisablesToFrontend
1 + // LightGathererJob
1 + // CacheLightJob
1 + // RenderableEntityFilterJob
1 + // CacheRenderableEntitiesJob
1 + // ComputableEntityFilterJob
1 + // CacheComputableEntitiesJob
singleRenderViewJobCount +
singleRenderViewCommandRebuildJobCount +
renderViewBuilderMaterialCacheJobCount +

View File

@ -52,6 +52,7 @@
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
QT_BEGIN_NAMESPACE
@ -280,39 +281,6 @@ private Q_SLOTS:
// mark jobs dirty and recheck
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 9 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}
{
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setLightGathererCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
// THEN
QCOMPARE(renderViewBuilder.lightGathererCacheNeedsToBeRebuilt(), true);
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 10 + 1 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}
{
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setRenderableCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
// THEN
QCOMPARE(renderViewBuilder.renderableCacheNeedsToBeRebuilt(), true);
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 10 + 1 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}
{
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setComputableCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
// THEN
QCOMPARE(renderViewBuilder.computableCacheNeedsToBeRebuilt(), true);
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 10 + 1 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}
}
void checkCheckJobDependencies()
@ -365,13 +333,14 @@ private Q_SLOTS:
QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
QCOMPARE(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6);
QCOMPARE(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7);
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.filterProximityJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(testAspect.renderer()->introspectShadersJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(testAspect.renderer()->bufferGathererJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(testAspect.renderer()->textureGathererJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(testAspect.renderer()->cacheLightJob()));
// Step 5
for (const auto &renderViewBuilderJob : renderViewBuilder.renderViewCommandUpdaterJobs()) {
@ -487,21 +456,18 @@ private Q_SLOTS:
Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport();
Qt3DRender::QClearBuffers *clearBuffer = new Qt3DRender::QClearBuffers(viewport);
Qt3DRender::TestAspect testAspect(buildSimpleScene(viewport));
Qt3DRender::Render::Renderer *renderer = testAspect.renderer();
// THEN
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setLightGathererCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.lightGathererJob()->run();
renderer->lightGathererJob()->run();
// THEN
QCOMPARE(renderViewBuilder.lightGathererJob()->lights().size(), 2);
QVERIFY(renderViewBuilder.lightGathererJob()->takeEnvironmentLight() != nullptr);
QCOMPARE(renderer->lightGathererJob()->lights().size(), 2);
QVERIFY(renderer->lightGathererJob()->takeEnvironmentLight() != nullptr);
}
void checkRenderableEntitiesFilteringExecution()
@ -510,20 +476,17 @@ private Q_SLOTS:
Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport();
Qt3DRender::QClearBuffers *clearBuffer = new Qt3DRender::QClearBuffers(viewport);
Qt3DRender::TestAspect testAspect(buildSimpleScene(viewport));
Qt3DRender::Render::Renderer *renderer = testAspect.renderer();
// THEN
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setRenderableCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.renderableEntityFilterJob()->run();
renderer->renderableEntityFilterJob()->run();
// THEN
QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->filteredEntities().size(), 1);
QCOMPARE(renderer->renderableEntityFilterJob()->filteredEntities().size(), 1);
}
void checkComputableEntitiesFilteringExecution()
@ -532,20 +495,17 @@ private Q_SLOTS:
Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport();
Qt3DRender::QClearBuffers *clearBuffer = new Qt3DRender::QClearBuffers(viewport);
Qt3DRender::TestAspect testAspect(buildSimpleScene(viewport));
Qt3DRender::Render::Renderer *renderer = testAspect.renderer();
// THEN
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setComputableCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.computableEntityFilterJob()->run();
renderer->computableEntityFilterJob()->run();
// THEN
QCOMPARE(renderViewBuilder.computableEntityFilterJob()->filteredEntities().size(), 1);
QCOMPARE(renderer->computableEntityFilterJob()->filteredEntities().size(), 1);
}
void checkSyncRenderViewInitializationExecution()
@ -662,24 +622,28 @@ private Q_SLOTS:
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer();
layerFilter->addLayer(layer);
Qt3DRender::TestAspect testAspect(buildEntityFilterTestScene(viewport, layer));
Qt3DRender::Render::Renderer *renderer = testAspect.renderer();
// THEN
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(layerFilter->id());
QVERIFY(leafNode != nullptr);
// WHEN
renderer->markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr);
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true);
renderViewBuilder.setRenderableCacheNeedsToBeRebuilt(true);
renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderer->renderableEntityFilterJob()->run();
renderer->cacheRenderableEntitiesJob()->run();
renderViewBuilder.renderViewJob()->run();
renderViewBuilder.renderableEntityFilterJob()->run();
renderViewBuilder.syncRenderViewPostInitializationJob()->run();
renderViewBuilder.filterEntityByLayerJob()->run();
QVector<Qt3DRender::Render::Entity *> renderableEntity = renderViewBuilder.renderableEntityFilterJob()->filteredEntities();
QVector<Qt3DRender::Render::Entity *> renderableEntity = renderer->renderableEntityFilterJob()->filteredEntities();
QVector<Qt3DRender::Render::Entity *> filteredEntity = renderViewBuilder.filterEntityByLayerJob()->filteredEntities();
// THEN