Bug 1836703 - Fix drop-shadow not invalidating correctly. r=gfx-reviewers,lsalzman

There is still a remaining issue in some cases with the color of
the drop-shadow when moving the slider, but this seems to be a
different problem. This patch fixes the main issue.

Differential Revision: https://phabricator.services.mozilla.com/D183314
This commit is contained in:
Glenn Watson 2023-07-17 20:06:25 +00:00
Родитель 06f72cdbb2
Коммит 4d4d79bcf7
3 изменённых файлов: 109 добавлений и 10 удалений

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

@ -3889,6 +3889,7 @@ impl SurfaceInfo {
/// Information from `get_surface_rects` about the allocated size, UV sampling
/// parameters etc for an off-screen surface
#[derive(Debug)]
struct SurfaceAllocInfo {
task_size: DeviceIntSize,
needs_scissor_rect: bool,
@ -7004,10 +7005,9 @@ fn get_surface_rects(
PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)) => {
let local_prim_rect = surface.clipped_local_rect;
let mut required_local_rect = match local_prim_rect.intersection(&local_clip_rect) {
Some(rect) => rect,
None => return None,
};
let mut required_local_rect = local_prim_rect
.intersection(&local_clip_rect)
.unwrap_or(PictureRect::zero());
for shadow in shadows {
let (blur_radius_x, blur_radius_y) = surface.clamp_blur_radius(
@ -7018,7 +7018,8 @@ fn get_surface_rects(
let blur_inflation_y = blur_radius_y * BLUR_SAMPLE_SCALE;
let local_shadow_rect = local_prim_rect
.translate(shadow.offset.cast_unit());
.translate(shadow.offset.cast_unit())
.inflate(blur_inflation_x, blur_inflation_y);
if let Some(clipped_shadow_rect) = local_clip_rect.intersection(&local_shadow_rect) {
let required_shadow_rect = clipped_shadow_rect.inflate(blur_inflation_x, blur_inflation_y);
@ -7228,3 +7229,103 @@ fn test_large_surface_scale_1() {
false,
);
}
#[test]
fn test_drop_filter_dirty_region_outside_prim() {
// Ensure that if we have a drop-filter where the content of the
// shadow is outside the dirty rect, but blurred pixels from that
// content will affect the dirty rect, that we correctly calculate
// the required region of the drop-filter input
use api::Shadow;
use crate::spatial_tree::{SceneSpatialTree, SpatialTree};
let mut cst = SceneSpatialTree::new();
let root_reference_frame_index = cst.root_reference_frame_index();
let mut spatial_tree = SpatialTree::new();
spatial_tree.apply_updates(cst.end_frame_and_get_pending_updates());
spatial_tree.update_tree(&SceneProperties::new());
let map_local_to_surface = SpaceMapper::new_with_target(
root_reference_frame_index,
root_reference_frame_index,
PictureRect::max_rect(),
&spatial_tree,
);
let mut surfaces = vec![
SurfaceInfo {
unclipped_local_rect: PictureRect::max_rect(),
clipped_local_rect: PictureRect::max_rect(),
is_opaque: true,
clipping_rect: PictureRect::max_rect(),
map_local_to_surface: map_local_to_surface.clone(),
raster_spatial_node_index: root_reference_frame_index,
surface_spatial_node_index: root_reference_frame_index,
device_pixel_scale: DevicePixelScale::new(1.0),
world_scale_factors: (1.0, 1.0),
local_scale: (1.0, 1.0),
allow_snapping: true,
force_scissor_rect: false,
},
SurfaceInfo {
unclipped_local_rect: PictureRect::new(
PicturePoint::new(0.0, 0.0),
PicturePoint::new(750.0, 450.0),
),
clipped_local_rect: PictureRect::new(
PicturePoint::new(0.0, 0.0),
PicturePoint::new(750.0, 450.0),
),
is_opaque: true,
clipping_rect: PictureRect::max_rect(),
map_local_to_surface,
raster_spatial_node_index: root_reference_frame_index,
surface_spatial_node_index: root_reference_frame_index,
device_pixel_scale: DevicePixelScale::new(1.0),
world_scale_factors: (1.0, 1.0),
local_scale: (1.0, 1.0),
allow_snapping: true,
force_scissor_rect: false,
},
];
let shadows = smallvec![
Shadow {
offset: LayoutVector2D::zero(),
color: ColorF::BLACK,
blur_radius: 75.0,
},
];
let composite_mode = PictureCompositeMode::Filter(Filter::DropShadows(shadows));
// Ensure we get a valid and correct render task size when dirty region covers entire screen
let info = get_surface_rects(
SurfaceIndex(1),
&composite_mode,
SurfaceIndex(0),
&mut surfaces,
&spatial_tree,
MAX_SURFACE_SIZE as f32,
false,
).expect("No surface rect");
assert_eq!(info.task_size, DeviceIntSize::new(1200, 900));
// Ensure we get a valid and correct render task size when dirty region is outside filter content
surfaces[0].clipping_rect = PictureRect::new(
PicturePoint::new(768.0, 128.0),
PicturePoint::new(1024.0, 256.0),
);
let info = get_surface_rects(
SurfaceIndex(1),
&composite_mode,
SurfaceIndex(0),
&mut surfaces,
&spatial_tree,
MAX_SURFACE_SIZE as f32,
false,
).expect("No surface rect");
assert_eq!(info.task_size, DeviceIntSize::new(432, 578));
}

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

@ -1801,9 +1801,9 @@ pref(layout.css.moz-document.content.enabled,false) == 1035091-2.html 1035091-re
== 1053035-1-flex.html 1053035-1-ref.html
== 1053035-1-grid.html 1053035-1-ref.html
== 1059167-1.html 1059167-1-ref.html
fails-if(!useDrawSnapshot) == 1059498-1.html 1059498-1-ref.html # WebRender: see bug 1504290
fails-if(!useDrawSnapshot) == 1059498-2.html 1059498-1-ref.html # WebRender: see bug 1504290
fails-if(!useDrawSnapshot) == 1059498-3.html 1059498-1-ref.html # WebRender: see bug 1499113
== 1059498-1.html 1059498-1-ref.html # WebRender: see bug 1504290
== 1059498-2.html 1059498-1-ref.html # WebRender: see bug 1504290
== 1059498-3.html 1059498-1-ref.html # WebRender: see bug 1499113
== 1062108-1.html 1062108-1-ref.html
== 1062792-1.html 1062792-1-ref.html
== 1066554-1.html 1066554-1-ref.html

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

@ -1,2 +0,0 @@
[filters-drop-shadow-003.html]
expected: FAIL