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