diff --git a/webrender/res/cs_blur.glsl b/webrender/res/cs_blur.glsl index c20b794494..85bce0236d 100644 --- a/webrender/res/cs_blur.glsl +++ b/webrender/res/cs_blur.glsl @@ -35,7 +35,7 @@ void main(void) { vec2 texture_size = vec2(textureSize(sCacheA8, 0).xy); #endif vUv.z = src_task.data1.x; - vBlurRadius = 3 * int(task.data1.y); + vBlurRadius = int(3.0 * task.data1.y); vSigma = task.data1.y; switch (aBlurDirection) { @@ -106,7 +106,7 @@ void main(void) { gauss_coefficient_sum += gauss_coefficient.x; gauss_coefficient.xy *= gauss_coefficient.yz; - for (int i=1 ; i <= vBlurRadius/2 ; ++i) { + for (int i=1 ; i <= vBlurRadius ; ++i) { vec2 offset = vOffsetScale * float(i); vec2 st0 = clamp(vUv.xy - offset, vUvRect.xy, vUvRect.zw); diff --git a/webrender/src/box_shadow.rs b/webrender/src/box_shadow.rs index c1d0be5f34..fe999f0360 100644 --- a/webrender/src/box_shadow.rs +++ b/webrender/src/box_shadow.rs @@ -12,7 +12,7 @@ use picture::PicturePrimitive; use util::RectHelpers; // The blur shader samples BLUR_SAMPLE_SCALE * blur_radius surrounding texels. -const BLUR_SAMPLE_SCALE: f32 = 3.0; +pub const BLUR_SAMPLE_SCALE: f32 = 3.0; impl FrameBuilder { pub fn add_box_shadow( diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 77ce956acb..a96fcc5de8 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -39,6 +39,7 @@ use tiling::{ContextIsolation, RenderTargetKind, StackingContextIndex}; use tiling::{PackedLayer, PackedLayerIndex, PrimitiveFlags, PrimitiveRunCmd, RenderPass}; use tiling::{RenderTargetContext, ScrollbarPrimitive, StackingContext}; use util::{self, pack_as_float, RectHelpers, recycle_vec}; +use box_shadow::BLUR_SAMPLE_SCALE; /// Construct a polygon from stacking context boundaries. /// `anchor` here is an index that's going to be preserved in all the @@ -1861,10 +1862,12 @@ impl FrameBuilder { match *filter { FilterOp::Blur(blur_radius) => { let blur_radius = device_length(blur_radius, device_pixel_ratio); + let blur_std_deviation = blur_radius.0 as f32; + let inflate_size = blur_std_deviation * BLUR_SAMPLE_SCALE; render_tasks.get_mut(current_task_id) - .inflate(blur_radius.0); + .inflate(inflate_size as i32); let blur_render_task = RenderTask::new_blur( - blur_radius, + blur_std_deviation, current_task_id, render_tasks, RenderTargetKind::Color, @@ -1877,8 +1880,8 @@ impl FrameBuilder { blur_render_task_id, HardwareCompositeOp::PremultipliedAlpha, DeviceIntPoint::new( - screen_origin.x - blur_radius.0, - screen_origin.y - blur_radius.0, + screen_origin.x - inflate_size as i32, + screen_origin.y - inflate_size as i32, ), next_z, ); diff --git a/webrender/src/picture.rs b/webrender/src/picture.rs index c43464d7fa..73938b1746 100644 --- a/webrender/src/picture.rs +++ b/webrender/src/picture.rs @@ -139,6 +139,11 @@ impl PicturePrimitive { }; let blur_radius = device_length(blur_radius, prim_context.device_pixel_ratio); + // Quote from https://drafts.csswg.org/css-backgrounds-3/#shadow-blur + // "the image that would be generated by applying to the shadow a + // Gaussian blur with a standard deviation equal to half the blur radius." + let blur_std_deviation = blur_radius.0 as f32 * 0.5; + let picture_task = RenderTask::new_picture( cache_size, prim_index, @@ -146,7 +151,7 @@ impl PicturePrimitive { ); let picture_task_id = render_tasks.add(picture_task); let render_task = RenderTask::new_blur( - blur_radius, + blur_std_deviation, picture_task_id, render_tasks, target_kind, diff --git a/webrender/src/render_task.rs b/webrender/src/render_task.rs index 1d48cf057c..803305e325 100644 --- a/webrender/src/render_task.rs +++ b/webrender/src/render_task.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use api::{ClipId, DeviceIntLength, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; +use api::{ClipId, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; use api::{FilterOp, MixBlendMode}; use api::{LayerRect, PipelineId}; use clip::{ClipSource, ClipSourcesWeakHandle, ClipStore}; @@ -262,7 +262,7 @@ pub struct PictureTask { #[derive(Debug)] pub struct BlurTask { - pub blur_radius: DeviceIntLength, + pub blur_std_deviation: f32, pub target_kind: RenderTargetKind, pub regions: Vec, } @@ -460,7 +460,7 @@ impl RenderTask { // +---- This is stored as the input task to the primitive shader. // pub fn new_blur( - blur_radius: DeviceIntLength, + blur_std_deviation: f32, src_task_id: RenderTaskId, render_tasks: &mut RenderTaskTree, target_kind: RenderTargetKind, @@ -474,7 +474,7 @@ impl RenderTask { children: vec![src_task_id], location: RenderTaskLocation::Dynamic(None, blur_target_size), kind: RenderTaskKind::VerticalBlur(BlurTask { - blur_radius, + blur_std_deviation, target_kind, regions: regions.to_vec(), }), @@ -488,7 +488,7 @@ impl RenderTask { children: vec![blur_task_v_id], location: RenderTaskLocation::Dynamic(None, blur_target_size), kind: RenderTaskKind::HorizontalBlur(BlurTask { - blur_radius, + blur_std_deviation, target_kind, regions: regions.to_vec(), }), @@ -602,7 +602,7 @@ impl RenderTask { target_rect.size.width as f32, target_rect.size.height as f32, target_index.0 as f32, - task_info.blur_radius.0 as f32, + task_info.blur_std_deviation, 0.0, 0.0, 0.0, diff --git a/wrench/reftests/boxshadow/box-shadow-border-radii.png b/wrench/reftests/boxshadow/box-shadow-border-radii.png index d8740745d6..16236db02d 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/boxshadow/box-shadow-suite-blur.png b/wrench/reftests/boxshadow/box-shadow-suite-blur.png index 0fd89ba822..25be66a335 100644 Binary files a/wrench/reftests/boxshadow/box-shadow-suite-blur.png and b/wrench/reftests/boxshadow/box-shadow-suite-blur.png differ diff --git a/wrench/reftests/boxshadow/inset-alpha.png b/wrench/reftests/boxshadow/inset-alpha.png index dede54ef44..a0b094c117 100644 Binary files a/wrench/reftests/boxshadow/inset-alpha.png and b/wrench/reftests/boxshadow/inset-alpha.png differ diff --git a/wrench/reftests/boxshadow/inset-border-radius.png b/wrench/reftests/boxshadow/inset-border-radius.png index d87e0f5c32..873176c68a 100644 Binary files a/wrench/reftests/boxshadow/inset-border-radius.png and b/wrench/reftests/boxshadow/inset-border-radius.png differ diff --git a/wrench/reftests/boxshadow/inset-large-offset-ref.png b/wrench/reftests/boxshadow/inset-large-offset-ref.png index 60776b8907..e65177d3e1 100644 Binary files a/wrench/reftests/boxshadow/inset-large-offset-ref.png and b/wrench/reftests/boxshadow/inset-large-offset-ref.png differ diff --git a/wrench/reftests/filters/filter-blur.png b/wrench/reftests/filters/filter-blur.png index 9354e3225e..6229cd2e0e 100644 Binary files a/wrench/reftests/filters/filter-blur.png and b/wrench/reftests/filters/filter-blur.png differ diff --git a/wrench/reftests/text/decorations-suite.png b/wrench/reftests/text/decorations-suite.png index f58068c913..ad91bf5f42 100644 Binary files a/wrench/reftests/text/decorations-suite.png and b/wrench/reftests/text/decorations-suite.png differ diff --git a/wrench/reftests/text/reftest.list b/wrench/reftests/text/reftest.list index 39120fd1df..edcbdc55d6 100644 --- a/wrench/reftests/text/reftest.list +++ b/wrench/reftests/text/reftest.list @@ -18,7 +18,7 @@ fuzzy(1,100) == decorations-suite.yaml decorations-suite.png == 1658.yaml 1658-ref.yaml == split-batch.yaml split-batch-ref.yaml == shadow-red.yaml shadow-red-ref.yaml -fuzzy(1,616) == shadow-grey.yaml shadow-grey-ref.yaml +fuzzy(1,640) == shadow-grey.yaml shadow-grey-ref.yaml == subtle-shadow.yaml subtle-shadow-ref.yaml == shadow-atomic.yaml shadow-atomic-ref.yaml == shadow-ordering.yaml shadow-ordering-ref.yaml