Commit b5d35ac7 authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Fix damage rect optimization for non root render passes

We will only do the optimization for the root render pass. If it's not root,
the overlay damage rect should be added first. This way it has a better chance
to be carved out, just the way it was before the optimization CL.

Bug:868561

Change-Id: I930307cb12ae3bd4fffd79a6311635e501ee1699
Reviewed-on: https://chromium-review.googlesource.com/c/1488037
Commit-Queue: Maggie Chen <magchen@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636254}
parent 8bf91a66
...@@ -394,11 +394,11 @@ void DCLayerOverlayProcessor::ProcessRenderPass( ...@@ -394,11 +394,11 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
// Quad is always promoted to either an underlay or an overlay after this // Quad is always promoted to either an underlay or an overlay after this
// point. It should not fail. // point. It should not fail.
// If the current overlay has changed in size/position from the // If the current overlay has changed in size/position from the previous
// previous frame, we have to add the overlay quads from the previous frame // frame, we have to add the overlay quads from the previous frame to the
// to the damage rect for GL compositor. It's hard to optimize the case with // damage rect for GL compositor. It's hard to optimize multiple overlays or
// multiple overlays. So always add the overlay rects back in this case. // an overlay in non-root render pass. So always add the overlay rects back
// This is only done once at the first overlay/underlay. // in these two cases. This is only done once at the first overlay/underlay.
if (current_frame_processed_overlay_count_ == 0 && is_root && if (current_frame_processed_overlay_count_ == 0 && is_root &&
!previous_frame_overlay_rect_union_.IsEmpty()) { !previous_frame_overlay_rect_union_.IsEmpty()) {
if (quad_rectangle_in_target_space != if (quad_rectangle_in_target_space !=
...@@ -570,8 +570,6 @@ void DCLayerOverlayProcessor::ProcessForUnderlay( ...@@ -570,8 +570,6 @@ void DCLayerOverlayProcessor::ProcessForUnderlay(
// Entire replacement quad must be redrawn. // Entire replacement quad must be redrawn.
// TODO(sunnyps): We should avoid this extra damage if we knew that the // TODO(sunnyps): We should avoid this extra damage if we knew that the
// video was the only thing damaging this render surface. // video was the only thing damaging this render surface.
// TODO(magchen): non-root quad_rectangle should be transformed to root
// target space
damage_rect->Union(quad_rectangle); damage_rect->Union(quad_rectangle);
} }
......
...@@ -2578,6 +2578,86 @@ TEST_F(DCLayerOverlayTest, DamageRectWithoutVideoDamage) { ...@@ -2578,6 +2578,86 @@ TEST_F(DCLayerOverlayTest, DamageRectWithoutVideoDamage) {
} }
} }
TEST_F(DCLayerOverlayTest, DamageRectWithNonRootOverlay) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({features::kDirectCompositionUnderlays,
features::kDirectCompositionNonrootOverlays},
{});
{
// A root solid quad
std::unique_ptr<RenderPass> root_pass = CreateRenderPass();
CreateOpaqueQuadAt(
resource_provider_.get(), root_pass->shared_quad_state_list.back(),
root_pass.get(), gfx::Rect(210, 0, 20, 20), SK_ColorWHITE);
// A non-root video quad
std::unique_ptr<RenderPass> nonroot_pass = CreateRenderPass();
auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
resource_provider_.get(), child_resource_provider_.get(),
child_provider_.get(), nonroot_pass->shared_quad_state_list.back(),
nonroot_pass.get());
video_quad->rect = gfx::Rect(0, 0, 200, 200);
video_quad->visible_rect = video_quad->rect;
DCLayerOverlayList dc_layer_list;
OverlayCandidateList overlay_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
// Damage rect fully outside video quad
damage_rect_ = gfx::Rect(210, 0, 20, 20);
RenderPassList pass_list;
pass_list.push_back(std::move(nonroot_pass));
pass_list.push_back(std::move(root_pass));
overlay_processor_->ProcessForOverlays(
resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
render_pass_filters, render_pass_backdrop_filters, &overlay_list,
nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
EXPECT_EQ(0U, overlay_list.size());
EXPECT_EQ(1U, dc_layer_list.size());
EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
EXPECT_EQ(-1, dc_layer_list.back().z_order);
// damage_rect returned from ProcessForOverlays() is for root render pass
// only. Non-root damage rect is not included.
EXPECT_EQ(gfx::Rect(210, 0, 20, 20), damage_rect_);
}
{
// A root solid quad
std::unique_ptr<RenderPass> root_pass = CreateRenderPass();
CreateOpaqueQuadAt(
resource_provider_.get(), root_pass->shared_quad_state_list.back(),
root_pass.get(), gfx::Rect(210, 0, 20, 20), SK_ColorWHITE);
// A non-root video quad
std::unique_ptr<RenderPass> nonroot_pass = CreateRenderPass();
auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
resource_provider_.get(), child_resource_provider_.get(),
child_provider_.get(), nonroot_pass->shared_quad_state_list.back(),
nonroot_pass.get());
video_quad->rect = gfx::Rect(0, 0, 200, 200);
video_quad->visible_rect = video_quad->rect;
DCLayerOverlayList dc_layer_list;
OverlayCandidateList overlay_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
// Damage rect fully outside video quad
damage_rect_ = gfx::Rect(210, 0, 20, 20);
RenderPassList pass_list;
pass_list.push_back(std::move(nonroot_pass));
pass_list.push_back(std::move(root_pass));
overlay_processor_->ProcessForOverlays(
resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
render_pass_filters, render_pass_backdrop_filters, &overlay_list,
nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
EXPECT_EQ(0U, overlay_list.size());
EXPECT_EQ(1U, dc_layer_list.size());
EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
EXPECT_EQ(-1, dc_layer_list.back().z_order);
// Nonroot damage_rect from the previous frame should be added to this frame
EXPECT_EQ(gfx::Rect(0, 0, 230, 200), damage_rect_);
}
}
TEST_F(DCLayerOverlayTest, DamageRect) { TEST_F(DCLayerOverlayTest, DamageRect) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
std::unique_ptr<RenderPass> pass = CreateRenderPass(); std::unique_ptr<RenderPass> pass = CreateRenderPass();
......
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