1 /* 2 * Copyright 2016 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_CONSTRUCTOR 9 #define SKSL_CONSTRUCTOR 10 11 #include "include/core/SkSpan.h" 12 #include "src/sksl/SkSLDefines.h" 13 #include "src/sksl/SkSLPosition.h" 14 #include "src/sksl/ir/SkSLExpression.h" 15 #include "src/sksl/ir/SkSLType.h" 16 17 #include <cstdint> 18 #include <memory> 19 #include <optional> 20 #include <string> 21 #include <utility> 22 23 namespace SkSL { 24 25 class Context; 26 enum class OperatorPrecedence : uint8_t; 27 28 /** 29 * Base class representing a constructor with unknown arguments. 30 */ 31 class AnyConstructor : public Expression { 32 public: AnyConstructor(Position pos,Kind kind,const Type * type)33 AnyConstructor(Position pos, Kind kind, const Type* type) 34 : INHERITED(pos, kind, type) {} 35 36 virtual SkSpan<std::unique_ptr<Expression>> argumentSpan() = 0; 37 virtual SkSpan<const std::unique_ptr<Expression>> argumentSpan() const = 0; 38 description(OperatorPrecedence)39 std::string description(OperatorPrecedence) const override; 40 41 const Type& componentType() const { 42 return this->type().componentType(); 43 } 44 supportsConstantValues()45 bool supportsConstantValues() const override { return true; } 46 std::optional<double> getConstantValue(int n) const override; 47 48 ComparisonResult compareConstant(const Expression& other) const override; 49 50 private: 51 using INHERITED = Expression; 52 }; 53 54 /** 55 * Base class representing a constructor that takes a single argument. 56 */ 57 class SingleArgumentConstructor : public AnyConstructor { 58 public: SingleArgumentConstructor(Position pos,Kind kind,const Type * type,std::unique_ptr<Expression> argument)59 SingleArgumentConstructor(Position pos, Kind kind, const Type* type, 60 std::unique_ptr<Expression> argument) 61 : INHERITED(pos, kind, type) 62 , fArgument(std::move(argument)) {} 63 argument()64 std::unique_ptr<Expression>& argument() { 65 return fArgument; 66 } 67 argument()68 const std::unique_ptr<Expression>& argument() const { 69 return fArgument; 70 } 71 argumentSpan()72 SkSpan<std::unique_ptr<Expression>> argumentSpan() final { 73 return {&fArgument, 1}; 74 } 75 argumentSpan()76 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final { 77 return {&fArgument, 1}; 78 } 79 80 private: 81 std::unique_ptr<Expression> fArgument; 82 83 using INHERITED = AnyConstructor; 84 }; 85 86 /** 87 * Base class representing a constructor that takes an array of arguments. 88 */ 89 class MultiArgumentConstructor : public AnyConstructor { 90 public: MultiArgumentConstructor(Position pos,Kind kind,const Type * type,ExpressionArray arguments)91 MultiArgumentConstructor(Position pos, Kind kind, const Type* type, 92 ExpressionArray arguments) 93 : INHERITED(pos, kind, type) 94 , fArguments(std::move(arguments)) {} 95 arguments()96 ExpressionArray& arguments() { 97 return fArguments; 98 } 99 arguments()100 const ExpressionArray& arguments() const { 101 return fArguments; 102 } 103 argumentSpan()104 SkSpan<std::unique_ptr<Expression>> argumentSpan() final { 105 return {&fArguments.front(), fArguments.size()}; 106 } 107 argumentSpan()108 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final { 109 return {&fArguments.front(), fArguments.size()}; 110 } 111 112 private: 113 ExpressionArray fArguments; 114 115 using INHERITED = AnyConstructor; 116 }; 117 118 /** 119 * Converts any GLSL constructor, such as `float2(x, y)` or `mat3x3(otherMat)` or `int[2](0, i)`, to 120 * an SkSL expression. 121 * 122 * Vector constructors must always consist of either exactly 1 scalar, or a collection of vectors 123 * and scalars totaling exactly the right number of scalar components. 124 * 125 * Matrix constructors must always consist of either exactly 1 scalar, exactly 1 matrix, or a 126 * collection of vectors and scalars totaling exactly the right number of scalar components. 127 * 128 * Array constructors must always contain the proper number of array elements (matching the Type). 129 */ 130 namespace Constructor { 131 // Creates, typechecks and simplifies constructor expressions. Reports errors via the 132 // ErrorReporter. This can return null on error, so be careful. There are several different 133 // Constructor expression types; this class chooses the proper one based on context, e.g. 134 // `ConstructorCompound`, `ConstructorScalarCast`, or `ConstructorMatrixResize`. 135 std::unique_ptr<Expression> Convert(const Context& context, 136 Position pos, 137 const Type& type, 138 ExpressionArray args); 139 } 140 141 } // namespace SkSL 142 143 #endif 144