• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SKSL_DSL_VAR
9 #define SKSL_DSL_VAR
10 
11 #include "include/private/SkSLStatement.h"
12 #include "include/sksl/DSLExpression.h"
13 #include "include/sksl/DSLModifiers.h"
14 #include "include/sksl/DSLType.h"
15 #include "include/sksl/SkSLPosition.h"
16 
17 #include <cstdint>
18 #include <memory>
19 #include <string_view>
20 #include <utility>
21 
22 namespace SkSL {
23 
24 class Expression;
25 class ExpressionArray;
26 class Variable;
27 enum class VariableStorage : int8_t;
28 
29 namespace dsl {
30 
31 class DSLVarBase {
32 public:
33     /**
34      * Constructs a new variable with the specified type and name.
35      */
36     DSLVarBase(VariableStorage storage, DSLType type, std::string_view name,
37                DSLExpression initialValue, Position pos, Position namePos);
38 
39     DSLVarBase(VariableStorage storage, const DSLModifiers& modifiers, DSLType type,
40                std::string_view name, DSLExpression initialValue, Position pos, Position namePos);
41 
42     DSLVarBase(DSLVarBase&&) = default;
43 
name()44     std::string_view name() const {
45         return fName;
46     }
47 
modifiers()48     const DSLModifiers& modifiers() const {
49         return fModifiers;
50     }
51 
storage()52     VariableStorage storage() const {
53         return fStorage;
54     }
55 
x()56     DSLExpression x() {
57         return DSLExpression(*this).x();
58     }
59 
y()60     DSLExpression y() {
61         return DSLExpression(*this).y();
62     }
63 
z()64     DSLExpression z() {
65         return DSLExpression(*this).z();
66     }
67 
w()68     DSLExpression w() {
69         return DSLExpression(*this).w();
70     }
71 
r()72     DSLExpression r() {
73         return DSLExpression(*this).r();
74     }
75 
g()76     DSLExpression g() {
77         return DSLExpression(*this).g();
78     }
79 
b()80     DSLExpression b() {
81         return DSLExpression(*this).b();
82     }
83 
a()84     DSLExpression a() {
85         return DSLExpression(*this).a();
86     }
87 
field(std::string_view name)88     DSLExpression field(std::string_view name) {
89         return DSLExpression(*this).field(name);
90     }
91 
92     DSLExpression operator[](DSLExpression&& index);
93 
94     DSLExpression operator++() {
95         return ++DSLExpression(*this);
96     }
97 
98     DSLExpression operator++(int) {
99         return DSLExpression(*this)++;
100     }
101 
102     DSLExpression operator--() {
103         return --DSLExpression(*this);
104     }
105 
106     DSLExpression operator--(int) {
107         return DSLExpression(*this)--;
108     }
109 
assign(T && param)110     template <class T> DSLExpression assign(T&& param) {
111         return this->assignExpression(DSLExpression(std::forward<T>(param)));
112     }
113 
114 protected:
115     /**
116      * Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
117      */
DSLVarBase(VariableStorage storage)118     DSLVarBase(VariableStorage storage) : fType(kVoid_Type), fStorage(storage) {}
119 
120     DSLExpression assignExpression(DSLExpression other);
121 
122     void swap(DSLVarBase& other);
123 
124     DSLModifiers fModifiers;
125     // We only need to keep track of the type here so that we can create the SkSL::Variable. For
126     // predefined variables this field is unnecessary, so we don't bother tracking it and just set
127     // it to kVoid; in other words, you shouldn't generally be relying on this field to be correct.
128     // If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead.
129     DSLType fType;
130     std::unique_ptr<SkSL::Statement> fDeclaration;
131     SkSL::Variable* fVar = nullptr;
132     Position fNamePosition;
133     std::string_view fName;
134     DSLExpression fInitialValue;
135     Position fPosition;
136     VariableStorage fStorage;
137     bool fInitialized = false;
138 
139     friend class DSLCore;
140     friend class DSLFunction;
141     friend class DSLWriter;
142 };
143 
144 /**
145  * A local variable.
146  */
147 class DSLVar : public DSLVarBase {
148 public:
149     DSLVar();
150 
151     DSLVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(),
152            Position pos = {}, Position namePos = {});
153 
154     DSLVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
155            DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {});
156 
157     DSLVar(DSLVar&&) = default;
158 
159     void swap(DSLVar& other);
160 
161 private:
162     using INHERITED = DSLVarBase;
163 };
164 
165 /**
166  * A global variable.
167  */
168 class DSLGlobalVar : public DSLVarBase {
169 public:
170     DSLGlobalVar();
171 
172     DSLGlobalVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(),
173                  Position pos = {}, Position namePos = {});
174 
175     DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
176                  DSLExpression initialValue = DSLExpression(),
177                  Position pos = {}, Position namePos = {});
178 
179     DSLGlobalVar(const char* name);
180 
181     DSLGlobalVar(DSLGlobalVar&&) = default;
182 
183     void swap(DSLGlobalVar& other);
184 
185     /**
186      * Implements the following method calls:
187      *     half4 shader::eval(float2 coords);
188      *     half4 colorFilter::eval(half4 input);
189      */
190     DSLExpression eval(DSLExpression x, Position pos = {});
191 
192     /**
193      * Implements the following method call:
194      *     half4 blender::eval(half4 src, half4 dst);
195      */
196     DSLExpression eval(DSLExpression x, DSLExpression y, Position pos = {});
197 
198 private:
199     DSLExpression eval(ExpressionArray args, Position pos);
200 
201     std::unique_ptr<SkSL::Expression> methodCall(std::string_view methodName, Position pos);
202 
203     using INHERITED = DSLVarBase;
204 };
205 
206 /**
207  * A function parameter.
208  */
209 class DSLParameter : public DSLVarBase {
210 public:
211     DSLParameter();
212 
213     DSLParameter(DSLType type, std::string_view name, Position pos = {}, Position namePos = {});
214 
215     DSLParameter(const DSLModifiers& modifiers, DSLType type, std::string_view name,
216                  Position pos = {}, Position namePos = {});
217 
218     DSLParameter(DSLParameter&&) = default;
219 
220     void swap(DSLParameter& other);
221 
222 private:
223     using INHERITED = DSLVarBase;
224 };
225 
226 } // namespace dsl
227 
228 } // namespace SkSL
229 
230 
231 #endif
232