Bug 1594128 - Add brush_radial_gradient to the multi-brush infrastructure. r=gw
authorNicolas Silva <nsilva@mozilla.com>
Thu, 21 Nov 2019 17:38:05 +0000
changeset 503319 6b339f631b3d6753afa82425708cf2e8786edc34
parent 503318 a215df75f72fe4031570fe5d9765f103e73cdaeb
child 503320 f83f356ca522614098013cc0b8178b48e01f6215
push id36833
push userbtara@mozilla.com
push dateFri, 22 Nov 2019 21:40:53 +0000
treeherdermozilla-central@2c912e46295e [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 - Add brush_radial_gradient to the multi-brush infrastructure. r=gw Differential Revision: https://phabricator.services.mozilla.com/D53996
gfx/wr/webrender/res/brush.glsl
gfx/wr/webrender/res/brush_multi.glsl
gfx/wr/webrender/res/brush_radial_gradient.glsl
--- a/gfx/wr/webrender/res/brush.glsl
+++ b/gfx/wr/webrender/res/brush.glsl
@@ -234,16 +234,22 @@ void main(void) {
             break;
         #endif
 
         #ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
         case BRUSH_KIND_LINEAR_GRADIENT:
             linear_gradient_brush_vs(BRUSH_VS_PARAMS);
             break;
         #endif
+
+        #ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
+        case BRUSH_KIND_RADIAL_GRADIENT:
+            radial_gradient_brush_vs(BRUSH_VS_PARAMS);
+            break;
+        #endif
     }
 
 #else
     WR_BRUSH_VS_FUNCTION(BRUSH_VS_PARAMS);
 #endif
 
 }
 
@@ -301,16 +307,22 @@ void main(void) {
         }
 #endif
 #ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
         case BRUSH_KIND_LINEAR_GRADIENT: {
             frag = linear_gradient_brush_fs();
             break;
         }
 #endif
+#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
+        case BRUSH_KIND_RADIAL_GRADIENT: {
+            frag = radial_gradient_brush_fs();
+            break;
+        }
+#endif
     }
 #else
     frag = WR_BRUSH_FS_FUNCTION();
 #endif
 
 
 #ifdef WR_FEATURE_ALPHA_PASS
     // Apply the clip mask
--- a/gfx/wr/webrender/res/brush_multi.glsl
+++ b/gfx/wr/webrender/res/brush_multi.glsl
@@ -39,16 +39,24 @@ int vecs_per_brush(int brush_kind);
 #undef VECS_PER_SPECIFIC_BRUSH
 #undef WR_BRUSH_VS_FUNCTION
 #undef WR_BRUSH_FS_FUNCTION
 
 #ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
 #include brush_linear_gradient
 #endif
 
