Bug 1399630 - Update webrender to commit 878914aaf4d230fa449ff7800b529fe9023fc3c5. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 15 Sep 2017 08:07:24 -0400
changeset 665580 31adad19ac0c360ecab9ac66787e07e3c66c13a6
parent 665579 5500f432a88828303595de17bf31d127baa12ff9
child 665581 2e6f093af5981da3ca2802f4dd6f7de1ee0b25ce
push id80115
push userbmo:eoger@fastmail.com
push dateFri, 15 Sep 2017 18:29:01 +0000
reviewersjrmuizel
bugs1399630
milestone57.0a1
Bug 1399630 - Update webrender to commit 878914aaf4d230fa449ff7800b529fe9023fc3c5. r=jrmuizel MozReview-Commit-ID: IuNfqTZ57Tb
gfx/doc/README.webrender
gfx/webrender/res/base.glsl
gfx/webrender/res/ps_box_shadow.fs.glsl
gfx/webrender/res/ps_box_shadow.glsl
gfx/webrender/res/ps_box_shadow.vs.glsl
gfx/webrender/res/ps_image.fs.glsl
gfx/webrender/res/ps_image.glsl
gfx/webrender/res/ps_image.vs.glsl
gfx/webrender/res/ps_rectangle.fs.glsl
gfx/webrender/res/ps_rectangle.glsl
gfx/webrender/res/ps_rectangle.vs.glsl
gfx/webrender/res/ps_text_run.fs.glsl
gfx/webrender/res/ps_text_run.glsl
gfx/webrender/res/ps_text_run.vs.glsl
gfx/webrender/res/ps_yuv_image.fs.glsl
gfx/webrender/res/ps_yuv_image.glsl
gfx/webrender/res/ps_yuv_image.vs.glsl
gfx/webrender/res/shared.glsl
gfx/webrender/src/tiling.rs
gfx/webrender_api/src/display_item.rs
--- a/gfx/doc/README.webrender
+++ b/gfx/doc/README.webrender
@@ -74,9 +74,9 @@ there is another crate in m-c called moz
 the same folder to store its rust dependencies. If one of the libraries that is
 required by both mozjs_sys and webrender is updated without updating the other
 project's Cargo.lock file, that results in build bustage.
 This means that any time you do this sort of manual update of packages, you need
 to make sure that mozjs_sys also has its Cargo.lock file updated if needed, hence
 the need to run the cargo update command in js/src as well. Hopefully this will
 be resolved soon.
 
-Latest Commit: 7d9444a24fb98bcc41afdca2a5bf145d514500f1
+Latest Commit: 878914aaf4d230fa449ff7800b529fe9023fc3c5
new file mode 100644
--- /dev/null
+++ b/gfx/webrender/res/base.glsl
@@ -0,0 +1,38 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if defined(GL_ES)
+    #if GL_ES == 1
+        #ifdef GL_FRAGMENT_PRECISION_HIGH
+        precision highp sampler2DArray;
+        #else
+        precision mediump sampler2DArray;
+        #endif
+
+        // Sampler default precision is lowp on mobile GPUs.
+        // This causes RGBA32F texture data to be clamped to 16 bit floats on some GPUs (e.g. Mali-T880).
+        // Define highp precision macro to allow lossless FLOAT texture sampling.
+        #define HIGHP_SAMPLER_FLOAT highp
+
+        // texelFetchOffset is buggy on some Android GPUs (see issue #1694).
+        // Fallback to texelFetch on mobile GPUs.
+        #define TEXEL_FETCH(sampler, position, lod, offset) texelFetch(sampler, position + offset, lod)
+    #else
+        #define HIGHP_SAMPLER_FLOAT
+        #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
+    #endif
+#else
+    #define HIGHP_SAMPLER_FLOAT
+    #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
+#endif
+
+#ifdef WR_VERTEX_SHADER
+    #define varying out
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+    precision highp float;
+
+    #define varying in
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_box_shadow.fs.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    vec4 clip_scale = vec4(1.0, 1.0, 1.0, do_clip());
-
-    // Mirror and stretch the box shadow corner over the entire
-    // primitives.
-    vec2 uv = vMirrorPoint - abs(vUv.xy - vMirrorPoint);
-
-    // Ensure that we don't fetch texels outside the box
-    // shadow corner. This can happen, for example, when
-    // drawing the outer parts of an inset box shadow.
-    uv = clamp(uv, vec2(0.0), vec2(1.0));
-
-    // Map the unit UV to the actual UV rect in the cache.
-    uv = mix(vCacheUvRectCoords.xy, vCacheUvRectCoords.zw, uv);
-
-    // Modulate the box shadow by the color.
-    float mask = texture(sSharedCacheA8, vec3(uv, vUv.z)).r;
-    oFragColor = clip_scale * dither(vColor * vec4(1.0, 1.0, 1.0, mask));
-}
--- a/gfx/webrender/res/ps_box_shadow.glsl
+++ b/gfx/webrender/res/ps_box_shadow.glsl
@@ -4,8 +4,65 @@
 
 #include shared,prim_shared
 
 flat varying vec4 vColor;
 
 varying vec3 vUv;
 flat varying vec2 vMirrorPoint;
 flat varying vec4 vCacheUvRectCoords;
