Bug 1594128 - Use generic slots for text, image and solid shader varyings. r=gw
authorNicolas Silva <nsilva@mozilla.com>
Thu, 21 Nov 2019 17:37:08 +0000
changeset 503328 bb21ea50b1e90bdafd620695b691227c6ac8295c
parent 503327 912718966a67fb7cf2f21c2690dce0bd5822377a
child 503329 0af881b4707af8d28c78d35ea50f2c4152164e28
push id101267
push usernsilva@mozilla.com
push dateFri, 22 Nov 2019 10:31:38 +0000
treeherderautoland@7a29d7acf94c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1594128
milestone72.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 1594128 - Use generic slots for text, image and solid shader varyings. r=gw The 'multi-brush' shader will have to dynamically switch between different brushes. In order to support that without needing the sum of all brush varying locations, allow aliasing a number of generic slots. This patch makes the assumption that one a vec2 and a vec4 cost the same amount of varying register space, which is suggested by the glsl specification about shader locations. If it is not the case we can add more granularity to the varying slots which are all vec4 at the moment. This also assumes that an unused varying is always optimized out. Differential Revision: https://phabricator.services.mozilla.com/D53726
gfx/wr/webrender/res/brush.glsl
gfx/wr/webrender/res/brush_image.glsl
gfx/wr/webrender/res/brush_solid.glsl
--- a/gfx/wr/webrender/res/brush.glsl
+++ b/gfx/wr/webrender/res/brush.glsl
@@ -56,16 +56,27 @@
 #define BRUSH_KIND_BLEND            0x6000000
 #define BRUSH_KIND_MIX_BLEND        0x7000000
 #define BRUSH_KIND_YV               0x8000000
 
 #ifdef WR_FEATURE_MULTI_BRUSH
 flat varying int v_brush_kind;
 #endif
 
+// A few varying slots for the brushes to use.
+// Using these instead of adding dedicated varyings avoids using a high
+// number of varyings in the multi-brush shader.
+flat varying vec4 flat_varying_vec4_0;
+flat varying vec4 flat_varying_vec4_1;
+flat varying vec4 flat_varying_vec4_2;
+flat varying vec4 flat_varying_vec4_3;
+flat varying vec4 flat_varying_vec4_4;
+varying vec4 varying_vec4_0;
+varying vec4 varying_vec4_1;
+
 #ifdef WR_VERTEX_SHADER
 
 #define FWD_DECLARE_VS_FUNCTION(name)   \
 void name(                              \
     VertexInfo vi,                      \
     int prim_address,                   \
     RectWithSize local_rect,            \
     RectWithSize segment_rect,          \
--- a/gfx/wr/webrender/res/brush_image.glsl
+++ b/gfx/wr/webrender/res/brush_image.glsl
@@ -6,34 +6,37 @@
 #define VECS_PER_SPECIFIC_BRUSH VECS_PER_IMAGE_BRUSH
 
 #define WR_BRUSH_VS_FUNCTION image_brush_vs
 #define WR_BRUSH_FS_FUNCTION image_brush_fs
 
 #include shared,prim_shared,brush
 
 #ifdef WR_FEATURE_ALPHA_PASS
-varying vec2 vLocalPos;
+#define V_LOCAL_POS         varying_vec4_0.xy
 #endif
 
 // Interpolated UV coordinates to sample.
-varying vec2 vUv;
-// X = layer index to sample, Y = flag to allow perspective interpolation of UV.
-flat varying vec2 vLayerAndPerspective;
+#define V_UV                varying_vec4_0.zw
+
+#ifdef WR_FEATURE_ALPHA_PASS
+#define V_COLOR             flat_varying_vec4_0
+#define V_MASK_SWIZZLE      flat_varying_vec4_1.xy
+#define V_TILE_REPEAT       flat_varying_vec4_1.zw
+#endif
+
 // Normalized bounds of the source image in the texture.
-flat varying vec4 vUvBounds;
+#define V_UV_BOUNDS         flat_varying_vec4_2
 // Normalized bounds of the source image in the texture, adjusted to avoid
 // sampling artifacts.
-flat varying vec4 vUvSampleBounds;
-
-#ifdef WR_FEATURE_ALPHA_PASS
-flat varying vec4 vColor;
-flat varying vec2 vMaskSwizzle;
-flat varying vec2 vTileRepeat;
-#endif
+#define V_UV_SAMPLE_BOUNDS  flat_varying_vec4_3
+// Layer index to sample.
+#define V_LAYER             flat_varying_vec4_4.x
+// Flag to allow perspective interpolation of UV.
+#define V_PERSPECTIVE       flat_varying_vec4_4.y
 
 #ifdef WR_VERTEX_SHADER
 
 // Must match the AlphaType enum.
 #define BLEND_MODE_ALPHA            0
 #define BLEND_MODE_PREMUL_ALPHA     1
 
 struct ImageBrushData {
@@ -107,24 +110,25 @@ void image_brush_vs(
             }
             if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) {
               stretch_size.y = stretch_size.y * uv_size.y;
             }
         }
     }
 
     float perspective_interpolate = (brush_flags & BRUSH_FLAG_PERSPECTIVE_INTERPOLATION) != 0 ? 1.0 : 0.0;
