2016-10-12 13:39:56 +00:00
|
|
|
Overview
|
|
|
|
========
|
|
|
|
|
2017-03-31 17:56:23 +00:00
|
|
|
SkSL ("Skia Shading Language") is a variant of GLSL which is used as Skia's
|
2016-10-12 13:39:56 +00:00
|
|
|
internal shading language. SkSL is, at its heart, a single standardized version
|
|
|
|
of GLSL which avoids all of the various version and dialect differences found
|
|
|
|
in GLSL "in the wild", but it does bring a few of its own changes to the table.
|
|
|
|
|
|
|
|
Skia uses the SkSL compiler to convert SkSL code to GLSL, GLSL ES, or SPIR-V
|
|
|
|
before handing it over to the graphics driver.
|
|
|
|
|
2017-06-29 14:03:38 +00:00
|
|
|
|
2016-10-12 13:39:56 +00:00
|
|
|
Differences from GLSL
|
|
|
|
=====================
|
|
|
|
|
|
|
|
SkSL is based on GLSL 4.5. For the most part, write SkSL exactly as you would
|
|
|
|
desktop GLSL, and the SkSL compiler will take care of version and dialect
|
|
|
|
differences (for instance, you always use "in" and "out", and skslc will handle
|
2017-03-31 17:56:23 +00:00
|
|
|
translating them to "varying" and "attribute" as appropriate). Be aware of the
|
2016-10-12 13:39:56 +00:00
|
|
|
following differences between SkSL and GLSL:
|
|
|
|
|
2017-05-10 19:06:17 +00:00
|
|
|
* "@if" and "@switch" are static versions of if and switch. They behave exactly
|
|
|
|
the same as if and switch in all respects other than it being a compile-time
|
|
|
|
error to use a non-constant expression as a test.
|
2016-11-21 20:59:48 +00:00
|
|
|
* GLSL caps can be referenced via the syntax 'sk_Caps.<name>', e.g.
|
|
|
|
sk_Caps.sampleVariablesSupport. The value will be a constant boolean or int,
|
|
|
|
as appropriate. As SkSL supports constant folding and branch elimination, this
|
|
|
|
means that an 'if' statement which statically queries a cap will collapse down
|
|
|
|
to the chosen branch, meaning that:
|
|
|
|
|
|
|
|
if (sk_Caps.externalTextureSupport)
|
|
|
|
do_something();
|
|
|
|
else
|
|
|
|
do_something_else();
|
|
|
|
|
|
|
|
will compile as if you had written either 'do_something();' or
|
|
|
|
'do_something_else();', depending on whether that cap is enabled or not.
|
2016-10-13 20:25:34 +00:00
|
|
|
* no #version statement is required, and will be ignored if present
|
2016-10-12 13:39:56 +00:00
|
|
|
* the output color is sk_FragColor (do not declare it)
|
2017-02-07 19:53:32 +00:00
|
|
|
* use sk_VertexID instead of gl_VertexID
|
2017-02-09 22:01:22 +00:00
|
|
|
* the fragment coordinate is sk_FragCoord, and is always relative to the upper
|
|
|
|
left.
|
2017-03-31 17:56:23 +00:00
|
|
|
* lowp, mediump, and highp are always permitted (but will only be respected if
|
2017-02-09 22:01:22 +00:00
|
|
|
you run on a device which supports them)
|
2016-10-12 13:39:56 +00:00
|
|
|
* you do not need to include ".0" to make a number a float (meaning that
|
|
|
|
"vec2(x, y) * 4" is perfectly legal in SkSL, unlike GLSL where it would often
|
2017-03-31 17:56:23 +00:00
|
|
|
have to be expressed "vec2(x, y) * 4.0". There is no performance penalty for
|
2016-10-12 13:39:56 +00:00
|
|
|
this, as the number is converted to a float at compile time)
|
|
|
|
* type suffixes on numbers (1.0f, 0xFFu) are both unnecessary and unsupported
|
2017-02-09 18:57:14 +00:00
|
|
|
* creating a smaller vector from a larger vector (e.g. vec2(vec3(1))) is
|
|
|
|
intentionally disallowed, as it is just a wordier way of performing a swizzle.
|
|
|
|
Use swizzles instead.
|
2016-11-28 17:03:26 +00:00
|
|
|
* Use texture() instead of textureProj(), e.g. texture(sampler2D, vec3) is
|
|
|
|
equivalent to GLSL's textureProj(sampler2D, vec3)
|
2016-10-12 13:39:56 +00:00
|
|
|
* some built-in functions and one or two rarely-used language features are not
|
|
|
|
yet supported (sorry!)
|
|
|
|
|
|
|
|
SkSL is still under development, and is expected to diverge further from GLSL
|
|
|
|
over time.
|
2017-06-29 14:03:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
SkSL Fragment Processors
|
|
|
|
========================
|
|
|
|
|
|
|
|
An extension of SkSL allows for the creation of fragment processors in pure
|
|
|
|
SkSL. The program defines its inputs similarly to a normal SkSL program (with
|
|
|
|
'in' and 'uniform' variables), but the 'main()' function represents only this
|
|
|
|
fragment processor's portion of the overall fragment shader.
|
|
|
|
|
|
|
|
Within an '.fp' fragment processor file:
|
|
|
|
|
|
|
|
* C++ code can be embedded in sections of the form:
|
|
|
|
|
|
|
|
@section_name { <arbitrary C++ code> }
|
|
|
|
|
|
|
|
Supported section are:
|
|
|
|
@header (in the .h file, outside the class declaration)
|
|
|
|
@class (in the .h file, inside the class declaration)
|
|
|
|
@cpp (in the .cpp file)
|
|
|
|
@constructorParams (extra parameters to the constructor, comma-separated)
|
|
|
|
@constructor (replaces the default constructor)
|
|
|
|
@initializers (constructor initializer list, comma-separated)
|
|
|
|
@emitCode (extra code for the emitCode function)
|
|
|
|
@fields (extra private fields, each terminated with a semicolon)
|
|
|
|
@make (replaces the default Make function)
|
|
|
|
@setData(<pdman>) (extra code for the setData function, where <pdman> is
|
|
|
|
the name of the GrGLSLProgramDataManager)
|
|
|
|
@test(<testData>) (the body of the TestCreate function, where <testData> is
|
|
|
|
the name of the GrProcessorTestData* parameter)
|
|
|
|
* global 'in' variables represent data passed to the fragment processor at
|
|
|
|
construction time. These variables become constructor parameters and are
|
|
|
|
stored in fragment processor fields. vec2s map to SkPoints, and vec4s map to
|
|
|
|
SkRects (in x, y, width, height) order.
|
|
|
|
* 'uniform' variables become, as one would expect, top-level uniforms. By
|
|
|
|
default they do not have any data provided to them; you will need to provide
|
|
|
|
them with data via the @setData section.
|
|
|
|
* 'in uniform' variables are uniforms that are automatically wired up to
|
|
|
|
fragment processor constructor parameters
|
|
|
|
* the 'sk_TransformedCoords2D' array provides access to 2D transformed
|
|
|
|
coordinates. sk_TransformedCoords2D[0] is equivalent to calling
|
|
|
|
fragBuilder->ensureCoords2D(args.fTransformedCoords[0]) (and the result is
|
|
|
|
cached, so you need not worry about using the value repeatedly).
|
|
|
|
* 'colorSpaceXform' is a supported type. It is reflected within SkSL as a mat4,
|
|
|
|
and on the C++ side as sk_sp<GrColorSpaceXform>.
|
|
|
|
* the texture() function can be passed a colorSpaceXform as an additional
|
|
|
|
parameter
|
|
|
|
* Uniform variables support an additional 'when' layout key.
|
|
|
|
'layout(when=foo) uniform int x;' means that this uniform will only be
|
|
|
|
emitted when the 'foo' expression is true.
|
|
|
|
* 'in' variables support an additional 'key' layout key.
|
|
|
|
'layout(key) uniform int x;' means that this uniform should be included in
|
|
|
|
the program's key. Matrix variables additionally support 'key=identity',
|
|
|
|
which causes the key to consider only whether or not the matrix is an
|
|
|
|
identity matrix.
|