Overview
========

SkSL ("Skia Shading Language") is a variant of GLSL which is used as Skia's
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.


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
translating them to "varying" and "attribute" as appropriate). Be aware of the
following differences between SkSL and GLSL:

* "@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.
* 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.
* no #version statement is required, and will be ignored if present
* the output color is sk_FragColor (do not declare it)
* use sk_VertexID instead of gl_VertexID
* the fragment coordinate is sk_FragCoord, and is always relative to the upper
  left.
* lowp, mediump, and highp are always permitted (but will only be respected if
  you run on a device which supports them)
* 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
  have to be expressed "vec2(x, y) * 4.0". There is no performance penalty for
  this, as the number is converted to a float at compile time)
* type suffixes on numbers (1.0f, 0xFFu) are both unnecessary and unsupported
* 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.
* Use texture() instead of textureProj(), e.g. texture(sampler2D, vec3) is
  equivalent to GLSL's textureProj(sampler2D, vec3)
* 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.


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)
    @headerEnd         (at the end of the .h file)
    @class             (in the .h file, inside the class declaration)
    @cpp               (in the .cpp file)
    @cppEnd            (at the end of 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)
    @coordTransform(<sampler>)
                       (the matrix to attach to the named sampler2D's
                        GrCoordTransform)
    @samplerParams(<sampler>)
                       (the sampler params to attach to the named sampler2D)
* 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.
