1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2023 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_IRHELPERS 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_IRHELPERS 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLAnalysis.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLBuiltinTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLContext.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLDefines.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLOperator.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLPosition.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLUtil.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLBinaryExpression.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLConstructorCompound.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLExpression.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLExpressionStatement.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLFieldAccess.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLFieldSymbol.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLIndexExpression.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLLiteral.h" 27*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLSwizzle.h" 28*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLSymbolTable.h" 29*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLVariableReference.h" 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 32*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker class Statement; 37*c8dee2aaSAndroid Build Coastguard Worker class Variable; 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker struct IRHelpers { IRHelpersIRHelpers40*c8dee2aaSAndroid Build Coastguard Worker IRHelpers(const Context& c) : fContext(c) {} 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker // Note that this class doesn't adhere to the typical Skia style rules; function names are 43*c8dee2aaSAndroid Build Coastguard Worker // capitalized, and we don't use `this->` prefixes. This helps nested expressions flow more 44*c8dee2aaSAndroid Build Coastguard Worker // naturally. 45*c8dee2aaSAndroid Build Coastguard Worker RefIRHelpers46*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Ref(const Variable* var) const { 47*c8dee2aaSAndroid Build Coastguard Worker return VariableReference::Make(Position(), var); 48*c8dee2aaSAndroid Build Coastguard Worker } 49*c8dee2aaSAndroid Build Coastguard Worker FieldIRHelpers50*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Field(const Variable* var, int idx) const { 51*c8dee2aaSAndroid Build Coastguard Worker return FieldAccess::Make(fContext, Position(), Ref(var), idx, 52*c8dee2aaSAndroid Build Coastguard Worker FieldAccess::OwnerKind::kAnonymousInterfaceBlock); 53*c8dee2aaSAndroid Build Coastguard Worker } 54*c8dee2aaSAndroid Build Coastguard Worker SwizzleIRHelpers55*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Swizzle(std::unique_ptr<Expression> base, ComponentArray c) const { 56*c8dee2aaSAndroid Build Coastguard Worker Position pos = base->fPosition; 57*c8dee2aaSAndroid Build Coastguard Worker return Swizzle::Make(fContext, pos, std::move(base), std::move(c)); 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker IndexIRHelpers60*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Index(std::unique_ptr<Expression> base, 61*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> idx) const { 62*c8dee2aaSAndroid Build Coastguard Worker Position pos = base->fPosition.rangeThrough(idx->fPosition); 63*c8dee2aaSAndroid Build Coastguard Worker return IndexExpression::Make(fContext, pos, std::move(base), std::move(idx)); 64*c8dee2aaSAndroid Build Coastguard Worker } 65*c8dee2aaSAndroid Build Coastguard Worker BinaryIRHelpers66*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Binary(std::unique_ptr<Expression> l, 67*c8dee2aaSAndroid Build Coastguard Worker Operator op, 68*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> r) const { 69*c8dee2aaSAndroid Build Coastguard Worker Position pos = l->fPosition.rangeThrough(r->fPosition); 70*c8dee2aaSAndroid Build Coastguard Worker return BinaryExpression::Make(fContext, pos, std::move(l), op, std::move(r)); 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker MulIRHelpers73*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Mul(std::unique_ptr<Expression> l, 74*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> r) const { 75*c8dee2aaSAndroid Build Coastguard Worker return Binary(std::move(l), OperatorKind::STAR, std::move(r)); 76*c8dee2aaSAndroid Build Coastguard Worker } 77*c8dee2aaSAndroid Build Coastguard Worker AddIRHelpers78*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Add(std::unique_ptr<Expression> l, 79*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> r) const { 80*c8dee2aaSAndroid Build Coastguard Worker return Binary(std::move(l), OperatorKind::PLUS, std::move(r)); 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker FloatIRHelpers83*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Float(float value) const { 84*c8dee2aaSAndroid Build Coastguard Worker return Literal::MakeFloat(Position(), value, fContext.fTypes.fFloat.get()); 85*c8dee2aaSAndroid Build Coastguard Worker } 86*c8dee2aaSAndroid Build Coastguard Worker IntIRHelpers87*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> Int(int value) const { 88*c8dee2aaSAndroid Build Coastguard Worker return Literal::MakeInt(Position(), value, fContext.fTypes.fInt.get()); 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker CtorXYZWIRHelpers91*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> CtorXYZW(std::unique_ptr<Expression> xy, 92*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> z, 93*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> w) const { 94*c8dee2aaSAndroid Build Coastguard Worker ExpressionArray args; 95*c8dee2aaSAndroid Build Coastguard Worker args.push_back(std::move(xy)); 96*c8dee2aaSAndroid Build Coastguard Worker args.push_back(std::move(z)); 97*c8dee2aaSAndroid Build Coastguard Worker args.push_back(std::move(w)); 98*c8dee2aaSAndroid Build Coastguard Worker return ConstructorCompound::Make(fContext, Position(), *fContext.fTypes.fFloat4, 99*c8dee2aaSAndroid Build Coastguard Worker std::move(args)); 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker AssignIRHelpers102*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Statement> Assign(std::unique_ptr<Expression> l, 103*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> r) const { 104*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(Analysis::UpdateVariableRefKind(l.get(), VariableRefKind::kWrite)); 105*c8dee2aaSAndroid Build Coastguard Worker return ExpressionStatement::Make(fContext, 106*c8dee2aaSAndroid Build Coastguard Worker Binary(std::move(l), OperatorKind::EQ, std::move(r))); 107*c8dee2aaSAndroid Build Coastguard Worker } 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker const Context& fContext; 110*c8dee2aaSAndroid Build Coastguard Worker }; 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker #endif 115