Bug 1543844 - Fix incorrect max scale detection in WR border rendering. r=emilio
authorGlenn Watson <github@intuitionlibrary.com>
Fri, 12 Apr 2019 09:58:24 +0000
changeset 469256 b1b702b25f5387d419eea9d6c0351d478090d5d0
parent 469255 c35e1a0a6cfb68df8bb1a5370faf6c918aa86fcb
child 469257 647b1f56c40383a0ed4e168a5218fdde6ee45382
push id112776
push usershindli@mozilla.com
push dateFri, 12 Apr 2019 16:20:17 +0000
treeherdermozilla-inbound@b4501ced5619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1543844
milestone68.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 1543844 - Fix incorrect max scale detection in WR border rendering. r=emilio 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
@@ -2578,18 +2578,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