Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / sksl / SkSLAnalysis.h
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #ifndef SkSLAnalysis_DEFINED
9 #define SkSLAnalysis_DEFINED
10
11 #include "include/private/SkSLSampleUsage.h"
12
13 #include <stdint.h>
14 #include <memory>
15 #include <set>
16
17 namespace SkSL {
18
19 class ErrorReporter;
20 class Expression;
21 class FunctionDeclaration;
22 class FunctionDefinition;
23 class Position;
24 class ProgramElement;
25 class ProgramUsage;
26 class Statement;
27 class Variable;
28 class VariableReference;
29 enum class VariableRefKind : int8_t;
30 struct ForLoopPositions;
31 struct LoadedModule;
32 struct LoopUnrollInfo;
33 struct ParsedModule;
34 struct Program;
35
36 /**
37  * Provides utilities for analyzing SkSL statically before it's composed into a full program.
38  */
39 namespace Analysis {
40
41 /**
42  * Determines how `program` samples `child`. By default, assumes that the sample coords
43  * (SK_MAIN_COORDS_BUILTIN) might be modified, so `child.eval(sampleCoords)` is treated as
44  * Explicit. If writesToSampleCoords is false, treats that as PassThrough, instead.
45  * If elidedSampleCoordCount is provided, the pointed to value will be incremented by the
46  * number of sample calls where the above rewrite was performed.
47  */
48 SampleUsage GetSampleUsage(const Program& program,
49                            const Variable& child,
50                            bool writesToSampleCoords = true,
51                            int* elidedSampleCoordCount = nullptr);
52
53 bool ReferencesBuiltin(const Program& program, int builtin);
54
55 bool ReferencesSampleCoords(const Program& program);
56 bool ReferencesFragCoords(const Program& program);
57
58 bool CallsSampleOutsideMain(const Program& program);
59
60 bool CallsColorTransformIntrinsics(const Program& program);
61
62 /**
63  * Determines if `function` always returns an opaque color (a vec4 where the last component is known
64  * to be 1). This is conservative, and based on constant expression analysis.
65  */
66 bool ReturnsOpaqueColor(const FunctionDefinition& function);
67
68 /**
69  * Checks for recursion or overly-deep function-call chains, and rejects programs which have them.
70  * Also, computes the size of the program in a completely flattened state--loops fully unrolled,
71  * function calls inlined--and rejects programs that exceed an arbitrary upper bound. This is
72  * intended to prevent absurdly large programs from overwhemling SkVM. Only strict-ES2 mode is
73  * supported; complex control flow is not SkVM-compatible (and this becomes the halting problem)
74  */
75 bool CheckProgramStructure(const Program& program, bool enforceSizeLimit);
76
77 /**
78  * Detect an orphaned variable declaration outside of a scope, e.g. if (true) int a;. Returns
79  * true if an error was reported.
80  */
81 bool DetectVarDeclarationWithoutScope(const Statement& stmt, ErrorReporter* errors = nullptr);
82
83 int NodeCountUpToLimit(const FunctionDefinition& function, int limit);
84
85 /**
86  * Finds unconditional exits from a switch-case. Returns true if this statement unconditionally
87  * causes an exit from this switch (via continue, break or return).
88  */
89 bool SwitchCaseContainsUnconditionalExit(Statement& stmt);
90
91 /**
92  * Finds conditional exits from a switch-case. Returns true if this statement contains a
93  * conditional that wraps a potential exit from the switch (via continue, break or return).
94  */
95 bool SwitchCaseContainsConditionalExit(Statement& stmt);
96
97 std::unique_ptr<ProgramUsage> GetUsage(const Program& program);
98 std::unique_ptr<ProgramUsage> GetUsage(const LoadedModule& module, const ParsedModule& base);
99
100 bool StatementWritesToVariable(const Statement& stmt, const Variable& var);
101
102 struct AssignmentInfo {
103     VariableReference* fAssignedVar = nullptr;
104 };
105 bool IsAssignable(Expression& expr, AssignmentInfo* info = nullptr,
106                   ErrorReporter* errors = nullptr);
107
108 /**
109  * Updates the `refKind` field of the VariableReference at the top level of `expr`.
110  * If `expr` can be assigned to (`IsAssignable`), true is returned and no errors are reported.
111  * If not, false is returned. and an error is reported if `errors` is non-null.
112  */
113 bool UpdateVariableRefKind(Expression* expr, VariableRefKind kind, ErrorReporter* errors = nullptr);
114
115 /**
116  * A "trivial" expression is one where we'd feel comfortable cloning it multiple times in
117  * the code, without worrying about incurring a performance penalty. Examples:
118  * - true
119  * - 3.14159265
120  * - myIntVariable
121  * - myColor.rgb
122  * - myArray[123]
123  * - myStruct.myField
124  * - half4(0)
125  *
126  * Trivial-ness is stackable. Somewhat large expressions can occasionally make the cut:
127  * - half4(myColor.a)
128  * - myStruct.myArrayField[7].xyz
129  */
130 bool IsTrivialExpression(const Expression& expr);
131
132 /**
133  * Returns true if both expression trees are the same. Used by the optimizer to look for self-
134  * assignment or self-comparison; won't necessarily catch complex cases. Rejects expressions
135  * that may cause side effects.
136  */
137 bool IsSameExpressionTree(const Expression& left, const Expression& right);
138
139 /**
140  * Returns true if expr is a constant-expression, as defined by GLSL 1.0, section 5.10.
141  * A constant expression is one of:
142  * - A literal value
143  * - A global or local variable qualified as 'const', excluding function parameters
144  * - An expression formed by an operator on operands that are constant expressions, including
145  *   getting an element of a constant vector or a constant matrix, or a field of a constant
146  *   structure
147  * - A constructor whose arguments are all constant expressions
148  * - A built-in function call whose arguments are all constant expressions, with the exception
149  *   of the texture lookup functions
150  */
151 bool IsConstantExpression(const Expression& expr);
152
153 /**
154  * Returns true if expr is a valid constant-index-expression, as defined by GLSL 1.0, Appendix A,
155  * Section 5. A constant-index-expression is:
156  * - A constant-expression
157  * - Loop indices (as defined in Appendix A, Section 4)
158  * - Expressions composed of both of the above
159  */
160 bool IsConstantIndexExpression(const Expression& expr,
161                                const std::set<const Variable*>* loopIndices);
162
163 /**
164  * Ensures that a for-loop meets the strict requirements of The OpenGL ES Shading Language 1.00,
165  * Appendix A, Section 4.
166  * If the requirements are met, information about the loop's structure is returned.
167  * If the requirements are not met, the problem is reported via `errors` (if not nullptr), and
168  * null is returned.
169  */
170 std::unique_ptr<LoopUnrollInfo> GetLoopUnrollInfo(Position pos,
171                                                   const ForLoopPositions& positions,
172                                                   const Statement* loopInitializer,
173                                                   const Expression* loopTest,
174                                                   const Expression* loopNext,
175                                                   const Statement* loopStatement,
176                                                   ErrorReporter* errors);
177
178 void ValidateIndexingForES2(const ProgramElement& pe, ErrorReporter& errors);
179
180 /** Detects functions that fail to return a value on at least one path. */
181 bool CanExitWithoutReturningValue(const FunctionDeclaration& funcDecl, const Statement& body);
182
183 /**
184  * Runs at finalization time to perform any last-minute correctness checks:
185  * - Reports @if/@switch statements that didn't optimize away
186  * - Reports dangling FunctionReference or TypeReference expressions
187  * - Reports function `out` params which are never written to (structs are currently exempt)
188  */
189 void DoFinalizationChecks(const Program& program);
190
191 }  // namespace Analysis
192 }  // namespace SkSL
193
194 #endif