diff --git a/webrender/res/brush_radial_gradient.glsl b/webrender/res/brush_radial_gradient.glsl index 62c7a99633..fdc58b8786 100644 --- a/webrender/res/brush_radial_gradient.glsl +++ b/webrender/res/brush_radial_gradient.glsl @@ -58,8 +58,6 @@ void brush_vs( vRepeatedSize = local_rect.size / tile_repeat.xy; vRepeatedSize.y *= ratio_xy; - vPos; - vGradientAddress = user_data.x; // Whether to repeat the gradient instead of clamping. diff --git a/webrender/src/display_list_flattener.rs b/webrender/src/display_list_flattener.rs index 23e54fbd6e..e669cd75e6 100644 --- a/webrender/src/display_list_flattener.rs +++ b/webrender/src/display_list_flattener.rs @@ -1843,6 +1843,7 @@ impl<'a> DisplayListFlattener<'a> { stops_count: usize, extend_mode: ExtendMode, gradient_index: CachedGradientIndex, + stretch_size: LayoutSize, ) { // Try to ensure that if the gradient is specified in reverse, then so long as the stops // are also supplied in reverse that the rendered result will be equivalent. To do this, @@ -1871,6 +1872,7 @@ impl<'a> DisplayListFlattener<'a> { start_point: sp, end_point: ep, gradient_index, + stretch_size, }, None, ); @@ -1889,43 +1891,49 @@ impl<'a> DisplayListFlattener<'a> { stops: ItemRange, stops_count: usize, extend_mode: ExtendMode, - tile_size: LayoutSize, + stretch_size: LayoutSize, tile_spacing: LayoutSize, ) { let gradient_index = CachedGradientIndex(self.cached_gradients.len()); self.cached_gradients.push(CachedGradient::new()); - let prim_infos = info.decompose( - tile_size, - tile_spacing, - 64 * 64, - ); - - if prim_infos.is_empty() { - self.add_gradient_impl( - clip_and_scroll, - info, - start_point, - end_point, - stops, - stops_count, - extend_mode, - gradient_index, + if tile_spacing != LayoutSize::zero() { + let prim_infos = info.decompose( + stretch_size, + tile_spacing, + 64 * 64, ); - } else { - for prim_info in prim_infos { - self.add_gradient_impl( - clip_and_scroll, - &prim_info, - start_point, - end_point, - stops, - stops_count, - extend_mode, - gradient_index, - ); + + if !prim_infos.is_empty() { + for prim_info in prim_infos { + self.add_gradient_impl( + clip_and_scroll, + &prim_info, + start_point, + end_point, + stops, + stops_count, + extend_mode, + gradient_index, + prim_info.rect.size, + ); + } + + return; } } + + self.add_gradient_impl( + clip_and_scroll, + info, + start_point, + end_point, + stops, + stops_count, + extend_mode, + gradient_index, + stretch_size, + ); } fn add_radial_gradient_impl( @@ -1939,6 +1947,7 @@ impl<'a> DisplayListFlattener<'a> { stops: ItemRange, extend_mode: ExtendMode, gradient_index: CachedGradientIndex, + stretch_size: LayoutSize, ) { let prim = BrushPrimitive::new( BrushKind::RadialGradient { @@ -1949,6 +1958,7 @@ impl<'a> DisplayListFlattener<'a> { end_radius, ratio_xy, gradient_index, + stretch_size, }, None, ); @@ -1971,45 +1981,51 @@ impl<'a> DisplayListFlattener<'a> { ratio_xy: f32, stops: ItemRange, extend_mode: ExtendMode, - tile_size: LayoutSize, + stretch_size: LayoutSize, tile_spacing: LayoutSize, ) { let gradient_index = CachedGradientIndex(self.cached_gradients.len()); self.cached_gradients.push(CachedGradient::new()); - let prim_infos = info.decompose( - tile_size, - tile_spacing, - 64 * 64, - ); - - if prim_infos.is_empty() { - self.add_radial_gradient_impl( - clip_and_scroll, - info, - center, - start_radius, - end_radius, - ratio_xy, - stops, - extend_mode, - gradient_index, + if tile_spacing != LayoutSize::zero() { + let prim_infos = info.decompose( + stretch_size, + tile_spacing, + 64 * 64, ); - } else { - for prim_info in prim_infos { - self.add_radial_gradient_impl( - clip_and_scroll, - &prim_info, - center, - start_radius, - end_radius, - ratio_xy, - stops, - extend_mode, - gradient_index, - ); + + if !prim_infos.is_empty() { + for prim_info in prim_infos { + self.add_radial_gradient_impl( + clip_and_scroll, + &prim_info, + center, + start_radius, + end_radius, + ratio_xy, + stops, + extend_mode, + gradient_index, + stretch_size, + ); + } + + return; } } + + self.add_radial_gradient_impl( + clip_and_scroll, + info, + center, + start_radius, + end_radius, + ratio_xy, + stops, + extend_mode, + gradient_index, + stretch_size, + ); } pub fn add_text( @@ -2137,7 +2153,6 @@ impl<'a> DisplayListFlattener<'a> { // See if conditions are met to run through the new // image brush shader, which supports segments. if tile_spacing == LayoutSize::zero() && - stretch_size == info.rect.size && tile_offset.is_none() { let prim = BrushPrimitive::new( BrushKind::Image { diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index 70950992e1..1a5b65d8e7 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -276,6 +276,7 @@ pub enum BrushKind { start_radius: f32, end_radius: f32, ratio_xy: f32, + stretch_size: LayoutSize, }, LinearGradient { gradient_index: CachedGradientIndex, @@ -285,6 +286,7 @@ pub enum BrushKind { reverse_stops: bool, start_point: LayoutPoint, end_point: LayoutPoint, + stretch_size: LayoutSize, } } @@ -1684,15 +1686,32 @@ impl PrimitiveStore { PrimitiveKind::Brush => { let brush = &self.cpu_brushes[metadata.cpu_prim_index.0]; brush.write_gpu_blocks(&mut request); + + let repeat = match brush.kind { + BrushKind::Image { stretch_size, .. } | + BrushKind::LinearGradient { stretch_size, .. } | + BrushKind::RadialGradient { stretch_size, .. } => { + [ + metadata.local_rect.size.width / stretch_size.width, + metadata.local_rect.size.height / stretch_size.height, + 0.0, + 0.0, + ] + } + _ => { + [1.0, 1.0, 0.0, 0.0] + } + }; + match brush.segment_desc { Some(ref segment_desc) => { for segment in &segment_desc.segments { // has to match VECS_PER_SEGMENT - request.write_segment(segment.local_rect); + request.write_segment(segment.local_rect, repeat); } } None => { - request.write_segment(metadata.local_rect); + request.write_segment(metadata.local_rect, repeat); } } } @@ -2462,13 +2481,9 @@ impl<'a> GpuDataRequest<'a> { fn write_segment( &mut self, local_rect: LayoutRect, + extra_params: [f32; 4], ) { self.push(local_rect); - self.push([ - 1.0, - 1.0, - 0.0, - 0.0 - ]); + self.push(extra_params); } } diff --git a/wrench/reftests/filters/blend-clipped.png b/wrench/reftests/filters/blend-clipped.png index 245adf353b..ddf9b920b7 100644 Binary files a/wrench/reftests/filters/blend-clipped.png and b/wrench/reftests/filters/blend-clipped.png differ diff --git a/wrench/reftests/image/reftest.list b/wrench/reftests/image/reftest.list index 329a8ac71b..028c7d91a1 100644 --- a/wrench/reftests/image/reftest.list +++ b/wrench/reftests/image/reftest.list @@ -2,7 +2,7 @@ == very-big.yaml very-big-ref.yaml == very-big-tile-size.yaml very-big-tile-size-ref.yaml == tile-with-spacing.yaml tile-with-spacing-ref.yaml -fuzzy(1,250000) == tile-repeat-prim-or-decompose.yaml tile-repeat-prim-or-decompose-ref.yaml +fuzzy(1,331264) == tile-repeat-prim-or-decompose.yaml tile-repeat-prim-or-decompose-ref.yaml platform(linux,mac) options(allow-mipmaps) == downscale.yaml downscale.png == segments.yaml segments.png platform(linux,mac) == yuv.yaml yuv.png diff --git a/wrench/reftests/transforms/local-clip.png b/wrench/reftests/transforms/local-clip.png index 88fcc870f9..92e25ec5e5 100644 Binary files a/wrench/reftests/transforms/local-clip.png and b/wrench/reftests/transforms/local-clip.png differ