diff --git a/webrender/src/prim_store/mod.rs b/webrender/src/prim_store/mod.rs index ad1e24e61a..1430614080 100644 --- a/webrender/src/prim_store/mod.rs +++ b/webrender/src/prim_store/mod.rs @@ -82,7 +82,7 @@ pub fn register_prim_chase_id(id: PrimitiveDebugId) { pub fn register_prim_chase_id(_: PrimitiveDebugId) { } -const MIN_BRUSH_SPLIT_AREA: f32 = 256.0 * 256.0; +const MIN_BRUSH_SPLIT_AREA: f32 = 128.0 * 128.0; pub const VECS_PER_SEGMENT: usize = 2; #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)] @@ -3696,17 +3696,11 @@ impl<'a> GpuDataRequest<'a> { clip_store: &ClipStore, data_stores: &DataStores, ) -> bool { - // If the brush is small, we generally want to skip building segments - // and just draw it as a single primitive with clip mask. However, - // if the clips are purely rectangles that have no per-fragment - // clip masks, we will segment anyway. This allows us to completely - // skip allocating a clip mask in these cases. - let is_large = prim_local_rect.size.area() > MIN_BRUSH_SPLIT_AREA; - - // TODO(gw): We should probably detect and store this on each - // ClipSources instance, to avoid having to iterate - // the clip sources here. - let mut rect_clips_only = true; + // If the brush is small, we want to skip building segments + // and just draw it as a single primitive with clip mask. + if prim_local_rect.size.area() < MIN_BRUSH_SPLIT_AREA { + return false; + } segment_builder.initialize( prim_local_rect, @@ -3715,7 +3709,6 @@ impl<'a> GpuDataRequest<'a> { ); // Segment the primitive on all the local-space clip sources that we can. - let mut local_clip_count = 0; for i in 0 .. clip_chain.clips_range.count { let clip_instance = clip_store .get_instance_from_range(&clip_chain.clips_range, i); @@ -3730,19 +3723,14 @@ impl<'a> GpuDataRequest<'a> { continue; } - local_clip_count += 1; - let (local_clip_rect, radius, mode) = match clip_node.item.kind { ClipItemKind::RoundedRectangle { rect, radius, mode } => { - rect_clips_only = false; (rect, Some(radius), mode) } ClipItemKind::Rectangle { rect, mode } => { (rect, None, mode) } ClipItemKind::BoxShadow { ref source } => { - rect_clips_only = false; - // For inset box shadows, we can clip out any // pixels that are inside the shadow region // and are beyond the inner rect, as they can't @@ -3781,43 +3769,7 @@ impl<'a> GpuDataRequest<'a> { segment_builder.push_clip_rect(local_clip_rect, radius, mode); } - if is_large || rect_clips_only { - // If there were no local clips, then we will subdivide the primitive into - // a uniform grid (up to 8x8 segments). This will typically result in - // a significant number of those segments either being completely clipped, - // or determined to not need a clip mask for that segment. - if local_clip_count == 0 && clip_chain.clips_range.count > 0 { - let x_clip_count = cmp::min(8, (prim_local_rect.size.width / 128.0).ceil() as i32); - let y_clip_count = cmp::min(8, (prim_local_rect.size.height / 128.0).ceil() as i32); - - for y in 0 .. y_clip_count { - let y0 = prim_local_rect.size.height * y as f32 / y_clip_count as f32; - let y1 = prim_local_rect.size.height * (y+1) as f32 / y_clip_count as f32; - - for x in 0 .. x_clip_count { - let x0 = prim_local_rect.size.width * x as f32 / x_clip_count as f32; - let x1 = prim_local_rect.size.width * (x+1) as f32 / x_clip_count as f32; - - let rect = LayoutRect::new( - LayoutPoint::new( - x0 + prim_local_rect.origin.x, - y0 + prim_local_rect.origin.y, - ), - LayoutSize::new( - x1 - x0, - y1 - y0, - ), - ); - - segment_builder.push_mask_region(rect, LayoutRect::zero(), None); - } - } - } - - return true - } - - false + true } impl PrimitiveInstance { diff --git a/webrender/src/scene_building.rs b/webrender/src/scene_building.rs index b39dd8e86a..ee9842f9ad 100644 --- a/webrender/src/scene_building.rs +++ b/webrender/src/scene_building.rs @@ -41,6 +41,7 @@ use crate::resource_cache::{FontInstanceMap, ImageRequest}; use crate::scene::{Scene, BuiltScene, SceneStats, StackingContextHelpers}; use crate::scene_builder_thread::Interners; use crate::spatial_node::{StickyFrameInfo, ScrollFrameKind}; +use euclid::approxeq::ApproxEq; use std::{f32, mem, usize, ops}; use std::collections::vec_deque::VecDeque; use std::sync::Arc; @@ -4087,13 +4088,21 @@ fn process_repeat_size( unsnapped_rect: &LayoutRect, repeat_size: LayoutSize, ) -> LayoutSize { + // FIXME(aosmond): The tile size is calculated based on several parameters + // during display list building. It may produce a slightly different result + // than the bounds due to floating point error accumulation, even though in + // theory they should be the same. We do a fuzzy check here to paper over + // that. It may make more sense to push the original parameters into scene + // building and let it do a saner calculation with more information (e.g. + // the snapped values). + const EPSILON: f32 = 0.001; LayoutSize::new( - if repeat_size.width == unsnapped_rect.size.width { + if repeat_size.width.approx_eq_eps(&unsnapped_rect.size.width, &EPSILON) { snapped_rect.size.width } else { repeat_size.width }, - if repeat_size.height == unsnapped_rect.size.height { + if repeat_size.height.approx_eq_eps(&unsnapped_rect.size.height, &EPSILON) { snapped_rect.size.height } else { repeat_size.height diff --git a/wrench/reftests/boxshadow/box-shadow-border-radii.png b/wrench/reftests/boxshadow/box-shadow-border-radii.png index 3fe9d3c06c..6143955683 100644 Binary files a/wrench/reftests/boxshadow/box-shadow-border-radii.png and b/wrench/reftests/boxshadow/box-shadow-border-radii.png differ diff --git a/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml b/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml new file mode 100644 index 0000000000..c9145fc5e6 --- /dev/null +++ b/wrench/reftests/gradient/linear-adjust-tile-size-ref.yaml @@ -0,0 +1,9 @@ +--- +root: + items: + - type: gradient + bounds: 15.47998046875 18 684.39990234375 643.199951171875 + start: 10.286011695861816 653.47998046875 + end: 143.13165283203125 520.7279663085938 + stops: [0.0, red, 1.0, blue] + repeat: true diff --git a/wrench/reftests/gradient/linear-adjust-tile-size.yaml b/wrench/reftests/gradient/linear-adjust-tile-size.yaml new file mode 100644 index 0000000000..4d78b9b99e --- /dev/null +++ b/wrench/reftests/gradient/linear-adjust-tile-size.yaml @@ -0,0 +1,10 @@ +--- +root: + items: + - type: gradient + bounds: 15.47998046875 18 684.39990234375 643.199951171875 + tile-size: 684.4000244140625 643.2000122070313 + start: 10.286011695861816 653.47998046875 + end: 143.13165283203125 520.7279663085938 + stops: [0.0, red, 1.0, blue] + repeat: true diff --git a/wrench/reftests/gradient/reftest.list b/wrench/reftests/gradient/reftest.list index 79fef2120c..ac0b6454b4 100644 --- a/wrench/reftests/gradient/reftest.list +++ b/wrench/reftests/gradient/reftest.list @@ -73,6 +73,8 @@ fuzzy(1,3) == tiling-conic-3.yaml tiling-conic-3-ref.yaml == radial-zero-size-2.yaml radial-zero-size-ref.yaml == radial-zero-size-3.yaml radial-zero-size-ref.yaml +== linear-adjust-tile-size.yaml linear-adjust-tile-size-ref.yaml + platform(linux,mac) == linear-aligned-border-radius.yaml linear-aligned-border-radius.png platform(linux,mac) == repeat-border-radius.yaml repeat-border-radius.png diff --git a/wrench/reftests/text/perspective-clip.png b/wrench/reftests/text/perspective-clip.png index 7273e7396d..3a836ecb2a 100644 Binary files a/wrench/reftests/text/perspective-clip.png and b/wrench/reftests/text/perspective-clip.png differ diff --git a/wrench/reftests/transforms/perspective-border-radius.png b/wrench/reftests/transforms/perspective-border-radius.png index cb5d20481e..6868bef430 100644 Binary files a/wrench/reftests/transforms/perspective-border-radius.png and b/wrench/reftests/transforms/perspective-border-radius.png differ diff --git a/wrench/reftests/transforms/perspective-shadow.png b/wrench/reftests/transforms/perspective-shadow.png index b065ab9a0e..2a0d50806c 100644 Binary files a/wrench/reftests/transforms/perspective-shadow.png and b/wrench/reftests/transforms/perspective-shadow.png differ diff --git a/wrench/reftests/transforms/prim-suite.png b/wrench/reftests/transforms/prim-suite.png index 1e1ad83728..08ce431df8 100644 Binary files a/wrench/reftests/transforms/prim-suite.png and b/wrench/reftests/transforms/prim-suite.png differ diff --git a/wrench/reftests/transforms/reftest.list b/wrench/reftests/transforms/reftest.list index 3630e6bb31..88727f025c 100644 --- a/wrench/reftests/transforms/reftest.list +++ b/wrench/reftests/transforms/reftest.list @@ -24,7 +24,7 @@ platform(linux,mac) fuzzy(1,283) == near-plane-clip.yaml near-plane-clip.png platform(linux,mac) == perspective-mask.yaml perspective-mask.png == rotate-clip.yaml rotate-clip-ref.yaml == clip-translate.yaml clip-translate-ref.yaml -platform(linux,mac) == perspective-clip.yaml perspective-clip.png +platform(linux,mac) fuzzy(1,1) == perspective-clip.yaml perspective-clip.png platform(linux,mac) fuzzy(1,2) == perspective-clip-1.yaml perspective-clip-1.png platform(linux,mac) fuzzy(1,2) == perspective-shadow.yaml perspective-shadow.png # The ref YAML here produces significantly worse quality diff --git a/wrench/reftests/transforms/rotated-clip-large.png b/wrench/reftests/transforms/rotated-clip-large.png index 1accf1b657..a9c0efbe00 100644 Binary files a/wrench/reftests/transforms/rotated-clip-large.png and b/wrench/reftests/transforms/rotated-clip-large.png differ