-    vLayerAndPerspective = vec2(res.layer, perspective_interpolate);
+    V_LAYER = res.layer;
+    V_PERSPECTIVE = perspective_interpolate;
 
     // Handle case where the UV coords are inverted (e.g. from an
     // external image).
     vec2 min_uv = min(uv0, uv1);
     vec2 max_uv = max(uv0, uv1);
 
-    vUvSampleBounds = vec4(
+    V_UV_SAMPLE_BOUNDS = vec4(
         min_uv + vec2(0.5),
         max_uv - vec2(0.5)
     ) / texture_size.xyxy;
 
     vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
 
 #ifdef WR_FEATURE_ALPHA_PASS
     int color_mode = prim_user_data.x & 0xffff;
@@ -146,136 +150,147 @@ void image_brush_vs(
             f = get_image_quad_uv(specific_resource_address, f);
             break;
         }
         default:
             break;
     }
 #endif
 
-    // Offset and scale vUv here to avoid doing it in the fragment shader.
+    // Offset and scale V_UV here to avoid doing it in the fragment shader.
     vec2 repeat = local_rect.size / stretch_size;
-    vUv = mix(uv0, uv1, f) - min_uv;
-    vUv /= texture_size;
-    vUv *= repeat.xy;
+    V_UV = mix(uv0, uv1, f) - min_uv;
+    V_UV /= texture_size;
+    V_UV *= repeat.xy;
     if (perspective_interpolate == 0.0) {
-        vUv *= vi.world_pos.w;
+        V_UV *= vi.world_pos.w;
     }
 
 #ifdef WR_FEATURE_TEXTURE_RECT
-    vUvBounds = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
+    V_UV_BOUNDS = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
 #else
-    vUvBounds = vec4(min_uv, max_uv) / texture_size.xyxy;
+    V_UV_BOUNDS = vec4(min_uv, max_uv) / texture_size.xyxy;
 #endif
 
 #ifdef WR_FEATURE_ALPHA_PASS
