Optimize away swizzles of constant variables.
Change-Id: I49807f18ea54e85c2b8f1419278c54aa2d6f8fac Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402581 Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
552fcb9a1b
commit
7b253d34ee
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/SkSLConstantFolder.h"
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
@ -183,20 +184,24 @@ std::unique_ptr<Expression> Swizzle::Make(const Context& context,
|
||||
return Swizzle::Make(context, std::move(base.base()), combined);
|
||||
}
|
||||
|
||||
// If we are swizzling a constant expression, we can use its value instead here (so that
|
||||
// swizzles like `colorWhite.x` can be simplified to `1`).
|
||||
const Expression* value = ConstantFolder::GetConstantValueForVariable(*expr);
|
||||
|
||||
// `half4(scalar).zyy` can be optimized to `half3(scalar)`, and `half3(scalar).y` can be
|
||||
// optimized to just `scalar`. The swizzle components don't actually matter, as every field
|
||||
// in a splat constructor holds the same value.
|
||||
if (expr->is<ConstructorSplat>()) {
|
||||
ConstructorSplat& splat = expr->as<ConstructorSplat>();
|
||||
if (value->is<ConstructorSplat>()) {
|
||||
const ConstructorSplat& splat = value->as<ConstructorSplat>();
|
||||
return ConstructorSplat::Make(
|
||||
context, splat.fOffset,
|
||||
splat.type().componentType().toCompound(context, components.size(), /*rows=*/1),
|
||||
std::move(splat.argument()));
|
||||
splat.argument()->clone());
|
||||
}
|
||||
|
||||
// Optimize swizzles of constructors.
|
||||
if (expr->isAnyConstructor()) {
|
||||
AnyConstructor& base = expr->asAnyConstructor();
|
||||
if (value->isAnyConstructor()) {
|
||||
const AnyConstructor& base = value->asAnyConstructor();
|
||||
auto baseArguments = base.argumentSpan();
|
||||
std::unique_ptr<Expression> replacement;
|
||||
const Type& componentType = exprType.componentType();
|
||||
@ -299,18 +304,8 @@ std::unique_ptr<Expression> Swizzle::Make(const Context& context,
|
||||
ExpressionArray newArgs;
|
||||
newArgs.reserve_back(swizzleSize);
|
||||
for (const ReorderedArgument& reorderedArg : reorderedArgs) {
|
||||
std::unique_ptr<Expression>& origArg = baseArguments[reorderedArg.fArgIndex];
|
||||
|
||||
// Clone the original argument if there are multiple references to it; just
|
||||
// steal it if there's only one reference left.
|
||||
std::unique_ptr<Expression> newArg;
|
||||
int8_t& exprRemainingRefs = exprUsed[reorderedArg.fArgIndex];
|
||||
SkASSERT(exprRemainingRefs > 0);
|
||||
if (--exprRemainingRefs == 0) {
|
||||
newArg = std::move(origArg);
|
||||
} else {
|
||||
newArg = origArg->clone();
|
||||
}
|
||||
std::unique_ptr<Expression> newArg =
|
||||
baseArguments[reorderedArg.fArgIndex]->clone();
|
||||
|
||||
if (reorderedArg.fComponents.empty()) {
|
||||
newArgs.push_back(std::move(newArg));
|
||||
|
@ -3,7 +3,7 @@
|
||||
error: 7: cannot assign to this expression
|
||||
error: 8: cannot modify immutable variable 'u'
|
||||
error: 9: cannot modify immutable variable 'x'
|
||||
error: 11: cannot modify immutable variable 'x'
|
||||
error: 11: cannot assign to this expression
|
||||
error: 12: cannot write to the same swizzle field more than once
|
||||
error: 14: cannot modify immutable variable 'l'
|
||||
error: 15: cannot modify immutable variable 'r'
|
||||
|
@ -3,16 +3,7 @@ out vec4 sk_FragColor;
|
||||
uniform vec4 colorRed;
|
||||
uniform vec4 colorGreen;
|
||||
vec4 main() {
|
||||
const vec4 _0_colorWhite = vec4(1.0);
|
||||
const vec2 _1_point = vec2(40.0, 60.0);
|
||||
bool _2_ok = true;
|
||||
_2_ok = _2_ok && (((_1_point.x >= 0.0 && _1_point.x <= 100.0) && _1_point.y >= 0.0) && _1_point.y <= 100.0);
|
||||
_2_ok = _2_ok && _0_colorWhite.x == 1.0;
|
||||
_2_ok = _2_ok && _0_colorWhite.x + _0_colorWhite.y == 2.0;
|
||||
_2_ok = _2_ok && (_0_colorWhite.x + _0_colorWhite.y) + _0_colorWhite.z == 3.0;
|
||||
_2_ok = _2_ok && ((_0_colorWhite.x + _0_colorWhite.y) + _0_colorWhite.z) + _0_colorWhite.w == 4.0;
|
||||
_2_ok = _2_ok && colorGreen * _0_colorWhite.x != colorRed * _0_colorWhite.y;
|
||||
const vec2 _3_pointOffset = _1_point.yx + _0_colorWhite.xz;
|
||||
_2_ok = _2_ok && _3_pointOffset == vec2(61.0, 41.0);
|
||||
_2_ok = _2_ok && colorGreen != colorRed;
|
||||
return _2_ok ? colorGreen : colorRed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user