AGSL and GLSL are very similar in syntax, allowing many GLSL fragment shader effects to be brought over to Android with minimal changes. AGSL fixes its GLSL feature set at GLSL ES 1.0 (the shading language used by OpenGL ES 2.0) to provide for maximum device reach.

A GLSL fragment shader controls the entire behavior of the GPU between the rasterizer and the blending hardware. That shader does all the work to compute a color, and the color it generates is exactly what is fed to the blending stage of the pipeline. When you write a shader in AGSL, you are programming a stage of the Android graphics pipeline. Many of the language differences stem from this.

## Shader execution

Just like in a GLSL shader, an AGSL shader begins execution in a main function. Unlike GLSL, the function takes the shader position in "local" coordinates as a parameter. This is similar to`gl_FragCoord`, but rather than framebuffer coordinates, these coordinates may have been translated prior to calling your shader. Your shader then returns the pixel color as a`vec4`in medium or high precision (similar to`out vec4 color`or`gl_FragColor`in GLSL).  

    mediump vec4 main(in vec2 fragCoord)

## Coordinate space

![GLSL vs AGSL coordinate spaces](https://developer.android.com/static/images/guide/topics/graphics/agsl/agsl-coordinate-glsl-vs-agsl.png)

*Shader drawn using GLSL vs[Near identical shader drawn using AGSL](https://shaders.skia.org/?id=9dc5c7170e82d49c47a3ee20d679ad5bef45b5ca7e23c4327dd93b8d3101256f)*

AGSL and GLSL use different coordinate spaces by default. In GLSL, the fragment coordinate (fragCoord) is relative to the lower left. AGSL matches the screen coordinate system of[Canvas](https://developer.android.com/reference/android/graphics/Canvas), which means that the Y axis begins from the upper left corner. If needed, you can convert between these two spaces by passing in the resolution as a uniform and using`resolution.y - fragCoord.y`for the Y axis value. Alternatively, you can apply a local transformation matrix to your shader.  

    // AGSL to GLSL coordinate space transformation matrix
    val localMatrix = Matrix()
    localMatrix.postScale(1.0f, -1.0f)
    localMatrix.postTranslate(0.0f, viewHeight)
    gridShader.setLocalMatrix(localMatrix)

## Precision and types

GLSL compatible precision modifiers are supported, but AGSL introduces`half`and`short`types which also represent medium precision.

Vector types can be declared as named \<base type\>\<columns\>. You can use`float2`instead of`vec2`and`bool4`instead of`bvec4`. Matrix types can be declared as named \<base type\>\<columns\>x\<rows\>, so`float3x3`instead of`mat3`. AGSL also allows GLSL-style declarations for`mat`and`vec`and these types are mapped to their float equivalents.

## Preprocessor

AGSL doesn't support GLSL style[preprocessor](https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives)directives. Convert #define statements to const variables. AGSL's compiler supports constant folding and branch elimination for const variables, so these will be efficient.

## Color spaces

Android Applications are color managed. The color space of a Canvas determines the working color space for drawing. Source content (like shaders, including[BitmapShader](https://developer.android.com/reference/android/graphics/BitmapShader)) also have color spaces.

For certain effects, such as physically accurate lighting, math should be done in a linear color space. To help with this, AGSL provides these intrinsic functions:  

    half3 toLinearSrgb(half3 color)
    half3 fromLinearSrgb(half3 color)

These convert colors between the working color space and Android's[`LINEAR_EXTENDED_SRGB`](https://developer.android.com/reference/android/graphics/ColorSpace.Named#LINEAR_EXTENDED_SRGB)color space. That space uses the sRGB color primaries (gamut), and a linear transfer function. It represents values outside of the sRGB gamut using extended range values (below 0.0 and above 1.0).

### Uniforms

Since AGSL doesn't know if uniforms contain colors, it won't automatically apply a color conversion to them. You can label`half4`/`float4`/`vec4`with`layout(color)`, which lets Android know that the uniform will be used as a color, allowing Android to transform the uniform value to the working color space.

In AGSL, declare the uniform like this:  

    layout(color) uniform half4 iColor;  // Input color
    uniform float2 iResolution;          // Viewport resolution (pixels)

In Android code, you can then set the uniform like this:  

    shader.setColorUniform("iColor", Color.GREEN)
    shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())