xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLConstructor.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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