+
+#ifdef WR_VERTEX_SHADER
+#define BS_HEADER_VECS 4
+
+void main(void) {
+    Primitive prim = load_primitive();
+    BoxShadow bs = fetch_boxshadow(prim.specific_prim_address);
+    RectWithSize segment_rect = fetch_instance_geometry(prim.specific_prim_address + BS_HEADER_VECS + prim.user_data0);
+
+    VertexInfo vi = write_vertex(segment_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 prim.local_rect);
+
+    RenderTaskData child_task = fetch_render_task(prim.user_data1);
+    vUv.z = child_task.data1.x;
+
+    // Constant offsets to inset from bilinear filtering border.
+    vec2 patch_origin = child_task.data0.xy + vec2(1.0);
+    vec2 patch_size_device_pixels = child_task.data0.zw - vec2(2.0);
+    vec2 patch_size = patch_size_device_pixels / uDevicePixelRatio;
+
+    vUv.xy = (vi.local_pos - prim.local_rect.p0) / patch_size;
+    vMirrorPoint = 0.5 * prim.local_rect.size / patch_size;
+
+    vec2 texture_size = vec2(textureSize(sSharedCacheA8, 0));
+    vCacheUvRectCoords = vec4(patch_origin, patch_origin + patch_size_device_pixels) / texture_size.xyxy;
+
+    vColor = bs.color;
+
+    write_clip(vi.screen_pos, prim.clip_area);
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    vec4 clip_scale = vec4(1.0, 1.0, 1.0, do_clip());
+
+    // Mirror and stretch the box shadow corner over the entire
+    // primitives.
+    vec2 uv = vMirrorPoint - abs(vUv.xy - vMirrorPoint);
+
+    // Ensure that we don't fetch texels outside the box
+    // shadow corner. This can happen, for example, when
+    // drawing the outer parts of an inset box shadow.
+    uv = clamp(uv, vec2(0.0), vec2(1.0));
+
+    // Map the unit UV to the actual UV rect in the cache.
+    uv = mix(vCacheUvRectCoords.xy, vCacheUvRectCoords.zw, uv);
+
+    // Modulate the box shadow by the color.
+    float mask = texture(sSharedCacheA8, vec3(uv, vUv.z)).r;
+    oFragColor = clip_scale * dither(vColor * vec4(1.0, 1.0, 1.0, mask));
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_box_shadow.vs.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#define BS_HEADER_VECS 4
-
-void main(void) {
-    Primitive prim = load_primitive();
-    BoxShadow bs = fetch_boxshadow(prim.specific_prim_address);
-    RectWithSize segment_rect = fetch_instance_geometry(prim.specific_prim_address + BS_HEADER_VECS + prim.user_data0);
-
-    VertexInfo vi = write_vertex(segment_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 prim.local_rect);
-
-    RenderTaskData child_task = fetch_render_task(prim.user_data1);
-    vUv.z = child_task.data1.x;
-
-    // Constant offsets to inset from bilinear filtering border.
-    vec2 patch_origin = child_task.data0.xy + vec2(1.0);
-    vec2 patch_size_device_pixels = child_task.data0.zw - vec2(2.0);
-    vec2 patch_size = patch_size_device_pixels / uDevicePixelRatio;
-
-    vUv.xy = (vi.local_pos - prim.local_rect.p0) / patch_size;
-    vMirrorPoint = 0.5 * prim.local_rect.size / patch_size;
-
-    vec2 texture_size = vec2(textureSize(sSharedCacheA8, 0));
-    vCacheUvRectCoords = vec4(patch_origin, patch_origin + patch_size_device_pixels) / texture_size.xyxy;
-
-    vColor = bs.color;
-
-    write_clip(vi.screen_pos, prim.clip_area);
-}
deleted file mode 100644
--- a/gfx/webrender/res/ps_image.fs.glsl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-#ifdef WR_FEATURE_TRANSFORM
-    float alpha = 0.0;
-    vec2 pos = init_transform_fs(vLocalPos, alpha);
-
-    // We clamp the texture coordinate calculation here to the local rectangle boundaries,
-    // which makes the edge of the texture stretch instead of repeat.
-    vec2 relative_pos_in_rect = clamp(pos, vLocalBounds.xy, vLocalBounds.zw) - vLocalBounds.xy;
-#else
-    float alpha = 1.0;
-    vec2 relative_pos_in_rect = vLocalPos;
-#endif
-
-    alpha = min(alpha, do_clip());
-
-    // We calculate the particular tile this fragment belongs to, taking into
-    // account the spacing in between tiles. We only paint if our fragment does
-    // not fall into that spacing.
-    vec2 position_in_tile = mod(relative_pos_in_rect, vStretchSize + vTileSpacing);
-    vec2 st = vTextureOffset + ((position_in_tile / vStretchSize) * vTextureSize);
-    st = clamp(st, vStRect.xy, vStRect.zw);
-
-    alpha = alpha * float(all(bvec2(step(position_in_tile, vStretchSize))));
-
-    oFragColor = vec4(alpha) * TEX_SAMPLE(sColor0, vec3(st, vLayer));
-}
--- a/gfx/webrender/res/ps_image.glsl
+++ b/gfx/webrender/res/ps_image.glsl
@@ -14,8 +14,98 @@ flat varying vec4 vStRect;        // Rec
 flat varying float vLayer;
 
 #ifdef WR_FEATURE_TRANSFORM
 varying vec3 vLocalPos;
 #else
 varying vec2 vLocalPos;
 #endif
 flat varying vec2 vStretchSize;
