Merge "Merge "Add null check in AuthBiometricView#onConfigurationChange" into tm-qpr-dev am: fb599cdf14 am: 92cd3305dd" into udc-dev
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
index 280e7ed9..23fcb69 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
@@ -15,163 +15,166 @@
  */
 package com.android.systemui.surfaceeffects.shaderutil
 
-/** A common utility functions that are used for computing shaders. */
-class ShaderUtilLibrary {
+/** Common utility functions that are used for computing shaders. */
+object ShaderUtilLibrary {
     // language=AGSL
-    companion object {
-        const val SHADER_LIB =
-            """
-            float triangleNoise(vec2 n) {
-                n  = fract(n * vec2(5.3987, 5.4421));
-                n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
-                float xy = n.x * n.y;
-                // compute in [0..2[ and remap to [-1.0..1.0[
-                return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
+    const val SHADER_LIB =
+        """
+        float triangleNoise(vec2 n) {
+            n  = fract(n * vec2(5.3987, 5.4421));
+            n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
+            float xy = n.x * n.y;
+            // compute in [0..2[ and remap to [-1.0..1.0[
+            return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
+        }
+
+        const float PI = 3.1415926535897932384626;
+
+        float sparkles(vec2 uv, float t) {
+            float n = triangleNoise(uv);
+            float s = 0.0;
+            for (float i = 0; i < 4; i += 1) {
+                float l = i * 0.01;
+                float h = l + 0.1;
+                float o = smoothstep(n - l, h, n);
+                o *= abs(sin(PI * o * (t + 0.55 * i)));
+                s += o;
             }
+            return s;
+        }
 
-            const float PI = 3.1415926535897932384626;
+        vec2 distort(vec2 p, float time, float distort_amount_radial,
+            float distort_amount_xy) {
+                float angle = atan(p.y, p.x);
+                  return p + vec2(sin(angle * 8 + time * 0.003 + 1.641),
+                            cos(angle * 5 + 2.14 + time * 0.00412)) * distort_amount_radial
+                     + vec2(sin(p.x * 0.01 + time * 0.00215 + 0.8123),
+                            cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
+        }
 
-            float sparkles(vec2 uv, float t) {
-                float n = triangleNoise(uv);
-                float s = 0.0;
-                for (float i = 0; i < 4; i += 1) {
-                    float l = i * 0.01;
-                    float h = l + 0.1;
-                    float o = smoothstep(n - l, h, n);
-                    o *= abs(sin(PI * o * (t + 0.55 * i)));
-                    s += o;
-                }
-                return s;
-            }
+        // Perceived luminosity (L′), not absolute luminosity.
+        half getLuminosity(vec3 c) {
+            return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+        }
 
-            vec2 distort(vec2 p, float time, float distort_amount_radial,
-                float distort_amount_xy) {
-                    float angle = atan(p.y, p.x);
-                      return p + vec2(sin(angle * 8 + time * 0.003 + 1.641),
-                                cos(angle * 5 + 2.14 + time * 0.00412)) * distort_amount_radial
-                         + vec2(sin(p.x * 0.01 + time * 0.00215 + 0.8123),
-                                cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
-            }
+        // Creates a luminosity mask and clamp to the legal range.
+        vec3 maskLuminosity(vec3 dest, float lum) {
+            dest.rgb *= vec3(lum);
+            // Clip back into the legal range
+            dest = clamp(dest, vec3(0.), vec3(1.0));
+            return dest;
+        }
 
-            // Perceived luminosity (L′), not absolute luminosity.
-            half getLuminosity(vec3 c) {
-                return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
-            }
+        // Return range [-1, 1].
+        vec3 hash(vec3 p) {
+            p = fract(p * vec3(.3456, .1234, .9876));
+            p += dot(p, p.yxz + 43.21);
+            p = (p.xxy + p.yxx) * p.zyx;
+            return (fract(sin(p) * 4567.1234567) - .5) * 2.;
+        }
 
-            // Creates a luminosity mask and clamp to the legal range.
-            vec3 maskLuminosity(vec3 dest, float lum) {
-                dest.rgb *= vec3(lum);
-                // Clip back into the legal range
-                dest = clamp(dest, vec3(0.), vec3(1.0));
-                return dest;
-            }
+        // Skew factors (non-uniform).
+        const half SKEW = 0.3333333;  // 1/3
+        const half UNSKEW = 0.1666667;  // 1/6
 
-            // Return range [-1, 1].
-            vec3 hash(vec3 p) {
-                p = fract(p * vec3(.3456, .1234, .9876));
-                p += dot(p, p.yxz + 43.21);
-                p = (p.xxy + p.yxx) * p.zyx;
-                return (fract(sin(p) * 4567.1234567) - .5) * 2.;
-            }
+        // Return range roughly [-1,1].
+        // It's because the hash function (that returns a random gradient vector) returns
+        // different magnitude of vectors. Noise doesn't have to be in the precise range thus
+        // skipped normalize.
+        half simplex3d(vec3 p) {
+            // Skew the input coordinate, so that we get squashed cubical grid
+            vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);
 
-            // Skew factors (non-uniform).
-            const half SKEW = 0.3333333;  // 1/3
-            const half UNSKEW = 0.1666667;  // 1/6
+            // Unskew back
+            vec3 u = s - (s.x + s.y + s.z) * UNSKEW;
 
-            // Return range roughly [-1,1].
-            // It's because the hash function (that returns a random gradient vector) returns
-            // different magnitude of vectors. Noise doesn't have to be in the precise range thus
-            // skipped normalize.
-            half simplex3d(vec3 p) {
-                // Skew the input coordinate, so that we get squashed cubical grid
-                vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);
+            // Unskewed coordinate that is relative to p, to compute the noise contribution
+            // based on the distance.
+            vec3 c0 = p - u;
 
-                // Unskew back
-                vec3 u = s - (s.x + s.y + s.z) * UNSKEW;
+            // We have six simplices (in this case tetrahedron, since we are in 3D) that we
+            // could possibly in.
+            // Here, we are finding the correct tetrahedron (simplex shape), and traverse its
+            // four vertices (c0..3) when computing noise contribution.
+            // The way we find them is by comparing c0's x,y,z values.
+            // For example in 2D, we can find the triangle (simplex shape in 2D) that we are in
+            // by comparing x and y values. i.e. x>y lower, x<y, upper triangle.
+            // Same applies in 3D.
+            //
+            // Below indicates the offsets (or offset directions) when c0=(x0,y0,z0)
+            // x0>y0>z0: (1,0,0), (1,1,0), (1,1,1)
+            // x0>z0>y0: (1,0,0), (1,0,1), (1,1,1)
+            // z0>x0>y0: (0,0,1), (1,0,1), (1,1,1)
+            // z0>y0>x0: (0,0,1), (0,1,1), (1,1,1)
+            // y0>z0>x0: (0,1,0), (0,1,1), (1,1,1)
+            // y0>x0>z0: (0,1,0), (1,1,0), (1,1,1)
+            //
+            // The rule is:
+            // * For offset1, set 1 at the max component, otherwise 0.
+            // * For offset2, set 0 at the min component, otherwise 1.
+            // * For offset3, set 1 for all.
+            //
+            // Encode x0-y0, y0-z0, z0-x0 in a vec3
+            vec3 en = c0 - c0.yzx;
+            // Each represents whether x0>y0, y0>z0, z0>x0
+            en = step(vec3(0.), en);
+            // en.zxy encodes z0>x0, x0>y0, y0>x0
+            vec3 offset1 = en * (1. - en.zxy); // find max
+            vec3 offset2 = 1. - en.zxy * (1. - en); // 1-(find min)
+            vec3 offset3 = vec3(1.);
 
-                // Unskewed coordinate that is relative to p, to compute the noise contribution
-                // based on the distance.
-                vec3 c0 = p - u;
+            vec3 c1 = c0 - offset1 + UNSKEW;
+            vec3 c2 = c0 - offset2 + UNSKEW * 2.;
+            vec3 c3 = c0 - offset3 + UNSKEW * 3.;
 
-                // We have six simplices (in this case tetrahedron, since we are in 3D) that we
-                // could possibly in.
-                // Here, we are finding the correct tetrahedron (simplex shape), and traverse its
-                // four vertices (c0..3) when computing noise contribution.
-                // The way we find them is by comparing c0's x,y,z values.
-                // For example in 2D, we can find the triangle (simplex shape in 2D) that we are in
-                // by comparing x and y values. i.e. x>y lower, x<y, upper triangle.
-                // Same applies in 3D.
-                //
-                // Below indicates the offsets (or offset directions) when c0=(x0,y0,z0)
-                // x0>y0>z0: (1,0,0), (1,1,0), (1,1,1)
-                // x0>z0>y0: (1,0,0), (1,0,1), (1,1,1)
-                // z0>x0>y0: (0,0,1), (1,0,1), (1,1,1)
-                // z0>y0>x0: (0,0,1), (0,1,1), (1,1,1)
-                // y0>z0>x0: (0,1,0), (0,1,1), (1,1,1)
-                // y0>x0>z0: (0,1,0), (1,1,0), (1,1,1)
-                //
-                // The rule is:
-                // * For offset1, set 1 at the max component, otherwise 0.
-                // * For offset2, set 0 at the min component, otherwise 1.
-                // * For offset3, set 1 for all.
-                //
-                // Encode x0-y0, y0-z0, z0-x0 in a vec3
-                vec3 en = c0 - c0.yzx;
-                // Each represents whether x0>y0, y0>z0, z0>x0
-                en = step(vec3(0.), en);
-                // en.zxy encodes z0>x0, x0>y0, y0>x0
-                vec3 offset1 = en * (1. - en.zxy); // find max
-                vec3 offset2 = 1. - en.zxy * (1. - en); // 1-(find min)
-                vec3 offset3 = vec3(1.);
+            // Kernel summation: dot(max(0, r^2-d^2))^4, noise contribution)
+            //
+            // First compute d^2, squared distance to the point.
+            vec4 w; // w = max(0, r^2 - d^2))
+            w.x = dot(c0, c0);
+            w.y = dot(c1, c1);
+            w.z = dot(c2, c2);
+            w.w = dot(c3, c3);
 
-                vec3 c1 = c0 - offset1 + UNSKEW;
-                vec3 c2 = c0 - offset2 + UNSKEW * 2.;
-                vec3 c3 = c0 - offset3 + UNSKEW * 3.;
+            // Noise contribution should decay to zero before they cross the simplex boundary.
+            // Usually r^2 is 0.5 or 0.6;
+            // 0.5 ensures continuity but 0.6 increases the visual quality for the application
+            // where discontinuity isn't noticeable.
+            w = max(0.6 - w, 0.);
 
-                // Kernel summation: dot(max(0, r^2-d^2))^4, noise contribution)
-                //
-                // First compute d^2, squared distance to the point.
-                vec4 w; // w = max(0, r^2 - d^2))
-                w.x = dot(c0, c0);
-                w.y = dot(c1, c1);
-                w.z = dot(c2, c2);
-                w.w = dot(c3, c3);
+            // Noise contribution from each point.
+            vec4 nc;
+            nc.x = dot(hash(s), c0);
+            nc.y = dot(hash(s + offset1), c1);
+            nc.z = dot(hash(s + offset2), c2);
+            nc.w = dot(hash(s + offset3), c3);
 
-                // Noise contribution should decay to zero before they cross the simplex boundary.
-                // Usually r^2 is 0.5 or 0.6;
-                // 0.5 ensures continuity but 0.6 increases the visual quality for the application
-                // where discontinuity isn't noticeable.
-                w = max(0.6 - w, 0.);
+            nc *= w*w*w*w;
 
-                // Noise contribution from each point.
-                vec4 nc;
-                nc.x = dot(hash(s), c0);
-                nc.y = dot(hash(s + offset1), c1);
-                nc.z = dot(hash(s + offset2), c2);
-                nc.w = dot(hash(s + offset3), c3);
+            // Add all the noise contributions.
+            // Should multiply by the possible max contribution to adjust the range in [-1,1].
+            return dot(vec4(32.), nc);
+        }
 
-                nc *= w*w*w*w;
+        // Random rotations.
+        // The way you create fractal noise is layering simplex noise with some rotation.
+        // To make random cloud looking noise, the rotations should not align. (Otherwise it
+        // creates patterned noise).
+        // Below rotations only rotate in one axis.
+        const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
+        const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
+        const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
 
-                // Add all the noise contributions.
-                // Should multiply by the possible max contribution to adjust the range in [-1,1].
-                return dot(vec4(32.), nc);
-            }
+        // Octave = 4
+        // Divide each coefficient by 3 to produce more grainy noise.
+        half simplex3d_fractal(vec3 p) {
+            return 0.675 * simplex3d(p * rot1) + 0.225 * simplex3d(2.0 * p * rot2)
+                    + 0.075 * simplex3d(4.0 * p * rot3) + 0.025 * simplex3d(8.0 * p);
+        }
 
-            // Random rotations.
-            // The way you create fractal noise is layering simplex noise with some rotation.
-            // To make random cloud looking noise, the rotations should not align. (Otherwise it
-            // creates patterned noise).
-            // Below rotations only rotate in one axis.
-            const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
-            const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
-            const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
-
-            // Octave = 4
-            // Divide each coefficient by 3 to produce more grainy noise.
-            half simplex3d_fractal(vec3 mat) {
-                return 0.675 * simplex3d(mat * rot1) + 0.225 * simplex3d(2.0 * mat * rot2)
-                        + 0.075 * simplex3d(4.0 * mat * rot3) + 0.025 * simplex3d(8.0 * mat);
-            }
-            """
-    }
+        // Screen blend
+        vec3 screen(vec3 dest, vec3 src) {
+            return dest + src - dest * src;
+        }
+    """
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
index 0e22667..d1ba7c4 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
@@ -36,6 +36,7 @@
             uniform float in_aspectRatio;
             uniform float in_opacity;
             uniform float in_pixelDensity;
+            uniform float in_inverseLuma;
             layout(color) uniform vec4 in_color;
             layout(color) uniform vec4 in_backgroundColor;
         """
@@ -47,7 +48,7 @@
                 uv.x *= in_aspectRatio;
 
                 vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
-                float luma = simplex3d(noiseP) * in_opacity;
+                float luma = abs(in_inverseLuma - simplex3d(noiseP)) * in_opacity;
                 vec3 mask = maskLuminosity(in_color.rgb, luma);
                 vec3 color = in_backgroundColor.rgb + mask * 0.6;
 
@@ -69,7 +70,7 @@
                 uv.x *= in_aspectRatio;
 
                 vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
-                float luma = simplex3d_fractal(noiseP) * in_opacity;
+                float luma = abs(in_inverseLuma - simplex3d_fractal(noiseP)) * in_opacity;
                 vec3 mask = maskLuminosity(in_color.rgb, luma);
                 vec3 color = in_backgroundColor.rgb + mask * 0.6;
 
@@ -123,6 +124,17 @@
         setFloatUniform("in_aspectRatio", width / max(height, 0.001f))
     }
 
+    /**
+     * Sets whether to inverse the luminosity of the noise.
+     *
+     * By default noise will be used as a luma matte as is. This means that you will see color in
+     * the brighter area. If you want to invert it, meaning blend color onto the darker side, set to
+     * true.
+     */
+    fun setInverseNoiseLuminosity(inverse: Boolean) {
+        setFloatUniform("in_inverseLuma", if (inverse) 1f else 0f)
+    }
+
     /** Current noise movements in x, y, and z axes. */
     var noiseOffsetX: Float = 0f
         private set