Bug 1543844 - Fix incorrect max scale detection in WR border rendering. r=emilio a=pascalc DEVEDITION_67_0b11_BUILD1 DEVEDITION_67_0b11_RELEASE FENNEC_67_0b11_BUILD1 FENNEC_67_0b11_RELEASE FIREFOX_67_0b11_BUILD1 FIREFOX_67_0b11_RELEASE
authorGlenn Watson <github@intuitionlibrary.com>
Fri, 12 Apr 2019 09:58:24 +0000
changeset 523174 3445cafb3544d9415a9151f1e0234f547f23ccb4
parent 523173 3c781347296418c3bf05f3aef1946bad319026e2
child 523175 2b1c9dc11c24b1bb63cea2fc896d5699b79b18de
push id11086
push userarchaeopteryx@coole-files.de
push dateMon, 15 Apr 2019 08:56:59 +0000
treeherdermozilla-beta@3445cafb3544 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio, pascalc
bugs1543844
milestone67.0
Bug 1543844 - Fix incorrect max scale detection in WR border rendering. r=emilio a=pascalc The local rect for border segments is not solely determined by the widths and/or radius. Instead of determining the max scale based on those parameters, use the calculated border segment rects to determine an appropriate max scale factor. Differential Revision: https://phabricator.services.mozilla.com/D27189
gfx/wr/webrender/src/border.rs
gfx/wr/webrender/src/prim_store/mod.rs
gfx/wr/wrench/reftests/border/max-scale-ref.yaml
gfx/wr/wrench/reftests/border/max-scale.yaml
gfx/wr/wrench/reftests/border/reftest.list
--- a/gfx/wr/webrender/src/border.rs
+++ b/gfx/wr/webrender/src/border.rs
@@ -6,17 +6,17 @@ use api::{BorderRadius, BorderSide, Bord
 use api::{LayoutPrimitiveInfo, NormalBorder as ApiNormalBorder, RepeatMode};
 use api::units::*;
 use ellipse::Ellipse;
 use euclid::vec2;
 use display_list_flattener::DisplayListFlattener;
 use gpu_types::{BorderInstance, BorderSegment, BrushFlags};
 use prim_store::{BorderSegmentInfo, BrushSegment, NinePatchDescriptor};
 use prim_store::{EdgeAaSegmentMask, ScrollNodeAndClipChain};
-use prim_store::borders::NormalBorderPrim;
+use prim_store::borders::{NormalBorderPrim, NormalBorderData};
 use util::{lerp, RectHelpers};
 
 // Using 2048 as the maximum radius in device space before which we
 // start stretching is up for debate.
 // the value must be chosen so that the corners will not use an
 // unreasonable amount of memory but should allow crisp corners in the
 // common cases.
 
@@ -867,31 +867,23 @@ pub fn create_border_segments(
     );
 }
 
 /// Computes the maximum scale that we allow for this set of border parameters.
 /// capping the scale will result in rendering very large corners at a lower
 /// resolution and stretching them, so they will have the right shape, but
 /// blurrier.
 pub fn get_max_scale_for_border(
-    radii: &BorderRadius,
-    widths: &LayoutSideOffsets
+    border_data: &NormalBorderData,
 ) -> LayoutToDeviceScale {
-    let r = radii.top_left.width
-        .max(radii.top_left.height)
-        .max(radii.top_right.width)
-        .max(radii.top_right.height)
-        .max(radii.bottom_left.width)
-        .max(radii.bottom_left.height)
-        .max(radii.bottom_right.width)
-        .max(radii.bottom_right.height)
-        .max(widths.top)
-        .max(widths.bottom)
-        .max(widths.left)
-        .max(widths.right);
+    let mut r = 1.0;
+    for segment in &border_data.border_segments {
+        let size = segment.local_task_size;
+        r = size.width.max(size.height.max(r));
+    }
 
     LayoutToDeviceScale::new(MAX_BORDER_RESOLUTION as f32 / r)
 }
 
 fn add_segment(
     task_rect: DeviceRect,
     style0: BorderStyle,
     style1: BorderStyle,
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -2554,18 +2554,17 @@ impl PrimitiveStore {
                 // power-of-2 boundary ensures we never scale up, only down --- avoiding
                 // jaggies. It also ensures we never scale down by more than a factor of
                 // 2, avoiding bad downscaling quality.
                 let scale_width = clamp_to_scale_factor(scale.0, false);
                 let scale_height = clamp_to_scale_factor(scale.1, false);
                 // Pick the maximum dimension as scale
                 let world_scale = LayoutToWorldScale::new(scale_width.max(scale_height));
                 let mut scale = world_scale * device_pixel_scale;
-                let max_scale = get_max_scale_for_border(&border_data.border.radius,
-                                                         &border_data.widths);
+                let max_scale = get_max_scale_for_border(border_data);
                 scale.0 = scale.0.min(max_scale.0);
 
                 // For each edge and corner, request the render task by content key
                 // from the render task cache. This ensures that the render task for
                 // this segment will be available for batching later in the frame.
                 let mut handles: SmallVec<[RenderTaskCacheEntryHandle; 8]> = SmallVec::new();
 
                 for segment in &border_data.border_segments {
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/border/max-scale-ref.yaml
@@ -0,0 +1,9 @@
+---
+root:
+  items:
+    - type: border
+      bounds: [ 0, 0, 4000, 1 ]
+      width: [ 1, 0, 0, 0 ]
+      border-type: normal
+      style: solid
+      color: red
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/border/max-scale.yaml
@@ -0,0 +1,12 @@
+---
+root:
+  items:
+    - type: stacking-context
+      transform: scale(3000, 1)
+      items:
+        - type: border
+          bounds: [ 0, 0, 100, 100 ]
+          width: [ 1, 0, 0, 0 ]
+          border-type: normal
+          style: solid
+          color: red
--- a/gfx/wr/wrench/reftests/border/reftest.list
+++ b/gfx/wr/wrench/reftests/border/reftest.list
@@ -23,8 +23,9 @@ platform(linux,mac) == dotted-corner-sma
 == overlapping.yaml overlapping.png
 == zero-width.yaml blank.yaml
 platform(linux,mac) == small-dotted-border.yaml small-dotted-border.png
 == discontinued-dash.yaml discontinued-dash.png
 platform(linux,mac) == border-dashed-dotted-caching.yaml border-dashed-dotted-caching.png
 != small-inset-outset.yaml small-inset-outset-notref.yaml
 == no-aa.yaml green-square.yaml
 border-double-1px.yaml border-double-1px-ref.yaml
+== max-scale.yaml max-scale-ref.yaml