+
+#ifdef WR_VERTEX_SHADER
+void main(void) {
+    Primitive prim = load_primitive();
+    Image image = fetch_image(prim.specific_prim_address);
+    ImageResource res = fetch_image_resource(prim.user_data0);
+
+#ifdef WR_FEATURE_TRANSFORM
+    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
+                                                    prim.local_clip_rect,
+                                                    prim.z,
+                                                    prim.layer,
+                                                    prim.task,
+                                                    prim.local_rect);
+    vLocalPos = vi.local_pos;
+#else
+    VertexInfo vi = write_vertex(prim.local_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 prim.local_rect);
+    vLocalPos = vi.local_pos - prim.local_rect.p0;
+#endif
+
+    write_clip(vi.screen_pos, prim.clip_area);
+
+    // If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
+    // non-normalized texture coordinates.
+#ifdef WR_FEATURE_TEXTURE_RECT
+    vec2 texture_size_normalization_factor = vec2(1, 1);
+#else
+    vec2 texture_size_normalization_factor = vec2(textureSize(sColor0, 0));
+#endif
+
+    vec2 uv0, uv1;
+
+    if (image.sub_rect.x < 0.0) {
+        uv0 = res.uv_rect.xy;
+        uv1 = res.uv_rect.zw;
+    } else {
+        uv0 = res.uv_rect.xy + image.sub_rect.xy;
+        uv1 = res.uv_rect.xy + image.sub_rect.zw;
+    }
+
+    // vUv will contain how many times this image has wrapped around the image size.
+    vec2 st0 = uv0 / texture_size_normalization_factor;
+    vec2 st1 = uv1 / texture_size_normalization_factor;
+
+    vLayer = res.layer;
+    vTextureSize = st1 - st0;
+    vTextureOffset = st0;
+    vTileSpacing = image.stretch_size_and_tile_spacing.zw;
+    vStretchSize = image.stretch_size_and_tile_spacing.xy;
+
+    // We clamp the texture coordinates to the half-pixel offset from the borders
+    // in order to avoid sampling outside of the texture area.
+    vec2 half_texel = vec2(0.5) / texture_size_normalization_factor;
+    vStRect = vec4(min(st0, st1) + half_texel, max(st0, st1) - half_texel);
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+#ifdef WR_FEATURE_TRANSFORM
+    float alpha = 0.0;
+    vec2 pos = init_transform_fs(vLocalPos, alpha);
+
+    // We clamp the texture coordinate calculation here to the local rectangle boundaries,
+    // which makes the edge of the texture stretch instead of repeat.
+    vec2 relative_pos_in_rect = clamp(pos, vLocalBounds.xy, vLocalBounds.zw) - vLocalBounds.xy;
+#else
+    float alpha = 1.0;
+    vec2 relative_pos_in_rect = vLocalPos;
+#endif
+
+    alpha = min(alpha, do_clip());
+
+    // We calculate the particular tile this fragment belongs to, taking into
+    // account the spacing in between tiles. We only paint if our fragment does
+    // not fall into that spacing.
+    vec2 position_in_tile = mod(relative_pos_in_rect, vStretchSize + vTileSpacing);
+    vec2 st = vTextureOffset + ((position_in_tile / vStretchSize) * vTextureSize);
+    st = clamp(st, vStRect.xy, vStRect.zw);
+
+    alpha = alpha * float(all(bvec2(step(position_in_tile, vStretchSize))));
+
+    oFragColor = vec4(alpha) * TEX_SAMPLE(sColor0, vec3(st, vLayer));
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_image.vs.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    Primitive prim = load_primitive();
-    Image image = fetch_image(prim.specific_prim_address);
-    ImageResource res = fetch_image_resource(prim.user_data0);
-
-#ifdef WR_FEATURE_TRANSFORM
-    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
-                                                    prim.local_clip_rect,
-                                                    prim.z,
-                                                    prim.layer,
-                                                    prim.task,
-                                                    prim.local_rect);
-    vLocalPos = vi.local_pos;
-#else
-    VertexInfo vi = write_vertex(prim.local_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 prim.local_rect);
-    vLocalPos = vi.local_pos - prim.local_rect.p0;
-#endif
-
-    write_clip(vi.screen_pos, prim.clip_area);
-
-    // If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
-    // non-normalized texture coordinates.
-#ifdef WR_FEATURE_TEXTURE_RECT
-    vec2 texture_size_normalization_factor = vec2(1, 1);
-#else
-    vec2 texture_size_normalization_factor = vec2(textureSize(sColor0, 0));
-#endif
-
-    vec2 uv0, uv1;
-
-    if (image.sub_rect.x < 0.0) {
-        uv0 = res.uv_rect.xy;
-        uv1 = res.uv_rect.zw;
-    } else {
-        uv0 = res.uv_rect.xy + image.sub_rect.xy;
-        uv1 = res.uv_rect.xy + image.sub_rect.zw;
-    }
-
-    // vUv will contain how many times this image has wrapped around the image size.
-    vec2 st0 = uv0 / texture_size_normalization_factor;
-    vec2 st1 = uv1 / texture_size_normalization_factor;
-
-    vLayer = res.layer;
-    vTextureSize = st1 - st0;
-    vTextureOffset = st0;
-    vTileSpacing = image.stretch_size_and_tile_spacing.zw;
-    vStretchSize = image.stretch_size_and_tile_spacing.xy;
-
-    // We clamp the texture coordinates to the half-pixel offset from the borders
-    // in order to avoid sampling outside of the texture area.
-    vec2 half_texel = vec2(0.5) / texture_size_normalization_factor;
-    vStRect = vec4(min(st0, st1) + half_texel, max(st0, st1) - half_texel);
-}
deleted file mode 100644
--- a/gfx/webrender/res/ps_rectangle.fs.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    float alpha = 1.0;
-#ifdef WR_FEATURE_TRANSFORM
-    alpha = 0.0;
-    init_transform_fs(vLocalPos, alpha);
-#endif
-
-#ifdef WR_FEATURE_CLIP
-    alpha = min(alpha, do_clip());
-#endif
-    oFragColor = vColor * vec4(1.0, 1.0, 1.0, alpha);
-}
--- a/gfx/webrender/res/ps_rectangle.glsl
+++ b/gfx/webrender/res/ps_rectangle.glsl
@@ -4,8 +4,51 @@
 
 #include shared,prim_shared
 
 varying vec4 vColor;
 
 #ifdef WR_FEATURE_TRANSFORM
 varying vec3 vLocalPos;
 #endif
