Commit 7ed6f397 authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Add clipping support to ProcessSurfaceOccludingDamage()

Clip the surface damage rect before adding it to
|damage_rects_union_of_surfaces_on_top_|. This is how we produce
|root_damage_rect_|.

Bug: 1117235
Change-Id: I83b11d2b79490fd072c3bc5484f7cb38a43f2037
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2412634
Commit-Queue: Maggie Chen <magchen@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809575}
parent 1b33428c
...@@ -42,6 +42,12 @@ class VIZ_SERVICE_EXPORT AggregatedFrame { ...@@ -42,6 +42,12 @@ class VIZ_SERVICE_EXPORT AggregatedFrame {
// Indicates whether this frame may contain video. // Indicates whether this frame may contain video.
bool may_contain_video = false; bool may_contain_video = false;
// This is the final root damage rect produced in
// ProcessSurfaceOccludingDamage().
// TODO(magchen@): This will be replaced by a damage rect list in the follow
// up CL.
gfx::Rect occluding_damage_;
// Contains the metadata required for drawing a delegated ink trail onto the // Contains the metadata required for drawing a delegated ink trail onto the
// end of a rendered ink stroke. This should only be present when two // end of a rendered ink stroke. This should only be present when two
// conditions are met: // conditions are met:
......
...@@ -254,8 +254,7 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect( ...@@ -254,8 +254,7 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect(
if (damage_rects_union_of_surfaces_on_top_.IsEmpty()) if (damage_rects_union_of_surfaces_on_top_.IsEmpty())
return gfx::Rect(); return gfx::Rect();
// Transform the quad to the parent root target space // Transform the quad to the root target space.
// Note: this quad is on the child root render pass.
gfx::Rect quad_in_root_target_space; gfx::Rect quad_in_root_target_space;
if (quad->shared_quad_state->is_clipped) { if (quad->shared_quad_state->is_clipped) {
gfx::Rect quad_in_target_space = cc::MathUtil::MapEnclosingClippedRect( gfx::Rect quad_in_target_space = cc::MathUtil::MapEnclosingClippedRect(
...@@ -271,7 +270,7 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect( ...@@ -271,7 +270,7 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect(
cc::MathUtil::MapEnclosingClippedRect(transform, quad->visible_rect); cc::MathUtil::MapEnclosingClippedRect(transform, quad->visible_rect);
} }
// damage_rects_union_of_surfaces_on_top_ is already in the parent root target // damage_rects_union_of_surfaces_on_top_ is already in the root target
// space. // space.
gfx::Rect occluding_damage_rect = damage_rects_union_of_surfaces_on_top_; gfx::Rect occluding_damage_rect = damage_rects_union_of_surfaces_on_top_;
occluding_damage_rect.Intersect(quad_in_root_target_space); occluding_damage_rect.Intersect(quad_in_root_target_space);
...@@ -283,13 +282,18 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect( ...@@ -283,13 +282,18 @@ gfx::Rect SurfaceAggregator::CalculateOccludingSurfaceDamageRect(
// surfaces on top has been added to damage_rects_union_of_surfaces_on_top_ // surfaces on top has been added to damage_rects_union_of_surfaces_on_top_
// before this. // before this.
void SurfaceAggregator::UnionSurfaceDamageRectsOnTop( void SurfaceAggregator::UnionSurfaceDamageRectsOnTop(
const gfx::Rect& surface_rect, const gfx::Rect& damage_rect,
const gfx::Transform& parent_quad_to_root_target_transform) { const gfx::Transform& parent_to_root_target_transform,
DCHECK(!surface_rect.IsEmpty()); const ClipData& clip_rect) {
DCHECK(!damage_rect.IsEmpty());
gfx::Rect damage_rect_in_root_target_space = gfx::Rect damage_rect_in_root_target_space =
cc::MathUtil::MapEnclosingClippedRect( cc::MathUtil::MapEnclosingClippedRect(parent_to_root_target_transform,
parent_quad_to_root_target_transform, surface_rect); damage_rect);
if (clip_rect.is_clipped)
damage_rect_in_root_target_space.Intersect(clip_rect.rect);
damage_rects_union_of_surfaces_on_top_.Union( damage_rects_union_of_surfaces_on_top_.Union(
damage_rect_in_root_target_space); damage_rect_in_root_target_space);
} }
...@@ -304,17 +308,26 @@ void SurfaceAggregator::UnionSurfaceDamageRectsOnTop( ...@@ -304,17 +308,26 @@ void SurfaceAggregator::UnionSurfaceDamageRectsOnTop(
// surface to which the optimization can be applied, this function returns // surface to which the optimization can be applied, this function returns
// that quad and sets the occluding_damage_rect out parameter to the // that quad and sets the occluding_damage_rect out parameter to the
// appropriate rectangle. // appropriate rectangle.
const DrawQuad* SurfaceAggregator::ProcessSurfaceOccludingDamage( const DrawQuad* SurfaceAggregator::ProcessSurfaceOccludingDamage(
const CompositorRenderPass& source_pass, const CompositorRenderPass& source_pass,
AggregatedRenderPass* dest_pass, AggregatedRenderPass* dest_pass,
const gfx::Transform& parent_target_transform, const gfx::Transform& parent_target_transform,
Surface* surface, const SurfaceId& surface_id,
bool is_last_pass_in_src_surface, const ClipData& clip_rect,
gfx::Rect* occluding_damage_rect) { gfx::Rect* occluding_damage_rect) {
if (!needs_surface_occluding_damage_rect_ || !is_last_pass_in_src_surface) if (!needs_surface_occluding_damage_rect_)
return nullptr; return nullptr;
Surface* surface = manager_->GetSurfaceForId(surface_id);
DCHECK(surface);
// Only process the damage rect once per surface.
const CompositorFrame& frame = surface->GetActiveFrame();
bool is_last_pass_on_src_surface =
&source_pass == frame.render_pass_list.back().get();
if (!is_last_pass_on_src_surface)
return nullptr;
// Transform from the parent quad space to the root target space.
gfx::Transform parent_quad_to_root_target_transform = gfx::Transform( gfx::Transform parent_quad_to_root_target_transform = gfx::Transform(
dest_pass->transform_to_root_target, parent_target_transform); dest_pass->transform_to_root_target, parent_target_transform);
...@@ -362,9 +375,18 @@ const DrawQuad* SurfaceAggregator::ProcessSurfaceOccludingDamage( ...@@ -362,9 +375,18 @@ const DrawQuad* SurfaceAggregator::ProcessSurfaceOccludingDamage(
// This should be done AFTER checking the occluding damage because the surface // This should be done AFTER checking the occluding damage because the surface
// on top should not include its own surface. // on top should not include its own surface.
if (!surface_damage_rect.IsEmpty()) { if (!surface_damage_rect.IsEmpty()) {
ClipData root_clip_rect;
if (clip_rect.is_clipped) {
// root_clip_rect is in the root target space.
root_clip_rect.rect = cc::MathUtil::MapEnclosingClippedRect(
dest_pass->transform_to_root_target, clip_rect.rect);
root_clip_rect.is_clipped = true;
}
UnionSurfaceDamageRectsOnTop(surface_damage_rect, UnionSurfaceDamageRectsOnTop(surface_damage_rect,
parent_quad_to_root_target_transform); parent_quad_to_root_target_transform,
root_clip_rect);
} }
return target_quad; return target_quad;
} }
...@@ -433,6 +455,16 @@ void SurfaceAggregator::HandleSurfaceQuad( ...@@ -433,6 +455,16 @@ void SurfaceAggregator::HandleSurfaceQuad(
dest_pass, rounded_corner_info); dest_pass, rounded_corner_info);
} }
if (needs_surface_occluding_damage_rect_ &&
latest_surface->surface_id() != primary_surface_id) {
gfx::Transform transform(
target_transform,
surface_quad->shared_quad_state->quad_to_target_transform);
transform.ConcatTransform(dest_pass->transform_to_root_target);
UnionSurfaceDamageRectsOnTop(surface_quad->rect, target_transform,
clip_rect);
}
EmitSurfaceContent(latest_surface, parent_device_scale_factor, surface_quad, EmitSurfaceContent(latest_surface, parent_device_scale_factor, surface_quad,
target_transform, clip_rect, dest_pass, ignore_undamaged, target_transform, clip_rect, dest_pass, ignore_undamaged,
damage_rect_in_quad_space, damage_rect_in_quad_space_valid, damage_rect_in_quad_space, damage_rect_in_quad_space_valid,
...@@ -592,8 +624,7 @@ void SurfaceAggregator::EmitSurfaceContent( ...@@ -592,8 +624,7 @@ void SurfaceAggregator::EmitSurfaceContent(
CopyQuadsToPass(source, copy_pass.get(), frame.device_scale_factor(), CopyQuadsToPass(source, copy_pass.get(), frame.device_scale_factor(),
child_to_parent_map, gfx::Transform(), {}, surface_id, child_to_parent_map, gfx::Transform(), {}, surface_id,
RoundedCornerInfo(), surface, RoundedCornerInfo());
/*is_last_pass*/ j == (render_pass_list.size() - 1));
// If the render pass has copy requests, or should be cached, or has // If the render pass has copy requests, or should be cached, or has
// moving-pixel filters, or in a moving-pixel surface, we should damage the // moving-pixel filters, or in a moving-pixel surface, we should damage the
...@@ -639,8 +670,7 @@ void SurfaceAggregator::EmitSurfaceContent( ...@@ -639,8 +670,7 @@ void SurfaceAggregator::EmitSurfaceContent(
CopyQuadsToPass(last_pass, dest_pass, frame.device_scale_factor(), CopyQuadsToPass(last_pass, dest_pass, frame.device_scale_factor(),
child_to_parent_map, combined_transform, quads_clip, child_to_parent_map, combined_transform, quads_clip,
surface_id, rounded_corner_info, surface, surface_id, rounded_corner_info);
/*is_last_pass*/ true);
} else { } else {
auto* shared_quad_state = CopyAndScaleSharedQuadState( auto* shared_quad_state = CopyAndScaleSharedQuadState(
source_sqs, scaled_quad_to_target_transform, target_transform, source_sqs, scaled_quad_to_target_transform, target_transform,
...@@ -732,7 +762,7 @@ void SurfaceAggregator::EmitDefaultBackgroundColorQuad( ...@@ -732,7 +762,7 @@ void SurfaceAggregator::EmitDefaultBackgroundColorQuad(
target_transform, target_transform,
surface_quad->shared_quad_state->quad_to_target_transform); surface_quad->shared_quad_state->quad_to_target_transform);
transform.ConcatTransform(dest_pass->transform_to_root_target); transform.ConcatTransform(dest_pass->transform_to_root_target);
UnionSurfaceDamageRectsOnTop(surface_quad->rect, transform); UnionSurfaceDamageRectsOnTop(surface_quad->rect, transform, clip_rect);
} }
} }
...@@ -970,9 +1000,7 @@ void SurfaceAggregator::CopyQuadsToPass( ...@@ -970,9 +1000,7 @@ void SurfaceAggregator::CopyQuadsToPass(
const gfx::Transform& target_transform, const gfx::Transform& target_transform,
const ClipData& clip_rect, const ClipData& clip_rect,
const SurfaceId& surface_id, const SurfaceId& surface_id,
const RoundedCornerInfo& parent_rounded_corner_info, const RoundedCornerInfo& parent_rounded_corner_info) {
Surface* surface,
bool is_last_pass) {
const QuadList& source_quad_list = source_pass.quad_list; const QuadList& source_quad_list = source_pass.quad_list;
const SharedQuadState* last_copied_source_shared_quad_state = nullptr; const SharedQuadState* last_copied_source_shared_quad_state = nullptr;
...@@ -1010,7 +1038,7 @@ void SurfaceAggregator::CopyQuadsToPass( ...@@ -1010,7 +1038,7 @@ void SurfaceAggregator::CopyQuadsToPass(
gfx::Rect occluding_damage_rect; gfx::Rect occluding_damage_rect;
const DrawQuad* quad_with_occluding_damage_rect = const DrawQuad* quad_with_occluding_damage_rect =
ProcessSurfaceOccludingDamage(source_pass, dest_pass, target_transform, ProcessSurfaceOccludingDamage(source_pass, dest_pass, target_transform,
surface, is_last_pass, surface_id, clip_rect,
&occluding_damage_rect); &occluding_damage_rect);
RoundedCornerInfo new_rounded_corner_info = parent_rounded_corner_info; RoundedCornerInfo new_rounded_corner_info = parent_rounded_corner_info;
...@@ -1205,8 +1233,7 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame, ...@@ -1205,8 +1233,7 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame,
child_to_parent_map, child_to_parent_map,
apply_surface_transform_to_root_pass ? surface_transform apply_surface_transform_to_root_pass ? surface_transform
: gfx::Transform(), : gfx::Transform(),
{}, surface->surface_id(), RoundedCornerInfo(), surface, {}, surface->surface_id(), RoundedCornerInfo());
is_root_pass);
// If the render pass has copy requests, or should be cached, or has // If the render pass has copy requests, or should be cached, or has
// moving-pixel filters, or in a moving-pixel surface, we should damage the // moving-pixel filters, or in a moving-pixel surface, we should damage the
...@@ -1759,6 +1786,7 @@ AggregatedFrame SurfaceAggregator::Aggregate( ...@@ -1759,6 +1786,7 @@ AggregatedFrame SurfaceAggregator::Aggregate(
CopyPasses(root_surface_frame, surface); CopyPasses(root_surface_frame, surface);
referenced_surfaces_.erase(surface_id); referenced_surfaces_.erase(surface_id);
DCHECK(referenced_surfaces_.empty()); DCHECK(referenced_surfaces_.empty());
frame.occluding_damage_ = damage_rects_union_of_surfaces_on_top_;
if (dest_pass_list_->empty()) { if (dest_pass_list_->empty()) {
ResetAfterAggregate(); ResetAfterAggregate();
......
...@@ -173,9 +173,7 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator { ...@@ -173,9 +173,7 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
const gfx::Transform& target_transform, const gfx::Transform& target_transform,
const ClipData& clip_rect, const ClipData& clip_rect,
const SurfaceId& surface_id, const SurfaceId& surface_id,
const RoundedCornerInfo& rounded_corner_info, const RoundedCornerInfo& rounded_corner_info);
Surface* surface,
bool is_last_pass);
// Recursively walks through the render pass and updates the // Recursively walks through the render pass and updates the
// |can_use_backdrop_filter_cache| flag on all RenderPassDrawQuads(RPDQ). // |can_use_backdrop_filter_cache| flag on all RenderPassDrawQuads(RPDQ).
...@@ -252,15 +250,24 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator { ...@@ -252,15 +250,24 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
gfx::Rect CalculateOccludingSurfaceDamageRect( gfx::Rect CalculateOccludingSurfaceDamageRect(
const DrawQuad* quad, const DrawQuad* quad,
const gfx::Transform& parent_quad_to_root_target_transform); const gfx::Transform& parent_quad_to_root_target_transform);
void UnionSurfaceDamageRectsOnTop(const gfx::Rect& surface_rect,
const gfx::Transform& target_transform);
// This function adds |damage_rect| to
// |damage_rects_union_of_surfaces_on_top_|. |damage_rect| is in the quad
// content space while both clip_rect and
// |damage_rects_union_of_surfaces_on_top_| are already on the root target
// space.
void UnionSurfaceDamageRectsOnTop(
const gfx::Rect& damage_rect,
const gfx::Transform& parent_to_root_target_transform,
const ClipData& clip_rect);
// Determine the overlay occluding damage.
const DrawQuad* ProcessSurfaceOccludingDamage( const DrawQuad* ProcessSurfaceOccludingDamage(
const CompositorRenderPass& source_pass, const CompositorRenderPass& source_pass,
AggregatedRenderPass* dest_pass, AggregatedRenderPass* dest_pass,
const gfx::Transform& parent_target_transform, const gfx::Transform& parent_target_transform,
Surface* surface, const SurfaceId& surface_id,
bool is_last_pass_in_src_surface, const ClipData& clip_rect,
gfx::Rect* occluding_damage_rect); gfx::Rect* occluding_damage_rect);
// Returns true if the render pass with the given id and cache_render_pass // Returns true if the render pass with the given id and cache_render_pass
......
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