Bug 1532245. Factor out component transfer code to a function in brush_blend shader for webreder. r=gw
☠☠ backed out by 62bce3145e7e ☠ ☠
authorTimothy Nikkel <tnikkel@gmail.com>
Mon, 11 Mar 2019 17:01:40 -0500
changeset 521494 c32dcf4e6f92de2e9523312a41fa71b77503f7e2
parent 521370 b9d87882a36584e2f17331b652cbc8681aee17ce
child 521495 62bce3145e7e880291d3ec81cfc3e6faa0501a6b
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1532245
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532245. Factor out component transfer code to a function in brush_blend shader for webreder. r=gw Some phones can't compile the shader as is: "ERROR: 0:1448: '' : No default label can be nested inside other control flow nested within their corresponding switch" https://github.com/servo/webrender/wiki/Driver-issues#bug-1532245---switch-statement-inside-control-flow-inside-switch-statement-fails-to-compile-on-some-android-phones Differential Revision: https://phabricator.services.mozilla.com/D22853
gfx/wr/webrender/res/brush_blend.glsl
--- a/gfx/wr/webrender/res/brush_blend.glsl
+++ b/gfx/wr/webrender/res/brush_blend.glsl
@@ -167,16 +167,70 @@ vec3 SrgbToLinear(vec3 color) {
 }
 
 vec3 LinearToSrgb(vec3 color) {
     vec3 c1 = color * 12.92;
     vec3 c2 = vec3(1.055) * pow(color, vec3(1.0 / 2.4)) - vec3(0.055);
     return if_then_else(lessThanEqual(color, vec3(0.0031308)), c1, c2);
 }
 
+// This function has to be factored out due to the following issue:
+// https://github.com/servo/webrender/wiki/Driver-issues#bug-1532245---switch-statement-inside-control-flow-inside-switch-statement-fails-to-compile-on-some-android-phones
+// (and now the words "default default" so angle_shader_validation.rs passes)
+vec4 ComponentTransfer(vec4 colora) {
+    // We push a different amount of data to the gpu cache depending on the
+    // function type.
+    // Identity => 0 blocks
+    // Table/Discrete => 64 blocks (256 values)
+    // Linear => 1 block (2 values)
+    // Gamma => 1 block (3 values)
+    // We loop through the color components and increment the offset (for the
+    // next color component) into the gpu cache based on how many blocks that
+    // function type put into the gpu cache.
+    // Table/Discrete use a 256 entry look up table.
+    // Linear/Gamma are a simple calculation.
+    int offset = 0;
+    vec4 texel;
+    int k;
+
+    for (int i = 0; i < 4; i++) {
+        switch (vFuncs[i]) {
+            case COMPONENT_TRANSFER_IDENTITY:
+                break;
+            case COMPONENT_TRANSFER_TABLE:
+            case COMPONENT_TRANSFER_DISCRETE:
+                // fetch value from lookup table
+                k = int(floor(colora[i]*255.0));
+                texel = fetch_from_gpu_cache_1(vTableAddress + offset + k/4);
+                colora[i] = clamp(texel[k % 4], 0.0, 1.0);
+                // offset plus 256/4 blocks
+                offset = offset + 64;
+                break;
+            case COMPONENT_TRANSFER_LINEAR:
+                // fetch the two values for use in the linear equation
+                texel = fetch_from_gpu_cache_1(vTableAddress + offset);
+                colora[i] = clamp(texel[0] * colora[i] + texel[1], 0.0, 1.0);
+                // offset plus 1 block
+                offset = offset + 1;
+                break;
+            case COMPONENT_TRANSFER_GAMMA:
+                // fetch the three values for use in the gamma equation
+                texel = fetch_from_gpu_cache_1(vTableAddress + offset);
+                colora[i] = clamp(texel[0] * pow(colora[i], texel[1]) + texel[2], 0.0, 1.0);
+                // offset plus 1 block
+                offset = offset + 1;
+                break;
+            default:
+                // shouldn't happen
+                break;
+        }
+    }
+    return colora;
+}
+
 Fragment brush_fs() {
     float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
     vec2 uv = vUv * perspective_divisor;
     vec4 Cs = texture(sColor0, vec3(uv, vLayerAndPerspective.x));
 
     // Un-premultiply the input.
     float alpha = Cs.a;
     vec3 color = alpha != 0.0 ? Cs.rgb / alpha : Cs.rgb;
@@ -198,64 +252,18 @@ Fragment brush_fs() {
             break;
         case 11:
             color = SrgbToLinear(color);
             break;
         case 12:
             color = LinearToSrgb(color);
             break;
         case 13: // Component Transfer
-            int offset = 0;
-            vec4 texel;
-            int k;
-
-            // We push a different amount of data to the gpu cache depending
-            // on the function type.
-            // Identity => 0 blocks
-            // Table/Discrete => 64 blocks (256 values)
-            // Linear => 1 block (2 values)
-            // Gamma => 1 block (3 values)
-            // We loop through the color components and increment the offset
-            // (for the next color component) into the gpu cache based on how
-            // many blocks that function type put into the gpu cache.
-            // Table/Discrete use a 256 entry look up table.
-            // Linear/Gamma are a simple calculation.
             vec4 colora = alpha != 0.0 ? Cs / alpha : Cs;
-            for (int i = 0; i < 4; i++) {
-                switch (vFuncs[i]) {
-                    case COMPONENT_TRANSFER_IDENTITY:
-                        break;
-                    case COMPONENT_TRANSFER_TABLE:
-                    case COMPONENT_TRANSFER_DISCRETE:
-                        // fetch value from lookup table
-                        k = int(floor(colora[i]*255.0));
-                        texel = fetch_from_gpu_cache_1(vTableAddress + offset + k/4);
-                        colora[i] = clamp(texel[k % 4], 0.0, 1.0);
-                        // offset plus 256/4 blocks
-                        offset = offset + 64;
-                        break;
-                    case COMPONENT_TRANSFER_LINEAR:
-                        // fetch the two values for use in the linear equation
-                        texel = fetch_from_gpu_cache_1(vTableAddress + offset);
-                        colora[i] = clamp(texel[0] * colora[i] + texel[1], 0.0, 1.0);
-                        // offset plus 1 block
-                        offset = offset + 1;
-                        break;
-                    case COMPONENT_TRANSFER_GAMMA:
-                        // fetch the three values for use in the gamma equation
-                        texel = fetch_from_gpu_cache_1(vTableAddress + offset);
-                        colora[i] = clamp(texel[0] * pow(colora[i], texel[1]) + texel[2], 0.0, 1.0);
-                        // offset plus 1 block
-                        offset = offset + 1;
-                        break;
-                    default:
-                        // shouldn't happen
-                        break;
-                }
-            }
+            colora = ComponentTransfer(colora);
             color = colora.rgb;
             alpha = colora.a;
             break;
         default:
             color = vColorMat * color + vColorOffset;
     }
 
     // Fail-safe to ensure that we don't sample outside the rendered