Bug 1550582 - Ensure the overlap is filled correctly when opposite border edges overlap. r=gw
authorJamie Nicol <jnicol@mozilla.com>
Wed, 15 May 2019 10:43:25 +0000
changeset 532737 93299787ec39d62a5832b7494fd3cf5dcdcbca7c
parent 532736 cc575aa34c366538f85e98e878e8a062e3cfbb33
child 532738 f613e818e43507bc9f900f3756a6921890427775
push id11272
push userapavel@mozilla.com
push dateThu, 16 May 2019 15:28:22 +0000
treeherdermozilla-beta@2265bfc5920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1550582, 1496540
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 1550582 - Ensure the overlap is filled correctly when opposite border edges overlap. r=gw To fix bug 1496540 it was made so that webrender clips border corner segments so that they do not overlap with their opposing edges. However, cases where opposing _edges_ both overlap with eachother (rather than just a corner overlapping with an edge), the corners are clipped too far and a gap is left in the middle. Additionally, no clipping was added to the edge segments. So rather than there be a gap there is an area that is painted twice, which is apparent if the colour is semi-transparent. This fixes these issues by identifying when opposing edges overlap and calculating the midpoint, then clipping the edges and corners to that midpoint instead. Differential Revision: https://phabricator.services.mozilla.com/D30814
gfx/wr/webrender/src/border.rs
--- a/gfx/wr/webrender/src/border.rs
+++ b/gfx/wr/webrender/src/border.rs
@@ -649,16 +649,27 @@ pub fn create_border_segments(
     border_segments: &mut Vec<BorderSegmentInfo>,
     brush_segments: &mut Vec<BrushSegment>,
 ) {
     let rect = LayoutRect::new(
         LayoutPoint::zero(),
         size,
     );
 
+    let overlap = LayoutSize::new(
+        (widths.left + widths.right - size.width).max(0.0),
+        (widths.top + widths.bottom - size.height).max(0.0),
+    );
+    let non_overlapping_widths = LayoutSideOffsets::new(
+        widths.top - overlap.height / 2.0,
+        widths.right - overlap.width / 2.0,
+        widths.bottom - overlap.height / 2.0,
+        widths.left - overlap.width / 2.0,
+    );
+
     let local_size_tl = LayoutSize::new(
         border.radius.top_left.width.max(widths.left),
         border.radius.top_left.height.max(widths.top),
     );
     let local_size_tr = LayoutSize::new(
         border.radius.top_right.width.max(widths.right),
         border.radius.top_right.height.max(widths.top),
     );
@@ -692,70 +703,70 @@ pub fn create_border_segments(
         widths.right,
         rect.size.height - local_size_tr.height - local_size_br.height,
     );
 
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y + local_size_tl.height + left_edge_info.local_offset,
-            rect.origin.x + widths.left,
+            rect.origin.x + non_overlapping_widths.left,
             rect.origin.y + local_size_tl.height + left_edge_info.local_offset + left_edge_info.local_size,
         ),
         &left_edge_info,
         border.left,
-        widths.left,
+        non_overlapping_widths.left,
         BorderSegment::Left,
         EdgeAaSegmentMask::LEFT | EdgeAaSegmentMask::RIGHT,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x + local_size_tl.width + top_edge_info.local_offset,
             rect.origin.y,
             rect.origin.x + local_size_tl.width + top_edge_info.local_offset + top_edge_info.local_size,
-            rect.origin.y + widths.top,
+            rect.origin.y + non_overlapping_widths.top,
         ),
         &top_edge_info,
         border.top,
-        widths.top,
+        non_overlapping_widths.top,
         BorderSegment::Top,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::BOTTOM,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
-            rect.origin.x + rect.size.width - widths.right,
+            rect.origin.x + rect.size.width - non_overlapping_widths.right,
             rect.origin.y + local_size_tr.height + right_edge_info.local_offset,
             rect.origin.x + rect.size.width,
             rect.origin.y + local_size_tr.height + right_edge_info.local_offset + right_edge_info.local_size,
         ),
         &right_edge_info,
         border.right,
-        widths.right,
+        non_overlapping_widths.right,
         BorderSegment::Right,
         EdgeAaSegmentMask::RIGHT | EdgeAaSegmentMask::LEFT,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset,
-            rect.origin.y + rect.size.height - widths.bottom,
+            rect.origin.y + rect.size.height - non_overlapping_widths.bottom,
             rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset + bottom_edge_info.local_size,
             rect.origin.y + rect.size.height,
         ),
         &bottom_edge_info,
         border.bottom,
-        widths.bottom,
+        non_overlapping_widths.bottom,
         BorderSegment::Bottom,
         EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::TOP,
         brush_segments,
         border_segments,
         border.do_aa,
     );
 
     add_corner_segment(
@@ -763,18 +774,18 @@ pub fn create_border_segments(
             rect.origin.x,
             rect.origin.y,
             rect.origin.x + local_size_tl.width,
             rect.origin.y + local_size_tl.height,
         ),
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y,
-            rect.max_x() - widths.right,
-            rect.max_y() - widths.bottom
+            rect.max_x() - non_overlapping_widths.right,
+            rect.max_y() - non_overlapping_widths.bottom
         ),
         border.left,
         border.top,
         LayoutSize::new(widths.left, widths.top),
         border.radius.top_left,
         BorderSegment::TopLeft,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT,
         rect.top_right(),
@@ -788,20 +799,20 @@ pub fn create_border_segments(
     add_corner_segment(
         LayoutRect::from_floats(
             rect.origin.x + rect.size.width - local_size_tr.width,
             rect.origin.y,
             rect.origin.x + rect.size.width,
             rect.origin.y + local_size_tr.height,
         ),
         LayoutRect::from_floats(
-            rect.origin.x + widths.left,
+            rect.origin.x + non_overlapping_widths.left,
             rect.origin.y,
             rect.max_x(),
-            rect.max_y() - widths.bottom,
+            rect.max_y() - non_overlapping_widths.bottom,
         ),
         border.top,
         border.right,
         LayoutSize::new(widths.right, widths.top),
         border.radius.top_right,
         BorderSegment::TopRight,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT,
         rect.origin,
@@ -815,18 +826,18 @@ pub fn create_border_segments(
     add_corner_segment(
         LayoutRect::from_floats(
             rect.origin.x + rect.size.width - local_size_br.width,
             rect.origin.y + rect.size.height - local_size_br.height,
             rect.origin.x + rect.size.width,
             rect.origin.y + rect.size.height,
         ),
         LayoutRect::from_floats(
-            rect.origin.x + widths.left,
-            rect.origin.y + widths.top,
+            rect.origin.x + non_overlapping_widths.left,
+            rect.origin.y + non_overlapping_widths.top,
             rect.max_x(),
             rect.max_y(),
         ),
         border.right,
         border.bottom,
         LayoutSize::new(widths.right, widths.bottom),
         border.radius.bottom_right,
         BorderSegment::BottomRight,
@@ -843,18 +854,18 @@ pub fn create_border_segments(
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y + rect.size.height - local_size_bl.height,
             rect.origin.x + local_size_bl.width,
             rect.origin.y + rect.size.height,
         ),
         LayoutRect::from_floats(
             rect.origin.x,
-            rect.origin.y + widths.top,
-            rect.max_x() - widths.right,
+            rect.origin.y + non_overlapping_widths.top,
+            rect.max_x() - non_overlapping_widths.right,
             rect.max_y(),
         ),
         border.bottom,
         border.left,
         LayoutSize::new(widths.left, widths.bottom),
         border.radius.bottom_left,
         BorderSegment::BottomLeft,
         EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT,