Support 'layout(when)' expressions in DSL C++.

This required some changes to how we name variables in DSL.
When-expressions are designed to expect a local C++ variable with the
same name as the layout key. This constraint means our DSLVar variables
CANNOT have the same name as the layout key. Now, all DSL variables are
given a prefix. We try to keep the code tidy by using just a leading
underscore as the prefix, where it's safe to do so. (The C++ naming
rules put some underscore-names out of bounds, but underscore followed
by a lowercase letter is safe.)

Change-Id: Iaa8878042329b9909096f05712d5cf636ea01822
Bug: skia:11854
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/400623
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2021-04-26 09:35:38 -04:00 committed by Skia Commit-Bot
parent 56ed7daeca
commit b9fc6e45c2
14 changed files with 328 additions and 223 deletions

View File

@ -1,11 +1,15 @@
layout(ctype=SkPMColor4f) in uniform half4 colorGreen, colorRed;
layout(key) in bool primaryColors;
layout(ctype=SkPMColor4f, when=primaryColors) in uniform half4 colorGreen, colorRed;
layout(ctype=SkPMColor4f, when=!primaryColors) in uniform half4 colorOrange, colorPurple;
half4 main() {
half4 green = primaryColors ? colorGreen : colorOrange;
half4 red = primaryColors ? colorRed : colorPurple;
bool t = true;
bool f = false;
return half4(t ? colorGreen.r : colorRed.r, // true -> colorGreen.r
f ? colorRed.g : colorGreen.g, // false -> colorGreen.g
(colorGreen.g == colorRed.r) ? colorGreen.b : colorRed.r, // true -> colorGreen.b
(colorGreen.a != colorRed.a) ? colorRed.g : colorGreen.a); // false -> colorGreen.a
return half4(t ? green.r : red.r, // true -> green.r
f ? red.g : green.g, // false -> green.g
(green.g == red.r) ? green.b : red.r, // true -> green.b
(green.a != red.a) ? red.g : green.a); // false -> green.a
}

View File

