Bug 1768678 - Fix blur source size adjustment for downscaling r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D152243
This commit is contained in:
Glenn Watson 2022-07-26 00:58:32 +00:00
parent c2d4a6be09
commit 4066f3d6bc
7 changed files with 21 additions and 9 deletions

View File

@ -5351,27 +5351,25 @@ impl PicturePrimitive {
height_std_deviation,
);
let mut device_rect = surface_rects.clipped;
let original_size = device_rect.size();
let original_size = surface_rects.clipped.size();
// Adjust the size to avoid introducing sampling errors during the down-scaling passes.
// what would be even better is to rasterize the picture at the down-scaled size
// directly.
let adjusted_size = BlurTask::adjusted_blur_source_size(
device_rect.size(),
original_size,
blur_std_deviation,
);
device_rect.set_size(adjusted_size);
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
let picture_task_id = frame_state.rg_builder.add().init(
RenderTask::new_dynamic(
surface_rects.task_size,
adjusted_size,
RenderTaskKind::new_picture(
surface_rects.task_size,
adjusted_size,
surface_rects.needs_scissor_rect,
device_rect.min,
surface_rects.clipped.min,
surface_spatial_node_index,
raster_spatial_node_index,
device_pixel_scale,

View File

@ -232,7 +232,7 @@ impl BlurTask {
// In order to do the blur down-scaling passes without introducing errors, we need the
// source of each down-scale pass to be a multuple of two. If need be, this inflates
// the source size so that each down-scale pass will sample correctly.
pub fn adjusted_blur_source_size(original_size: DeviceSize, mut std_dev: DeviceSize) -> DeviceSize {
pub fn adjusted_blur_source_size(original_size: DeviceSize, mut std_dev: DeviceSize) -> DeviceIntSize {
let mut adjusted_size = original_size;
let mut scale_factor = 1.0;
while std_dev.width > MAX_BLUR_STD_DEVIATION && std_dev.height > MAX_BLUR_STD_DEVIATION {
@ -245,7 +245,7 @@ impl BlurTask {
adjusted_size = (original_size.to_f32() / scale_factor).ceil();
}
adjusted_size * scale_factor
(adjusted_size * scale_factor).round().to_i32()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,11 @@
# verify that we correctly size an image to a power of two when
# using downscale passes to avoid blur artifacts
---
root:
items:
- type: stacking-context
bounds: [100, 100, 300, 300]
filters: blur(16.4, 16.4)
items:
- image: "firefox.png"
bounds: 20 20 200 200

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -1,5 +1,6 @@
== filter-grayscale.yaml filter-grayscale-ref.yaml
platform(linux,mac) == draw_calls(7) color_targets(7) alpha_targets(0) filter-blur.yaml filter-blur.png
platform(linux,mac) == filter-blur-downscale-fractional.yaml filter-blur-downscale-fractional.png
== isolated.yaml isolated-ref.yaml
== invisible.yaml invisible-ref.yaml
fuzzy-if(platform(swgl),1,10000) == opacity.yaml opacity-ref.yaml

View File

@ -0,0 +1,2 @@
[backdrop-filter-edge-clipping.html]
fuzzy: maxDifference=10-32;totalPixels=1750-2100