diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-10-17 10:03:01 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-29 09:13:35 +0100 |
commit | fee0f43522483415b4af1475caaca21658f3e24a (patch) | |
tree | 7e226f37ec3685b7caed96330f98f6aa82b74e27 /src/render/renderers | |
parent | 3c5848a923b9b9393753c654e837fc8c99bd8b23 (diff) |
Convert EntityRenderCommandData to struct of vectors
Change-Id: Ib290491476b083e6aa4cff5c112a802c4e198987
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/renderers')
8 files changed, 90 insertions, 43 deletions
diff --git a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h index 725f83b62..9f45a8005 100644 --- a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h +++ b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h @@ -68,14 +68,14 @@ public: inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } inline void setEntities(const QVector<Entity *> &entities) { m_entities = entities; } - inline QVector<EntityRenderCommandData> &commandData() { return m_commandData; } + inline EntityRenderCommandData &commandData() { return m_commandData; } void run() final; private: RenderView *m_renderView; QVector<Entity *> m_entities; - QVector<EntityRenderCommandData> m_commandData; + EntityRenderCommandData m_commandData; }; typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr; diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp index d58b288e6..af1d545ed 100644 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp +++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp @@ -70,11 +70,7 @@ void RenderViewCommandUpdaterJob::run() // Copy commands out of cached -> ensures we can submit them for rendering // while cache is rebuilt or modified for next frame - QVector<RenderCommand> commands; - commands.reserve(m_renderables.size()); - for (const EntityRenderCommandData *data : m_renderables) - commands.push_back(data->command); - m_commands = commands; + m_commands = m_renderables.commands; } } diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h index 3fff5f1a0..72caef6cf 100644 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h +++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h @@ -71,7 +71,7 @@ public: inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; } - inline void setRenderables(const QVector<EntityRenderCommandData *> &renderables) Q_DECL_NOTHROW { m_renderables = renderables; } + inline void setRenderables(const EntityRenderCommandData &renderables) Q_DECL_NOTHROW { m_renderables = renderables; } QVector<RenderCommand> &commands() Q_DECL_NOTHROW { return m_commands; } @@ -80,7 +80,7 @@ public: private: RenderView *m_renderView; Renderer *m_renderer; - QVector<EntityRenderCommandData *> m_renderables; + EntityRenderCommandData m_renderables; QVector<RenderCommand> m_commands; }; diff --git a/src/render/renderers/opengl/renderer/rendercommand_p.h b/src/render/renderers/opengl/renderer/rendercommand_p.h index 58ab0cadd..0180d6996 100644 --- a/src/render/renderers/opengl/renderer/rendercommand_p.h +++ b/src/render/renderers/opengl/renderer/rendercommand_p.h @@ -131,11 +131,58 @@ inline bool operator!=(const RenderCommand &lhs, const RenderCommand &rhs) noexc struct EntityRenderCommandData { - Entity *entity; - RenderCommand command; - RenderPassParameterData passData; + QVector<Entity *> entities; + QVector<RenderCommand> commands; + QVector<RenderPassParameterData> passesData; + + void reserve(int size) + { + entities.reserve(size); + commands.reserve(size); + passesData.reserve(size); + } + + inline int size() const { return entities.size(); } + + inline void push_back(Entity *e, const RenderCommand &c, const RenderPassParameterData &p) + { + entities.push_back(e); + commands.push_back(c); + passesData.push_back(p); + } + + inline void push_back(Entity *e, RenderCommand &&c, RenderPassParameterData &&p) + { + entities.push_back(e); + commands.push_back(std::move(c)); + passesData.push_back(std::move(p)); + } + + EntityRenderCommandData &operator+=(const EntityRenderCommandData &t) + { + entities += t.entities; + commands += t.commands; + passesData += t.passesData; + return *this; + } + + EntityRenderCommandData &operator+=(EntityRenderCommandData &&t) + { + entities += std::move(t.entities); + commands += std::move(t.commands); + passesData += std::move(t.passesData); + return *this; + } + + EntityRenderCommandData mid(int idx, int len) const + { + return { entities.mid(idx, len), commands.mid(idx, len), passesData.mid(idx, len) }; + } + + }; + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/renderers/opengl/renderer/renderercache_p.h b/src/render/renderers/opengl/renderer/renderercache_p.h index 984004993..02fe4ff41 100644 --- a/src/render/renderers/opengl/renderer/renderercache_p.h +++ b/src/render/renderers/opengl/renderer/renderercache_p.h @@ -70,7 +70,7 @@ struct RendererCache { QVector<Entity *> filterEntitiesByLayer; MaterialParameterGathererData materialParameterGatherer; - QVector<EntityRenderCommandData> renderCommandData; + EntityRenderCommandData renderCommandData; }; // Shared amongst all RV cache diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index b102de9de..97d494370 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -621,11 +621,11 @@ void RenderView::addClearBuffers(const ClearBuffers *cb) { } // If we are there, we know that entity had a GeometryRenderer + Material -QVector<EntityRenderCommandData> RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities) const +EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities) const { - QVector<EntityRenderCommandData> commands; - commands.reserve(entities.size()); + EntityRenderCommandData commands; + commands.reserve(entities.size()); for (Entity *entity : entities) { GeometryRenderer *geometryRenderer = nullptr; @@ -662,8 +662,9 @@ QVector<EntityRenderCommandData> RenderView::buildDrawRenderCommands(const QVect } command.m_shader = m_manager->lookupHandle<Shader, ShaderManager, HShader>(pass->shaderProgram()); - const EntityRenderCommandData commandData = { entity, command, passData }; - commands.append(commandData); + commands.push_back(entity, + std::move(command), + std::move(passData)); } } } @@ -671,15 +672,17 @@ QVector<EntityRenderCommandData> RenderView::buildDrawRenderCommands(const QVect return commands; } -QVector<EntityRenderCommandData> RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities) const +EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities) const { // If the RenderView contains only a ComputeDispatch then it cares about // A ComputeDispatch is also implicitely a NoDraw operation // enabled flag // layer component // material/effect/technique/parameters/filters/ - QVector<EntityRenderCommandData> commands; + EntityRenderCommandData commands; + commands.reserve(entities.size()); + for (Entity *entity : entities) { ComputeCommand *computeJob = nullptr; HComputeCommand computeCommandHandle = entity->componentHandle<ComputeCommand>(); @@ -712,8 +715,9 @@ QVector<EntityRenderCommandData> RenderView::buildComputeRenderCommands(const QV command.m_workGroups[1] = std::max(m_workGroups[1], computeJob->y()); command.m_workGroups[2] = std::max(m_workGroups[2], computeJob->z()); - const EntityRenderCommandData commandData = { entity, command, passData }; - commands.append(commandData); + commands.push_back(entity, + std::move(command), + std::move(passData)); } } } @@ -721,7 +725,7 @@ QVector<EntityRenderCommandData> RenderView::buildComputeRenderCommands(const QV return commands; } -void RenderView::updateRenderCommand(QVector<EntityRenderCommandData *> &renderCommandData) +void RenderView::updateRenderCommand(EntityRenderCommandData &renderCommandData) { // Note: since many threads can be building render commands // we need to ensure that the UniformBlockValueBuilder they are using @@ -731,10 +735,10 @@ void RenderView::updateRenderCommand(QVector<EntityRenderCommandData *> &renderC builder->textureManager = m_manager->textureManager(); m_localData.setLocalData(builder); - for (EntityRenderCommandData *commandData : renderCommandData) { - Entity *entity = commandData->entity; - RenderPassParameterData passData = commandData->passData; - RenderCommand &command = commandData->command; + for (int i = 0, m = renderCommandData.size(); i < m; ++i) { + Entity *entity = renderCommandData.entities.at(i); + const RenderPassParameterData passData = renderCommandData.passesData.at(i); + RenderCommand &command = renderCommandData.commands[i]; // Pick which lights to take in to account. // For now decide based on the distance by taking the MAX_LIGHTS closest lights. diff --git a/src/render/renderers/opengl/renderer/renderview_p.h b/src/render/renderers/opengl/renderer/renderview_p.h index 7d148118d..1221e7a59 100644 --- a/src/render/renderers/opengl/renderer/renderview_p.h +++ b/src/render/renderers/opengl/renderer/renderview_p.h @@ -227,11 +227,11 @@ public: RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true); - QVector<EntityRenderCommandData> buildDrawRenderCommands(const QVector<Entity *> &entities) const; - QVector<EntityRenderCommandData> buildComputeRenderCommands(const QVector<Entity *> &entities) const; + EntityRenderCommandData buildDrawRenderCommands(const QVector<Entity *> &entities) const; + EntityRenderCommandData buildComputeRenderCommands(const QVector<Entity *> &entities) const; - void updateRenderCommand(QVector<EntityRenderCommandData *> &renderCommandData); + void updateRenderCommand(EntityRenderCommandData &renderCommandData); void setCommands(const QVector<RenderCommand> &commands) Q_DECL_NOTHROW { m_commands = commands; } diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp index ead29ec03..40179fbd6 100644 --- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp +++ b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp @@ -268,11 +268,7 @@ public: // 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 = cache->leafNodeCache[m_leafNode]; - writableCacheForLeaf.renderCommandData.clear(); - - QVector<EntityRenderCommandData> commandData; + EntityRenderCommandData commandData; // Reduction { int totalCommandCount = 0; @@ -282,10 +278,12 @@ public: for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) commandData += std::move(renderViewCommandBuilder->commandData()); } - // Store in cache + + // Store new cache + RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode]; writableCacheForLeaf.renderCommandData = std::move(commandData); } - const QVector<EntityRenderCommandData> commandData = dataCacheForLeaf.renderCommandData; + const EntityRenderCommandData commandData = dataCacheForLeaf.renderCommandData; const QVector<Entity *> filteredEntities = dataCacheForLeaf.filterEntitiesByLayer; QVector<Entity *> renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities; @@ -317,26 +315,28 @@ public: // Filter out Render commands for which the Entity wasn't selected because // of frustum, proximity or layer filtering - QVector<EntityRenderCommandData *> filteredCommandData; + EntityRenderCommandData filteredCommandData; filteredCommandData.reserve(renderableEntities.size()); // Because dataCacheForLeaf.renderableEntities or computeEntities are sorted // What we get out of EntityRenderCommandData is also sorted by Entity auto eIt = std::cbegin(renderableEntities); - auto cIt = std::cbegin(commandData); const auto eEnd = std::cend(renderableEntities); - const auto cEnd = std::cend(commandData); + int cIt = 0; + const int cEnd = commandData.size(); while (eIt != eEnd) { const Entity *targetEntity = *eIt; // Advance until we have commands whose Entity has a lower address // than the selected filtered entity - while (cIt->entity < targetEntity && cIt != cEnd) + while (cIt != cEnd && commandData.entities.at(cIt) < targetEntity) ++cIt; // Push pointers to command data for all commands that match the // entity - while (cIt->entity == targetEntity && cIt != cEnd) { - filteredCommandData.push_back(const_cast<EntityRenderCommandData *>(&(*cIt))); + while (cIt != cEnd && commandData.entities.at(cIt) == targetEntity) { + filteredCommandData.push_back(commandData.entities.at(cIt), + commandData.commands.at(cIt), + commandData.passesData.at(cIt)); ++cIt; } ++eIt; |