-    vTileRepeat = repeat.xy;
+    V_TILE_REPEAT = repeat.xy;
 
     float opacity = float(prim_user_data.z) / 65535.0;
     switch (blend_mode) {
         case BLEND_MODE_ALPHA:
             image_data.color.a *= opacity;
             break;
         case BLEND_MODE_PREMUL_ALPHA:
         default:
             image_data.color *= opacity;
             break;
     }
 
     switch (color_mode) {
         case COLOR_MODE_ALPHA:
         case COLOR_MODE_BITMAP:
-            vMaskSwizzle = vec2(0.0, 1.0);
-            vColor = image_data.color;
+            V_MASK_SWIZZLE = vec2(0.0, 1.0);
+            V_COLOR = image_data.color;
             break;
         case COLOR_MODE_SUBPX_BG_PASS2:
         case COLOR_MODE_SUBPX_DUAL_SOURCE:
         case COLOR_MODE_IMAGE:
-            vMaskSwizzle = vec2(1.0, 0.0);
-            vColor = image_data.color;
+            V_MASK_SWIZZLE = vec2(1.0, 0.0);
+            V_COLOR = image_data.color;
             break;
         case COLOR_MODE_SUBPX_CONST_COLOR:
         case COLOR_MODE_SUBPX_BG_PASS0:
         case COLOR_MODE_COLOR_BITMAP:
-            vMaskSwizzle = vec2(1.0, 0.0);
-            vColor = vec4(image_data.color.a);
+            V_MASK_SWIZZLE = vec2(1.0, 0.0);
+            V_COLOR = vec4(image_data.color.a);
             break;
         case COLOR_MODE_SUBPX_BG_PASS1:
-            vMaskSwizzle = vec2(-1.0, 1.0);
-            vColor = vec4(image_data.color.a) * image_data.background_color;
+            V_MASK_SWIZZLE = vec2(-1.0, 1.0);
+            V_COLOR = vec4(image_data.color.a) * image_data.background_color;
             break;
         default:
-            vMaskSwizzle = vec2(0.0);
-            vColor = vec4(1.0);
+            V_MASK_SWIZZLE = vec2(0.0);
+            V_COLOR = vec4(1.0);
     }
 
