Commit a127deaf authored by yjliu's avatar yjliu Committed by Commit Bot

Invalidate backdrop filter cache when surface property changes.

When a render surface's |clip_rect| or |content_rect| changes, we should
invalidate its backdrop filter cache flag even when the damage from
under the surface doesn't intersect the surface's current rect.

Of course surface property can be changed due to other reasons, such as
transform change, effect change or ancestor property change. Not all
such changes should cause the backdrop filter cache flag to invalidate,
and an example is removal of a child layer. However, currently all such
changes are treated uniformly, i.e. will trigger backdrop filter cache
flag to invalidate.

This CL also removes the constraint to only set the backdrop filter
cache flag when there's blur effect so now all render surfaces will have
a valid value for this flag.

Bug: 1147894
Change-Id: I2f09363f7553ba0c1e6caaa2443391c9c582e441
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2533530Reviewed-by: default avatarweiliangc <weiliangc@chromium.org>
Commit-Queue: Jun Liu <yjliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826922}
parent b9c2b54a
......@@ -435,28 +435,23 @@ void DamageTracker::AccumulateDamageFromRenderSurface(
gfx::ToEnclosingRect(render_surface->DrawableContentRect());
data.Update(surface_rect_in_target_space, mailboxId_);
const FilterOperations& backdrop_filters = render_surface->BackdropFilters();
if (!surface_is_new &&
backdrop_filters.HasFilterOfType(FilterOperation::BLUR)) {
gfx::Rect damage_on_target;
bool valid = damage_for_this_update_.GetAsRect(&damage_on_target);
if (!valid || damage_on_target.Intersects(surface_rect_in_target_space)) {
render_surface->set_can_use_cached_backdrop_filtered_result(false);
} else {
surfaces_with_backdrop_blur_filter.emplace_back(
std::make_pair(render_surface, surface_rect_in_target_space));
}
} else {
render_surface->set_can_use_cached_backdrop_filtered_result(false);
}
if (surface_is_new || render_surface->SurfacePropertyChanged()) {
// The entire surface contributes damage.
damage_for_this_update_.Union(surface_rect_in_target_space);
// The surface's old region is now exposed on the target surface, too.
damage_for_this_update_.Union(old_surface_rect);
render_surface->set_can_use_cached_backdrop_filtered_result(false);
} else {
// Check if current accumulated damage intersects the render surface.
gfx::Rect damage_on_target;
bool valid = damage_for_this_update_.GetAsRect(&damage_on_target);
if (valid && !damage_on_target.Intersects(surface_rect_in_target_space)) {
surfaces_with_backdrop_blur_filter.emplace_back(
std::make_pair(render_surface, surface_rect_in_target_space));
} else {
render_surface->set_can_use_cached_backdrop_filtered_result(false);
}
// Only the surface's damage_rect will damage the target surface.
gfx::Rect damage_rect_in_local_space;
bool is_valid_rect = render_surface->damage_tracker()->GetDamageRectIfValid(
......
......@@ -2059,21 +2059,18 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
EmulateDrawingOneFrame(root);
// No change under child1_.
EXPECT_TRUE(
// child1_'s render target has changed its surface property.
EXPECT_FALSE(
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
// Let run for one update and there should be no damage left.
ClearDamageForAllSurfaces(root);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
// CASE 1.1: Setting a non-intersecting update rect on the root
// doesn't invalidate child1_'s cached backdrop-filtered result.
// Damage rect at 0,0 20x20 (expanded to -6,-6 32x32) doesn't intersect
// 270,270 36x38.
ClearDamageForAllSurfaces(root);
// Damage rect at 0,0 20x20 doesn't intersect 270,270 36x38.
root->UnionUpdateRect(gfx::Rect(0, 0, 20, 20));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
......@@ -2081,8 +2078,7 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 1.2: Setting an intersecting update rect on the root invalidates
// child1_'s cached backdrop-filtered result.
// Damage rect at 260,260 20x20 (expanded to 254,254 32x32) intersects 270,270
// 36x38.
// Damage rect at 260,260 20x20 intersects 270,270 36x38.
ClearDamageForAllSurfaces(root);
root->UnionUpdateRect(gfx::Rect(260, 260, 20, 20));
EmulateDrawingOneFrame(root);
......@@ -2114,7 +2110,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->can_use_cached_backdrop_filtered_result());
// Let run for one update and there should be no damage left.
ClearDamageForAllSurfaces(root);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
......@@ -2122,7 +2117,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 3.1: Adding a non-intersecting damage rect to a sibling layer under
// the render surface with the backdrop filter doesn't invalidate cached
// backdrop-filtered result. Damage rect on grand_child1_ at 302,302 1x1
// expanded by a 6-pixel spread (296,296 13x13)
// doesn't intersect 280,280 15x16.
ClearDamageForAllSurfaces(root);
grand_child1_->AddDamageRect(gfx::Rect(2, 2, 1.f, 1.f));
......@@ -2133,7 +2127,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 3.2: Adding an intersecting damage rect to a sibling layer under the
// render surface with the backdrop filter invalidates cached
// backdrop-filtered result. Damage rect on grand_child2_ at 290,290 1x1
// expanded by a 6-pixel spread (284,284 13x13)
// intersects 280,280 15x16.
ClearDamageForAllSurfaces(root);
grand_child2_->AddDamageRect(gfx::Rect(0, 0, 1.f, 1.f));
......@@ -2152,8 +2145,8 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->damage_tracker()
->GetDamageRectIfValid(&damage_rect));
EXPECT_EQ(gfx::Rect(170, 170, 1.f, 1.f), damage_rect);
// Damage rect at 170,170 1x1 (expanded to 164,164 13x13) in render target
// local space doesn't intersect 180,180 15x16.
// Damage rect at 170,170 1x1 in render target local space doesn't intersect
// 180,180 15x16.
EXPECT_TRUE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
......@@ -2167,8 +2160,8 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->damage_tracker()
->GetDamageRectIfValid(&damage_rect));
EXPECT_EQ(gfx::Rect(170, 170, 11.f, 11.f), damage_rect);
// Damage rect at 170,170 11x11 (expanded to 164,164 23x23) in render target
// local space intersects 180,180 15x16
// Damage rect at 170,170 11x11 in render target local space intersects
// 180,180 15x16
EXPECT_FALSE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment