diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2018-10-10 12:20:00 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2018-12-14 13:26:57 +0000 |
commit | d403604d74780b6bf2a7dee235942a2c9a9305d2 (patch) | |
tree | c943f63d6327d0a9451f8c1fb924dc0bd1d7b055 | |
parent | e3fbebe61111dfe670ffe19c96e313157df7331f (diff) |
QShaderProgramBuilder: add properties to access generated shader code
Change-Id: Ib4d448198b2f53850ff0c9b1f2ff4d2d905eea26
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
7 files changed, 382 insertions, 3 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp index 4c8e2c0ca..d57c8c01f 100644 --- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp +++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp @@ -180,6 +180,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri) qmlRegisterType<Qt3DRender::QShaderProgram>(uri, 2, 0, "ShaderProgram"); qmlRegisterType<Qt3DRender::QShaderProgram, 9>(uri, 2, 9, "ShaderProgram"); qmlRegisterType<Qt3DRender::QShaderProgramBuilder>(uri, 2, 10, "ShaderProgramBuilder"); + qmlRegisterType<Qt3DRender::QShaderProgramBuilder>(uri, 2, 13, "ShaderProgramBuilder"); qmlRegisterUncreatableType<Qt3DRender::QShaderData>(uri, 2, 0, "QShaderData", "Quick3D should instantiate Quick3DShaderData only"); qmlRegisterType<Qt3DRender::Render::Quick::Quick3DShaderDataArray>(uri, 2, 0, "ShaderDataArray"); qmlRegisterType<Qt3DRender::Render::Quick::Quick3DShaderData>(uri, 2, 0, "ShaderData"); diff --git a/src/render/materialsystem/qshaderprogrambuilder.cpp b/src/render/materialsystem/qshaderprogrambuilder.cpp index 9318f96af..84dd33372 100644 --- a/src/render/materialsystem/qshaderprogrambuilder.cpp +++ b/src/render/materialsystem/qshaderprogrambuilder.cpp @@ -94,6 +94,53 @@ QShaderProgramBuilder::QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Q { } +void QShaderProgramBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QShaderProgramBuilder); + if (change->type() == Qt3DCore::PropertyUpdated) { + const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); + if (e->propertyName() == QByteArrayLiteral("generatedShaderCode")) { + const bool blocked = blockNotifications(true); + const QPair<int, QByteArray> data = e->value().value<QPair<int, QByteArray>>(); + + switch (data.first) { + case QShaderProgram::Vertex: { + d->m_vertexShaderCode = data.second; + emit vertexShaderCodeChanged(d->m_vertexShaderCode); + break; + } + case QShaderProgram::Fragment:{ + d->m_fragmentShaderCode = data.second; + emit fragmentShaderCodeChanged(d->m_fragmentShaderCode); + break; + } + case QShaderProgram::Geometry: { + d->m_geometryShaderCode = data.second; + emit geometryShaderCodeChanged(d->m_geometryShaderCode); + break; + } + case QShaderProgram::Compute: { + d->m_computeShaderCode = data.second; + emit computeShaderCodeChanged(d->m_computeShaderCode); + break; + } + case QShaderProgram::TessellationControl: { + d->m_tessControlShaderCode = data.second; + emit tessellationControlShaderCodeChanged(d->m_tessControlShaderCode); + break; + } + case QShaderProgram::TessellationEvaluation: { + d->m_tessEvalShaderCode = data.second; + emit tessellationEvaluationShaderCodeChanged(d->m_tessEvalShaderCode); + break; + } + } + + blockNotifications(blocked); + } + } +} + /*! \qmlproperty string ShaderProgramBuilder::shaderProgram @@ -311,6 +358,114 @@ QUrl QShaderProgramBuilder::computeShaderGraph() const return d->m_computeShaderGraph; } +/*! + \qmlproperty string ShaderProgramBuilder:vertexShaderCode + + Holds the generated vertex shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:vertexShaderCode + + Holds the generate vertex shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::vertexShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_vertexShaderCode; +} + +/*! + \qmlproperty string ShaderProgramBuilder:tessellationControlShaderCode + + Holds the generated tessellation control shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:tessellationControlShaderCode + + Holds the generate tessellation control shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::tessellationControlShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_tessControlShaderCode; +} + +/*! + \qmlproperty string ShaderProgramBuilder:tessellationEvaluationShaderCode + + Holds the generated tessellation evaluation shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:tessellationEvaluationShaderCode + + Holds the generate tessellation evaluation shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::tessellationEvaluationShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_tessEvalShaderCode; +} + +/*! + \qmlproperty string ShaderProgramBuilder:geometryShaderCode + + Holds the generated geometry shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:geometryShaderCode + + Holds the generate geometry shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::geometryShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_geometryShaderCode; +} + +/*! + \qmlproperty string ShaderProgramBuilder::fragmentShaderCode + + Holds the generated fragment shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:fragmentShaderCode + + Holds the generate fragment shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::fragmentShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_fragmentShaderCode; +} + +/*! + \qmlproperty string ShaderProgramBuilder::computeShaderCode + + Holds the generated compute shader code + \since 2.13 +*/ +/*! + \property QShaderProgram:Builder:computeShaderCode + + Holds the generate compute shader code. + \since 5.13 +*/ +QByteArray QShaderProgramBuilder::computeShaderCode() const +{ + Q_D(const QShaderProgramBuilder); + return d->m_computeShaderCode; +} + Qt3DCore::QNodeCreatedChangeBasePtr QShaderProgramBuilder::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QShaderProgramBuilderData>::create(this); diff --git a/src/render/materialsystem/qshaderprogrambuilder.h b/src/render/materialsystem/qshaderprogrambuilder.h index fbbf7c752..532aa7d73 100644 --- a/src/render/materialsystem/qshaderprogrambuilder.h +++ b/src/render/materialsystem/qshaderprogrambuilder.h @@ -63,6 +63,12 @@ class QT3DRENDERSHARED_EXPORT QShaderProgramBuilder : public Qt3DCore::QNode Q_PROPERTY(QUrl geometryShaderGraph READ geometryShaderGraph WRITE setGeometryShaderGraph NOTIFY geometryShaderGraphChanged) Q_PROPERTY(QUrl fragmentShaderGraph READ fragmentShaderGraph WRITE setFragmentShaderGraph NOTIFY fragmentShaderGraphChanged) Q_PROPERTY(QUrl computeShaderGraph READ computeShaderGraph WRITE setComputeShaderGraph NOTIFY computeShaderGraphChanged) + Q_PROPERTY(QByteArray vertexShaderCode READ vertexShaderCode NOTIFY vertexShaderCodeChanged REVISION 13) + Q_PROPERTY(QByteArray tessellationControlShaderCode READ tessellationControlShaderCode NOTIFY tessellationControlShaderCodeChanged REVISION 13) + Q_PROPERTY(QByteArray tessellationEvaluationShaderCode READ tessellationEvaluationShaderCode NOTIFY tessellationEvaluationShaderCodeChanged REVISION 13) + Q_PROPERTY(QByteArray geometryShaderCode READ geometryShaderCode NOTIFY geometryShaderCodeChanged REVISION 13) + Q_PROPERTY(QByteArray fragmentShaderCode READ fragmentShaderCode NOTIFY fragmentShaderCodeChanged REVISION 13) + Q_PROPERTY(QByteArray computeShaderCode READ computeShaderCode NOTIFY computeShaderCodeChanged REVISION 13) public: explicit QShaderProgramBuilder(Qt3DCore::QNode *parent = nullptr); @@ -76,6 +82,12 @@ public: QUrl geometryShaderGraph() const; QUrl fragmentShaderGraph() const; QUrl computeShaderGraph() const; + QByteArray vertexShaderCode() const; + QByteArray tessellationControlShaderCode() const; + QByteArray tessellationEvaluationShaderCode() const; + QByteArray geometryShaderCode() const; + QByteArray fragmentShaderCode() const; + QByteArray computeShaderCode() const; public Q_SLOTS: void setShaderProgram(Qt3DRender::QShaderProgram *program); @@ -96,9 +108,16 @@ Q_SIGNALS: void geometryShaderGraphChanged(const QUrl &geometryShaderGraph); void fragmentShaderGraphChanged(const QUrl &fragmentShaderGraph); void computeShaderGraphChanged(const QUrl &computeShaderGraph); + void vertexShaderCodeChanged(const QByteArray &vertexShaderCode); + void tessellationControlShaderCodeChanged(const QByteArray &tessellationControlShaderCode); + void tessellationEvaluationShaderCodeChanged(const QByteArray &tessellationEvaluationShaderCode); + void geometryShaderCodeChanged(const QByteArray &geometryShaderCode); + void fragmentShaderCodeChanged(const QByteArray &fragmentShaderCode); + void computeShaderCodeChanged(const QByteArray &computeShaderCode); protected: explicit QShaderProgramBuilder(QShaderProgramBuilderPrivate &dd, Qt3DCore::QNode *parent = nullptr); + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: Q_DECLARE_PRIVATE(QShaderProgramBuilder) diff --git a/src/render/materialsystem/qshaderprogrambuilder_p.h b/src/render/materialsystem/qshaderprogrambuilder_p.h index e1b470229..2ac765a1d 100644 --- a/src/render/materialsystem/qshaderprogrambuilder_p.h +++ b/src/render/materialsystem/qshaderprogrambuilder_p.h @@ -74,6 +74,12 @@ public: QUrl m_geometryShaderGraph; QUrl m_fragmentShaderGraph; QUrl m_computeShaderGraph; + QByteArray m_vertexShaderCode; + QByteArray m_tessControlShaderCode; + QByteArray m_tessEvalShaderCode; + QByteArray m_geometryShaderCode; + QByteArray m_fragmentShaderCode; + QByteArray m_computeShaderCode; }; struct QShaderProgramBuilderData diff --git a/src/render/materialsystem/shaderbuilder.cpp b/src/render/materialsystem/shaderbuilder.cpp index 283866d68..e0683332f 100644 --- a/src/render/materialsystem/shaderbuilder.cpp +++ b/src/render/materialsystem/shaderbuilder.cpp @@ -40,6 +40,7 @@ #include "shaderbuilder_p.h" #include <Qt3DRender/private/qshaderprogrambuilder_p.h> +#include <Qt3DRender/qshaderprogram.h> #include <Qt3DRender/private/qurlhelper_p.h> #include <QtGui/private/qshaderformat_p.h> @@ -111,6 +112,31 @@ using namespace Qt3DCore; namespace Qt3DRender { namespace Render { + +namespace { + +QShaderProgram::ShaderType toQShaderProgramType(ShaderBuilder::ShaderType type) +{ + switch (type) { + case ShaderBuilder::ShaderType::Vertex: + return QShaderProgram::Vertex; + case ShaderBuilder::ShaderType::TessellationControl: + return QShaderProgram::TessellationControl; + case ShaderBuilder::ShaderType::TessellationEvaluation: + return QShaderProgram::TessellationEvaluation; + case ShaderBuilder::ShaderType::Geometry: + return QShaderProgram::Geometry; + case ShaderBuilder::ShaderType::Fragment: + return QShaderProgram::Fragment; + case ShaderBuilder::ShaderType::Compute: + return QShaderProgram::Compute; + default: + Q_UNREACHABLE(); + } +} + +} // anonymous + QString ShaderBuilder::getPrototypesFile() { return qt3dGlobalShaderPrototypes->prototypesFile(); @@ -284,6 +310,13 @@ void ShaderBuilder::generateCode(ShaderBuilder::ShaderType type) const auto code = generator.createShaderCode(m_enabledLayers); m_codes.insert(type, deincludify(code, graphPath + QStringLiteral(".glsl"))); m_dirtyTypes.remove(type); + + // Send notification to the frontend + Qt3DCore::QPropertyUpdatedChangePtr propertyChange = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + propertyChange->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + propertyChange->setPropertyName("generatedShaderCode"); + propertyChange->setValue(QVariant::fromValue(qMakePair(int(toQShaderProgramType(type)), m_codes.value(type)))); + notifyObservers(propertyChange); } void ShaderBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) diff --git a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp index 93bee22cc..021a3d6c1 100644 --- a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp +++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp @@ -38,12 +38,12 @@ #include <Qt3DCore/qnodecreatedchange.h> #include "testpostmanarbiter.h" -class tst_QShaderProgramBuilder : public QObject +class tst_QShaderProgramBuilder : public Qt3DRender::QShaderProgramBuilder { Q_OBJECT public: tst_QShaderProgramBuilder() - : QObject() + : Qt3DRender::QShaderProgramBuilder() { qRegisterMetaType<Qt3DRender::QShaderProgram*>("Qt3DRender::QShaderProgram*"); } @@ -63,6 +63,12 @@ private Q_SLOTS: QCOMPARE(builder.geometryShaderGraph(), QUrl()); QCOMPARE(builder.fragmentShaderGraph(), QUrl()); QCOMPARE(builder.computeShaderGraph(), QUrl()); + QCOMPARE(builder.vertexShaderCode(), QByteArray()); + QCOMPARE(builder.fragmentShaderCode(), QByteArray()); + QCOMPARE(builder.computeShaderCode(), QByteArray()); + QCOMPARE(builder.geometryShaderCode(), QByteArray()); + QCOMPARE(builder.tessellationEvaluationShaderCode(), QByteArray()); + QCOMPARE(builder.tessellationControlShaderCode(), QByteArray()); } void checkPropertyChanges() @@ -592,8 +598,90 @@ private Q_SLOTS: // THEN QCOMPARE(arbiter.events.size(), 0); } + } + + void checkGeneratedCodePropertyUpdates() + { + { + // WHEN + QSignalSpy spy(this, SIGNAL(vertexShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Vertex), QByteArrayLiteral("vertex")))); + sceneChangeEvent(valueChange); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(vertexShaderCode(), QByteArrayLiteral("vertex")); + } + { + // WHEN + QSignalSpy spy(this, SIGNAL(fragmentShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Fragment), QByteArrayLiteral("fragment")))); + sceneChangeEvent(valueChange); + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(fragmentShaderCode(), QByteArrayLiteral("fragment")); + } + { + // WHEN + QSignalSpy spy(this, SIGNAL(geometryShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Geometry), QByteArrayLiteral("geometry")))); + sceneChangeEvent(valueChange); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(geometryShaderCode(), QByteArrayLiteral("geometry")); + } + { + // WHEN + QSignalSpy spy(this, SIGNAL(computeShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Compute), QByteArrayLiteral("compute")))); + sceneChangeEvent(valueChange); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(computeShaderCode(), QByteArrayLiteral("compute")); + } + { + // WHEN + QSignalSpy spy(this, SIGNAL(tessellationControlShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationControl), QByteArrayLiteral("control")))); + sceneChangeEvent(valueChange); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(tessellationControlShaderCode(), QByteArrayLiteral("control")); + } + { + // WHEN + QSignalSpy spy(this, SIGNAL(tessellationEvaluationShaderCodeChanged(QByteArray))); + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("generatedShaderCode"); + valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationEvaluation), QByteArrayLiteral("eval")))); + sceneChangeEvent(valueChange); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(tessellationEvaluationShaderCode(), QByteArrayLiteral("eval")); + } } + }; QTEST_MAIN(tst_QShaderProgramBuilder) diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp index 6557acb6c..007bfac7c 100644 --- a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp +++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp @@ -28,12 +28,15 @@ #include <QtTest/QTest> #include <qbackendnodetester.h> +#include <Qt3DCore/private/qbackendnode_p.h> #include <Qt3DRender/private/shaderbuilder_p.h> #include <Qt3DRender/qshaderprogram.h> #include <Qt3DRender/qshaderprogrambuilder.h> #include "testrenderer.h" +#include "testpostmanarbiter.h" Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderBuilder::ShaderType) +Q_DECLARE_METATYPE(Qt3DRender::QShaderProgram::ShaderType) class tst_ShaderBuilder : public Qt3DCore::QBackendNodeTester { @@ -539,7 +542,81 @@ private slots: // THEN QCOMPARE(backend.shaderGraph(type), graphUrl); QVERIFY(!backend.isShaderCodeDirty(type)); -// QCOMPARE(backend.shaderCode(type), es2Code); + QCOMPARE(backend.shaderCode(type), es2Code); + } + + void checkCodeUpdatedNotification_data() + { + QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type"); + QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("notificationType"); + + QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex << Qt3DRender::QShaderProgram::Vertex; + QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl << Qt3DRender::QShaderProgram::TessellationControl; + QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation << Qt3DRender::QShaderProgram::TessellationEvaluation; + QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry << Qt3DRender::QShaderProgram::Geometry; + QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment << Qt3DRender::QShaderProgram::Fragment; + QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute << Qt3DRender::QShaderProgram::Compute; + } + + + void checkCodeUpdatedNotification() + { + // GIVEN + Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json"); + QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty()); + QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type); + QFETCH(Qt3DRender::QShaderProgram::ShaderType, notificationType); + + const auto gl3Api = []{ + auto api = Qt3DRender::GraphicsApiFilterData(); + api.m_api = Qt3DRender::QGraphicsApiFilter::OpenGL; + api.m_profile = Qt3DRender::QGraphicsApiFilter::CoreProfile; + api.m_major = 3; + api.m_minor = 2; + return api; + }(); + + const auto readCode = [](const QString &suffix) -> QString { + const auto filePath = QStringLiteral(":/output.") + suffix; + QFile file(filePath); + if (!file.open(QFile::ReadOnly | QFile::Text)) + qFatal("File open failed: %s", qPrintable(filePath)); + return file.readAll(); + }; + + const auto gl3Code = readCode("gl3"); + + Qt3DRender::Render::ShaderBuilder backend; + TestArbiter arbiter; + Qt3DCore::QBackendNodePrivate::get(&backend)->setArbiter(&arbiter); + + + // WHEN + const auto graphUrl = QUrl::fromEncoded("qrc:/input.json"); + backend.setShaderGraph(type, graphUrl); + + // THEN + QCOMPARE(backend.shaderGraph(type), graphUrl); + QVERIFY(backend.isShaderCodeDirty(type)); + QVERIFY(backend.shaderCode(type).isEmpty()); + + // WHEN + backend.setGraphicsApi(gl3Api); + backend.generateCode(type); + + // THEN + QCOMPARE(backend.shaderGraph(type), graphUrl); + QVERIFY(!backend.isShaderCodeDirty(type)); + QCOMPARE(backend.shaderCode(type), gl3Code); + + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(arbiter.events.count(), 1); + QCOMPARE(change->propertyName(), "generatedShaderCode"); + const QPair<int, QByteArray> value = change->value().value<QPair<int, QByteArray>>(); + QCOMPARE(value.first, int(notificationType)); + QCOMPARE(value.second, gl3Code); + + arbiter.events.clear(); } }; |