-    vLocalPos = vi.local_pos;
+    V_LOCAL_POS = vi.local_pos;
 #endif
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER
 
 vec2 compute_repeated_uvs(float perspective_divisor) {
-    vec2 uv_size = vUvBounds.zw - vUvBounds.xy;
+    vec2 uv_size = V_UV_BOUNDS.zw - V_UV_BOUNDS.xy;
 
 #ifdef WR_FEATURE_ALPHA_PASS
     // This prevents the uv on the top and left parts of the primitive that was inflated
     // for anti-aliasing purposes from going beyound the range covered by the regular
     // (non-inflated) primitive.
-    vec2 local_uv = max(vUv * perspective_divisor, vec2(0.0));
+    vec2 local_uv = max(V_UV * perspective_divisor, vec2(0.0));
 
     // Handle horizontal and vertical repetitions.
-    vec2 repeated_uv = mod(local_uv, uv_size) + vUvBounds.xy;
+    vec2 repeated_uv = mod(local_uv, uv_size) + V_UV_BOUNDS.xy;
 
     // This takes care of the bottom and right inflated parts.
     // We do it after the modulo because the latter wraps around the values exactly on
     // the right and bottom edges, which we do not want.
-    if (local_uv.x >= vTileRepeat.x * uv_size.x) {
-        repeated_uv.x = vUvBounds.z;
+    if (local_uv.x >= V_TILE_REPEAT.x * uv_size.x) {
+        repeated_uv.x = V_UV_BOUNDS.z;
     }
-    if (local_uv.y >= vTileRepeat.y * uv_size.y) {
-        repeated_uv.y = vUvBounds.w;
+    if (local_uv.y >= V_TILE_REPEAT.y * uv_size.y) {
+        repeated_uv.y = V_UV_BOUNDS.w;
     }
 #else
-    vec2 repeated_uv = mod(vUv * perspective_divisor, uv_size) + vUvBounds.xy;
+    vec2 repeated_uv = mod(V_UV * perspective_divisor, uv_size) + V_UV_BOUNDS.xy;
 #endif
 
     return repeated_uv;
 }
 
 Fragment image_brush_fs() {
-    float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
+    float perspective_divisor = mix(gl_FragCoord.w, 1.0, V_PERSPECTIVE);
 
 #ifdef WR_FEATURE_REPETITION
     vec2 repeated_uv = compute_repeated_uvs(perspective_divisor);
 #else
-    vec2 repeated_uv = vUv * perspective_divisor + vUvBounds.xy;
+    vec2 repeated_uv = V_UV * perspective_divisor + V_UV_BOUNDS.xy;
 #endif
 
     // Clamp the uvs to avoid sampling artifacts.
-    vec2 uv = clamp(repeated_uv, vUvSampleBounds.xy, vUvSampleBounds.zw);
+    vec2 uv = clamp(repeated_uv, V_UV_SAMPLE_BOUNDS.xy, V_UV_SAMPLE_BOUNDS.zw);
 
-    vec4 texel = TEX_SAMPLE(sColor0, vec3(uv, vLayerAndPerspective.x));
+    vec4 texel = TEX_SAMPLE(sColor0, vec3(uv, V_LAYER));
 
     Fragment frag;
 
 #ifdef WR_FEATURE_ALPHA_PASS
     #ifdef WR_FEATURE_ANTIALIASING
-        float alpha = init_transform_fs(vLocalPos);
+        float alpha = init_transform_fs(V_LOCAL_POS);
     #else
         float alpha = 1.0;
     #endif
-    texel.rgb = texel.rgb * vMaskSwizzle.x + texel.aaa * vMaskSwizzle.y;
+    texel.rgb = texel.rgb * V_MASK_SWIZZLE.x + texel.aaa * V_MASK_SWIZZLE.y;
 
     vec4 alpha_mask = texel * alpha;
-    frag.color = vColor * alpha_mask;
+    frag.color = V_COLOR * alpha_mask;
 
     #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
-        frag.blend = alpha_mask * vColor.a;
+        frag.blend = alpha_mask * V_COLOR.a;
     #endif
 #else
     frag.color = texel;
 #endif
 
     return frag;
 }
 #endif
+
+// Undef macro names that could be re-defined by other shaders.
+#undef V_LOCAL_POS
+#undef V_UV
+#undef V_COLOR
+#undef V_MASK_SWIZZLE
+#undef V_TILE_REPEAT
+#undef V_UV_BOUNDS
+#undef V_UV_SAMPLE_BOUNDS
+#undef V_LAYER
+#undef V_PERSPECTIVE
--- a/gfx/wr/webrender/res/brush_solid.glsl
+++ b/gfx/wr/webrender/res/brush_solid.glsl
@@ -5,20 +5,20 @@
 #define VECS_PER_SOLID_BRUSH 1
 #define VECS_PER_SPECIFIC_BRUSH VECS_PER_SOLID_BRUSH
 
 #define WR_BRUSH_VS_FUNCTION solid_brush_vs
 #define WR_BRUSH_FS_FUNCTION solid_brush_fs
 
 #include shared,prim_shared,brush
 
-flat varying vec4 vColor;
+#define V_COLOR             flat_varying_vec4_0
 
 #ifdef WR_FEATURE_ALPHA_PASS
-varying vec2 vLocalPos;
+#define V_LOCAL_POS         varying_vec4_0.xy
 #endif
 
 #ifdef WR_VERTEX_SHADER
 
 struct SolidBrush {
     vec4 color;
 };
 
@@ -37,25 +37,29 @@ void solid_brush_vs(
     mat4 transform,
     PictureTask pic_task,
     int brush_flags,
     vec4 unused
 ) {
     SolidBrush prim = fetch_solid_primitive(prim_address);
 
     float opacity = float(prim_user_data.x) / 65535.0;
-    vColor = prim.color * opacity;
+    V_COLOR = prim.color * opacity;
 
 #ifdef WR_FEATURE_ALPHA_PASS
-    vLocalPos = vi.local_pos;
+    V_LOCAL_POS = vi.local_pos;
 #endif
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER
 Fragment solid_brush_fs() {
-    vec4 color = vColor;
+    vec4 color = V_COLOR;
 #ifdef WR_FEATURE_ALPHA_PASS
-    color *= init_transform_fs(vLocalPos);
+    color *= init_transform_fs(V_LOCAL_POS);
 #endif
     return Fragment(color);
 }
 #endif
+
+// Undef macro names that could be re-defined by other shaders.
+#undef V_COLOR
+#undef V_LOCAL_POS