summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2018-01-22 10:44:55 +0100
committerSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2018-02-01 12:29:04 +0000
commit929e72e36cc10556bdf33a50911f2cd651f0b8dc (patch)
tree13c644d15561b018776d7155e6c6b1f2756d6c42 /src
parentd22d786d94540d50fde776c5f44ccdb041824343 (diff)
Organize dirty bits in categories
To get a better overview of which dirty bits changed at what time, this change organizes them in the following categories: - current: dirty bits at job building - marked: dirty bits marked since last job building - remaining: dirty bits set but not cleared in the previous frame Further, within renderBinJobs, we add a variable "notCleared" to keep track of which bits in "current" should be set in "remaining". Change-Id: I43a42a4fd495a6d9f794721d1f09381718dfa647 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/render/backend/abstractrenderer_p.h2
-rw-r--r--src/render/backend/renderer.cpp52
-rw-r--r--src/render/backend/renderer_p.h12
3 files changed, 41 insertions, 25 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index c934dbfae..bc8a9812f 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -141,7 +141,9 @@ public:
virtual void markDirty(BackendNodeDirtySet changes, BackendNode *node) = 0;
virtual BackendNodeDirtySet dirtyBits() = 0;
+#if defined(QT_BUILD_INTERNAL)
virtual void clearDirtyBits(BackendNodeDirtySet changes) = 0;
+#endif
virtual bool shouldRender() = 0;
virtual void skipNextFrame() = 0;
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 20aeaf2df..c1b5760c7 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -162,7 +162,6 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_waitForInitializationToBeCompleted(0)
, m_pickEventFilter(new PickEventFilter())
, m_exposed(0)
- , m_changeSet(0)
, m_lastFrameCorrect(0)
, m_glContext(nullptr)
, m_shareContext(nullptr)
@@ -514,7 +513,7 @@ void Renderer::setSceneRoot(QBackendNodeFactory *factory, Entity *sgRoot)
m_updateTreeEnabledJob->setRoot(m_renderSceneRoot);
// Set all flags to dirty
- m_changeSet |= AbstractRenderer::AllDirty;
+ m_dirtyBits.marked |= AbstractRenderer::AllDirty;
}
void Renderer::registerEventFilter(QEventFilterService *service)
@@ -1445,25 +1444,29 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node)
{
Q_UNUSED(node);
- m_changeSet |= changes;
+ m_dirtyBits.marked |= changes;
}
Renderer::BackendNodeDirtySet Renderer::dirtyBits()
{
- return m_changeSet;
+ return m_dirtyBits.marked;
}
+#if defined(QT_BUILD_INTERNAL)
void Renderer::clearDirtyBits(BackendNodeDirtySet changes)
{
- m_changeSet &= ~changes;
+ m_dirtyBits.remaining &= ~changes;
+ m_dirtyBits.marked &= ~changes;
}
+#endif
bool Renderer::shouldRender()
{
// Only render if something changed during the last frame, or the last frame
// was not rendered successfully (or render-on-demand is disabled)
return (m_settings->renderPolicy() == QRenderSettings::Always
- || m_changeSet != 0
+ || m_dirtyBits.marked != 0
+ || m_dirtyBits.remaining != 0
|| !m_lastFrameCorrect.load());
}
@@ -1497,28 +1500,31 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
- BackendNodeDirtySet changesToUnset = dirtyBits();
+ const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
+ m_dirtyBits.marked = 0;
+ m_dirtyBits.remaining = 0;
+ BackendNodeDirtySet notCleared = 0;
// Add jobs
- const bool entitiesEnabledDirty = changesToUnset & AbstractRenderer::EntityEnabledDirty;
+ const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
if (entitiesEnabledDirty) {
renderBinJobs.push_back(m_updateTreeEnabledJob);
m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
}
- if (changesToUnset & AbstractRenderer::TransformDirty) {
+ if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
renderBinJobs.push_back(m_worldTransformJob);
renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
renderBinJobs.push_back(m_updateShaderDataTransformJob);
}
- if (changesToUnset & AbstractRenderer::GeometryDirty) {
+ if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty) {
renderBinJobs.push_back(m_calculateBoundingVolumeJob);
renderBinJobs.push_back(m_updateMeshTriangleListJob);
}
- if (changesToUnset & AbstractRenderer::GeometryDirty ||
- changesToUnset & AbstractRenderer::TransformDirty) {
+ if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
+ dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
renderBinJobs.push_back(m_expandBoundingVolumeJob);
}
@@ -1534,13 +1540,13 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Jobs to prepare GL Resource upload
renderBinJobs.push_back(m_vaoGathererJob);
- if (changesToUnset & AbstractRenderer::BuffersDirty)
+ if (dirtyBitsForFrame & AbstractRenderer::BuffersDirty)
renderBinJobs.push_back(m_bufferGathererJob);
- if (changesToUnset & AbstractRenderer::ShadersDirty)
+ if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty)
renderBinJobs.push_back(m_shaderGathererJob);
- if (changesToUnset & AbstractRenderer::TexturesDirty) {
+ if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) {
renderBinJobs.push_back(m_syncTextureLoadingJob);
renderBinJobs.push_back(m_textureGathererJob);
}
@@ -1548,7 +1554,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Layer cache is dependent on layers, layer filters and the enabled flag
// on entities
- const bool layersDirty = changesToUnset & AbstractRenderer::LayersDirty;
+ const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty;
bool layersCacheRebuilt = false;
@@ -1584,19 +1590,19 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Only reset LayersDirty flag once we have really rebuilt the caches
if (layersDirty && !layersCacheRebuilt)
- changesToUnset.setFlag(AbstractRenderer::LayersDirty, false);
+ notCleared |= AbstractRenderer::LayersDirty;
if (entitiesEnabledDirty && !layersCacheRebuilt)
- changesToUnset.setFlag(AbstractRenderer::EntityEnabledDirty, false);
+ notCleared |= AbstractRenderer::EntityEnabledDirty;
// Clear dirty bits
// TO DO: When secondary GL thread is integrated, the following line can be removed
- changesToUnset.setFlag(AbstractRenderer::ShadersDirty, false);
+ notCleared |= AbstractRenderer::ShadersDirty;
// Clear all dirty flags but Compute so that
// we still render every frame when a compute shader is used in a scene
- if (changesToUnset.testFlag(Renderer::ComputeDirty))
- changesToUnset.setFlag(Renderer::ComputeDirty, false);
- clearDirtyBits(changesToUnset);
+ notCleared |= Renderer::ComputeDirty;
+
+ m_dirtyBits.remaining = dirtyBitsForFrame & notCleared;
return renderBinJobs;
}
@@ -1722,7 +1728,7 @@ void Renderer::performCompute(const RenderView *, RenderCommand *command)
command->m_workGroups[2]);
}
// HACK: Reset the compute flag to dirty
- m_changeSet |= AbstractRenderer::ComputeDirty;
+ m_dirtyBits.marked |= AbstractRenderer::ComputeDirty;
#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
int err = m_graphicsContext->openGLContext()->functions()->glGetError();
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index d4917e28c..987576059 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -182,8 +182,10 @@ public:
void markDirty(BackendNodeDirtySet changes, BackendNode *node) Q_DECL_OVERRIDE;
BackendNodeDirtySet dirtyBits() Q_DECL_OVERRIDE;
- void clearDirtyBits(BackendNodeDirtySet changes) Q_DECL_OVERRIDE;
+#if defined(QT_BUILD_INTERNAL)
+ void clearDirtyBits(BackendNodeDirtySet changes) Q_DECL_OVERRIDE;
+#endif
bool shouldRender() Q_DECL_OVERRIDE;
void skipNextFrame() Q_DECL_OVERRIDE;
@@ -307,7 +309,13 @@ private:
QVector<Attribute *> m_dirtyAttributes;
QVector<Geometry *> m_dirtyGeometry;
QAtomicInt m_exposed;
- BackendNodeDirtySet m_changeSet;
+
+ struct DirtyBits {
+ BackendNodeDirtySet marked = 0; // marked dirty since last job build
+ BackendNodeDirtySet remaining = 0; // remaining dirty after jobs have finished
+ };
+ DirtyBits m_dirtyBits;
+
QAtomicInt m_lastFrameCorrect;
QOpenGLContext *m_glContext;
QOpenGLContext *m_shareContext;