Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
SkSL::Type Class Reference

#include <SkSLType.h>

Inheritance diagram for SkSL::Type:
SkSL::Symbol SkSL::IRNode SkSL::Poolable SkSL::AliasType SkSL::ArrayType SkSL::AtomicType SkSL::GenericType SkSL::LiteralType SkSL::MatrixType SkSL::SamplerType SkSL::ScalarType SkSL::StructType SkSL::TextureType SkSL::VectorType

Public Types

enum class  TypeKind : int8_t {
  kArray , kAtomic , kGeneric , kLiteral ,
  kMatrix , kOther , kSampler , kSeparateSampler ,
  kScalar , kStruct , kTexture , kVector ,
  kVoid , kColorFilter , kShader , kBlender
}
 
enum class  NumberKind : int8_t {
  kFloat , kSigned , kUnsigned , kBoolean ,
  kNonnumeric
}
 
enum class  TextureAccess : int8_t { kSample , kRead , kWrite , kReadWrite }
 
- Public Types inherited from SkSL::Symbol
using Kind = SymbolKind
 

Public Member Functions

 Type (const Type &other)=delete
 
std::string getArrayName (int arraySize) const
 
template<typename T >
bool is () const
 
template<typename T >
const Tas () const
 
template<typename T >
Tas ()
 
const Typeclone (const Context &context, SymbolTable *symbolTable) const
 
virtual bool isBuiltin () const
 
std::string displayName () const
 
std::string description () const override
 
bool isAllowedInES2 (const Context &context) const
 
virtual bool isAllowedInES2 () const
 
virtual bool isAllowedInUniform (Position *errorPosition=nullptr) const
 
virtual const Typeresolve () const
 
bool matches (const Type &other) const
 
const char * abbreviatedName () const
 
TypeKind typeKind () const
 
virtual NumberKind numberKind () const
 
bool isBoolean () const
 
bool isNumber () const
 
bool isFloat () const
 
bool isSigned () const
 
bool isUnsigned () const
 
bool isInteger () const
 
bool isOpaque () const
 
bool isStorageTexture () const
 
virtual int priority () const
 
bool canCoerceTo (const Type &other, bool allowNarrowing) const
 
CoercionCost coercionCost (const Type &other) const
 
virtual const TypecomponentType () const
 
const TypecolumnType (const Context &context) const
 
virtual const TypetextureType () const
 
virtual int columns () const
 
virtual int rows () const
 
virtual double minimumValue () const
 
virtual double maximumValue () const
 
virtual size_t slotCount () const
 
virtual const TypeslotType (size_t) const
 
virtual SkSpan< const Fieldfields () const
 
virtual SkSpan< const Type *const > coercibleTypes () const
 
virtual SpvDim_ dimensions () const
 
virtual bool isDepth () const
 
virtual bool isArrayedTexture () const
 
bool isVoid () const
 
bool isGeneric () const
 
bool isSampler () const
 
bool isAtomic () const
 
virtual bool isScalar () const
 
virtual bool isLiteral () const
 
virtual const TypescalarTypeForLiteral () const
 
virtual bool isVector () const
 
virtual bool isMatrix () const
 
virtual bool isArray () const
 
virtual bool isUnsizedArray () const
 
virtual bool isStruct () const
 
virtual bool isInterfaceBlock () const
 
bool isEffectChild () const
 
virtual bool isMultisampled () const
 
virtual TextureAccess textureAccess () const
 
bool hasPrecision () const
 
bool highPrecision () const
 
virtual int bitWidth () const
 
virtual bool isOrContainsArray () const
 
virtual bool isOrContainsUnsizedArray () const
 
virtual bool isOrContainsAtomic () const
 
const TypetoCompound (const Context &context, int columns, int rows) const
 
const TypeapplyQualifiers (const Context &context, ModifierFlags *modifierFlags, Position pos) const
 
std::unique_ptr< ExpressioncoerceExpression (std::unique_ptr< Expression > expr, const Context &context) const
 
bool checkForOutOfRangeLiteral (const Context &context, const Expression &expr) const
 
bool checkForOutOfRangeLiteral (const Context &context, double value, Position pos) const
 
bool checkIfUsableInArray (const Context &context, Position arrayPos) const
 
SKSL_INT convertArraySize (const Context &context, Position arrayPos, std::unique_ptr< Expression > size) const
 
SKSL_INT convertArraySize (const Context &context, Position arrayPos, Position sizePos, SKSL_INT size) const
 
- Public Member Functions inherited from SkSL::Symbol
 Symbol (Position pos, Kind kind, std::string_view name, const Type *type=nullptr)
 
 ~Symbol () override
 
std::unique_ptr< Expressioninstantiate (const Context &context, Position pos) const
 
const Typetype () const
 
Kind kind () const
 
std::string_view name () const
 
void setName (std::string_view newName)
 
- Public Member Functions inherited from SkSL::IRNode
virtual ~IRNode ()
 
 IRNode (const IRNode &)=delete
 
IRNodeoperator= (const IRNode &)=delete
 
Position position () const
 
void setPosition (Position p)
 
template<typename T >
bool is () const
 
template<typename T >
const Tas () const
 
template<typename T >
Tas ()
 

Static Public Member Functions

static std::unique_ptr< TypeMakeArrayType (const Context &context, std::string_view name, const Type &componentType, int columns)
 
static std::unique_ptr< TypeMakeAliasType (std::string_view name, const Type &targetType)
 
static std::unique_ptr< TypeMakeGenericType (const char *name, SkSpan< const Type *const > types, const Type *slotType)
 
static std::unique_ptr< TypeMakeLiteralType (const char *name, const Type &scalarType, int8_t priority)
 
static std::unique_ptr< TypeMakeMatrixType (std::string_view name, const char *abbrev, const Type &componentType, int columns, int8_t rows)
 
static std::unique_ptr< TypeMakeSamplerType (const char *name, const Type &textureType)
 
static std::unique_ptr< TypeMakeScalarType (std::string_view name, const char *abbrev, Type::NumberKind numberKind, int8_t priority, int8_t bitWidth)
 
static std::unique_ptr< TypeMakeSpecialType (const char *name, const char *abbrev, Type::TypeKind typeKind)
 
static std::unique_ptr< TypeMakeStructType (const Context &context, Position pos, std::string_view name, skia_private::TArray< Field > fields, bool interfaceBlock=false)
 
static std::unique_ptr< TypeMakeTextureType (const char *name, SpvDim_ dimensions, bool isDepth, bool isArrayedTexture, bool isMultisampled, TextureAccess textureAccess)
 
static std::unique_ptr< TypeMakeVectorType (std::string_view name, const char *abbrev, const Type &componentType, int columns)
 
static std::unique_ptr< TypeMakeAtomicType (std::string_view name, const char *abbrev)
 
- Static Public Member Functions inherited from SkSL::Poolable
static void * operator new (const size_t size)
 
static void operator delete (void *ptr)
 

Static Public Attributes

static constexpr Kind kIRNodeKind = Kind::kType
 
static constexpr int kMaxAbbrevLength = 3
 
static constexpr int kUnsizedArray = -1
 

Protected Member Functions

 Type (std::string_view name, const char *abbrev, TypeKind kind, Position pos=Position())
 
const TypeapplyPrecisionQualifiers (const Context &context, ModifierFlags *modifierFlags, Position pos) const
 
const TypeapplyAccessQualifiers (const Context &context, ModifierFlags *modifierFlags, Position pos) const
 
bool isInRootSymbolTable () const
 
virtual int structNestingDepth () const
 
- Protected Member Functions inherited from SkSL::IRNode
 IRNode (Position position, int kind)
 

Additional Inherited Members

- Public Attributes inherited from SkSL::IRNode
Position fPosition
 
- Protected Attributes inherited from SkSL::IRNode
int fKind
 

Detailed Description

Represents a type, such as int or float4.

