summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-11-29 12:20:11 +0100
committerPaul Lemire <paul.lemire@kdab.com>2019-12-02 12:35:49 +0100
commite5f99df24f4a587e30f9bba08cc5398c6d8354e3 (patch)
treefb80dd26472bda4c8f99780016618238d5b7439e
parenta2b5b5c8f6e09ccfaca8044b34f4d9675c3be14a (diff)
RenderViewCommandUpdaterJob: stop copying renderables data
This makes the post command update synchronization job a lot faster. Change-Id: I845c39cd4e2c0e56e8eefa05bbdd20d0bc3d2454 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp8
-rw-r--r--src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h12
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp13
-rw-r--r--src/render/renderers/opengl/renderer/renderview_p.h3
-rw-r--r--src/render/renderers/opengl/renderer/renderviewbuilder.cpp31
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<RenderCommand> &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<RenderCommand> 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 QVector<Ent
return commands;
}
-void RenderView::updateRenderCommand(EntityRenderCommandData &renderCommandData)
+void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData,
+ int offset,
+ int count)
{
// Note: since many threads can be building render commands
// we need to ensure that the UniformBlockValueBuilder they are using
@@ -735,10 +737,11 @@ void RenderView::updateRenderCommand(EntityRenderCommandData &renderCommandData)
builder->textureManager = 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<Entity *> &entities) const;
- void updateRenderCommand(EntityRenderCommandData &renderCommandData);
+ void updateRenderCommand(EntityRenderCommandData *renderCommandData,
+ int offset, int count);
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 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<RenderCommand> commands = std::move(commandData->commands);
- QVector<RenderCommand> 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));
}
}