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/private/SkTArray.h"
12 #include "src/sksl/SkSLIRGenerator.h"
13 #include "src/sksl/ir/SkSLExpression.h"
14 #include "src/sksl/ir/SkSLFloatLiteral.h"
15 #include "src/sksl/ir/SkSLIntLiteral.h"
16 #include "src/sksl/ir/SkSLPrefixExpression.h"
17 
18 namespace SkSL {
19 
20 /**
21  * Represents the construction of a compound type, such as "float2(x, y)".
22  *
23  * Vector constructors will always consist of either exactly 1 scalar, or a collection of vectors
24  * and scalars totalling exactly the right number of scalar components.
25  *
26  * Matrix constructors will always consist of either exactly 1 scalar, exactly 1 matrix, or a
27  * collection of vectors and scalars totalling exactly the right number of scalar components.
28  */
29 class Constructor final : public Expression {
30 public:
31     static constexpr Kind kExpressionKind = Kind::kConstructor;
32 
Constructor(int offset,const Type * type,ExpressionArray arguments)33     Constructor(int offset, const Type* type, ExpressionArray arguments)
34         : INHERITED(offset, kExpressionKind, type)
35         , fArguments(std::move(arguments)) {}
36 
arguments()37     ExpressionArray& arguments() {
38         return fArguments;
39     }
40 
arguments()41     const ExpressionArray& arguments() const {
42         return fArguments;
43     }
44 
45     std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
46                                                   const DefinitionMap& definitions) override;
47 
hasProperty(Property property)48     bool hasProperty(Property property) const override {
49         for (const std::unique_ptr<Expression>& arg: this->arguments()) {
50             if (arg->hasProperty(property)) {
51                 return true;
52             }
53         }
54         return false;
55     }
56 
clone()57     std::unique_ptr<Expression> clone() const override {
58         ExpressionArray cloned;
59         cloned.reserve_back(this->arguments().size());
60         for (const std::unique_ptr<Expression>& arg: this->arguments()) {
61             cloned.push_back(arg->clone());
62         }
63         return std::make_unique<Constructor>(fOffset, &this->type(), std::move(cloned));
64     }
65 
description()66     String description() const override {
67         String result = this->type().description() + "(";
68         const char* separator = "";
69         for (const std::unique_ptr<Expression>& arg: this->arguments()) {
70             result += separator;
71             result += arg->description();
72             separator = ", ";
73         }
74         result += ")";
75         return result;
76     }
77 
isCompileTimeConstant()78     bool isCompileTimeConstant() const override {
79         for (const std::unique_ptr<Expression>& arg: this->arguments()) {
80             if (!arg->isCompileTimeConstant()) {
81                 return false;
82             }
83         }
84         return true;
85     }
86 
isConstantOrUniform()87     bool isConstantOrUniform() const override {
88         for (const std::unique_ptr<Expression>& arg: this->arguments()) {
89             if (!arg->isConstantOrUniform()) {
90                 return false;
91             }
92         }
93         return true;
94     }
95 
96     bool compareConstant(const Context& context, const Expression& other) const override;
97 
98     template <typename resultType>
99     resultType getVecComponent(int index) const;
100 
getFVecComponent(int n)101     SKSL_FLOAT getFVecComponent(int n) const override {
102         return this->getVecComponent<SKSL_FLOAT>(n);
103     }
104 
105     /**
106      * For a literal vector expression, return the integer value of the n'th vector component. It is
107      * an error to call this method on an expression which is not a literal vector.
108      */
getIVecComponent(int n)109     SKSL_INT getIVecComponent(int n) const override {
110         return this->getVecComponent<SKSL_INT>(n);
111     }
112 
113     SKSL_FLOAT getMatComponent(int col, int row) const override;
114 
115 private:
116     ExpressionArray fArguments;
117 
118     using INHERITED = Expression;
119 };
120 
121 }  // namespace SkSL
122 
123 #endif
124