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

Improving damage accumulation in SA for pixel-moving foreground filters.

Render pass with pixel-moving filters will now report its |output_rect|
as its damage if any of its quads has damage. Surfaces' damage reporting
is no longer directly affected by pixel-moving filters.

gfx::Rect PrewalkRenderPass(RenderPass* render_pass) {
   gfx::Rect damage_rect;

   // Go through quads back to front to accumulate damage and update |damage_rect|.
   for (DrawQuad* quad : quad_list)  { // in reverse order
       .....
   }
   // Expand the damage to cover entire |output_rect| if the render pass has pixel-moving foreground filters.
   if (!damage_rect.IsEmpty() && render_pass.filters.HasFilterThatMovesPixels())
       damage_rect.Union(render_pass.output_rect);

   return damage_rect;
}

For more details and pseudo-code, please see:
https://docs.google.com/document/d/1D1MTNTaJnZjbmMZGMz0u150N3u5evEFSmJU-ou2vcFw/edit#heading=h.qxb209uq3j9k

Bug: 1110016
Change-Id: I3c495d8ea1ed25585c636a0989a3c7f51fdce7b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2321114Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Commit-Queue: Jun Liu <yjliu@chromium.org>
Auto-Submit: Jun Liu <yjliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797978}
parent 9e654542
...@@ -1255,6 +1255,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1255,6 +1255,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
bool will_draw, bool will_draw,
const gfx::Rect& damage_from_parent, const gfx::Rect& damage_from_parent,
const gfx::Transform& target_to_root_transform, const gfx::Transform& target_to_root_transform,
bool in_moved_pixel_rp,
PrewalkResult* result) { PrewalkResult* result) {
if (render_pass_entry->is_visited) { if (render_pass_entry->is_visited) {
// This render pass is an ancestor of itself and is not supported. // This render pass is an ancestor of itself and is not supported.
...@@ -1271,15 +1272,12 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1271,15 +1272,12 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
RenderPassId remapped_pass_id = RenderPassId remapped_pass_id =
pass_id_remapper_.Remap(render_pass.id, surface->surface_id()); pass_id_remapper_.Remap(render_pass.id, surface->surface_id());
// |moved_pixel_passes_| stores all the render passes affected by filters // |moved_pixel_passes_| stores all the render passes affected by filters
// that move pixels, so |has_pixel_moving_filter| should be set to true either // that move pixels, so |in_moved_pixel_rp| should be set to true either
// if the current render pass has pixel_moving_filter(s) or if it is inside an // if the current render pass has pixel_moving_filter(s) or if it is inside an
// ancestor render pass that has pixel_moving_filter(s). // ancestor render pass that has pixel_moving_filter(s).
bool has_pixel_moving_filter = render_pass.filters.HasFilterThatMovesPixels(); in_moved_pixel_rp |= render_pass.filters.HasFilterThatMovesPixels();
if (has_pixel_moving_filter) if (in_moved_pixel_rp)
moved_pixel_passes_.insert(remapped_pass_id); moved_pixel_passes_.insert(remapped_pass_id);
bool in_moved_pixel_pass =
has_pixel_moving_filter ||
base::Contains(moved_pixel_passes_, remapped_pass_id);
gfx::Transform root_to_target_transform(gfx::Transform::kSkipInitialization); gfx::Transform root_to_target_transform(gfx::Transform::kSkipInitialization);
const bool transform_inverted = const bool transform_inverted =
...@@ -1364,7 +1362,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1364,7 +1362,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
inverse, accumulated_damage_in_child_space); inverse, accumulated_damage_in_child_space);
} }
} }
child_rect = PrewalkSurface(child_surface, in_moved_pixel_pass, child_rect = PrewalkSurface(child_surface, in_moved_pixel_rp,
remapped_pass_id, will_draw, remapped_pass_id, will_draw,
accumulated_damage_in_child_space, result); accumulated_damage_in_child_space, result);
child_rect = gfx::ScaleToEnclosingRect(child_rect, x_scale, y_scale); child_rect = gfx::ScaleToEnclosingRect(child_rect, x_scale, y_scale);
...@@ -1373,12 +1371,6 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1373,12 +1371,6 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
if (quad_damage_rect.IsEmpty()) if (quad_damage_rect.IsEmpty())
continue; continue;
if (in_moved_pixel_pass) {
damage_rect = cc::MathUtil::ProjectEnclosingClippedRect(
root_to_target_transform, full_damage);
continue;
}
} else if (quad->material == DrawQuad::Material::kRenderPass) { } else if (quad->material == DrawQuad::Material::kRenderPass) {
auto* render_pass_quad = RenderPassDrawQuad::MaterialCast(quad); auto* render_pass_quad = RenderPassDrawQuad::MaterialCast(quad);
...@@ -1428,8 +1420,6 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1428,8 +1420,6 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
RenderPassId remapped_child_pass_id = RenderPassId remapped_child_pass_id =
pass_id_remapper_.Remap(child_pass_id, surface->surface_id()); pass_id_remapper_.Remap(child_pass_id, surface->surface_id());
if (in_moved_pixel_pass)
moved_pixel_passes_.insert(remapped_child_pass_id);
render_pass_dependencies_[remapped_pass_id].insert( render_pass_dependencies_[remapped_pass_id].insert(
remapped_child_pass_id); remapped_child_pass_id);
...@@ -1439,7 +1429,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1439,7 +1429,7 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
quad->shared_quad_state->quad_to_target_transform); quad->shared_quad_state->quad_to_target_transform);
quad_damage_rect = PrewalkRenderPass( quad_damage_rect = PrewalkRenderPass(
&child_render_pass_entry, surface, render_pass_map, will_draw, &child_render_pass_entry, surface, render_pass_map, will_draw,
gfx::Rect(), child_to_root_transform, result); gfx::Rect(), child_to_root_transform, in_moved_pixel_rp, result);
} else { } else {
continue; continue;
...@@ -1457,11 +1447,16 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass( ...@@ -1457,11 +1447,16 @@ gfx::Rect SurfaceAggregator::PrewalkRenderPass(
} }
damage_rect.Union(rect_in_target_space); damage_rect.Union(rect_in_target_space);
} }
// Expand the damage to cover entire |output_rect| if the |render_pass| has
// pixel-moving foreground filter.
if (!damage_rect.IsEmpty() && render_pass.filters.HasFilterThatMovesPixels())
damage_rect.Union(render_pass.output_rect);
return damage_rect; return damage_rect;
} }
gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface, gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface,
bool in_moved_pixel_surface, bool in_moved_pixel_rp,
RenderPassId parent_pass_id, RenderPassId parent_pass_id,
bool will_draw, bool will_draw,
const gfx::Rect& damage_from_parent, const gfx::Rect& damage_from_parent,
...@@ -1491,8 +1486,6 @@ gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface, ...@@ -1491,8 +1486,6 @@ gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface,
RenderPassId remapped_pass_id = pass_id_remapper_.Remap( RenderPassId remapped_pass_id = pass_id_remapper_.Remap(
frame.render_pass_list.back()->id, surface->surface_id()); frame.render_pass_list.back()->id, surface->surface_id());
if (in_moved_pixel_surface)
moved_pixel_passes_.insert(remapped_pass_id);
if (parent_pass_id) if (parent_pass_id)
render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id); render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id);
...@@ -1542,9 +1535,9 @@ gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface, ...@@ -1542,9 +1535,9 @@ gfx::Rect SurfaceAggregator::PrewalkSurface(Surface* surface,
DCHECK(it != render_pass_map.end()); DCHECK(it != render_pass_map.end());
RenderPassMapEntry& entry = it->second; RenderPassMapEntry& entry = it->second;
damage_rect.Union(PrewalkRenderPass(&entry, surface, &render_pass_map, damage_rect.Union(PrewalkRenderPass(
will_draw, damage_from_parent, &entry, surface, &render_pass_map, will_draw, damage_from_parent,
gfx::Transform(), result)); gfx::Transform(), in_moved_pixel_rp, result));
damage_rect = cc::MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( damage_rect = cc::MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(
root_pass_transform, damage_rect); root_pass_transform, damage_rect);
...@@ -1742,7 +1735,7 @@ AggregatedFrame SurfaceAggregator::Aggregate( ...@@ -1742,7 +1735,7 @@ AggregatedFrame SurfaceAggregator::Aggregate(
DCHECK(referenced_surfaces_.empty()); DCHECK(referenced_surfaces_.empty());
PrewalkResult prewalk_result; PrewalkResult prewalk_result;
gfx::Rect surfaces_damage_rect = PrewalkSurface( gfx::Rect surfaces_damage_rect = PrewalkSurface(
surface, /*in_moved_pixel_surface=*/false, /*parent_pass=*/RenderPassId(), surface, /*in_moved_pixel_rp=*/false, /*parent_pass=*/RenderPassId(),
/*will_draw=*/true, /*damage_from_parent=*/gfx::Rect(), &prewalk_result); /*will_draw=*/true, /*damage_from_parent=*/gfx::Rect(), &prewalk_result);
root_damage_rect_ = surfaces_damage_rect; root_damage_rect_ = surfaces_damage_rect;
// |root_damage_rect_| is used to restrict aggregating quads only if they // |root_damage_rect_| is used to restrict aggregating quads only if they
......
...@@ -208,6 +208,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator { ...@@ -208,6 +208,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
// If there's no merging of |surface|, |accummulated_damage| is empty. // If there's no merging of |surface|, |accummulated_damage| is empty.
// - |target_to_root_transform| is the transform from current render pass to // - |target_to_root_transform| is the transform from current render pass to
// the root. // the root.
// - |in_moved_pixel_rp| marks if the current render pass is embedded by an
// ancestor render pass with a pixel-moving foreground filter.
// - |result| is the result of a prewalk of the surface that contains the // - |result| is the result of a prewalk of the surface that contains the
// render pass. // render pass.
gfx::Rect PrewalkRenderPass( gfx::Rect PrewalkRenderPass(
...@@ -217,13 +219,14 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator { ...@@ -217,13 +219,14 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
bool will_draw, bool will_draw,
const gfx::Rect& damage_from_parent, const gfx::Rect& damage_from_parent,
const gfx::Transform& target_to_root_transform, const gfx::Transform& target_to_root_transform,
bool in_moved_pixel_rp,
PrewalkResult* result); PrewalkResult* result);
// Walk the Surface tree from |surface|. Validate the resources of the // Walk the Surface tree from |surface|. Validate the resources of the
// current surface and its descendants, check if there are any copy requests, // current surface and its descendants, check if there are any copy requests,
// and return the combined damage rect. // and return the combined damage rect.
gfx::Rect PrewalkSurface(Surface* surface, gfx::Rect PrewalkSurface(Surface* surface,
bool in_moved_pixel_surface, bool in_moved_pixel_rp,
RenderPassId parent_pass, RenderPassId parent_pass,
bool will_draw, bool will_draw,
const gfx::Rect& damage_from_parent, const gfx::Rect& damage_from_parent,
......
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