The SkSL binary format was originally created for internal use, to store our built-in include files in a format which required less processing time than the original text versions.
This improved compiler startup time and memory footprint, but as the format was purpose-built for encoding our include files, it could not encode a normal SkSL program. It only supported the subset of SkSL required by the include files, had no means of referring to external symbols, and had not been tested outside of being used to encode our small handful of include files.
To both improve testability and to support the needs of clients requiring a binary SkSL format, this feature has been extended to support arbitrary SkSL files. Full test coverage is achieved by encoding our entire corpus of SkSL tests to binary, decoding them, and ensuring that the decoded output program matches the unmodified original program.
A binary SkSL file has the following header:
Type | Field Name |
---|---|
uint16 | version |
uint16 | stringLength |
char[stringLength] | stringData |
The version number is incremented whenever the file format changes. This document describes version 11.
stringLength
is the total length of all of the string data in the file, including the length bytes of the strings, but not counting the stringLength
field itself. Each string consists of a uint8
length followed by the string’s characters, which are not null terminated.
The header is immediately followed by a sequence of one or more commands encoding the contents. A typical SkSL binary will contain exactly one kProgram_Command
.
The following types may appear as data members of commands. All numbers are stored in little endian byte ordering.
Name | Description |
---|---|
int8 | a signed 8 bit integer |
int16 | a signed 16 bit integer |
int32 | a signed 32 bit integer |
uint8 | an unsigned 8 bit integer |
uint16 | an unsigned 16 bit integer |
uint32 | an unsigned 32 bit integer |
float | a 32 bit IEEE floating point number |
bool | a single byte with the value either 0 (false ) or 1 (true ) |
String | a uint8 length, followed by a uint16 offset [^1] |
ProgramKind | a uint8 mapping to a value in the SkSL::ProgramKind enum |
SkSLVersion | a uint8 mapping to a value in the SkSL::Version enum |
VariableStorage | a uint8 mapping to a value in the SkSL::VariableStorage enum |
Operator | a uint8 mapping to a value in the SkSL::Operator::Kind enum |
FieldAccessOwnerKind | a uint8 mapping to a value in the SkSL::FieldAccessOwnerKind enum |
VariableRefKind | a uint8 mapping to a value in the SkSL::VariableRefKind enum |
SwizzleComponent | a uint8 mapping to a value in the SkSL::SwizzleComponent::Type enum |
Symbol | an instance of any command in the Symbol category |
SymbolId | a uint16 ID specified by a Symbol category command [^2] |
Expression | an instance of any command in the Expressions category |
ProgramElement | an instance of any command in the ProgramElements category |
Statement | an instance of any command in the Statements category |
Type | an instance of one of the “Type” Symbol commands [^3] |
Layout | an instance of the one of the Layout commands [^4] |
Modifiers | an instance of one of the Modifiers commands [^5] |
k*_Command | an instance of the specified command |
[^1]: The offset of a String
is relative to the beginning of the stringData
field of the header.
[^2]: There is one exception to SymbolId
s referring to Symbol commands: if a SymbolId
is kBuiltin_Symbol
, the SymbolId
is followed by a String representing the name of the symbol.
[^3]: The Type symbol commands are kArrayType_Command
, kStructType_Command
, or a kSymbolRef_Command
referring to an existing type.
[^4]: The “Layout” commands are kBuiltinLayout_Command
, kDefaultLayout_Command
, and kLayout_Command
.
[^5]: The “Modifiers” commands are kDefaultModifiers_Command
, kModifiers8Bit_Command
, and kModifiers_Command)
.
Each command consists of a single uint8
identifying the command, followed by its data.
Type | Field Name |
---|---|
int16 | builtin |
An SkSL::Layout
with the specified builtin value, but all other fields left with their default values.
An SkSL::Layout
with every field set to its default value.
An SkSL::Modifiers
with every field set to its default value.
Type | Field Name |
---|---|
ProgramElement[] | elements |
kElementsComplete_Command |
The end of the elements array is indicated by the presence of kElementsComplete_Command
.
Signifies the end of a list of elements.
Type | Field Name |
---|---|
int32 | flags |
int8 | location |
int16 | offset |
int16 | binding |
int8 | index |
int8 | set |
int16 | builtin |
int8 | inputAttachmentIndex |
Represents an SkSL::Layout
with all fields specified.
Type | Field Name |
---|---|
Layout | layout |
uint8 | flags |
A shortened version of Modifiers
which only represents the least significant 8 bits of flags
, leaving the other bits as zero.
Type | Field Name |
---|---|
Layout | layout |
uint32 | flags |
Type | Field Name |
---|---|
ProgramKind | programKind |
SkSLVersion | requiredVersion |
kSymbolTable_Command | symbolTable |
kElements_Command | elements |
bool | useFlipRTUniform |
useFlipRTUniform
refers to a field in Program::Inputs
.
Type | Field Name |
---|---|
uint16 | ownedSymbolCount |
Symbol[ownedSymbolCount] | ownedSymbols |
uint16 | symbolCount |
SymbolID[symbolCount] | symbols |
The IDs in the symbols array do not relate to indices in ownedSymbols
, and instead refer to the IDs specified at the beginning of commands in the Symbol category.
Type | Field Name |
---|---|
SymbolId | declaration |
Statement | body |
Provides the body corresponding to a FunctionDeclaration
.
Type | Field Name |
---|---|
uint16 | declaration |
Represents a function declaration appearing in the program as a function prototype.
Type | Field Name |
---|---|
SymbolId | var |
String | typeName |
String | instanceName |
uint8 | arraySize |
An interface block. instanceName
may be zero-length to indicate the lack of an instance name. arraySize
will be zero if the instance name was not present or was not followed by an array size.
Type | Field Name |
---|---|
Type | structType |
Represents a struct definition appearing at top-level scope.
Type | Field Name |
---|---|
uint8 | parameterCount |
Variable[parameterCount] | parameters |
FunctionDeclaration | decl |
FunctionDefinition | defn |
Represents a function from Program.fSharedElements
.
Type | Field Name |
---|---|
kVarDeclaration_Command | decl |
A VarDeclaration
appearing in global scope.
Type | Field Name |
---|---|
uint16 | id |
Type | componentType |
uint8 | count |
Type | Field Name |
---|---|
SymbolId | ownerId |
uint8 | index |
Symbol referring to a particular field of a StructType
. Unlike other symbols, Field does not have its own ID; references to a Field are compiled in terms of the owner’s ID.
Type | Field Name |
---|---|
uint16 | id |
Modifiers | modifiers |
String | name |
uint8 | parameterCount |
SymbolId[parameterCount] | parameters |
Type | returnType |
Type | Field Name |
---|---|
uint16 | id |
String | name |
uint8 | fieldCount |
Field[fieldCount] | fields |
The Field
type referenced in this command is:
struct Field { Modifiers modifiers; String name; Type type; };
Type | Field Name |
---|---|
SymbolId | id |
Refers to a Symbol which has already been written by another command.
Type | Field Name |
---|---|
uint16 | id |
uint8 | count |
FunctionDeclaration[count] | functions |
Type | Field Name |
---|---|
uint16 | id |
Modifiers | modifiers |
String | name |
Type | type |
VariableStorage | storage |
Type | Field Name |
---|---|
Expression | left |
Operator | op |
Expression | right |
Type | type |
Represents a binary operator applied to two expressions.
Type | Field Name |
---|---|
bool | value |
Represents a literal true
or false
value.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorArray
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorArrayCast
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorCompound
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorCompoundCast
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorDiagonalMatrix
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorMatrixResize
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorScalarCast
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorSplat
.
Type | Field Name |
---|---|
Type | type |
uint8 | argCount |
Expression[argCount] | arguments |
Represents an instance of SkSL::ConstructorStruct
.
Type | Field Name |
---|---|
Expression | base |
uint8 | index |
FieldAccessOwnerKind | ownerKind |
A reference to the index
’th field of the base
struct.
Type | Field Name |
---|---|
float | value |
Represents a floating point literal.
Type | Field Name |
---|---|
Type | type |
SymbolId | function |
uint8 | argCount |
Expression[argCount] | arguments |
Represents a call to function(arguments...)
.
Type | Field Name |
---|---|
Expression | base |
Expression | index |
Represents the expression base[index]
.
Type | Field Name |
---|---|
int32 | value |
Represents an integer literal.
Type | Field Name |
---|---|
Operator | op |
Expression | operand |
Represents applying the postfix operator op
to operand
.
Type | Field Name |
---|---|
Operator | op |
Expression | operand |
Represents applying the prefix operator op
to operand
.
Type | Field Name |
---|---|
String | name |
Represents a field of sk_Caps
, such as “integerSupport”
.
Type | Field Name |
---|---|
Expression | base |
uint8 | componentCount |
SwizzleComponent[componentCount] | components |
Represents the swizzle base.components
.
Type | Field Name |
---|---|
Expression | test |
Expression | ifTrue |
Expression | ifFalse |
Represents the ternary expression test ? ifTrue : ifFalse
.
Type | Field Name |
---|---|
SymbolID | var |
VariableRefKind | refKind |
Represents a reference to the variable var
.
Type | Field Name |
---|---|
kSymbolTable_Command | symbolTable |
uint8 | statementCount |
Statement[statementCount] | statements |
uint8 | blockKind |
A block of statements.
A break
statement.
A continue
statement.
A discard
statement.
Type | Field Name |
---|---|
Statement | stmt |
Expression | test |
Represents do stmt; while(test);
.
Type | Field Name |
---|---|
Expression | expression |
Represents the statement expression;
.
Type | Field Name |
---|---|
Statement | initializer |
Expression | test |
Expression | next |
Statement | body |
SymbolTable | symbols |
Represents for (initializer; test; next) body;
. test
, next
, and body
may all be kVoid_Command
to represent their absence.
Type | Field Name |
---|---|
bool | isStatic |
Expression | test |
Statement | ifTrue |
Statement | ifFalse |
Represents if (test) ifTrue; else ifFalse;
(or @if
, if isStatic
is true). ifFalse
may be kVoid_Command
to represent the absence of an else
statement.
Represents an empty statement (a bare semicolon).
Type | Field Name |
---|---|
Expression | value |
Represents the statement return value;
. value
may be kVoid_Command
to represent the absence of a return value.
Type | Field Name |
---|---|
bool | isStatic |
kSymbolTable_Command | symbols |
Expression | value |
uint8 | caseCount |
Case[caseCount] | cases |
The Case
type referenced in this command is:
struct Case { bool isDefault; (when !isDefault) Expression value; uint8 statementCount; Statement statements[statementCount]; };
Represents a switch
or @switch
statement on value. Each case begins with a bool
identifying whether or not it is the default case; the default case does not contain the value
field.
Type | Field Name |
---|---|
SymbolId | var |
Type | baseType |
uint8 | arraySize |
Expression | value |
Represents the variable declaration statement baseType var[arraySize] = value;
. An arraySize
of zero omits the array declaration. A value of kVoid_Command
omits the initializer.
A marker indicating that a node is not present.