@ -511,21 +511,20 @@ static bool variable_exists_with_name(const std::unordered_map<const Variable*,
const char* DSLCPPCodeGenerator::getVariableCppName(const Variable& var) {
String& cppName = fVariableCppNames[&var];
if (cppName.empty()) {
if (!variable_exists_with_name(fVariableCppNames, var.name())) {
// Nothing needs to change; use the name as-is.
cppName = var.name();
} else {
// Another variable with the same name exists in the function, at a different scope.
// Append a numeric prefix to disambiguate the two. (This check could be more efficient,
// but it really doesn't matter much; this case is rare, and we don't compile DSL CPPs
// at Skia runtime.)
for (int prefix=0;; ++prefix) {
String prefixedName = String::printf("_%d_%.*s", prefix, (int)var.name().size(),
var.name().data());
if (!variable_exists_with_name(fVariableCppNames, prefixedName)) {
cppName = std::move(prefixedName);
break;
}
// Append a prefix to the variable name. This serves two purposes:
// - disambiguates variables with the same name that live in different SkSL scopes
// - gives the DSLVar a distinct name, leaving the original name free to be given to a
// C++ constant, for the case of layout-keys that need to work in C++ `when` expressions
// Probing for a unique name could be more efficient, but it really doesn't matter much;
// overlapping names are super rare, and we only compile DSLs in skslc at build time.
for (int prefix = 0;; ++prefix) {
String prefixedName = (prefix > 0 || !islower(var.name()[0]))
? String::printf("_%d_%.*s", prefix, (int)var.name().size(), var.name().data())
: String::printf("_%.*s", (int)var.name().size(), var.name().data());
if (!variable_exists_with_name(fVariableCppNames, prefixedName)) {
cppName = std::move(prefixedName);
break;
}
}
}
@ -533,20 +532,24 @@ const char* DSLCPPCodeGenerator::getVariableCppName(const Variable& var) {
return cppName.c_str();
}
void DSLCPPCodeGenerator::writeVar(const Variable& var) {
this->write("Var ");
this->write(this->getVariableCppName(var));
this->write("(");
void DSLCPPCodeGenerator::writeVarCtorExpression(const Variable& var) {
this->write(this->getDSLModifiers(var.modifiers()));
this->write(", ");
this->write(this->getDSLType(var.type()));
this->write(", \"");
this->write(this->getVariableCppName(var));
this->write(var.name());
this->write("\"");
if (var.initialValue()) {
this->write(", ");
this->writeExpression(*var.initialValue(), Precedence::kTopLevel);
}
}
void DSLCPPCodeGenerator::writeVar(const Variable& var) {
this->write("Var ");
this->write(this->getVariableCppName(var));
this->write("(");
this->writeVarCtorExpression(var);
this->write(");\n");
}
@ -738,6 +741,17 @@ String DSLCPPCodeGenerator::getDSLModifiers(const Modifiers& modifiers) {
return text;
}
String DSLCPPCodeGenerator::getDefaultDSLValue(const Variable& var) {
// TODO: default_value returns half4(NaN) for colors, but DSL aborts if passed a literal NaN.
// Theoretically this really shouldn't matter.
switch (var.type().typeKind()) {
case Type::TypeKind::kScalar:
case Type::TypeKind::kVector: return this->getTypeName(var.type()) + "(0)";
case Type::TypeKind::kMatrix: return this->getTypeName(var.type()) + "(1)";
default: SK_ABORT("unsupported type: %s", var.type().description().c_str());
}
}
void DSLCPPCodeGenerator::writeStatement(const Statement& s) {
switch (s.kind()) {
case Statement::Kind::kBlock:
@ -829,16 +843,35 @@ void DSLCPPCodeGenerator::addUniform(const Variable& var) {
if (!needs_uniform_var(var)) {
return;
}
const char* varCppName = this->getVariableCppName(var);
if (var.modifiers().fLayout.fWhen.fLength) {
this->writef(" if (%s) {\n ", String(var.modifiers().fLayout.fWhen).c_str());
// In cases where the `when` clause is true, we set up the Var normally.
this->writef(
"Var %s;\n"
"if (%.*s) {\n"
" Var(",
varCppName,
(int)var.modifiers().fLayout.fWhen.size(), var.modifiers().fLayout.fWhen.data());
this->writeVarCtorExpression(var);
this->writef(").swap(%s);\n ", varCppName);
} else {
this->writeVar(var);
}
this->writeVar(var);
this->writef("%.*sVar = VarUniformHandle(%s);\n",
(int)var.name().size(), var.name().data(), this->getVariableCppName(var));
if (var.modifiers().fLayout.fWhen.fLength) {
this->write(" }\n");
// In cases where the `when` is false, we declare the Var as a const with a default value.
this->writef("} else {\n"
" Var(kConst_Modifier, %s, \"%.*s\", %s).swap(%s);\n"
" Declare(%s);\n"
"}\n",
this->getDSLType(var.type()).c_str(),
(int)var.name().size(), var.name().data(),
this->getDefaultDSLValue(var).c_str(),
varCppName, varCppName);
}
}
@ -927,12 +960,16 @@ bool DSLCPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms)
// the variable (which we do need, to fill in the Var's initial value).
std::vector<String> argumentList;
(void) this->formatRuntimeValue(var.type(), var.modifiers().fLayout,
"_outer." + var.name(), &argumentList);
var.name(), &argumentList);
const char* varCppName = this->getVariableCppName(var);
this->writef("Var %s(kConst_Modifier, %s, \"%s\", %s(",
this->writef("[[maybe_unused]] const auto& %.*s = _outer.%.*s;\n"
"Var %s(kConst_Modifier, %s, \"%.*s\", %s(",
(int)var.name().size(), var.name().data(),
(int)var.name().size(), var.name().data(),
varCppName, this->getDSLType(var.type()).c_str(),
varCppName, this->getTypeName(var.type()).c_str());
(int)var.name().size(), var.name().data(),
this->getTypeName(var.type()).c_str());
const char* separator = "";
for (const String& arg : argumentList) {
this->write(separator);
@ -1061,12 +1098,9 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
const Variable& variable = decl.var();
if (needs_uniform_var(variable)) {
const char* varCppName = this->getVariableCppName(variable);
this->writef(" UniformHandle& %s = %.*sVar;\n"
" (void) %s;\n",
varCppName, (int)variable.name().size(),
variable.name().data(), varCppName);
this->writef(" [[maybe_unused]] UniformHandle& %.*s = %.*sVar;\n",
(int)variable.name().size(), variable.name().data(),
(int)variable.name().size(), variable.name().data());
} else if (SectionAndParameterHelper::IsParameter(variable) &&
!variable.type().isFragmentProcessor()) {
if (!wroteProcessor) {
@ -1076,12 +1110,9 @@ void DSLCPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
}
if (!variable.type().isFragmentProcessor()) {
const char* varCppName = this->getVariableCppName(variable);
this->writef(" auto %s = _outer.%.*s;\n"
" (void) %s;\n",
varCppName, (int)variable.name().size(),
variable.name().data(), varCppName);
this->writef(" [[maybe_unused]] const auto& %.*s = _outer.%.*s;\n",
(int)variable.name().size(), variable.name().data(),
(int)variable.name().size(), variable.name().data());
}
}
}

View File

@ -53,6 +53,8 @@ private:
void writeVar(const Variable& var);
void writeVarCtorExpression(const Variable& var);
void writeVarDeclaration(const VarDeclaration& var, bool global);
void writef(const char* s, va_list va) SK_PRINTF_LIKE(2, 0);
@ -71,6 +73,8 @@ private:
String getDSLModifiers(const Modifiers& type);
String getDefaultDSLValue(const Variable& var);
void writeSwizzle(const Swizzle& swizzle) override;
void writeVariableReference(const VariableReference& ref) override;

View File

@ -76,8 +76,11 @@ static void test_dsl_fp(skiatest::Reporter* r,
DSL_FP_TEST_ES2(DSLFPTest_IfStatement, /*one:*/ 1.0f)
DSL_FP_TEST_ES2(DSLFPTest_Swizzle)
DSL_FP_TEST_ES2(DSLFPTest_Ternary, /*colorGreen:*/ SkPMColor4f{0, 1, 0, 1},
/*colorRed:*/ SkPMColor4f{1, 0, 0, 1})
DSL_FP_TEST_ES2(DSLFPTest_Ternary, /*primaryColors:*/true,
/*colorGreen:*/ SkPMColor4f{0.0, 1.0, 0.0, 1.0},
/*colorRed:*/ SkPMColor4f{1.0, 0.0, 0.0, 1.0},
/*colorOrange:*/ SkPMColor4f{1.0, 0.5, 0.0, 1.0},
/*colorPurple:*/ SkPMColor4f{0.5, 0.0, 0.5, 1.0})
DSL_FP_TEST(DSLFPTest_DoStatement, /*shouldLoop:*/ false)
DSL_FP_TEST(DSLFPTest_ForStatement, /*colorWhite:*/ SkPMColor4f{1, 1, 1, 1})
DSL_FP_TEST(DSLFPTest_SwitchStatement)

View File

@ -29,53 +29,53 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var m(kNo_Modifier, DSLType(kHalf4x4_Type), "m", Half4x4(1.0f));
Var n(kNo_Modifier, DSLType(kHalf4_Type), "n", Half4(1.0f));
Var b(kNo_Modifier, DSLType(kBool4_Type), "b", Bool4(true));
Declare(m);
Declare(n);
Declare(b);
n.x() = Abs(n.x());
b.z() = All(Swizzle(b, X, Y));
b.w() = Any(Swizzle(b, X, Y, Z));
n = Ceil(n);
n.x() = Clamp(n.y(), n.z(), n.w());
n.y() = Cos(n.y());
n.w() = n.x() * n.w() - n.y() * n.z();
Swizzle(n, X, Y, Z) = Degrees(Swizzle(n, X, Y, Z));
n.w() = Distance(Swizzle(n, X, Z), Swizzle(n, Y, W));
n.x() = Dot(Swizzle(n, Y, Z, W), Swizzle(n, Y, Z, W));
Swizzle(b, X, Y, Z) = Equal(Swizzle(b, X, X, X), Swizzle(b, W, W, W));
Swizzle(n, Y, Z) = Exp(Swizzle(n, W, X));
Swizzle(n, Z, W) = Exp2(Swizzle(n, X, Y));
n.x() = Faceforward(n.y(), n.z(), n.w());
n = Floor(n);
Swizzle(n, Y, Z, W) = Fract(Swizzle(n, Y, Z, W));
Swizzle(b, X, Y) = GreaterThan(Swizzle(n, X, Y), Swizzle(n, Z, W));
Swizzle(b, X, Y) = GreaterThanEqual(Swizzle(n, X, Y), Swizzle(n, Z, W));
n = Inversesqrt(n);
m = Inverse(m);
n.w() = Length(Swizzle(n, Z, Y, Y, X));
Swizzle(b, X, Y) = LessThan(Swizzle(n, X, Y), Swizzle(n, Z, W));
Swizzle(b, X, Y) = LessThanEqual(Swizzle(n, X, Y), Swizzle(n, Z, W));
n.x() = Log(n.x());
n.y() = Max(n.z(), n.w());
n.z() = Min(n.x(), n.y());
n.w() = Mod(n.y(), n.z());
n = Normalize(n);
b = Not(b);
n.x() = Pow(n.y(), n.z());
Swizzle(n, X, Y, Z) = Radians(Swizzle(n, Y, Z, W));
Swizzle(n, X, Y) = Reflect(Swizzle(n, X, Y), Swizzle(n, Z, W));
Swizzle(n, W, Z) = Refract(Swizzle(n, X, Y), Swizzle(n, Z, W), 2.0f);
n = Saturate(n);
n.x() = Sign(n.x());
n.y() = Sin(n.y());
Swizzle(n, Z, W) = Smoothstep(Swizzle(n, X, X), Swizzle(n, Y, Y), Swizzle(n, Z, Z));
n = Sqrt(n);
Swizzle(n, X, Y) = Step(Swizzle(n, X, Y), Swizzle(n, Z, W));
n.x() = Tan(n.x());
n = Half4(Swizzle(n, W, W, W) / Max(n.w(), 9.9999997473787516e-05f), n.w());
Var _m(kNo_Modifier, DSLType(kHalf4x4_Type), "m", Half4x4(1.0f));
Var _n(kNo_Modifier, DSLType(kHalf4_Type), "n", Half4(1.0f));
Var _b(kNo_Modifier, DSLType(kBool4_Type), "b", Bool4(true));
Declare(_m);
Declare(_n);
Declare(_b);
_n.x() = Abs(_n.x());
_b.z() = All(Swizzle(_b, X, Y));
_b.w() = Any(Swizzle(_b, X, Y, Z));
_n = Ceil(_n);
_n.x() = Clamp(_n.y(), _n.z(), _n.w());
_n.y() = Cos(_n.y());
_n.w() = _n.x() * _n.w() - _n.y() * _n.z();
Swizzle(_n, X, Y, Z) = Degrees(Swizzle(_n, X, Y, Z));
_n.w() = Distance(Swizzle(_n, X, Z), Swizzle(_n, Y, W));
_n.x() = Dot(Swizzle(_n, Y, Z, W), Swizzle(_n, Y, Z, W));
Swizzle(_b, X, Y, Z) = Equal(Swizzle(_b, X, X, X), Swizzle(_b, W, W, W));
Swizzle(_n, Y, Z) = Exp(Swizzle(_n, W, X));
Swizzle(_n, Z, W) = Exp2(Swizzle(_n, X, Y));
_n.x() = Faceforward(_n.y(), _n.z(), _n.w());
_n = Floor(_n);
Swizzle(_n, Y, Z, W) = Fract(Swizzle(_n, Y, Z, W));
Swizzle(_b, X, Y) = GreaterThan(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
Swizzle(_b, X, Y) = GreaterThanEqual(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
_n = Inversesqrt(_n);
_m = Inverse(_m);
_n.w() = Length(Swizzle(_n, Z, Y, Y, X));
Swizzle(_b, X, Y) = LessThan(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
Swizzle(_b, X, Y) = LessThanEqual(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
_n.x() = Log(_n.x());
_n.y() = Max(_n.z(), _n.w());
_n.z() = Min(_n.x(), _n.y());
_n.w() = Mod(_n.y(), _n.z());
_n = Normalize(_n);
_b = Not(_b);
_n.x() = Pow(_n.y(), _n.z());
Swizzle(_n, X, Y, Z) = Radians(Swizzle(_n, Y, Z, W));
Swizzle(_n, X, Y) = Reflect(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
Swizzle(_n, W, Z) = Refract(Swizzle(_n, X, Y), Swizzle(_n, Z, W), 2.0f);
_n = Saturate(_n);
_n.x() = Sign(_n.x());
_n.y() = Sin(_n.y());
Swizzle(_n, Z, W) = Smoothstep(Swizzle(_n, X, X), Swizzle(_n, Y, Y), Swizzle(_n, Z, Z));
_n = Sqrt(_n);
Swizzle(_n, X, Y) = Step(Swizzle(_n, X, Y), Swizzle(_n, Z, W));
_n.x() = Tan(_n.x());
_n = Half4(Swizzle(_n, W, W, W) / Max(_n.w(), 9.9999997473787516e-05f), _n.w());
Return(Half4(0.0f, 1.0f, 0.0f, 1.0f));
EndFragmentProcessor();
}

View File

@ -29,14 +29,15 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var shouldLoop(kConst_Modifier, DSLType(kBool_Type), "shouldLoop", Bool(!!(_outer.shouldLoop)));
Declare(shouldLoop);
Var color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(1.0f, 1.0f, 1.0f, 1.0f));
Declare(color);
Do(color.x() -= 0.25f, /*While:*/ shouldLoop);
Do(Block(color.x() -= 0.25f, If(color.x() <= 0.0f, /*Then:*/ Break())), /*While:*/ color.w() == 1.0f);
Do(Block(color.z() -= 0.25f, If(color.w() == 1.0f || sk_Caps.builtinFMASupport(), /*Then:*/ Continue()), color.y() = 0.0f), /*While:*/ color.z() > 0.0f);
Return(color);
[[maybe_unused]] const auto& shouldLoop = _outer.shouldLoop;
Var _shouldLoop(kConst_Modifier, DSLType(kBool_Type), "shouldLoop", Bool(!!(shouldLoop)));
Declare(_shouldLoop);
Var _color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(1.0f, 1.0f, 1.0f, 1.0f));
Declare(_color);
Do(_color.x() -= 0.25f, /*While:*/ _shouldLoop);
Do(Block(_color.x() -= 0.25f, If(_color.x() <= 0.0f, /*Then:*/ Break())), /*While:*/ _color.w() == 1.0f);
Do(Block(_color.z() -= 0.25f, If(_color.w() == 1.0f || sk_Caps.builtinFMASupport(), /*Then:*/ Continue()), _color.y() = 0.0f), /*While:*/ _color.z() > 0.0f);
Return(_color);
EndFragmentProcessor();
}
private:

View File

@ -29,17 +29,18 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var colorWhite(kConst_Modifier, DSLType(kHalf4_Type), "colorWhite", Half4(_outer.colorWhite.fR, _outer.colorWhite.fG, _outer.colorWhite.fB, _outer.colorWhite.fA));
Declare(colorWhite);
Var color(kNo_Modifier, DSLType(kHalf4_Type), "color", colorWhite);
Var a(kNo_Modifier, DSLType(kHalf_Type), "a", 0.0f);
Var r(kNo_Modifier, DSLType(kHalf_Type), "r", -5.0f);
Var b(kNo_Modifier, DSLType(kHalf_Type), "b", 5.0f);
Declare(color);
For(Declare(a), a <= 1.0f, ++a, /*Body:*/ color.w() = a);
For(Declare(r), r < 5.0f, r += 1.0f, /*Body:*/ Block(color.x() = r, If(color.x() == 0.0f, /*Then:*/ Break())));
For(Declare(b), b >= 0.0f, b -= 1.0f, /*Body:*/ Block(color.z() = b, If(color.w() == 1.0f, /*Then:*/ Continue()), color.y() = 0.0f));
Return(color);
[[maybe_unused]] const auto& colorWhite = _outer.colorWhite;
Var _colorWhite(kConst_Modifier, DSLType(kHalf4_Type), "colorWhite", Half4(colorWhite.fR, colorWhite.fG, colorWhite.fB, colorWhite.fA));
Declare(_colorWhite);
Var _color(kNo_Modifier, DSLType(kHalf4_Type), "color", _colorWhite);
Var _a(kNo_Modifier, DSLType(kHalf_Type), "a", 0.0f);
Var _r(kNo_Modifier, DSLType(kHalf_Type), "r", -5.0f);
Var _b(kNo_Modifier, DSLType(kHalf_Type), "b", 5.0f);
Declare(_color);
For(Declare(_a), _a <= 1.0f, ++_a, /*Body:*/ _color.w() = _a);
For(Declare(_r), _r < 5.0f, _r += 1.0f, /*Body:*/ Block(_color.x() = _r, If(_color.x() == 0.0f, /*Then:*/ Break())));
For(Declare(_b), _b >= 0.0f, _b -= 1.0f, /*Body:*/ Block(_color.z() = _b, If(_color.w() == 1.0f, /*Then:*/ Continue()), _color.y() = 0.0f));
Return(_color);
EndFragmentProcessor();
}
private:

View File

@ -29,16 +29,17 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var one(kConst_Modifier, DSLType(kHalf_Type), "one", Half(_outer.one));
Declare(one);
Var color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(0.0f));
Declare(color);
If(Swizzle(color, X, Y) == Swizzle(color, Z, W), /*Then:*/ color.w() = one);
If(Swizzle(color, X, Y) == Swizzle(color, Z, W), /*Then:*/ Block(color.x() = color.w()));
If(color.x() == color.y(), /*Then:*/ color = Swizzle(color, W, X, W, W), /*Else:*/ color = Swizzle(color, X, X, X, W));
If(((color.x() + color.y()) + color.z()) + color.w() == one, /*Then:*/ Block(color = Half4(-1.0f)), /*Else:*/ If(((color.x() + color.y()) + color.z()) + color.w() == 2.0f, /*Then:*/ Block(color = Half4(-2.0f)), /*Else:*/ Block(color = Swizzle(color, Y, Y, W, W))));
If(color.x() == one, /*Then:*/ Block(If(color.x() == 2.0f, /*Then:*/ Block(color = Swizzle(color, X, X, X, X)), /*Else:*/ Block(color = Swizzle(color, Y, Y, Y, Y)))), /*Else:*/ Block(If(color.z() * color.w() == one, /*Then:*/ Block(color = Swizzle(color, X, Z, Y, W)), /*Else:*/ Block(color = Swizzle(color, W, W, W, W)))));
Return(color);
[[maybe_unused]] const auto& one = _outer.one;
Var _one(kConst_Modifier, DSLType(kHalf_Type), "one", Half(one));
Declare(_one);
Var _color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(0.0f));
Declare(_color);
If(Swizzle(_color, X, Y) == Swizzle(_color, Z, W), /*Then:*/ _color.w() = _one);
If(Swizzle(_color, X, Y) == Swizzle(_color, Z, W), /*Then:*/ Block(_color.x() = _color.w()));
If(_color.x() == _color.y(), /*Then:*/ _color = Swizzle(_color, W, X, W, W), /*Else:*/ _color = Swizzle(_color, X, X, X, W));
If(((_color.x() + _color.y()) + _color.z()) + _color.w() == _one, /*Then:*/ Block(_color = Half4(-1.0f)), /*Else:*/ If(((_color.x() + _color.y()) + _color.z()) + _color.w() == 2.0f, /*Then:*/ Block(_color = Half4(-2.0f)), /*Else:*/ Block(_color = Swizzle(_color, Y, Y, W, W))));
If(_color.x() == _one, /*Then:*/ Block(If(_color.x() == 2.0f, /*Then:*/ Block(_color = Swizzle(_color, X, X, X, X)), /*Else:*/ Block(_color = Swizzle(_color, Y, Y, Y, Y)))), /*Else:*/ Block(If(_color.z() * _color.w() == _one, /*Then:*/ Block(_color = Swizzle(_color, X, Z, Y, W)), /*Else:*/ Block(_color = Swizzle(_color, W, W, W, W)))));
Return(_color);
EndFragmentProcessor();
}
private:

View File

@ -29,13 +29,13 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var coords(kConst_Modifier, DSLType(kFloat2_Type), "coords", Float2(0.5f));
Var xform(kConst_Modifier, DSLType(kFloat3x3_Type), "xform", Float3x3(2.0f));
Var inColor(kConst_Modifier, DSLType(kHalf4_Type), "inColor", Half4(0.75f));
Declare(coords);
Declare(xform);
Declare(inColor);
Return(((((SampleChild(0) * SampleChild(1, coords)) * SampleChild(2, xform)) * SampleChild(0, inColor)) * SampleChild(1, coords, inColor)) * SampleChild(2, xform, inColor));
Var _coords(kConst_Modifier, DSLType(kFloat2_Type), "coords", Float2(0.5f));
Var _xform(kConst_Modifier, DSLType(kFloat3x3_Type), "xform", Float3x3(2.0f));
Var _inColor(kConst_Modifier, DSLType(kHalf4_Type), "inColor", Half4(0.75f));
Declare(_coords);
Declare(_xform);
Declare(_inColor);
Return(((((SampleChild(0) * SampleChild(1, _coords)) * SampleChild(2, _xform)) * SampleChild(0, _inColor)) * SampleChild(1, _coords, _inColor)) * SampleChild(2, _xform, _inColor));
EndFragmentProcessor();
}
private:

View File

@ -29,21 +29,21 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var color(kNo_Modifier, DSLType(kInt4_Type), "color", Int4(0));
Declare(color);
Switch(color.x(),
Case(0, ++color.y()),
Var _color(kNo_Modifier, DSLType(kInt4_Type), "color", Int4(0));
Declare(_color);
Switch(_color.x(),
Case(0, ++_color.y()),
Case(1, Break()),
Case(2, Return(Half4(0.0f))),
Case(3),
Case(4, ++color.x()),
Case(5, Block(++color.z()), Break()),
Default(Block(--color.y(), Break())));
Switch(color.y(),
Case(4, ++_color.x()),
Case(5, Block(++_color.z()), Break()),
Default(Block(--_color.y(), Break())));
Switch(_color.y(),
Case(1, Break()),
Case(0, Block(color.x() = 1, color.z() = 1)));
Block(color.w() = color.y());
Return(Half4(color));
Case(0, Block(_color.x() = 1, _color.z() = 1)));
Block(_color.w() = _color.y());
Return(Half4(_color));
EndFragmentProcessor();
}
private:

View File

@ -29,67 +29,67 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var v(kNo_Modifier, DSLType(kHalf4_Type), "v", Half4(1.0f, 2.0f, 3.0f, 4.0f));
Var b(kNo_Modifier, DSLType(kBool4_Type), "b", Bool4(true, true, true, true));
Declare(v);
v = Half4(v.x(), 1.0f, 1.0f, 1.0f);
v = Half4(Swizzle(v, X, Y), 1.0f, 1.0f);
v = Half4(v.x(), 1.0f, 1.0f, 1.0f);
v = Half4(0.0f, v.y(), 1.0f, 1.0f);
v = Half4(Swizzle(v, X, Y, Z), 1.0f);
v = Half4(Swizzle(v, X, Y), 1.0f, 1.0f);
v = Half4(v.x(), 0.0f, v.z(), 1.0f);
v = Half4(v.x(), 1.0f, 0.0f, 1.0f);
v = Half4(1.0f, Swizzle(v, Y, Z), 1.0f);
v = Half4(0.0f, v.y(), 1.0f, 1.0f);
v = Half4(1.0f, 1.0f, v.z(), 1.0f);
v = Half4(Swizzle(v, X, Y, Z), 1.0f);
v = Swizzle(v, W, W, W, W);
v = Half4(Swizzle(v, X, Y), 1.0f, 0.0f);
v = Swizzle(v, X, Z, Z, X);
v = Half4(v.x(), 0.0f, v.z(), 1.0f);
v = Half4(v.x(), 1.0f, 1.0f, v.w());
v = Half4(v.x(), 1.0f, 0.0f, 1.0f);
v = Half4(1.0f, Swizzle(v, Y, Z, W));
v = Half4(0.0f, Swizzle(v, Y, Z), 1.0f);
v = Half4(0.0f, v.y(), 1.0f, v.w());
v = Half4(1.0f, v.y(), 1.0f, 1.0f);
v = Half4(0.0f, 0.0f, Swizzle(v, Z, W));
v = Half4(0.0f, 0.0f, v.z(), 1.0f);
v = Half4(0.0f, 1.0f, 1.0f, v.w());
v = Half4(0.0f, Swizzle(v, Z, Y, X));
v = Half4(0.0f, 0.0f, Swizzle(v, X, W));
v = Half4(1.0f, 1.0f, Swizzle(v, W, X));
v = Half4(Swizzle(v, Z, Y), 1.0f, 1.0f);
v = Half4(Swizzle(v, X, X), 1.0f, 1.0f);
v = Swizzle(v, W, Z, W, Z);
Declare(b);
b = Bool4(b.x(), true, true, true);
b = Bool4(Swizzle(b, X, Y), false, true);
b = Bool4(b.x(), true, true, false);
b = Bool4(false, b.y(), true, true);
b = Bool4(Swizzle(b, X, Y, Z), true);
b = Bool4(Swizzle(b, X, Y), true, true);
b = Bool4(b.x(), false, b.z(), true);
b = Bool4(b.x(), true, false, false);
b = Bool4(true, Swizzle(b, Y, Z), false);
b = Bool4(false, b.y(), true, false);
b = Bool4(true, true, b.z(), false);
b = Bool4(Swizzle(b, X, Y, Z), true);
b = Swizzle(b, W, W, W, W);
b = Bool4(Swizzle(b, X, Y), true, false);
b = Swizzle(b, X, Z, Z, X);
b = Bool4(b.x(), false, b.z(), true);
b = Bool4(b.x(), true, true, b.w());
b = Bool4(b.x(), true, false, true);
b = Bool4(true, Swizzle(b, Y, Z, W));
b = Bool4(false, Swizzle(b, Y, Z), true);
b = Bool4(false, b.y(), true, b.w());
b = Bool4(true, b.y(), true, true);
b = Bool4(false, false, Swizzle(b, Z, W));
b = Bool4(false, false, b.z(), true);
b = Bool4(false, true, true, b.w());
Return(Half4(Half2(Swizzle(b, X, Y)), 0.0f, v.z()));
Var _v(kNo_Modifier, DSLType(kHalf4_Type), "v", Half4(1.0f, 2.0f, 3.0f, 4.0f));
Var _b(kNo_Modifier, DSLType(kBool4_Type), "b", Bool4(true, true, true, true));
Declare(_v);
_v = Half4(_v.x(), 1.0f, 1.0f, 1.0f);
_v = Half4(Swizzle(_v, X, Y), 1.0f, 1.0f);
_v = Half4(_v.x(), 1.0f, 1.0f, 1.0f);
_v = Half4(0.0f, _v.y(), 1.0f, 1.0f);
_v = Half4(Swizzle(_v, X, Y, Z), 1.0f);
_v = Half4(Swizzle(_v, X, Y), 1.0f, 1.0f);
_v = Half4(_v.x(), 0.0f, _v.z(), 1.0f);
_v = Half4(_v.x(), 1.0f, 0.0f, 1.0f);
_v = Half4(1.0f, Swizzle(_v, Y, Z), 1.0f);
_v = Half4(0.0f, _v.y(), 1.0f, 1.0f);
_v = Half4(1.0f, 1.0f, _v.z(), 1.0f);
_v = Half4(Swizzle(_v, X, Y, Z), 1.0f);
_v = Swizzle(_v, W, W, W, W);
_v = Half4(Swizzle(_v, X, Y), 1.0f, 0.0f);
_v = Swizzle(_v, X, Z, Z, X);
_v = Half4(_v.x(), 0.0f, _v.z(), 1.0f);
_v = Half4(_v.x(), 1.0f, 1.0f, _v.w());
_v = Half4(_v.x(), 1.0f, 0.0f, 1.0f);
_v = Half4(1.0f, Swizzle(_v, Y, Z, W));
_v = Half4(0.0f, Swizzle(_v, Y, Z), 1.0f);
_v = Half4(0.0f, _v.y(), 1.0f, _v.w());
_v = Half4(1.0f, _v.y(), 1.0f, 1.0f);
_v = Half4(0.0f, 0.0f, Swizzle(_v, Z, W));
_v = Half4(0.0f, 0.0f, _v.z(), 1.0f);
_v = Half4(0.0f, 1.0f, 1.0f, _v.w());
_v = Half4(0.0f, Swizzle(_v, Z, Y, X));
_v = Half4(0.0f, 0.0f, Swizzle(_v, X, W));
_v = Half4(1.0f, 1.0f, Swizzle(_v, W, X));
_v = Half4(Swizzle(_v, Z, Y), 1.0f, 1.0f);
_v = Half4(Swizzle(_v, X, X), 1.0f, 1.0f);
_v = Swizzle(_v, W, Z, W, Z);
Declare(_b);
_b = Bool4(_b.x(), true, true, true);
_b = Bool4(Swizzle(_b, X, Y), false, true);
_b = Bool4(_b.x(), true, true, false);
_b = Bool4(false, _b.y(), true, true);
_b = Bool4(Swizzle(_b, X, Y, Z), true);
_b = Bool4(Swizzle(_b, X, Y), true, true);
_b = Bool4(_b.x(), false, _b.z(), true);
_b = Bool4(_b.x(), true, false, false);
_b = Bool4(true, Swizzle(_b, Y, Z), false);
_b = Bool4(false, _b.y(), true, false);
_b = Bool4(true, true, _b.z(), false);
_b = Bool4(Swizzle(_b, X, Y, Z), true);
_b = Swizzle(_b, W, W, W, W);
_b = Bool4(Swizzle(_b, X, Y), true, false);
_b = Swizzle(_b, X, Z, Z, X);
_b = Bool4(_b.x(), false, _b.z(), true);
_b = Bool4(_b.x(), true, true, _b.w());
_b = Bool4(_b.x(), true, false, true);
_b = Bool4(true, Swizzle(_b, Y, Z, W));
_b = Bool4(false, Swizzle(_b, Y, Z), true);
_b = Bool4(false, _b.y(), true, _b.w());
_b = Bool4(true, _b.y(), true, true);
_b = Bool4(false, false, Swizzle(_b, Z, W));
_b = Bool4(false, false, _b.z(), true);
_b = Bool4(false, true, true, _b.w());
Return(Half4(Half2(Swizzle(_b, X, Y)), 0.0f, _v.z()));
EndFragmentProcessor();
}
private:

