diff options
Diffstat (limited to 'gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp')
-rw-r--r-- | gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp b/gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp new file mode 100644 index 0000000000..0e07fac6f5 --- /dev/null +++ b/gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2023 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkTypes.h" +#include "include/private/SkSLIRNode.h" +#include "include/private/SkSLModifiers.h" +#include "src/sksl/SkSLAnalysis.h" +#include "src/sksl/analysis/SkSLProgramVisitor.h" +#include "src/sksl/ir/SkSLExpression.h" +#include "src/sksl/ir/SkSLFunctionCall.h" +#include "src/sksl/ir/SkSLFunctionDeclaration.h" +#include "src/sksl/ir/SkSLVariable.h" +#include "src/sksl/ir/SkSLVariableReference.h" + +namespace SkSL { + +bool Analysis::IsDynamicallyUniformExpression(const Expression& expr) { + class IsDynamicallyUniformExpressionVisitor : public ProgramVisitor { + public: + bool visitExpression(const Expression& expr) override { + switch (expr.kind()) { + case Expression::Kind::kBinary: + case Expression::Kind::kConstructorArray: + case Expression::Kind::kConstructorArrayCast: + case Expression::Kind::kConstructorCompound: + case Expression::Kind::kConstructorCompoundCast: + case Expression::Kind::kConstructorDiagonalMatrix: + case Expression::Kind::kConstructorMatrixResize: + case Expression::Kind::kConstructorScalarCast: + case Expression::Kind::kConstructorSplat: + case Expression::Kind::kConstructorStruct: + case Expression::Kind::kFieldAccess: + case Expression::Kind::kIndex: + case Expression::Kind::kPostfix: + case Expression::Kind::kPrefix: + case Expression::Kind::kSwizzle: + case Expression::Kind::kTernary: + // These expressions might be dynamically uniform, if they are composed entirely + // of constants and uniforms. + break; + + case Expression::Kind::kVariableReference: { + // Verify that variable references are const or uniform. + const Variable* var = expr.as<VariableReference>().variable(); + if (!var || !(var->modifiers().fFlags & (Modifiers::Flag::kConst_Flag | + Modifiers::Flag::kUniform_Flag))) { + fIsDynamicallyUniform = false; + return true; + } + break; + } + case Expression::Kind::kFunctionCall: { + // Verify that function calls are pure. + const FunctionDeclaration& decl = expr.as<FunctionCall>().function(); + if (!(decl.modifiers().fFlags & Modifiers::Flag::kPure_Flag)) { + fIsDynamicallyUniform = false; + return true; + } + break; + } + case Expression::Kind::kLiteral: + // Literals are compile-time constants. + return false; + + default: + // This expression isn't dynamically uniform. + fIsDynamicallyUniform = false; + return true; + } + return INHERITED::visitExpression(expr); + } + + bool fIsDynamicallyUniform = true; + using INHERITED = ProgramVisitor; + }; + + IsDynamicallyUniformExpressionVisitor visitor; + visitor.visitExpression(expr); + return visitor.fIsDynamicallyUniform; +} + +} // namespace SkSL |