Fix assertion in constant-folder when using float4(mat2) casts.
The no-op-arithmetic simplifier was written before we allowed casting a
mat2x2 to a float4, and did not expect a matrix inside a vector ctor.
The expression `float4(myMat2) * float4(anything)` would assert when we
tried to determine if `myMat2` was a constant zero or constant one.
The code has been rewritten to use getConstantSubexpression and now
allows matrices inside.
Change-Id: Id625141256bf89d816c57d2d21f16b0ec252c158
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/440858
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/resources/sksl/folding/MatrixFoldingES2.sksl b/resources/sksl/folding/MatrixFoldingES2.sksl
index 544a0bb..1061ed6 100644
--- a/resources/sksl/folding/MatrixFoldingES2.sksl
+++ b/resources/sksl/folding/MatrixFoldingES2.sksl
@@ -1,3 +1,4 @@
+uniform float2x2 testMatrix2x2;
uniform half4 colorRed, colorGreen;
uniform half unknownInput;
@@ -32,6 +33,11 @@
ok = ok && (float2x2(float4(1.0, 0.0, 0.0, 1.0)) == float2x2(1.0));
ok = ok && (float2x2(1.0, 0.0, float2(0.0, 1.0)) == float2x2(1.0));
ok = ok && (float2x2(float2(1.0, 0.0), 0.0, 1.0) == float2x2(1.0));
+
+ ok = ok && (float4(testMatrix2x2) * float4(1)) == float4(1, 2, 3, 4);
+ ok = ok && (float4(testMatrix2x2) * float4(1)) == float4(testMatrix2x2);
+ ok = ok && (float4(testMatrix2x2) * float4(0)) == float4(0);
+
return ok;
}
diff --git a/src/sksl/SkSLConstantFolder.cpp b/src/sksl/SkSLConstantFolder.cpp
index abef8d5..f9824f5 100644
--- a/src/sksl/SkSLConstantFolder.cpp
+++ b/src/sksl/SkSLConstantFolder.cpp
@@ -160,30 +160,25 @@
}
static bool contains_constant_zero(const Expression& expr) {
- if (expr.isAnyConstructor()) {
- for (const auto& arg : expr.asAnyConstructor().argumentSpan()) {
- if (contains_constant_zero(*arg)) {
- return true;
- }
+ int numSlots = expr.type().slotCount();
+ for (int index = 0; index < numSlots; ++index) {
+ const Expression* subexpr = expr.getConstantSubexpression(index);
+ if (subexpr && is_constant_scalar_value(*subexpr, 0.0f)) {
+ return true;
}
- return false;
}
- return is_constant_scalar_value(expr, 0.0);
+ return false;
}
static bool is_constant_value(const Expression& expr, float value) {
- // This check only supports scalars and vectors (and in particular, not matrices).
- SkASSERT(expr.type().isScalar() || expr.type().isVector());
-
- if (expr.isAnyConstructor()) {
- for (const auto& arg : expr.asAnyConstructor().argumentSpan()) {
- if (!is_constant_value(*arg, value)) {
- return false;
- }
+ int numSlots = expr.type().slotCount();
+ for (int index = 0; index < numSlots; ++index) {
+ const Expression* subexpr = expr.getConstantSubexpression(index);
+ if (!subexpr || !is_constant_scalar_value(*subexpr, value)) {
+ return false;
}
- return true;
}
- return is_constant_scalar_value(expr, value);
+ return true;
}
bool ConstantFolder::ErrorOnDivideByZero(const Context& context, int offset, Operator op,
diff --git a/tests/sksl/folding/MatrixFoldingES2.glsl b/tests/sksl/folding/MatrixFoldingES2.glsl
index 7a6a73f..d428cfe 100644
--- a/tests/sksl/folding/MatrixFoldingES2.glsl
+++ b/tests/sksl/folding/MatrixFoldingES2.glsl
@@ -1,5 +1,6 @@
out vec4 sk_FragColor;
+uniform mat2 testMatrix2x2;
uniform vec4 colorRed;
uniform vec4 colorGreen;
uniform float unknownInput;
@@ -7,5 +8,6 @@
bool _0_ok = true;
_0_ok = _0_ok && mat3(unknownInput) == mat3(mat2(1.0));
_0_ok = _0_ok && mat3(9.0, 0.0, 0.0, 0.0, 9.0, 0.0, 0.0, 0.0, unknownInput) == mat3(mat2(9.0));
+ _0_ok = _0_ok && vec4(testMatrix2x2) == vec4(1.0, 2.0, 3.0, 4.0);
return _0_ok ? colorGreen : colorRed;
}