+
+#ifdef WR_VERTEX_SHADER
+void main(void) {
+    Primitive prim = load_primitive();
+    Rectangle rect = fetch_rectangle(prim.specific_prim_address);
+    vColor = rect.color;
+#ifdef WR_FEATURE_TRANSFORM
+    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
+                                                    prim.local_clip_rect,
+                                                    prim.z,
+                                                    prim.layer,
+                                                    prim.task,
+                                                    prim.local_rect);
+    vLocalPos = vi.local_pos;
+#else
+    VertexInfo vi = write_vertex(prim.local_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 prim.local_rect);
+#endif
+
+#ifdef WR_FEATURE_CLIP
+    write_clip(vi.screen_pos, prim.clip_area);
+#endif
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    float alpha = 1.0;
+#ifdef WR_FEATURE_TRANSFORM
+    alpha = 0.0;
+    init_transform_fs(vLocalPos, alpha);
+#endif
+
+#ifdef WR_FEATURE_CLIP
+    alpha = min(alpha, do_clip());
+#endif
+    oFragColor = vColor * vec4(1.0, 1.0, 1.0, alpha);
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_rectangle.vs.glsl
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    Primitive prim = load_primitive();
-    Rectangle rect = fetch_rectangle(prim.specific_prim_address);
-    vColor = rect.color;
-#ifdef WR_FEATURE_TRANSFORM
-    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
-                                                    prim.local_clip_rect,
-                                                    prim.z,
-                                                    prim.layer,
-                                                    prim.task,
-                                                    prim.local_rect);
-    vLocalPos = vi.local_pos;
-#else
-    VertexInfo vi = write_vertex(prim.local_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 prim.local_rect);
-#endif
-
-#ifdef WR_FEATURE_CLIP
-    write_clip(vi.screen_pos, prim.clip_area);
-#endif
-}
deleted file mode 100644
--- a/gfx/webrender/res/ps_text_run.fs.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    vec3 tc = vec3(clamp(vUv.xy, vUvBorder.xy, vUvBorder.zw), vUv.z);
-#ifdef WR_FEATURE_SUBPIXEL_AA
-    //note: the blend mode is not compatible with clipping
-    oFragColor = texture(sColor0, tc);
-#else
-    float alpha = texture(sColor0, tc).a;
-#ifdef WR_FEATURE_TRANSFORM
-    float a = 0.0;
-    init_transform_fs(vLocalPos, a);
-    alpha *= a;
-#endif
-    vec4 color = vColor;
-    alpha = min(alpha, do_clip());
-    oFragColor = vec4(vColor.rgb, vColor.a * alpha);
-#endif
-}
--- a/gfx/webrender/res/ps_text_run.glsl
+++ b/gfx/webrender/res/ps_text_run.glsl
@@ -6,8 +6,79 @@
 
 flat varying vec4 vColor;
 varying vec3 vUv;
 flat varying vec4 vUvBorder;
 
 #ifdef WR_FEATURE_TRANSFORM
 varying vec3 vLocalPos;
 #endif
+
+#ifdef WR_VERTEX_SHADER
+void main(void) {
+    Primitive prim = load_primitive();
+    TextRun text = fetch_text_run(prim.specific_prim_address);
+
+    int glyph_index = prim.user_data0;
+    int resource_address = prim.user_data1;
+
+    Glyph glyph = fetch_glyph(prim.specific_prim_address,
+                              glyph_index,
+                              text.subpx_dir);
+    GlyphResource res = fetch_glyph_resource(resource_address);
+
+    vec2 local_pos = glyph.offset +
+                     text.offset +
+                     vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio;
+
+    RectWithSize local_rect = RectWithSize(local_pos,
+                                           (res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio);
+
+#ifdef WR_FEATURE_TRANSFORM
+    TransformVertexInfo vi = write_transform_vertex(local_rect,
+                                                    prim.local_clip_rect,
+                                                    prim.z,
+                                                    prim.layer,
+                                                    prim.task,
+                                                    local_rect);
+    vLocalPos = vi.local_pos;
+    vec2 f = (vi.local_pos.xy / vi.local_pos.z - local_rect.p0) / local_rect.size;
+#else
+    VertexInfo vi = write_vertex(local_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 local_rect);
+    vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
+#endif
+
+    write_clip(vi.screen_pos, prim.clip_area);
+
+    vec2 texture_size = vec2(textureSize(sColor0, 0));
+    vec2 st0 = res.uv_rect.xy / texture_size;
+    vec2 st1 = res.uv_rect.zw / texture_size;
+
+    vColor = text.color;
+    vUv = vec3(mix(st0, st1, f), res.layer);
+    vUvBorder = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    vec3 tc = vec3(clamp(vUv.xy, vUvBorder.xy, vUvBorder.zw), vUv.z);
+#ifdef WR_FEATURE_SUBPIXEL_AA
+    //note: the blend mode is not compatible with clipping
+    oFragColor = texture(sColor0, tc);
+#else
+    float alpha = texture(sColor0, tc).a;
+#ifdef WR_FEATURE_TRANSFORM
+    float a = 0.0;
+    init_transform_fs(vLocalPos, a);
+    alpha *= a;
+#endif
+    vec4 color = vColor;
+    alpha = min(alpha, do_clip());
+    oFragColor = vec4(vColor.rgb, vColor.a * alpha);
+#endif
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_text_run.vs.glsl
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    Primitive prim = load_primitive();
-    TextRun text = fetch_text_run(prim.specific_prim_address);
-
-    int glyph_index = prim.user_data0;
-    int resource_address = prim.user_data1;
-
-    Glyph glyph = fetch_glyph(prim.specific_prim_address,
-                              glyph_index,
-                              text.subpx_dir);
-    GlyphResource res = fetch_glyph_resource(resource_address);
-
-    vec2 local_pos = glyph.offset +
-                     text.offset +
-                     vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio;
-
-    RectWithSize local_rect = RectWithSize(local_pos,
-                                           (res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio);
-
-#ifdef WR_FEATURE_TRANSFORM
-    TransformVertexInfo vi = write_transform_vertex(local_rect,
-                                                    prim.local_clip_rect,
-                                                    prim.z,
-                                                    prim.layer,
-                                                    prim.task,
-                                                    local_rect);
-    vLocalPos = vi.local_pos;
-    vec2 f = (vi.local_pos.xy / vi.local_pos.z - local_rect.p0) / local_rect.size;
-#else
-    VertexInfo vi = write_vertex(local_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 local_rect);
-    vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
-#endif
-
-    write_clip(vi.screen_pos, prim.clip_area);
-
-    vec2 texture_size = vec2(textureSize(sColor0, 0));
-    vec2 st0 = res.uv_rect.xy / texture_size;
-    vec2 st1 = res.uv_rect.zw / texture_size;
-
-    vColor = text.color;
-    vUv = vec3(mix(st0, st1, f), res.layer);
-    vUvBorder = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
-}
deleted file mode 100644
--- a/gfx/webrender/res/ps_yuv_image.fs.glsl
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(WR_FEATURE_YUV_REC601) && !defined(WR_FEATURE_YUV_REC709)
-#define WR_FEATURE_YUV_REC601
-#endif
-
-// The constants added to the Y, U and V components are applied in the fragment shader.
-#if defined(WR_FEATURE_YUV_REC601)
-// From Rec601:
-// [R]   [1.1643835616438356,  0.0,                 1.5960267857142858   ]   [Y -  16]
-// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708   ] x [U - 128]
-// [B]   [1.1643835616438356,  2.017232142857143,   8.862867620416422e-17]   [V - 128]
-//
-// For the range [0,1] instead of [0,255].
-//
-// The matrix is stored in column-major.
-const mat3 YuvColorMatrix = mat3(
-    1.16438,  1.16438, 1.16438,
-    0.0,     -0.39176, 2.01723,
-    1.59603, -0.81297, 0.0
-);
-#elif defined(WR_FEATURE_YUV_REC709)
-// From Rec709:
-// [R]   [1.1643835616438356,  4.2781193979771426e-17, 1.7927410714285714]   [Y -  16]
-// [G] = [1.1643835616438358, -0.21324861427372963,   -0.532909328559444 ] x [U - 128]
-// [B]   [1.1643835616438356,  2.1124017857142854,     0.0               ]   [V - 128]
-//
-// For the range [0,1] instead of [0,255]:
-//
-// The matrix is stored in column-major.
-const mat3 YuvColorMatrix = mat3(
-    1.16438,  1.16438,  1.16438,
-    0.0    , -0.21325,  2.11240,
-    1.79274, -0.53291,  0.0
-);
-#endif
-
-void main(void) {
-#ifdef WR_FEATURE_TRANSFORM
-    float alpha = 0.0;
-    vec2 pos = init_transform_fs(vLocalPos, alpha);
-
-    // We clamp the texture coordinate calculation here to the local rectangle boundaries,
-    // which makes the edge of the texture stretch instead of repeat.
-    vec2 relative_pos_in_rect = clamp(pos, vLocalBounds.xy, vLocalBounds.zw) - vLocalBounds.xy;
-#else
-    float alpha = 1.0;;
-    vec2 relative_pos_in_rect = vLocalPos;
-#endif
-
-    alpha = min(alpha, do_clip());
-
-    // We clamp the texture coordinates to the half-pixel offset from the borders
-    // in order to avoid sampling outside of the texture area.
-    vec2 st_y = vTextureOffsetY + clamp(
-        relative_pos_in_rect / vStretchSize * vTextureSizeY,
-        vHalfTexelY, vTextureSizeY - vHalfTexelY);
-#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
-    vec2 uv_offset = clamp(
-        relative_pos_in_rect / vStretchSize * vTextureSizeUv,
-        vHalfTexelUv, vTextureSizeUv - vHalfTexelUv);
-    // NV12 only uses 2 textures. The sColor0 is for y and sColor1 is for uv.
-    // The texture coordinates of u and v are the same. So, we could skip the
-    // st_v if the format is NV12.
-    vec2 st_u = vTextureOffsetU + uv_offset;
-#endif
-
-    vec3 yuv_value;
-#ifdef WR_FEATURE_INTERLEAVED_Y_CB_CR
-    // "The Y, Cb and Cr color channels within the 422 data are mapped into
-    // the existing green, blue and red color channels."
-    // https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
-    yuv_value = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).gbr;
-#elif defined(WR_FEATURE_NV12)
-    yuv_value.x = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).r;
-    yuv_value.yz = TEX_SAMPLE(sColor1, vec3(st_u, vLayers.y)).rg;
-#else
-    // The yuv_planar format should have this third texture coordinate.
-    vec2 st_v = vTextureOffsetV + uv_offset;
-
-    yuv_value.x = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).r;
-    yuv_value.y = TEX_SAMPLE(sColor1, vec3(st_u, vLayers.y)).r;
-    yuv_value.z = TEX_SAMPLE(sColor2, vec3(st_v, vLayers.z)).r;
-#endif
-
-    // See the YuvColorMatrix definition for an explanation of where the constants come from.
-    vec3 rgb = YuvColorMatrix * (yuv_value - vec3(0.06275, 0.50196, 0.50196));
-    oFragColor = vec4(rgb, alpha);
-}
--- a/gfx/webrender/res/ps_yuv_image.glsl
+++ b/gfx/webrender/res/ps_yuv_image.glsl
@@ -17,8 +17,177 @@ flat varying vec2 vHalfTexelY;     // No
 flat varying vec2 vHalfTexelUv;    // Normalized length of the half of u and v texels.
 flat varying vec3 vLayers;
 
 #ifdef WR_FEATURE_TRANSFORM
 varying vec3 vLocalPos;
 #else
 varying vec2 vLocalPos;
 #endif
+
+#ifdef WR_VERTEX_SHADER
+void main(void) {
+    Primitive prim = load_primitive();
+#ifdef WR_FEATURE_TRANSFORM
+    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
+                                                    prim.local_clip_rect,
+                                                    prim.z,
+                                                    prim.layer,
+                                                    prim.task,
+                                                    prim.local_rect);
+    vLocalPos = vi.local_pos;
+#else
+    VertexInfo vi = write_vertex(prim.local_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 prim.local_rect);
+    vLocalPos = vi.local_pos - prim.local_rect.p0;
+#endif
+
+    write_clip(vi.screen_pos, prim.clip_area);
+
+    ImageResource y_rect = fetch_image_resource(prim.user_data0);
+    vLayers = vec3(y_rect.layer, 0.0, 0.0);
+
+#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR  // only 1 channel
+    ImageResource u_rect = fetch_image_resource(prim.user_data1);
+    vLayers.y = u_rect.layer;
+#ifndef WR_FEATURE_NV12 // 2 channel
+    ImageResource v_rect = fetch_image_resource(prim.user_data2);
+    vLayers.z = v_rect.layer;
+#endif
+#endif
+
+    // If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
+    // non-normalized texture coordinates.
+#ifdef WR_FEATURE_TEXTURE_RECT
+    vec2 y_texture_size_normalization_factor = vec2(1, 1);
+#else
+    vec2 y_texture_size_normalization_factor = vec2(textureSize(sColor0, 0));
+#endif
+    vec2 y_st0 = y_rect.uv_rect.xy / y_texture_size_normalization_factor;
+    vec2 y_st1 = y_rect.uv_rect.zw / y_texture_size_normalization_factor;
+
+    vTextureSizeY = y_st1 - y_st0;
+    vTextureOffsetY = y_st0;
+
+#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
+    // This assumes the U and V surfaces have the same size.
+#ifdef WR_FEATURE_TEXTURE_RECT
+    vec2 uv_texture_size_normalization_factor = vec2(1, 1);
+#else
+    vec2 uv_texture_size_normalization_factor = vec2(textureSize(sColor1, 0));
+#endif
+    vec2 u_st0 = u_rect.uv_rect.xy / uv_texture_size_normalization_factor;
+    vec2 u_st1 = u_rect.uv_rect.zw / uv_texture_size_normalization_factor;
+
+#ifndef WR_FEATURE_NV12
+    vec2 v_st0 = v_rect.uv_rect.xy / uv_texture_size_normalization_factor;
+#endif
+
+    vTextureSizeUv = u_st1 - u_st0;
+    vTextureOffsetU = u_st0;
+#ifndef WR_FEATURE_NV12
+    vTextureOffsetV = v_st0;
+#endif
+#endif
+
+    YuvImage image = fetch_yuv_image(prim.specific_prim_address);
+    vStretchSize = image.size;
+
+    vHalfTexelY = vec2(0.5) / y_texture_size_normalization_factor;
+#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
+    vHalfTexelUv = vec2(0.5) / uv_texture_size_normalization_factor;
+#endif
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+#if !defined(WR_FEATURE_YUV_REC601) && !defined(WR_FEATURE_YUV_REC709)
+#define WR_FEATURE_YUV_REC601
+#endif
+
+// The constants added to the Y, U and V components are applied in the fragment shader.
+#if defined(WR_FEATURE_YUV_REC601)
+// From Rec601:
+// [R]   [1.1643835616438356,  0.0,                 1.5960267857142858   ]   [Y -  16]
+// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708   ] x [U - 128]
+// [B]   [1.1643835616438356,  2.017232142857143,   8.862867620416422e-17]   [V - 128]
+//
+// For the range [0,1] instead of [0,255].
+//
+// The matrix is stored in column-major.
+const mat3 YuvColorMatrix = mat3(
+    1.16438,  1.16438, 1.16438,
+    0.0,     -0.39176, 2.01723,
+    1.59603, -0.81297, 0.0
+);
+#elif defined(WR_FEATURE_YUV_REC709)
+// From Rec709:
+// [R]   [1.1643835616438356,  4.2781193979771426e-17, 1.7927410714285714]   [Y -  16]
+// [G] = [1.1643835616438358, -0.21324861427372963,   -0.532909328559444 ] x [U - 128]
+// [B]   [1.1643835616438356,  2.1124017857142854,     0.0               ]   [V - 128]
+//
+// For the range [0,1] instead of [0,255]:
+//
+// The matrix is stored in column-major.
+const mat3 YuvColorMatrix = mat3(
+    1.16438,  1.16438,  1.16438,
+    0.0    , -0.21325,  2.11240,
+    1.79274, -0.53291,  0.0
+);
+#endif
+
+void main(void) {
+#ifdef WR_FEATURE_TRANSFORM
+    float alpha = 0.0;
+    vec2 pos = init_transform_fs(vLocalPos, alpha);
+
+    // We clamp the texture coordinate calculation here to the local rectangle boundaries,
+    // which makes the edge of the texture stretch instead of repeat.
+    vec2 relative_pos_in_rect = clamp(pos, vLocalBounds.xy, vLocalBounds.zw) - vLocalBounds.xy;
+#else
+    float alpha = 1.0;;
+    vec2 relative_pos_in_rect = vLocalPos;
+#endif
+
+    alpha = min(alpha, do_clip());
+
+    // We clamp the texture coordinates to the half-pixel offset from the borders
+    // in order to avoid sampling outside of the texture area.
+    vec2 st_y = vTextureOffsetY + clamp(
+        relative_pos_in_rect / vStretchSize * vTextureSizeY,
+        vHalfTexelY, vTextureSizeY - vHalfTexelY);
+#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
+    vec2 uv_offset = clamp(
+        relative_pos_in_rect / vStretchSize * vTextureSizeUv,
+        vHalfTexelUv, vTextureSizeUv - vHalfTexelUv);
+    // NV12 only uses 2 textures. The sColor0 is for y and sColor1 is for uv.
+    // The texture coordinates of u and v are the same. So, we could skip the
+    // st_v if the format is NV12.
+    vec2 st_u = vTextureOffsetU + uv_offset;
+#endif
+
+    vec3 yuv_value;
+#ifdef WR_FEATURE_INTERLEAVED_Y_CB_CR
+    // "The Y, Cb and Cr color channels within the 422 data are mapped into
+    // the existing green, blue and red color channels."
+    // https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
+    yuv_value = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).gbr;
+#elif defined(WR_FEATURE_NV12)
+    yuv_value.x = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).r;
+    yuv_value.yz = TEX_SAMPLE(sColor1, vec3(st_u, vLayers.y)).rg;
+#else
+    // The yuv_planar format should have this third texture coordinate.
+    vec2 st_v = vTextureOffsetV + uv_offset;
+
+    yuv_value.x = TEX_SAMPLE(sColor0, vec3(st_y, vLayers.x)).r;
+    yuv_value.y = TEX_SAMPLE(sColor1, vec3(st_u, vLayers.y)).r;
+    yuv_value.z = TEX_SAMPLE(sColor2, vec3(st_v, vLayers.z)).r;
+#endif
+
+    // See the YuvColorMatrix definition for an explanation of where the constants come from.
+    vec3 rgb = YuvColorMatrix * (yuv_value - vec3(0.06275, 0.50196, 0.50196));
+    oFragColor = vec4(rgb, alpha);
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_yuv_image.vs.glsl
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-void main(void) {
-    Primitive prim = load_primitive();
-#ifdef WR_FEATURE_TRANSFORM
-    TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
-                                                    prim.local_clip_rect,
-                                                    prim.z,
-                                                    prim.layer,
-                                                    prim.task,
-                                                    prim.local_rect);
-    vLocalPos = vi.local_pos;
-#else
-    VertexInfo vi = write_vertex(prim.local_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 prim.local_rect);
-    vLocalPos = vi.local_pos - prim.local_rect.p0;
-#endif
-
-    write_clip(vi.screen_pos, prim.clip_area);
-
-    ImageResource y_rect = fetch_image_resource(prim.user_data0);
-    vLayers = vec3(y_rect.layer, 0.0, 0.0);
-
-#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR  // only 1 channel
-    ImageResource u_rect = fetch_image_resource(prim.user_data1);
-    vLayers.y = u_rect.layer;
-#ifndef WR_FEATURE_NV12 // 2 channel
-    ImageResource v_rect = fetch_image_resource(prim.user_data2);
-    vLayers.z = v_rect.layer;
-#endif
-#endif
-
-    // If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
-    // non-normalized texture coordinates.
-#ifdef WR_FEATURE_TEXTURE_RECT
-    vec2 y_texture_size_normalization_factor = vec2(1, 1);
-#else
-    vec2 y_texture_size_normalization_factor = vec2(textureSize(sColor0, 0));
-#endif
-    vec2 y_st0 = y_rect.uv_rect.xy / y_texture_size_normalization_factor;
-    vec2 y_st1 = y_rect.uv_rect.zw / y_texture_size_normalization_factor;
-
-    vTextureSizeY = y_st1 - y_st0;
-    vTextureOffsetY = y_st0;
-
-#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
-    // This assumes the U and V surfaces have the same size.
-#ifdef WR_FEATURE_TEXTURE_RECT
-    vec2 uv_texture_size_normalization_factor = vec2(1, 1);
-#else
-    vec2 uv_texture_size_normalization_factor = vec2(textureSize(sColor1, 0));
-#endif
-    vec2 u_st0 = u_rect.uv_rect.xy / uv_texture_size_normalization_factor;
-    vec2 u_st1 = u_rect.uv_rect.zw / uv_texture_size_normalization_factor;
-
-#ifndef WR_FEATURE_NV12
-    vec2 v_st0 = v_rect.uv_rect.xy / uv_texture_size_normalization_factor;
-#endif
-
-    vTextureSizeUv = u_st1 - u_st0;
-    vTextureOffsetU = u_st0;
-#ifndef WR_FEATURE_NV12
-    vTextureOffsetV = v_st0;
-#endif
-#endif
-
-    YuvImage image = fetch_yuv_image(prim.specific_prim_address);
-    vStretchSize = image.size;
-
-    vHalfTexelY = vec2(0.5) / y_texture_size_normalization_factor;
-#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR
-    vHalfTexelUv = vec2(0.5) / uv_texture_size_normalization_factor;
-#endif
-}
--- a/gfx/webrender/res/shared.glsl
+++ b/gfx/webrender/res/shared.glsl
@@ -3,91 +3,56 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef WR_FEATURE_TEXTURE_EXTERNAL
 // Please check https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
 // for this extension.
 #extension GL_OES_EGL_image_external_essl3 : require
 #endif
 
+#include base
+
 // The textureLod() doesn't support samplerExternalOES for WR_FEATURE_TEXTURE_EXTERNAL.
 // https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
 //
 // The textureLod() doesn't support sampler2DRect for WR_FEATURE_TEXTURE_RECT, too.
 //
 // Use texture() instead.
 #if defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_RECT) || defined(WR_FEATURE_TEXTURE_2D)
 #define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
 #else
 // In normal case, we use textureLod(). We haven't used the lod yet. So, we always pass 0.0 now.
 #define TEX_SAMPLE(sampler, tex_coord) textureLod(sampler, tex_coord, 0.0)
 #endif
 
-// texelFetchOffset is buggy on some Android GPUs (see issue #1694).
-// Fallback to texelFetch on mobile GPUs.
-#if defined(GL_ES) 
-    #if GL_ES == 1
-        #define TEXEL_FETCH(sampler, position, lod, offset) texelFetch(sampler, position + offset, lod)
-    #else
-        #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
-    #endif
-#else
-    #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset)
-#endif
-
 //======================================================================================
 // Vertex shader attributes and uniforms
 //======================================================================================
 #ifdef WR_VERTEX_SHADER
-    #define varying out
-
     // Uniform inputs
     uniform mat4 uTransform;       // Orthographic projection
     uniform float uDevicePixelRatio;
 
     // Attribute inputs
     in vec3 aPosition;
 #endif
 
 //======================================================================================
 // Fragment shader attributes and uniforms
 //======================================================================================
 #ifdef WR_FRAGMENT_SHADER
