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