• 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/sksl/DSLExpression.h"
12 #include "include/sksl/DSLModifiers.h"
13 #include "include/sksl/DSLType.h"
14 
15 namespace SkSL {
16 
17 class Expression;
18 class IRGenerator;
19 class SPIRVCodeGenerator;
20 class Variable;
21 enum class VariableStorage : int8_t;
22 
23 namespace dsl {
24 
25 class DSLVarBase {
26 public:
27     /**
28      * Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
29      */
DSLVarBase()30     DSLVarBase() : fType(kVoid_Type), fDeclared(true) {}
31 
32     /**
33      * Constructs a new variable with the specified type and name. The name is used (in mangled
34      * form) in the resulting shader code; it is not otherwise important. Since mangling prevents
35      * name conflicts and the variable's name is only important when debugging shaders, the name
36      * parameter is optional.
37      */
38     DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue, PositionInfo pos);
39 
40     DSLVarBase(DSLType type, DSLExpression initialValue, PositionInfo pos);
41 
42     DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::string_view name,
43                DSLExpression initialValue, PositionInfo pos);
44 
45     DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue,
46                PositionInfo pos);
47 
48     DSLVarBase(DSLVarBase&&) = default;
49 
50     virtual ~DSLVarBase();
51 
name()52     skstd::string_view name() const {
53         return fName;
54     }
55 
modifiers()56     const DSLModifiers& modifiers() const {
57         return fModifiers;
58     }
59 
60     virtual VariableStorage storage() const = 0;
61 
x()62     DSLExpression x() {
63         return DSLExpression(*this, PositionInfo()).x();
64     }
65 
y()66     DSLExpression y() {
67         return DSLExpression(*this, PositionInfo()).y();
68     }
69 
z()70     DSLExpression z() {
71         return DSLExpression(*this, PositionInfo()).z();
72     }
73 
w()74     DSLExpression w() {
75         return DSLExpression(*this, PositionInfo()).w();
76     }
77 
r()78     DSLExpression r() {
79         return DSLExpression(*this, PositionInfo()).r();
80     }
81 
g()82     DSLExpression g() {
83         return DSLExpression(*this, PositionInfo()).g();
84     }
85 
b()86     DSLExpression b() {
87         return DSLExpression(*this, PositionInfo()).b();
88     }
89 
a()90     DSLExpression a() {
91         return DSLExpression(*this, PositionInfo()).a();
92     }
93 
field(skstd::string_view name)94     DSLExpression field(skstd::string_view name) {
95         return DSLExpression(*this, PositionInfo()).field(name);
96     }
97 
98     DSLPossibleExpression operator[](DSLExpression&& index);
99 
100     DSLPossibleExpression operator++() {
101         return ++DSLExpression(*this, PositionInfo());
102     }
103 
104     DSLPossibleExpression operator++(int) {
105         return DSLExpression(*this, PositionInfo())++;
106     }
107 
108     DSLPossibleExpression operator--() {
109         return --DSLExpression(*this, PositionInfo());
110     }
111 
112     DSLPossibleExpression operator--(int) {
113         return DSLExpression(*this, PositionInfo())--;
114     }
115 
116 protected:
117     DSLPossibleExpression assign(DSLExpression other);
118 
119     void swap(DSLVarBase& other);
120 
121     DSLModifiers fModifiers;
122     // We only need to keep track of the type here so that we can create the SkSL::Variable. For
123     // predefined variables this field is unnecessary, so we don't bother tracking it and just set
124     // it to kVoid; in other words, you shouldn't generally be relying on this field to be correct.
125     // If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead.
126     DSLType fType;
127     int fUniformHandle = -1;
128     std::unique_ptr<SkSL::Statement> fDeclaration;
129     const SkSL::Variable* fVar = nullptr;
130     skstd::string_view fRawName; // for error reporting
131     skstd::string_view fName;
132     DSLExpression fInitialValue;
133     // true if we have attempted to create the SkSL var
134     bool fInitialized = false;
135     bool fDeclared = false;
136     PositionInfo fPosition;
137 
138     friend class DSLCore;
139     friend class DSLExpression;
140     friend class DSLFunction;
141     friend class DSLWriter;
142     friend class ::SkSL::IRGenerator;
143     friend class ::SkSL::SPIRVCodeGenerator;
144 };
145 
146 /**
147  * A local variable.
148  */
149 class DSLVar : public DSLVarBase {
150 public:
151     DSLVar() = default;
152 
153     DSLVar(DSLType type, skstd::string_view name = "var",
154            DSLExpression initialValue = DSLExpression(),
155            PositionInfo pos = PositionInfo::Capture())
INHERITED(type,name,std::move (initialValue),pos)156         : INHERITED(type, name, std::move(initialValue), pos) {}
157 
158     DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(),
159            PositionInfo pos = PositionInfo::Capture())
DSLVar(type,skstd::string_view (name),std::move (initialValue),pos)160         : DSLVar(type, skstd::string_view(name), std::move(initialValue), pos) {}
161 
162     DSLVar(DSLType type, DSLExpression initialValue, PositionInfo pos = PositionInfo::Capture())
INHERITED(type,std::move (initialValue),pos)163         : INHERITED(type, std::move(initialValue), pos) {}
164 
165     DSLVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
166            DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
INHERITED(modifiers,type,name,std::move (initialValue),pos)167         : INHERITED(modifiers, type, name, std::move(initialValue), pos) {}
168 
169     DSLVar(const DSLModifiers& modifiers, DSLType type, const char* name,
170            DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
DSLVar(modifiers,type,skstd::string_view (name),std::move (initialValue),pos)171         : DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {}
172 
173     DSLVar(DSLVar&&) = default;
174 
175     VariableStorage storage() const override;
176 
177     void swap(DSLVar& other);
178 
179     DSLPossibleExpression operator=(DSLExpression expr);
180 
181     DSLPossibleExpression operator=(DSLVar& param) {
182         return this->operator=(DSLExpression(param));
183     }
184 
185     template<class Param>
186     DSLPossibleExpression operator=(Param& param) {
187         return this->operator=(DSLExpression(param));
188     }
189 
190 private:
191     using INHERITED = DSLVarBase;
192 };
193 
194 /**
195  * A global variable.
196  */
197 class DSLGlobalVar : public DSLVarBase {
198 public:
199     DSLGlobalVar() = default;
200 
201     DSLGlobalVar(DSLType type, skstd::string_view name = "var",
202            DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
INHERITED(type,name,std::move (initialValue),pos)203         : INHERITED(type, name, std::move(initialValue), pos) {}
204 
205     DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(),
206                  PositionInfo pos = PositionInfo::Capture())
DSLGlobalVar(type,skstd::string_view (name),std::move (initialValue),pos)207         : DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue), pos) {}
208 
209     DSLGlobalVar(DSLType type, DSLExpression initialValue,
210                  PositionInfo pos = PositionInfo::Capture())
INHERITED(type,std::move (initialValue),pos)211         : INHERITED(type, std::move(initialValue), pos) {}
212 
213     DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
214            DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
INHERITED(modifiers,type,name,std::move (initialValue),pos)215         : INHERITED(modifiers, type, name, std::move(initialValue), pos) {}
216 
217     DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, const char* name,
218            DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
DSLGlobalVar(modifiers,type,skstd::string_view (name),std::move (initialValue),pos)219         : DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {}
220 
221     DSLGlobalVar(const char* name);
222 
223     DSLGlobalVar(DSLGlobalVar&&) = default;
224 
225     VariableStorage storage() const override;
226 
227     void swap(DSLGlobalVar& other);
228 
229     DSLPossibleExpression operator=(DSLExpression expr);
230 
231     DSLPossibleExpression operator=(DSLGlobalVar& param) {
232         return this->operator=(DSLExpression(param));
233     }
234 
235     template<class Param>
236     DSLPossibleExpression operator=(Param& param) {
237         return this->operator=(DSLExpression(param));
238     }
239 
240     /**
241      * Implements the following method calls:
242      *     half4 shader::eval(float2 coords);
243      *     half4 colorFilter::eval(half4 input);
244      */
245     DSLExpression eval(DSLExpression x, PositionInfo pos = PositionInfo::Capture());
246 
247     /**
248      * Implements the following method call:
249      *     half4 blender::eval(half4 src, half4 dst);
250      */
251     DSLExpression eval(DSLExpression x, DSLExpression y,
252             PositionInfo pos = PositionInfo::Capture());
253 
254 private:
255     DSLExpression eval(ExpressionArray args, PositionInfo pos);
256 
257     std::unique_ptr<SkSL::Expression> methodCall(skstd::string_view methodName, PositionInfo pos);
258 
259     using INHERITED = DSLVarBase;
260 };
261 
262 /**
263  * A function parameter.
264  */
265 class DSLParameter : public DSLVarBase {
266 public:
267     DSLParameter() = default;
268 
269     DSLParameter(DSLType type, skstd::string_view name = "var",
270                  PositionInfo pos = PositionInfo::Capture())
INHERITED(type,name,DSLExpression (),pos)271         : INHERITED(type, name, DSLExpression(), pos) {}
272 
273     DSLParameter(DSLType type, const char* name, PositionInfo pos = PositionInfo::Capture())
DSLParameter(type,skstd::string_view (name),pos)274         : DSLParameter(type, skstd::string_view(name), pos) {}
275 
276     DSLParameter(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
277                  PositionInfo pos = PositionInfo::Capture())
INHERITED(modifiers,type,name,DSLExpression (),pos)278         : INHERITED(modifiers, type, name, DSLExpression(), pos) {}
279 
280     DSLParameter(const DSLModifiers& modifiers, DSLType type, const char* name,
281                  PositionInfo pos = PositionInfo::Capture())
DSLParameter(modifiers,type,skstd::string_view (name),pos)282         : DSLParameter(modifiers, type, skstd::string_view(name), pos) {}
283 
284     DSLParameter(DSLParameter&&) = default;
285 
286     VariableStorage storage() const override;
287 
288     void swap(DSLParameter& other);
289 
290     DSLPossibleExpression operator=(DSLExpression expr);
291 
292     DSLPossibleExpression operator=(DSLParameter& param) {
293         return this->operator=(DSLExpression(param));
294     }
295 
296     template<class Param>
297     DSLPossibleExpression operator=(Param& param) {
298         return this->operator=(DSLExpression(param));
299     }
300 
301 private:
302     using INHERITED = DSLVarBase;
303 };
304 
305 } // namespace dsl
306 
307 } // namespace SkSL
308 
309 
310 #endif
311