summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-03-28 12:50:49 +0200
committerPaul Lemire <paul.lemire@kdab.com>2017-06-01 12:12:55 +0000
commit11a7585b75def904f7450eea50455ca6e8e9396f (patch)
tree9a8f0c05d9d43dd1f072101ce691528c197c3e58 /src
parent25135da0642516bb209a400035641148d7ae1a49 (diff)
Renderer: add more dirty flags and launch jobs based on that
This allows to launch the boundings volumes and transform related jobs only when transforms or geometry have changed. This will be extended in the following commits to Materials, FrameGraph... Change-Id: I71bc61471639ead32de71c9e78952fb0741ef185 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/render/backend/abstractrenderer_p.h16
-rw-r--r--src/render/backend/entity.cpp21
-rw-r--r--src/render/backend/renderer.cpp69
-rw-r--r--src/render/backend/rendersettings_p.h4
-rw-r--r--src/render/framegraph/viewportnode_p.h2
-rw-r--r--src/render/geometry/buffer.cpp2
-rw-r--r--src/render/geometry/geometry.cpp2
-rw-r--r--src/render/geometry/geometryrenderer.cpp2
-rw-r--r--src/render/materialsystem/shader.cpp2
-rw-r--r--src/render/texture/texture.cpp2
10 files changed, 84 insertions, 38 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index 2f7545454..0e78b597d 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -95,11 +95,17 @@ public:
// Changes made to backend nodes are reported to the Renderer
enum BackendNodeDirtyFlag {
- TransformDirty = 1 << 0,
- MaterialDirty = 1 << 1,
- GeometryDirty = 1 << 2,
- ComputeDirty = 1 << 3,
- AllDirty = 1 << 15
+ TransformDirty = 1 << 0,
+ MaterialDirty = 1 << 1,
+ GeometryDirty = 1 << 2,
+ ComputeDirty = 1 << 3,
+ ParameterDirty = 1 << 4,
+ FrameGraphDirty = 1 << 5,
+ EntityEnabledDirty = 1 << 6,
+ BuffersDirty = 1 << 7,
+ TexturesDirty = 1 << 8,
+ ShadersDirty = 1 << 9,
+ AllDirty = 0xffffff
};
Q_DECLARE_FLAGS(BackendNodeDirtySet, BackendNodeDirtyFlag)
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index 898c1e36e..6292fc9c4 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -199,6 +199,7 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const auto componentIdAndType = QNodeIdTypePair(change->componentId(), change->componentMetaObject());
addComponent(componentIdAndType);
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Added. Id =" << change->componentId();
+ markDirty(AbstractRenderer::AllDirty);
break;
}
@@ -206,28 +207,42 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QComponentRemovedChangePtr change = qSharedPointerCast<QComponentRemovedChange>(e);
removeComponent(change->componentId());
qCDebug(Render::RenderNodes) << Q_FUNC_INFO << "Component Removed. Id =" << change->componentId();
+ markDirty(AbstractRenderer::AllDirty);
break;
}
case PropertyValueAdded: {
QPropertyNodeAddedChangePtr change = qSharedPointerCast<QPropertyNodeAddedChange>(e);
- if (change->metaObject()->inherits(&QEntity::staticMetaObject))
+ if (change->metaObject()->inherits(&QEntity::staticMetaObject)) {
appendChildHandle(m_nodeManagers->renderNodesManager()->lookupHandle(change->addedNodeId()));
+ markDirty(AbstractRenderer::AllDirty);
+ }
break;
}
case PropertyValueRemoved: {
QPropertyNodeRemovedChangePtr change = qSharedPointerCast<QPropertyNodeRemovedChange>(e);
- if (change->metaObject()->inherits(&QEntity::staticMetaObject))
+ if (change->metaObject()->inherits(&QEntity::staticMetaObject)) {
removeChildHandle(m_nodeManagers->renderNodesManager()->lookupHandle(change->removedNodeId()));
+ markDirty(AbstractRenderer::AllDirty);
+ }
break;
}
+ case PropertyUpdated: {
+ QPropertyUpdatedChangePtr change = qSharedPointerCast<QPropertyUpdatedChange>(e);
+ if (change->propertyName() == QByteArrayLiteral("enabled")) {
+ // We only mark as dirty the renderer
+ markDirty(AbstractRenderer::EntityEnabledDirty);
+ // We let QBackendNode::sceneChangeEvent change the enabled property
+ }
+
+ break;
+ }
default:
break;
}
- markDirty(AbstractRenderer::AllDirty);
BackendNode::sceneChangeEvent(e);
}
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index b89f21522..bea84a26e 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -501,6 +501,9 @@ void Renderer::setSceneRoot(QBackendNodeFactory *factory, Entity *sgRoot)
m_pickBoundingVolumeJob->setRoot(m_renderSceneRoot);
m_updateLevelOfDetailJob->setRoot(m_renderSceneRoot);
m_updateTreeEnabledJob->setRoot(m_renderSceneRoot);
+
+ // Set all flags to dirty
+ m_changeSet |= AbstractRenderer::AllDirty;
}
void Renderer::registerEventFilter(QEventFilterService *service)
@@ -578,14 +581,8 @@ void Renderer::doRender()
submissionStatsPart2.jobId.typeAndInstance[1] = 0;
submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
#endif
- if (canRender()) {
- // Clear all dirty flags but Compute so that
- // we still render every frame when a compute shader is used in a scene
- BackendNodeDirtySet changesToUnset = m_changeSet;
- if (changesToUnset.testFlag(Renderer::ComputeDirty))
- changesToUnset.setFlag(Renderer::ComputeDirty, false);
- clearDirtyBits(changesToUnset);
+ if (canRender()) {
{ // Scoped to destroy surfaceLock
QSurface *surface = nullptr;
for (const Render::RenderView *rv: renderViews) {
@@ -1405,22 +1402,28 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_pickBoundingVolumeJob->setKeyEvents(pendingKeyEvents());
m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
- // Set dependencies of resource gatherer
- for (const QAspectJobPtr &jobPtr : renderBinJobs) {
- jobPtr->addDependency(m_bufferGathererJob);
- jobPtr->addDependency(m_textureGathererJob);
- jobPtr->addDependency(m_shaderGathererJob);
- }
// Add jobs
- renderBinJobs.push_back(m_updateShaderDataTransformJob);
- renderBinJobs.push_back(m_updateMeshTriangleListJob);
- renderBinJobs.push_back(m_updateTreeEnabledJob);
+ if (dirtyBits() & AbstractRenderer::EntityEnabledDirty)
+ renderBinJobs.push_back(m_updateTreeEnabledJob);
+
+ if (dirtyBits() & AbstractRenderer::TransformDirty) {
+ renderBinJobs.push_back(m_worldTransformJob);
+ renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
+ renderBinJobs.push_back(m_updateShaderDataTransformJob);
+ }
+
+ if (dirtyBits() & AbstractRenderer::GeometryDirty) {
+ renderBinJobs.push_back(m_calculateBoundingVolumeJob);
+ renderBinJobs.push_back(m_updateMeshTriangleListJob);
+ }
+
+ if (dirtyBits() & AbstractRenderer::GeometryDirty ||
+ dirtyBits() & AbstractRenderer::TransformDirty) {
+ renderBinJobs.push_back(m_expandBoundingVolumeJob);
+ }
+
renderBinJobs.push_back(m_updateLevelOfDetailJob);
- renderBinJobs.push_back(m_expandBoundingVolumeJob);
- renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
- renderBinJobs.push_back(m_calculateBoundingVolumeJob);
- renderBinJobs.push_back(m_worldTransformJob);
renderBinJobs.push_back(m_cleanupJob);
renderBinJobs.push_back(m_sendRenderCaptureJob);
renderBinJobs.push_back(m_sendBufferCaptureJob);
@@ -1428,11 +1431,18 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
renderBinJobs.append(bufferJobs);
// Jobs to prepare GL Resource upload
- renderBinJobs.push_back(m_syncTextureLoadingJob);
renderBinJobs.push_back(m_vaoGathererJob);
- renderBinJobs.push_back(m_bufferGathererJob);
- renderBinJobs.push_back(m_textureGathererJob);
- renderBinJobs.push_back(m_shaderGathererJob);
+
+ if (dirtyBits() & AbstractRenderer::BuffersDirty)
+ renderBinJobs.push_back(m_bufferGathererJob);
+
+ if (dirtyBits() & AbstractRenderer::ShadersDirty)
+ renderBinJobs.push_back(m_shaderGathererJob);
+
+ if (dirtyBits() & AbstractRenderer::TexturesDirty) {
+ renderBinJobs.push_back(m_syncTextureLoadingJob);
+ renderBinJobs.push_back(m_textureGathererJob);
+ }
QMutexLocker lock(&m_renderQueueMutex);
if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case)
@@ -1454,6 +1464,17 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_renderQueue->setTargetRenderViewCount(fgBranchCount);
}
+ // Clear dirty bits
+ BackendNodeDirtySet changesToUnset = dirtyBits();
+ // TO DO: When secondary GL thread is integrated, the following line can be removed
+ changesToUnset.setFlag(AbstractRenderer::ShadersDirty, false);
+
+ // 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);
+
return renderBinJobs;
}
diff --git a/src/render/backend/rendersettings_p.h b/src/render/backend/rendersettings_p.h
index bfd2c21b2..960edee29 100644
--- a/src/render/backend/rendersettings_p.h
+++ b/src/render/backend/rendersettings_p.h
@@ -75,6 +75,10 @@ public:
QPickingSettings::PickResultMode pickResultMode() const { return m_pickResultMode; }
QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode() const { return m_faceOrientationPickingMode; }
float pickWorldSpaceTolerance() const { return m_pickWorldSpaceTolerance; }
+
+ // For unit test purposes
+ void setActiveFrameGraphId(Qt3DCore::QNodeId frameGraphNodeId) { m_activeFrameGraph = frameGraphNodeId; }
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
diff --git a/src/render/framegraph/viewportnode_p.h b/src/render/framegraph/viewportnode_p.h
index 85003ff36..18adc3f0c 100644
--- a/src/render/framegraph/viewportnode_p.h
+++ b/src/render/framegraph/viewportnode_p.h
@@ -64,7 +64,7 @@ namespace Render {
class Renderer;
-class ViewportNode : public FrameGraphNode
+class Q_AUTOTEST_EXPORT ViewportNode : public FrameGraphNode
{
public:
ViewportNode();
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index 55c86910f..3498e2c36 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -178,7 +178,7 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
} else if (propertyName == QByteArrayLiteral("syncData")) {
m_syncData = propertyChange->value().toBool();
}
- markDirty(AbstractRenderer::AllDirty);
+ markDirty(AbstractRenderer::BuffersDirty);
}
BackendNode::sceneChangeEvent(e);
}
diff --git a/src/render/geometry/geometry.cpp b/src/render/geometry/geometry.cpp
index 2eebb8222..49205958c 100644
--- a/src/render/geometry/geometry.cpp
+++ b/src/render/geometry/geometry.cpp
@@ -112,7 +112,7 @@ void Geometry::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
default:
break;
}
- markDirty(AbstractRenderer::AllDirty);
+ markDirty(AbstractRenderer::GeometryDirty);
BackendNode::sceneChangeEvent(e);
}
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index 4f5432e1d..d69cbcbd9 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -175,7 +175,7 @@ void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
break;
}
- markDirty(AbstractRenderer::AllDirty);
+ markDirty(AbstractRenderer::GeometryDirty);
BackendNode::sceneChangeEvent(e);
diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp
index 915ca1d54..9803aa008 100644
--- a/src/render/materialsystem/shader.cpp
+++ b/src/render/materialsystem/shader.cpp
@@ -190,7 +190,7 @@ void Shader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
setStatus(QShaderProgram::NotReady);
updateDNA();
}
- markDirty(AbstractRenderer::AllDirty);
+ markDirty(AbstractRenderer::ShadersDirty);
}
BackendNode::sceneChangeEvent(e);
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index 21f29d0b6..ecaf287b2 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -250,7 +250,7 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
addDirtyFlag(dirty);
- markDirty(AbstractRenderer::AllDirty);
+ markDirty(AbstractRenderer::TexturesDirty);
BackendNode::sceneChangeEvent(e);
}