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