Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Unified Diff: components/viz/service/display/surface_aggregator_unittest.cc

Issue 2873593002: Force use of and cache render surface. (Closed)
Patch Set: Rebased to resolve conflict. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/viz/service/display/surface_aggregator.cc ('k') | ui/compositor/layer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/viz/service/display/surface_aggregator_unittest.cc
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 3a09bbd3b06ae007d21097f6a6156bd49a718daa..984d8cda2659748c4e14deddbd895d67bda368ff 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -2506,5 +2506,582 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ColorSpaceTest) {
EXPECT_EQ(color_space3, aggregated_frame.render_pass_list[2]->color_space);
}
+// Tests that has_damage_from_contributing_content is aggregated correctly from
+// child surface quads.
+TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageByChangingChildSurface) {
+ Quad child_surface_quads[] = {Quad::RenderPassQuad(1)};
+ Pass child_surface_passes[] = {
+ Pass(child_surface_quads, arraysize(child_surface_quads), 1)};
+
+ cc::CompositorFrame child_surface_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_surface_passes, arraysize(child_surface_passes));
+
+ LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+ SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_local_surface_id);
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ Quad root_surface_quads[] = {
+ Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+ Pass root_passes[] = {
+ Pass(root_surface_quads, arraysize(root_surface_quads), 1)};
+
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ // On first frame there is no existing cache texture to worry about re-using,
+ // so we don't worry what this bool is set to.
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ // No Surface changed, so no damage should be given.
+ {
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Change child_frame with damage should set the flag.
+ {
+ cc::CompositorFrame child_surface_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_surface_passes, arraysize(child_surface_passes));
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // True for new child_frame with damage.
+ EXPECT_TRUE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Change child_frame without damage should not set the flag.
+ {
+ cc::CompositorFrame child_surface_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_surface_passes, arraysize(child_surface_passes));
+ child_surface_frame.render_pass_list[0]->damage_rect = gfx::Rect();
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // False for new child_frame without damage.
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+}
+
+// Tests that has_damage_from_contributing_content is aggregated correctly from
+// grand child surface quads.
+TEST_F(SurfaceAggregatorValidSurfaceTest,
+ HasDamageByChangingGrandChildSurface) {
+ auto grand_child_support = CompositorFrameSinkSupport::Create(
+ nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
+ kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+
+ Quad child_surface_quads[] = {Quad::RenderPassQuad(1)};
+ Pass child_surface_passes[] = {
+ Pass(child_surface_quads, arraysize(child_surface_quads), 1)};
+
+ cc::CompositorFrame child_surface_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_surface_passes, arraysize(child_surface_passes));
+
+ LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+ SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_local_surface_id);
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ Quad root_surface_quads[] = {
+ Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+ Pass root_passes[] = {
+ Pass(root_surface_quads, arraysize(root_surface_quads), 1)};
+
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ // On first frame there is no existing cache texture to worry about re-using,
+ // so we don't worry what this bool is set to.
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ // No Surface changed, so no damage should be given.
+ {
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Add a grand_child_frame should cause damage.
+ Quad grand_child_quads[] = {Quad::RenderPassQuad(1)};
+ Pass grand_child_passes[] = {
+ Pass(grand_child_quads, arraysize(grand_child_quads), 1)};
+ LocalSurfaceId grand_child_local_surface_id = allocator_.GenerateId();
+ SurfaceId grand_child_surface_id(grand_child_support->frame_sink_id(),
+ grand_child_local_surface_id);
+ {
+ cc::CompositorFrame grand_child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&grand_child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ grand_child_passes, arraysize(grand_child_passes));
+
+ grand_child_support->SubmitCompositorFrame(grand_child_local_surface_id,
+ std::move(grand_child_frame));
+
+ Quad new_child_surface_quads[] = {
+ child_surface_quads[0],
+ Quad::SurfaceQuad(grand_child_surface_id, InvalidSurfaceId(), 1.f)};
+ Pass new_child_surface_passes[] = {
+ Pass(new_child_surface_quads, arraysize(new_child_surface_quads), 1)};
+ child_surface_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ new_child_surface_passes, arraysize(new_child_surface_passes));
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // True for new grand_child_frame.
+ EXPECT_TRUE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // No Surface changed, so no damage should be given.
+ {
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Change grand_child_frame with damage should set the flag.
+ {
+ cc::CompositorFrame grand_child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&grand_child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ grand_child_passes, arraysize(grand_child_passes));
+ grand_child_support->SubmitCompositorFrame(grand_child_local_surface_id,
+ std::move(grand_child_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // True for new grand_child_frame with damage.
+ EXPECT_TRUE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Change grand_child_frame without damage should not set the flag.
+ {
+ cc::CompositorFrame grand_child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&grand_child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ grand_child_passes, arraysize(grand_child_passes));
+ grand_child_frame.render_pass_list[0]->damage_rect = gfx::Rect();
+ grand_child_support->SubmitCompositorFrame(grand_child_local_surface_id,
+ std::move(grand_child_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // False for new grand_child_frame without damage.
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ }
+
+ grand_child_support->EvictCurrentSurface();
+}
+
+// Tests that has_damage_from_contributing_content is aggregated correctly from
+// render pass quads.
+TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageFromRenderPassQuads) {
+ Quad child_quads[] = {Quad::RenderPassQuad(1)};
+ Pass child_passes[] = {Pass(child_quads, arraysize(child_quads), 1)};
+
+ cc::CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_passes, arraysize(child_passes));
+
+ LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+ SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_local_surface_id);
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
+
+ Quad root_surface_quads[] = {
+ Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+ Quad root_render_pass_quads[] = {Quad::RenderPassQuad(1)};
+
+ Pass root_passes[] = {
+ Pass(root_surface_quads, arraysize(root_surface_quads), 1),
+ Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
+
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ // On first frame there is no existing cache texture to worry about re-using,
+ // so we don't worry what this bool is set to.
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ ASSERT_EQ(2u, aggregated_pass_list.size());
+
+ // No Surface changed, so no damage should be given.
+ {
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ EXPECT_FALSE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ EXPECT_FALSE(aggregated_frame.render_pass_list[1]
+ ->has_damage_from_contributing_content);
+ }
+
+ // Changing child_frame should damage both render_pass.
+ {
+ cc::CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_passes, arraysize(child_passes));
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ // True for new child_frame.
+ EXPECT_TRUE(aggregated_frame.render_pass_list[0]
+ ->has_damage_from_contributing_content);
+ EXPECT_TRUE(aggregated_frame.render_pass_list[1]
+ ->has_damage_from_contributing_content);
+ }
+}
+
+// Tests that the first frame damage_rect of a cached render pass should be
+// fully damaged.
+TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectOfCachedRenderPass) {
+ int pass_id[] = {1, 2};
+ Quad root_quads[][1] = {
+ {Quad::SolidColorQuad(SK_ColorGREEN)}, {Quad::RenderPassQuad(pass_id[0])},
+ };
+ Pass root_passes[] = {
+ Pass(root_quads[0], arraysize(root_quads[0]), pass_id[0]),
+ Pass(root_quads[1], arraysize(root_quads[1]), pass_id[1])};
+
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ ASSERT_EQ(2u, aggregated_pass_list.size());
+
+ // The root surface was enqueued without being aggregated once, so it should
+ // be treated as completely damaged.
+ EXPECT_TRUE(
+ aggregated_pass_list[0]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
+ EXPECT_TRUE(
+ aggregated_pass_list[1]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
+
+ // For offscreen render pass, only the visible area is damaged.
+ {
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ root_passes, arraysize(root_passes));
+
+ auto* nonroot_pass = root_frame.render_pass_list[0].get();
+ nonroot_pass->transform_to_root_target.Translate(8, 0);
+
+ gfx::Rect root_pass_damage = gfx::Rect(0, 0, 10, 10);
+ auto* root_pass = root_frame.render_pass_list[1].get();
+ root_pass->damage_rect = root_pass_damage;
+ auto* root_pass_sqs = root_pass->shared_quad_state_list.front();
+ root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ // Only the visible area is damaged.
+ EXPECT_EQ(gfx::Rect(0, 0, 2, 10), aggregated_pass_list[0]->damage_rect);
+ EXPECT_EQ(root_pass_damage, aggregated_pass_list[1]->damage_rect);
+ }
+
+ // For offscreen cached render pass, should have full damage.
+ {
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ root_passes, arraysize(root_passes));
+
+ auto* nonroot_pass = root_frame.render_pass_list[0].get();
+ nonroot_pass->transform_to_root_target.Translate(8, 0);
+ nonroot_pass->cache_render_pass = true;
+
+ gfx::Rect root_pass_damage = gfx::Rect(0, 0, 10, 10);
+ auto* root_pass = root_frame.render_pass_list[1].get();
+ root_pass->damage_rect = root_pass_damage;
+ auto* root_pass_sqs = root_pass->shared_quad_state_list.front();
+ root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ // Should have full damage.
+ EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
+ EXPECT_EQ(root_pass_damage, aggregated_pass_list[1]->damage_rect);
+ }
+}
+
+// Tests that the first frame damage_rect of cached render pass of a child
+// surface should be fully damaged.
+TEST_F(SurfaceAggregatorValidSurfaceTest,
+ DamageRectOfCachedRenderPassInChildSurface) {
+ int pass_id[] = {1, 2};
+ Quad child_quads[][1] = {
+ {Quad::SolidColorQuad(SK_ColorGREEN)}, {Quad::RenderPassQuad(pass_id[0])},
+ };
+ Pass child_passes[] = {
+ Pass(child_quads[0], arraysize(child_quads[0]), pass_id[0]),
+ Pass(child_quads[1], arraysize(child_quads[1]), pass_id[1])};
+
+ cc::CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_passes, arraysize(child_passes));
+
+ LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+ SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_local_surface_id);
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
+
+ Quad root_surface_quads[] = {
+ Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+
+ Pass root_passes[] = {
+ Pass(root_surface_quads, arraysize(root_surface_quads), 1)};
+
+ cc::CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ support_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ ASSERT_EQ(2u, aggregated_pass_list.size());
+
+ // The root surface was enqueued without being aggregated once, so it should
+ // be treated as completely damaged.
+ EXPECT_TRUE(
+ aggregated_pass_list[0]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
+ EXPECT_TRUE(
+ aggregated_pass_list[1]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
+
+ // For offscreen render pass, only the visible area is damaged.
+ {
+ cc::CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_passes, arraysize(child_passes));
+
+ auto* child_nonroot_pass = child_frame.render_pass_list[0].get();
+ child_nonroot_pass->transform_to_root_target.Translate(8, 0);
+
+ gfx::Rect child_root_pass_damage = gfx::Rect(0, 0, 10, 10);
+ auto* child_root_pass = child_frame.render_pass_list[1].get();
+ child_root_pass->damage_rect = child_root_pass_damage;
+ auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
+ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ // Only the visible area is damaged.
+ EXPECT_EQ(gfx::Rect(0, 0, 2, 10), aggregated_pass_list[0]->damage_rect);
+ EXPECT_EQ(child_root_pass_damage, aggregated_pass_list[1]->damage_rect);
+ }
+
+ // For offscreen cached render pass, should have full damage.
+ {
+ cc::CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
+ AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+ child_passes, arraysize(child_passes));
+
+ auto* child_nonroot_pass = child_frame.render_pass_list[0].get();
+ child_nonroot_pass->transform_to_root_target.Translate(8, 0);
+ child_nonroot_pass->cache_render_pass = true;
+
+ gfx::Rect child_root_pass_damage = gfx::Rect(0, 0, 10, 10);
+ auto* child_root_pass = child_frame.render_pass_list[1].get();
+ child_root_pass->damage_rect = child_root_pass_damage;
+ auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
+ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+
+ child_support_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
+
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ // Should have full damage.
+ EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
+ EXPECT_EQ(child_root_pass_damage, aggregated_pass_list[1]->damage_rect);
+ }
+}
+
+// Tests that quads outside the damage rect are not ignored for cached render
+// pass.
+TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
+ LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+ SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_local_surface_id);
+ // The child surface has two quads, one with a visible rect of 15,15 6x6 and
+ // the other other with a visible rect of 10,10 2x2 (relative to root target
+ // space).
+ {
+ int pass_id[] = {1, 2};
+ Quad child_quads[][1] = {
+ {Quad::SolidColorQuad(SK_ColorGREEN)},
+ {Quad::RenderPassQuad(pass_id[0])},
+ };
+ Pass child_passes[] = {
+ Pass(child_quads[0], arraysize(child_quads[0]), pass_id[0]),
+ Pass(child_quads[1], arraysize(child_quads[1]), pass_id[1])};
+
+ cc::RenderPassList child_pass_list;
+ AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
+ arraysize(child_passes));
+
+ child_pass_list[0]->quad_list.ElementAt(0)->visible_rect =
+ gfx::Rect(1, 1, 3, 3);
+ auto* child_sqs = child_pass_list[0]->shared_quad_state_list.ElementAt(0u);
+ child_sqs->quad_to_target_transform.Translate(3, 3);
+ child_sqs->quad_to_target_transform.Scale(2, 2);
+
+ child_pass_list[0]->cache_render_pass = true;
+
+ child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
+ gfx::Rect(0, 0, 2, 2);
+
+ SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+ &child_pass_list);
+ }
+
+ {
+ int pass_id[] = {1, 2};
+ Quad root_quads[][1] = {
+ {Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)},
+ {Quad::RenderPassQuad(pass_id[0])},
+ };
+ Pass root_passes[] = {
+ Pass(root_quads[0], arraysize(root_quads[0]), pass_id[0]),
+ Pass(root_quads[1], arraysize(root_quads[1]), pass_id[1])};
+
+ cc::RenderPassList root_pass_list;
+ AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ auto* root_pass = root_pass_list[1].get();
+ root_pass->shared_quad_state_list.front()
+ ->quad_to_target_transform.Translate(10, 10);
+ root_pass->damage_rect = gfx::Rect(0, 0, 1, 1);
+
+ SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ &root_pass_list);
+ }
+
+ SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ ASSERT_EQ(3u, aggregated_pass_list.size());
+
+ // Damage rect for first aggregation should contain entire root surface.
+ EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect);
+ EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
+ EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+ EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+
+ // Test should not ignore outside for cached render pass.
+ // Create a root surface with a smaller damage rect.
+ {
+ int pass_id[] = {1, 2};
+ Quad root_quads[][1] = {
+ {Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)},
+ {Quad::RenderPassQuad(pass_id[0])},
+ };
+ Pass root_passes[] = {
+ Pass(root_quads[0], arraysize(root_quads[0]), pass_id[0]),
+ Pass(root_quads[1], arraysize(root_quads[1]), pass_id[1])};
+
+ cc::RenderPassList root_pass_list;
+ AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+ arraysize(root_passes));
+
+ auto* root_pass = root_pass_list[1].get();
+ root_pass->shared_quad_state_list.front()
+ ->quad_to_target_transform.Translate(10, 10);
+ root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
+ SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ &root_pass_list);
+ }
+
+ {
+ cc::CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id);
+ const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+ ASSERT_EQ(3u, aggregated_pass_list.size());
+
+ // The first quad is a cached render pass, should be included and fully
+ // damaged.
+ EXPECT_EQ(gfx::Rect(1, 1, 3, 3),
+ aggregated_pass_list[0]->quad_list.back()->visible_rect);
+ EXPECT_EQ(gfx::Rect(0, 0, 2, 2),
+ aggregated_pass_list[1]->quad_list.back()->visible_rect);
+ EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
+ EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[1]->damage_rect);
+ EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect);
+ EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
+ EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+ EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+ }
+}
+
} // namespace
} // namespace viz
« no previous file with comments | « components/viz/service/display/surface_aggregator.cc ('k') | ui/compositor/layer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698