Definition at line 94 of file SkSLType.h.

Member Enumeration Documentation

◆ NumberKind

enum class SkSL::Type::NumberKind : int8_t
strong
Enumerator
kFloat 
kSigned 
kUnsigned 
kBoolean 
kNonnumeric 

Definition at line 122 of file SkSLType.h.

◆ TextureAccess

enum class SkSL::Type::TextureAccess : int8_t
strong
Enumerator
kSample 
kRead 
kWrite 
kReadWrite 

Definition at line 130 of file SkSLType.h.

130 : int8_t {
131 kSample, // `kSample` access level allows both sampling and reading
132 kRead,
133 kWrite,
135 };

◆ TypeKind

enum class SkSL::Type::TypeKind : int8_t
strong
Enumerator
kArray 
kAtomic 
kGeneric 
kLiteral 
kMatrix 
kOther 
kSampler 
kSeparateSampler 
kScalar 
kStruct 
kTexture 
kVector 
kVoid 
kColorFilter 
kShader 
kBlender 

Definition at line 101 of file SkSLType.h.

Constructor & Destructor Documentation

◆ Type() [1/2]

SkSL::Type::Type ( const Type other)
delete

◆ Type() [2/2]

SkSL::Type::Type ( std::string_view  name,
const char *  abbrev,
TypeKind  kind,
Position  pos = Position() 
)
inlineprotected

Definition at line 639 of file SkSLType.h.

640 : INHERITED(pos, kIRNodeKind, name)
641 , fTypeKind(kind) {
642 SkASSERT(strlen(abbrev) <= kMaxAbbrevLength);
643 strcpy(fAbbreviatedName, abbrev);
644 }
SkPoint pos
#define SkASSERT(cond)
Definition SkAssert.h:116
std::string_view name() const
Definition SkSLSymbol.h:51
Kind kind() const
Definition SkSLSymbol.h:47
static constexpr Kind kIRNodeKind
Definition SkSLType.h:96
static constexpr int kMaxAbbrevLength
Definition SkSLType.h:97

Member Function Documentation

◆ abbreviatedName()

const char * SkSL::Type::abbreviatedName ( ) const
inline

Returns an abbreviated name of the type, meant for name-mangling. (e.g. float4x4 -> f44)

Definition at line 276 of file SkSLType.h.

276 {
277 return fAbbreviatedName;
278 }

◆ applyAccessQualifiers()

const Type * SkSL::Type::applyAccessQualifiers ( const Context context,
ModifierFlags modifierFlags,
Position  pos 
) const
protected

Definition at line 1014 of file SkSLType.cpp.

