summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-10-08 08:08:21 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-10-14 08:04:40 +0200
commitc8134efd470482e2254e7b232deb386828af5610 (patch)
treedda08eedc773b84b02b40660a61e987126815c7f
parentca48552bf2c150886fe1b064a061bb77bc76f230 (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.cpp88
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder.h1
-rw-r--r--src/render/materialsystem/qshaderprogrambuilder_p.h6
-rw-r--r--src/render/materialsystem/shader.cpp38
-rw-r--r--src/render/materialsystem/shader_p.h7
-rw-r--r--src/render/materialsystem/shaderbuilder.cpp62
-rw-r--r--src/render/materialsystem/shaderbuilder_p.h36
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp5
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp90
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h22
-rw-r--r--tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp32
-rw-r--r--tests/auto/render/shader/tst_shader.cpp2
-rw-r--r--tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp148
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 &notification : 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();
}
};