diff options
author | Svenn-Arne Dragly <svenn-arne.dragly@qt.io> | 2018-01-22 10:44:55 +0100 |
---|---|---|
committer | Svenn-Arne Dragly <svenn-arne.dragly@qt.io> | 2018-02-01 12:29:04 +0000 |
commit | 929e72e36cc10556bdf33a50911f2cd651f0b8dc (patch) | |
tree | 13c644d15561b018776d7155e6c6b1f2756d6c42 /src | |
parent | d22d786d94540d50fde776c5f44ccdb041824343 (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.h | 2 | ||||
-rw-r--r-- | src/render/backend/renderer.cpp | 52 | ||||
-rw-r--r-- | src/render/backend/renderer_p.h | 12 |
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; |