summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp')
-rw-r--r--gfx/skia/skia/src/sksl/analysis/SkSLIsDynamicallyUniformExpression.cpp86
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