From e5f99df24f4a587e30f9bba08cc5398c6d8354e3 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 29 Nov 2019 12:20:11 +0100 Subject: RenderViewCommandUpdaterJob: stop copying renderables data This makes the post command update synchronization job a lot faster. Change-Id: I845c39cd4e2c0e56e8eefa05bbdd20d0bc3d2454 Reviewed-by: Sean Harmer --- .../opengl/jobs/renderviewcommandupdaterjob.cpp | 8 +++--- .../opengl/jobs/renderviewcommandupdaterjob_p.h | 12 +++++++-- .../renderers/opengl/renderer/renderview.cpp | 13 +++++---- .../renderers/opengl/renderer/renderview_p.h | 3 ++- .../opengl/renderer/renderviewbuilder.cpp | 31 ++++++++++------------ 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp index af1d545ed..95c352dbe 100644 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp +++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp @@ -54,6 +54,8 @@ int renderViewInstanceCounter = 0; RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob() : Qt3DCore::QAspectJob() + , m_offset(0) + , m_count(0) , m_renderView(nullptr) , m_renderer(nullptr) { @@ -66,11 +68,7 @@ void RenderViewCommandUpdaterJob::run() // if a child has a mesh in the view frustum while its parent isn't contained in it. if (!m_renderView->noDraw()) { // Update Render Commands (Uniform Change, Depth Change) - m_renderView->updateRenderCommand(m_renderables); - - // Copy commands out of cached -> ensures we can submit them for rendering - // while cache is rebuilt or modified for next frame - m_commands = m_renderables.commands; + m_renderView->updateRenderCommand(m_renderables, m_offset, m_count); } } diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h index 72caef6cf..e6df3f3b3 100644 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h +++ b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h @@ -71,16 +71,24 @@ 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 EntityRenderCommandData &renderables) Q_DECL_NOTHROW { m_renderables = renderables; } + inline void setRenderables(EntityRenderCommandData *renderables, int offset, int count) Q_DECL_NOTHROW + { + m_offset = offset; + m_count = count; + m_renderables = renderables; + } + EntityRenderCommandData *renderables() const { return m_renderables; } QVector &commands() Q_DECL_NOTHROW { return m_commands; } void run() final; private: + int m_offset; + int m_count; RenderView *m_renderView; Renderer *m_renderer; - EntityRenderCommandData m_renderables; + EntityRenderCommandData *m_renderables; QVector m_commands; }; diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index 76bdb537b..e761507ce 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -725,7 +725,9 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVectortextureManager = m_manager->textureManager(); m_localData.setLocalData(builder); - 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]; + for (int i = 0, m = count; i < m; ++i) { + const int idx = offset + i; + Entity *entity = renderCommandData->entities.at(idx); + const RenderPassParameterData passData = renderCommandData->passesData.at(idx); + RenderCommand &command = renderCommandData->commands[idx]; // 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 1221e7a59..0d0a1dbf9 100644 --- a/src/render/renderers/opengl/renderer/renderview_p.h +++ b/src/render/renderers/opengl/renderer/renderview_p.h @@ -231,7 +231,8 @@ public: EntityRenderCommandData buildComputeRenderCommands(const QVector &entities) const; - void updateRenderCommand(EntityRenderCommandData &renderCommandData); + void updateRenderCommand(EntityRenderCommandData *renderCommandData, + int offset, int count); void setCommands(const QVector &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 96fa55c47..2bf2759fb 100644 --- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp +++ b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp @@ -117,16 +117,11 @@ public: // Append all the commands and sort them RenderView *rv = m_renderViewJob->renderView(); - int totalCommandCount = 0; - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandUpdaterJobs)) - totalCommandCount += renderViewCommandBuilder->commands().size(); + const EntityRenderCommandData *commandData = m_renderViewCommandUpdaterJobs.first()->renderables(); + const QVector commands = std::move(commandData->commands); - QVector commands; - commands.reserve(totalCommandCount); - - // Reduction - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandUpdaterJobs)) - commands += std::move(renderViewCommandBuilder->commands()); + // TO DO: Cache the EntityRenderCommandData so that it can be reused if nothing in the scene has changed + delete commandData; rv->setCommands(commands); @@ -316,8 +311,8 @@ public: // Filter out Render commands for which the Entity wasn't selected because // of frustum, proximity or layer filtering - EntityRenderCommandData filteredCommandData; - filteredCommandData.reserve(renderableEntities.size()); + EntityRenderCommandData *filteredCommandData = new EntityRenderCommandData(); + 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); @@ -335,9 +330,9 @@ public: // Push pointers to command data for all commands that match the // entity while (cIt != cEnd && commandData.entities.at(cIt) == targetEntity) { - filteredCommandData.push_back(commandData.entities.at(cIt), - commandData.commands.at(cIt), - commandData.passesData.at(cIt)); + filteredCommandData->push_back(commandData.entities.at(cIt), + commandData.commands.at(cIt), + commandData.passesData.at(cIt)); ++cIt; } ++eIt; @@ -346,13 +341,15 @@ public: // Split among the number of command builders int i = 0; const int m = RenderViewBuilder::optimalJobCount() - 1; - const int packetSize = filteredCommandData.size() / RenderViewBuilder::optimalJobCount(); + const int packetSize = filteredCommandData->size() / RenderViewBuilder::optimalJobCount(); while (i < m) { const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i); - renderViewCommandBuilder->setRenderables(filteredCommandData.mid(i * packetSize, packetSize)); + renderViewCommandBuilder->setRenderables(filteredCommandData, i * packetSize, packetSize); ++i; } - m_renderViewCommandUpdaterJobs.at(i)->setRenderables(filteredCommandData.mid(i * packetSize, packetSize + filteredCommandData.size() % (m + 1))); + m_renderViewCommandUpdaterJobs.at(i)->setRenderables(filteredCommandData, + i * packetSize, + packetSize + filteredCommandData->size() % (m + 1)); } } -- cgit v1.2.3