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/ir/SkSLExpression.h" 13 14 namespace SkSL { 15 16 /** 17 * Base class representing a constructor with unknown arguments. 18 */ 19 class AnyConstructor : public Expression { 20 public: AnyConstructor(int line,Kind kind,const Type * type)21 AnyConstructor(int line, Kind kind, const Type* type) 22 : INHERITED(line, kind, type) {} 23 24 virtual SkSpan<std::unique_ptr<Expression>> argumentSpan() = 0; 25 virtual SkSpan<const std::unique_ptr<Expression>> argumentSpan() const = 0; 26 hasProperty(Property property)27 bool hasProperty(Property property) const override { 28 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 29 if (arg->hasProperty(property)) { 30 return true; 31 } 32 } 33 return false; 34 } 35 description()36 String description() const override { 37 String result = this->type().description() + "("; 38 const char* separator = ""; 39 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 40 result += separator; 41 result += arg->description(); 42 separator = ", "; 43 } 44 result += ")"; 45 return result; 46 } 47 componentType()48 const Type& componentType() const { 49 return this->type().componentType(); 50 } 51 isCompileTimeConstant()52 bool isCompileTimeConstant() const override { 53 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 54 if (!arg->isCompileTimeConstant()) { 55 return false; 56 } 57 } 58 return true; 59 } 60 isConstantOrUniform()61 bool isConstantOrUniform() const override { 62 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 63 if (!arg->isConstantOrUniform()) { 64 return false; 65 } 66 } 67 return true; 68 } 69 supportsConstantValues()70 bool supportsConstantValues() const override { return true; } 71 skstd::optional<double> getConstantValue(int n) const override; 72 73 ComparisonResult compareConstant(const Expression& other) const override; 74 75 private: 76 std::unique_ptr<Expression> fArgument; 77 78 using INHERITED = Expression; 79 }; 80 81 /** 82 * Base class representing a constructor that takes a single argument. 83 */ 84 class SingleArgumentConstructor : public AnyConstructor { 85 public: SingleArgumentConstructor(int line,Kind kind,const Type * type,std::unique_ptr<Expression> argument)86 SingleArgumentConstructor(int line, Kind kind, const Type* type, 87 std::unique_ptr<Expression> argument) 88 : INHERITED(line, kind, type) 89 , fArgument(std::move(argument)) {} 90 argument()91 std::unique_ptr<Expression>& argument() { 92 return fArgument; 93 } 94 argument()95 const std::unique_ptr<Expression>& argument() const { 96 return fArgument; 97 } 98 argumentSpan()99 SkSpan<std::unique_ptr<Expression>> argumentSpan() final { 100 return {&fArgument, 1}; 101 } 102 argumentSpan()103 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final { 104 return {&fArgument, 1}; 105 } 106 107 private: 108 std::unique_ptr<Expression> fArgument; 109 110 using INHERITED = AnyConstructor; 111 }; 112 113 /** 114 * Base class representing a constructor that takes an array of arguments. 115 */ 116 class MultiArgumentConstructor : public AnyConstructor { 117 public: MultiArgumentConstructor(int line,Kind kind,const Type * type,ExpressionArray arguments)118 MultiArgumentConstructor(int line, Kind kind, const Type* type, ExpressionArray arguments) 119 : INHERITED(line, kind, type) 120 , fArguments(std::move(arguments)) {} 121 arguments()122 ExpressionArray& arguments() { 123 return fArguments; 124 } 125 arguments()126 const ExpressionArray& arguments() const { 127 return fArguments; 128 } 129 cloneArguments()130 ExpressionArray cloneArguments() const { 131 ExpressionArray clonedArgs; 132 clonedArgs.reserve_back(this->arguments().size()); 133 for (const std::unique_ptr<Expression>& arg: this->arguments()) { 134 clonedArgs.push_back(arg->clone()); 135 } 136 return clonedArgs; 137 } 138 argumentSpan()139 SkSpan<std::unique_ptr<Expression>> argumentSpan() final { 140 return {&fArguments.front(), fArguments.size()}; 141 } 142 argumentSpan()143 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final { 144 return {&fArguments.front(), fArguments.size()}; 145 } 146 147 private: 148 ExpressionArray fArguments; 149 150 using INHERITED = AnyConstructor; 151 }; 152 153 /** 154 * Converts any GLSL constructor, such as `float2(x, y)` or `mat3x3(otherMat)` or `int[2](0, i)`, to 155 * an SkSL expression. 156 * 157 * Vector constructors must always consist of either exactly 1 scalar, or a collection of vectors 158 * and scalars totaling exactly the right number of scalar components. 159 * 160 * Matrix constructors must always consist of either exactly 1 scalar, exactly 1 matrix, or a 161 * collection of vectors and scalars totaling exactly the right number of scalar components. 162 * 163 * Array constructors must always contain the proper number of array elements (matching the Type). 164 */ 165 namespace Constructor { 166 // Creates, typechecks and simplifies constructor expressions. Reports errors via the 167 // ErrorReporter. This can return null on error, so be careful. There are several different 168 // Constructor expression types; this class chooses the proper one based on context, e.g. 169 // `ConstructorCompound`, `ConstructorScalarCast`, or `ConstructorMatrixResize`. 170 std::unique_ptr<Expression> Convert(const Context& context, 171 int line, 172 const Type& type, 173 ExpressionArray args); 174 }; 175 176 } // namespace SkSL 177 178 #endif 179