summaryrefslogtreecommitdiffstats
path: root/src/gui/util
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-02-20 08:34:46 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-02-20 08:34:46 +0100
commit41ecb6abbf371e4b774f3123c87e314c40bfaba3 (patch)
tree3de5b56e081177a61cea932e7ecbe60db66fcde3 /src/gui/util
parentd928beb024c240b37d35d2c53f25648c99a484b4 (diff)
parent7981dbfaf371a368fbd69e935768b310f42a0e5a (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
Diffstat (limited to 'src/gui/util')
-rw-r--r--src/gui/util/qshadergenerator.cpp42
-rw-r--r--src/gui/util/qshadergraph.cpp47
2 files changed, 86 insertions, 3 deletions
diff --git a/src/gui/util/qshadergenerator.cpp b/src/gui/util/qshadergenerator.cpp
index 4beed8ed25..7085082d97 100644
--- a/src/gui/util/qshadergenerator.cpp
+++ b/src/gui/util/qshadergenerator.cpp
@@ -42,6 +42,8 @@
#include "qshaderlanguage_p.h"
#include <QRegularExpression>
+#include <cctype>
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(ShaderGenerator, "ShaderGenerator", QtWarningMsg)
@@ -457,6 +459,13 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
QByteArray line = node.rule(format).substitution;
const QVector<QShaderNodePort> ports = node.ports();
+ struct VariableReplacement {
+ QByteArray placeholder;
+ QByteArray variable;
+ };
+
+ QVector<VariableReplacement> variableReplacements;
+
// Generate temporary variable names vN
for (const QShaderNodePort &port : ports) {
const QString portName = port.name;
@@ -472,10 +481,37 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
if (variableIndex < 0)
continue;
- const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8());
- const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex));
+ VariableReplacement replacement;
+ replacement.placeholder = QByteArrayLiteral("$") + portName.toUtf8();
+ replacement.variable = QByteArrayLiteral("v") + QByteArray::number(variableIndex);
+
+ variableReplacements.append(std::move(replacement));
+ }
+
+ int begin = 0;
+ while ((begin = line.indexOf('$', begin)) != -1) {
+ int end = begin + 1;
+ char endChar = line.at(end);
+ const int size = line.size();
+ while (end < size && (std::isalnum(endChar) || endChar == '_')) {
+ ++end;
+ endChar = line.at(end);
+ }
+
+ const int placeholderLength = end - begin;
- line.replace(placeholder, variable);
+ const QByteArray variableName = line.mid(begin, placeholderLength);
+ const auto replacementIt = std::find_if(variableReplacements.cbegin(), variableReplacements.cend(),
+ [&variableName](const VariableReplacement &replacement) {
+ return variableName == replacement.placeholder;
+ });
+
+ if (replacementIt != variableReplacements.cend()) {
+ line.replace(begin, placeholderLength, replacementIt->variable);
+ begin += replacementIt->variable.length();
+ } else {
+ begin = end;
+ }
}
// Substitute variable names by generated vN variable names
diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp
index 46fe6ac6d6..611bb4b938 100644
--- a/src/gui/util/qshadergraph.cpp
+++ b/src/gui/util/qshadergraph.cpp
@@ -123,6 +123,50 @@ namespace
}
return targetStatement;
}
+
+ void removeNodesWithUnboundInputs(QVector<QShaderGraph::Statement> &statements,
+ const QVector<QShaderGraph::Edge> &allEdges)
+ {
+ // A node is invalid if any of its input ports is disconected
+ // or connected to the output port of another invalid node.
+
+ // Keeps track of the edges from the nodes we know to be valid
+ // to unvisited nodes
+ auto currentEdges = QVector<QShaderGraph::Edge>();
+
+ statements.erase(std::remove_if(statements.begin(),
+ statements.end(),
+ [&currentEdges, &allEdges] (const QShaderGraph::Statement &statement) {
+ const QShaderNode &node = statement.node;
+ const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, node.uuid());
+ const QVector<QShaderNodePort> ports = node.ports();
+
+ bool allInputsConnected = true;
+ for (const QShaderNodePort &port : node.ports()) {
+ if (port.direction == QShaderNodePort::Output)
+ continue;
+
+ const auto edgeIt = std::find_if(outgoing.cbegin(),
+ outgoing.cend(),
+ [&port] (const QShaderGraph::Edge &edge) {
+ return edge.targetPortName == port.name;
+ });
+
+ if (edgeIt != outgoing.cend())
+ currentEdges.removeAll(*edgeIt);
+ else
+ allInputsConnected = false;
+ }
+
+ if (allInputsConnected) {
+ const QVector<QShaderGraph::Edge> incoming = incomingEdges(allEdges, node.uuid());
+ currentEdges.append(incoming);
+ }
+
+ return !allInputsConnected;
+ }),
+ statements.end());
+ }
}
QUuid QShaderGraph::Statement::uuid() const noexcept
@@ -248,6 +292,9 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
}
std::reverse(result.begin(), result.end());
+
+ removeNodesWithUnboundInputs(result, enabledEdges);
+
return result;
}