-    precision highp float;
-
-    #define varying in
-
     // Uniform inputs
 
     // Fragment shader outputs
     out vec4 oFragColor;
 #endif
 
 //======================================================================================
 // Shared shader uniforms
 //======================================================================================
-#if defined(GL_ES)
-    #if GL_ES == 1
-        #ifdef GL_FRAGMENT_PRECISION_HIGH
-        precision highp sampler2DArray;
-        #else
-        precision mediump sampler2DArray;
-        #endif
-
-        // Sampler default precision is lowp on mobile GPUs.
-        // This causes RGBA32F texture data to be clamped to 16 bit floats on some GPUs (e.g. Mali-T880).
-        // Define highp precision macro to allow lossless FLOAT texture sampling.
-        #define HIGHP_SAMPLER_FLOAT highp
-    #else
-        #define HIGHP_SAMPLER_FLOAT
-    #endif
-#else
-    #define HIGHP_SAMPLER_FLOAT
-#endif
-
 #ifdef WR_FEATURE_TEXTURE_2D
 uniform sampler2D sColor0;
 uniform sampler2D sColor1;
 uniform sampler2D sColor2;
 #elif defined WR_FEATURE_TEXTURE_RECT
 uniform sampler2DRect sColor0;
 uniform sampler2DRect sColor1;
 uniform sampler2DRect sColor2;
--- a/gfx/webrender/src/tiling.rs
+++ b/gfx/webrender/src/tiling.rs
@@ -48,17 +48,18 @@ impl AlphaBatchHelpers for PrimitiveStor
                 match text_run_cpu.font.render_mode {
                     FontRenderMode::Subpixel => BlendMode::Subpixel(text_run_cpu.color),
                     FontRenderMode::Alpha | FontRenderMode::Mono => BlendMode::Alpha,
                 }
             }
             PrimitiveKind::Image |
             PrimitiveKind::AlignedGradient |
             PrimitiveKind::AngleGradient |
-            PrimitiveKind::RadialGradient => {
+            PrimitiveKind::RadialGradient |
+            PrimitiveKind::TextShadow => {
                 if needs_blending {
                     BlendMode::PremultipliedAlpha
                 } else {
                     BlendMode::None
                 }
             }
             _ => {
                 if needs_blending {
--- a/gfx/webrender_api/src/display_item.rs
+++ b/gfx/webrender_api/src/display_item.rs
@@ -98,16 +98,17 @@ pub struct ClipDisplayItem {
 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
 pub struct StickyFrameDisplayItem {
     pub id: ClipId,
     pub sticky_frame_info: StickyFrameInfo,
 }
 
 pub type StickyFrameInfo = TypedSideOffsets2D<Option<StickySideConstraint>, LayoutPoint>;
 
+#[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
 pub struct StickySideConstraint {
     pub margin: f32,
     pub max_offset: f32,
 }
 
 #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
 pub enum ScrollSensitivity {