1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/sksl/DSLCore.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/private/SkSLDefines.h" 11cb93a386Sopenharmony_ci#include "include/sksl/DSLSymbols.h" 12cb93a386Sopenharmony_ci#include "include/sksl/DSLVar.h" 13cb93a386Sopenharmony_ci#include "src/sksl/SkSLCompiler.h" 14cb93a386Sopenharmony_ci#include "src/sksl/SkSLThreadContext.h" 15cb93a386Sopenharmony_ci#include "src/sksl/dsl/priv/DSLWriter.h" 16cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBlock.h" 17cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBreakStatement.h" 18cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLContinueStatement.h" 19cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLDiscardStatement.h" 20cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLDoStatement.h" 21cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLExtension.h" 22cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLField.h" 23cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLForStatement.h" 24cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionCall.h" 25cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLIfStatement.h" 26cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLInterfaceBlock.h" 27cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLModifiersDeclaration.h" 28cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLReturnStatement.h" 29cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLStructDefinition.h" 30cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwitchStatement.h" 31cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwizzle.h" 32cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLTernaryExpression.h" 33cb93a386Sopenharmony_ci#include "src/sksl/transform/SkSLTransform.h" 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_cinamespace SkSL { 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_cinamespace dsl { 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_civoid Start(SkSL::Compiler* compiler, ProgramKind kind) { 40cb93a386Sopenharmony_ci Start(compiler, kind, ProgramSettings()); 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_civoid Start(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings) { 44cb93a386Sopenharmony_ci ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings, 45cb93a386Sopenharmony_ci compiler->moduleForProgramKind(kind), /*isModule=*/false)); 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_civoid StartModule(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings, 49cb93a386Sopenharmony_ci SkSL::ParsedModule baseModule) { 50cb93a386Sopenharmony_ci ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings, 51cb93a386Sopenharmony_ci baseModule, /*isModule=*/true)); 52cb93a386Sopenharmony_ci} 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_civoid End() { 55cb93a386Sopenharmony_ci SkASSERTF(!ThreadContext::InFragmentProcessor(), 56cb93a386Sopenharmony_ci "more calls to StartFragmentProcessor than to EndFragmentProcessor"); 57cb93a386Sopenharmony_ci ThreadContext::SetInstance(nullptr); 58cb93a386Sopenharmony_ci} 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ciErrorReporter& GetErrorReporter() { 61cb93a386Sopenharmony_ci return ThreadContext::GetErrorReporter(); 62cb93a386Sopenharmony_ci} 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_civoid SetErrorReporter(ErrorReporter* errorReporter) { 65cb93a386Sopenharmony_ci SkASSERT(errorReporter); 66cb93a386Sopenharmony_ci ThreadContext::SetErrorReporter(errorReporter); 67cb93a386Sopenharmony_ci} 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ciclass DSLCore { 70cb93a386Sopenharmony_cipublic: 71cb93a386Sopenharmony_ci static std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<String> source) { 72cb93a386Sopenharmony_ci ThreadContext& instance = ThreadContext::Instance(); 73cb93a386Sopenharmony_ci SkSL::Compiler& compiler = *instance.fCompiler; 74cb93a386Sopenharmony_ci const SkSL::Context& context = *compiler.fContext; 75cb93a386Sopenharmony_ci // Variables defined in the pre-includes need their declaring elements added to the program 76cb93a386Sopenharmony_ci if (!instance.fConfig->fIsBuiltinCode && context.fIntrinsics) { 77cb93a386Sopenharmony_ci Transform::FindAndDeclareBuiltinVariables(context, instance.fConfig->fKind, 78cb93a386Sopenharmony_ci instance.fSharedElements); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci Pool* pool = instance.fPool.get(); 81cb93a386Sopenharmony_ci auto result = std::make_unique<SkSL::Program>(std::move(source), 82cb93a386Sopenharmony_ci std::move(instance.fConfig), 83cb93a386Sopenharmony_ci compiler.fContext, 84cb93a386Sopenharmony_ci std::move(instance.fProgramElements), 85cb93a386Sopenharmony_ci std::move(instance.fSharedElements), 86cb93a386Sopenharmony_ci std::move(instance.fModifiersPool), 87cb93a386Sopenharmony_ci std::move(compiler.fSymbolTable), 88cb93a386Sopenharmony_ci std::move(instance.fPool), 89cb93a386Sopenharmony_ci instance.fInputs); 90cb93a386Sopenharmony_ci bool success = false; 91cb93a386Sopenharmony_ci if (!compiler.finalize(*result)) { 92cb93a386Sopenharmony_ci // Do not return programs that failed to compile. 93cb93a386Sopenharmony_ci } else if (!compiler.optimize(*result)) { 94cb93a386Sopenharmony_ci // Do not return programs that failed to optimize. 95cb93a386Sopenharmony_ci } else { 96cb93a386Sopenharmony_ci // We have a successful program! 97cb93a386Sopenharmony_ci success = true; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci if (!success) { 100cb93a386Sopenharmony_ci ThreadContext::ReportErrors(PositionInfo()); 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci if (pool) { 103cb93a386Sopenharmony_ci pool->detachFromThread(); 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci SkASSERT(instance.fProgramElements.empty()); 106cb93a386Sopenharmony_ci SkASSERT(!ThreadContext::SymbolTable()); 107cb93a386Sopenharmony_ci return success ? std::move(result) : nullptr; 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci static DSLGlobalVar sk_FragColor() { 111cb93a386Sopenharmony_ci return DSLGlobalVar("sk_FragColor"); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci static DSLGlobalVar sk_FragCoord() { 115cb93a386Sopenharmony_ci return DSLGlobalVar("sk_FragCoord"); 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci static DSLExpression sk_Position() { 119cb93a386Sopenharmony_ci return DSLExpression(Symbol("sk_Position")); 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci template <typename... Args> 123cb93a386Sopenharmony_ci static DSLPossibleExpression Call(const char* name, Args... args) { 124cb93a386Sopenharmony_ci SkSL::ExpressionArray argArray; 125cb93a386Sopenharmony_ci argArray.reserve_back(sizeof...(args)); 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci // in C++17, we could just do: 128cb93a386Sopenharmony_ci // (argArray.push_back(args.release()), ...); 129cb93a386Sopenharmony_ci int unused[] = {0, (static_cast<void>(argArray.push_back(args.release())), 0)...}; 130cb93a386Sopenharmony_ci static_cast<void>(unused); 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci return SkSL::FunctionCall::Convert(ThreadContext::Context(), /*line=*/-1, 133cb93a386Sopenharmony_ci ThreadContext::Compiler().convertIdentifier(-1, name), std::move(argArray)); 134cb93a386Sopenharmony_ci } 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci static DSLStatement Break(PositionInfo pos) { 137cb93a386Sopenharmony_ci return SkSL::BreakStatement::Make(pos.line()); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci static DSLStatement Continue(PositionInfo pos) { 141cb93a386Sopenharmony_ci return SkSL::ContinueStatement::Make(pos.line()); 142cb93a386Sopenharmony_ci } 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci static void Declare(const DSLModifiers& modifiers) { 145cb93a386Sopenharmony_ci ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::ModifiersDeclaration>( 146cb93a386Sopenharmony_ci ThreadContext::Modifiers(modifiers.fModifiers))); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci static DSLStatement Declare(DSLVar& var, PositionInfo pos) { 150cb93a386Sopenharmony_ci if (var.fDeclared) { 151cb93a386Sopenharmony_ci ThreadContext::ReportError("variable has already been declared", pos); 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ci var.fDeclared = true; 154cb93a386Sopenharmony_ci return DSLWriter::Declaration(var); 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci static DSLStatement Declare(SkTArray<DSLVar>& vars, PositionInfo pos) { 158cb93a386Sopenharmony_ci StatementArray statements; 159cb93a386Sopenharmony_ci for (DSLVar& v : vars) { 160cb93a386Sopenharmony_ci statements.push_back(Declare(v, pos).release()); 161cb93a386Sopenharmony_ci } 162cb93a386Sopenharmony_ci return SkSL::Block::MakeUnscoped(pos.line(), std::move(statements)); 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci static void Declare(DSLGlobalVar& var, PositionInfo pos) { 166cb93a386Sopenharmony_ci if (var.fDeclared) { 167cb93a386Sopenharmony_ci ThreadContext::ReportError("variable has already been declared", pos); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci var.fDeclared = true; 170cb93a386Sopenharmony_ci std::unique_ptr<SkSL::Statement> stmt = DSLWriter::Declaration(var); 171cb93a386Sopenharmony_ci if (stmt) { 172cb93a386Sopenharmony_ci if (!stmt->isEmpty()) { 173cb93a386Sopenharmony_ci ThreadContext::ProgramElements().push_back( 174cb93a386Sopenharmony_ci std::make_unique<SkSL::GlobalVarDeclaration>(std::move(stmt))); 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci } else if (var.fName == SkSL::Compiler::FRAGCOLOR_NAME) { 177cb93a386Sopenharmony_ci // sk_FragColor can end up with a null declaration despite no error occurring due to 178cb93a386Sopenharmony_ci // specific treatment in the compiler. Ignore the null and just grab the existing 179cb93a386Sopenharmony_ci // variable from the symbol table. 180cb93a386Sopenharmony_ci const SkSL::Symbol* alreadyDeclared = (*ThreadContext::SymbolTable())[var.fName]; 181cb93a386Sopenharmony_ci if (alreadyDeclared && alreadyDeclared->is<Variable>()) { 182cb93a386Sopenharmony_ci var.fVar = &alreadyDeclared->as<Variable>(); 183cb93a386Sopenharmony_ci var.fInitialized = true; 184cb93a386Sopenharmony_ci } 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci static void Declare(SkTArray<DSLGlobalVar>& vars, PositionInfo pos) { 189cb93a386Sopenharmony_ci for (DSLGlobalVar& v : vars) { 190cb93a386Sopenharmony_ci Declare(v, pos); 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci } 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci static DSLStatement Discard(PositionInfo pos) { 195cb93a386Sopenharmony_ci return SkSL::DiscardStatement::Make(pos.line()); 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ci static DSLPossibleStatement Do(DSLStatement stmt, DSLExpression test) { 199cb93a386Sopenharmony_ci return DoStatement::Convert(ThreadContext::Context(), stmt.release(), test.release()); 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ci static DSLPossibleStatement For(DSLStatement initializer, DSLExpression test, 203cb93a386Sopenharmony_ci DSLExpression next, DSLStatement stmt, PositionInfo pos) { 204cb93a386Sopenharmony_ci return ForStatement::Convert(ThreadContext::Context(), pos.line(), 205cb93a386Sopenharmony_ci initializer.releaseIfPossible(), test.releaseIfPossible(), 206cb93a386Sopenharmony_ci next.releaseIfPossible(), stmt.release(), 207cb93a386Sopenharmony_ci ThreadContext::SymbolTable()); 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci static DSLPossibleStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, 211cb93a386Sopenharmony_ci bool isStatic) { 212cb93a386Sopenharmony_ci return IfStatement::Convert(ThreadContext::Context(), /*line=*/-1, isStatic, test.release(), 213cb93a386Sopenharmony_ci ifTrue.release(), ifFalse.releaseIfPossible()); 214cb93a386Sopenharmony_ci } 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ci static void FindRTAdjust(SkSL::InterfaceBlock& intf, PositionInfo pos) { 217cb93a386Sopenharmony_ci const std::vector<SkSL::Type::Field>& fields = 218cb93a386Sopenharmony_ci intf.variable().type().componentType().fields(); 219cb93a386Sopenharmony_ci const Context& context = ThreadContext::Context(); 220cb93a386Sopenharmony_ci for (size_t i = 0; i < fields.size(); ++i) { 221cb93a386Sopenharmony_ci const SkSL::Type::Field& f = fields[i]; 222cb93a386Sopenharmony_ci if (f.fName == SkSL::Compiler::RTADJUST_NAME) { 223cb93a386Sopenharmony_ci if (*f.fType == *context.fTypes.fFloat4) { 224cb93a386Sopenharmony_ci ThreadContext::RTAdjustData& rtAdjust = ThreadContext::RTAdjustState(); 225cb93a386Sopenharmony_ci rtAdjust.fInterfaceBlock = &intf.variable(); 226cb93a386Sopenharmony_ci rtAdjust.fFieldIndex = i; 227cb93a386Sopenharmony_ci } else { 228cb93a386Sopenharmony_ci ThreadContext::ReportError("sk_RTAdjust must have type 'float4'", pos); 229cb93a386Sopenharmony_ci } 230cb93a386Sopenharmony_ci break; 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci } 233cb93a386Sopenharmony_ci } 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci static DSLGlobalVar InterfaceBlock(const DSLModifiers& modifiers, skstd::string_view typeName, 236cb93a386Sopenharmony_ci SkTArray<DSLField> fields, skstd::string_view varName, 237cb93a386Sopenharmony_ci int arraySize, PositionInfo pos) { 238cb93a386Sopenharmony_ci // We need to create a new struct type for the interface block, but we don't want it in the 239cb93a386Sopenharmony_ci // symbol table. Since dsl::Struct automatically sticks it in the symbol table, we create it 240cb93a386Sopenharmony_ci // the old fashioned way with MakeStructType. 241cb93a386Sopenharmony_ci std::vector<SkSL::Type::Field> skslFields; 242cb93a386Sopenharmony_ci skslFields.reserve(fields.count()); 243cb93a386Sopenharmony_ci for (const DSLField& field : fields) { 244cb93a386Sopenharmony_ci const SkSL::Type* baseType = &field.fType.skslType(); 245cb93a386Sopenharmony_ci if (baseType->isArray()) { 246cb93a386Sopenharmony_ci baseType = &baseType->componentType(); 247cb93a386Sopenharmony_ci } 248cb93a386Sopenharmony_ci SkSL::VarDeclaration::ErrorCheck(ThreadContext::Context(), pos.line(), 249cb93a386Sopenharmony_ci field.fModifiers.fModifiers, baseType, Variable::Storage::kInterfaceBlock); 250cb93a386Sopenharmony_ci GetErrorReporter().reportPendingErrors(field.fPosition); 251cb93a386Sopenharmony_ci skslFields.push_back(SkSL::Type::Field(field.fModifiers.fModifiers, field.fName, 252cb93a386Sopenharmony_ci &field.fType.skslType())); 253cb93a386Sopenharmony_ci } 254cb93a386Sopenharmony_ci const SkSL::Type* structType = ThreadContext::SymbolTable()->takeOwnershipOfSymbol( 255cb93a386Sopenharmony_ci SkSL::Type::MakeStructType(pos.line(), typeName, std::move(skslFields))); 256cb93a386Sopenharmony_ci DSLType varType = arraySize > 0 ? Array(structType, arraySize) : DSLType(structType); 257cb93a386Sopenharmony_ci DSLGlobalVar var(modifiers, varType, !varName.empty() ? varName : typeName, DSLExpression(), 258cb93a386Sopenharmony_ci pos); 259cb93a386Sopenharmony_ci // Interface blocks can't be declared, so we always need to mark the var declared ourselves. 260cb93a386Sopenharmony_ci // We do this only when fDSLMarkVarDeclared is false, so we don't double-declare it. 261cb93a386Sopenharmony_ci if (!ThreadContext::Settings().fDSLMarkVarsDeclared) { 262cb93a386Sopenharmony_ci DSLWriter::MarkDeclared(var); 263cb93a386Sopenharmony_ci } 264cb93a386Sopenharmony_ci const SkSL::Variable* skslVar = DSLWriter::Var(var); 265cb93a386Sopenharmony_ci if (skslVar) { 266cb93a386Sopenharmony_ci auto intf = std::make_unique<SkSL::InterfaceBlock>(pos.line(), 267cb93a386Sopenharmony_ci *skslVar, typeName, varName, arraySize, ThreadContext::SymbolTable()); 268cb93a386Sopenharmony_ci FindRTAdjust(*intf, pos); 269cb93a386Sopenharmony_ci ThreadContext::ProgramElements().push_back(std::move(intf)); 270cb93a386Sopenharmony_ci if (varName.empty()) { 271cb93a386Sopenharmony_ci const std::vector<SkSL::Type::Field>& structFields = structType->fields(); 272cb93a386Sopenharmony_ci for (size_t i = 0; i < structFields.size(); ++i) { 273cb93a386Sopenharmony_ci ThreadContext::SymbolTable()->add(std::make_unique<SkSL::Field>(pos.line(), 274cb93a386Sopenharmony_ci skslVar, 275cb93a386Sopenharmony_ci i)); 276cb93a386Sopenharmony_ci } 277cb93a386Sopenharmony_ci } else { 278cb93a386Sopenharmony_ci AddToSymbolTable(var); 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci } 281cb93a386Sopenharmony_ci GetErrorReporter().reportPendingErrors(pos); 282cb93a386Sopenharmony_ci return var; 283cb93a386Sopenharmony_ci } 284cb93a386Sopenharmony_ci 285cb93a386Sopenharmony_ci static DSLStatement Return(DSLExpression value, PositionInfo pos) { 286cb93a386Sopenharmony_ci // Note that because Return is called before the function in which it resides exists, at 287cb93a386Sopenharmony_ci // this point we do not know the function's return type. We therefore do not check for 288cb93a386Sopenharmony_ci // errors, or coerce the value to the correct type, until the return statement is actually 289cb93a386Sopenharmony_ci // added to a function. (This is done in FunctionDefinition::Convert.) 290cb93a386Sopenharmony_ci return SkSL::ReturnStatement::Make(pos.line(), value.releaseIfPossible()); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci 293cb93a386Sopenharmony_ci static DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a, 294cb93a386Sopenharmony_ci PositionInfo pos) { 295cb93a386Sopenharmony_ci return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(), 296cb93a386Sopenharmony_ci ComponentArray{a}), 297cb93a386Sopenharmony_ci pos); 298cb93a386Sopenharmony_ci } 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci static DSLExpression Swizzle(DSLExpression base, 301cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 302cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 303cb93a386Sopenharmony_ci PositionInfo pos) { 304cb93a386Sopenharmony_ci return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(), 305cb93a386Sopenharmony_ci ComponentArray{a, b}), 306cb93a386Sopenharmony_ci pos); 307cb93a386Sopenharmony_ci } 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci static DSLExpression Swizzle(DSLExpression base, 310cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 311cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 312cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type c, 313cb93a386Sopenharmony_ci PositionInfo pos) { 314cb93a386Sopenharmony_ci return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(), 315cb93a386Sopenharmony_ci ComponentArray{a, b, c}), 316cb93a386Sopenharmony_ci pos); 317cb93a386Sopenharmony_ci } 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci static DSLExpression Swizzle(DSLExpression base, 320cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 321cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 322cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type c, 323cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type d, 324cb93a386Sopenharmony_ci PositionInfo pos) { 325cb93a386Sopenharmony_ci return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(), 326cb93a386Sopenharmony_ci ComponentArray{a,b,c,d}), 327cb93a386Sopenharmony_ci pos); 328cb93a386Sopenharmony_ci } 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ci static DSLPossibleExpression Select(DSLExpression test, DSLExpression ifTrue, 331cb93a386Sopenharmony_ci DSLExpression ifFalse) { 332cb93a386Sopenharmony_ci return TernaryExpression::Convert(ThreadContext::Context(), test.release(), 333cb93a386Sopenharmony_ci ifTrue.release(), ifFalse.release()); 334cb93a386Sopenharmony_ci } 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_ci static DSLPossibleStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, 337cb93a386Sopenharmony_ci bool isStatic) { 338cb93a386Sopenharmony_ci ExpressionArray values; 339cb93a386Sopenharmony_ci values.reserve_back(cases.count()); 340cb93a386Sopenharmony_ci StatementArray caseBlocks; 341cb93a386Sopenharmony_ci caseBlocks.reserve_back(cases.count()); 342cb93a386Sopenharmony_ci for (DSLCase& c : cases) { 343cb93a386Sopenharmony_ci values.push_back(c.fValue.releaseIfPossible()); 344cb93a386Sopenharmony_ci caseBlocks.push_back(SkSL::Block::Make(/*line=*/-1, 345cb93a386Sopenharmony_ci std::move(c.fStatements), /*symbols=*/nullptr, /*isScope=*/false)); 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci return SwitchStatement::Convert(ThreadContext::Context(), /*line=*/-1, isStatic, 348cb93a386Sopenharmony_ci value.release(), std::move(values), std::move(caseBlocks), 349cb93a386Sopenharmony_ci ThreadContext::SymbolTable()); 350cb93a386Sopenharmony_ci } 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci static DSLPossibleStatement While(DSLExpression test, DSLStatement stmt) { 353cb93a386Sopenharmony_ci return ForStatement::ConvertWhile(ThreadContext::Context(), /*line=*/-1, test.release(), 354cb93a386Sopenharmony_ci stmt.release(), ThreadContext::SymbolTable()); 355cb93a386Sopenharmony_ci } 356cb93a386Sopenharmony_ci}; 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_cistd::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<String> source) { 359cb93a386Sopenharmony_ci return DSLCore::ReleaseProgram(std::move(source)); 360cb93a386Sopenharmony_ci} 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ciDSLGlobalVar sk_FragColor() { 363cb93a386Sopenharmony_ci return DSLCore::sk_FragColor(); 364cb93a386Sopenharmony_ci} 365cb93a386Sopenharmony_ci 366cb93a386Sopenharmony_ciDSLGlobalVar sk_FragCoord() { 367cb93a386Sopenharmony_ci return DSLCore::sk_FragCoord(); 368cb93a386Sopenharmony_ci} 369cb93a386Sopenharmony_ci 370cb93a386Sopenharmony_ciDSLExpression sk_Position() { 371cb93a386Sopenharmony_ci return DSLCore::sk_Position(); 372cb93a386Sopenharmony_ci} 373cb93a386Sopenharmony_ci 374cb93a386Sopenharmony_civoid AddExtension(skstd::string_view name, PositionInfo pos) { 375cb93a386Sopenharmony_ci ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::Extension>(pos.line(), name)); 376cb93a386Sopenharmony_ci ThreadContext::ReportErrors(pos); 377cb93a386Sopenharmony_ci} 378cb93a386Sopenharmony_ci 379cb93a386Sopenharmony_ciDSLStatement Break(PositionInfo pos) { 380cb93a386Sopenharmony_ci return DSLCore::Break(pos); 381cb93a386Sopenharmony_ci} 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ciDSLStatement Continue(PositionInfo pos) { 384cb93a386Sopenharmony_ci return DSLCore::Continue(pos); 385cb93a386Sopenharmony_ci} 386cb93a386Sopenharmony_ci 387cb93a386Sopenharmony_civoid Declare(const DSLModifiers& modifiers, PositionInfo pos) { 388cb93a386Sopenharmony_ci SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind; 389cb93a386Sopenharmony_ci if (kind != ProgramKind::kFragment && 390cb93a386Sopenharmony_ci kind != ProgramKind::kVertex) { 391cb93a386Sopenharmony_ci ThreadContext::ReportError("layout qualifiers are not allowed in this kind of program", 392cb93a386Sopenharmony_ci pos); 393cb93a386Sopenharmony_ci return; 394cb93a386Sopenharmony_ci } 395cb93a386Sopenharmony_ci DSLCore::Declare(modifiers); 396cb93a386Sopenharmony_ci} 397cb93a386Sopenharmony_ci 398cb93a386Sopenharmony_ci// Logically, we'd want the variable's initial value to appear on here in Declare, since that 399cb93a386Sopenharmony_ci// matches how we actually write code (and in fact that was what our first attempt looked like). 400cb93a386Sopenharmony_ci// Unfortunately, C++ doesn't guarantee execution order between arguments, and Declare() can appear 401cb93a386Sopenharmony_ci// as a function argument in constructs like Block(Declare(x, 0), foo(x)). If these are executed out 402cb93a386Sopenharmony_ci// of order, we will evaluate the reference to x before we evaluate Declare(x, 0), and thus the 403cb93a386Sopenharmony_ci// variable's initial value is unknown at the point of reference. There are probably some other 404cb93a386Sopenharmony_ci// issues with this as well, but it is particularly dangerous when x is const, since SkSL will 405cb93a386Sopenharmony_ci// expect its value to be known when it is referenced and will end up asserting, dereferencing a 406cb93a386Sopenharmony_ci// null pointer, or possibly doing something else awful. 407cb93a386Sopenharmony_ci// 408cb93a386Sopenharmony_ci// So, we put the initial value onto the Var itself instead of the Declare to guarantee that it is 409cb93a386Sopenharmony_ci// always executed in the correct order. 410cb93a386Sopenharmony_ciDSLStatement Declare(DSLVar& var, PositionInfo pos) { 411cb93a386Sopenharmony_ci return DSLCore::Declare(var, pos); 412cb93a386Sopenharmony_ci} 413cb93a386Sopenharmony_ci 414cb93a386Sopenharmony_ciDSLStatement Declare(SkTArray<DSLVar>& vars, PositionInfo pos) { 415cb93a386Sopenharmony_ci return DSLCore::Declare(vars, pos); 416cb93a386Sopenharmony_ci} 417cb93a386Sopenharmony_ci 418cb93a386Sopenharmony_civoid Declare(DSLGlobalVar& var, PositionInfo pos) { 419cb93a386Sopenharmony_ci DSLCore::Declare(var, pos); 420cb93a386Sopenharmony_ci} 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_civoid Declare(SkTArray<DSLGlobalVar>& vars, PositionInfo pos) { 423cb93a386Sopenharmony_ci DSLCore::Declare(vars, pos); 424cb93a386Sopenharmony_ci} 425cb93a386Sopenharmony_ci 426cb93a386Sopenharmony_ciDSLStatement Discard(PositionInfo pos) { 427cb93a386Sopenharmony_ci if (ThreadContext::GetProgramConfig()->fKind != ProgramKind::kFragment) { 428cb93a386Sopenharmony_ci ThreadContext::ReportError("discard statement is only permitted in fragment shaders", pos); 429cb93a386Sopenharmony_ci } 430cb93a386Sopenharmony_ci return DSLCore::Discard(pos); 431cb93a386Sopenharmony_ci} 432cb93a386Sopenharmony_ci 433cb93a386Sopenharmony_ciDSLStatement Do(DSLStatement stmt, DSLExpression test, PositionInfo pos) { 434cb93a386Sopenharmony_ci return DSLStatement(DSLCore::Do(std::move(stmt), std::move(test)), pos); 435cb93a386Sopenharmony_ci} 436cb93a386Sopenharmony_ci 437cb93a386Sopenharmony_ciDSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next, 438cb93a386Sopenharmony_ci DSLStatement stmt, PositionInfo pos) { 439cb93a386Sopenharmony_ci return DSLStatement(DSLCore::For(std::move(initializer), std::move(test), std::move(next), 440cb93a386Sopenharmony_ci std::move(stmt), pos), pos); 441cb93a386Sopenharmony_ci} 442cb93a386Sopenharmony_ci 443cb93a386Sopenharmony_ciDSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, PositionInfo pos) { 444cb93a386Sopenharmony_ci return DSLStatement(DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse), 445cb93a386Sopenharmony_ci /*isStatic=*/false), 446cb93a386Sopenharmony_ci pos); 447cb93a386Sopenharmony_ci} 448cb93a386Sopenharmony_ci 449cb93a386Sopenharmony_ciDSLGlobalVar InterfaceBlock(const DSLModifiers& modifiers, skstd::string_view typeName, 450cb93a386Sopenharmony_ci SkTArray<DSLField> fields, skstd::string_view varName, int arraySize, 451cb93a386Sopenharmony_ci PositionInfo pos) { 452cb93a386Sopenharmony_ci SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind; 453cb93a386Sopenharmony_ci if (kind != ProgramKind::kFragment && 454cb93a386Sopenharmony_ci kind != ProgramKind::kVertex) { 455cb93a386Sopenharmony_ci ThreadContext::ReportError("interface blocks are not allowed in this kind of program", pos); 456cb93a386Sopenharmony_ci return DSLGlobalVar(); 457cb93a386Sopenharmony_ci } 458cb93a386Sopenharmony_ci return DSLCore::InterfaceBlock(modifiers, typeName, std::move(fields), varName, arraySize, pos); 459cb93a386Sopenharmony_ci} 460cb93a386Sopenharmony_ci 461cb93a386Sopenharmony_ciDSLStatement Return(DSLExpression expr, PositionInfo pos) { 462cb93a386Sopenharmony_ci return DSLCore::Return(std::move(expr), pos); 463cb93a386Sopenharmony_ci} 464cb93a386Sopenharmony_ci 465cb93a386Sopenharmony_ciDSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse, 466cb93a386Sopenharmony_ci PositionInfo pos) { 467cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Select(std::move(test), std::move(ifTrue), std::move(ifFalse)), 468cb93a386Sopenharmony_ci pos); 469cb93a386Sopenharmony_ci} 470cb93a386Sopenharmony_ci 471cb93a386Sopenharmony_ciDSLStatement StaticIf(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, 472cb93a386Sopenharmony_ci PositionInfo pos) { 473cb93a386Sopenharmony_ci return DSLStatement(DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse), 474cb93a386Sopenharmony_ci /*isStatic=*/true), 475cb93a386Sopenharmony_ci pos); 476cb93a386Sopenharmony_ci} 477cb93a386Sopenharmony_ci 478cb93a386Sopenharmony_ciDSLPossibleStatement PossibleStaticSwitch(DSLExpression value, SkTArray<DSLCase> cases) { 479cb93a386Sopenharmony_ci return DSLCore::Switch(std::move(value), std::move(cases), /*isStatic=*/true); 480cb93a386Sopenharmony_ci} 481cb93a386Sopenharmony_ci 482cb93a386Sopenharmony_ciDSLStatement StaticSwitch(DSLExpression value, SkTArray<DSLCase> cases, PositionInfo pos) { 483cb93a386Sopenharmony_ci return DSLStatement(PossibleStaticSwitch(std::move(value), std::move(cases)), pos); 484cb93a386Sopenharmony_ci} 485cb93a386Sopenharmony_ci 486cb93a386Sopenharmony_ciDSLPossibleStatement PossibleSwitch(DSLExpression value, SkTArray<DSLCase> cases) { 487cb93a386Sopenharmony_ci return DSLCore::Switch(std::move(value), std::move(cases), /*isStatic=*/false); 488cb93a386Sopenharmony_ci} 489cb93a386Sopenharmony_ci 490cb93a386Sopenharmony_ciDSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, PositionInfo pos) { 491cb93a386Sopenharmony_ci return DSLStatement(PossibleSwitch(std::move(value), std::move(cases)), pos); 492cb93a386Sopenharmony_ci} 493cb93a386Sopenharmony_ci 494cb93a386Sopenharmony_ciDSLStatement While(DSLExpression test, DSLStatement stmt, PositionInfo pos) { 495cb93a386Sopenharmony_ci return DSLStatement(DSLCore::While(std::move(test), std::move(stmt)), pos); 496cb93a386Sopenharmony_ci} 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ciDSLExpression Abs(DSLExpression x, PositionInfo pos) { 499cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("abs", std::move(x)), pos); 500cb93a386Sopenharmony_ci} 501cb93a386Sopenharmony_ci 502cb93a386Sopenharmony_ciDSLExpression All(DSLExpression x, PositionInfo pos) { 503cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("all", std::move(x)), pos); 504cb93a386Sopenharmony_ci} 505cb93a386Sopenharmony_ci 506cb93a386Sopenharmony_ciDSLExpression Any(DSLExpression x, PositionInfo pos) { 507cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("any", std::move(x)), pos); 508cb93a386Sopenharmony_ci} 509cb93a386Sopenharmony_ci 510cb93a386Sopenharmony_ciDSLExpression Atan(DSLExpression y_over_x, PositionInfo pos) { 511cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("atan", std::move(y_over_x)), pos); 512cb93a386Sopenharmony_ci} 513cb93a386Sopenharmony_ci 514cb93a386Sopenharmony_ciDSLExpression Atan(DSLExpression y, DSLExpression x, PositionInfo pos) { 515cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("atan", std::move(y), std::move(x)), pos); 516cb93a386Sopenharmony_ci} 517cb93a386Sopenharmony_ci 518cb93a386Sopenharmony_ciDSLExpression Ceil(DSLExpression x, PositionInfo pos) { 519cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("ceil", std::move(x)), pos); 520cb93a386Sopenharmony_ci} 521cb93a386Sopenharmony_ci 522cb93a386Sopenharmony_ciDSLExpression Clamp(DSLExpression x, DSLExpression min, DSLExpression max, PositionInfo pos) { 523cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("clamp", std::move(x), std::move(min), std::move(max)), pos); 524cb93a386Sopenharmony_ci} 525cb93a386Sopenharmony_ci 526cb93a386Sopenharmony_ciDSLExpression Cos(DSLExpression x, PositionInfo pos) { 527cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("cos", std::move(x)), pos); 528cb93a386Sopenharmony_ci} 529cb93a386Sopenharmony_ci 530cb93a386Sopenharmony_ciDSLExpression Cross(DSLExpression x, DSLExpression y, PositionInfo pos) { 531cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("cross", std::move(x), std::move(y)), pos); 532cb93a386Sopenharmony_ci} 533cb93a386Sopenharmony_ci 534cb93a386Sopenharmony_ciDSLExpression Degrees(DSLExpression x, PositionInfo pos) { 535cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("degrees", std::move(x)), pos); 536cb93a386Sopenharmony_ci} 537cb93a386Sopenharmony_ci 538cb93a386Sopenharmony_ciDSLExpression Distance(DSLExpression x, DSLExpression y, PositionInfo pos) { 539cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("distance", std::move(x), std::move(y)), pos); 540cb93a386Sopenharmony_ci} 541cb93a386Sopenharmony_ci 542cb93a386Sopenharmony_ciDSLExpression Dot(DSLExpression x, DSLExpression y, PositionInfo pos) { 543cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("dot", std::move(x), std::move(y)), pos); 544cb93a386Sopenharmony_ci} 545cb93a386Sopenharmony_ci 546cb93a386Sopenharmony_ciDSLExpression Equal(DSLExpression x, DSLExpression y, PositionInfo pos) { 547cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("equal", std::move(x), std::move(y)), pos); 548cb93a386Sopenharmony_ci} 549cb93a386Sopenharmony_ci 550cb93a386Sopenharmony_ciDSLExpression Exp(DSLExpression x, PositionInfo pos) { 551cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("exp", std::move(x)), pos); 552cb93a386Sopenharmony_ci} 553cb93a386Sopenharmony_ci 554cb93a386Sopenharmony_ciDSLExpression Exp2(DSLExpression x, PositionInfo pos) { 555cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("exp2", std::move(x)), pos); 556cb93a386Sopenharmony_ci} 557cb93a386Sopenharmony_ci 558cb93a386Sopenharmony_ciDSLExpression Faceforward(DSLExpression n, DSLExpression i, DSLExpression nref, PositionInfo pos) { 559cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("faceforward", std::move(n), std::move(i), std::move(nref)), 560cb93a386Sopenharmony_ci pos); 561cb93a386Sopenharmony_ci} 562cb93a386Sopenharmony_ci 563cb93a386Sopenharmony_ciDSLExpression Fract(DSLExpression x, PositionInfo pos) { 564cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("fract", std::move(x)), pos); 565cb93a386Sopenharmony_ci} 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_ciDSLExpression Floor(DSLExpression x, PositionInfo pos) { 568cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("floor", std::move(x)), pos); 569cb93a386Sopenharmony_ci} 570cb93a386Sopenharmony_ci 571cb93a386Sopenharmony_ciDSLExpression GreaterThan(DSLExpression x, DSLExpression y, PositionInfo pos) { 572cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("greaterThan", std::move(x), std::move(y)), pos); 573cb93a386Sopenharmony_ci} 574cb93a386Sopenharmony_ci 575cb93a386Sopenharmony_ciDSLExpression GreaterThanEqual(DSLExpression x, DSLExpression y, PositionInfo pos) { 576cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("greaterThanEqual", std::move(x), std::move(y)), pos); 577cb93a386Sopenharmony_ci} 578cb93a386Sopenharmony_ci 579cb93a386Sopenharmony_ciDSLExpression Inverse(DSLExpression x, PositionInfo pos) { 580cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("inverse", std::move(x)), pos); 581cb93a386Sopenharmony_ci} 582cb93a386Sopenharmony_ci 583cb93a386Sopenharmony_ciDSLExpression Inversesqrt(DSLExpression x, PositionInfo pos) { 584cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("inversesqrt", std::move(x)), pos); 585cb93a386Sopenharmony_ci} 586cb93a386Sopenharmony_ci 587cb93a386Sopenharmony_ciDSLExpression Length(DSLExpression x, PositionInfo pos) { 588cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("length", std::move(x)), pos); 589cb93a386Sopenharmony_ci} 590cb93a386Sopenharmony_ci 591cb93a386Sopenharmony_ciDSLExpression LessThan(DSLExpression x, DSLExpression y, PositionInfo pos) { 592cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("lessThan", std::move(x), std::move(y)), pos); 593cb93a386Sopenharmony_ci} 594cb93a386Sopenharmony_ci 595cb93a386Sopenharmony_ciDSLExpression LessThanEqual(DSLExpression x, DSLExpression y, PositionInfo pos) { 596cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("lessThanEqual", std::move(x), std::move(y)), pos); 597cb93a386Sopenharmony_ci} 598cb93a386Sopenharmony_ci 599cb93a386Sopenharmony_ciDSLExpression Log(DSLExpression x, PositionInfo pos) { 600cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("log", std::move(x)), pos); 601cb93a386Sopenharmony_ci} 602cb93a386Sopenharmony_ci 603cb93a386Sopenharmony_ciDSLExpression Log2(DSLExpression x, PositionInfo pos) { 604cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("log2", std::move(x)), pos); 605cb93a386Sopenharmony_ci} 606cb93a386Sopenharmony_ci 607cb93a386Sopenharmony_ciDSLExpression Max(DSLExpression x, DSLExpression y, PositionInfo pos) { 608cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("max", std::move(x), std::move(y)), pos); 609cb93a386Sopenharmony_ci} 610cb93a386Sopenharmony_ci 611cb93a386Sopenharmony_ciDSLExpression Min(DSLExpression x, DSLExpression y, PositionInfo pos) { 612cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("min", std::move(x), std::move(y)), pos); 613cb93a386Sopenharmony_ci} 614cb93a386Sopenharmony_ci 615cb93a386Sopenharmony_ciDSLExpression Mix(DSLExpression x, DSLExpression y, DSLExpression a, PositionInfo pos) { 616cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("mix", std::move(x), std::move(y), std::move(a)), pos); 617cb93a386Sopenharmony_ci} 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ciDSLExpression Mod(DSLExpression x, DSLExpression y, PositionInfo pos) { 620cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("mod", std::move(x), std::move(y)), pos); 621cb93a386Sopenharmony_ci} 622cb93a386Sopenharmony_ci 623cb93a386Sopenharmony_ciDSLExpression Normalize(DSLExpression x, PositionInfo pos) { 624cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("normalize", std::move(x)), pos); 625cb93a386Sopenharmony_ci} 626cb93a386Sopenharmony_ci 627cb93a386Sopenharmony_ciDSLExpression NotEqual(DSLExpression x, DSLExpression y, PositionInfo pos) { 628cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("notEqual", std::move(x), std::move(y)), pos); 629cb93a386Sopenharmony_ci} 630cb93a386Sopenharmony_ci 631cb93a386Sopenharmony_ciDSLExpression Pow(DSLExpression x, DSLExpression y, PositionInfo pos) { 632cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("pow", std::move(x), std::move(y)), pos); 633cb93a386Sopenharmony_ci} 634cb93a386Sopenharmony_ci 635cb93a386Sopenharmony_ciDSLExpression Radians(DSLExpression x, PositionInfo pos) { 636cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("radians", std::move(x)), pos); 637cb93a386Sopenharmony_ci} 638cb93a386Sopenharmony_ci 639cb93a386Sopenharmony_ciDSLExpression Reflect(DSLExpression i, DSLExpression n, PositionInfo pos) { 640cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("reflect", std::move(i), std::move(n)), pos); 641cb93a386Sopenharmony_ci} 642cb93a386Sopenharmony_ci 643cb93a386Sopenharmony_ciDSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta, PositionInfo pos) { 644cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("refract", std::move(i), std::move(n), std::move(eta)), pos); 645cb93a386Sopenharmony_ci} 646cb93a386Sopenharmony_ci 647cb93a386Sopenharmony_ciDSLExpression Round(DSLExpression x, PositionInfo pos) { 648cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("round", std::move(x)), pos); 649cb93a386Sopenharmony_ci} 650cb93a386Sopenharmony_ci 651cb93a386Sopenharmony_ciDSLExpression Saturate(DSLExpression x, PositionInfo pos) { 652cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("saturate", std::move(x)), pos); 653cb93a386Sopenharmony_ci} 654cb93a386Sopenharmony_ci 655cb93a386Sopenharmony_ciDSLExpression Sign(DSLExpression x, PositionInfo pos) { 656cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("sign", std::move(x)), pos); 657cb93a386Sopenharmony_ci} 658cb93a386Sopenharmony_ci 659cb93a386Sopenharmony_ciDSLExpression Sin(DSLExpression x, PositionInfo pos) { 660cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("sin", std::move(x)), pos); 661cb93a386Sopenharmony_ci} 662cb93a386Sopenharmony_ci 663cb93a386Sopenharmony_ciDSLExpression Smoothstep(DSLExpression edge1, DSLExpression edge2, DSLExpression x, 664cb93a386Sopenharmony_ci PositionInfo pos) { 665cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("smoothstep", std::move(edge1), std::move(edge2), 666cb93a386Sopenharmony_ci std::move(x)), 667cb93a386Sopenharmony_ci pos); 668cb93a386Sopenharmony_ci} 669cb93a386Sopenharmony_ci 670cb93a386Sopenharmony_ciDSLExpression Sqrt(DSLExpression x, PositionInfo pos) { 671cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("sqrt", std::move(x)), pos); 672cb93a386Sopenharmony_ci} 673cb93a386Sopenharmony_ci 674cb93a386Sopenharmony_ciDSLExpression Step(DSLExpression edge, DSLExpression x, PositionInfo pos) { 675cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("step", std::move(edge), std::move(x)), pos); 676cb93a386Sopenharmony_ci} 677cb93a386Sopenharmony_ci 678cb93a386Sopenharmony_ciDSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a, 679cb93a386Sopenharmony_ci PositionInfo pos) { 680cb93a386Sopenharmony_ci return DSLCore::Swizzle(std::move(base), a, pos); 681cb93a386Sopenharmony_ci} 682cb93a386Sopenharmony_ci 683cb93a386Sopenharmony_ciDSLExpression Swizzle(DSLExpression base, 684cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 685cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 686cb93a386Sopenharmony_ci PositionInfo pos) { 687cb93a386Sopenharmony_ci return DSLCore::Swizzle(std::move(base), a, b, pos); 688cb93a386Sopenharmony_ci} 689cb93a386Sopenharmony_ci 690cb93a386Sopenharmony_ciDSLExpression Swizzle(DSLExpression base, 691cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 692cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 693cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type c, 694cb93a386Sopenharmony_ci PositionInfo pos) { 695cb93a386Sopenharmony_ci return DSLCore::Swizzle(std::move(base), a, b, c, pos); 696cb93a386Sopenharmony_ci} 697cb93a386Sopenharmony_ci 698cb93a386Sopenharmony_ciDSLExpression Swizzle(DSLExpression base, 699cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type a, 700cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type b, 701cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type c, 702cb93a386Sopenharmony_ci SkSL::SwizzleComponent::Type d, 703cb93a386Sopenharmony_ci PositionInfo pos) { 704cb93a386Sopenharmony_ci return DSLCore::Swizzle(std::move(base), a, b, c, d, pos); 705cb93a386Sopenharmony_ci} 706cb93a386Sopenharmony_ci 707cb93a386Sopenharmony_ciDSLExpression Tan(DSLExpression x, PositionInfo pos) { 708cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("tan", std::move(x)), pos); 709cb93a386Sopenharmony_ci} 710cb93a386Sopenharmony_ci 711cb93a386Sopenharmony_ciDSLExpression Unpremul(DSLExpression x, PositionInfo pos) { 712cb93a386Sopenharmony_ci return DSLExpression(DSLCore::Call("unpremul", std::move(x)), pos); 713cb93a386Sopenharmony_ci} 714cb93a386Sopenharmony_ci 715cb93a386Sopenharmony_ci} // namespace dsl 716cb93a386Sopenharmony_ci 717cb93a386Sopenharmony_ci} // namespace SkSL 718