+#undef VECS_PER_SPECIFIC_BRUSH
+#undef WR_BRUSH_VS_FUNCTION
+#undef WR_BRUSH_FS_FUNCTION
+
+#ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
+#include brush_radial_gradient
+#endif
+
 int vecs_per_brush(int brush_kind) {
     int result;
     switch (brush_kind) {
         #ifdef WR_FEATURE_IMAGE_BRUSH
         case BRUSH_KIND_IMAGE:
             result = VECS_PER_IMAGE_BRUSH;
             break;
         #endif
@@ -71,12 +79,18 @@ int vecs_per_brush(int brush_kind) {
             break;
         #endif
 
         #ifdef WR_FEATURE_LINEAR_GRADIENT_BRUSH
         case BRUSH_KIND_LINEAR_GRADIENT:
             result = VECS_PER_LINEAR_GRADIENT_BRUSH;
             break;
         #endif
+
+        #ifdef WR_FEATURE_RADIAL_GRADIENT_BRUSH
+        case BRUSH_KIND_RADIAL_GRADIENT:
+            result = VECS_PER_RADIAL_GRADIENT_BRUSH;
+            break;
+        #endif
     }
 
     return result;
 }
--- a/gfx/wr/webrender/res/brush_radial_gradient.glsl
+++ b/gfx/wr/webrender/res/brush_radial_gradient.glsl
@@ -5,29 +5,30 @@
 #define VECS_PER_RADIAL_GRADIENT_BRUSH 2
 #define VECS_PER_SPECIFIC_BRUSH VECS_PER_RADIAL_GRADIENT_BRUSH
 
 #define WR_BRUSH_VS_FUNCTION radial_gradient_brush_vs
 #define WR_BRUSH_FS_FUNCTION radial_gradient_brush_fs
 
 #include shared,prim_shared,brush
 
-flat varying HIGHP_FS_ADDRESS int vGradientAddress;
-flat varying float vGradientRepeat;
+#define V_GRADIENT_ADDRESS  flat_varying_highp_int_address_0
 
-flat varying vec2 vCenter;
-flat varying float vStartRadius;
-flat varying float vEndRadius;
+#define V_CENTER            flat_varying_vec4_0.xy
+#define V_START_RADIUS      flat_varying_vec4_0.z
+#define V_END_RADIUS        flat_varying_vec4_0.w
 
-varying vec2 vPos;
-flat varying vec2 vRepeatedSize;
+#define V_REPEATED_SIZE     flat_varying_vec4_1.xy
+#define V_GRADIENT_REPEAT   flat_varying_vec4_1.z
+
+#define V_POS               varying_vec4_0.zw
 
 #ifdef WR_FEATURE_ALPHA_PASS
-varying vec2 vLocalPos;
-flat varying vec2 vTileRepeat;
+#define V_LOCAL_POS         varying_vec4_0.xy
+#define V_TILE_REPEAT       flat_varying_vec4_2.xy
 #endif
 
 #ifdef WR_VERTEX_SHADER
 
 struct RadialGradient {
     vec4 center_start_end_radius;
     float ratio_xy;
     int extend_mode;
@@ -54,111 +55,122 @@ void radial_gradient_brush_vs(
     mat4 transform,
     PictureTask pic_task,
     int brush_flags,
     vec4 texel_rect
 ) {
     RadialGradient gradient = fetch_radial_gradient(prim_address);
 
     if ((brush_flags & BRUSH_FLAG_SEGMENT_RELATIVE) != 0) {
-        vPos = (vi.local_pos - segment_rect.p0) / segment_rect.size;
-        vPos = vPos * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
-        vPos = vPos * local_rect.size;
+        V_POS = (vi.local_pos - segment_rect.p0) / segment_rect.size;
+        V_POS = V_POS * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
+        V_POS = V_POS * local_rect.size;
     } else {
-        vPos = vi.local_pos - local_rect.p0;
+        V_POS = vi.local_pos - local_rect.p0;
     }
 
-    vCenter = gradient.center_start_end_radius.xy;
-    vStartRadius = gradient.center_start_end_radius.z;
-    vEndRadius = gradient.center_start_end_radius.w;
+    V_CENTER = gradient.center_start_end_radius.xy;
+    V_START_RADIUS = gradient.center_start_end_radius.z;
+    V_END_RADIUS = gradient.center_start_end_radius.w;
 
     // Transform all coordinates by the y scale so the
     // fragment shader can work with circles
     vec2 tile_repeat = local_rect.size / gradient.stretch_size;
-    vPos.y *= gradient.ratio_xy;
-    vCenter.y *= gradient.ratio_xy;
-    vRepeatedSize = gradient.stretch_size;
-    vRepeatedSize.y *=  gradient.ratio_xy;
+    V_POS.y *= gradient.ratio_xy;
+    V_CENTER.y *= gradient.ratio_xy;
+    V_REPEATED_SIZE = gradient.stretch_size;
+    V_REPEATED_SIZE.y *=  gradient.ratio_xy;
 
-    vGradientAddress = prim_user_data.x;
+    V_GRADIENT_ADDRESS = prim_user_data.x;
 
     // Whether to repeat the gradient instead of clamping.
-    vGradientRepeat = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
+    V_GRADIENT_REPEAT = float(gradient.extend_mode != EXTEND_MODE_CLAMP);
 
 #ifdef WR_FEATURE_ALPHA_PASS
-    vTileRepeat = tile_repeat.xy;
-    vLocalPos = vi.local_pos;
+    V_TILE_REPEAT = tile_repeat.xy;
+    V_LOCAL_POS = vi.local_pos;
 #endif
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER
 Fragment radial_gradient_brush_fs() {
 
 #ifdef WR_FEATURE_ALPHA_PASS
     // Handle top and left inflated edges (see brush_image).
-    vec2 local_pos = max(vPos, vec2(0.0));
+    vec2 local_pos = max(V_POS, vec2(0.0));
 
     // Apply potential horizontal and vertical repetitions.
-    vec2 pos = mod(local_pos, vRepeatedSize);
+    vec2 pos = mod(local_pos, V_REPEATED_SIZE);
 
-    vec2 prim_size = vRepeatedSize * vTileRepeat;
+    vec2 prim_size = V_REPEATED_SIZE * V_TILE_REPEAT;
     // Handle bottom and right inflated edges (see brush_image).
     if (local_pos.x >= prim_size.x) {
-        pos.x = vRepeatedSize.x;
+        pos.x = V_REPEATED_SIZE.x;
     }
     if (local_pos.y >= prim_size.y) {
-        pos.y = vRepeatedSize.y;
+        pos.y = V_REPEATED_SIZE.y;
     }
 #else
     // Apply potential horizontal and vertical repetitions.
-    vec2 pos = mod(vPos, vRepeatedSize);
+    vec2 pos = mod(V_POS, V_REPEATED_SIZE);
 #endif
 
-    vec2 pd = pos - vCenter;
-    float rd = vEndRadius - vStartRadius;
+    vec2 pd = pos - V_CENTER;
+    float rd = V_END_RADIUS - V_START_RADIUS;
 
-    // Solve for t in length(t - pd) = vStartRadius + t * rd
+    // Solve for t in length(t - pd) = V_START_RADIUS + t * rd
     // using a quadratic equation in form of At^2 - 2Bt + C = 0
     float A = -(rd * rd);
-    float B = vStartRadius * rd;
-    float C = dot(pd, pd) - vStartRadius * vStartRadius;
+    float B = V_START_RADIUS * rd;
+    float C = dot(pd, pd) - V_START_RADIUS * V_START_RADIUS;
 
     float offset;
     if (A == 0.0) {
         // Since A is 0, just solve for -2Bt + C = 0
         if (B == 0.0) {
             discard;
         }
         float t = 0.5 * C / B;
-        if (vStartRadius + rd * t >= 0.0) {
+        if (V_START_RADIUS + rd * t >= 0.0) {
             offset = t;
         } else {
             discard;
         }
     } else {
         float discr = B * B - A * C;
         if (discr < 0.0) {
             discard;
         }
         discr = sqrt(discr);
         float t0 = (B + discr) / A;
         float t1 = (B - discr) / A;
-        if (vStartRadius + rd * t0 >= 0.0) {
+        if (V_START_RADIUS + rd * t0 >= 0.0) {
             offset = t0;
-        } else if (vStartRadius + rd * t1 >= 0.0) {
+        } else if (V_START_RADIUS + rd * t1 >= 0.0) {
             offset = t1;
         } else {
             discard;
         }
     }
 
-    vec4 color = sample_gradient(vGradientAddress,
+    vec4 color = sample_gradient(V_GRADIENT_ADDRESS,
                                  offset,
-                                 vGradientRepeat);
+                                 V_GRADIENT_REPEAT);
 
 #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_GRADIENT_ADDRESS
+#undef V_CENTER
+#undef V_START_RADIUS
+#undef V_END_RADIUS
+#undef V_REPEATED_SIZE
+#undef V_GRADIENT_REPEAT
+#undef V_POS
+#undef V_LOCAL_POS
+#undef V_TILE_REPEAT