diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-10-08 08:08:21 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-14 08:04:40 +0200 |
commit | c8134efd470482e2254e7b232deb386828af5610 (patch) | |
tree | dda08eedc773b84b02b40660a61e987126815c7f | |
parent | ca48552bf2c150886fe1b064a061bb77bc76f230 (diff) |
Convert Shader/ShaderBuilder jobs to use direct sync
Change-Id: Ia56ba6176c86e34904611ae57e682ac9d52c79f7
Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r-- | src/render/materialsystem/qshaderprogrambuilder.cpp | 88 | ||||
-rw-r--r-- | src/render/materialsystem/qshaderprogrambuilder.h | 1 | ||||
-rw-r--r-- | src/render/materialsystem/qshaderprogrambuilder_p.h | 6 | ||||
-rw-r--r-- | src/render/materialsystem/shader.cpp | 38 | ||||
-rw-r--r-- | src/render/materialsystem/shader_p.h | 7 | ||||
-rw-r--r-- | src/render/materialsystem/shaderbuilder.cpp | 62 | ||||
-rw-r--r-- | src/render/materialsystem/shaderbuilder_p.h | 36 | ||||
-rw-r--r-- | src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp | 5 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer.cpp | 90 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer_p.h | 22 | ||||
-rw-r--r-- | tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp | 32 | ||||
-rw-r--r-- | tests/auto/render/shader/tst_shader.cpp | 2 | ||||
-rw-r--r-- | tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp | 148 |
13 files changed, 238 insertions, 299 deletions
diff --git a/src/render/materialsystem/qshaderprogrambuilder.cpp b/src/render/materialsystem/qshaderprogrambuilder.cpp index cafe23ee4..6613661d1 100644 --- a/src/render/materialsystem/qshaderprogrambuilder.cpp +++ b/src/render/materialsystem/qshaderprogrambuilder.cpp @@ -79,6 +79,47 @@ QShaderProgramBuilderPrivate::QShaderProgramBuilderPrivate() { } +void QShaderProgramBuilderPrivate::setShaderCode(const QByteArray &code, QShaderProgram::ShaderType type) +{ + Q_Q(QShaderProgramBuilder); + const bool blocked = q->blockNotifications(true); + + switch (type) { + case QShaderProgram::Vertex: { + m_vertexShaderCode = code; + emit q->vertexShaderCodeChanged(m_vertexShaderCode); + break; + } + case QShaderProgram::Fragment:{ + m_fragmentShaderCode = code; + emit q->fragmentShaderCodeChanged(m_fragmentShaderCode); + break; + } + case QShaderProgram::Geometry: { + m_geometryShaderCode = code; + emit q->geometryShaderCodeChanged(m_geometryShaderCode); + break; + } + case QShaderProgram::Compute: { + m_computeShaderCode = code; + emit q->computeShaderCodeChanged(m_computeShaderCode); + break; + } + case QShaderProgram::TessellationControl: { + m_tessControlShaderCode = code; + emit q->tessellationControlShaderCodeChanged(m_tessControlShaderCode); + break; + } + case QShaderProgram::TessellationEvaluation: { + m_tessEvalShaderCode = code; + emit q->tessellationEvaluationShaderCodeChanged(m_tessEvalShaderCode); + break; + } + } + + q->blockNotifications(blocked); +} + QShaderProgramBuilder::QShaderProgramBuilder(QNode *parent) : QNode(*new QShaderProgramBuilderPrivate, parent) { @@ -94,53 +135,6 @@ 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 diff --git a/src/render/materialsystem/qshaderprogrambuilder.h b/src/render/materialsystem/qshaderprogrambuilder.h index 184093730..5dc6b54ff 100644 --- a/src/render/materialsystem/qshaderprogrambuilder.h +++ b/src/render/materialsystem/qshaderprogrambuilder.h @@ -117,7 +117,6 @@ Q_SIGNALS: 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 2ac765a1d..22f8e6e58 100644 --- a/src/render/materialsystem/qshaderprogrambuilder_p.h +++ b/src/render/materialsystem/qshaderprogrambuilder_p.h @@ -52,6 +52,8 @@ // #include <private/qnode_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> +#include <Qt3DRender/qshaderprogram.h> #include <Qt3DRender/qshaderprogrambuilder.h> #include <QtCore/qurl.h> @@ -60,7 +62,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { -class QShaderProgramBuilderPrivate : public Qt3DCore::QNodePrivate +class Q_3DRENDERSHARED_PRIVATE_EXPORT QShaderProgramBuilderPrivate : public Qt3DCore::QNodePrivate { public: QShaderProgramBuilderPrivate(); @@ -80,6 +82,8 @@ public: QByteArray m_geometryShaderCode; QByteArray m_fragmentShaderCode; QByteArray m_computeShaderCode; + + void setShaderCode(const QByteArray &code, QShaderProgram::ShaderType type); }; struct QShaderProgramBuilderData diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index f35fba9fa..58709b37e 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -64,6 +64,7 @@ Shader::Shader() , m_dna(0) , m_graphicsContext(nullptr) , m_status(QShaderProgram::NotReady) + , m_requiresFrontendSync(false) { m_shaderCode.resize(static_cast<int>(QShaderProgram::Compute) + 1); } @@ -170,8 +171,9 @@ void Shader::setShaderCode(QShaderProgram::ShaderType type, const QByteArray &co m_shaderCode[type] = code; m_isLoaded = false; - setStatus(QShaderProgram::NotReady); + m_status = QShaderProgram::NotReady; updateDNA(); + m_requiresFrontendSync = true; markDirty(AbstractRenderer::ShadersDirty); } @@ -237,20 +239,13 @@ ShaderStorageBlock Shader::storageBlockForBlockName(const QString &blockName) return ShaderStorageBlock(); } -// To be called from a worker thread -void Shader::submitPendingNotifications() -{ - const QVector<Qt3DCore::QPropertyUpdatedChangePtr> notifications = std::move(m_pendingNotifications); - for (const Qt3DCore::QPropertyUpdatedChangePtr ¬ification : notifications) - notifyObservers(notification); -} - void Shader::prepareUniforms(ShaderParameterPack &pack) { const PackUniformHash &values = pack.uniforms(); auto it = values.cbegin(); const auto end = values.cend(); + while (it != end) { // Find if there's a uniform with the same name id for (const ShaderUniform &uniform : qAsConst(m_uniforms)) { @@ -412,32 +407,21 @@ void Shader::initializeFromReference(const Shader &other) m_shaderStorageBlockNames = other.m_shaderStorageBlockNames; m_shaderStorageBlocks = other.m_shaderStorageBlocks; m_isLoaded = other.m_isLoaded; - setStatus(other.status()); - setLog(other.log()); + m_status = other.m_status; + m_log = other.m_log; + m_requiresFrontendSync = true; } void Shader::setLog(const QString &log) { - if (log != m_log) { - m_log = log; - Qt3DCore::QPropertyUpdatedChangePtr e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("log"); - e->setValue(QVariant::fromValue(m_log)); - m_pendingNotifications.push_back(e); - } + m_log = log; + m_requiresFrontendSync = true; } void Shader::setStatus(QShaderProgram::Status status) { - if (status != m_status) { - m_status = status; - Qt3DCore::QPropertyUpdatedChangePtr e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("status"); - e->setValue(QVariant::fromValue(m_status)); - m_pendingNotifications.push_back(e); - } + m_status = status; + m_requiresFrontendSync = true; } } // namespace Render diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index f8cdde3b7..fe1a401d9 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -122,8 +122,8 @@ public: inline QString log() const { return m_log; } inline QShaderProgram::Status status() const { return m_status; } - void submitPendingNotifications(); - inline bool hasPendingNotifications() const { return !m_pendingNotifications.empty(); } + inline bool requiresFrontendSync() const { return m_requiresFrontendSync; } + inline void unsetRequiresFrontendSync() { m_requiresFrontendSync = false; } private: QVector<QString> m_uniformsNames; @@ -155,8 +155,7 @@ private: QMetaObject::Connection m_contextConnection; QString m_log; QShaderProgram::Status m_status; - - QVector<Qt3DCore::QPropertyUpdatedChangePtr> m_pendingNotifications; + bool m_requiresFrontendSync; void updateDNA(); diff --git a/src/render/materialsystem/shaderbuilder.cpp b/src/render/materialsystem/shaderbuilder.cpp index 6116ca56b..4e9327003 100644 --- a/src/render/materialsystem/shaderbuilder.cpp +++ b/src/render/materialsystem/shaderbuilder.cpp @@ -115,31 +115,6 @@ 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(); @@ -191,7 +166,7 @@ void ShaderBuilder::setEnabledLayers(const QStringList &layers) m_enabledLayers = layers; - for (QHash<ShaderType, QUrl>::const_iterator it = m_graphs.cbegin(); it != m_graphs.cend(); ++it) { + for (auto it = m_graphs.cbegin(); it != m_graphs.cend(); ++it) { if (!it.value().isEmpty()) m_dirtyTypes.insert(it.key()); } @@ -208,18 +183,18 @@ void ShaderBuilder::setGraphicsApi(const GraphicsApiFilterData &graphicsApi) return; m_graphicsApi = graphicsApi; - for (QHash<ShaderType, QUrl>::const_iterator it = m_graphs.cbegin(); it != m_graphs.cend(); ++it) { + for (auto it = m_graphs.cbegin(); it != m_graphs.cend(); ++it) { if (!it.value().isEmpty()) m_dirtyTypes.insert(it.key()); } } -QUrl ShaderBuilder::shaderGraph(ShaderBuilder::ShaderType type) const +QUrl ShaderBuilder::shaderGraph(QShaderProgram::ShaderType type) const { return m_graphs.value(type); } -void ShaderBuilder::setShaderGraph(ShaderBuilder::ShaderType type, const QUrl &url) +void ShaderBuilder::setShaderGraph(QShaderProgram::ShaderType type, const QUrl &url) { if (url != m_graphs.value(type)) { m_graphs.insert(type, url); @@ -227,17 +202,17 @@ void ShaderBuilder::setShaderGraph(ShaderBuilder::ShaderType type, const QUrl &u } } -QByteArray ShaderBuilder::shaderCode(ShaderBuilder::ShaderType type) const +QByteArray ShaderBuilder::shaderCode(QShaderProgram::ShaderType type) const { return m_codes.value(type); } -bool ShaderBuilder::isShaderCodeDirty(ShaderBuilder::ShaderType type) const +bool ShaderBuilder::isShaderCodeDirty(QShaderProgram::ShaderType type) const { return m_dirtyTypes.contains(type); } -void ShaderBuilder::generateCode(ShaderBuilder::ShaderType type) +void ShaderBuilder::generateCode(QShaderProgram::ShaderType type) { const auto graphPath = QUrlHelper::urlToLocalFileOrQrc(shaderGraph(type)); QFile file(graphPath); @@ -273,12 +248,9 @@ void ShaderBuilder::generateCode(ShaderBuilder::ShaderType type) m_codes.insert(type, QShaderProgramPrivate::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); + m_pendingUpdates.push_back({ peerId(), + type, + m_codes.value(type) }); } void ShaderBuilder::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) @@ -305,13 +277,13 @@ void ShaderBuilder::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) markDirty(AbstractRenderer::ShadersDirty); } - static const std::pair<ShaderType, QUrl (QShaderProgramBuilder::*)() const> shaderTypesToGetters[] = { - {Vertex, &QShaderProgramBuilder::vertexShaderGraph}, - {TessellationControl, &QShaderProgramBuilder::tessellationControlShaderGraph}, - {TessellationEvaluation, &QShaderProgramBuilder::tessellationEvaluationShaderGraph}, - {Geometry, &QShaderProgramBuilder::geometryShaderGraph}, - {Fragment, &QShaderProgramBuilder::fragmentShaderGraph}, - {Compute, &QShaderProgramBuilder::computeShaderGraph}, + static const std::pair<QShaderProgram::ShaderType, QUrl (QShaderProgramBuilder::*)() const> shaderTypesToGetters[] = { + {QShaderProgram::Vertex, &QShaderProgramBuilder::vertexShaderGraph}, + {QShaderProgram::TessellationControl, &QShaderProgramBuilder::tessellationControlShaderGraph}, + {QShaderProgram::TessellationEvaluation, &QShaderProgramBuilder::tessellationEvaluationShaderGraph}, + {QShaderProgram::Geometry, &QShaderProgramBuilder::geometryShaderGraph}, + {QShaderProgram::Fragment, &QShaderProgramBuilder::fragmentShaderGraph}, + {QShaderProgram::Compute, &QShaderProgramBuilder::computeShaderGraph}, }; for (auto it = std::cbegin(shaderTypesToGetters), end = std::cend(shaderTypesToGetters); it != end; ++it) { diff --git a/src/render/materialsystem/shaderbuilder_p.h b/src/render/materialsystem/shaderbuilder_p.h index 6b92d3114..ac7a165b8 100644 --- a/src/render/materialsystem/shaderbuilder_p.h +++ b/src/render/materialsystem/shaderbuilder_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <Qt3DRender/qshaderprogram.h> #include <Qt3DRender/private/backendnode_p.h> #include <Qt3DRender/private/qgraphicsapifilter_p.h> @@ -60,18 +61,16 @@ namespace Qt3DRender { namespace Render { +struct ShaderBuilderUpdate +{ + Qt3DCore::QNodeId builderId; + Qt3DRender::QShaderProgram::ShaderType shaderType; + QByteArray shaderCode; +}; + class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderBuilder : public BackendNode { public: - enum ShaderType { - Vertex = 0, - TessellationControl, - TessellationEvaluation, - Geometry, - Fragment, - Compute - }; - static QString getPrototypesFile(); static void setPrototypesFile(const QString &file); static QStringList getPrototypeNames(); @@ -86,25 +85,28 @@ public: GraphicsApiFilterData graphicsApi() const; void setGraphicsApi(const GraphicsApiFilterData &graphicsApi); - QUrl shaderGraph(ShaderType type) const; - void setShaderGraph(ShaderType type, const QUrl &url); + QUrl shaderGraph(QShaderProgram::ShaderType type) const; + void setShaderGraph(QShaderProgram::ShaderType type, const QUrl &url); - QByteArray shaderCode(ShaderType type) const; - bool isShaderCodeDirty(ShaderType type) const; + QByteArray shaderCode(QShaderProgram::ShaderType type) const; + bool isShaderCodeDirty(QShaderProgram::ShaderType type) const; - void generateCode(ShaderType type); + void generateCode(QShaderProgram::ShaderType type); void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; + QVector<ShaderBuilderUpdate> &updates() { return m_pendingUpdates; } + private: void setEnabledLayers(const QStringList &layers); GraphicsApiFilterData m_graphicsApi; Qt3DCore::QNodeId m_shaderProgramId; QStringList m_enabledLayers; - QHash<ShaderType, QUrl> m_graphs; - QHash<ShaderType, QByteArray> m_codes; - QSet<ShaderType> m_dirtyTypes; + QHash<QShaderProgram::ShaderType, QUrl> m_graphs; + QHash<QShaderProgram::ShaderType, QByteArray> m_codes; + QSet<QShaderProgram::ShaderType> m_dirtyTypes; + QVector<ShaderBuilderUpdate> m_pendingUpdates; }; } // namespace Render diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp index f4bd8b871..333453ac7 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp @@ -279,7 +279,7 @@ void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderPro } -// Called by GL Command Thread +// Called by Renderer::updateGLResources void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager) { bool wasPresent = false; @@ -317,7 +317,8 @@ void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager) shader->setGraphicsContext(this); shader->setLoaded(true); - shader->markDirty(AbstractRenderer::AllDirty); + // Will force notifications to be sent to frontend at next frame + shader->markDirty(AbstractRenderer::ShadersDirty); } } diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 42af03d11..3da9b6c48 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -91,6 +91,8 @@ #include <Qt3DRender/private/renderviewbuilder_p.h> #include <Qt3DRender/private/setfence_p.h> #include <Qt3DRender/private/subtreeenabler_p.h> +#include <Qt3DRender/private/qshaderprogrambuilder_p.h> +#include <Qt3DRender/private/qshaderprogram_p.h> #include <Qt3DRender/qcameralens.h> #include <Qt3DCore/private/qeventfilterservice_p.h> @@ -191,16 +193,18 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create()) , m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create()) , m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create()) - , m_bufferGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering)) - , m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering)) - , m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) - , m_sendTextureChangesToFrontendJob(decltype(m_sendTextureChangesToFrontendJob)::create([] {}, - [this] (Qt3DCore::QAspectManager *m) { sendTextureChangesToFrontend(m); }, - JobTypes::SendTextureChangesToFrontend)) - , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) - , m_sendDisablesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) - , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) - , m_syncLoadingJobs(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncLoadingJobs)) + , m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering)) + , m_vaoGathererJob(SynchronizerJobPtr::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering)) + , m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) + , m_sendTextureChangesToFrontendJob(SynchronizerPostFramePtr::create([] {}, + [this] (Qt3DCore::QAspectManager *m) { sendTextureChangesToFrontend(m); }, + JobTypes::SendTextureChangesToFrontend)) + , m_sendSetFenceHandlesToFrontendJob(SynchronizerJobPtr::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) + , m_sendDisablesToFrontendJob(SynchronizerJobPtr::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) + , m_introspectShaderJob(SynchronizerPostFramePtr::create([this] { reloadDirtyShaders(); }, + [this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); }, + JobTypes::DirtyShaderGathering)) + , m_syncLoadingJobs(SynchronizerJobPtr::create([] {}, JobTypes::SyncLoadingJobs)) , m_ownedContext(false) , m_offscreenHelper(nullptr) , m_shouldSwapBuffers(true) @@ -1104,45 +1108,22 @@ void Renderer::reloadDirtyShaders() if (shaderBuilder) { shaderBuilder->setGraphicsApi(*technique->graphicsApiFilter()); - for (int i = 0; i <= ShaderBuilder::Compute; i++) { - const auto builderType = static_cast<ShaderBuilder::ShaderType>(i); - if (!shaderBuilder->shaderGraph(builderType).isValid()) + for (int i = 0; i <= QShaderProgram::Compute; i++) { + const auto shaderType = static_cast<QShaderProgram::ShaderType>(i); + if (!shaderBuilder->shaderGraph(shaderType).isValid()) continue; - if (shaderBuilder->isShaderCodeDirty(builderType)) { - shaderBuilder->generateCode(builderType); + if (shaderBuilder->isShaderCodeDirty(shaderType)) { + shaderBuilder->generateCode(shaderType); + m_shaderBuilderUpdates.append(std::move(shaderBuilder->updates())); } - QShaderProgram::ShaderType shaderType = QShaderProgram::Vertex; - switch (builderType) { - case ShaderBuilder::Vertex: - shaderType = QShaderProgram::Vertex; - break; - case ShaderBuilder::TessellationControl: - shaderType = QShaderProgram::TessellationControl; - break; - case ShaderBuilder::TessellationEvaluation: - shaderType = QShaderProgram::TessellationEvaluation; - break; - case ShaderBuilder::Geometry: - shaderType = QShaderProgram::Geometry; - break; - case ShaderBuilder::Fragment: - shaderType = QShaderProgram::Fragment; - break; - case ShaderBuilder::Compute: - shaderType = QShaderProgram::Compute; - break; - } - - const auto code = shaderBuilder->shaderCode(builderType); + const auto code = shaderBuilder->shaderCode(shaderType); shader->setShaderCode(shaderType, code); } } - if (Q_UNLIKELY(shader->hasPendingNotifications())) - shader->submitPendingNotifications(); - // If the shader hasn't be loaded, load it + // If the shader hasn't been loaded, load it if (shader != nullptr && !shader->isLoaded()) loadShader(shader, shaderHandle); } @@ -1150,6 +1131,33 @@ void Renderer::reloadDirtyShaders() } } +// Executed in job postFrame +void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) +{ + Q_ASSERT(isRunning()); + + // Sync Shader + const QVector<HShader> activeShaders = m_nodesManager->shaderManager()->activeHandles(); + for (const HShader &handle :activeShaders) { + Shader *s = m_nodesManager->shaderManager()->data(handle); + if (s->requiresFrontendSync()) { + QShaderProgram *frontend = static_cast<decltype(frontend)>(manager->lookupNode(s->peerId())); + QShaderProgramPrivate *dFrontend = static_cast<decltype(dFrontend)>(QNodePrivate::get(frontend)); + dFrontend->setStatus(s->status()); + dFrontend->setLog(s->log()); + s->unsetRequiresFrontendSync(); + } + } + + // Sync ShaderBuilder + const QVector<ShaderBuilderUpdate> shaderBuilderUpdates = std::move(m_shaderBuilderUpdates); + for (const ShaderBuilderUpdate &update : shaderBuilderUpdates) { + QShaderProgramBuilder *builder = static_cast<decltype(builder)>(manager->lookupNode(update.builderId)); + QShaderProgramBuilderPrivate *dBuilder = static_cast<decltype(dBuilder)>(QNodePrivate::get(builder)); + dBuilder->setShaderCode(update.shaderCode, update.shaderType); + } +} + // Executed in a job (as postFrame) void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager) { diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 41a071290..29aece008 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -81,6 +81,7 @@ #include <Qt3DRender/private/renderercache_p.h> #include <Qt3DRender/private/texture_p.h> #include <Qt3DRender/private/glfence_p.h> +#include <Qt3DRender/private/shaderbuilder_p.h> #include <QHash> #include <QMatrix4x4> @@ -154,7 +155,7 @@ class UpdateLevelOfDetailJob; typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr; using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; -using IntrospectShadersJobPtr = GenericLambdaJobPtr<std::function<void()>>; +using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>; class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer { @@ -220,7 +221,7 @@ public: inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; } inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; } - inline IntrospectShadersJobPtr introspectShadersJob() const { return m_introspectShaderJob; } + inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; } inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; } inline Qt3DCore::QAspectJobPtr sendTextureChangesToFrontendJob() const { return m_sendTextureChangesToFrontendJob; } @@ -374,14 +375,13 @@ private: HVao *previousVAOHandle, OpenGLVertexArrayObject **vao); - GenericLambdaJobPtr<std::function<void ()>> m_bufferGathererJob; - GenericLambdaJobPtr<std::function<void ()>> m_vaoGathererJob; - GenericLambdaJobPtr<std::function<void ()>> m_textureGathererJob; - GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>> m_sendTextureChangesToFrontendJob; - GenericLambdaJobPtr<std::function<void ()>> m_sendSetFenceHandlesToFrontendJob; - GenericLambdaJobPtr<std::function<void ()>> m_sendDisablesToFrontendJob; - IntrospectShadersJobPtr m_introspectShaderJob; - + SynchronizerJobPtr m_bufferGathererJob; + SynchronizerJobPtr m_vaoGathererJob; + SynchronizerJobPtr m_textureGathererJob; + SynchronizerPostFramePtr m_sendTextureChangesToFrontendJob; + SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob; + SynchronizerJobPtr m_sendDisablesToFrontendJob; + SynchronizerPostFramePtr m_introspectShaderJob; SynchronizerJobPtr m_syncLoadingJobs; void lookForAbandonedVaos(); @@ -389,6 +389,7 @@ private: void lookForDownloadableBuffers(); void lookForDirtyTextures(); void reloadDirtyShaders(); + void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager); void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager); void sendSetFenceHandlesToFrontend(); void sendDisablesToFrontend(); @@ -404,6 +405,7 @@ private: QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; QVector<Qt3DCore::QNodeId> m_updatedDisables; Qt3DCore::QNodeIdVector m_textureIdsToCleanup; + QVector<ShaderBuilderUpdate> m_shaderBuilderUpdates; bool m_ownedContext; diff --git a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp index 881c24728..851316e60 100644 --- a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp +++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp @@ -594,13 +594,11 @@ private Q_SLOTS: void checkGeneratedCodePropertyUpdates() { + Qt3DRender::QShaderProgramBuilderPrivate *dBuilder = static_cast<decltype(dBuilder)>(Qt3DCore::QNodePrivate::get(this)); { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("vertex"), Qt3DRender::QShaderProgram::Vertex); // THEN QVERIFY(spy.isValid()); @@ -610,10 +608,7 @@ private Q_SLOTS: { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("fragment"), Qt3DRender::QShaderProgram::Fragment); // THEN QVERIFY(spy.isValid()); @@ -623,10 +618,7 @@ private Q_SLOTS: { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("geometry"), Qt3DRender::QShaderProgram::Geometry); // THEN QVERIFY(spy.isValid()); @@ -636,10 +628,8 @@ private Q_SLOTS: { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("compute"), Qt3DRender::QShaderProgram::Compute); + // THEN QVERIFY(spy.isValid()); @@ -649,10 +639,7 @@ private Q_SLOTS: { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("control"), Qt3DRender::QShaderProgram::TessellationControl); // THEN QVERIFY(spy.isValid()); @@ -662,10 +649,7 @@ private Q_SLOTS: { // 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); + dBuilder->setShaderCode(QByteArrayLiteral("eval"), Qt3DRender::QShaderProgram::TessellationEvaluation); // THEN QVERIFY(spy.isValid()); diff --git a/tests/auto/render/shader/tst_shader.cpp b/tests/auto/render/shader/tst_shader.cpp index bfebe2467..d1578aee7 100644 --- a/tests/auto/render/shader/tst_shader.cpp +++ b/tests/auto/render/shader/tst_shader.cpp @@ -103,7 +103,7 @@ void tst_RenderShader::matchesFrontendPeer() for (int i = Qt3DRender::QShaderProgram::Vertex; i <= Qt3DRender::QShaderProgram::Compute; ++i) QCOMPARE(backend.shaderCode()[i], - frontend->shaderCode( static_cast<const Qt3DRender::QShaderProgram::ShaderType>(i))); + frontend->shaderCode(static_cast<Qt3DRender::QShaderProgram::ShaderType>(i))); } void tst_RenderShader::cleanupLeavesACoherentState() diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp index 7a9e0fac4..7a08fe018 100644 --- a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp +++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp @@ -36,7 +36,6 @@ #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 @@ -78,8 +77,8 @@ private slots: // THEN QVERIFY(!shaderBuilder.isEnabled()); QVERIFY(shaderBuilder.enabledLayers().isEmpty()); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QCOMPARE(shaderBuilder.shaderGraph(type), QUrl()); QCOMPARE(shaderBuilder.shaderCode(type), QByteArray()); QVERIFY(!shaderBuilder.isShaderCodeDirty(type)); @@ -158,29 +157,29 @@ private slots: QCOMPARE(backend.enabledLayers(), frontend->enabledLayers()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Vertex), frontend->vertexShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Vertex), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Vertex), !frontend->vertexShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::Vertex), frontend->vertexShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::Vertex), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::Vertex), !frontend->vertexShaderGraph().isEmpty()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::TessellationControl), frontend->tessellationControlShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::TessellationControl), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::TessellationControl), !frontend->tessellationControlShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::TessellationControl), frontend->tessellationControlShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::TessellationControl), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::TessellationControl), !frontend->tessellationControlShaderGraph().isEmpty()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), frontend->tessellationEvaluationShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), !frontend->tessellationEvaluationShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::TessellationEvaluation), frontend->tessellationEvaluationShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::TessellationEvaluation), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::TessellationEvaluation), !frontend->tessellationEvaluationShaderGraph().isEmpty()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Geometry), frontend->geometryShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Geometry), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Geometry), !frontend->geometryShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::Geometry), frontend->geometryShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::Geometry), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::Geometry), !frontend->geometryShaderGraph().isEmpty()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Fragment), frontend->fragmentShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Fragment), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Fragment), !frontend->fragmentShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::Fragment), frontend->fragmentShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::Fragment), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::Fragment), !frontend->fragmentShaderGraph().isEmpty()); - QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Compute), frontend->computeShaderGraph()); - QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Compute), QByteArray()); - QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Compute), !frontend->computeShaderGraph().isEmpty()); + QCOMPARE(backend.shaderGraph(Qt3DRender::QShaderProgram::Compute), frontend->computeShaderGraph()); + QCOMPARE(backend.shaderCode(Qt3DRender::QShaderProgram::Compute), QByteArray()); + QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::QShaderProgram::Compute), !frontend->computeShaderGraph().isEmpty()); // WHEN backend.cleanup(); @@ -188,8 +187,8 @@ private slots: // THEN QVERIFY(!backend.isEnabled()); QVERIFY(backend.enabledLayers().isEmpty()); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QCOMPARE(backend.shaderGraph(type), QUrl()); QCOMPARE(backend.shaderCode(type), QByteArray()); QVERIFY(!backend.isShaderCodeDirty(type)); @@ -279,16 +278,16 @@ private slots: const auto layers = QStringList() << "foo" << "bar"; static const std::pair< - Qt3DRender::Render::ShaderBuilder::ShaderType, + Qt3DRender::QShaderProgram::ShaderType, void (Qt3DRender::QShaderProgramBuilder::*)(const QUrl &) > shaderTypesToSetters[] = { - {Qt3DRender::Render::ShaderBuilder::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, + {Qt3DRender::QShaderProgram::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, + {Qt3DRender::QShaderProgram::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, + {Qt3DRender::QShaderProgram::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, + {Qt3DRender::QShaderProgram::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, + {Qt3DRender::QShaderProgram::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, + {Qt3DRender::QShaderProgram::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, }; @@ -303,8 +302,8 @@ private slots: // THEN QCOMPARE(backend.enabledLayers(), layers); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QVERIFY(backend.isShaderCodeDirty(type)); backend.generateCode(type); // Resets the dirty flag } @@ -317,8 +316,8 @@ private slots: // THEN QCOMPARE(backend.enabledLayers(), layers); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QVERIFY(!backend.isShaderCodeDirty(type)); backend.generateCode(type); // Resets the dirty flag } @@ -331,8 +330,8 @@ private slots: // THEN QVERIFY(backend.shaderProgramId().isNull()); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QVERIFY(backend.isShaderCodeDirty(type)); backend.generateCode(type); // Resets the dirty flag } @@ -347,8 +346,8 @@ private slots: // THEN QVERIFY(backend.enabledLayers().isEmpty()); - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i); + for (int i = 0; i <= Qt3DRender::QShaderProgram::Compute; i++) { + const auto type = static_cast<Qt3DRender::QShaderProgram::ShaderType>(i); QVERIFY(!backend.isShaderCodeDirty(type)); backend.generateCode(type); // Resets the dirty flag } @@ -358,32 +357,32 @@ private slots: void shouldHandleShaderGraphPropertiesChanges_data() { - QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type"); + QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("type"); QTest::addColumn<QUrl>("graphUrl"); - QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex + QTest::newRow("vertex") << Qt3DRender::QShaderProgram::Vertex << QUrl::fromEncoded("qrc:/vertex.json"); - QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl + QTest::newRow("tessControl") << Qt3DRender::QShaderProgram::TessellationControl << QUrl::fromEncoded("qrc:/tesscontrol.json"); - QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation + QTest::newRow("tessEval") << Qt3DRender::QShaderProgram::TessellationEvaluation << QUrl::fromEncoded("qrc:/tesseval.json"); - QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry + QTest::newRow("geometry") << Qt3DRender::QShaderProgram::Geometry << QUrl::fromEncoded("qrc:/geometry.json"); - QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment + QTest::newRow("fragment") << Qt3DRender::QShaderProgram::Fragment << QUrl::fromEncoded("qrc:/fragment.json"); - QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute + QTest::newRow("compute") << Qt3DRender::QShaderProgram::Compute << QUrl::fromEncoded("qrc:/compute.json"); } void shouldHandleShaderGraphPropertiesChanges() { // GIVEN - QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type); + QFETCH(Qt3DRender::QShaderProgram::ShaderType, type); QFETCH(QUrl, graphUrl); Qt3DRender::Render::ShaderBuilder backend; @@ -393,16 +392,16 @@ private slots: simulateInitializationSync(&frontend, &backend); static const QHash< - Qt3DRender::Render::ShaderBuilder::ShaderType, + Qt3DRender::QShaderProgram::ShaderType, void (Qt3DRender::QShaderProgramBuilder::*)(const QUrl &) > shaderTypesToSetters = { - {Qt3DRender::Render::ShaderBuilder::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, - {Qt3DRender::Render::ShaderBuilder::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, + {Qt3DRender::QShaderProgram::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, + {Qt3DRender::QShaderProgram::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, + {Qt3DRender::QShaderProgram::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, + {Qt3DRender::QShaderProgram::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, + {Qt3DRender::QShaderProgram::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, + {Qt3DRender::QShaderProgram::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, }; // WHEN @@ -455,14 +454,14 @@ private slots: void shouldHandleShaderCodeGeneration_data() { - QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type"); - - QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex; - QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl; - QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation; - QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry; - QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment; - QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute; + QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("type"); + + QTest::newRow("vertex") << Qt3DRender::QShaderProgram::Vertex; + QTest::newRow("tessControl") << Qt3DRender::QShaderProgram::TessellationControl; + QTest::newRow("tessEval") << Qt3DRender::QShaderProgram::TessellationEvaluation; + QTest::newRow("geometry") << Qt3DRender::QShaderProgram::Geometry; + QTest::newRow("fragment") << Qt3DRender::QShaderProgram::Fragment; + QTest::newRow("compute") << Qt3DRender::QShaderProgram::Compute; } void shouldHandleShaderCodeGeneration() @@ -471,7 +470,7 @@ private slots: Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json"); QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty()); - QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type); + QFETCH(Qt3DRender::QShaderProgram::ShaderType, type); const auto gl3Api = []{ auto api = Qt3DRender::GraphicsApiFilterData(); @@ -540,15 +539,15 @@ private slots: void checkCodeUpdatedNotification_data() { - QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type"); + QTest::addColumn<Qt3DRender::QShaderProgram::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; + QTest::newRow("vertex") << Qt3DRender::QShaderProgram::Vertex << Qt3DRender::QShaderProgram::Vertex; + QTest::newRow("tessControl") << Qt3DRender::QShaderProgram::TessellationControl << Qt3DRender::QShaderProgram::TessellationControl; + QTest::newRow("tessEval") << Qt3DRender::QShaderProgram::TessellationEvaluation << Qt3DRender::QShaderProgram::TessellationEvaluation; + QTest::newRow("geometry") << Qt3DRender::QShaderProgram::Geometry << Qt3DRender::QShaderProgram::Geometry; + QTest::newRow("fragment") << Qt3DRender::QShaderProgram::Fragment << Qt3DRender::QShaderProgram::Fragment; + QTest::newRow("compute") << Qt3DRender::QShaderProgram::Compute << Qt3DRender::QShaderProgram::Compute; } @@ -559,7 +558,7 @@ private slots: Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json"); QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty()); - QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type); + QFETCH(Qt3DRender::QShaderProgram::ShaderType, type); QFETCH(Qt3DRender::QShaderProgram::ShaderType, notificationType); const auto gl3Api = []{ @@ -603,15 +602,6 @@ private slots: 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(); } }; |