Bug 1523495 - Adjust shadow blur target sizes to avoid down-scaling artifacts. r=gw

Differential Revision: https://phabricator.services.mozilla.com/D18856
This commit is contained in:
Nicolas Silva 2019-02-06 16:08:24 +01:00
Родитель 6058d31f3a
Коммит f7b60f1a61
2 изменённых файлов: 28 добавлений и 6 удалений

Просмотреть файл

@ -2960,7 +2960,7 @@ impl PicturePrimitive {
PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color)) => {
let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0;
let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
let rounded_std_dev = blur_std_deviation.round();
// The clipped field is the part of the picture that is visible
// on screen. The unclipped field is the screen-space rect of
// the complete picture, if no screen / clip-chain was applied
@ -2969,10 +2969,13 @@ impl PicturePrimitive {
// blur results, inflate that clipped area by the blur range, and
// then intersect with the total screen rect, to minimize the
// allocation size.
let device_rect = clipped
.inflate(blur_range, blur_range)
.intersection(&unclipped.to_i32())
.unwrap();
let mut device_rect = clipped.inflate(blur_range, blur_range)
.intersection(&unclipped.to_i32())
.unwrap();
device_rect.size = RenderTask::adjusted_blur_source_size(
device_rect.size,
rounded_std_dev,
);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
@ -2996,7 +2999,7 @@ impl PicturePrimitive {
let picture_task_id = frame_state.render_tasks.add(picture_task);
let blur_render_task = RenderTask::new_blur(
blur_std_deviation.round(),
rounded_std_dev,
picture_task_id,
frame_state.render_tasks,
RenderTargetKind::Color,

Просмотреть файл

@ -626,6 +626,25 @@ impl RenderTask {
)
}
// 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: DeviceIntSize, mut std_dev: f32) -> DeviceIntSize {
let mut adjusted_size = original_size;
let mut scale_factor = 1.0;
while std_dev > MAX_BLUR_STD_DEVIATION {
if adjusted_size.width < MIN_DOWNSCALING_RT_SIZE ||
adjusted_size.height < MIN_DOWNSCALING_RT_SIZE {
break;
}
std_dev *= 0.5;
scale_factor *= 2.0;
adjusted_size = (original_size.to_f32() / scale_factor).ceil().to_i32();
}
adjusted_size * scale_factor as i32
}
// Construct a render task to apply a blur to a primitive.
// The render task chain that is constructed looks like:
//