1016 {
1017 ModifierFlags accessQualifiers = *modifierFlags & (ModifierFlag::kReadOnly |
1019
1020 // We're going to return a whole new type, so the modifier bits must be cleared out.
1021 *modifierFlags &= ~(ModifierFlag::kReadOnly |
1023
1024 if (this->matches(*context.fTypes.fTexture2D)) {
1025 // We require all texture2Ds to be qualified with `readonly` or `writeonly`.
1026 // (Read-write textures are not yet supported in WGSL.)
1027 if (accessQualifiers == ModifierFlag::kReadOnly) {
1028 return context.fTypes.fReadOnlyTexture2D.get();
1029 }
1030 if (accessQualifiers == ModifierFlag::kWriteOnly) {
1031 return context.fTypes.fWriteOnlyTexture2D.get();
1032 }
1033 context.fErrors->error(
1034 pos,
1035 accessQualifiers
1036 ? "'readonly' and 'writeonly' qualifiers cannot be combined"
1037 : "'texture2D' requires a 'readonly' or 'writeonly' access qualifier");
1038 return this;
1039 }
1040
1041 if (accessQualifiers) {
1042 context.fErrors->error(pos, "type '" + this->displayName() + "' does not support "
1043 "qualifier '" + accessQualifiers.description() + "'");
1044 }
1045
1046 return this;
1047}
bool matches(const Type &other) const
Definition SkSLType.h:269
std::string displayName() const
Definition SkSLType.h:234

◆ applyPrecisionQualifiers()

const Type * SkSL::Type::applyPrecisionQualifiers ( const Context context,
ModifierFlags modifierFlags,
Position  pos 
) const
protected

Definition at line 945 of file SkSLType.cpp.

947 {
948 ModifierFlags precisionQualifiers = *modifierFlags & (ModifierFlag::kHighp |
951 if (precisionQualifiers == ModifierFlag::kNone) {
952 // No precision qualifiers here. Return the type as-is.
953 return this;
954 }
955
956 if (!ProgramConfig::IsRuntimeEffect(context.fConfig->fKind)) {
957 // We want to discourage precision modifiers internally. Instead, use the type that
958 // corresponds to the precision you need. (e.g. half vs float, short vs int)
959 context.fErrors->error(pos, "precision qualifiers are not allowed");
960 return context.fTypes.fPoison.get();
961 }
962
963 if (SkPopCount(precisionQualifiers.value()) > 1) {
964 context.fErrors->error(pos, "only one precision qualifier can be used");
965 return context.fTypes.fPoison.get();
966 }
967
968 // We're going to return a whole new type, so the modifier bits can be cleared out.
969 *modifierFlags &= ~(ModifierFlag::kHighp |
972
973 const Type& component = this->componentType();
974 if (component.highPrecision()) {
975 if (precisionQualifiers & ModifierFlag::kHighp) {
976 // Type is already high precision, and we are requesting high precision. Return as-is.
977 return this;
978 }
979
980 // SkSL doesn't support low precision, so `lowp` is interpreted as medium precision.
981 // Ascertain the mediump equivalent type for this type, if any.
982 const Type* mediumpType;
983 switch (component.numberKind()) {
985 mediumpType = context.fTypes.fHalf.get();
986 break;
987
989 mediumpType = context.fTypes.fShort.get();
990 break;
991
993 mediumpType = context.fTypes.fUShort.get();
994 break;
995
996 default:
997 mediumpType = context.fTypes.fPoison.get();
998 break;
999 }
1000
1001 if (mediumpType) {
1002 // Convert the mediump component type into the final vector/matrix/array type as needed.
1003 return this->isArray()
1004 ? context.fSymbolTable->addArrayDimension(context, mediumpType, this->columns())
1005 : &mediumpType->toCompound(context, this->columns(), this->rows());
1006 }
1007 }
1008
1009 context.fErrors->error(pos, "type '" + this->displayName() +
1010 "' does not support precision qualifiers");
1011 return context.fTypes.fPoison.get();
1012}
static int SkPopCount(uint32_t n)
Definition SkMathPriv.h:136
virtual bool isArray() const
Definition SkSLType.h:532
virtual int rows() const
Definition SkSLType.h:438
virtual const Type & componentType() const
Definition SkSLType.h:404
virtual int columns() const
Definition SkSLType.h:429
static bool IsRuntimeEffect(ProgramKind kind)

◆ applyQualifiers()

const Type * SkSL::Type::applyQualifiers ( const Context context,
ModifierFlags modifierFlags,
Position  pos 
) const

Returns a type which honors the precision and access-level qualifiers set in ModifierFlags. For example:

  • Modifier mediump + Type float2: Type half2
  • Modifier readonly + Type texture2D: Type readonlyTexture2D Generates an error if the qualifiers don't make sense (highp bool, writeonly MyStruct)

Definition at line 936 of file SkSLType.cpp.

938 {
939 const Type* type;
940 type = this->applyPrecisionQualifiers(context, modifierFlags, pos);
941 type = type->applyAccessQualifiers(context, modifierFlags, pos);
942 return type;
943}
const Type & type() const
Definition SkSLSymbol.h:42
const Type * applyPrecisionQualifiers(const Context &context, ModifierFlags *modifierFlags, Position pos) const
Definition SkSLType.cpp:945
const Type * applyAccessQualifiers(const Context &context, ModifierFlags *modifierFlags, Position pos) const

◆ as() [1/2]

template<typename T >
T & SkSL::Type::as ( )
inline

Definition at line 216 of file SkSLType.h.

216 {
217 SkASSERT(this->is<T>());
218 return static_cast<T&>(*this);
219 }
#define T

◆ as() [2/2]

template<typename T >
const T & SkSL::Type::as ( ) const
inline

Definition at line 210 of file SkSLType.h.

210 {
211 SkASSERT(this->is<T>());
212 return static_cast<const T&>(*this);
213 }

◆ bitWidth()

virtual int SkSL::Type::bitWidth ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::LiteralType, SkSL::ScalarType, SkSL::MatrixType, and SkSL::VectorType.

Definition at line 574 of file SkSLType.h.

574 {
575 return 0;
576 }

◆ canCoerceTo()

bool SkSL::Type::canCoerceTo ( const Type other,
bool  allowNarrowing 
) const
inline

Returns true if an instance of this type can be freely coerced (implicitly converted) to another type.

Definition at line 388 of file SkSLType.h.

388 {
389 return this->coercionCost(other).isPossible(allowNarrowing);
390 }
CoercionCost coercionCost(const Type &other) const
Definition SkSLType.cpp:899
bool isPossible(bool allowNarrowing) const
Definition SkSLType.h:44

◆ checkForOutOfRangeLiteral() [1/2]

bool SkSL::Type::checkForOutOfRangeLiteral ( const Context context,
const Expression expr 
) const

Detects any IntLiterals in the expression which can't fit in this type.

Definition at line 1262 of file SkSLType.cpp.

1262 {
1263 bool foundError = false;
1264 const Type& baseType = this->componentType();
1265 if (baseType.isNumber()) {
1266 // Replace constant expressions with their corresponding values.
1267 const Expression* valueExpr = ConstantFolder::GetConstantValueForVariable(expr);
1268 if (valueExpr->supportsConstantValues()) {
1269 // Iterate over every constant subexpression in the value.
1270 int numSlots = valueExpr->type().slotCount();
1271 for (int slot = 0; slot < numSlots; ++slot) {
1272 std::optional<double> slotVal = valueExpr->getConstantValue(slot);
1273 // Check for Literal values that are out of range for the base type.
1274 if (slotVal.has_value() &&
1275 baseType.checkForOutOfRangeLiteral(context, *slotVal, valueExpr->fPosition)) {
1276 foundError = true;
1277 }
1278 }
1279 }
1280 }
1281
1282 // We don't need range checks for floats or booleans; any matched-type value is acceptable.
1283 return foundError;
1284}
static const Expression * GetConstantValueForVariable(const Expression &value)

◆ checkForOutOfRangeLiteral() [2/2]

bool SkSL::Type::checkForOutOfRangeLiteral ( const Context context,
double  value,
Position  pos 
) const

Checks if value can fit in this type. The type must be scalar.

Definition at line 1286 of file SkSLType.cpp.

1286 {
1287 SkASSERT(this->isScalar());
1288 if (!this->isNumber()) {
1289 return false;
1290 }
1291 if (value >= this->minimumValue() && value <= this->maximumValue()) {
1292 return false;
1293 }
1294 // We found a value that can't fit in our type. Flag it as an error.
1295 context.fErrors->error(pos, SkSL::String::printf("value is out of range for type '%s': %.0f",
1296 this->displayName().c_str(),
1297 value));
1298 return true;
1299}
bool isNumber() const
Definition SkSLType.h:304
virtual bool isScalar() const
Definition SkSLType.h:512
virtual double maximumValue() const
Definition SkSLType.h:449
virtual double minimumValue() const
Definition SkSLType.h:444
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1

◆ checkIfUsableInArray()

bool SkSL::Type::checkIfUsableInArray ( const Context context,
Position  arrayPos 
) const

Reports errors and returns false if this type cannot be used as the base type for an array.

Definition at line 1301 of file SkSLType.cpp.

1301 {
1302 if (this->isArray()) {
1303 context.fErrors->error(arrayPos, "multi-dimensional arrays are not supported");
1304 return false;
1305 }
1306 if (this->isVoid()) {
1307 context.fErrors->error(arrayPos, "type 'void' may not be used in an array");
1308 return false;
1309 }
1310 if (this->isOpaque() && !this->isAtomic()) {
1311 context.fErrors->error(arrayPos, "opaque type '" + std::string(this->name()) +
1312 "' may not be used in an array");
1313 return false;
1314 }
1315 return true;
1316}
bool isAtomic() const
Definition SkSLType.h:508
bool isOpaque() const
Definition SkSLType.h:353
bool isVoid() const
Definition SkSLType.h:496

◆ clone()

const Type * SkSL::Type::clone ( const Context context,
SymbolTable symbolTable 
) const

Creates a clone of this Type, if needed, and inserts it into a different symbol table.

Definition at line 1185 of file SkSLType.cpp.

1185 {
1186 // Many types are built-ins, and exist in every SymbolTable by default.
1187 if (this->isInRootSymbolTable()) {
1188 return this;
1189 }
1190 // If we are compiling a program, and the type comes from the program's module, it is safe to
1191 // assume that the type is in-scope anywhere in the program without actually recursing through
1192 // the SymbolTable hierarchy to prove it.
1193 if (!context.fConfig->fIsBuiltinCode && this->isBuiltin()) {
1194 return this;
1195 }
1196 // Even if the type isn't a built-in, it might already exist in the SymbolTable. Search by name.
1197 const Symbol* existingSymbol = symbolTable->find(this->name());
1198 if (existingSymbol != nullptr) {
1199 const Type* existingType = &existingSymbol->as<Type>();
1200 SkASSERT(existingType->typeKind() == this->typeKind());
1201 return existingType;
1202 }
1203 // This type actually needs to be cloned into the destination SymbolTable.
1204 switch (this->typeKind()) {
1205 case TypeKind::kArray: {
1206 return symbolTable->addArrayDimension(context, &this->componentType(), this->columns());
1207 }
1208 case TypeKind::kStruct: {
1209 // We are cloning an existing struct, so there's no need to call MakeStructType and
1210 // fully error-check it again.
1211 const std::string* name = symbolTable->takeOwnershipOfString(std::string(this->name()));
1212 SkSpan<const Field> fieldSpan = this->fields();
1213 return symbolTable->add(
1214 context,
1215 std::make_unique<StructType>(this->fPosition,
1216 *name,
1217 TArray<Field>(fieldSpan.data(), fieldSpan.size()),
1218 this->structNestingDepth(),
1219 /*interfaceBlock=*/this->isInterfaceBlock(),
1220 /*isBuiltin=*/context.fConfig->fIsBuiltinCode));
1221 }
1222 default:
1223 SkDEBUGFAILF("don't know how to clone type '%s'", this->description().c_str());
1224 return nullptr;
1225 }
1226}
#define SkDEBUGFAILF(fmt,...)
Definition SkAssert.h:119
Position fPosition
Definition SkSLIRNode.h:109
Symbol(Position pos, Kind kind, std::string_view name, const Type *type=nullptr)
Definition SkSLSymbol.h:31
bool isInRootSymbolTable() const
Definition SkSLType.h:655
virtual SkSpan< const Field > fields() const
Definition SkSLType.h:469
std::string description() const override
Definition SkSLType.h:238
TypeKind typeKind() const
Definition SkSLType.h:283
constexpr T * data() const
Definition SkSpan_impl.h:94
constexpr size_t size() const
Definition SkSpan_impl.h:95

◆ coerceExpression()

std::unique_ptr< Expression > SkSL::Type::coerceExpression ( std::unique_ptr< Expression expr,
const Context context 
) const

Coerces the passed-in expression to this type. If the types are incompatible, reports an error and returns null.

Definition at line 1228 of file SkSLType.cpp.

1229 {
1230 if (!expr || expr->isIncomplete(context)) {
1231 return nullptr;
1232 }
1233 if (expr->type().matches(*this)) {
1234 return expr;
1235 }
1236
1237 const Position pos = expr->fPosition;
1238 const ProgramSettings& settings = context.fConfig->fSettings;
1239 if (!expr->coercionCost(*this).isPossible(settings.fAllowNarrowingConversions)) {
1240 context.fErrors->error(pos, "expected '" + this->displayName() + "', but found '" +
1241 expr->type().displayName() + "'");
1242 return nullptr;
1243 }
1244
1245 if (this->isScalar()) {
1246 return ConstructorScalarCast::Make(context, pos, *this, std::move(expr));
1247 }
1248 if (this->isVector() || this->isMatrix()) {
1249 return ConstructorCompoundCast::Make(context, pos, *this, std::move(expr));
1250 }
1251 if (this->isArray()) {
1252 return ConstructorArrayCast::Make(context, pos, *this, std::move(expr));
1253 }
1254 context.fErrors->error(pos, "cannot construct '" + this->displayName() + "'");
1255 return nullptr;
1256}
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
virtual bool isVector() const
Definition SkSLType.h:524
virtual bool isMatrix() const
Definition SkSLType.h:528

◆ coercibleTypes()

virtual SkSpan< const Type *const > SkSL::Type::coercibleTypes ( ) const
inlinevirtual

For generic types, returns the types that this generic type can substitute for.

Reimplemented in SkSL::AliasType, and SkSL::GenericType.

Definition at line 476 of file SkSLType.h.

476 {
477 SkDEBUGFAIL("Internal error: not a generic type");
478 return {};
479 }
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118

◆ coercionCost()

CoercionCost SkSL::Type::coercionCost ( const Type other) const

Determines the "cost" of coercing (implicitly converting) this type to another type. The cost is a number with no particular meaning other than that lower costs are preferable to higher costs. Returns INT_MAX if the coercion is not possible.

Definition at line 899 of file SkSLType.cpp.

899 {
900 if (this->matches(other)) {
901 return CoercionCost::Free();
902 }
903 if (this->typeKind() == other.typeKind() &&
904 (this->isVector() || this->isMatrix() || this->isArray())) {
905 // Vectors/matrices/arrays of the same size can be coerced if their component type can be.
906 if (this->isMatrix() && (this->rows() != other.rows())) {
908 }
909 if (this->columns() != other.columns()) {
911 }
912 return this->componentType().coercionCost(other.componentType());
913 }
914 if (this->isNumber() && other.isNumber()) {
915 if (this->isLiteral() && this->isInteger()) {
916 return CoercionCost::Free();
917 } else if (this->numberKind() != other.numberKind()) {
919 } else if (other.priority() >= this->priority()) {
920 return CoercionCost::Normal(other.priority() - this->priority());
921 } else {
922 return CoercionCost::Narrowing(this->priority() - other.priority());
923 }
924 }
925 if (fTypeKind == TypeKind::kGeneric) {
927 for (size_t i = 0; i < types.size(); i++) {
928 if (types[i]->matches(other)) {
929 return CoercionCost::Normal((int) i + 1);
930 }
931 }
932 }
934}
virtual int priority() const
Definition SkSLType.h:379
virtual bool isLiteral() const
Definition SkSLType.h:516
virtual NumberKind numberKind() const
Definition SkSLType.h:290
virtual SkSpan< const Type *const > coercibleTypes() const
Definition SkSLType.h:476
bool isInteger() const
Definition SkSLType.h:339
static CoercionCost Impossible()
Definition SkSLType.h:42
static CoercionCost Narrowing(int cost)
Definition SkSLType.h:41
static CoercionCost Free()
Definition SkSLType.h:39
static CoercionCost Normal(int cost)
Definition SkSLType.h:40

◆ columns()

virtual int SkSL::Type::columns ( ) const
inlinevirtual

For matrices and vectors, returns the number of columns (e.g. both mat3 and float3 return 3). For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1. For all other types, causes an assertion failure.

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::LiteralType, SkSL::ScalarType, SkSL::MatrixType, and SkSL::VectorType.

Definition at line 429 of file SkSLType.h.

429 {
430 SkDEBUGFAIL("type does not have columns");
431 return -1;
432 }

◆ columnType()

const Type & SkSL::Type::columnType ( const Context context) const
inline

For matrix types, returns the type of a single column (m[n]). Asserts for all other types.

Definition at line 411 of file SkSLType.h.

411 {
412 return this->componentType().toCompound(context, this->rows(), /*rows=*/1);
413 }
const Type & toCompound(const Context &context, int columns, int rows) const

◆ componentType()

virtual const Type & SkSL::Type::componentType ( ) const
inlinevirtual

For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component type of Float). For arrays, returns the base type. For all other types, returns the type itself.

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::MatrixType, and SkSL::VectorType.

Definition at line 404 of file SkSLType.h.

404 {
405 return *this;
406 }

◆ convertArraySize() [1/2]

SKSL_INT SkSL::Type::convertArraySize ( const Context context,
Position  arrayPos,
Position  sizePos,
SKSL_INT  size 
) const

Definition at line 1333 of file SkSLType.cpp.

1336 {
1337 if (!this->checkIfUsableInArray(context, arrayPos)) {
1338 // `checkIfUsableInArray` will generate an error for us.
1339 return 0;
1340 }
1341 if (size <= 0) {
1342 context.fErrors->error(sizePos, "array size must be positive");
1343 return 0;
1344 }
1345 // We can't get a meaningful slot count if the interior type contains an unsized array; we'll
1346 // assert if we try. Unsized arrays should only occur in a handful of limited cases (e.g. an
1347 // interface block with a trailing buffer), and will never be valid in a runtime effect.
1348 if (!this->isOrContainsUnsizedArray()) {
1349 if (SkSafeMath::Mul(this->slotCount(), size) > kVariableSlotLimit) {
1350 context.fErrors->error(sizePos, "array size is too large");
1351 return 0;
1352 }
1353 }
1354 return size;
1355}
bool checkIfUsableInArray(const Context &context, Position arrayPos) const
virtual size_t slotCount() const
Definition SkSLType.h:457
virtual bool isOrContainsUnsizedArray() const
Definition SkSLType.h:582
static size_t Mul(size_t x, size_t y)
static constexpr int kVariableSlotLimit
Definition SkSLDefines.h:45
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259

◆ convertArraySize() [2/2]

SKSL_INT SkSL::Type::convertArraySize ( const Context context,
Position  arrayPos,
std::unique_ptr< Expression size 
) const

Verifies that the expression is a valid constant array size for this type. Returns the array size, or reports errors and returns zero if the expression isn't a valid literal value.

Definition at line 1318 of file SkSLType.cpp.

1320 {
1321 size = context.fTypes.fInt->coerceExpression(std::move(size), context);
1322 if (!size) {
1323 return 0;
1324 }
1326 if (!ConstantFolder::GetConstantInt(*size, &count)) {
1327 context.fErrors->error(size->fPosition, "array size must be an integer");
1328 return 0;
1329 }
1330 return this->convertArraySize(context, arrayPos, size->fPosition, count);
1331}
int count
int64_t SKSL_INT
Definition SkSLDefines.h:16
static bool GetConstantInt(const Expression &value, SKSL_INT *out)
SKSL_INT convertArraySize(const Context &context, Position arrayPos, std::unique_ptr< Expression > size) const

◆ description()

std::string SkSL::Type::description ( ) const
inlineoverridevirtual

Implements SkSL::IRNode.

Definition at line 238 of file SkSLType.h.

238 {
239 return this->displayName();
240 }

◆ dimensions()

virtual SpvDim_ SkSL::Type::dimensions ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::TextureType, and SkSL::SamplerType.

Definition at line 481 of file SkSLType.h.

481 {
482 SkDEBUGFAIL("Internal error: not a texture type");
483 return SpvDim1D;
484 }
@ SpvDim1D
Definition spirv.h:142

◆ displayName()

std::string SkSL::Type::displayName ( ) const
inline

Definition at line 234 of file SkSLType.h.

234 {
235 return std::string(this->scalarTypeForLiteral().name());
236 }
virtual const Type & scalarTypeForLiteral() const
Definition SkSLType.h:520

◆ fields()

virtual SkSpan< const Field > SkSL::Type::fields ( ) const
inlinevirtual

Reimplemented in SkSL::StructType.

Definition at line 469 of file SkSLType.h.

469 {
470 SK_ABORT("Internal error: not a struct");
471 }
#define SK_ABORT(message,...)
Definition SkAssert.h:70

◆ getArrayName()

std::string SkSL::Type::getArrayName ( int  arraySize) const

Converts a component type and a size (float, 10) into an array name ("float[10]").

Definition at line 756 of file SkSLType.cpp.

756 {
757 std::string_view name = this->name();
758 if (arraySize == kUnsizedArray) {
759 return String::printf("%.*s[]", (int)name.size(), name.data());
760 }
761 return String::printf("%.*s[%d]", (int)name.size(), name.data(), arraySize);
762}
static constexpr int kUnsizedArray
Definition SkSLType.h:99

◆ hasPrecision()

bool SkSL::Type::hasPrecision ( ) const
inline

Definition at line 566 of file SkSLType.h.

566 {
567 return this->componentType().isNumber() || this->isSampler();
568 }
bool isSampler() const
Definition SkSLType.h:504

◆ highPrecision()

bool SkSL::Type::highPrecision ( ) const
inline

Definition at line 570 of file SkSLType.h.

570 {
571 return this->bitWidth() >= 32;
572 }
virtual int bitWidth() const
Definition SkSLType.h:574

◆ is()

template<typename T >
bool SkSL::Type::is ( ) const
inline

Definition at line 205 of file SkSLType.h.

205 {
206 return this->typeKind() == T::kTypeKind;
207 }

◆ isAllowedInES2() [1/2]

virtual bool SkSL::Type::isAllowedInES2 ( ) const
inlinevirtual

Returns true if this type is legal to use in a strict-ES2 program.

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::ScalarType, SkSL::AtomicType, SkSL::MatrixType, SkSL::StructType, and SkSL::VectorType.

Definition at line 246 of file SkSLType.h.

246 {
247 return true;
248 }

◆ isAllowedInES2() [2/2]

bool SkSL::Type::isAllowedInES2 ( const Context context) const

Returns true if the program supports this type. Strict ES2 programs can't use ES3 types.

Definition at line 1258 of file SkSLType.cpp.

1258 {
1259 return !context.fConfig->strictES2Mode() || this->isAllowedInES2();
1260}
virtual bool isAllowedInES2() const
Definition SkSLType.h:246

◆ isAllowedInUniform()

virtual bool SkSL::Type::isAllowedInUniform ( Position errorPosition = nullptr) const
inlinevirtual

Returns true if this type is legal to use as a uniform. If false is returned, the errorPosition field may be populated; if it is, this position can be used to emit an extra diagnostic "caused by: <a field>" for nested types. Note that runtime effects enforce additional, much stricter rules about uniforms; these limitations are not handled here.

Reimplemented in SkSL::ScalarType, SkSL::AtomicType, SkSL::ArrayType, SkSL::StructType, and SkSL::VectorType.

Definition at line 257 of file SkSLType.h.

257 {
258 // We don't allow samplers, textures or atomics to be marked as uniforms.
259 // This rules out all opaque types.
260 return !this->isOpaque();
261 }

◆ isArray()

virtual bool SkSL::Type::isArray ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::ArrayType.

Definition at line 532 of file SkSLType.h.

532 {
533 return false;
534 }

◆ isArrayedTexture()

virtual bool SkSL::Type::isArrayedTexture ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::TextureType, and SkSL::SamplerType.

Definition at line 491 of file SkSLType.h.

491 {
492 SkDEBUGFAIL("Internal error: not a texture type");
493 return false;
494 }

◆ isAtomic()

bool SkSL::Type::isAtomic ( ) const
inline

Definition at line 508 of file SkSLType.h.

508 {
509 return this->typeKind() == TypeKind::kAtomic;
510 }

◆ isBoolean()

bool SkSL::Type::isBoolean ( ) const
inline

Returns true if this type is a bool.

Definition at line 297 of file SkSLType.h.

297 {
298 return this->numberKind() == NumberKind::kBoolean;
299 }

◆ isBuiltin()

virtual bool SkSL::Type::isBuiltin ( ) const
inlinevirtual

Returns true if this type is known to come from BuiltinTypes, or is declared in a module. If this returns true, the Type will always be available in the root SymbolTable and never needs to be copied to migrate an Expression from one location to another. If it returns false, the Type might not exist in a separate SymbolTable and you'll need to consider cloning it.

Reimplemented in SkSL::ArrayType, and SkSL::StructType.

Definition at line 230 of file SkSLType.h.

230 {
231 return true;
232 }

◆ isDepth()

virtual bool SkSL::Type::isDepth ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::TextureType, and SkSL::SamplerType.

Definition at line 486 of file SkSLType.h.

486 {
487 SkDEBUGFAIL("Internal error: not a texture type");
488 return false;
489 }

◆ isEffectChild()

bool SkSL::Type::isEffectChild ( ) const
inline

Definition at line 550 of file SkSLType.h.

550 {
551 return fTypeKind == TypeKind::kColorFilter ||
552 fTypeKind == TypeKind::kShader ||
553 fTypeKind == TypeKind::kBlender;
554 }

◆ isFloat()

bool SkSL::Type::isFloat ( ) const
inline

Returns true if this is a floating-point scalar type (float or half).

Definition at line 318 of file SkSLType.h.

318 {
319 return this->numberKind() == NumberKind::kFloat;
320 }

◆ isGeneric()

bool SkSL::Type::isGeneric ( ) const
inline

Definition at line 500 of file SkSLType.h.

500 {
501 return fTypeKind == TypeKind::kGeneric;
502 }

◆ isInRootSymbolTable()

bool SkSL::Type::isInRootSymbolTable ( ) const
inlineprotected

Only structs and arrays can be created in code; all other types exist in the root.

Definition at line 655 of file SkSLType.h.

655 {
656 return !(this->isArray() || this->isStruct());
657 }
virtual bool isStruct() const
Definition SkSLType.h:540

◆ isInteger()

bool SkSL::Type::isInteger ( ) const
inline

Returns true if this is a signed or unsigned integer.

Definition at line 339 of file SkSLType.h.

339 {
340 switch (this->numberKind()) {
343 return true;
344 default:
345 return false;
346 }
347 }

◆ isInterfaceBlock()

virtual bool SkSL::Type::isInterfaceBlock ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::StructType.

Definition at line 544 of file SkSLType.h.

544 {
545 return false;
546 }

◆ isLiteral()

virtual bool SkSL::Type::isLiteral ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::LiteralType.

Definition at line 516 of file SkSLType.h.

516 {
517 return false;
518 }

◆ isMatrix()

virtual bool SkSL::Type::isMatrix ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::MatrixType.

Definition at line 528 of file SkSLType.h.

528 {
529 return false;
530 }

◆ isMultisampled()

virtual bool SkSL::Type::isMultisampled ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::TextureType, and SkSL::SamplerType.

Definition at line 556 of file SkSLType.h.

556 {
557 SkDEBUGFAIL("not a texture type");
558 return false;
559 }

◆ isNumber()

bool SkSL::Type::isNumber ( ) const
inline

Returns true if this is a numeric scalar type.

Definition at line 304 of file SkSLType.h.

304 {
305 switch (this->numberKind()) {
309 return true;
310 default:
311 return false;
312 }
313 }

◆ isOpaque()

bool SkSL::Type::isOpaque ( ) const
inline

Returns true if this is an "opaque type" (an external object which the shader references in some fashion). https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Opaque_types

Definition at line 353 of file SkSLType.h.

353 {
354 switch (fTypeKind) {
362 return true;
363 default:
364 return false;
365 }
366 }

◆ isOrContainsArray()

virtual bool SkSL::Type::isOrContainsArray ( ) const
inlinevirtual

Reimplemented in SkSL::ArrayType, and SkSL::StructType.

Definition at line 578 of file SkSLType.h.

578 {
579 return false;
580 }

◆ isOrContainsAtomic()

virtual bool SkSL::Type::isOrContainsAtomic ( ) const
inlinevirtual

Reimplemented in SkSL::ArrayType, SkSL::AtomicType, and SkSL::StructType.

Definition at line 586 of file SkSLType.h.

586 {
587 return false;
588 }

◆ isOrContainsUnsizedArray()

virtual bool SkSL::Type::isOrContainsUnsizedArray ( ) const
inlinevirtual

Reimplemented in SkSL::ArrayType, and SkSL::StructType.

Definition at line 582 of file SkSLType.h.

582 {
583 return false;
584 }

◆ isSampler()

bool SkSL::Type::isSampler ( ) const
inline

Definition at line 504 of file SkSLType.h.

504 {
505 return fTypeKind == TypeKind::kSampler;
506 }

◆ isScalar()

virtual bool SkSL::Type::isScalar ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::LiteralType, and SkSL::ScalarType.

Definition at line 512 of file SkSLType.h.

512 {
513 return false;
514 }

◆ isSigned()

bool SkSL::Type::isSigned ( ) const
inline

Returns true if this is a signed scalar type (int or short).

Definition at line 325 of file SkSLType.h.

325 {
326 return this->numberKind() == NumberKind::kSigned;
327 }

◆ isStorageTexture()

bool SkSL::Type::isStorageTexture ( ) const
inline

Returns true if this is a storage texture.

Definition at line 371 of file SkSLType.h.

371 {
372 return fTypeKind == TypeKind::kTexture && this->dimensions() != SpvDimSubpassData;
373 }
virtual SpvDim_ dimensions() const
Definition SkSLType.h:481
@ SpvDimSubpassData
Definition spirv.h:148

◆ isStruct()

virtual bool SkSL::Type::isStruct ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::StructType.

Definition at line 540 of file SkSLType.h.

540 {
541 return false;
542 }

◆ isUnsigned()

bool SkSL::Type::isUnsigned ( ) const
inline

Returns true if this is an unsigned scalar type (uint or ushort).

Definition at line 332 of file SkSLType.h.

332 {
333 return this->numberKind() == NumberKind::kUnsigned;
334 }

◆ isUnsizedArray()

virtual bool SkSL::Type::isUnsizedArray ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::ArrayType.

Definition at line 536 of file SkSLType.h.

536 {
537 return false;
538 }

◆ isVector()

virtual bool SkSL::Type::isVector ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, and SkSL::VectorType.

Definition at line 524 of file SkSLType.h.

524 {
525 return false;
526 }

◆ isVoid()

bool SkSL::Type::isVoid ( ) const
inline

Definition at line 496 of file SkSLType.h.

496 {
497 return fTypeKind == TypeKind::kVoid;
498 }

◆ MakeAliasType()

std::unique_ptr< Type > SkSL::Type::MakeAliasType ( std::string_view  name,
const Type targetType 
)
static

Creates an alias which maps to another type.

Definition at line 764 of file SkSLType.cpp.

764 {
765 return std::make_unique<AliasType>(std::move(name), targetType);
766}

◆ MakeArrayType()

std::unique_ptr< Type > SkSL::Type::MakeArrayType ( const Context context,
std::string_view  name,
const Type componentType,
int  columns 
)
static

Creates an array type. columns may be kUnsizedArray.

Definition at line 768 of file SkSLType.cpp.

771 {
772 return std::make_unique<ArrayType>(std::move(name), componentType.abbreviatedName(),
773 componentType, columns, context.fConfig->fIsBuiltinCode);
774}
const char * abbreviatedName() const
Definition SkSLType.h:276

◆ MakeAtomicType()

std::unique_ptr< Type > SkSL::Type::MakeAtomicType ( std::string_view  name,
const char *  abbrev 
)
static

Create an atomic type.

Definition at line 807 of file SkSLType.cpp.

807 {
808 return std::make_unique<AtomicType>(name, abbrev);
809}

◆ MakeGenericType()

std::unique_ptr< Type > SkSL::Type::MakeGenericType ( const char *  name,
SkSpan< const Type *const >  types,
const Type slotType 
)
static

Create a generic type which maps to the listed types–e.g. $genType is a generic type which can match float, float2, float3 or float4.

Definition at line 776 of file SkSLType.cpp.

778 {
779 return std::make_unique<GenericType>(name, types, slotType);
780}
virtual const Type & slotType(size_t) const
Definition SkSLType.h:465

◆ MakeLiteralType()

std::unique_ptr< Type > SkSL::Type::MakeLiteralType ( const char *  name,
const Type scalarType,
int8_t  priority 
)
static

Create a type for literal scalars.

Definition at line 782 of file SkSLType.cpp.

783 {
784 return std::make_unique<LiteralType>(name, scalarType, priority);
785}

◆ MakeMatrixType()

std::unique_ptr< Type > SkSL::Type::MakeMatrixType ( std::string_view  name,
const char *  abbrev,
const Type componentType,
int  columns,
int8_t  rows 
)
static

Create a matrix type.

Definition at line 787 of file SkSLType.cpp.

788 {
789 return std::make_unique<MatrixType>(name, abbrev, componentType, columns, rows);
790}

◆ MakeSamplerType()

std::unique_ptr< Type > SkSL::Type::MakeSamplerType ( const char *  name,
const Type textureType 
)
static

Create a sampler type.

Definition at line 792 of file SkSLType.cpp.

792 {
793 return std::make_unique<SamplerType>(name, textureType);
794}
virtual const Type & textureType() const
Definition SkSLType.h:419

◆ MakeScalarType()

std::unique_ptr< Type > SkSL::Type::MakeScalarType ( std::string_view  name,
const char *  abbrev,
Type::NumberKind  numberKind,
int8_t  priority,
int8_t  bitWidth 
)
static

Create a scalar type.

Definition at line 801 of file SkSLType.cpp.

803 {
804 return std::make_unique<ScalarType>(name, abbrev, numberKind, priority, bitWidth);
805}

◆ MakeSpecialType()

std::unique_ptr< Type > SkSL::Type::MakeSpecialType ( const char *  name,
const char *  abbrev,
Type::TypeKind  typeKind 
)
static

Create a "special" type with the given name, abbreviation, and TypeKind.

Definition at line 796 of file SkSLType.cpp.

797 {
798 return std::unique_ptr<Type>(new Type(name, abbrev, typeKind));
799}

◆ MakeStructType()

std::unique_ptr< Type > SkSL::Type::MakeStructType ( const Context context,
Position  pos,
std::string_view  name,
skia_private::TArray< Field fields,
bool  interfaceBlock = false 
)
static

Creates a struct type with the given fields. Reports an error if the struct is not well-formed.

Definition at line 811 of file SkSLType.cpp.

815 {
816 const char* const structOrIB = interfaceBlock ? "interface block" : "struct";
817 const char* const aStructOrIB = interfaceBlock ? "an interface block" : "a struct";
818
819 if (fields.empty()) {
820 context.fErrors->error(pos, std::string(structOrIB) + " '" + std::string(name) +
821 "' must contain at least one field");
822 }
823 size_t slots = 0;
824
826 for (const Field& field : fields) {
827 // Add this field name to our set; if the set doesn't grow, we found a duplicate.
828 int numFieldNames = fieldNames.count();
829 fieldNames.add(field.fName);
830 if (fieldNames.count() == numFieldNames) {
831 context.fErrors->error(field.fPosition, "field '" + std::string(field.fName) +
832 "' was already defined in the same " +
833 std::string(structOrIB) + " ('" +
834 std::string(name) + "')");
835 }
836 if (field.fModifierFlags != ModifierFlag::kNone) {
837 std::string desc = field.fModifierFlags.description();
838 context.fErrors->error(field.fPosition, "modifier '" + desc + "' is not permitted on " +
839 std::string(aStructOrIB) + " field");
840 }
841 if (field.fLayout.fFlags & LayoutFlag::kBinding) {
842 context.fErrors->error(field.fPosition, "layout qualifier 'binding' is not permitted "
843 "on " + std::string(aStructOrIB) + " field");
844 }
845 if (field.fLayout.fFlags & LayoutFlag::kSet) {
846 context.fErrors->error(field.fPosition, "layout qualifier 'set' is not permitted on " +
847 std::string(aStructOrIB) + " field");
848 }
849
850 if (field.fType->isVoid()) {
851 context.fErrors->error(field.fPosition, "type 'void' is not permitted in " +
852 std::string(aStructOrIB));
853 }
854 if (field.fType->isOpaque() && !field.fType->isAtomic()) {
855 context.fErrors->error(field.fPosition, "opaque type '" + field.fType->displayName() +
856 "' is not permitted in " +
857 std::string(aStructOrIB));
858 }
859 if (field.fType->isOrContainsUnsizedArray()) {
860 if (!interfaceBlock) {
861 // Reject unsized arrays anywhere in structs.
862 context.fErrors->error(field.fPosition, "unsized arrays are not permitted here");
863 }
864 } else {
865 // If we haven't already exceeded the struct size limit...
866 if (slots < kVariableSlotLimit) {
867 // ... see if this field causes us to exceed the size limit.
868 slots = SkSafeMath::Add(slots, field.fType->slotCount());
869 if (slots >= kVariableSlotLimit) {
870 context.fErrors->error(pos, std::string(structOrIB) + " is too large");
871 }
872 }
873 }
874 }
875 int nestingDepth = 0;
876 for (const Field& field : fields) {
877 nestingDepth = std::max(nestingDepth, field.fType->structNestingDepth());
878 }
879 if (nestingDepth >= kMaxStructDepth) {
880 context.fErrors->error(pos, std::string(structOrIB) + " '" + std::string(name) +
881 "' is too deeply nested");
882 }
883 return std::make_unique<StructType>(pos, name, std::move(fields), nestingDepth + 1,
884 interfaceBlock, context.fConfig->fIsBuiltinCode);
885}
static size_t Add(size_t x, size_t y)
int count() const
Definition SkTHash.h:564
void add(T item)
Definition SkTHash.h:573
static constexpr int kMaxStructDepth
Definition SkSLType.cpp:40

◆ MakeTextureType()

std::unique_ptr< Type > SkSL::Type::MakeTextureType ( const char *  name,
SpvDim_  dimensions,
bool  isDepth,
bool  isArrayedTexture,
bool  isMultisampled,
TextureAccess  textureAccess 
)
static

Create a texture type.

Definition at line 887 of file SkSLType.cpp.

889 {
890 return std::make_unique<TextureType>(name, dimensions, isDepth, isArrayedTexture,
892}
virtual bool isDepth() const
Definition SkSLType.h:486
virtual TextureAccess textureAccess() const
Definition SkSLType.h:561
virtual bool isMultisampled() const
Definition SkSLType.h:556
virtual bool isArrayedTexture() const
Definition SkSLType.h:491

◆ MakeVectorType()

std::unique_ptr< Type > SkSL::Type::MakeVectorType ( std::string_view  name,
const char *  abbrev,
const Type componentType,
int  columns 
)
static

Create a vector type.

Definition at line 894 of file SkSLType.cpp.

895 {
896 return std::make_unique<VectorType>(name, abbrev, componentType, columns);
897}

◆ matches()

bool SkSL::Type::matches ( const Type other) const
inline

Returns true if these types are equal after alias resolution.

Definition at line 269 of file SkSLType.h.

269 {
270 return this->resolve().name() == other.resolve().name();
271 }
virtual const Type & resolve() const
Definition SkSLType.h:264

◆ maximumValue()

virtual double SkSL::Type::maximumValue ( ) const
inlinevirtual

Reimplemented in SkSL::LiteralType, and SkSL::ScalarType.

Definition at line 449 of file SkSLType.h.

449 {
450 SkDEBUGFAIL("type does not have a maximum value");
451 return +INFINITY;
452 }

◆ minimumValue()

virtual double SkSL::Type::minimumValue ( ) const
inlinevirtual

Returns the minimum value that can fit in the type.

Reimplemented in SkSL::LiteralType, and SkSL::ScalarType.

Definition at line 444 of file SkSLType.h.

444 {
445 SkDEBUGFAIL("type does not have a minimum value");
446 return -INFINITY;
447 }

◆ numberKind()

virtual NumberKind SkSL::Type::numberKind ( ) const
inlinevirtual

Returns the NumberKind of this type (always kNonnumeric for non-scalar values).

Reimplemented in SkSL::AliasType, SkSL::LiteralType, and SkSL::ScalarType.

Definition at line 290 of file SkSLType.h.

290 {
292 }

◆ priority()

virtual int SkSL::Type::priority ( ) const
inlinevirtual

Returns the "priority" of a number type, in order of float > half > int > short. When operating on two number types, the result is the higher-priority type.

Reimplemented in SkSL::AliasType, SkSL::LiteralType, and SkSL::ScalarType.

Definition at line 379 of file SkSLType.h.

379 {
380 SkDEBUGFAIL("not a number type");
381 return -1;
382 }

◆ resolve()

virtual const Type & SkSL::Type::resolve ( ) const
inlinevirtual

If this is an alias, returns the underlying type, otherwise returns this.

Reimplemented in SkSL::AliasType.

Definition at line 264 of file SkSLType.h.

264 {
265 return *this;
266 }

◆ rows()

virtual int SkSL::Type::rows ( ) const
inlinevirtual

For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vectors and scalars, returns 1. For all other types, causes an assertion failure.

Reimplemented in SkSL::AliasType, SkSL::LiteralType, SkSL::ScalarType, SkSL::MatrixType, and SkSL::VectorType.

Definition at line 438 of file SkSLType.h.

438 {
439 SkDEBUGFAIL("type does not have rows");
440 return -1;
441 }

◆ scalarTypeForLiteral()

virtual const Type & SkSL::Type::scalarTypeForLiteral ( ) const
inlinevirtual

Reimplemented in SkSL::LiteralType.

Definition at line 520 of file SkSLType.h.

520 {
521 return *this;
522 }

◆ slotCount()

virtual size_t SkSL::Type::slotCount ( ) const
inlinevirtual

Returns the number of scalars needed to hold this type.

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::LiteralType, SkSL::ScalarType, SkSL::MatrixType, SkSL::StructType, and SkSL::VectorType.

Definition at line 457 of file SkSLType.h.

457 {
458 return 0;
459 }

◆ slotType()

virtual const Type & SkSL::Type::slotType ( size_t  ) const
inlinevirtual

Returns the type of the value in the nth slot. For scalar, vector and matrix types, should always match componentType().

Reimplemented in SkSL::AliasType, SkSL::ArrayType, SkSL::LiteralType, SkSL::ScalarType, SkSL::AtomicType, SkSL::MatrixType, SkSL::TextureType, SkSL::SamplerType, SkSL::StructType, SkSL::VectorType, and SkSL::GenericType.

Definition at line 465 of file SkSLType.h.

465 {
466 return *this;
467 }

◆ structNestingDepth()

virtual int SkSL::Type::structNestingDepth ( ) const
inlineprotectedvirtual

If the type is a struct, returns the depth of the struct's most deeply-nested field.

Reimplemented in SkSL::StructType.

Definition at line 660 of file SkSLType.h.

660 {
661 return 0;
662 }

◆ textureAccess()

virtual TextureAccess SkSL::Type::textureAccess ( ) const
inlinevirtual

Reimplemented in SkSL::AliasType, SkSL::TextureType, and SkSL::SamplerType.

Definition at line 561 of file SkSLType.h.

561 {
562 SkDEBUGFAIL("not a texture type");
564 }

◆ textureType()

virtual const Type & SkSL::Type::textureType ( ) const
inlinevirtual

For texture samplers, returns the type of texture it samples (e.g., sampler2D has a texture type of texture2D).

Reimplemented in SkSL::SamplerType.

Definition at line 419 of file SkSLType.h.

419 {
420 SkDEBUGFAIL("not a sampler type");
421 return *this;
422 }

◆ toCompound()

const Type & SkSL::Type::toCompound ( const Context context,
int  columns,
int  rows 
) const

Returns the corresponding vector or matrix type with the specified number of columns and rows.

Definition at line 1049 of file SkSLType.cpp.

1049 {
1050 SkASSERT(this->isScalar());
1051 if (columns == 1 && rows == 1) {
1052 return *this;
1053 }
1054 if (this->matches(*context.fTypes.fFloat) || this->matches(*context.fTypes.fFloatLiteral)) {
1055 switch (rows) {
1056 case 1:
1057 switch (columns) {
1058 case 1: return *context.fTypes.fFloat;
1059 case 2: return *context.fTypes.fFloat2;
1060 case 3: return *context.fTypes.fFloat3;
1061 case 4: return *context.fTypes.fFloat4;
1062 default: SK_ABORT("unsupported vector column count (%d)", columns);
1063 }
1064 case 2:
1065 switch (columns) {
1066 case 2: return *context.fTypes.fFloat2x2;
1067 case 3: return *context.fTypes.fFloat3x2;
1068 case 4: return *context.fTypes.fFloat4x2;
1069 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1070 }
1071 case 3:
1072 switch (columns) {
1073 case 2: return *context.fTypes.fFloat2x3;
1074 case 3: return *context.fTypes.fFloat3x3;
1075 case 4: return *context.fTypes.fFloat4x3;
1076 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1077 }
1078 case 4:
1079 switch (columns) {
1080 case 2: return *context.fTypes.fFloat2x4;
1081 case 3: return *context.fTypes.fFloat3x4;
1082 case 4: return *context.fTypes.fFloat4x4;
1083 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1084 }
1085 default: SK_ABORT("unsupported row count (%d)", rows);
1086 }
1087 } else if (this->matches(*context.fTypes.fHalf)) {
1088 switch (rows) {
1089 case 1:
1090 switch (columns) {
1091 case 1: return *context.fTypes.fHalf;
1092 case 2: return *context.fTypes.fHalf2;
1093 case 3: return *context.fTypes.fHalf3;
1094 case 4: return *context.fTypes.fHalf4;
1095 default: SK_ABORT("unsupported vector column count (%d)", columns);
1096 }
1097 case 2:
1098 switch (columns) {
1099 case 2: return *context.fTypes.fHalf2x2;
1100 case 3: return *context.fTypes.fHalf3x2;
1101 case 4: return *context.fTypes.fHalf4x2;
1102 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1103 }
1104 case 3:
1105 switch (columns) {
1106 case 2: return *context.fTypes.fHalf2x3;
1107 case 3: return *context.fTypes.fHalf3x3;
1108 case 4: return *context.fTypes.fHalf4x3;
1109 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1110 }
1111 case 4:
1112 switch (columns) {
1113 case 2: return *context.fTypes.fHalf2x4;
1114 case 3: return *context.fTypes.fHalf3x4;
1115 case 4: return *context.fTypes.fHalf4x4;
1116 default: SK_ABORT("unsupported matrix column count (%d)", columns);
1117 }
1118 default: SK_ABORT("unsupported row count (%d)", rows);
1119 }
1120 } else if (this->matches(*context.fTypes.fInt) || this->matches(*context.fTypes.fIntLiteral)) {
1121 switch (rows) {
1122 case 1:
1123 switch (columns) {
1124 case 1: return *context.fTypes.fInt;
1125 case 2: return *context.fTypes.fInt2;
1126 case 3: return *context.fTypes.fInt3;
1127 case 4: return *context.fTypes.fInt4;
1128 default: SK_ABORT("unsupported vector column count (%d)", columns);
1129 }
1130 default: SK_ABORT("unsupported row count (%d)", rows);
1131 }
1132 } else if (this->matches(*context.fTypes.fShort)) {
1133 switch (rows) {
1134 case 1:
1135 switch (columns) {
1136 case 1: return *context.fTypes.fShort;
1137 case 2: return *context.fTypes.fShort2;
1138 case 3: return *context.fTypes.fShort3;
1139 case 4: return *context.fTypes.fShort4;
1140 default: SK_ABORT("unsupported vector column count (%d)", columns);
1141 }
1142 default: SK_ABORT("unsupported row count (%d)", rows);
1143 }
1144 } else if (this->matches(*context.fTypes.fUInt)) {
1145 switch (rows) {
1146 case 1:
1147 switch (columns) {
1148 case 1: return *context.fTypes.fUInt;
1149 case 2: return *context.fTypes.fUInt2;
1150 case 3: return *context.fTypes.fUInt3;
1151 case 4: return *context.fTypes.fUInt4;
1152 default: SK_ABORT("unsupported vector column count (%d)", columns);
1153 }
1154 default: SK_ABORT("unsupported row count (%d)", rows);
1155 }
1156 } else if (this->matches(*context.fTypes.fUShort)) {
1157 switch (rows) {
1158 case 1:
1159 switch (columns) {
1160 case 1: return *context.fTypes.fUShort;
1161 case 2: return *context.fTypes.fUShort2;
1162 case 3: return *context.fTypes.fUShort3;
1163 case 4: return *context.fTypes.fUShort4;
1164 default: SK_ABORT("unsupported vector column count (%d)", columns);
1165 }
1166 default: SK_ABORT("unsupported row count (%d)", rows);
1167 }
1168 } else if (this->matches(*context.fTypes.fBool)) {
1169 switch (rows) {
1170 case 1:
1171 switch (columns) {
1172 case 1: return *context.fTypes.fBool;
1173 case 2: return *context.fTypes.fBool2;
1174 case 3: return *context.fTypes.fBool3;
1175 case 4: return *context.fTypes.fBool4;
1176 default: SK_ABORT("unsupported vector column count (%d)", columns);
1177 }
1178 default: SK_ABORT("unsupported row count (%d)", rows);
1179 }
1180 }
1181 SkDEBUGFAILF("unsupported toCompound type %s", this->description().c_str());
1182 return *context.fTypes.fVoid;
1183}

◆ typeKind()

TypeKind SkSL::Type::typeKind ( ) const
inline

Returns the category (scalar, vector, matrix, etc.) of this type.

Definition at line 283 of file SkSLType.h.

283 {
284 return fTypeKind;
285 }

Member Data Documentation

◆ kIRNodeKind

constexpr Kind SkSL::Type::kIRNodeKind = Kind::kType
inlinestaticconstexpr

Definition at line 96 of file SkSLType.h.

◆ kMaxAbbrevLength

constexpr int SkSL::Type::kMaxAbbrevLength = 3
inlinestaticconstexpr

Definition at line 97 of file SkSLType.h.

◆ kUnsizedArray

constexpr int SkSL::Type::kUnsizedArray = -1
inlinestaticconstexpr

Definition at line 99 of file SkSLType.h.


The documentation for this class was generated from the following files: