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