From b8435ca421d5612afabec1d717ea0a29be8a9c5c Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 15:58:20 +0200 Subject: Update QShaderProgram to use direct sync Change-Id: I71cac1345ed7b9e14b8cdc479c60f0384bb0b198 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/materialsystem/shader.cpp | 56 ++++++++++----------------------- src/render/materialsystem/shader_p.h | 4 +-- tests/auto/render/shader/tst_shader.cpp | 52 ++++++++++++------------------ 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(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer>::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>(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(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(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(); - 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 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 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 m_uniformsNames; QVector m_uniformsNamesIds; QVector 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("property"); QTest::addColumn("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); -- cgit v1.2.3