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 #include "include/sksl/DSLCore.h"
9
10 #include "include/core/SkTypes.h"
11 #include "include/private/SkSLDefines.h"
12 #include "include/private/SkSLProgramElement.h"
13 #include "include/private/SkSLStatement.h"
14 #include "include/sksl/DSLModifiers.h"
15 #include "include/sksl/DSLType.h"
16 #include "include/sksl/DSLVar.h"
17 #include "include/sksl/SkSLPosition.h"
18 #include "src/sksl/SkSLCompiler.h"
19 #include "src/sksl/SkSLModifiersPool.h" // IWYU pragma: keep
20 #include "src/sksl/SkSLPool.h"
21 #include "src/sksl/SkSLProgramSettings.h"
22 #include "src/sksl/SkSLThreadContext.h"
23 #include "src/sksl/dsl/priv/DSLWriter.h"
24 #include "src/sksl/ir/SkSLBlock.h"
25 #include "src/sksl/ir/SkSLBreakStatement.h"
26 #include "src/sksl/ir/SkSLContinueStatement.h"
27 #include "src/sksl/ir/SkSLDiscardStatement.h"
28 #include "src/sksl/ir/SkSLDoStatement.h"
29 #include "src/sksl/ir/SkSLExpression.h"
30 #include "src/sksl/ir/SkSLExtension.h"
31 #include "src/sksl/ir/SkSLForStatement.h"
32 #include "src/sksl/ir/SkSLFunctionCall.h"
33 #include "src/sksl/ir/SkSLIfStatement.h"
34 #include "src/sksl/ir/SkSLInterfaceBlock.h"
35 #include "src/sksl/ir/SkSLModifiersDeclaration.h"
36 #include "src/sksl/ir/SkSLProgram.h"
37 #include "src/sksl/ir/SkSLReturnStatement.h"
38 #include "src/sksl/ir/SkSLSwitchStatement.h"
39 #include "src/sksl/ir/SkSLSwizzle.h"
40 #include "src/sksl/ir/SkSLTernaryExpression.h"
41 #include "src/sksl/ir/SkSLVarDeclarations.h"
42
43 #include <vector>
44
45 namespace SkSL {
46
47 class Variable;
48
49 namespace dsl {
50
Start(SkSL::Compiler * compiler,ProgramKind kind)51 void Start(SkSL::Compiler* compiler, ProgramKind kind) {
52 Start(compiler, kind, ProgramSettings());
53 }
54
Start(SkSL::Compiler * compiler,ProgramKind kind,const ProgramSettings & settings)55 void Start(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings) {
56 ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
57 compiler->moduleForProgramKind(kind),
58 /*isModule=*/false));
59 }
60
StartModule(SkSL::Compiler * compiler,ProgramKind kind,const ProgramSettings & settings,const SkSL::Module * parent)61 void StartModule(SkSL::Compiler* compiler,
62 ProgramKind kind,
63 const ProgramSettings& settings,
64 const SkSL::Module* parent) {
65 ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
66 parent, /*isModule=*/true));
67 }
68
End()69 void End() {
70 ThreadContext::SetInstance(nullptr);
71 }
72
GetErrorReporter()73 ErrorReporter& GetErrorReporter() {
74 return ThreadContext::GetErrorReporter();
75 }
76
SetErrorReporter(ErrorReporter * errorReporter)77 void SetErrorReporter(ErrorReporter* errorReporter) {
78 SkASSERT(errorReporter);
79 ThreadContext::SetErrorReporter(errorReporter);
80 }
81
82 class DSLCore {
83 public:
ReleaseProgram(std::unique_ptr<std::string> source)84 static std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<std::string> source) {
85 ThreadContext& instance = ThreadContext::Instance();
86 SkSL::Compiler& compiler = *instance.fCompiler;
87 Pool* pool = instance.fPool.get();
88 auto result = std::make_unique<SkSL::Program>(std::move(source),
89 std::move(instance.fConfig),
90 compiler.fContext,
91 std::move(instance.fProgramElements),
92 std::move(instance.fSharedElements),
93 std::move(instance.fModifiersPool),
94 std::move(compiler.fSymbolTable),
95 std::move(instance.fPool),
96 instance.fInputs);
97 bool success = false;
98 if (!compiler.finalize(*result)) {
99 // Do not return programs that failed to compile.
100 } else if (!compiler.optimize(*result)) {
101 // Do not return programs that failed to optimize.
102 } else {
103 // We have a successful program!
104 success = true;
105 }
106 if (pool) {
107 pool->detachFromThread();
108 }
109 SkASSERT(instance.fProgramElements.empty());
110 SkASSERT(!ThreadContext::SymbolTable());
111 return success ? std::move(result) : nullptr;
112 }
113
114 template <typename... Args>
Call(const char * name,Position pos,Args...args)115 static DSLExpression Call(const char* name, Position pos, Args... args) {
116 SkSL::ExpressionArray argArray;
117 argArray.reserve_back(sizeof...(args));
118 ((void)argArray.push_back(args.release()), ...);
119
120 return DSLExpression(SkSL::FunctionCall::Convert(ThreadContext::Context(), pos,
121 ThreadContext::Compiler().convertIdentifier(Position(), name),
122 std::move(argArray)));
123 }
124
Break(Position pos)125 static DSLStatement Break(Position pos) {
126 return SkSL::BreakStatement::Make(pos);
127 }
128
Continue(Position pos)129 static DSLStatement Continue(Position pos) {
130 return SkSL::ContinueStatement::Make(pos);
131 }
132
Declare(const DSLModifiers & modifiers)133 static void Declare(const DSLModifiers& modifiers) {
134 ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::ModifiersDeclaration>(
135 ThreadContext::Modifiers(modifiers.fModifiers)));
136 }
137
Declare(DSLVar & var,Position pos)138 static DSLStatement Declare(DSLVar& var, Position pos) {
139 return DSLWriter::Declaration(var);
140 }
141
Declare(SkTArray<DSLVar> & vars,Position pos)142 static DSLStatement Declare(SkTArray<DSLVar>& vars, Position pos) {
143 StatementArray statements;
144 for (DSLVar& v : vars) {
145 statements.push_back(Declare(v, pos).release());
146 }
147 return SkSL::Block::Make(pos, std::move(statements), Block::Kind::kCompoundStatement);
148 }
149
Declare(DSLGlobalVar & var,Position pos)150 static void Declare(DSLGlobalVar& var, Position pos) {
151 std::unique_ptr<SkSL::Statement> stmt = DSLWriter::Declaration(var);
152 if (stmt && !stmt->isEmpty()) {
153 ThreadContext::ProgramElements().push_back(
154 std::make_unique<SkSL::GlobalVarDeclaration>(std::move(stmt)));
155 }
156 }
157
Declare(SkTArray<DSLGlobalVar> & vars,Position pos)158 static void Declare(SkTArray<DSLGlobalVar>& vars, Position pos) {
159 for (DSLGlobalVar& v : vars) {
160 Declare(v, pos);
161 }
162 }
163
Discard(Position pos)164 static DSLStatement Discard(Position pos) {
165 return DSLStatement(SkSL::DiscardStatement::Convert(ThreadContext::Context(), pos), pos);
166 }
167
Do(DSLStatement stmt,DSLExpression test,Position pos)168 static DSLStatement Do(DSLStatement stmt, DSLExpression test, Position pos) {
169 return DSLStatement(DoStatement::Convert(ThreadContext::Context(), pos, stmt.release(),
170 test.release()), pos);
171 }
172
For(DSLStatement initializer,DSLExpression test,DSLExpression next,DSLStatement stmt,Position pos,const ForLoopPositions & forLoopPositions)173 static DSLStatement For(DSLStatement initializer, DSLExpression test,
174 DSLExpression next, DSLStatement stmt, Position pos,
175 const ForLoopPositions& forLoopPositions) {
176 return DSLStatement(ForStatement::Convert(ThreadContext::Context(), pos, forLoopPositions,
177 initializer.releaseIfPossible(),
178 test.releaseIfPossible(),
179 next.releaseIfPossible(),
180 stmt.release(),
181 ThreadContext::SymbolTable()), pos);
182 }
183
If(DSLExpression test,DSLStatement ifTrue,DSLStatement ifFalse,Position pos)184 static DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse,
185 Position pos) {
186 return DSLStatement(IfStatement::Convert(ThreadContext::Context(),
187 pos,
188 test.release(),
189 ifTrue.release(),
190 ifFalse.releaseIfPossible()), pos);
191 }
192
InterfaceBlock(const DSLModifiers & modifiers,std::string_view typeName,SkTArray<DSLField> fields,std::string_view varName,int arraySize,Position pos)193 static DSLExpression InterfaceBlock(const DSLModifiers& modifiers, std::string_view typeName,
194 SkTArray<DSLField> fields, std::string_view varName,
195 int arraySize, Position pos) {
196 // Build a struct type corresponding to the passed-in fields and array size.
197 DSLType varType = StructType(typeName, fields, /*interfaceBlock=*/true, pos);
198 if (arraySize > 0) {
199 varType = Array(varType, arraySize);
200 }
201
202 // Create a global variable to attach our interface block to. (The variable doesn't actually
203 // get a program element, though; the interface block does instead.)
204 DSLGlobalVar var(modifiers, varType, varName, DSLExpression(), pos);
205 if (SkSL::Variable* skslVar = DSLWriter::Var(var)) {
206 // Add an InterfaceBlock program element to the program.
207 if (std::unique_ptr<SkSL::InterfaceBlock> intf = SkSL::InterfaceBlock::Convert(
208 ThreadContext::Context(), pos, skslVar, ThreadContext::SymbolTable())) {
209 ThreadContext::ProgramElements().push_back(std::move(intf));
210 // Return a VariableReference to the global variable tied to the interface block.
211 return DSLExpression(var);
212 }
213 }
214
215 // The InterfaceBlock couldn't be created; return poison.
216 return DSLExpression(nullptr);
217 }
218
Return(DSLExpression value,Position pos)219 static DSLStatement Return(DSLExpression value, Position pos) {
220 // Note that because Return is called before the function in which it resides exists, at
221 // this point we do not know the function's return type. We therefore do not check for
222 // errors, or coerce the value to the correct type, until the return statement is actually
223 // added to a function. (This is done in FunctionDefinition::Convert.)
224 return SkSL::ReturnStatement::Make(pos, value.releaseIfPossible());
225 }
226
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,Position pos,Position maskPos)227 static DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a,
228 Position pos, Position maskPos) {
229 return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
230 base.release(), ComponentArray{a}),
231 pos);
232 }
233
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,Position pos,Position maskPos)234 static DSLExpression Swizzle(DSLExpression base,
235 SkSL::SwizzleComponent::Type a,
236 SkSL::SwizzleComponent::Type b,
237 Position pos,
238 Position maskPos) {
239 return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
240 base.release(), ComponentArray{a, b}),
241 pos);
242 }
243
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,SkSL::SwizzleComponent::Type c,Position pos,Position maskPos)244 static DSLExpression Swizzle(DSLExpression base,
245 SkSL::SwizzleComponent::Type a,
246 SkSL::SwizzleComponent::Type b,
247 SkSL::SwizzleComponent::Type c,
248 Position pos,
249 Position maskPos) {
250 return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
251 base.release(), ComponentArray{a, b, c}),
252 pos);
253 }
254
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,SkSL::SwizzleComponent::Type c,SkSL::SwizzleComponent::Type d,Position pos,Position maskPos)255 static DSLExpression Swizzle(DSLExpression base,
256 SkSL::SwizzleComponent::Type a,
257 SkSL::SwizzleComponent::Type b,
258 SkSL::SwizzleComponent::Type c,
259 SkSL::SwizzleComponent::Type d,
260 Position pos,
261 Position maskPos) {
262 return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
263 base.release(), ComponentArray{a, b, c, d}),
264 pos);
265 }
266
Select(DSLExpression test,DSLExpression ifTrue,DSLExpression ifFalse,Position pos)267 static DSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse,
268 Position pos) {
269 auto result = TernaryExpression::Convert(ThreadContext::Context(), pos, test.release(),
270 ifTrue.release(), ifFalse.release());
271 SkASSERT(!result || result->fPosition == pos);
272 return DSLExpression(std::move(result), pos);
273 }
274
Switch(DSLExpression value,SkTArray<DSLCase> cases,Position pos)275 static DSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, Position pos) {
276 ExpressionArray values;
277 values.reserve_back(cases.size());
278 StatementArray caseBlocks;
279 caseBlocks.reserve_back(cases.size());
280 for (DSLCase& c : cases) {
281 values.push_back(c.fValue.releaseIfPossible());
282 caseBlocks.push_back(SkSL::Block::Make(Position(), std::move(c.fStatements),
283 Block::Kind::kUnbracedBlock));
284 }
285 return DSLStatement(SwitchStatement::Convert(ThreadContext::Context(), pos,
286 value.release(),
287 std::move(values),
288 std::move(caseBlocks),
289 ThreadContext::SymbolTable()), pos);
290 }
291
While(DSLExpression test,DSLStatement stmt,Position pos)292 static DSLStatement While(DSLExpression test, DSLStatement stmt, Position pos) {
293 return DSLStatement(ForStatement::ConvertWhile(ThreadContext::Context(), pos,
294 test.release(),
295 stmt.release(),
296 ThreadContext::SymbolTable()), pos);
297 }
298 };
299
ReleaseProgram(std::unique_ptr<std::string> source)300 std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<std::string> source) {
301 return DSLCore::ReleaseProgram(std::move(source));
302 }
303
AddExtension(std::string_view name,Position pos)304 void AddExtension(std::string_view name, Position pos) {
305 ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::Extension>(pos, name));
306 }
307
Break(Position pos)308 DSLStatement Break(Position pos) {
309 return DSLCore::Break(pos);
310 }
311
Continue(Position pos)312 DSLStatement Continue(Position pos) {
313 return DSLCore::Continue(pos);
314 }
315
Declare(const DSLModifiers & modifiers,Position pos)316 void Declare(const DSLModifiers& modifiers, Position pos) {
317 SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind;
318 if (!ProgramConfig::IsFragment(kind) &&
319 !ProgramConfig::IsVertex(kind)) {
320 ThreadContext::ReportError("layout qualifiers are not allowed in this kind of program",
321 pos);
322 return;
323 }
324 DSLCore::Declare(modifiers);
325 }
326
327 // Logically, we'd want the variable's initial value to appear on here in Declare, since that
328 // matches how we actually write code (and in fact that was what our first attempt looked like).
329 // Unfortunately, C++ doesn't guarantee execution order between arguments, and Declare() can appear
330 // as a function argument in constructs like Block(Declare(x, 0), foo(x)). If these are executed out
331 // of order, we will evaluate the reference to x before we evaluate Declare(x, 0), and thus the
332 // variable's initial value is unknown at the point of reference. There are probably some other
333 // issues with this as well, but it is particularly dangerous when x is const, since SkSL will
334 // expect its value to be known when it is referenced and will end up asserting, dereferencing a
335 // null pointer, or possibly doing something else awful.
336 //
337 // So, we put the initial value onto the Var itself instead of the Declare to guarantee that it is
338 // always executed in the correct order.
Declare(DSLVar & var,Position pos)339 DSLStatement Declare(DSLVar& var, Position pos) {
340 return DSLCore::Declare(var, pos);
341 }
342
Declare(SkTArray<DSLVar> & vars,Position pos)343 DSLStatement Declare(SkTArray<DSLVar>& vars, Position pos) {
344 return DSLCore::Declare(vars, pos);
345 }
346
Declare(DSLGlobalVar & var,Position pos)347 void Declare(DSLGlobalVar& var, Position pos) {
348 DSLCore::Declare(var, pos);
349 }
350
Declare(SkTArray<DSLGlobalVar> & vars,Position pos)351 void Declare(SkTArray<DSLGlobalVar>& vars, Position pos) {
352 DSLCore::Declare(vars, pos);
353 }
354
Discard(Position pos)355 DSLStatement Discard(Position pos) {
356 return DSLCore::Discard(pos);
357 }
358
Do(DSLStatement stmt,DSLExpression test,Position pos)359 DSLStatement Do(DSLStatement stmt, DSLExpression test, Position pos) {
360 return DSLCore::Do(std::move(stmt), std::move(test), pos);
361 }
362
For(DSLStatement initializer,DSLExpression test,DSLExpression next,DSLStatement stmt,Position pos,ForLoopPositions forLoopPositions)363 DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
364 DSLStatement stmt, Position pos, ForLoopPositions forLoopPositions) {
365 return DSLCore::For(std::move(initializer), std::move(test), std::move(next),
366 std::move(stmt), pos, forLoopPositions);
367 }
368
If(DSLExpression test,DSLStatement ifTrue,DSLStatement ifFalse,Position pos)369 DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, Position pos) {
370 return DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse), pos);
371 }
372
InterfaceBlock(const DSLModifiers & modifiers,std::string_view typeName,SkTArray<DSLField> fields,std::string_view varName,int arraySize,Position pos)373 DSLExpression InterfaceBlock(const DSLModifiers& modifiers, std::string_view typeName,
374 SkTArray<DSLField> fields, std::string_view varName, int arraySize,
375 Position pos) {
376 return DSLCore::InterfaceBlock(modifiers, typeName, std::move(fields), varName, arraySize, pos);
377 }
378
Return(DSLExpression expr,Position pos)379 DSLStatement Return(DSLExpression expr, Position pos) {
380 return DSLCore::Return(std::move(expr), pos);
381 }
382
Select(DSLExpression test,DSLExpression ifTrue,DSLExpression ifFalse,Position pos)383 DSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse,
384 Position pos) {
385 return DSLCore::Select(std::move(test), std::move(ifTrue), std::move(ifFalse), pos);
386 }
387
Switch(DSLExpression value,SkTArray<DSLCase> cases,Position pos)388 DSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, Position pos) {
389 return DSLCore::Switch(std::move(value), std::move(cases), pos);
390 }
391
While(DSLExpression test,DSLStatement stmt,Position pos)392 DSLStatement While(DSLExpression test, DSLStatement stmt, Position pos) {
393 return DSLCore::While(std::move(test), std::move(stmt), pos);
394 }
395
Abs(DSLExpression x,Position pos)396 DSLExpression Abs(DSLExpression x, Position pos) {
397 return DSLCore::Call("abs", pos, std::move(x));
398 }
399
All(DSLExpression x,Position pos)400 DSLExpression All(DSLExpression x, Position pos) {
401 return DSLCore::Call("all", pos, std::move(x));
402 }
403
Any(DSLExpression x,Position pos)404 DSLExpression Any(DSLExpression x, Position pos) {
405 return DSLCore::Call("any", pos, std::move(x));
406 }
407
Atan(DSLExpression y_over_x,Position pos)408 DSLExpression Atan(DSLExpression y_over_x, Position pos) {
409 return DSLCore::Call("atan", pos, std::move(y_over_x));
410 }
411
Atan(DSLExpression y,DSLExpression x,Position pos)412 DSLExpression Atan(DSLExpression y, DSLExpression x, Position pos) {
413 return DSLCore::Call("atan", pos, std::move(y), std::move(x));
414 }
415
Ceil(DSLExpression x,Position pos)416 DSLExpression Ceil(DSLExpression x, Position pos) {
417 return DSLCore::Call("ceil", pos, std::move(x));
418 }
419
Clamp(DSLExpression x,DSLExpression min,DSLExpression max,Position pos)420 DSLExpression Clamp(DSLExpression x, DSLExpression min, DSLExpression max, Position pos) {
421 return DSLCore::Call("clamp", pos, std::move(x), std::move(min), std::move(max));
422 }
423
Cos(DSLExpression x,Position pos)424 DSLExpression Cos(DSLExpression x, Position pos) {
425 return DSLCore::Call("cos", pos, std::move(x));
426 }
427
Cross(DSLExpression x,DSLExpression y,Position pos)428 DSLExpression Cross(DSLExpression x, DSLExpression y, Position pos) {
429 return DSLCore::Call("cross", pos, std::move(x), std::move(y));
430 }
431
Degrees(DSLExpression x,Position pos)432 DSLExpression Degrees(DSLExpression x, Position pos) {
433 return DSLCore::Call("degrees", pos, std::move(x));
434 }
435
Distance(DSLExpression x,DSLExpression y,Position pos)436 DSLExpression Distance(DSLExpression x, DSLExpression y, Position pos) {
437 return DSLCore::Call("distance", pos, std::move(x), std::move(y));
438 }
439
Dot(DSLExpression x,DSLExpression y,Position pos)440 DSLExpression Dot(DSLExpression x, DSLExpression y, Position pos) {
441 return DSLCore::Call("dot", pos, std::move(x), std::move(y));
442 }
443
Equal(DSLExpression x,DSLExpression y,Position pos)444 DSLExpression Equal(DSLExpression x, DSLExpression y, Position pos) {
445 return DSLCore::Call("equal", pos, std::move(x), std::move(y));
446 }
447
Exp(DSLExpression x,Position pos)448 DSLExpression Exp(DSLExpression x, Position pos) {
449 return DSLCore::Call("exp", pos, std::move(x));
450 }
451
Exp2(DSLExpression x,Position pos)452 DSLExpression Exp2(DSLExpression x, Position pos) {
453 return DSLCore::Call("exp2", pos, std::move(x));
454 }
455
Faceforward(DSLExpression n,DSLExpression i,DSLExpression nref,Position pos)456 DSLExpression Faceforward(DSLExpression n, DSLExpression i, DSLExpression nref, Position pos) {
457 return DSLCore::Call("faceforward", pos, std::move(n), std::move(i), std::move(nref));
458 }
459
Fract(DSLExpression x,Position pos)460 DSLExpression Fract(DSLExpression x, Position pos) {
461 return DSLCore::Call("fract", pos, std::move(x));
462 }
463
Floor(DSLExpression x,Position pos)464 DSLExpression Floor(DSLExpression x, Position pos) {
465 return DSLCore::Call("floor", pos, std::move(x));
466 }
467
GreaterThan(DSLExpression x,DSLExpression y,Position pos)468 DSLExpression GreaterThan(DSLExpression x, DSLExpression y, Position pos) {
469 return DSLCore::Call("greaterThan", pos, std::move(x), std::move(y));
470 }
471
GreaterThanEqual(DSLExpression x,DSLExpression y,Position pos)472 DSLExpression GreaterThanEqual(DSLExpression x, DSLExpression y, Position pos) {
473 return DSLCore::Call("greaterThanEqual", pos, std::move(x), std::move(y));
474 }
475
Inverse(DSLExpression x,Position pos)476 DSLExpression Inverse(DSLExpression x, Position pos) {
477 return DSLCore::Call("inverse", pos, std::move(x));
478 }
479
Inversesqrt(DSLExpression x,Position pos)480 DSLExpression Inversesqrt(DSLExpression x, Position pos) {
481 return DSLCore::Call("inversesqrt", pos, std::move(x));
482 }
483
Length(DSLExpression x,Position pos)484 DSLExpression Length(DSLExpression x, Position pos) {
485 return DSLCore::Call("length", pos, std::move(x));
486 }
487
LessThan(DSLExpression x,DSLExpression y,Position pos)488 DSLExpression LessThan(DSLExpression x, DSLExpression y, Position pos) {
489 return DSLCore::Call("lessThan", pos, std::move(x), std::move(y));
490 }
491
LessThanEqual(DSLExpression x,DSLExpression y,Position pos)492 DSLExpression LessThanEqual(DSLExpression x, DSLExpression y, Position pos) {
493 return DSLCore::Call("lessThanEqual", pos, std::move(x), std::move(y));
494 }
495
Log(DSLExpression x,Position pos)496 DSLExpression Log(DSLExpression x, Position pos) {
497 return DSLCore::Call("log", pos, std::move(x));
498 }
499
Log2(DSLExpression x,Position pos)500 DSLExpression Log2(DSLExpression x, Position pos) {
501 return DSLCore::Call("log2", pos, std::move(x));
502 }
503
Max(DSLExpression x,DSLExpression y,Position pos)504 DSLExpression Max(DSLExpression x, DSLExpression y, Position pos) {
505 return DSLCore::Call("max", pos, std::move(x), std::move(y));
506 }
507
Min(DSLExpression x,DSLExpression y,Position pos)508 DSLExpression Min(DSLExpression x, DSLExpression y, Position pos) {
509 return DSLCore::Call("min", pos, std::move(x), std::move(y));
510 }
511
Mix(DSLExpression x,DSLExpression y,DSLExpression a,Position pos)512 DSLExpression Mix(DSLExpression x, DSLExpression y, DSLExpression a, Position pos) {
513 return DSLCore::Call("mix", pos, std::move(x), std::move(y), std::move(a));
514 }
515
Mod(DSLExpression x,DSLExpression y,Position pos)516 DSLExpression Mod(DSLExpression x, DSLExpression y, Position pos) {
517 return DSLCore::Call("mod", pos, std::move(x), std::move(y));
518 }
519
Normalize(DSLExpression x,Position pos)520 DSLExpression Normalize(DSLExpression x, Position pos) {
521 return DSLCore::Call("normalize", pos, std::move(x));
522 }
523
NotEqual(DSLExpression x,DSLExpression y,Position pos)524 DSLExpression NotEqual(DSLExpression x, DSLExpression y, Position pos) {
525 return DSLCore::Call("notEqual", pos, std::move(x), std::move(y));
526 }
527
Pow(DSLExpression x,DSLExpression y,Position pos)528 DSLExpression Pow(DSLExpression x, DSLExpression y, Position pos) {
529 return DSLCore::Call("pow", pos, std::move(x), std::move(y));
530 }
531
Radians(DSLExpression x,Position pos)532 DSLExpression Radians(DSLExpression x, Position pos) {
533 return DSLCore::Call("radians", pos, std::move(x));
534 }
535
Reflect(DSLExpression i,DSLExpression n,Position pos)536 DSLExpression Reflect(DSLExpression i, DSLExpression n, Position pos) {
537 return DSLCore::Call("reflect", pos, std::move(i), std::move(n));
538 }
539
Refract(DSLExpression i,DSLExpression n,DSLExpression eta,Position pos)540 DSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta, Position pos) {
541 return DSLCore::Call("refract", pos, std::move(i), std::move(n), std::move(eta));
542 }
543
Round(DSLExpression x,Position pos)544 DSLExpression Round(DSLExpression x, Position pos) {
545 return DSLCore::Call("round", pos, std::move(x));
546 }
547
Saturate(DSLExpression x,Position pos)548 DSLExpression Saturate(DSLExpression x, Position pos) {
549 return DSLCore::Call("saturate", pos, std::move(x));
550 }
551
Sign(DSLExpression x,Position pos)552 DSLExpression Sign(DSLExpression x, Position pos) {
553 return DSLCore::Call("sign", pos, std::move(x));
554 }
555
Sin(DSLExpression x,Position pos)556 DSLExpression Sin(DSLExpression x, Position pos) {
557 return DSLCore::Call("sin", pos, std::move(x));
558 }
559
Smoothstep(DSLExpression edge1,DSLExpression edge2,DSLExpression x,Position pos)560 DSLExpression Smoothstep(DSLExpression edge1, DSLExpression edge2, DSLExpression x,
561 Position pos) {
562 return DSLCore::Call("smoothstep", pos, std::move(edge1), std::move(edge2), std::move(x));
563 }
564
Sqrt(DSLExpression x,Position pos)565 DSLExpression Sqrt(DSLExpression x, Position pos) {
566 return DSLCore::Call("sqrt", pos, std::move(x));
567 }
568
Step(DSLExpression edge,DSLExpression x,Position pos)569 DSLExpression Step(DSLExpression edge, DSLExpression x, Position pos) {
570 return DSLCore::Call("step", pos, std::move(edge), std::move(x));
571 }
572
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,Position pos,Position maskPos)573 DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a,
574 Position pos, Position maskPos) {
575 return DSLCore::Swizzle(std::move(base), a, pos, maskPos);
576 }
577
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,Position pos,Position maskPos)578 DSLExpression Swizzle(DSLExpression base,
579 SkSL::SwizzleComponent::Type a,
580 SkSL::SwizzleComponent::Type b,
581 Position pos,
582 Position maskPos) {
583 return DSLCore::Swizzle(std::move(base), a, b, pos, maskPos);
584 }
585
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,SkSL::SwizzleComponent::Type c,Position pos,Position maskPos)586 DSLExpression Swizzle(DSLExpression base,
587 SkSL::SwizzleComponent::Type a,
588 SkSL::SwizzleComponent::Type b,
589 SkSL::SwizzleComponent::Type c,
590 Position pos,
591 Position maskPos) {
592 return DSLCore::Swizzle(std::move(base), a, b, c, pos, maskPos);
593 }
594
Swizzle(DSLExpression base,SkSL::SwizzleComponent::Type a,SkSL::SwizzleComponent::Type b,SkSL::SwizzleComponent::Type c,SkSL::SwizzleComponent::Type d,Position pos,Position maskPos)595 DSLExpression Swizzle(DSLExpression base,
596 SkSL::SwizzleComponent::Type a,
597 SkSL::SwizzleComponent::Type b,
598 SkSL::SwizzleComponent::Type c,
599 SkSL::SwizzleComponent::Type d,
600 Position pos,
601 Position maskPos) {
602 return DSLCore::Swizzle(std::move(base), a, b, c, d, pos, maskPos);
603 }
604
Tan(DSLExpression x,Position pos)605 DSLExpression Tan(DSLExpression x, Position pos) {
606 return DSLCore::Call("tan", pos, std::move(x));
607 }
608
Unpremul(DSLExpression x,Position pos)609 DSLExpression Unpremul(DSLExpression x, Position pos) {
610 return DSLCore::Call("unpremul", pos, std::move(x));
611 }
612
613 } // namespace dsl
614
615 } // namespace SkSL
616