1 /*
2 * Copyright 2020 Google LLC
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_DSL_TYPE
9 #define SKSL_DSL_TYPE
10
11 #include "include/core/SkSpan.h"
12 #include "include/private/SkSLString.h"
13 #include "include/sksl/DSLExpression.h"
14 #include "include/sksl/DSLModifiers.h"
15
16 #include <cstdint>
17
18 namespace SkSL {
19
20 class Type;
21
22 namespace dsl {
23
24 class DSLExpression;
25 class DSLField;
26 class DSLVarBase;
27
28 enum TypeConstant : uint8_t {
29 kBool_Type,
30 kBool2_Type,
31 kBool3_Type,
32 kBool4_Type,
33 kHalf_Type,
34 kHalf2_Type,
35 kHalf3_Type,
36 kHalf4_Type,
37 kHalf2x2_Type,
38 kHalf3x2_Type,
39 kHalf4x2_Type,
40 kHalf2x3_Type,
41 kHalf3x3_Type,
42 kHalf4x3_Type,
43 kHalf2x4_Type,
44 kHalf3x4_Type,
45 kHalf4x4_Type,
46 kFloat_Type,
47 kFloat2_Type,
48 kFloat3_Type,
49 kFloat4_Type,
50 kFragmentProcessor_Type,
51 kFloat2x2_Type,
52 kFloat3x2_Type,
53 kFloat4x2_Type,
54 kFloat2x3_Type,
55 kFloat3x3_Type,
56 kFloat4x3_Type,
57 kFloat2x4_Type,
58 kFloat3x4_Type,
59 kFloat4x4_Type,
60 kInt_Type,
61 kInt2_Type,
62 kInt3_Type,
63 kInt4_Type,
64 kShader_Type,
65 kShort_Type,
66 kShort2_Type,
67 kShort3_Type,
68 kShort4_Type,
69 kUInt_Type,
70 kUInt2_Type,
71 kUInt3_Type,
72 kUInt4_Type,
73 kUShort_Type,
74 kUShort2_Type,
75 kUShort3_Type,
76 kUShort4_Type,
77 kVoid_Type,
78 kPoison_Type,
79 };
80
81 class DSLType {
82 public:
DSLType(TypeConstant tc)83 DSLType(TypeConstant tc)
84 : fTypeConstant(tc) {}
85
86 DSLType(const SkSL::Type* type);
87
88 DSLType(skstd::string_view name);
89
90 DSLType(skstd::string_view name,
91 DSLModifiers* modifiers,
92 PositionInfo pos = PositionInfo::Capture());
93
94 /**
95 * Returns true if this type is a bool.
96 */
97 bool isBoolean() const;
98
99 /**
100 * Returns true if this is a numeric scalar type.
101 */
102 bool isNumber() const;
103
104 /**
105 * Returns true if this is a floating-point scalar type (float or half).
106 */
107 bool isFloat() const;
108
109 /**
110 * Returns true if this is a signed scalar type (int or short).
111 */
112 bool isSigned() const;
113
114 /**
115 * Returns true if this is an unsigned scalar type (uint or ushort).
116 */
117 bool isUnsigned() const;
118
119 /**
120 * Returns true if this is a signed or unsigned integer.
121 */
122 bool isInteger() const;
123
124 /**
125 * Returns true if this is a scalar type.
126 */
127 bool isScalar() const;
128
129 /**
130 * Returns true if this is a vector type.
131 */
132 bool isVector() const;
133
134 /**
135 * Returns true if this is a matrix type.
136 */
137 bool isMatrix() const;
138
139 /**
140 * Returns true if this is a array type.
141 */
142 bool isArray() const;
143
144 /**
145 * Returns true if this is a struct type.
146 */
147 bool isStruct() const;
148
149 /**
150 * Returns true if this is a Skia object type (shader, colorFilter, blender).
151 */
152 bool isEffectChild() const;
153
154 template<typename... Args>
Construct(DSLType type,DSLVarBase & var,Args &&...args)155 static DSLPossibleExpression Construct(DSLType type, DSLVarBase& var, Args&&... args) {
156 DSLExpression argArray[] = {var, args...};
157 return Construct(type, SkMakeSpan(argArray));
158 }
159
160 template<typename... Args>
Construct(DSLType type,DSLExpression expr,Args &&...args)161 static DSLPossibleExpression Construct(DSLType type, DSLExpression expr, Args&&... args) {
162 DSLExpression argArray[] = {std::move(expr), std::move(args)...};
163 return Construct(type, SkMakeSpan(argArray));
164 }
165
166 static DSLPossibleExpression Construct(DSLType type, SkSpan<DSLExpression> argArray);
167
168 private:
169 const SkSL::Type& skslType() const;
170
171 const SkSL::Type* fSkSLType = nullptr;
172
173 TypeConstant fTypeConstant = kPoison_Type;
174
175 friend DSLType Array(const DSLType& base, int count, PositionInfo pos);
176 friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
177 friend class DSLCore;
178 friend class DSLFunction;
179 friend class DSLVarBase;
180 friend class DSLWriter;
181 };
182
183 #define TYPE(T) \
184 template<typename... Args> \
185 DSLExpression T(Args&&... args) { \
186 return DSLType::Construct(k ## T ## _Type, std::forward<Args>(args)...); \
187 }
188
189 #define VECTOR_TYPE(T) \
190 TYPE(T) \
191 TYPE(T ## 2) \
192 TYPE(T ## 3) \
193 TYPE(T ## 4)
194
195 #define MATRIX_TYPE(T) \
196 TYPE(T ## 2x2) \
197 TYPE(T ## 3x2) \
198 TYPE(T ## 4x2) \
199 TYPE(T ## 2x3) \
200 TYPE(T ## 3x3) \
201 TYPE(T ## 4x3) \
202 TYPE(T ## 2x4) \
203 TYPE(T ## 3x4) \
204 TYPE(T ## 4x4)
205
206 VECTOR_TYPE(Bool)
207 VECTOR_TYPE(Float)
208 VECTOR_TYPE(Half)
209 VECTOR_TYPE(Int)
210 VECTOR_TYPE(UInt)
211 VECTOR_TYPE(Short)
212 VECTOR_TYPE(UShort)
213
214 MATRIX_TYPE(Float)
215 MATRIX_TYPE(Half)
216
217 #undef TYPE
218 #undef VECTOR_TYPE
219 #undef MATRIX_TYPE
220
221 DSLType Array(const DSLType& base, int count, PositionInfo pos = PositionInfo::Capture());
222
223 class DSLField {
224 public:
225 DSLField(const DSLType type, skstd::string_view name,
226 PositionInfo pos = PositionInfo::Capture())
DSLField(DSLModifiers (),type,name,pos)227 : DSLField(DSLModifiers(), type, name, pos) {}
228
229 DSLField(const DSLModifiers& modifiers, const DSLType type, skstd::string_view name,
230 PositionInfo pos = PositionInfo::Capture())
fModifiers(modifiers)231 : fModifiers(modifiers)
232 , fType(type)
233 , fName(name)
234 , fPosition(pos) {}
235
236 private:
237 DSLModifiers fModifiers;
238 const DSLType fType;
239 skstd::string_view fName;
240 PositionInfo fPosition;
241
242 friend class DSLCore;
243 friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
244 };
245
246 DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields,
247 PositionInfo pos = PositionInfo::Capture());
248
249 template<typename... Field>
Struct(skstd::string_view name,Field...fields)250 DSLType Struct(skstd::string_view name, Field... fields) {
251 DSLField fieldTypes[] = {std::move(fields)...};
252 return Struct(name, SkMakeSpan(fieldTypes), PositionInfo());
253 }
254
255 } // namespace dsl
256
257 } // namespace SkSL
258
259 #endif
260