1*c8dee2aaSAndroid Build Coastguard Worker--- 2*c8dee2aaSAndroid Build Coastguard Workertitle: 'SkSL & Runtime Effects' 3*c8dee2aaSAndroid Build Coastguard WorkerlinkTitle: 'SkSL' 4*c8dee2aaSAndroid Build Coastguard Worker--- 5*c8dee2aaSAndroid Build Coastguard Worker 6*c8dee2aaSAndroid Build Coastguard Worker## Overview 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker**SkSL** is Skia's 9*c8dee2aaSAndroid Build Coastguard Worker[shading language](https://en.wikipedia.org/wiki/Shading_language). 10*c8dee2aaSAndroid Build Coastguard Worker**`SkRuntimeEffect`** is a Skia C++ object that can be used to create 11*c8dee2aaSAndroid Build Coastguard Worker`SkShader`, `SkColorFilter`, and `SkBlender` objects with behavior controlled by 12*c8dee2aaSAndroid Build Coastguard WorkerSkSL code. 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard WorkerYou can experiment with SkSL at https://shaders.skia.org/. The syntax is very 15*c8dee2aaSAndroid Build Coastguard Workersimilar to GLSL. When using SkSL effects in your Skia application, there are 16*c8dee2aaSAndroid Build Coastguard Workerimportant differences (from GLSL) to remember. Most of these differences are 17*c8dee2aaSAndroid Build Coastguard Workerbecause of one basic fact: **With GPU shading languages, you are programming a 18*c8dee2aaSAndroid Build Coastguard Workerstage of the 19*c8dee2aaSAndroid Build Coastguard Worker[GPU pipeline](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview). 20*c8dee2aaSAndroid Build Coastguard WorkerWith SkSL, you are programming a stage of the Skia pipeline.** 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard WorkerIn particular, a GLSL fragment shader controls the entire behavior of the GPU 23*c8dee2aaSAndroid Build Coastguard Workerbetween the rasterizer and the blending hardware. That shader does all of the 24*c8dee2aaSAndroid Build Coastguard Workerwork to compute a color, and the color it generates is exactly what is fed to 25*c8dee2aaSAndroid Build Coastguard Workerthe fixed-function blending stage of the pipeline. 26*c8dee2aaSAndroid Build Coastguard Worker 27*c8dee2aaSAndroid Build Coastguard WorkerSkSL effects exist as part of the larger Skia pipeline. When you issue a canvas 28*c8dee2aaSAndroid Build Coastguard Workerdrawing operation, Skia (generally) assembles a single GPU fragment shader to do 29*c8dee2aaSAndroid Build Coastguard Workerall of the required work. This shader typically includes several pieces. For 30*c8dee2aaSAndroid Build Coastguard Workerexample, it might include: 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker- Evaluating whether a pixel falls inside or outside of the shape being drawn 33*c8dee2aaSAndroid Build Coastguard Worker (or on the border, where it might apply antialiasing). 34*c8dee2aaSAndroid Build Coastguard Worker- Evaluating whether a pixel falls inside or outside of the clipping region 35*c8dee2aaSAndroid Build Coastguard Worker (again, with possible antialiasing logic for border pixels). 36*c8dee2aaSAndroid Build Coastguard Worker- Logic for the `SkShader` on the `SkPaint`. The `SkShader` can actually be a 37*c8dee2aaSAndroid Build Coastguard Worker tree of objects (due to `SkShaders::Blend` and other features described 38*c8dee2aaSAndroid Build Coastguard Worker below). 39*c8dee2aaSAndroid Build Coastguard Worker- Similar logic for the `SkColorFilter` (which can also be a tree, due to 40*c8dee2aaSAndroid Build Coastguard Worker `SkColorFilters::Compose`, `SkColorFilters::Blend`, and features described 41*c8dee2aaSAndroid Build Coastguard Worker below). 42*c8dee2aaSAndroid Build Coastguard Worker- Blending code (for certain `SkBlendMode`s, or for custom blending specified 43*c8dee2aaSAndroid Build Coastguard Worker with `SkPaint::setBlender`). 44*c8dee2aaSAndroid Build Coastguard Worker- Color space conversion code, as part of Skia's [color management](/docs/user/color). 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard WorkerEven if the `SkPaint` has a complex tree of objects in the `SkShader`, 47*c8dee2aaSAndroid Build Coastguard Worker`SkColorFilter`, or `SkBlender` fields, there is still only a _single_ GPU 48*c8dee2aaSAndroid Build Coastguard Workerfragment shader. Each node in that tree creates a single function. The clipping 49*c8dee2aaSAndroid Build Coastguard Workercode and geometry code each create a function. The blending code might create a 50*c8dee2aaSAndroid Build Coastguard Workerfunction. The overall fragment shader then calls all of these functions (which 51*c8dee2aaSAndroid Build Coastguard Workermay call other functions, e.g. in the case of an `SkShader` tree). 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker**Your SkSL effect contributes a function to the GPU's fragment shader.** 54*c8dee2aaSAndroid Build Coastguard Worker 55*c8dee2aaSAndroid Build Coastguard Worker--- 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker## Evaluating (sampling) other SkShaders 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard WorkerIn GLSL, a fragment shader can sample a texture. With runtime effects, the 60*c8dee2aaSAndroid Build Coastguard Workerobject that you bind (in C++) is an `SkShader`, represented by a `shader` in 61*c8dee2aaSAndroid Build Coastguard WorkerSkSL. To make it clear that you are operating on an object that will emit its 62*c8dee2aaSAndroid Build Coastguard Workerown shader code, you don't use `sample`. Instead, the `shader` object has a 63*c8dee2aaSAndroid Build Coastguard Worker`.eval()` method. Regardless, Skia has simple methods for creating an `SkShader` 64*c8dee2aaSAndroid Build Coastguard Workerfrom an `SkImage`, so it's easy to use images in your runtime effects: 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_EvaluatingImageShader'></fiddle-embed-sk> 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard WorkerBecause the object you bind and evaluate is an `SkShader`, you can directly use 69*c8dee2aaSAndroid Build Coastguard Workerany Skia shader, without necessarily turning it into an image (texture) first. 70*c8dee2aaSAndroid Build Coastguard WorkerFor example, you can evaluate a linear gradient. In this example, there is no 71*c8dee2aaSAndroid Build Coastguard Workertexture created to hold the gradient. Skia generates a single fragment shader 72*c8dee2aaSAndroid Build Coastguard Workerthat computes the gradient color, samples from the image's texture, and then 73*c8dee2aaSAndroid Build Coastguard Workermultiplies the two together: 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_EvaluatingTwoShaders'></fiddle-embed-sk> 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard WorkerOf course, you can even invoke another runtime effect, allowing you to combine 78*c8dee2aaSAndroid Build Coastguard Workershader snippets dynamically: 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_EvaluatingNestedShaders'></fiddle-embed-sk> 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker--- 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker## Coordinate Spaces 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard WorkerTo understand how coordinates work in SkSL, you first need to understand 87*c8dee2aaSAndroid Build Coastguard Worker[how they work in Skia](/docs/user/coordinates). If you're comfortable with 88*c8dee2aaSAndroid Build Coastguard WorkerSkia's coordinate spaces, then just remember that the coordinates supplied to 89*c8dee2aaSAndroid Build Coastguard Workeryour `main()` are **local** coordinates. They will be relative to the coordinate 90*c8dee2aaSAndroid Build Coastguard Workerspace of the `SkShader`. This will match the local space of the canvas and any 91*c8dee2aaSAndroid Build Coastguard Worker`localMatrix` transformations. Additionally, if the shader is invoked by 92*c8dee2aaSAndroid Build Coastguard Workeranother, that parent shader may modify them arbitrarily. 93*c8dee2aaSAndroid Build Coastguard Worker 94*c8dee2aaSAndroid Build Coastguard WorkerIn addition, the `SkShader` produced from an `SkImage` does not use normalized 95*c8dee2aaSAndroid Build Coastguard Workercoordinates (like a texture in GLSL). It uses `(0, 0)` in the upper-left corner, 96*c8dee2aaSAndroid Build Coastguard Workerand `(w, h)` in the bottom-right corner. Normally, this is exactly what you 97*c8dee2aaSAndroid Build Coastguard Workerwant. If you're evaluating an `SkImageShader` with coordinates based on the ones 98*c8dee2aaSAndroid Build Coastguard Workerpassed to you, the scale is correct. However, if you want to adjust those 99*c8dee2aaSAndroid Build Coastguard Workercoordinates (to do some kind of re-mapping of the image), remember that the 100*c8dee2aaSAndroid Build Coastguard Workercoordinates are scaled up to the dimensions of the image: 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_CoordinateSpaces'></fiddle-embed-sk> 103*c8dee2aaSAndroid Build Coastguard Worker 104*c8dee2aaSAndroid Build Coastguard Worker--- 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker## Color Spaces 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard WorkerApplications using Skia are usually [color managed](/docs/user/color). The color 109*c8dee2aaSAndroid Build Coastguard Workerspace of a surface (destination) determines the working color space for a draw. 110*c8dee2aaSAndroid Build Coastguard WorkerSource content (like shaders, including `SkImageShader`) also have color spaces. 111*c8dee2aaSAndroid Build Coastguard WorkerBy default, inputs to your SkSL shader will be transformed to the working color 112*c8dee2aaSAndroid Build Coastguard Workerspace. Some inputs require special care to get (or inhibit) this behavior, though. 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard WorkerFirst, let's see Skia's color management in action. Here, we're drawing a portion 115*c8dee2aaSAndroid Build Coastguard Workerof the mandrill image twice. The first time, we've drawn it normally, respecting 116*c8dee2aaSAndroid Build Coastguard Workerthe color space stored in the file (this happens to be the [sRGB](https://en.wikipedia.org/wiki/SRGB) 117*c8dee2aaSAndroid Build Coastguard Workercolor space. The second time, we've assigned the Rec. 2020 color space to the image. 118*c8dee2aaSAndroid Build Coastguard WorkerThis simply tells Skia to treat the image as if the colors stored are actually in 119*c8dee2aaSAndroid Build Coastguard Workerthat color space. Skia then transforms those values from Rec. 2020 to the 120*c8dee2aaSAndroid Build Coastguard Workerdestination surface's color space (sRGB). As a result, all of the colors look more 121*c8dee2aaSAndroid Build Coastguard Workervivid. More importantly, if the image really *were* in some other color space, or 122*c8dee2aaSAndroid Build Coastguard Workerif the destination surface were in some other color space, this automatic conversion 123*c8dee2aaSAndroid Build Coastguard Workeris desirable, because it ensures content looks consistently correct on any user's 124*c8dee2aaSAndroid Build Coastguard Workerscreen. 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_ColorSpaces'></fiddle-embed-sk> 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker### Uniforms 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard WorkerSkia and SkSL doesn't know if your `uniform` variables contain colors, so it won't 131*c8dee2aaSAndroid Build Coastguard Workerautomatically apply color conversion to them. In the below example, there are two 132*c8dee2aaSAndroid Build Coastguard Workeruniforms declared: `color` and `not_a_color`. The SkSL simply fades in one of the 133*c8dee2aaSAndroid Build Coastguard Workertwo uniform "colors" horizontally, choosing a different uniform for the top and 134*c8dee2aaSAndroid Build Coastguard Workerbottom half of the shader. The code passes the same values to both uniforms, four 135*c8dee2aaSAndroid Build Coastguard Workerfloating point values `{1,0,0,1}` that represent "red". 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard WorkerTo really see the effect of automatic uniform conversion, the fiddle draws to an 138*c8dee2aaSAndroid Build Coastguard Workeroffscreen surface in the [Rec. 2020](https://en.wikipedia.org/wiki/Rec._2020) color 139*c8dee2aaSAndroid Build Coastguard Workerspace. Rec. 2020 has a very _wide gamut_, which means that it can represent more 140*c8dee2aaSAndroid Build Coastguard Workervivid colors than the common default [sRGB](https://en.wikipedia.org/wiki/SRGB) 141*c8dee2aaSAndroid Build Coastguard Workercolor space. In particular, the purest red in sRGB is fairly dull compared to pure 142*c8dee2aaSAndroid Build Coastguard Workerred in Rec. 2020. 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard WorkerTo understand what happens in this fiddle, we'll explain the steps for the two 145*c8dee2aaSAndroid Build Coastguard Workerdifferent cases. For the top half, we use `not_a_color`. Skia and SkSL don't know 146*c8dee2aaSAndroid Build Coastguard Workerthat you intend to use this as a color, so the raw floating point values you supply 147*c8dee2aaSAndroid Build Coastguard Workerare fed directly to the SkSL shader. In other words - when the SkSL executes, 148*c8dee2aaSAndroid Build Coastguard Worker`not_a_color` will contain `{1,0,0,1}`, regardless of the surface's color space. 149*c8dee2aaSAndroid Build Coastguard WorkerThis produces the most vivid red possible in the destination's color space (which 150*c8dee2aaSAndroid Build Coastguard Workerends up looking like a very bright red in this case). 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard WorkerFor the bottom half, we have declared the uniform `color` with the special syntax 153*c8dee2aaSAndroid Build Coastguard Worker`layout(color)`. That tells SkSL that this variable will be used as a color. 154*c8dee2aaSAndroid Build Coastguard Worker`layout(color)` can only be used on uniform values that are `vec3` (i.e., RGB) or 155*c8dee2aaSAndroid Build Coastguard Worker`vec4` (i.e., RGBA). In either case, the colors you supply when providing uniform data 156*c8dee2aaSAndroid Build Coastguard Workershould be unpremultiplied sRGB colors. Those colors can include values outside of 157*c8dee2aaSAndroid Build Coastguard Workerthe range `[0,1]`, if you want to supply wide gamut colors. This is the same way 158*c8dee2aaSAndroid Build Coastguard Workerthat Skia accepts and stores colors on `SkPaint`. When the SkSL executes, Skia 159*c8dee2aaSAndroid Build Coastguard Workertransforms the uniform value to the working color space. In this case, that means 160*c8dee2aaSAndroid Build Coastguard Workerthat `color` (which starts out as sRGB red) is turned into whatever values represent 161*c8dee2aaSAndroid Build Coastguard Workerthat same color in the Rec. 2020 color space. 162*c8dee2aaSAndroid Build Coastguard Worker 163*c8dee2aaSAndroid Build Coastguard WorkerThe overall effect here is to make the correctly labeled uniform much duller, but 164*c8dee2aaSAndroid Build Coastguard Workerthat is actually what you want when working with uniform colors. By labeling uniform 165*c8dee2aaSAndroid Build Coastguard Workercolors this way, your source colors (that you place in uniforms) will represent the 166*c8dee2aaSAndroid Build Coastguard Workersame, consistent color regardless of the color space of the destination surface. 167*c8dee2aaSAndroid Build Coastguard Worker 168*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_Uniforms'></fiddle-embed-sk> 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker### Raw Image Shaders 171*c8dee2aaSAndroid Build Coastguard Worker 172*c8dee2aaSAndroid Build Coastguard WorkerAlthough most images contain colors that should be color managed, some images 173*c8dee2aaSAndroid Build Coastguard Workercontain data that isn't actually colors. This includes images storing normals, 174*c8dee2aaSAndroid Build Coastguard Workermaterial properties (e.g., roughness), heightmaps, or any other purely 175*c8dee2aaSAndroid Build Coastguard Workermathematical data that happens to be stored in an image. When using these kinds 176*c8dee2aaSAndroid Build Coastguard Workerof images in SkSL, you probably want to use a *raw* image shader, created with 177*c8dee2aaSAndroid Build Coastguard Worker`SkImage::makeRawShader`. These work like regular image shaders (including 178*c8dee2aaSAndroid Build Coastguard Workerfiltering and tiling), with a few major differences: 179*c8dee2aaSAndroid Build Coastguard Worker - No color space transformation is ever applied (the color space of the image 180*c8dee2aaSAndroid Build Coastguard Worker is ignored). 181*c8dee2aaSAndroid Build Coastguard Worker - Images with an alpha type of kUnpremul are **not** automatically premultiplied. 182*c8dee2aaSAndroid Build Coastguard Worker - Bicubic filtering is not supported. Requesting bicubic filtering when 183*c8dee2aaSAndroid Build Coastguard Worker calling `makeRawShader` will return `nullptr`. 184*c8dee2aaSAndroid Build Coastguard Worker 185*c8dee2aaSAndroid Build Coastguard WorkerHere, we create an image holding a spherical normal map. Then we use that with 186*c8dee2aaSAndroid Build Coastguard Workera lighting shader to show what happens when rendering to a different color space. 187*c8dee2aaSAndroid Build Coastguard WorkerIf we use a regular image shader, the normals will be treated as colors, and 188*c8dee2aaSAndroid Build Coastguard Workertransformed to the working color space. This alters the normals, incorrectly. 189*c8dee2aaSAndroid Build Coastguard WorkerFor the final draw, we use a raw image shader, which returns the original 190*c8dee2aaSAndroid Build Coastguard Workernormals, ignoring the working color space. 191*c8dee2aaSAndroid Build Coastguard Worker 192*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_RawImageShaders'></fiddle-embed-sk> 193*c8dee2aaSAndroid Build Coastguard Worker 194*c8dee2aaSAndroid Build Coastguard Worker### Working In a Known Color Space 195*c8dee2aaSAndroid Build Coastguard Worker 196*c8dee2aaSAndroid Build Coastguard WorkerWithin an SkSL shader, you don't know what the working color space is. For many 197*c8dee2aaSAndroid Build Coastguard Workereffects, this is fine - evaluating image shaders, and doing simple color math 198*c8dee2aaSAndroid Build Coastguard Workeris usually going to give reasonable results (particularly if you know that 199*c8dee2aaSAndroid Build Coastguard Workerthe working color space for an application is always sRGB, for example). For 200*c8dee2aaSAndroid Build Coastguard Workercertain effects, though, it may be important to do some math in a fixed, known 201*c8dee2aaSAndroid Build Coastguard Workercolor space. The most common example is lighting -- to get physically accurate 202*c8dee2aaSAndroid Build Coastguard Workerlighting, math should be done in a _linear_ color space. To help with this, 203*c8dee2aaSAndroid Build Coastguard WorkerSkSL provides two intrinsic functions: 204*c8dee2aaSAndroid Build Coastguard Worker 205*c8dee2aaSAndroid Build Coastguard Worker``` 206*c8dee2aaSAndroid Build Coastguard Workervec3 toLinearSrgb(vec3 color); 207*c8dee2aaSAndroid Build Coastguard Workervec3 fromLinearSrgb(vec3 color); 208*c8dee2aaSAndroid Build Coastguard Worker``` 209*c8dee2aaSAndroid Build Coastguard Worker 210*c8dee2aaSAndroid Build Coastguard WorkerThese convert colors between the working color space and the linear sRGB color 211*c8dee2aaSAndroid Build Coastguard Workerspace. That space uses the sRGB color primaries (gamut), and a linear transfer 212*c8dee2aaSAndroid Build Coastguard Workerfunction. It represents values outside of the sRGB gamut using extended range 213*c8dee2aaSAndroid Build Coastguard Workervalues (below 0.0 and above 1.0). This corresponds to Android's 214*c8dee2aaSAndroid Build Coastguard Worker[LINEAR_EXTENDED_SRGB](https://developer.android.com/reference/android/graphics/ColorSpace.Named.html#LINEAR_EXTENDED_SRGB) 215*c8dee2aaSAndroid Build Coastguard Workeror Apple's 216*c8dee2aaSAndroid Build Coastguard Worker[extendedLinearSRGB](https://developer.apple.com/documentation/coregraphics/cgcolorspace/1690961-extendedlinearsrgb), 217*c8dee2aaSAndroid Build Coastguard Workerfor example. 218*c8dee2aaSAndroid Build Coastguard Worker 219*c8dee2aaSAndroid Build Coastguard WorkerHere's an example showing a sphere, with lighting math being done in the default 220*c8dee2aaSAndroid Build Coastguard Workerworking space (sRGB), and again with the math done in a linear space: 221*c8dee2aaSAndroid Build Coastguard Worker 222*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_LinearSRGB'></fiddle-embed-sk> 223*c8dee2aaSAndroid Build Coastguard Worker 224*c8dee2aaSAndroid Build Coastguard Worker--- 225*c8dee2aaSAndroid Build Coastguard Worker 226*c8dee2aaSAndroid Build Coastguard Worker## Premultiplied Alpha 227*c8dee2aaSAndroid Build Coastguard Worker 228*c8dee2aaSAndroid Build Coastguard WorkerWhen dealing with transparent colors, there are two (common) 229*c8dee2aaSAndroid Build Coastguard Worker[possible representations](https://en.wikipedia.org/wiki/Alpha_compositing#Straight_versus_premultiplied). 230*c8dee2aaSAndroid Build Coastguard WorkerSkia calls these _unpremultiplied_ (what Wikipedia calls _straight_), and 231*c8dee2aaSAndroid Build Coastguard Worker_premultiplied_. In the Skia pipeline, every `SkShader` returns premultiplied 232*c8dee2aaSAndroid Build Coastguard Workercolors. 233*c8dee2aaSAndroid Build Coastguard Worker 234*c8dee2aaSAndroid Build Coastguard WorkerIf you're familiar with OpenGL blending, you can think of it in terms of the 235*c8dee2aaSAndroid Build Coastguard Workerblend equation. For common alpha blending (called 236*c8dee2aaSAndroid Build Coastguard Worker[source-over](https://developer.android.com/reference/android/graphics/PorterDuff.Mode#SRC_OVER)), 237*c8dee2aaSAndroid Build Coastguard Workeryou would normally configure your blend function as 238*c8dee2aaSAndroid Build Coastguard Worker`(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)`. Skia defines source-over blending as 239*c8dee2aaSAndroid Build Coastguard Workerif the blend function were `(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)`. 240*c8dee2aaSAndroid Build Coastguard Worker 241*c8dee2aaSAndroid Build Coastguard WorkerSkia's use of premultiplied alpha implies: 242*c8dee2aaSAndroid Build Coastguard Worker 243*c8dee2aaSAndroid Build Coastguard Worker- If you start with an unpremultiplied `SkImage` (like a PNG), turn that into an 244*c8dee2aaSAndroid Build Coastguard Worker `SkImageShader`, and evaluate that shader... the resulting colors will be 245*c8dee2aaSAndroid Build Coastguard Worker `[R*A, G*A, B*A, A]`, **not** `[R, G, B, A]`. 246*c8dee2aaSAndroid Build Coastguard Worker- If your SkSL will return transparent colors, it must be sure to multiply the 247*c8dee2aaSAndroid Build Coastguard Worker `RGB` by `A`. 248*c8dee2aaSAndroid Build Coastguard Worker- For more complex shaders, you must understand which of your colors are 249*c8dee2aaSAndroid Build Coastguard Worker premultiplied vs. unpremultiplied. Many operations don't make sense if you mix 250*c8dee2aaSAndroid Build Coastguard Worker both kinds of color together. 251*c8dee2aaSAndroid Build Coastguard Worker 252*c8dee2aaSAndroid Build Coastguard WorkerThe image below demonstrates this: properly premultiplied colors produce a smooth 253*c8dee2aaSAndroid Build Coastguard Workergradient as alpha decreases. Unpremultipled colors cause the gradient to display 254*c8dee2aaSAndroid Build Coastguard Workerincorrectly, becoming too bright and shifting hue as the alpha changes. 255*c8dee2aaSAndroid Build Coastguard Worker 256*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_PremultipliedAlpha'></fiddle-embed-sk> 257*c8dee2aaSAndroid Build Coastguard Worker 258*c8dee2aaSAndroid Build Coastguard Worker--- 259*c8dee2aaSAndroid Build Coastguard Worker 260*c8dee2aaSAndroid Build Coastguard Worker## Minified SkSL 261*c8dee2aaSAndroid Build Coastguard Worker 262*c8dee2aaSAndroid Build Coastguard WorkerSkia includes a minifier tool which can automatically reduce the size of your Runtime Effect 263*c8dee2aaSAndroid Build Coastguard Workeror SkMesh code. The tool eliminates whitespace and comments, shortens function and variable names, 264*c8dee2aaSAndroid Build Coastguard Workerand deletes unreferenced code. 265*c8dee2aaSAndroid Build Coastguard Worker 266*c8dee2aaSAndroid Build Coastguard WorkerAs an example, here is the previous demo in its minified form. The shader code is reduced to 267*c8dee2aaSAndroid Build Coastguard Workerapproximately half of its original size, while displaying the exact same result. 268*c8dee2aaSAndroid Build Coastguard Worker 269*c8dee2aaSAndroid Build Coastguard Worker<fiddle-embed-sk name='@SkSL_MinifiedSkSL'></fiddle-embed-sk> 270*c8dee2aaSAndroid Build Coastguard Worker 271*c8dee2aaSAndroid Build Coastguard WorkerTo enable this tool, add `skia_compile_modules = true` to your gn argument list. (At the command 272*c8dee2aaSAndroid Build Coastguard Workerline, type `gn args out/yourbuild` to access the arguments, or edit the file `out/yourbuild/args.gn` 273*c8dee2aaSAndroid Build Coastguard Workerdirectly.) Use `ninja` to compile Skia once more, and you will now have a new utility called 274*c8dee2aaSAndroid Build Coastguard Worker`sksl-minify` in the output directory. 275*c8dee2aaSAndroid Build Coastguard Worker 276*c8dee2aaSAndroid Build Coastguard WorkerWhen minifying a mesh program, you must supply `struct Varyings` and `struct Attributes` which 277*c8dee2aaSAndroid Build Coastguard Workercorrespond to the SkMeshSpecification. These structs will be eliminated from the minified program 278*c8dee2aaSAndroid Build Coastguard Workerfor convenience. 279*c8dee2aaSAndroid Build Coastguard Worker 280*c8dee2aaSAndroid Build Coastguard Worker`sksl-minify` takes the following command line arguments: 281*c8dee2aaSAndroid Build Coastguard Worker 282*c8dee2aaSAndroid Build Coastguard Worker- An output path, e.g. `MyShader.minified.sksl` 283*c8dee2aaSAndroid Build Coastguard Worker- An input path, e.g. `MyShader.sksl` 284*c8dee2aaSAndroid Build Coastguard Worker- (Optional) Pass `--stringify` to wrap the minified SkSL text in a quoted C++ string. 285*c8dee2aaSAndroid Build Coastguard Worker By default, the output file will contain plain SkSL. The minified shader string in the example 286*c8dee2aaSAndroid Build Coastguard Worker code above was created with --stringify. 287*c8dee2aaSAndroid Build Coastguard Worker- (Optional) Pass `--shader`, `--colorfilter`, `--blender`, `--meshfrag` or `--meshvert` to set 288*c8dee2aaSAndroid Build Coastguard Worker the program kind. The default value is `--shader`. 289