• 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 #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