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/SkSLIRGenerator.h" 13 #include "src/sksl/ir/SkSLExpression.h" 14 15 namespace SkSL { 16 17 /** 18 * Base class representing a constructor with unknown arguments. 19 */ 20 class AnyConstructor : public Expression { 21 public: AnyConstructor(int offset,Kind kind,const Type * type)22 AnyConstructor(int offset, Kind kind, const Type* type) 23 : INHERITED(offset, kind, type) {} 24 25 virtual SkSpan<std::unique_ptr<Expression>> argumentSpan() = 0; 26 virtual SkSpan<const std::unique_ptr<Expression>> argumentSpan() const = 0; 27 hasProperty(Property property)28 bool hasProperty(Property property) const override { 29 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 30 if (arg->hasProperty(property)) { 31 return true; 32 } 33 } 34 return false; 35 } 36 description()37 String description() const override { 38 String result = this->type().description() + "("; 39 const char* separator = ""; 40 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 41 result += separator; 42 result += arg->description(); 43 separator = ", "; 44 } 45 result += ")"; 46 return result; 47 } 48 componentType()49 const Type& componentType() const { 50 return this->type().componentType(); 51 } 52 isCompileTimeConstant()53 bool isCompileTimeConstant() const override { 54 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 55 if (!arg->isCompileTimeConstant()) { 56 return false; 57 } 58 } 59 return true; 60 } 61 isConstantOrUniform()62 bool isConstantOrUniform() const override { 63 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) { 64 if (!arg->isConstantOrUniform()) { 65 return false; 66 } 67 } 68 return true; 69 } 70 71 const Expression* getConstantSubexpression(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 offset,Kind kind,const Type * type,std::unique_ptr<Expression> argument)86 SingleArgumentConstructor(int offset, Kind kind, const Type* type, 87 std::unique_ptr<Expression> argument) 88 : INHERITED(offset, 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 offset,Kind kind,const Type * type,ExpressionArray arguments)118 MultiArgumentConstructor(int offset, Kind kind, const Type* type, ExpressionArray arguments) 119 : INHERITED(offset, 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 offset, 172 const Type& type, 173 ExpressionArray args); 174 }; 175 176 } // namespace SkSL 177 178 #endif 179