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