View File

@ -29,44 +29,98 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var colorGreen(kUniform_Modifier, DSLType(kHalf4_Type), "colorGreen");
colorGreenVar = VarUniformHandle(colorGreen);
Var colorRed(kUniform_Modifier, DSLType(kHalf4_Type), "colorRed");
colorRedVar = VarUniformHandle(colorRed);
Var t(kNo_Modifier, DSLType(kBool_Type), "t", true);
Var f(kNo_Modifier, DSLType(kBool_Type), "f", false);
Declare(t);
Declare(f);
Return(Half4(Select(t, /*If True:*/ colorGreen.x(), /*If False:*/ colorRed.x()), Select(f, /*If True:*/ colorRed.y(), /*If False:*/ colorGreen.y()), Select(colorGreen.y() == colorRed.x(), /*If True:*/ colorGreen.z(), /*If False:*/ colorRed.x()), Select(colorGreen.w() != colorRed.w(), /*If True:*/ colorRed.y(), /*If False:*/ colorGreen.w())));
[[maybe_unused]] const auto& primaryColors = _outer.primaryColors;
Var _primaryColors(kConst_Modifier, DSLType(kBool_Type), "primaryColors", Bool(!!(primaryColors)));
Declare(_primaryColors);
Var _colorGreen;
if (primaryColors) {
Var(kUniform_Modifier, DSLType(kHalf4_Type), "colorGreen").swap(_colorGreen);
colorGreenVar = VarUniformHandle(_colorGreen);
} else {
Var(kConst_Modifier, DSLType(kHalf4_Type), "colorGreen", Half4(0)).swap(_colorGreen);
Declare(_colorGreen);
}
Var _colorRed;
if (primaryColors) {
Var(kUniform_Modifier, DSLType(kHalf4_Type), "colorRed").swap(_colorRed);
colorRedVar = VarUniformHandle(_colorRed);
} else {
Var(kConst_Modifier, DSLType(kHalf4_Type), "colorRed", Half4(0)).swap(_colorRed);
Declare(_colorRed);
}
Var _colorOrange;
if (!primaryColors) {
Var(kUniform_Modifier, DSLType(kHalf4_Type), "colorOrange").swap(_colorOrange);
colorOrangeVar = VarUniformHandle(_colorOrange);
} else {
Var(kConst_Modifier, DSLType(kHalf4_Type), "colorOrange", Half4(0)).swap(_colorOrange);
Declare(_colorOrange);
}
Var _colorPurple;
if (!primaryColors) {
Var(kUniform_Modifier, DSLType(kHalf4_Type), "colorPurple").swap(_colorPurple);
colorPurpleVar = VarUniformHandle(_colorPurple);
} else {
Var(kConst_Modifier, DSLType(kHalf4_Type), "colorPurple", Half4(0)).swap(_colorPurple);
Declare(_colorPurple);
}
Var _green(kNo_Modifier, DSLType(kHalf4_Type), "green", Select(_primaryColors, /*If True:*/ _colorGreen, /*If False:*/ _colorOrange));
Var _red(kNo_Modifier, DSLType(kHalf4_Type), "red", Select(_primaryColors, /*If True:*/ _colorRed, /*If False:*/ _colorPurple));
Var _t(kNo_Modifier, DSLType(kBool_Type), "t", true);
Var _f(kNo_Modifier, DSLType(kBool_Type), "f", false);
Declare(_green);
Declare(_red);
Declare(_t);
Declare(_f);
Return(Half4(Select(_t, /*If True:*/ _green.x(), /*If False:*/ _red.x()), Select(_f, /*If True:*/ _red.y(), /*If False:*/ _green.y()), Select(_green.y() == _red.x(), /*If True:*/ _green.z(), /*If False:*/ _red.x()), Select(_green.w() != _red.w(), /*If True:*/ _red.y(), /*If False:*/ _green.w())));
EndFragmentProcessor();
}
private:
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
const GrDSLFPTest_Ternary& _outer = _proc.cast<GrDSLFPTest_Ternary>();
{
pdman.set4fv(colorGreenVar, 1, (_outer.colorGreen).vec());
pdman.set4fv(colorRedVar, 1, (_outer.colorRed).vec());
if (colorGreenVar.isValid()) {
pdman.set4fv(colorGreenVar, 1, (_outer.colorGreen).vec());
}
if (colorRedVar.isValid()) {
pdman.set4fv(colorRedVar, 1, (_outer.colorRed).vec());
}
if (colorOrangeVar.isValid()) {
pdman.set4fv(colorOrangeVar, 1, (_outer.colorOrange).vec());
}
if (colorPurpleVar.isValid()) {
pdman.set4fv(colorPurpleVar, 1, (_outer.colorPurple).vec());
}
}
}
UniformHandle colorGreenVar;
UniformHandle colorRedVar;
UniformHandle colorOrangeVar;
UniformHandle colorPurpleVar;
};
std::unique_ptr<GrGLSLFragmentProcessor> GrDSLFPTest_Ternary::onMakeProgramImpl() const {
return std::make_unique<GrGLSLDSLFPTest_Ternary>();
}
void GrDSLFPTest_Ternary::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
b->addBool(primaryColors, "primaryColors");
}
bool GrDSLFPTest_Ternary::onIsEqual(const GrFragmentProcessor& other) const {
const GrDSLFPTest_Ternary& that = other.cast<GrDSLFPTest_Ternary>();
(void) that;
if (primaryColors != that.primaryColors) return false;
if (colorGreen != that.colorGreen) return false;
if (colorRed != that.colorRed) return false;
if (colorOrange != that.colorOrange) return false;
if (colorPurple != that.colorPurple) return false;
return true;
}
GrDSLFPTest_Ternary::GrDSLFPTest_Ternary(const GrDSLFPTest_Ternary& src)
: INHERITED(kGrDSLFPTest_Ternary_ClassID, src.optimizationFlags())
, primaryColors(src.primaryColors)
, colorGreen(src.colorGreen)
, colorRed(src.colorRed) {
, colorRed(src.colorRed)
, colorOrange(src.colorOrange)
, colorPurple(src.colorPurple) {
this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrDSLFPTest_Ternary::clone() const {
@ -74,6 +128,6 @@ std::unique_ptr<GrFragmentProcessor> GrDSLFPTest_Ternary::clone() const {
}
#if GR_TEST_UTILS
SkString GrDSLFPTest_Ternary::onDumpInfo() const {
return SkStringPrintf("(colorGreen=half4(%f, %f, %f, %f), colorRed=half4(%f, %f, %f, %f))", colorGreen.fR, colorGreen.fG, colorGreen.fB, colorGreen.fA, colorRed.fR, colorRed.fG, colorRed.fB, colorRed.fA);
return SkStringPrintf("(primaryColors=%d, colorGreen=half4(%f, %f, %f, %f), colorRed=half4(%f, %f, %f, %f), colorOrange=half4(%f, %f, %f, %f), colorPurple=half4(%f, %f, %f, %f))", !!(primaryColors), colorGreen.fR, colorGreen.fG, colorGreen.fB, colorGreen.fA, colorRed.fR, colorRed.fG, colorRed.fB, colorRed.fA, colorOrange.fR, colorOrange.fG, colorOrange.fB, colorOrange.fA, colorPurple.fR, colorPurple.fG, colorPurple.fB, colorPurple.fA);
}
#endif

View File

@ -14,19 +14,25 @@
class GrDSLFPTest_Ternary : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f colorGreen, SkPMColor4f colorRed) {
return std::unique_ptr<GrFragmentProcessor>(new GrDSLFPTest_Ternary(colorGreen, colorRed));
static std::unique_ptr<GrFragmentProcessor> Make(bool primaryColors, SkPMColor4f colorGreen, SkPMColor4f colorRed, SkPMColor4f colorOrange, SkPMColor4f colorPurple) {
return std::unique_ptr<GrFragmentProcessor>(new GrDSLFPTest_Ternary(primaryColors, colorGreen, colorRed, colorOrange, colorPurple));
}
GrDSLFPTest_Ternary(const GrDSLFPTest_Ternary& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "DSLFPTest_Ternary"; }
bool primaryColors;
SkPMColor4f colorGreen;
SkPMColor4f colorRed;
SkPMColor4f colorOrange;
SkPMColor4f colorPurple;
private:
GrDSLFPTest_Ternary(SkPMColor4f colorGreen, SkPMColor4f colorRed)
GrDSLFPTest_Ternary(bool primaryColors, SkPMColor4f colorGreen, SkPMColor4f colorRed, SkPMColor4f colorOrange, SkPMColor4f colorPurple)
: INHERITED(kGrDSLFPTest_Ternary_ClassID, kNone_OptimizationFlags)
, primaryColors(primaryColors)
, colorGreen(colorGreen)
, colorRed(colorRed) {
, colorRed(colorRed)
, colorOrange(colorOrange)
, colorPurple(colorPurple) {
}
std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;

View File

@ -29,12 +29,12 @@ public:
using namespace SkSL::dsl;
StartFragmentProcessor(this, &args);
Var color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(1.0f));
Declare(color);
While(color.x() > 0.5f, color.x() -= 0.25f);
While(color.w() == 1.0f, Block(color.x() -= 0.25f, If(color.x() <= 0.0f, /*Then:*/ Break())));
While(color.z() > 0.0f, Block(color.z() -= 0.25f, If(color.w() == 1.0f, /*Then:*/ Continue()), color.y() = 0.0f));
Return(color);
Var _color(kNo_Modifier, DSLType(kHalf4_Type), "color", Half4(1.0f));
Declare(_color);
While(_color.x() > 0.5f, _color.x() -= 0.25f);
While(_color.w() == 1.0f, Block(_color.x() -= 0.25f, If(_color.x() <= 0.0f, /*Then:*/ Break())));
While(_color.z() > 0.0f, Block(_color.z() -= 0.25f, If(_color.w() == 1.0f, /*Then:*/ Continue()), _color.y() = 0.0f));
Return(_color);
EndFragmentProcessor();
}
private: