• 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_CORE
9 #define SKSL_DSL_CORE
10 
11 #include "include/private/SkSLDefines.h"
12 #include "include/private/SkSLProgramKind.h"
13 #include "include/private/base/SkTArray.h"
14 #include "include/sksl/DSLCase.h"
15 #include "include/sksl/DSLExpression.h"
16 #include "include/sksl/DSLStatement.h"
17 #include "include/sksl/DSLVar.h"  // IWYU pragma: keep
18 #include "include/sksl/SkSLPosition.h"
19 
20 #include <memory>
21 #include <string>
22 #include <string_view>
23 #include <utility>
24 
25 namespace SkSL {
26 
27 class Compiler;
28 class ErrorReporter;
29 struct Program;
30 struct ProgramSettings;
31 
32 namespace dsl {
33 
34 class DSLField;
35 class DSLModifiers;
36 
37 // When users import the DSL namespace via `using namespace SkSL::dsl`, we want the SwizzleComponent
38 // Type enum to come into scope as well, so `Swizzle(var, X, Y, ONE)` can work as expected.
39 // `namespace SkSL::SwizzleComponent` contains only an `enum Type`; this `using namespace` directive
40 // shouldn't pollute the SkSL::dsl namespace with anything else.
41 using namespace SkSL::SwizzleComponent;
42 
43 /**
44  * Starts DSL output on the current thread using the specified compiler. This must be called
45  * prior to any other DSL functions.
46  */
47 void Start(SkSL::Compiler* compiler, SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment);
48 
49 void Start(SkSL::Compiler* compiler, SkSL::ProgramKind kind, const SkSL::ProgramSettings& settings);
50 
51 /**
52  * Signals the end of DSL output. This must be called sometime between a call to Start() and the
53  * termination of the thread.
54  */
55 void End();
56 
57 /**
58  * Returns all global elements (functions and global variables) as a self-contained Program. The
59  * optional source string is retained as the program's source. DSL programs do not normally have
60  * sources, but when a DSL program is produced from parsed program text (as in Parser), it may be
61  * important to retain it so that any std::string_views derived from it remain valid.
62  */
63 std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<std::string> source = nullptr);
64 
65 /**
66  * Returns the ErrorReporter which will be notified of any errors that occur during DSL calls. The
67  * default error reporter aborts on any error.
68  */
69 ErrorReporter& GetErrorReporter();
70 
71 /**
72  * Installs an ErrorReporter which will be notified of any errors that occur during DSL calls.
73  */
74 void SetErrorReporter(ErrorReporter* errorReporter);
75 
76 /**
77  * #extension <name> : enable
78  */
79 void AddExtension(std::string_view name, Position pos = {});
80 
81 /**
82  * break;
83  */
84 DSLStatement Break(Position pos = {});
85 
86 /**
87  * continue;
88  */
89 DSLStatement Continue(Position pos = {});
90 
91 /**
92  * Adds a modifiers declaration to the current program.
93  */
94 void Declare(const DSLModifiers& modifiers, Position pos = {});
95 
96 /**
97  * Creates a local variable declaration statement.
98  */
99 DSLStatement Declare(DSLVar& var, Position pos = {});
100 
101 /**
102  * Creates a local variable declaration statement containing multiple variables.
103  */
104 DSLStatement Declare(SkTArray<DSLVar>& vars, Position pos = {});
105 
106 /**
107  * Declares a global variable.
108  */
109 void Declare(DSLGlobalVar& var, Position pos = {});
110 
111 /**
112  * Declares a set of global variables.
113  */
114 void Declare(SkTArray<DSLGlobalVar>& vars, Position pos = {});
115 
116 /**
117  * default: statements
118  */
119 template<class... Statements>
Default(Statements...statements)120 DSLCase Default(Statements... statements) {
121     return DSLCase(DSLExpression(), std::move(statements)...);
122 }
123 
124 /**
125  * discard;
126  */
127 DSLStatement Discard(Position pos = {});
128 
129 /**
130  * do stmt; while (test);
131  */
132 DSLStatement Do(DSLStatement stmt, DSLExpression test, Position pos = {});
133 
134 /**
135  * for (initializer; test; next) stmt;
136  */
137 DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
138                  DSLStatement stmt, Position pos = {}, ForLoopPositions positions = {});
139 
140 /**
141  * if (test) ifTrue; [else ifFalse;]
142  */
143 DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse = DSLStatement(),
144                 Position pos = {});
145 
146 DSLExpression InterfaceBlock(const DSLModifiers& modifiers,  std::string_view typeName,
147                              SkTArray<DSLField> fields, std::string_view varName = "",
148                              int arraySize = 0, Position pos = {});
149 
150 /**
151  * return [value];
152  */
153 DSLStatement Return(DSLExpression value = DSLExpression(),
154                     Position pos = {});
155 
156 /**
157  * test ? ifTrue : ifFalse
158  */
159 DSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse,
160                      Position  = {});
161 
162 // Internal use only
163 DSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, Position pos = {});
164 
165 /**
166  * switch (value) { cases }
167  */
168 template<class... Cases>
Switch(DSLExpression value,Cases...cases)169 DSLStatement Switch(DSLExpression value, Cases... cases) {
170     SkTArray<DSLCase> caseArray;
171     caseArray.reserve_back(sizeof...(cases));
172     (caseArray.push_back(std::move(cases)), ...);
173     return Switch(std::move(value), std::move(caseArray), Position{});
174 }
175 
176 /**
177  * while (test) stmt;
178  */
179 DSLStatement While(DSLExpression test, DSLStatement stmt,
180                    Position pos = {});
181 
182 /**
183  * expression.xyz1
184  */
185 DSLExpression Swizzle(DSLExpression base,
186                       SkSL::SwizzleComponent::Type a,
187                       Position pos = {},
188                       Position maskPos = {});
189 
190 DSLExpression Swizzle(DSLExpression base,
191                       SkSL::SwizzleComponent::Type a,
192                       SkSL::SwizzleComponent::Type b,
193                       Position pos = {},
194                       Position maskPos = {});
195 
196 DSLExpression Swizzle(DSLExpression base,
197                       SkSL::SwizzleComponent::Type a,
198                       SkSL::SwizzleComponent::Type b,
199                       SkSL::SwizzleComponent::Type c,
200                       Position pos = {},
201                       Position maskPos = {});
202 
203 DSLExpression Swizzle(DSLExpression base,
204                       SkSL::SwizzleComponent::Type a,
205                       SkSL::SwizzleComponent::Type b,
206                       SkSL::SwizzleComponent::Type c,
207                       SkSL::SwizzleComponent::Type d,
208                       Position pos = {},
209                       Position maskPos = {});
210 
211 /**
212  * Returns the absolute value of x. If x is a vector, operates componentwise.
213  */
214 DSLExpression Abs(DSLExpression x, Position pos = {});
215 
216 /**
217  * Returns true if all of the components of boolean vector x are true.
218  */
219 DSLExpression All(DSLExpression x, Position pos = {});
220 
221 /**
222  * Returns true if any of the components of boolean vector x are true.
223  */
224 DSLExpression Any(DSLExpression x, Position pos = {});
225 
226 /**
227  * Returns the arctangent of y over x. Operates componentwise on vectors.
228  */
229 DSLExpression Atan(DSLExpression y_over_x, Position pos = {});
230 DSLExpression Atan(DSLExpression y, DSLExpression x, Position pos = {});
231 
232 /**
233  * Returns x rounded towards positive infinity. If x is a vector, operates componentwise.
234  */
235 DSLExpression Ceil(DSLExpression x, Position pos = {});
236 
237 /**
238  * Returns x clamped to between min and max. If x is a vector, operates componentwise.
239  */
240 DSLExpression Clamp(DSLExpression x, DSLExpression min, DSLExpression max,
241                     Position pos = {});
242 
243 /**
244  * Returns the cosine of x. If x is a vector, operates componentwise.
245  */
246 DSLExpression Cos(DSLExpression x, Position pos = {});
247 
248 /**
249  * Returns the cross product of x and y.
250  */
251 DSLExpression Cross(DSLExpression x, DSLExpression y, Position pos = {});
252 
253 /**
254  * Returns x converted from radians to degrees. If x is a vector, operates componentwise.
255  */
256 DSLExpression Degrees(DSLExpression x, Position pos = {});
257 
258 /**
259  * Returns the distance between x and y.
260  */
261 DSLExpression Distance(DSLExpression x, DSLExpression y,
262                        Position pos = {});
263 
264 /**
265  * Returns the dot product of x and y.
266  */
267 DSLExpression Dot(DSLExpression x, DSLExpression y, Position pos = {});
268 
269 /**
270  * Returns a boolean vector indicating whether components of x are equal to the corresponding
271  * components of y.
272  */
273 DSLExpression Equal(DSLExpression x, DSLExpression y, Position pos = {});
274 
275 /**
276  * Returns e^x. If x is a vector, operates componentwise.
277  */
278 DSLExpression Exp(DSLExpression x, Position pos = {});
279 
280 /**
281  * Returns 2^x. If x is a vector, operates componentwise.
282  */
283 DSLExpression Exp2(DSLExpression x, Position pos = {});
284 
285 /**
286  * If dot(i, nref) >= 0, returns n, otherwise returns -n.
287  */
288 DSLExpression Faceforward(DSLExpression n, DSLExpression i, DSLExpression nref,
289                           Position pos = {});
290 
291 /**
292  * Returns x rounded towards negative infinity. If x is a vector, operates componentwise.
293  */
294 DSLExpression Floor(DSLExpression x, Position pos = {});
295 
296 /**
297  * Returns the fractional part of x. If x is a vector, operates componentwise.
298  */
299 DSLExpression Fract(DSLExpression x, Position pos = {});
300 
301 /**
302  * Returns a boolean vector indicating whether components of x are greater than the corresponding
303  * components of y.
304  */
305 DSLExpression GreaterThan(DSLExpression x, DSLExpression y,
306                           Position pos = {});
307 
308 /**
309  * Returns a boolean vector indicating whether components of x are greater than or equal to the
310  * corresponding components of y.
311  */
312 DSLExpression GreaterThanEqual(DSLExpression x, DSLExpression y,
313                                Position pos = {});
314 
315 /**
316  * Returns the 1/sqrt(x). If x is a vector, operates componentwise.
317  */
318 DSLExpression Inversesqrt(DSLExpression x, Position pos = {});
319 
320 /**
321  * Returns the inverse of the matrix x.
322  */
323 DSLExpression Inverse(DSLExpression x, Position pos = {});
324 
325 /**
326  * Returns the length of the vector x.
327  */
328 DSLExpression Length(DSLExpression x, Position pos = {});
329 
330 /**
331  * Returns a boolean vector indicating whether components of x are less than the corresponding
332  * components of y.
333  */
334 DSLExpression LessThan(DSLExpression x, DSLExpression y,
335                        Position pos = {});
336 
337 /**
338  * Returns a boolean vector indicating whether components of x are less than or equal to the
339  * corresponding components of y.
340  */
341 DSLExpression LessThanEqual(DSLExpression x, DSLExpression y,
342                             Position pos = {});
343 
344 /**
345  * Returns the log base e of x. If x is a vector, operates componentwise.
346  */
347 DSLExpression Log(DSLExpression x, Position pos = {});
348 
349 /**
350  * Returns the log base 2 of x. If x is a vector, operates componentwise.
351  */
352 DSLExpression Log2(DSLExpression x, Position pos = {});
353 
354 /**
355  * Returns the larger (closer to positive infinity) of x and y. If x is a vector, operates
356  * componentwise. y may be either a vector of the same dimensions as x, or a scalar.
357  */
358 DSLExpression Max(DSLExpression x, DSLExpression y, Position pos = {});
359 
360 /**
361  * Returns the smaller (closer to negative infinity) of x and y. If x is a vector, operates
362  * componentwise. y may be either a vector of the same dimensions as x, or a scalar.
363  */
364 DSLExpression Min(DSLExpression x, DSLExpression y, Position pos = {});
365 
366 /**
367  * Returns a linear intepolation between x and y at position a, where a=0 results in x and a=1
368  * results in y. If x and y are vectors, operates componentwise. a may be either a vector of the
369  * same dimensions as x and y, or a scalar.
370  */
371 DSLExpression Mix(DSLExpression x, DSLExpression y, DSLExpression a,
372                   Position pos = {});
373 
374 /**
375  * Returns x modulo y. If x is a vector, operates componentwise. y may be either a vector of the
376  * same dimensions as x, or a scalar.
377  */
378 DSLExpression Mod(DSLExpression x, DSLExpression y, Position pos = {});
379 
380 /**
381  * Returns the vector x normalized to a length of 1.
382  */
383 DSLExpression Normalize(DSLExpression x, Position pos = {});
384 
385 /**
386  * Returns a boolean vector indicating whether components of x are not equal to the corresponding
387  * components of y.
388  */
389 DSLExpression NotEqual(DSLExpression x, DSLExpression y,
390                        Position pos = {});
391 
392 /**
393  * Returns x raised to the power y. If x is a vector, operates componentwise. y may be either a
394  * vector of the same dimensions as x, or a scalar.
395  */
396 DSLExpression Pow(DSLExpression x, DSLExpression y, Position pos = {});
397 
398 /**
399  * Returns x converted from degrees to radians. If x is a vector, operates componentwise.
400  */
401 DSLExpression Radians(DSLExpression x, Position pos = {});
402 
403 /**
404  * Returns i reflected from a surface with normal n.
405  */
406 DSLExpression Reflect(DSLExpression i, DSLExpression n, Position pos = {});
407 
408 /**
409  * Returns i refracted across a surface with normal n and ratio of indices of refraction eta.
410  */
411 DSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta,
412                       Position pos = {});
413 
414 /**
415  * Returns x, rounded to the nearest integer. If x is a vector, operates componentwise.
416  */
417 DSLExpression Round(DSLExpression x, Position pos = {});
418 
419 /**
420  * Returns x clamped to the range [0, 1]. If x is a vector, operates componentwise.
421  */
422 DSLExpression Saturate(DSLExpression x, Position pos = {});
423 
424 /**
425  * Returns -1, 0, or 1 depending on whether x is negative, zero, or positive, respectively. If x is
426  * a vector, operates componentwise.
427  */
428 DSLExpression Sign(DSLExpression x, Position pos = {});
429 
430 /**
431  * Returns the sine of x. If x is a vector, operates componentwise.
432  */
433 DSLExpression Sin(DSLExpression x, Position pos = {});
434 
435 /**
436  * Returns a smooth interpolation between 0 (at x=edge1) and 1 (at x=edge2). If x is a vector,
437  * operates componentwise. edge1 and edge2 may either be both vectors of the same dimensions as x or
438  * scalars.
439  */
440 DSLExpression Smoothstep(DSLExpression edge1, DSLExpression edge2, DSLExpression x,
441                          Position pos = {});
442 
443 /**
444  * Returns the square root of x. If x is a vector, operates componentwise.
445  */
446 DSLExpression Sqrt(DSLExpression x, Position pos = {});
447 
448 /**
449  * Returns 0 if x < edge or 1 if x >= edge. If x is a vector, operates componentwise. edge may be
450  * either a vector of the same dimensions as x, or a scalar.
451  */
452 DSLExpression Step(DSLExpression edge, DSLExpression x, Position pos = {});
453 
454 /**
455  * Returns the tangent of x. If x is a vector, operates componentwise.
456  */
457 DSLExpression Tan(DSLExpression x, Position pos = {});
458 
459 /**
460  * Returns x converted from premultipled to unpremultiplied alpha.
461  */
462 DSLExpression Unpremul(DSLExpression x, Position pos = {});
463 
464 } // namespace dsl
465 
466 } // namespace SkSL
467 
468 #endif
469