QmlDesigner: Prepare the process to compile shaders externally

Also added customValue for Uniform

Task-number: QDS-10811
Change-Id: Ie47ad41d0c80da149bdab9cae542297d59abcee6
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Amr Essam
2023-10-09 13:46:08 +03:00
committed by Amr Elsayed
parent 82be17c2c6
commit 93ba99f019
6 changed files with 73 additions and 33 deletions

View File

@@ -20,6 +20,31 @@ Column {
// The delay in ms to wait until updating the effect // The delay in ms to wait until updating the effect
readonly property int updateDelay: 200 readonly property int updateDelay: 200
// Create a dummy parent to host the effect qml object
function createNewComponent() {
var oldComponent = componentParent.children[0];
if (oldComponent)
oldComponent.destroy();
try {
const newObject = Qt.createQmlObject(
effectMakerModel.qmlComponentString,
componentParent,
""
);
effectMakerModel.resetEffectError(0);
} catch (error) {
let errorString = "QML: ERROR: ";
let errorLine = -1;
if (error.qmlErrors.length > 0) {
// Show the first QML error
let e = error.qmlErrors[0];
errorString += e.lineNumber + ": " + e.message;
errorLine = e.lineNumber;
}
effectMakerModel.setEffectError(errorString, 0, errorLine);
}
}
Rectangle { // toolbar Rectangle { // toolbar
width: parent.width width: parent.width
height: StudioTheme.Values.toolbarHeight height: StudioTheme.Values.toolbarHeight
@@ -154,32 +179,6 @@ Column {
layer.smooth: true layer.smooth: true
} }
// Create a dummy parent to host the effect qml object
function createNewComponent() {
var oldComponent = componentParent.children[0];
if (oldComponent)
oldComponent.destroy();
try {
const newObject = Qt.createQmlObject(
effectMakerModel.qmlComponentString,
componentParent,
""
);
effectMakerModel.resetEffectError(0);
} catch (error) {
let errorString = "QML: ERROR: ";
let errorLine = -1;
if (error.qmlErrors.length > 0) {
// Show the first QML error
let e = error.qmlErrors[0];
errorString += e.lineNumber + ": " + e.message;
errorLine = e.lineNumber;
}
effectMakerModel.setEffectError(errorString, 0, errorLine);
}
}
Connections { Connections {
target: effectMakerModel target: effectMakerModel
function onShadersBaked() { function onShadersBaked() {

View File

@@ -3,7 +3,7 @@ find_package(Qt6 OPTIONAL_COMPONENTS Gui Quick ShaderTools)
add_qtc_plugin(EffectMakerNew add_qtc_plugin(EffectMakerNew
CONDITION TARGET QmlDesigner AND TARGET Qt::ShaderTools CONDITION TARGET QmlDesigner AND TARGET Qt::ShaderTools
PLUGIN_DEPENDS PLUGIN_DEPENDS
QtCreator::Core QtCreator::QmlDesigner QtCreator::Core QtCreator::QmlDesigner QtCreator::ProjectExplorer
DEPENDS DEPENDS
Qt::Core Qt::Core
QtCreator::Utils Qt::CorePrivate Qt::Widgets Qt::Qml Qt::QmlPrivate Qt::Quick Qt::ShaderTools Qt::ShaderToolsPrivate QtCreator::Utils Qt::CorePrivate Qt::Widgets Qt::Qml Qt::QmlPrivate Qt::Quick Qt::ShaderTools Qt::ShaderToolsPrivate

View File

@@ -10,6 +10,12 @@
#include <QByteArrayView> #include <QByteArrayView>
#include <QVector2D> #include <QVector2D>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
namespace EffectMaker { namespace EffectMaker {
@@ -758,7 +764,7 @@ void EffectMakerModel::updateCustomUniforms()
// Custom values are not readonly, others inside the effect can be // Custom values are not readonly, others inside the effect can be
QString readOnly = uniform->useCustomValue() ? QString() : QStringLiteral("readonly "); QString readOnly = uniform->useCustomValue() ? QString() : QStringLiteral("readonly ");
previewEffectPropertiesString += " " + readOnly + "property " + type + " " previewEffectPropertiesString += " " + readOnly + "property " + type + " "
+ propertyName + bindedValueString + '\n'; + propertyName + valueString + '\n';
// Define type properties are not added into exports // Define type properties are not added into exports
if (!isDefine) { if (!isDefine) {
if (uniform->useCustomValue()) { if (uniform->useCustomValue()) {
@@ -783,7 +789,9 @@ void EffectMakerModel::updateCustomUniforms()
} }
// See if any of the properties changed // See if any of the properties changed
// TODO m_exportedRootPropertiesString = exportedRootPropertiesString;
m_previewEffectPropertiesString = previewEffectPropertiesString;
m_exportedEffectPropertiesString = exportedEffectPropertiesString;
} }
void EffectMakerModel::bakeShaders() void EffectMakerModel::bakeShaders()
@@ -807,6 +815,7 @@ void EffectMakerModel::bakeShaders()
QString vs = m_vertexShader; QString vs = m_vertexShader;
m_baker.setSourceString(vs.toUtf8(), QShader::VertexStage); m_baker.setSourceString(vs.toUtf8(), QShader::VertexStage);
QShader vertShader = m_baker.bake(); QShader vertShader = m_baker.bake();
if (!vertShader.isValid()) { if (!vertShader.isValid()) {
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage()); qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorVert); setEffectError(m_baker.errorMessage().split('\n').first(), ErrorVert);
@@ -821,6 +830,7 @@ void EffectMakerModel::bakeShaders()
m_baker.setSourceString(fs.toUtf8(), QShader::FragmentStage); m_baker.setSourceString(fs.toUtf8(), QShader::FragmentStage);
QShader fragShader = m_baker.bake(); QShader fragShader = m_baker.bake();
if (!fragShader.isValid()) { if (!fragShader.isValid()) {
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage()); qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorFrag); setEffectError(m_baker.errorMessage().split('\n').first(), ErrorFrag);
@@ -908,6 +918,7 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
// When used in preview component, we need property with value // When used in preview component, we need property with value
// and when in exported component, property with binding to root value. // and when in exported component, property with binding to root value.
s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString; s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString;
if (!customImagesString.isEmpty()) if (!customImagesString.isEmpty())
s += '\n' + customImagesString; s += '\n' + customImagesString;
@@ -925,6 +936,21 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
return s; return s;
} }
Utils::FilePath EffectMakerModel::qsbPath() const
{
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
if (target) {
if (QtSupport::QtVersion *qtVer = QtSupport::QtKitAspect::qtVersion(target->kit())) {
Utils::FilePath path = qtVer->binPath().pathAppended("qsb").withExecutableSuffix();
if (path.exists())
return path;
}
}
qWarning() << "Shader baking failed, QSB not found.";
return {};
}
void EffectMakerModel::updateQmlComponent() void EffectMakerModel::updateQmlComponent()
{ {
// Clear possible QML runtime errors // Clear possible QML runtime errors

View File

@@ -5,6 +5,8 @@
#include "shaderfeatures.h" #include "shaderfeatures.h"
#include <utils/filepath.h>
#include <QMap> #include <QMap>
#include <QRegularExpression> #include <QRegularExpression>
#include <QStandardItemModel> #include <QStandardItemModel>
@@ -12,6 +14,10 @@
#include <QtShaderTools/private/qshaderbaker_p.h> #include <QtShaderTools/private/qshaderbaker_p.h>
namespace Utils {
class Process;
}
namespace EffectMaker { namespace EffectMaker {
class CompositionNode; class CompositionNode;
@@ -60,14 +66,17 @@ public:
QString fragmentShader() const; QString fragmentShader() const;
void setFragmentShader(const QString &newFragmentShader); void setFragmentShader(const QString &newFragmentShader);
QString vertexShader() const; QString vertexShader() const;
void setVertexShader(const QString &newVertexShader); void setVertexShader(const QString &newVertexShader);
const QString &qmlComponentString() const; const QString &qmlComponentString() const;
void setQmlComponentString(const QString &string);
Q_INVOKABLE void updateQmlComponent(); Q_INVOKABLE void updateQmlComponent();
Q_INVOKABLE void resetEffectError(int type);
Q_INVOKABLE void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
signals: signals:
void isEmptyChanged(); void isEmptyChanged();
void selectedIndexChanged(int idx); void selectedIndexChanged(int idx);
@@ -102,8 +111,6 @@ private:
void updateBakedShaderVersions(); void updateBakedShaderVersions();
QString detectErrorMessage(const QString &errorMessage); QString detectErrorMessage(const QString &errorMessage);
EffectError effectError() const; EffectError effectError() const;
void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
void resetEffectError(int type);
QString valueAsString(const Uniform &uniform); QString valueAsString(const Uniform &uniform);
QString valueAsBinding(const Uniform &uniform); QString valueAsBinding(const Uniform &uniform);
@@ -121,6 +128,9 @@ private:
QString getCustomShaderVaryings(bool outState); QString getCustomShaderVaryings(bool outState);
QString generateVertexShader(bool includeUniforms = true); QString generateVertexShader(bool includeUniforms = true);
QString generateFragmentShader(bool includeUniforms = true); QString generateFragmentShader(bool includeUniforms = true);
Utils::FilePath qsbPath() const;
void updateCustomUniforms(); void updateCustomUniforms();
void bakeShaders(); void bakeShaders();
@@ -140,7 +150,7 @@ private:
QString m_vertexShader; QString m_vertexShader;
QStringList m_defaultRootVertexShader; QStringList m_defaultRootVertexShader;
QStringList m_defaultRootFragmentShader; QStringList m_defaultRootFragmentShader;
QShaderBaker m_baker; QShaderBaker m_baker; // TODO: Remove
QTemporaryFile m_fragmentShaderFile; QTemporaryFile m_fragmentShaderFile;
QTemporaryFile m_vertexShaderFile; QTemporaryFile m_vertexShaderFile;
// Used in exported QML, at root of the file // Used in exported QML, at root of the file

View File

@@ -7,6 +7,8 @@
#include "effectmakermodel.h" #include "effectmakermodel.h"
#include "effectmakernodesmodel.h" #include "effectmakernodesmodel.h"
#include "effectmakerview.h" #include "effectmakerview.h"
#include "nodeinstanceview.h"
#include "qmldesignerconstants.h" #include "qmldesignerconstants.h"
#include "qmldesignerplugin.h" #include "qmldesignerplugin.h"
#include "qqmlcontext.h" #include "qqmlcontext.h"

View File

@@ -40,6 +40,9 @@ Uniform::Uniform(const QJsonObject &propObj)
// QEN files don't store the current value, so with those use default value // QEN files don't store the current value, so with those use default value
value = defaultValue; value = defaultValue;
} }
m_customValue = propObj.value("customValue").toString();
m_useCustomValue = getBoolValue(propObj.value("useCustomValue"), false);
minValue = propObj.value("minValue").toString(); minValue = propObj.value("minValue").toString();
maxValue = propObj.value("maxValue").toString(); maxValue = propObj.value("maxValue").toString();