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