Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Iace12004afdfe765a3068dfcf6f1320c1123c539
This commit is contained in:
commit
65cafea797
@ -532,7 +532,7 @@ struct Q_CORE_EXPORT QMetaObject
|
||||
static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
|
||||
&& QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
|
||||
&& !std::is_convertible<Func, const char*>::value, bool>::type
|
||||
invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret)
|
||||
invokeMethod(QObject *context, Func function, decltype(function()) *ret)
|
||||
{
|
||||
return invokeMethodImpl(context,
|
||||
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
|
||||
|
@ -7519,6 +7519,8 @@ float QString::toFloat(bool *ok) const
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
/*! \fn QString &QString::setNum(uint n, int base)
|
||||
@ -7576,6 +7578,8 @@ QString &QString::setNum(qulonglong n, int base)
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
QString &QString::setNum(double n, char f, int prec)
|
||||
@ -7594,6 +7598,8 @@ QString &QString::setNum(double n, char f, int prec)
|
||||
The formatting always uses QLocale::C, i.e., English/UnitedStates.
|
||||
To get a localized string representation of a number, use
|
||||
QLocale::toString() with the appropriate locale.
|
||||
|
||||
\sa number()
|
||||
*/
|
||||
|
||||
|
||||
|
@ -904,6 +904,9 @@ int QTextDocument::lineCount() const
|
||||
|
||||
Returns the number of characters of this document.
|
||||
|
||||
\note As a QTextDocument always contains at least one
|
||||
QChar::ParagraphSeparator, this method will return at least 1.
|
||||
|
||||
\sa blockCount(), characterAt()
|
||||
*/
|
||||
int QTextDocument::characterCount() const
|
||||
|
@ -346,10 +346,9 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
code << QByteArrayLiteral("void main()");
|
||||
code << QByteArrayLiteral("{");
|
||||
|
||||
const QRegularExpression localToGlobalRegExp(QStringLiteral("^.*\\s+(\\w+)\\s*=\\s*((?:\\w+\\(.*\\))|(?:\\w+)).*;$"));
|
||||
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("^(.*\\s+(v\\d+))\\s*=\\s*(.*);$"));
|
||||
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("([^;]*\\s+(v\\d+))\\s*=\\s*([^;]*);"));
|
||||
const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
|
||||
const QRegularExpression outputToTemporaryAssignmentRegExp(QStringLiteral("^\\s*(\\w+)\\s*=\\s*(.*);$"));
|
||||
const QRegularExpression statementRegExp(QStringLiteral("\\s*(\\w+)\\s*=\\s*([^;]*);"));
|
||||
|
||||
struct Variable;
|
||||
|
||||
@ -517,14 +516,29 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
// Substitute variable names by generated vN variable names
|
||||
const QByteArray substitutionedLine = replaceParameters(line, node, format);
|
||||
|
||||
Variable *v = nullptr;
|
||||
QRegularExpressionMatchIterator matches;
|
||||
|
||||
switch (node.type()) {
|
||||
// Record name of temporary variable that possibly references a global input
|
||||
// We will replace the temporary variables by the matching global variables later
|
||||
case QShaderNode::Input: {
|
||||
const QRegularExpressionMatch match = localToGlobalRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Input:
|
||||
case QShaderNode::Output:
|
||||
matches = statementRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||
break;
|
||||
case QShaderNode::Function:
|
||||
matches = temporaryVariableToAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||
break;
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
while (matches.hasNext()) {
|
||||
QRegularExpressionMatch match = matches.next();
|
||||
|
||||
Variable *v = nullptr;
|
||||
|
||||
switch (node.type()) {
|
||||
// Record name of temporary variable that possibly references a global input
|
||||
// We will replace the temporary variables by the matching global variables later
|
||||
case QShaderNode::Input: {
|
||||
const QString localVariable = match.captured(1);
|
||||
const QString globalVariable = match.captured(2);
|
||||
|
||||
@ -535,13 +549,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
Assignment assignment;
|
||||
assignment.expression = globalVariable;
|
||||
v->assignment = assignment;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QShaderNode::Function: {
|
||||
const QRegularExpressionMatch match = temporaryVariableToAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Function: {
|
||||
const QString localVariableDeclaration = match.captured(1);
|
||||
const QString localVariableName = match.captured(2);
|
||||
const QString assignmentContent = match.captured(3);
|
||||
@ -554,13 +565,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
|
||||
// Find variables that may be referenced in the assignment
|
||||
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QShaderNode::Output: {
|
||||
const QRegularExpressionMatch match = outputToTemporaryAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
|
||||
if (match.hasMatch()) {
|
||||
case QShaderNode::Output: {
|
||||
const QString outputDeclaration = match.captured(1);
|
||||
const QString assignmentContent = match.captured(2);
|
||||
|
||||
@ -575,17 +583,17 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
||||
|
||||
// Find variables that may be referenced in the assignment
|
||||
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
|
||||
break;
|
||||
}
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QShaderNode::Invalid:
|
||||
break;
|
||||
}
|
||||
|
||||
LineContent lineContent;
|
||||
lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
|
||||
lineContent.var = v;
|
||||
lines << lineContent;
|
||||
LineContent lineContent;
|
||||
lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
|
||||
lineContent.var = v;
|
||||
lines << lineContent;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through all lines
|
||||
|
@ -101,7 +101,13 @@ Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option)
|
||||
if (option)
|
||||
return option->fontMetrics.fontDpi();
|
||||
|
||||
// Fall back to historical Qt behavior: hardocded 72 DPI on mac,
|
||||
// primary screen DPI on other platforms.
|
||||
#ifdef Q_OS_DARWIN
|
||||
return qstyleBaseDpi;
|
||||
#else
|
||||
return qt_defaultDpiX();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
|
||||
|
@ -199,6 +199,8 @@ private slots:
|
||||
void shouldUseGlobalVariableRatherThanTemporaries();
|
||||
void shouldGenerateTemporariesWisely();
|
||||
void shouldHandlePortNamesPrefixingOneAnother();
|
||||
void shouldHandleNodesWithMultipleOutputPorts();
|
||||
void shouldHandleExpressionsInInputNodes();
|
||||
};
|
||||
|
||||
void tst_QShaderGenerator::shouldHaveDefaultState()
|
||||
@ -1299,6 +1301,127 @@ void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother()
|
||||
QCOMPARE(code, expected.join("\n"));
|
||||
}
|
||||
|
||||
void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts()
|
||||
{
|
||||
// GIVEN
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||
|
||||
auto input = createNode({
|
||||
createPort(QShaderNodePort::Output, "output0"),
|
||||
createPort(QShaderNodePort::Output, "output1")
|
||||
});
|
||||
input.addRule(gl4, QShaderNode::Rule("vec4 $output0 = globalIn0;"
|
||||
"float $output1 = globalIn1;",
|
||||
QByteArrayList() << "in vec4 globalIn0;" << "in float globalIn1;"));
|
||||
|
||||
auto function = createNode({
|
||||
createPort(QShaderNodePort::Input, "input0"),
|
||||
createPort(QShaderNodePort::Input, "input1"),
|
||||
createPort(QShaderNodePort::Output, "output0"),
|
||||
createPort(QShaderNodePort::Output, "output1")
|
||||
});
|
||||
function.addRule(gl4, QShaderNode::Rule("vec4 $output0 = $input0;"
|
||||
"float $output1 = $input1;"));
|
||||
|
||||
auto output = createNode({
|
||||
createPort(QShaderNodePort::Input, "input0"),
|
||||
createPort(QShaderNodePort::Input, "input1")
|
||||
});
|
||||
|
||||
output.addRule(gl4, QShaderNode::Rule("globalOut0 = $input0;"
|
||||
"globalOut1 = $input1;",
|
||||
QByteArrayList() << "out vec4 globalOut0;" << "out float globalOut1;"));
|
||||
|
||||
// WHEN
|
||||
const auto graph = [=] {
|
||||
auto res = QShaderGraph();
|
||||
|
||||
res.addNode(input);
|
||||
res.addNode(function);
|
||||
res.addNode(output);
|
||||
|
||||
res.addEdge(createEdge(input.uuid(), "output0", function.uuid(), "input0"));
|
||||
res.addEdge(createEdge(input.uuid(), "output1", function.uuid(), "input1"));
|
||||
|
||||
res.addEdge(createEdge(function.uuid(), "output0", output.uuid(), "input0"));
|
||||
res.addEdge(createEdge(function.uuid(), "output1", output.uuid(), "input1"));
|
||||
|
||||
return res;
|
||||
}();
|
||||
|
||||
auto generator = QShaderGenerator();
|
||||
generator.graph = graph;
|
||||
generator.format = gl4;
|
||||
|
||||
const auto code = generator.createShaderCode();
|
||||
|
||||
// THEN
|
||||
const auto expected = QByteArrayList()
|
||||
<< "#version 400 core"
|
||||
<< ""
|
||||
<< "in vec4 globalIn0;"
|
||||
<< "in float globalIn1;"
|
||||
<< "out vec4 globalOut0;"
|
||||
<< "out float globalOut1;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " globalOut0 = globalIn0;"
|
||||
<< " globalOut1 = globalIn1;"
|
||||
<< "}"
|
||||
<< "";
|
||||
QCOMPARE(code, expected.join("\n"));
|
||||
}
|
||||
|
||||
void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes()
|
||||
{
|
||||
// GIVEN
|
||||
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||
|
||||
auto input = createNode({
|
||||
createPort(QShaderNodePort::Output, "output")
|
||||
});
|
||||
input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;"));
|
||||
|
||||
auto output = createNode({
|
||||
createPort(QShaderNodePort::Input, "input")
|
||||
});
|
||||
|
||||
output.addRule(gl4, QShaderNode::Rule("globalOut = $input;",
|
||||
QByteArrayList() << "out float globalOut;"));
|
||||
|
||||
// WHEN
|
||||
const auto graph = [=] {
|
||||
auto res = QShaderGraph();
|
||||
|
||||
res.addNode(input);
|
||||
res.addNode(output);
|
||||
|
||||
res.addEdge(createEdge(input.uuid(), "output", output.uuid(), "input"));
|
||||
|
||||
return res;
|
||||
}();
|
||||
|
||||
auto generator = QShaderGenerator();
|
||||
generator.graph = graph;
|
||||
generator.format = gl4;
|
||||
|
||||
const auto code = generator.createShaderCode();
|
||||
|
||||
// THEN
|
||||
const auto expected = QByteArrayList()
|
||||
<< "#version 400 core"
|
||||
<< ""
|
||||
<< "out float globalOut;"
|
||||
<< ""
|
||||
<< "void main()"
|
||||
<< "{"
|
||||
<< " globalOut = 3 + 4;"
|
||||
<< "}"
|
||||
<< "";
|
||||
QCOMPARE(code, expected.join("\n"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QShaderGenerator)
|
||||
|
||||
#include "tst_qshadergenerator.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user