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 #ifdef SKSL_EXT
145 /**
146 * Returns true if this is an unsized array type.
147 */
148 bool isUnsizedArray() const;
149 #endif
150
151 /**
152 * Returns true if this is a struct type.
153 */
154 bool isStruct() const;
155
156 /**
157 * Returns true if this is a Skia object type (shader, colorFilter, blender).
158 */
159 bool isEffectChild() const;
160
161 template<typename... Args>
Construct(DSLType type,DSLVarBase & var,Args &&...args)162 static DSLPossibleExpression Construct(DSLType type, DSLVarBase& var, Args&&... args) {
163 DSLExpression argArray[] = {var, args...};
164 return Construct(type, SkMakeSpan(argArray));
165 }
166
167 template<typename... Args>
Construct(DSLType type,DSLExpression expr,Args &&...args)168 static DSLPossibleExpression Construct(DSLType type, DSLExpression expr, Args&&... args) {
169 DSLExpression argArray[] = {std::move(expr), std::move(args)...};
170 return Construct(type, SkMakeSpan(argArray));
171 }
172
173 static DSLPossibleExpression Construct(DSLType type, SkSpan<DSLExpression> argArray);
174
175 private:
176 const SkSL::Type& skslType() const;
177
178 const SkSL::Type* fSkSLType = nullptr;
179
180 TypeConstant fTypeConstant = kPoison_Type;
181
182 friend DSLType Array(const DSLType& base, int count, PositionInfo pos);
183 #ifdef SKSL_EXT
184 friend DSLType UnsizedArray(const DSLType& base, PositionInfo pos);
185 #endif
186 friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
187 friend class DSLCore;
188 friend class DSLFunction;
189 friend class DSLVarBase;
190 friend class DSLWriter;
191 };
192
193 #define TYPE(T) \
194 template<typename... Args> \
195 DSLExpression T(Args&&... args) { \
196 return DSLType::Construct(k ## T ## _Type, std::forward<Args>(args)...); \
197 }
198
199 #define VECTOR_TYPE(T) \
200 TYPE(T) \
201 TYPE(T ## 2) \
202 TYPE(T ## 3) \
203 TYPE(T ## 4)
204
205 #define MATRIX_TYPE(T) \
206 TYPE(T ## 2x2) \
207 TYPE(T ## 3x2) \
208 TYPE(T ## 4x2) \
209 TYPE(T ## 2x3) \
210 TYPE(T ## 3x3) \
211 TYPE(T ## 4x3) \
212 TYPE(T ## 2x4) \
213 TYPE(T ## 3x4) \
214 TYPE(T ## 4x4)
215
216 VECTOR_TYPE(Bool)
217 VECTOR_TYPE(Float)
218 VECTOR_TYPE(Half)
219 VECTOR_TYPE(Int)
220 VECTOR_TYPE(UInt)
221 VECTOR_TYPE(Short)
222 VECTOR_TYPE(UShort)
223
224 MATRIX_TYPE(Float)
225 MATRIX_TYPE(Half)
226
227 #undef TYPE
228 #undef VECTOR_TYPE
229 #undef MATRIX_TYPE
230
231 DSLType Array(const DSLType& base, int count, PositionInfo pos = PositionInfo::Capture());
232 #ifdef SKSL_EXT
233 DSLType UnsizedArray(const DSLType& base, PositionInfo pos = PositionInfo::Capture());
234 #endif
235
236 class DSLField {
237 public:
238 DSLField(const DSLType type, skstd::string_view name,
239 PositionInfo pos = PositionInfo::Capture())
DSLField(DSLModifiers (),type,name,pos)240 : DSLField(DSLModifiers(), type, name, pos) {}
241
242 DSLField(const DSLModifiers& modifiers, const DSLType type, skstd::string_view name,
243 PositionInfo pos = PositionInfo::Capture())
fModifiers(modifiers)244 : fModifiers(modifiers)
245 , fType(type)
246 , fName(name)
247 , fPosition(pos) {}
248
249 private:
250 DSLModifiers fModifiers;
251 const DSLType fType;
252 skstd::string_view fName;
253 PositionInfo fPosition;
254
255 friend class DSLCore;
256 friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
257 };
258
259 DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields,
260 PositionInfo pos = PositionInfo::Capture());
261
262 template<typename... Field>
Struct(skstd::string_view name,Field...fields)263 DSLType Struct(skstd::string_view name, Field... fields) {
264 DSLField fieldTypes[] = {std::move(fields)...};
265 return Struct(name, SkMakeSpan(fieldTypes), PositionInfo());
266 }
267
268 } // namespace dsl
269
270 } // namespace SkSL
271
272 #endif
273