1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/quad_culler.h"
9 #include "cc/base/math_util.h"
10 #include "cc/debug/overdraw_metrics.h"
11 #include "cc/layers/append_quads_data.h"
12 #include "cc/layers/render_surface_impl.h"
13 #include "cc/layers/tiled_layer_impl.h"
14 #include "cc/quads/render_pass_draw_quad.h"
15 #include "cc/quads/solid_color_draw_quad.h"
16 #include "cc/quads/tile_draw_quad.h"
17 #include "cc/resources/layer_tiling_data.h"
18 #include "cc/test/fake_impl_proxy.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/occlusion_tracker_test_common.h"
21 #include "cc/trees/occlusion_tracker.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/transform.h"
30 class TestOcclusionTrackerImpl
31 : public TestOcclusionTrackerBase<LayerImpl, RenderSurfaceImpl> {
33 TestOcclusionTrackerImpl(const gfx::Rect& scissor_rect_in_screen,
34 bool record_metrics_for_frame = true)
35 : TestOcclusionTrackerBase(scissor_rect_in_screen,
36 record_metrics_for_frame) {}
39 DISALLOW_COPY_AND_ASSIGN(TestOcclusionTrackerImpl);
42 typedef LayerIterator<LayerImpl> LayerIteratorType;
44 class QuadCullerTest : public testing::Test {
47 : host_impl_(&proxy_),
50 scoped_ptr<TiledLayerImpl> MakeLayer(TiledLayerImpl* parent,
51 const gfx::Transform& draw_transform,
52 const gfx::Rect& layer_rect,
55 const gfx::Rect& layer_opaque_rect,
56 LayerImplList& surface_layer_list) {
57 scoped_ptr<TiledLayerImpl> layer =
58 TiledLayerImpl::Create(host_impl_.active_tree(), layer_id_++);
59 scoped_ptr<LayerTilingData> tiler = LayerTilingData::Create(
60 gfx::Size(100, 100), LayerTilingData::NO_BORDER_TEXELS);
61 tiler->SetBounds(layer_rect.size());
62 layer->SetTilingData(*tiler);
63 layer->set_skips_draw(false);
64 layer->SetDrawsContent(true);
65 layer->draw_properties().target_space_transform = draw_transform;
66 layer->draw_properties().screen_space_transform = draw_transform;
67 layer->draw_properties().visible_content_rect = layer_rect;
68 layer->draw_properties().opacity = opacity;
69 layer->SetContentsOpaque(opaque);
70 layer->SetBounds(layer_rect.size());
71 layer->SetContentBounds(layer_rect.size());
73 ResourceProvider::ResourceId resource_id = 1;
74 for (int i = 0; i < tiler->num_tiles_x(); ++i) {
75 for (int j = 0; j < tiler->num_tiles_y(); ++j) {
76 gfx::Rect tile_opaque_rect =
78 ? tiler->tile_bounds(i, j)
79 : gfx::IntersectRects(tiler->tile_bounds(i, j), layer_opaque_rect);
80 layer->PushTileProperties(i, j, resource_id++, tile_opaque_rect, false);
84 gfx::Rect rect_in_target = MathUtil::MapEnclosingClippedRect(
85 layer->draw_transform(), layer->visible_content_rect());
87 layer->CreateRenderSurface();
88 layer->render_surface()->SetContentRect(rect_in_target);
89 surface_layer_list.push_back(layer.get());
90 layer->render_surface()->layer_list().push_back(layer.get());
92 layer->draw_properties().render_target = parent->render_target();
93 parent->render_surface()->layer_list().push_back(layer.get());
94 rect_in_target.Union(MathUtil::MapEnclosingClippedRect(
95 parent->draw_transform(), parent->visible_content_rect()));
96 parent->render_surface()->SetContentRect(rect_in_target);
98 layer->draw_properties().drawable_content_rect = rect_in_target;
103 void AppendQuads(QuadList* quad_list,
104 SharedQuadStateList* shared_state_list,
105 TiledLayerImpl* layer,
106 LayerIteratorType* it,
107 OcclusionTrackerImpl* occlusion_tracker) {
108 occlusion_tracker->EnterLayer(*it);
109 QuadCuller quad_culler(
110 quad_list, shared_state_list, layer, *occlusion_tracker, false, false);
111 AppendQuadsData data;
112 layer->AppendQuads(&quad_culler, &data);
113 occlusion_tracker->LeaveLayer(*it);
118 FakeImplProxy proxy_;
119 FakeLayerTreeHostImpl host_impl_;
123 DISALLOW_COPY_AND_ASSIGN(QuadCullerTest);
126 #define DECLARE_AND_INITIALIZE_TEST_QUADS() \
127 QuadList quad_list; \
128 SharedQuadStateList shared_state_list; \
129 LayerImplList render_surface_layer_list; \
130 gfx::Transform child_transform; \
131 gfx::Size root_size = gfx::Size(300, 300); \
132 gfx::Rect root_rect = gfx::Rect(root_size); \
133 gfx::Size child_size = gfx::Size(200, 200); \
134 gfx::Rect child_rect = gfx::Rect(child_size);
136 TEST_F(QuadCullerTest, NoCulling) {
137 DECLARE_AND_INITIALIZE_TEST_QUADS();
139 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
145 render_surface_layer_list);
146 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
152 render_surface_layer_list);
153 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
154 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
156 AppendQuads(&quad_list,
161 AppendQuads(&quad_list,
166 EXPECT_EQ(13u, quad_list.size());
168 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
169 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
173 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
176 TEST_F(QuadCullerTest, CullChildLinesUpTopLeft) {
177 DECLARE_AND_INITIALIZE_TEST_QUADS();
179 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
185 render_surface_layer_list);
186 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
192 render_surface_layer_list);
193 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
194 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
196 AppendQuads(&quad_list,
201 AppendQuads(&quad_list,
206 EXPECT_EQ(9u, quad_list.size());
208 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
210 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
211 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
216 TEST_F(QuadCullerTest, CullWhenChildOpacityNotOne) {
217 DECLARE_AND_INITIALIZE_TEST_QUADS();
219 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
225 render_surface_layer_list);
226 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
232 render_surface_layer_list);
233 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
234 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
236 AppendQuads(&quad_list,
241 AppendQuads(&quad_list,
246 EXPECT_EQ(13u, quad_list.size());
248 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
249 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
253 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
256 TEST_F(QuadCullerTest, CullWhenChildOpaqueFlagFalse) {
257 DECLARE_AND_INITIALIZE_TEST_QUADS();
259 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
265 render_surface_layer_list);
266 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
272 render_surface_layer_list);
273 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
274 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
276 AppendQuads(&quad_list,
281 AppendQuads(&quad_list,
286 EXPECT_EQ(13u, quad_list.size());
288 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
289 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
293 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
296 TEST_F(QuadCullerTest, CullCenterTileOnly) {
297 DECLARE_AND_INITIALIZE_TEST_QUADS();
299 child_transform.Translate(50, 50);
300 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
306 render_surface_layer_list);
307 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
313 render_surface_layer_list);
314 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
315 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
317 AppendQuads(&quad_list,
322 AppendQuads(&quad_list,
327 ASSERT_EQ(quad_list.size(), 12u);
329 gfx::Rect quad_visible_rect1 = quad_list[5]->visible_rect;
330 EXPECT_EQ(50, quad_visible_rect1.height());
332 gfx::Rect quad_visible_rect3 = quad_list[7]->visible_rect;
333 EXPECT_EQ(50, quad_visible_rect3.width());
335 // Next index is 8, not 9, since centre quad culled.
336 gfx::Rect quad_visible_rect4 = quad_list[8]->visible_rect;
337 EXPECT_EQ(50, quad_visible_rect4.width());
338 EXPECT_EQ(250, quad_visible_rect4.x());
340 gfx::Rect quad_visible_rect6 = quad_list[10]->visible_rect;
341 EXPECT_EQ(50, quad_visible_rect6.height());
342 EXPECT_EQ(250, quad_visible_rect6.y());
345 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 100000, 1);
347 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
348 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
353 TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize1) {
354 DECLARE_AND_INITIALIZE_TEST_QUADS();
356 child_transform.Translate(100, 100);
358 // Make the root layer's quad have extent (99.1, 99.1) -> (200.9, 200.9) to
359 // make sure it doesn't get culled due to transform rounding.
360 gfx::Transform root_transform;
361 root_transform.Translate(99.1f, 99.1f);
362 root_transform.Scale(1.018f, 1.018f);
364 root_rect = child_rect = gfx::Rect(0, 0, 100, 100);
366 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
372 render_surface_layer_list);
373 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
379 render_surface_layer_list);
380 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
381 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
383 AppendQuads(&quad_list,
388 AppendQuads(&quad_list,
393 EXPECT_EQ(2u, quad_list.size());
396 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 20363, 1);
398 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
400 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
403 TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize2) {
404 DECLARE_AND_INITIALIZE_TEST_QUADS();
406 // Make the child's quad slightly smaller than, and centred over, the root
407 // layer tile. Verify the child does not cause the quad below to be culled
409 child_transform.Translate(100.1f, 100.1f);
410 child_transform.Scale(0.982f, 0.982f);
412 gfx::Transform root_transform;
413 root_transform.Translate(100, 100);
415 root_rect = child_rect = gfx::Rect(0, 0, 100, 100);
417 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
423 render_surface_layer_list);
424 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
430 render_surface_layer_list);
431 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
432 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
434 AppendQuads(&quad_list,
439 AppendQuads(&quad_list,
444 EXPECT_EQ(2u, quad_list.size());
447 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 19643, 1);
449 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
451 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
454 TEST_F(QuadCullerTest, CullChildLinesUpBottomRight) {
455 DECLARE_AND_INITIALIZE_TEST_QUADS();
457 child_transform.Translate(100, 100);
458 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
464 render_surface_layer_list);
465 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
471 render_surface_layer_list);
472 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
473 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
475 AppendQuads(&quad_list,
480 AppendQuads(&quad_list,
485 EXPECT_EQ(9u, quad_list.size());
487 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
489 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
490 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
495 TEST_F(QuadCullerTest, CullSubRegion) {
496 DECLARE_AND_INITIALIZE_TEST_QUADS();
498 child_transform.Translate(50, 50);
499 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
505 render_surface_layer_list);
506 gfx::Rect child_opaque_rect(child_rect.x() + child_rect.width() / 4,
507 child_rect.y() + child_rect.height() / 4,
508 child_rect.width() / 2,
509 child_rect.height() / 2);
510 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
516 render_surface_layer_list);
517 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
518 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
520 AppendQuads(&quad_list,
525 AppendQuads(&quad_list,
530 EXPECT_EQ(12u, quad_list.size());
532 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
533 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
536 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
541 TEST_F(QuadCullerTest, CullSubRegion2) {
542 DECLARE_AND_INITIALIZE_TEST_QUADS();
544 child_transform.Translate(50, 10);
545 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
551 render_surface_layer_list);
552 gfx::Rect child_opaque_rect(child_rect.x() + child_rect.width() / 4,
553 child_rect.y() + child_rect.height() / 4,
554 child_rect.width() / 2,
555 child_rect.height() * 3 / 4);
556 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
562 render_surface_layer_list);
563 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
564 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
566 AppendQuads(&quad_list,
571 AppendQuads(&quad_list,
576 EXPECT_EQ(12u, quad_list.size());
578 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
579 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
582 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
587 TEST_F(QuadCullerTest, CullSubRegionCheckOvercull) {
588 DECLARE_AND_INITIALIZE_TEST_QUADS();
590 child_transform.Translate(50, 49);
591 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
597 render_surface_layer_list);
598 gfx::Rect child_opaque_rect(child_rect.x() + child_rect.width() / 4,
599 child_rect.y() + child_rect.height() / 4,
600 child_rect.width() / 2,
601 child_rect.height() / 2);
602 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
608 render_surface_layer_list);
609 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
610 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
612 AppendQuads(&quad_list,
617 AppendQuads(&quad_list,
622 EXPECT_EQ(13u, quad_list.size());
624 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
625 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
628 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
633 TEST_F(QuadCullerTest, NonAxisAlignedQuadsDontOcclude) {
634 DECLARE_AND_INITIALIZE_TEST_QUADS();
636 // Use a small rotation so as to not disturb the geometry significantly.
637 child_transform.Rotate(1);
639 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
645 render_surface_layer_list);
646 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
652 render_surface_layer_list);
653 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
654 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
656 AppendQuads(&quad_list,
661 AppendQuads(&quad_list,
666 EXPECT_EQ(13u, quad_list.size());
668 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 130000, 1);
670 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
672 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
675 // This test requires some explanation: here we are rotating the quads to be
676 // culled. The 2x2 tile child layer remains in the top-left corner, unrotated,
677 // but the 3x3 tile parent layer is rotated by 1 degree. Of the four tiles the
678 // child would normally occlude, three will move (slightly) out from under the
679 // child layer, and one moves further under the child. Only this last tile
681 TEST_F(QuadCullerTest, NonAxisAlignedQuadsSafelyCulled) {
682 DECLARE_AND_INITIALIZE_TEST_QUADS();
684 // Use a small rotation so as to not disturb the geometry significantly.
685 gfx::Transform parent_transform;
686 parent_transform.Rotate(1);
688 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
694 render_surface_layer_list);
695 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
701 render_surface_layer_list);
702 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
703 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
705 AppendQuads(&quad_list,
710 AppendQuads(&quad_list,
715 EXPECT_EQ(12u, quad_list.size());
717 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 100600, 1);
719 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
720 EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
725 TEST_F(QuadCullerTest, WithoutMetrics) {
726 DECLARE_AND_INITIALIZE_TEST_QUADS();
727 scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
733 render_surface_layer_list);
734 scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
740 render_surface_layer_list);
741 bool record_metrics = false;
742 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000),
744 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
746 AppendQuads(&quad_list,
751 AppendQuads(&quad_list,
756 EXPECT_EQ(9u, quad_list.size());
758 occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque());
760 occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent());
762 occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing());
765 TEST_F(QuadCullerTest, PartialCullingNotDestroyed) {
766 DECLARE_AND_INITIALIZE_TEST_QUADS();
768 scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
774 render_surface_layer_list);
776 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
777 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
779 QuadCuller culler(&quad_list,
786 SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
788 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
789 color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
791 scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
792 pass_quad->SetNew(sqs,
794 RenderPass::Id(10, 10),
802 scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
803 replica_quad->SetNew(sqs,
805 RenderPass::Id(10, 10),
813 // Set a visible rect on the quads.
814 color_quad->visible_rect = gfx::Rect(20, 30, 10, 11);
815 pass_quad->visible_rect = gfx::Rect(50, 60, 13, 14);
816 replica_quad->visible_rect = gfx::Rect(30, 40, 15, 16);
818 // Nothing is occluding.
819 occlusion_tracker.EnterLayer(it);
821 EXPECT_EQ(0u, quad_list.size());
823 AppendQuadsData data;
824 culler.Append(color_quad.PassAs<DrawQuad>(), &data);
825 culler.Append(pass_quad.PassAs<DrawQuad>(), &data);
826 culler.Append(replica_quad.PassAs<DrawQuad>(), &data);
828 ASSERT_EQ(3u, quad_list.size());
830 // The partial culling is preserved.
831 EXPECT_EQ(gfx::Rect(20, 30, 10, 11).ToString(),
832 quad_list[0]->visible_rect.ToString());
833 EXPECT_EQ(gfx::Rect(50, 60, 13, 14).ToString(),
834 quad_list[1]->visible_rect.ToString());
835 EXPECT_EQ(gfx::Rect(30, 40, 15, 16).ToString(),
836 quad_list[2]->visible_rect.ToString());
839 TEST_F(QuadCullerTest, PartialCullingWithOcclusionNotDestroyed) {
840 DECLARE_AND_INITIALIZE_TEST_QUADS();
842 scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
848 render_surface_layer_list);
850 TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
851 LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
853 QuadCuller culler(&quad_list,
860 SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
862 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
863 color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
865 scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
866 pass_quad->SetNew(sqs,
868 RenderPass::Id(10, 10),
876 scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
877 replica_quad->SetNew(sqs,
879 RenderPass::Id(10, 10),
887 // Set a visible rect on the quads.
888 color_quad->visible_rect = gfx::Rect(10, 10, 10, 11);
889 pass_quad->visible_rect = gfx::Rect(10, 20, 13, 14);
890 replica_quad->visible_rect = gfx::Rect(10, 30, 15, 16);
892 // Occlude the left part of the visible rects.
893 occlusion_tracker.EnterLayer(it);
894 occlusion_tracker.set_occlusion_from_outside_target(gfx::Rect(0, 0, 15, 100));
896 EXPECT_EQ(0u, quad_list.size());
898 AppendQuadsData data;
899 culler.Append(color_quad.PassAs<DrawQuad>(), &data);
900 culler.Append(pass_quad.PassAs<DrawQuad>(), &data);
901 culler.Append(replica_quad.PassAs<DrawQuad>(), &data);
903 ASSERT_EQ(3u, quad_list.size());
905 // The partial culling is preserved, while the left side of the quads is newly
907 EXPECT_EQ(gfx::Rect(15, 10, 5, 11).ToString(),
908 quad_list[0]->visible_rect.ToString());
909 EXPECT_EQ(gfx::Rect(15, 20, 8, 14).ToString(),
910 quad_list[1]->visible_rect.ToString());
911 EXPECT_EQ(gfx::Rect(15, 30, 10, 16).ToString(),
912 quad_list[2]->visible_rect.ToString());