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
,
45 LayerIteratorActions::FrontToBack
> LayerIteratorType
;
47 class QuadCullerTest
: public testing::Test
{
50 : host_impl_(&proxy_
),
53 scoped_ptr
<TiledLayerImpl
> MakeLayer(TiledLayerImpl
* parent
,
54 const gfx::Transform
& draw_transform
,
55 const gfx::Rect
& layer_rect
,
58 const gfx::Rect
& layer_opaque_rect
,
59 LayerImplList
& surface_layer_list
) {
60 scoped_ptr
<TiledLayerImpl
> layer
=
61 TiledLayerImpl::Create(host_impl_
.active_tree(), layer_id_
++);
62 scoped_ptr
<LayerTilingData
> tiler
= LayerTilingData::Create(
63 gfx::Size(100, 100), LayerTilingData::NO_BORDER_TEXELS
);
64 tiler
->SetBounds(layer_rect
.size());
65 layer
->SetTilingData(*tiler
);
66 layer
->set_skips_draw(false);
67 layer
->SetDrawsContent(true);
68 layer
->draw_properties().target_space_transform
= draw_transform
;
69 layer
->draw_properties().screen_space_transform
= draw_transform
;
70 layer
->draw_properties().visible_content_rect
= layer_rect
;
71 layer
->draw_properties().opacity
= opacity
;
72 layer
->SetContentsOpaque(opaque
);
73 layer
->SetBounds(layer_rect
.size());
74 layer
->SetContentBounds(layer_rect
.size());
76 ResourceProvider::ResourceId resource_id
= 1;
77 for (int i
= 0; i
< tiler
->num_tiles_x(); ++i
) {
78 for (int j
= 0; j
< tiler
->num_tiles_y(); ++j
) {
79 gfx::Rect tile_opaque_rect
=
81 ? tiler
->tile_bounds(i
, j
)
82 : gfx::IntersectRects(tiler
->tile_bounds(i
, j
), layer_opaque_rect
);
83 layer
->PushTileProperties(i
, j
, resource_id
++, tile_opaque_rect
, false);
87 gfx::Rect rect_in_target
= MathUtil::MapClippedRect(
88 layer
->draw_transform(), layer
->visible_content_rect());
90 layer
->CreateRenderSurface();
91 layer
->render_surface()->SetContentRect(rect_in_target
);
92 surface_layer_list
.push_back(layer
.get());
93 layer
->render_surface()->layer_list().push_back(layer
.get());
95 layer
->draw_properties().render_target
= parent
->render_target();
96 parent
->render_surface()->layer_list().push_back(layer
.get());
97 rect_in_target
.Union(MathUtil::MapClippedRect(
98 parent
->draw_transform(), parent
->visible_content_rect()));
99 parent
->render_surface()->SetContentRect(rect_in_target
);
101 layer
->draw_properties().drawable_content_rect
= rect_in_target
;
106 void AppendQuads(QuadList
* quad_list
,
107 SharedQuadStateList
* shared_state_list
,
108 TiledLayerImpl
* layer
,
109 LayerIteratorType
* it
,
110 OcclusionTrackerImpl
* occlusion_tracker
) {
111 occlusion_tracker
->EnterLayer(*it
);
112 QuadCuller
quad_culler(
113 quad_list
, shared_state_list
, layer
, *occlusion_tracker
, false, false);
114 AppendQuadsData data
;
115 layer
->AppendQuads(&quad_culler
, &data
);
116 occlusion_tracker
->LeaveLayer(*it
);
121 FakeImplProxy proxy_
;
122 FakeLayerTreeHostImpl host_impl_
;
126 DISALLOW_COPY_AND_ASSIGN(QuadCullerTest
);
129 #define DECLARE_AND_INITIALIZE_TEST_QUADS() \
130 QuadList quad_list; \
131 SharedQuadStateList shared_state_list; \
132 LayerImplList render_surface_layer_list; \
133 gfx::Transform child_transform; \
134 gfx::Size root_size = gfx::Size(300, 300); \
135 gfx::Rect root_rect = gfx::Rect(root_size); \
136 gfx::Size child_size = gfx::Size(200, 200); \
137 gfx::Rect child_rect = gfx::Rect(child_size);
139 TEST_F(QuadCullerTest
, NoCulling
) {
140 DECLARE_AND_INITIALIZE_TEST_QUADS();
142 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
148 render_surface_layer_list
);
149 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
155 render_surface_layer_list
);
156 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
157 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
159 AppendQuads(&quad_list
,
164 AppendQuads(&quad_list
,
169 EXPECT_EQ(13u, quad_list
.size());
171 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
172 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
176 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
179 TEST_F(QuadCullerTest
, CullChildLinesUpTopLeft
) {
180 DECLARE_AND_INITIALIZE_TEST_QUADS();
182 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
188 render_surface_layer_list
);
189 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
195 render_surface_layer_list
);
196 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
197 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
199 AppendQuads(&quad_list
,
204 AppendQuads(&quad_list
,
209 EXPECT_EQ(9u, quad_list
.size());
211 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
213 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
214 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
219 TEST_F(QuadCullerTest
, CullWhenChildOpacityNotOne
) {
220 DECLARE_AND_INITIALIZE_TEST_QUADS();
222 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
228 render_surface_layer_list
);
229 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
235 render_surface_layer_list
);
236 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
237 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
239 AppendQuads(&quad_list
,
244 AppendQuads(&quad_list
,
249 EXPECT_EQ(13u, quad_list
.size());
251 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
252 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
256 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
259 TEST_F(QuadCullerTest
, CullWhenChildOpaqueFlagFalse
) {
260 DECLARE_AND_INITIALIZE_TEST_QUADS();
262 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
268 render_surface_layer_list
);
269 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
275 render_surface_layer_list
);
276 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
277 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
279 AppendQuads(&quad_list
,
284 AppendQuads(&quad_list
,
289 EXPECT_EQ(13u, quad_list
.size());
291 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
292 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
296 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
299 TEST_F(QuadCullerTest
, CullCenterTileOnly
) {
300 DECLARE_AND_INITIALIZE_TEST_QUADS();
302 child_transform
.Translate(50, 50);
303 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
309 render_surface_layer_list
);
310 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
316 render_surface_layer_list
);
317 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
318 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
320 AppendQuads(&quad_list
,
325 AppendQuads(&quad_list
,
330 ASSERT_EQ(quad_list
.size(), 12u);
332 gfx::Rect quad_visible_rect1
= quad_list
[5]->visible_rect
;
333 EXPECT_EQ(50, quad_visible_rect1
.height());
335 gfx::Rect quad_visible_rect3
= quad_list
[7]->visible_rect
;
336 EXPECT_EQ(50, quad_visible_rect3
.width());
338 // Next index is 8, not 9, since centre quad culled.
339 gfx::Rect quad_visible_rect4
= quad_list
[8]->visible_rect
;
340 EXPECT_EQ(50, quad_visible_rect4
.width());
341 EXPECT_EQ(250, quad_visible_rect4
.x());
343 gfx::Rect quad_visible_rect6
= quad_list
[10]->visible_rect
;
344 EXPECT_EQ(50, quad_visible_rect6
.height());
345 EXPECT_EQ(250, quad_visible_rect6
.y());
348 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 100000, 1);
350 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
351 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
356 TEST_F(QuadCullerTest
, CullCenterTileNonIntegralSize1
) {
357 DECLARE_AND_INITIALIZE_TEST_QUADS();
359 child_transform
.Translate(100, 100);
361 // Make the root layer's quad have extent (99.1, 99.1) -> (200.9, 200.9) to
362 // make sure it doesn't get culled due to transform rounding.
363 gfx::Transform root_transform
;
364 root_transform
.Translate(99.1f
, 99.1f
);
365 root_transform
.Scale(1.018f
, 1.018f
);
367 root_rect
= child_rect
= gfx::Rect(0, 0, 100, 100);
369 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
375 render_surface_layer_list
);
376 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
382 render_surface_layer_list
);
383 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
384 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
386 AppendQuads(&quad_list
,
391 AppendQuads(&quad_list
,
396 EXPECT_EQ(2u, quad_list
.size());
399 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 20363, 1);
401 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
403 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
406 TEST_F(QuadCullerTest
, CullCenterTileNonIntegralSize2
) {
407 DECLARE_AND_INITIALIZE_TEST_QUADS();
409 // Make the child's quad slightly smaller than, and centred over, the root
410 // layer tile. Verify the child does not cause the quad below to be culled
412 child_transform
.Translate(100.1f
, 100.1f
);
413 child_transform
.Scale(0.982f
, 0.982f
);
415 gfx::Transform root_transform
;
416 root_transform
.Translate(100, 100);
418 root_rect
= child_rect
= gfx::Rect(0, 0, 100, 100);
420 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
426 render_surface_layer_list
);
427 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
433 render_surface_layer_list
);
434 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
435 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
437 AppendQuads(&quad_list
,
442 AppendQuads(&quad_list
,
447 EXPECT_EQ(2u, quad_list
.size());
450 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 19643, 1);
452 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
454 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
457 TEST_F(QuadCullerTest
, CullChildLinesUpBottomRight
) {
458 DECLARE_AND_INITIALIZE_TEST_QUADS();
460 child_transform
.Translate(100, 100);
461 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
467 render_surface_layer_list
);
468 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
474 render_surface_layer_list
);
475 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
476 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
478 AppendQuads(&quad_list
,
483 AppendQuads(&quad_list
,
488 EXPECT_EQ(9u, quad_list
.size());
490 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
492 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
493 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
498 TEST_F(QuadCullerTest
, CullSubRegion
) {
499 DECLARE_AND_INITIALIZE_TEST_QUADS();
501 child_transform
.Translate(50, 50);
502 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
508 render_surface_layer_list
);
509 gfx::Rect
child_opaque_rect(child_rect
.x() + child_rect
.width() / 4,
510 child_rect
.y() + child_rect
.height() / 4,
511 child_rect
.width() / 2,
512 child_rect
.height() / 2);
513 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
519 render_surface_layer_list
);
520 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
521 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
523 AppendQuads(&quad_list
,
528 AppendQuads(&quad_list
,
533 EXPECT_EQ(12u, quad_list
.size());
535 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
536 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
539 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
544 TEST_F(QuadCullerTest
, CullSubRegion2
) {
545 DECLARE_AND_INITIALIZE_TEST_QUADS();
547 child_transform
.Translate(50, 10);
548 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
554 render_surface_layer_list
);
555 gfx::Rect
child_opaque_rect(child_rect
.x() + child_rect
.width() / 4,
556 child_rect
.y() + child_rect
.height() / 4,
557 child_rect
.width() / 2,
558 child_rect
.height() * 3 / 4);
559 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
565 render_surface_layer_list
);
566 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
567 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
569 AppendQuads(&quad_list
,
574 AppendQuads(&quad_list
,
579 EXPECT_EQ(12u, quad_list
.size());
581 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
582 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
585 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
590 TEST_F(QuadCullerTest
, CullSubRegionCheckOvercull
) {
591 DECLARE_AND_INITIALIZE_TEST_QUADS();
593 child_transform
.Translate(50, 49);
594 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
600 render_surface_layer_list
);
601 gfx::Rect
child_opaque_rect(child_rect
.x() + child_rect
.width() / 4,
602 child_rect
.y() + child_rect
.height() / 4,
603 child_rect
.width() / 2,
604 child_rect
.height() / 2);
605 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
611 render_surface_layer_list
);
612 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
613 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
615 AppendQuads(&quad_list
,
620 AppendQuads(&quad_list
,
625 EXPECT_EQ(13u, quad_list
.size());
627 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
628 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(),
631 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
636 TEST_F(QuadCullerTest
, NonAxisAlignedQuadsDontOcclude
) {
637 DECLARE_AND_INITIALIZE_TEST_QUADS();
639 // Use a small rotation so as to not disturb the geometry significantly.
640 child_transform
.Rotate(1);
642 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
648 render_surface_layer_list
);
649 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
655 render_surface_layer_list
);
656 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
657 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
659 AppendQuads(&quad_list
,
664 AppendQuads(&quad_list
,
669 EXPECT_EQ(13u, quad_list
.size());
671 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 130000, 1);
673 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
675 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
678 // This test requires some explanation: here we are rotating the quads to be
679 // culled. The 2x2 tile child layer remains in the top-left corner, unrotated,
680 // but the 3x3 tile parent layer is rotated by 1 degree. Of the four tiles the
681 // child would normally occlude, three will move (slightly) out from under the
682 // child layer, and one moves further under the child. Only this last tile
684 TEST_F(QuadCullerTest
, NonAxisAlignedQuadsSafelyCulled
) {
685 DECLARE_AND_INITIALIZE_TEST_QUADS();
687 // Use a small rotation so as to not disturb the geometry significantly.
688 gfx::Transform parent_transform
;
689 parent_transform
.Rotate(1);
691 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
697 render_surface_layer_list
);
698 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
704 render_surface_layer_list
);
705 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
706 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
708 AppendQuads(&quad_list
,
713 AppendQuads(&quad_list
,
718 EXPECT_EQ(12u, quad_list
.size());
720 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque(), 100600, 1);
722 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
723 EXPECT_NEAR(occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing(),
728 TEST_F(QuadCullerTest
, WithoutMetrics
) {
729 DECLARE_AND_INITIALIZE_TEST_QUADS();
730 scoped_ptr
<TiledLayerImpl
> root_layer
= MakeLayer(NULL
,
736 render_surface_layer_list
);
737 scoped_ptr
<TiledLayerImpl
> child_layer
= MakeLayer(root_layer
.get(),
743 render_surface_layer_list
);
744 bool record_metrics
= false;
745 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000),
747 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
749 AppendQuads(&quad_list
,
754 AppendQuads(&quad_list
,
759 EXPECT_EQ(9u, quad_list
.size());
761 occlusion_tracker
.overdraw_metrics()->pixels_drawn_opaque());
763 occlusion_tracker
.overdraw_metrics()->pixels_drawn_translucent());
765 occlusion_tracker
.overdraw_metrics()->pixels_culled_for_drawing());
768 TEST_F(QuadCullerTest
, PartialCullingNotDestroyed
) {
769 DECLARE_AND_INITIALIZE_TEST_QUADS();
771 scoped_ptr
<TiledLayerImpl
> dummy_layer
= MakeLayer(NULL
,
777 render_surface_layer_list
);
779 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(1000, 1000));
780 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
782 QuadCuller
culler(&quad_list
,
789 SharedQuadState
* sqs
= culler
.UseSharedQuadState(SharedQuadState::Create());
791 scoped_ptr
<SolidColorDrawQuad
> color_quad
= SolidColorDrawQuad::Create();
792 color_quad
->SetNew(sqs
, gfx::Rect(100, 100), SK_ColorRED
, false);
794 scoped_ptr
<RenderPassDrawQuad
> pass_quad
= RenderPassDrawQuad::Create();
795 pass_quad
->SetNew(sqs
,
797 RenderPass::Id(10, 10),
805 scoped_ptr
<RenderPassDrawQuad
> replica_quad
= RenderPassDrawQuad::Create();
806 replica_quad
->SetNew(sqs
,
808 RenderPass::Id(10, 10),
816 // Set a visible rect on the quads.
817 color_quad
->visible_rect
= gfx::Rect(20, 30, 10, 11);
818 pass_quad
->visible_rect
= gfx::Rect(50, 60, 13, 14);
819 replica_quad
->visible_rect
= gfx::Rect(30, 40, 15, 16);
821 // Nothing is occluding.
822 occlusion_tracker
.EnterLayer(it
);
824 EXPECT_EQ(0u, quad_list
.size());
826 AppendQuadsData data
;
827 culler
.Append(color_quad
.PassAs
<DrawQuad
>(), &data
);
828 culler
.Append(pass_quad
.PassAs
<DrawQuad
>(), &data
);
829 culler
.Append(replica_quad
.PassAs
<DrawQuad
>(), &data
);
831 ASSERT_EQ(3u, quad_list
.size());
833 // The partial culling is preserved.
834 EXPECT_EQ(gfx::Rect(20, 30, 10, 11).ToString(),
835 quad_list
[0]->visible_rect
.ToString());
836 EXPECT_EQ(gfx::Rect(50, 60, 13, 14).ToString(),
837 quad_list
[1]->visible_rect
.ToString());
838 EXPECT_EQ(gfx::Rect(30, 40, 15, 16).ToString(),
839 quad_list
[2]->visible_rect
.ToString());
842 TEST_F(QuadCullerTest
, PartialCullingWithOcclusionNotDestroyed
) {
843 DECLARE_AND_INITIALIZE_TEST_QUADS();
845 scoped_ptr
<TiledLayerImpl
> dummy_layer
= MakeLayer(NULL
,
851 render_surface_layer_list
);
853 TestOcclusionTrackerImpl
occlusion_tracker(gfx::Rect(1000, 1000));
854 LayerIteratorType it
= LayerIteratorType::Begin(&render_surface_layer_list
);
856 QuadCuller
culler(&quad_list
,
863 SharedQuadState
* sqs
= culler
.UseSharedQuadState(SharedQuadState::Create());
865 scoped_ptr
<SolidColorDrawQuad
> color_quad
= SolidColorDrawQuad::Create();
866 color_quad
->SetNew(sqs
, gfx::Rect(100, 100), SK_ColorRED
, false);
868 scoped_ptr
<RenderPassDrawQuad
> pass_quad
= RenderPassDrawQuad::Create();
869 pass_quad
->SetNew(sqs
,
871 RenderPass::Id(10, 10),
879 scoped_ptr
<RenderPassDrawQuad
> replica_quad
= RenderPassDrawQuad::Create();
880 replica_quad
->SetNew(sqs
,
882 RenderPass::Id(10, 10),
890 // Set a visible rect on the quads.
891 color_quad
->visible_rect
= gfx::Rect(10, 10, 10, 11);
892 pass_quad
->visible_rect
= gfx::Rect(10, 20, 13, 14);
893 replica_quad
->visible_rect
= gfx::Rect(10, 30, 15, 16);
895 // Occlude the left part of the visible rects.
896 occlusion_tracker
.EnterLayer(it
);
897 occlusion_tracker
.set_occlusion_from_outside_target(gfx::Rect(0, 0, 15, 100));
899 EXPECT_EQ(0u, quad_list
.size());
901 AppendQuadsData data
;
902 culler
.Append(color_quad
.PassAs
<DrawQuad
>(), &data
);
903 culler
.Append(pass_quad
.PassAs
<DrawQuad
>(), &data
);
904 culler
.Append(replica_quad
.PassAs
<DrawQuad
>(), &data
);
906 ASSERT_EQ(3u, quad_list
.size());
908 // The partial culling is preserved, while the left side of the quads is newly
910 EXPECT_EQ(gfx::Rect(15, 10, 5, 11).ToString(),
911 quad_list
[0]->visible_rect
.ToString());
912 EXPECT_EQ(gfx::Rect(15, 20, 8, 14).ToString(),
913 quad_list
[1]->visible_rect
.ToString());
914 EXPECT_EQ(gfx::Rect(15, 30, 10, 16).ToString(),
915 quad_list
[2]->visible_rect
.ToString());