summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-09-19 15:58:20 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-09-26 14:22:12 +0200
commitb8435ca421d5612afabec1d717ea0a29be8a9c5c (patch)
treed614990af1a0905875dbde114955f6aa082fd773
parent29dc5ced83b9d992ca533711d25ab31ebe984ee4 (diff)
Update QShaderProgram to use direct sync
Change-Id: I71cac1345ed7b9e14b8cdc479c60f0384bb0b198 Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r--src/render/frontend/qrenderaspect.cpp2
-rw-r--r--src/render/materialsystem/shader.cpp56
-rw-r--r--src/render/materialsystem/shader_p.h4
-rw-r--r--tests/auto/render/shader/tst_shader.cpp52
4 files changed, 39 insertions, 75 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index ec8664e2b..804dbef6c 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -289,7 +289,7 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QParameter, true>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer));
q->registerBackendType<QRenderPass, true>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer));
q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers));
- q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer));
+ q->registerBackendType<QShaderProgram, true>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer));
q->registerBackendType<QShaderProgramBuilder>(QSharedPointer<Render::NodeFunctor<Render::ShaderBuilder, Render::ShaderBuilderManager> >::create(m_renderer));
q->registerBackendType<QTechnique, true>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<QShaderImage, true>(QSharedPointer<Render::NodeFunctor<Render::ShaderImage, Render::ShaderImageManager>>::create(m_renderer));
diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp
index d42b0dda7..f35fba9fa 100644
--- a/src/render/materialsystem/shader.cpp
+++ b/src/render/materialsystem/shader.cpp
@@ -101,23 +101,24 @@ void Shader::cleanup()
m_status = QShaderProgram::NotReady;
}
-void Shader::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void Shader::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
{
- const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QShaderProgramData>>(change);
- const auto &data = typedChange->data;
-
- for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i)
- m_shaderCode[i].clear();
-
- m_shaderCode[QShaderProgram::Vertex] = data.vertexShaderCode;
- m_shaderCode[QShaderProgram::TessellationControl] = data.tessellationControlShaderCode;
- m_shaderCode[QShaderProgram::TessellationEvaluation] = data.tessellationEvaluationShaderCode;
- m_shaderCode[QShaderProgram::Geometry] = data.geometryShaderCode;
- m_shaderCode[QShaderProgram::Fragment] = data.fragmentShaderCode;
- m_shaderCode[QShaderProgram::Compute] = data.computeShaderCode;
- m_isLoaded = false;
- updateDNA();
- markDirty(AbstractRenderer::ShadersDirty);
+ const QShaderProgram *node = qobject_cast<const QShaderProgram *>(frontEnd);
+ if (!node)
+ return;
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+
+ if (firstTime)
+ for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i)
+ m_shaderCode[i].clear();
+
+ for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) {
+ const QShaderProgram::ShaderType shaderType = static_cast<QShaderProgram::ShaderType>(i);
+ const QByteArray code = node->shaderCode(shaderType);
+ if (code != m_shaderCode.value(shaderType))
+ setShaderCode(shaderType, code);
+ }
}
void Shader::setGraphicsContext(GraphicsContext *context)
@@ -174,29 +175,6 @@ void Shader::setShaderCode(QShaderProgram::ShaderType type, const QByteArray &co
markDirty(AbstractRenderer::ShadersDirty);
}
-void Shader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- if (e->type() == PropertyUpdated) {
- QPropertyUpdatedChangePtr propertyChange = e.staticCast<QPropertyUpdatedChange>();
- QVariant propertyValue = propertyChange->value();
-
- if (propertyChange->propertyName() == QByteArrayLiteral("vertexShaderCode"))
- setShaderCode(QShaderProgram::Vertex, propertyValue.toByteArray());
- else if (propertyChange->propertyName() == QByteArrayLiteral("fragmentShaderCode"))
- setShaderCode(QShaderProgram::Fragment, propertyValue.toByteArray());
- else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationControlShaderCode"))
- setShaderCode(QShaderProgram::TessellationControl, propertyValue.toByteArray());
- else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationEvaluationShaderCode"))
- setShaderCode(QShaderProgram::TessellationEvaluation, propertyValue.toByteArray());
- else if (propertyChange->propertyName() == QByteArrayLiteral("geometryShaderCode"))
- setShaderCode(QShaderProgram::Geometry, propertyValue.toByteArray());
- else if (propertyChange->propertyName() == QByteArrayLiteral("computeShaderCode"))
- setShaderCode(QShaderProgram::Compute, propertyValue.toByteArray());
- }
-
- BackendNode::sceneChangeEvent(e);
-}
-
QHash<QString, ShaderUniform> Shader::activeUniformsForUniformBlock(int blockIndex) const
{
return m_uniformBlockIndexToShaderUniforms.value(blockIndex);
diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h
index 9eb24904c..f8cdde3b7 100644
--- a/src/render/materialsystem/shader_p.h
+++ b/src/render/materialsystem/shader_p.h
@@ -99,7 +99,7 @@ public:
QVector<QByteArray> shaderCode() const;
void setShaderCode(QShaderProgram::ShaderType type, const QByteArray &code);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
+ void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
bool isLoaded() const { QMutexLocker lock(&m_mutex); return m_isLoaded; }
void setLoaded(bool loaded) { QMutexLocker lock(&m_mutex); m_isLoaded = loaded; }
ProgramDNA dna() const Q_DECL_NOTHROW { return m_dna; }
@@ -126,8 +126,6 @@ public:
inline bool hasPendingNotifications() const { return !m_pendingNotifications.empty(); }
private:
- void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
-
QVector<QString> m_uniformsNames;
QVector<int> m_uniformsNamesIds;
QVector<ShaderUniform> m_uniforms;
diff --git a/tests/auto/render/shader/tst_shader.cpp b/tests/auto/render/shader/tst_shader.cpp
index 067db55e7..bfebe2467 100644
--- a/tests/auto/render/shader/tst_shader.cpp
+++ b/tests/auto/render/shader/tst_shader.cpp
@@ -97,7 +97,7 @@ void tst_RenderShader::matchesFrontendPeer()
Qt3DRender::Render::Shader backend;
backend.setRenderer(&renderer);
- simulateInitialization(frontend.data(), &backend);
+ simulateInitializationSync(frontend.data(), &backend);
QCOMPARE(backend.isLoaded(), false);
QVERIFY(backend.dna() != 0U);
@@ -113,7 +113,7 @@ void tst_RenderShader::cleanupLeavesACoherentState()
Qt3DRender::Render::Shader shader;
shader.setRenderer(&renderer);
- simulateInitialization(frontend.data(), &shader);
+ simulateInitializationSync(frontend.data(), &shader);
shader.cleanup();
@@ -130,73 +130,61 @@ void tst_RenderShader::cleanupLeavesACoherentState()
void tst_RenderShader::dealWithPropertyChanges_data()
{
- QTest::addColumn<QByteArray>("property");
QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("type");
- QTest::newRow("vertex") << QByteArrayLiteral("vertexShaderCode")
- << Qt3DRender::QShaderProgram::Vertex;
+ QTest::newRow("vertex") << Qt3DRender::QShaderProgram::Vertex;
- QTest::newRow("tessControl") << QByteArrayLiteral("tessellationControlShaderCode")
- << Qt3DRender::QShaderProgram::TessellationControl;
+ QTest::newRow("tessControl") << Qt3DRender::QShaderProgram::TessellationControl;
- QTest::newRow("tessEval") << QByteArrayLiteral("tessellationEvaluationShaderCode")
- << Qt3DRender::QShaderProgram::TessellationEvaluation;
+ QTest::newRow("tessEval") << Qt3DRender::QShaderProgram::TessellationEvaluation;
- QTest::newRow("geometry") << QByteArrayLiteral("geometryShaderCode")
- << Qt3DRender::QShaderProgram::Geometry;
+ QTest::newRow("geometry") << Qt3DRender::QShaderProgram::Geometry;
- QTest::newRow("fragment") << QByteArrayLiteral("fragmentShaderCode")
- << Qt3DRender::QShaderProgram::Fragment;
+ QTest::newRow("fragment") << Qt3DRender::QShaderProgram::Fragment;
- QTest::newRow("compute") << QByteArrayLiteral("computeShaderCode")
- << Qt3DRender::QShaderProgram::Compute;
+ QTest::newRow("compute") << Qt3DRender::QShaderProgram::Compute;
}
void tst_RenderShader::dealWithPropertyChanges()
{
// GIVEN
- QFETCH(QByteArray, property);
QFETCH(Qt3DRender::QShaderProgram::ShaderType, type);
Qt3DRender::Render::Shader backend;
+ Qt3DRender::QShaderProgram shader;
backend.setLoaded(true);
TestRenderer renderer;
backend.setRenderer(&renderer);
+ simulateInitializationSync(&shader, &backend);
// WHEN
- auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
- updateChange->setValue(QStringLiteral("foo"));
- updateChange->setPropertyName(property);
- backend.sceneChangeEvent(updateChange);
+ shader.setShaderCode(type, QByteArrayLiteral("foo"));
+ backend.syncFromFrontEnd(&shader, false);
// THEN
- QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("foo"));
QVERIFY(!backend.isLoaded());
QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
renderer.resetDirty();
backend.setLoaded(true);
// WHEN
- updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
- updateChange->setValue(QStringLiteral("foo"));
- updateChange->setPropertyName(property);
- backend.sceneChangeEvent(updateChange);
+ shader.setShaderCode(type, QByteArrayLiteral("foo"));
+ backend.syncFromFrontEnd(&shader, false);
// THEN
- QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("foo"));
QVERIFY(backend.isLoaded());
QCOMPARE(renderer.dirtyBits(), 0);
renderer.resetDirty();
backend.setLoaded(true);
// WHEN
- updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
- updateChange->setValue(QStringLiteral("bar"));
- updateChange->setPropertyName(property);
- backend.sceneChangeEvent(updateChange);
+ shader.setShaderCode(type, QByteArrayLiteral("bar"));
+ backend.syncFromFrontEnd(&shader, false);
// THEN
- QCOMPARE(backend.shaderCode().at(type), QStringLiteral("bar"));
+ QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("bar"));
QVERIFY(!backend.isLoaded());
QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
renderer.resetDirty();
@@ -216,7 +204,7 @@ void tst_RenderShader::checkSetRendererDirtyOnInitialization()
QCOMPARE(renderer.dirtyBits(), 0);
// WHEN
- simulateInitialization(frontend.data(), &shader);
+ simulateInitializationSync(frontend.data(), &shader);
// THEN
QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);