Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/sksl/ir/SkSLType.h
Line
Count
Source (jump to first uncovered line)
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_TYPE
9
#define SKSL_TYPE
10
11
#include "include/core/SkStringView.h"
12
#include "include/private/SkSLModifiers.h"
13
#include "include/private/SkSLSymbol.h"
14
#include "src/sksl/SkSLPosition.h"
15
#include "src/sksl/SkSLUtil.h"
16
#include "src/sksl/spirv.h"
17
#include <algorithm>
18
#include <climits>
19
#include <vector>
20
#include <memory>
21
22
namespace SkSL {
23
24
class BuiltinTypes;
25
class Context;
26
class SymbolTable;
27
28
struct CoercionCost {
29
21.2M
    static CoercionCost Free()              { return {    0,    0, false }; }
30
86.6k
    static CoercionCost Normal(int cost)    { return { cost,    0, false }; }
31
104k
    static CoercionCost Narrowing(int cost) { return {    0, cost, false }; }
32
667k
    static CoercionCost Impossible()        { return {    0,    0,  true }; }
33
34
20.9M
    bool isPossible(bool allowNarrowing) const {
35
20.9M
        return !fImpossible && (fNarrowingCost == 0 || allowNarrowing);
36
20.9M
    }
37
38
    // Addition of two costs. Saturates at Impossible().
39
179k
    CoercionCost operator+(CoercionCost rhs) const {
40
179k
        if (fImpossible || rhs.fImpossible) {
41
1.71k
            return Impossible();
42
1.71k
        }
43
177k
        return { fNormalCost + rhs.fNormalCost, fNarrowingCost + rhs.fNarrowingCost, false };
44
177k
    }
45
46
10.3M
    bool operator<(CoercionCost rhs) const {
47
10.3M
        return std::tie(    fImpossible,     fNarrowingCost,     fNormalCost) <
48
10.3M
               std::tie(rhs.fImpossible, rhs.fNarrowingCost, rhs.fNormalCost);
49
10.3M
    }
50
51
    int  fNormalCost;
52
    int  fNarrowingCost;
53
    bool fImpossible;
54
};
55
56
/**
57
 * Represents a type, such as int or float4.
58
 */
59
class Type : public Symbol {
60
public:
61
    static constexpr Kind kSymbolKind = Kind::kType;
62
    static constexpr int kMaxAbbrevLength = 3;
63
64
    struct Field {
65
        Field(Modifiers modifiers, skstd::string_view name, const Type* type)
66
        : fModifiers(modifiers)
67
        , fName(name)
68
191k
        , fType(std::move(type)) {}
69
70
0
        String description() const {
71
0
            return fType->displayName() + " " + fName + ";";
72
0
        }
73
74
        Modifiers fModifiers;
75
        skstd::string_view fName;
76
        const Type* fType;
77
    };
78
79
    enum class TypeKind : int8_t {
80
        kArray,
81
        kGeneric,
82
        kLiteral,
83
        kMatrix,
84
        kOther,
85
        kSampler,
86
        kSeparateSampler,
87
        kScalar,
88
        kStruct,
89
        kTexture,
90
        kVector,
91
        kVoid,
92
93
        // Types that represent stages in the Skia pipeline
94
        kColorFilter,
95
        kShader,
96
        kBlender,
97
    };
98
99
    enum class NumberKind : int8_t {
100
        kFloat,
101
        kSigned,
102
        kUnsigned,
103
        kBoolean,
104
        kNonnumeric
105
    };
106
107
    Type(const Type& other) = delete;
108
109
    /** Creates an array type. */
110
    static constexpr int kUnsizedArray = -1;
111
    static std::unique_ptr<Type> MakeArrayType(skstd::string_view name, const Type& componentType,
112
                                               int columns);
113
114
    /** Converts a component type and a size (float, 10) into an array name ("float[10]"). */
115
    String getArrayName(int arraySize) const;
116
117
    /**
118
     * Create a generic type which maps to the listed types--e.g. $genType is a generic type which
119
     * can match float, float2, float3 or float4.
120
     */
121
    static std::unique_ptr<Type> MakeGenericType(const char* name, std::vector<const Type*> types);
122
123
    /** Create a type for literal scalars. */
124
    static std::unique_ptr<Type> MakeLiteralType(const char* name, const Type& scalarType,
125
                                                 int8_t priority);
126
127
    /** Create a matrix type. */
128
    static std::unique_ptr<Type> MakeMatrixType(skstd::string_view name, const char* abbrev,
129
                                                const Type& componentType, int columns,
130
                                                int8_t rows);
131
132
    /** Create a sampler type. */
133
    static std::unique_ptr<Type> MakeSamplerType(const char* name, const Type& textureType);
134
135
    /** Create a scalar type. */
136
    static std::unique_ptr<Type> MakeScalarType(skstd::string_view name, const char* abbrev,
137
                                                Type::NumberKind numberKind, int8_t priority,
138
                                                int8_t bitWidth);
139
140
    /**
141
     * Create a "special" type with the given name, abbreviation, and TypeKind.
142
     */
143
    static std::unique_ptr<Type> MakeSpecialType(const char* name, const char* abbrev,
144
                                                 Type::TypeKind typeKind);
145
146
    /** Creates a struct type with the given fields. */
147
    static std::unique_ptr<Type> MakeStructType(int offset, skstd::string_view name,
148
                                                std::vector<Field> fields);
149
150
    /** Create a texture type. */
151
    static std::unique_ptr<Type> MakeTextureType(const char* name, SpvDim_ dimensions,
152
                                                 bool isDepth, bool isArrayedTexture,
153
                                                 bool isMultisampled, bool isSampled);
154
155
    /** Create a vector type. */
156
    static std::unique_ptr<Type> MakeVectorType(skstd::string_view name, const char* abbrev,
157
                                                const Type& componentType, int columns);
158
159
    template <typename T>
160
2.04M
    bool is() const {
161
2.04M
        return this->typeKind() == T::kTypeKind;
162
2.04M
    }
bool SkSL::Type::is<SkSL::ArrayType>() const
Line
Count
Source
160
34.2k
    bool is() const {
161
34.2k
        return this->typeKind() == T::kTypeKind;
162
34.2k
    }
bool SkSL::Type::is<SkSL::ScalarType>() const
Line
Count
Source
160
1.74M
    bool is() const {
161
1.74M
        return this->typeKind() == T::kTypeKind;
162
1.74M
    }
bool SkSL::Type::is<SkSL::TextureType>() const
Line
Count
Source
160
268k
    bool is() const {
161
268k
        return this->typeKind() == T::kTypeKind;
162
268k
    }
163
164
    template <typename T>
165
2.07M
    const T& as() const {
166
2.07M
        SkASSERT(this->is<T>());
167
2.07M
        return static_cast<const T&>(*this);
168
2.07M
    }
SkSL::ScalarType const& SkSL::Type::as<SkSL::ScalarType>() const
Line
Count
Source
165
52.0k
    const T& as() const {
166
52.0k
        SkASSERT(this->is<T>());
167
52.0k
        return static_cast<const T&>(*this);
168
52.0k
    }
SkSL::TextureType const& SkSL::Type::as<SkSL::TextureType>() const
Line
Count
Source
165
8.00k
    const T& as() const {
166
8.00k
        SkASSERT(this->is<T>());
167
8.00k
        return static_cast<const T&>(*this);
168
8.00k
    }
SkSL::ScalarType const& SkSL::Type::as<SkSL::ScalarType>() const
Line
Count
Source
165
1.74M
    const T& as() const {
166
1.74M
        SkASSERT(this->is<T>());
167
1.74M
        return static_cast<const T&>(*this);
168
1.74M
    }
SkSL::TextureType const& SkSL::Type::as<SkSL::TextureType>() const
Line
Count
Source
165
268k
    const T& as() const {
166
268k
        SkASSERT(this->is<T>());
167
268k
        return static_cast<const T&>(*this);
168
268k
    }
169
170
    template <typename T>
171
    T& as() {
172
        SkASSERT(this->is<T>());
173
        return static_cast<T&>(*this);
174
    }
175
176
    /** Creates a clone of this Type, if needed, and inserts it into a different symbol table. */
177
    const Type* clone(SymbolTable* symbolTable) const;
178
179
    /**
180
     * Returns true if this type is known to come from BuiltinTypes. If this returns true, the Type
181
     * will always be available in the root SymbolTable and never needs to be copied to migrate an
182
     * Expression from one location to another. If it returns false, the Type might not exist in a
183
     * separate SymbolTable and you'll need to consider copying it.
184
     */
185
789k
    bool isInBuiltinTypes() const {
186
789k
        return !(this->isArray() || this->isStruct());
187
789k
    }
188
189
4.70M
    String displayName() const {
190
4.70M
        return String(this->scalarTypeForLiteral().name());
191
4.70M
    }
192
193
8
    String description() const override {
194
8
        return this->displayName();
195
8
    }
196
197
418k
    bool isPrivate() const {
198
418k
        return this->name().starts_with("$");
199
418k
    }
200
201
53.8k
    virtual bool allowedInES2() const {
202
53.8k
        return true;
203
53.8k
    }
204
205
53.0M
    bool operator==(const Type& other) const {
206
53.0M
        return this->name() == other.name();
207
53.0M
    }
208
209
515k
    bool operator!=(const Type& other) const {
210
515k
        return this->name() != other.name();
211
515k
    }
212
213
    /**
214
     * Returns an abbreviated name of the type, meant for name-mangling. (e.g. float4x4 -> f44)
215
     */
216
165k
    const char* abbreviatedName() const {
217
165k
        return fAbbreviatedName;
218
165k
    }
219
220
    /**
221
     * Returns the category (scalar, vector, matrix, etc.) of this type.
222
     */
223
47.8M
    TypeKind typeKind() const {
224
47.8M
        return fTypeKind;
225
47.8M
    }
226
227
    /**
228
     * Returns the NumberKind of this type (always kNonnumeric for non-scalar values).
229
     */
230
931k
    virtual NumberKind numberKind() const {
231
931k
        return NumberKind::kNonnumeric;
232
931k
    }
233
234
    /**
235
     * Returns true if this type is a bool.
236
     */
237
23.6M
    bool isBoolean() const {
238
23.6M
        return this->numberKind() == NumberKind::kBoolean;
239
23.6M
    }
240
241
    /**
242
     * Returns true if this is a numeric scalar type.
243
     */
244
2.63M
    bool isNumber() const {
245
2.63M
        switch (this->numberKind()) {
246
1.17M
            case NumberKind::kFloat:
247
2.50M
            case NumberKind::kSigned:
248
2.52M
            case NumberKind::kUnsigned:
249
2.52M
                return true;
250
110k
            default:
251
110k
                return false;
252
2.63M
        }
253
2.63M
    }
254
255
    /**
256
     * Returns true if this is a floating-point scalar type (float or half).
257
     */
258
4.23M
    bool isFloat() const {
259
4.23M
        return this->numberKind() == NumberKind::kFloat;
260
4.23M
    }
261
262
    /**
263
     * Returns true if this is a signed scalar type (int or short).
264
     */
265
334k
    bool isSigned() const {
266
334k
        return this->numberKind() == NumberKind::kSigned;
267
334k
    }
268
269
    /**
270
     * Returns true if this is an unsigned scalar type (uint or ushort).
271
     */
272
405k
    bool isUnsigned() const {
273
405k
        return this->numberKind() == NumberKind::kUnsigned;
274
405k
    }
275
276
    /**
277
     * Returns true if this is a signed or unsigned integer.
278
     */
279
3.60M
    bool isInteger() const {
280
3.60M
        switch (this->numberKind()) {
281
2.16M
            case NumberKind::kSigned:
282
2.21M
            case NumberKind::kUnsigned:
283
2.21M
                return true;
284
1.39M
            default:
285
1.39M
                return false;
286
3.60M
        }
287
3.60M
    }
288
289
    /**
290
     * Returns true if this is an "opaque type" (an external object which the shader references in
291
     * some fashion), or void. https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Opaque_types
292
     */
293
2.78M
    bool isOpaque() const {
294
2.78M
        switch (fTypeKind) {
295
0
            case TypeKind::kBlender:
296
1.09k
            case TypeKind::kColorFilter:
297
1.12k
            case TypeKind::kOther:
298
4.00k
            case TypeKind::kSampler:
299
16.4k
            case TypeKind::kSeparateSampler:
300
17.6k
            case TypeKind::kShader:
301
17.6k
            case TypeKind::kTexture:
302
22.0k
            case TypeKind::kVoid:
303
22.0k
                return true;
304
2.76M
            default:
305
2.76M
                return false;
306
2.78M
        }
307
2.78M
    }
308
309
    /**
310
     * Returns the "priority" of a number type, in order of float > half > int > short.
311
     * When operating on two number types, the result is the higher-priority type.
312
     */
313
0
    virtual int priority() const {
314
0
        SkDEBUGFAIL("not a number type");
315
0
        return -1;
316
0
    }
Unexecuted instantiation: SkSL::Type::priority() const
Unexecuted instantiation: SkSL::Type::priority() const
317
318
    /**
319
     * Returns true if an instance of this type can be freely coerced (implicitly converted) to
320
     * another type.
321
     */
322
624k
    bool canCoerceTo(const Type& other, bool allowNarrowing) const {
323
624k
        return this->coercionCost(other).isPossible(allowNarrowing);
324
624k
    }
325
326
    /**
327
     * Determines the "cost" of coercing (implicitly converting) this type to another type. The cost
328
     * is a number with no particular meaning other than that lower costs are preferable to higher
329
     * costs. Returns INT_MAX if the coercion is not possible.
330
     */
331
    CoercionCost coercionCost(const Type& other) const;
332
333
    /**
334
     * For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component
335
     * type of Float). For arrays, returns the base type. For all other types, returns the type
336
     * itself.
337
     */
338
23.2M
    virtual const Type& componentType() const {
339
23.2M
        return *this;
340
23.2M
    }
341
342
    /**
343
     * For texturesamplers, returns the type of texture it samples (e.g., sampler2D has
344
     * a texture type of texture2D).
345
     */
346
0
    virtual const Type& textureType() const {
347
0
        SkDEBUGFAIL("not a texture type");
348
0
        return *this;
349
0
    }
Unexecuted instantiation: SkSL::Type::textureType() const
Unexecuted instantiation: SkSL::Type::textureType() const
350
351
    /**
352
     * For matrices and vectors, returns the number of columns (e.g. both mat3 and float3 return 3).
353
     * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1.
354
     * For all other types, causes an assertion failure.
355
     */
356
0
    virtual int columns() const {
357
0
        SkDEBUGFAIL("type does not have columns");
358
0
        return -1;
359
0
    }
Unexecuted instantiation: SkSL::Type::columns() const
Unexecuted instantiation: SkSL::Type::columns() const
360
361
    /**
362
     * For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vectors and scalars,
363
     * returns 1. For all other types, causes an assertion failure.
364
     */
365
0
    virtual int rows() const {
366
0
        SkDEBUGFAIL("type does not have rows");
367
0
        return -1;
368
0
    }
Unexecuted instantiation: SkSL::Type::rows() const
Unexecuted instantiation: SkSL::Type::rows() const
369
370
    /** For integer types, returns the minimum value that can fit in the type. */
371
86.2k
    int64_t minimumValue() const {
372
86.2k
        SkASSERT(this->isInteger());
373
86.2k
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
374
82.9k
        return this->isUnsigned() ? 0 : -(k1 << (this->bitWidth() - 1));
375
86.2k
    }
SkSL::Type::minimumValue() const
Line
Count
Source
371
8
    int64_t minimumValue() const {
372
8
        SkASSERT(this->isInteger());
373
8
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
374
8
        return this->isUnsigned() ? 0 : -(k1 << (this->bitWidth() - 1));
375
8
    }
SkSL::Type::minimumValue() const
Line
Count
Source
371
86.2k
    int64_t minimumValue() const {
372
86.2k
        SkASSERT(this->isInteger());
373
86.2k
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
374
82.9k
        return this->isUnsigned() ? 0 : -(k1 << (this->bitWidth() - 1));
375
86.2k
    }
376
377
    /** For integer types, returns the maximum value that can fit in the type. */
378
83.3k
    int64_t maximumValue() const {
379
83.3k
        SkASSERT(this->isInteger());
380
83.3k
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
381
1.77k
        return (this->isUnsigned() ? (k1 << this->bitWidth())
382
81.6k
                                   : (k1 << (this->bitWidth() - 1))) - 1;
383
83.3k
    }
SkSL::Type::maximumValue() const
Line
Count
Source
378
8
    int64_t maximumValue() const {
379
8
        SkASSERT(this->isInteger());
380
8
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
381
0
        return (this->isUnsigned() ? (k1 << this->bitWidth())
382
8
                                   : (k1 << (this->bitWidth() - 1))) - 1;
383
8
    }
SkSL::Type::maximumValue() const
Line
Count
Source
378
83.3k
    int64_t maximumValue() const {
379
83.3k
        SkASSERT(this->isInteger());
380
83.3k
        constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
381
1.77k
        return (this->isUnsigned() ? (k1 << this->bitWidth())
382
81.6k
                                   : (k1 << (this->bitWidth() - 1))) - 1;
383
83.3k
    }
384
385
    /**
386
     * Returns the number of scalars needed to hold this type.
387
     */
388
37.4M
    size_t slotCount() const {
389
37.4M
        switch (this->typeKind()) {
390
0
            case Type::TypeKind::kBlender:
391
0
            case Type::TypeKind::kColorFilter:
392
0
            case Type::TypeKind::kGeneric:
393
0
            case Type::TypeKind::kOther:
394
0
            case Type::TypeKind::kSampler:
395
0
            case Type::TypeKind::kSeparateSampler:
396
0
            case Type::TypeKind::kShader:
397
0
            case Type::TypeKind::kTexture:
398
0
            case Type::TypeKind::kVoid:
399
0
                return 0;
400
401
429k
            case Type::TypeKind::kLiteral:
402
26.5M
            case Type::TypeKind::kScalar:
403
26.5M
                return 1;
404
405
10.9M
            case Type::TypeKind::kVector:
406
10.9M
                return this->columns();
407
408
73.3k
            case Type::TypeKind::kMatrix:
409
73.3k
                return this->columns() * this->rows();
410
411
0
            case Type::TypeKind::kStruct: {
412
0
                size_t slots = 0;
413
0
                for (const Field& field : this->fields()) {
414
0
                    slots += field.fType->slotCount();
415
0
                }
416
0
                return slots;
417
429k
            }
418
1.30k
            case Type::TypeKind::kArray:
419
1.30k
                SkASSERT(this->columns() > 0);
420
1.30k
                return this->columns() * this->componentType().slotCount();
421
0
        }
422
0
        SkUNREACHABLE;
423
0
    }
SkSL::Type::slotCount() const
Line
Count
Source
388
4.91M
    size_t slotCount() const {
389
4.91M
        switch (this->typeKind()) {
390
0
            case Type::TypeKind::kBlender:
391
0
            case Type::TypeKind::kColorFilter:
392
0
            case Type::TypeKind::kGeneric:
393
0
            case Type::TypeKind::kOther:
394
0
            case Type::TypeKind::kSampler:
395
0
            case Type::TypeKind::kSeparateSampler:
396
0
            case Type::TypeKind::kShader:
397
0
            case Type::TypeKind::kTexture:
398
0
            case Type::TypeKind::kVoid:
399
0
                return 0;
400
401
48
            case Type::TypeKind::kLiteral:
402
2.26M
            case Type::TypeKind::kScalar:
403
2.26M
                return 1;
404
405
2.64M
            case Type::TypeKind::kVector:
406
2.64M
                return this->columns();
407
408
3
            case Type::TypeKind::kMatrix:
409
3
                return this->columns() * this->rows();
410
411
0
            case Type::TypeKind::kStruct: {
412
0
                size_t slots = 0;
413
0
                for (const Field& field : this->fields()) {
414
0
                    slots += field.fType->slotCount();
415
0
                }
416
0
                return slots;
417
48
            }
418
0
            case Type::TypeKind::kArray:
419
0
                SkASSERT(this->columns() > 0);
420
0
                return this->columns() * this->componentType().slotCount();
421
0
        }
422
0
        SkUNREACHABLE;
423
0
    }
SkSL::Type::slotCount() const
Line
Count
Source
388
32.5M
    size_t slotCount() const {
389
32.5M
        switch (this->typeKind()) {
390
0
            case Type::TypeKind::kBlender:
391
0
            case Type::TypeKind::kColorFilter:
392
0
            case Type::TypeKind::kGeneric:
393
0
            case Type::TypeKind::kOther:
394
0
            case Type::TypeKind::kSampler:
395
0
            case Type::TypeKind::kSeparateSampler:
396
0
            case Type::TypeKind::kShader:
397
0
            case Type::TypeKind::kTexture:
398
0
            case Type::TypeKind::kVoid:
399
0
                return 0;
400
401
429k
            case Type::TypeKind::kLiteral:
402
24.2M
            case Type::TypeKind::kScalar:
403
24.2M
                return 1;
404
405
8.26M
            case Type::TypeKind::kVector:
406
8.26M
                return this->columns();
407
408
73.3k
            case Type::TypeKind::kMatrix:
409
73.3k
                return this->columns() * this->rows();
410
411
0
            case Type::TypeKind::kStruct: {
412
0
                size_t slots = 0;
413
0
                for (const Field& field : this->fields()) {
414
0
                    slots += field.fType->slotCount();
415
0
                }
416
0
                return slots;
417
429k
            }
418
1.30k
            case Type::TypeKind::kArray:
419
1.30k
                SkASSERT(this->columns() > 0);
420
1.30k
                return this->columns() * this->componentType().slotCount();
421
0
        }
422
0
        SkUNREACHABLE;
423
0
    }
424
425
0
    virtual const std::vector<Field>& fields() const {
426
0
        SK_ABORT("Internal error: not a struct");
427
0
    }
428
429
    /**
430
     * For generic types, returns the types that this generic type can substitute for.
431
     */
432
0
    virtual const std::vector<const Type*>& coercibleTypes() const {
433
0
        SK_ABORT("Internal error: not a generic type");
434
0
    }
435
436
0
    virtual SpvDim_ dimensions() const {
437
0
        SkASSERT(false);
438
0
        return SpvDim1D;
439
0
    }
Unexecuted instantiation: SkSL::Type::dimensions() const
Unexecuted instantiation: SkSL::Type::dimensions() const
440
441
0
    virtual bool isDepth() const {
442
0
        SkASSERT(false);
443
0
        return false;
444
0
    }
Unexecuted instantiation: SkSL::Type::isDepth() const
Unexecuted instantiation: SkSL::Type::isDepth() const
445
446
0
    virtual bool isArrayedTexture() const {
447
0
        SkASSERT(false);
448
0
        return false;
449
0
    }
Unexecuted instantiation: SkSL::Type::isArrayedTexture() const
Unexecuted instantiation: SkSL::Type::isArrayedTexture() const
450
451
654k
    bool isVoid() const {
452
654k
        return fTypeKind == TypeKind::kVoid;
453
654k
    }
454
455
22.1M
    virtual bool isScalar() const {
456
22.1M
        return false;
457
22.1M
    }
458
459
338k
    virtual bool isLiteral() const {
460
338k
        return false;
461
338k
    }
462
463
5.24M
    virtual const Type& scalarTypeForLiteral() const {
464
5.24M
        return *this;
465
5.24M
    }
466
467
25.8M
    virtual bool isVector() const {
468
25.8M
        return false;
469
25.8M
    }
470
471
31.0M
    virtual bool isMatrix() const {
472
31.0M
        return false;
473
31.0M
    }
474
475
4.55M
    virtual bool isArray() const {
476
4.55M
        return false;
477
4.55M
    }
478
479
2.61M
    virtual bool isStruct() const {
480
2.61M
        return false;
481
2.61M
    }
482
483
    // Is this type something that can be bound & sampled from an SkRuntimeEffect?
484
    // Includes types that represent stages of the Skia pipeline (colorFilter, shader, blender).
485
304k
    bool isEffectChild() const {
486
304k
        return fTypeKind == TypeKind::kColorFilter ||
487
303k
               fTypeKind == TypeKind::kShader ||
488
302k
               fTypeKind == TypeKind::kBlender;
489
304k
    }
490
491
0
    virtual bool isMultisampled() const {
492
0
        SkASSERT(false);
493
0
        return false;
494
0
    }
Unexecuted instantiation: SkSL::Type::isMultisampled() const
Unexecuted instantiation: SkSL::Type::isMultisampled() const
495
496
0
    virtual bool isSampled() const {
497
0
        SkASSERT(false);
498
0
        return false;
499
0
    }
Unexecuted instantiation: SkSL::Type::isSampled() const
Unexecuted instantiation: SkSL::Type::isSampled() const
500
501
198k
    bool hasPrecision() const {
502
198k
        return this->componentType().isNumber() || fTypeKind == TypeKind::kSampler;
503
198k
    }
504
505
10.4M
    bool highPrecision() const {
506
10.4M
        return this->bitWidth() >= 32;
507
10.4M
    }
508
509
11.2k
    virtual int bitWidth() const {
510
11.2k
        return 0;
511
11.2k
    }
512
513
    bool isOrContainsArray() const;
514
515
    /**
516
     * Returns the corresponding vector or matrix type with the specified number of columns and
517
     * rows.
518
     */
519
    const Type& toCompound(const Context& context, int columns, int rows) const;
520
521
    /**
522
     * Returns a type which honors the precision qualifiers set in Modifiers. e.g., kMediump_Flag
523
     * when applied to `float2` will return `half2`. Generates an error if the precision qualifiers
524
     * don't make sense, e.g. `highp bool` or `mediump MyStruct`.
525
     */
526
    const Type* applyPrecisionQualifiers(const Context& context,
527
                                         const Modifiers& modifiers,
528
                                         SymbolTable* symbols,
529
                                         int offset) const;
530
531
    /**
532
     * Coerces the passed-in expression to this type. If the types are incompatible, reports an
533
     * error and returns null.
534
     */
535
    std::unique_ptr<Expression> coerceExpression(std::unique_ptr<Expression> expr,
536
                                                 const Context& context) const;
537
538
    /** Detects any IntLiterals in the expression which can't fit in this type. */
539
    bool checkForOutOfRangeLiteral(const Context& context, const Expression& expr) const;
540
541
protected:
542
    Type(skstd::string_view name, const char* abbrev, TypeKind kind, int offset = -1)
543
        : INHERITED(offset, kSymbolKind, name)
544
4.07M
        , fTypeKind(kind) {
545
4.07M
        SkASSERT(strlen(abbrev) <= kMaxAbbrevLength);
546
4.07M
        strcpy(fAbbreviatedName, abbrev);
547
4.07M
    }
SkSL::Type::Type(skstd::string_view, char const*, SkSL::Type::TypeKind, int)
Line
Count
Source
544
116k
        , fTypeKind(kind) {
545
116k
        SkASSERT(strlen(abbrev) <= kMaxAbbrevLength);
546
116k
        strcpy(fAbbreviatedName, abbrev);
547
116k
    }
SkSL::Type::Type(skstd::string_view, char const*, SkSL::Type::TypeKind, int)
Line
Count
Source
544
3.95M
        , fTypeKind(kind) {
545
3.95M
        SkASSERT(strlen(abbrev) <= kMaxAbbrevLength);
546
3.95M
        strcpy(fAbbreviatedName, abbrev);
547
3.95M
    }
548
549
private:
550
    friend class BuiltinTypes;
551
552
    using INHERITED = Symbol;
553
554
    char fAbbreviatedName[kMaxAbbrevLength + 1] = {};
555
    TypeKind fTypeKind;
556
};
557
558
}  // namespace SkSL
559
560
#endif