Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / cc / trees / quad_culler_unittest.cc
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.
4
5 #include "cc/trees/quad_culler.h"
6
7 #include <vector>
8
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"
26
27 namespace cc {
28 namespace {
29
30 class TestOcclusionTrackerImpl
31     : public TestOcclusionTrackerBase<LayerImpl, RenderSurfaceImpl> {
32  public:
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) {}
37
38  private:
39   DISALLOW_COPY_AND_ASSIGN(TestOcclusionTrackerImpl);
40 };
41
42 typedef LayerIterator<LayerImpl> LayerIteratorType;
43
44 class QuadCullerTest : public testing::Test {
45  public:
46   QuadCullerTest()
47       : host_impl_(&proxy_),
48         layer_id_(1) {}
49
50   scoped_ptr<TiledLayerImpl> MakeLayer(TiledLayerImpl* parent,
51                                        const gfx::Transform& draw_transform,
52                                        const gfx::Rect& layer_rect,
53                                        float opacity,
54                                        bool opaque,
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());
72
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 =
77             opaque
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);
81       }
82     }
83
84     gfx::Rect rect_in_target = MathUtil::MapEnclosingClippedRect(
85         layer->draw_transform(), layer->visible_content_rect());
86     if (!parent) {
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());
91     } else {
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);
97     }
98     layer->draw_properties().drawable_content_rect = rect_in_target;
99
100     return layer.Pass();
101   }
102
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);
114     ++it;
115   }
116
117  protected:
118   FakeImplProxy proxy_;
119   FakeLayerTreeHostImpl host_impl_;
120   int layer_id_;
121
122  private:
123   DISALLOW_COPY_AND_ASSIGN(QuadCullerTest);
124 };
125
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);
135
136 TEST_F(QuadCullerTest, NoCulling) {
137   DECLARE_AND_INITIALIZE_TEST_QUADS();
138
139   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
140                                                     gfx::Transform(),
141                                                     root_rect,
142                                                     1.f,
143                                                     true,
144                                                     gfx::Rect(),
145                                                     render_surface_layer_list);
146   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
147                                                      gfx::Transform(),
148                                                      child_rect,
149                                                      1.f,
150                                                      false,
151                                                      gfx::Rect(),
152                                                      render_surface_layer_list);
153   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
154   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
155
156   AppendQuads(&quad_list,
157               &shared_state_list,
158               child_layer.get(),
159               &it,
160               &occlusion_tracker);
161   AppendQuads(&quad_list,
162               &shared_state_list,
163               root_layer.get(),
164               &it,
165               &occlusion_tracker);
166   EXPECT_EQ(13u, quad_list.size());
167   EXPECT_NEAR(
168       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
169   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
170               40000,
171               1);
172   EXPECT_NEAR(
173       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
174 }
175
176 TEST_F(QuadCullerTest, CullChildLinesUpTopLeft) {
177   DECLARE_AND_INITIALIZE_TEST_QUADS();
178
179   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
180                                                     gfx::Transform(),
181                                                     root_rect,
182                                                     1.f,
183                                                     true,
184                                                     gfx::Rect(),
185                                                     render_surface_layer_list);
186   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
187                                                      gfx::Transform(),
188                                                      child_rect,
189                                                      1.f,
190                                                      true,
191                                                      gfx::Rect(),
192                                                      render_surface_layer_list);
193   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
194   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
195
196   AppendQuads(&quad_list,
197               &shared_state_list,
198               child_layer.get(),
199               &it,
200               &occlusion_tracker);
201   AppendQuads(&quad_list,
202               &shared_state_list,
203               root_layer.get(),
204               &it,
205               &occlusion_tracker);
206   EXPECT_EQ(9u, quad_list.size());
207   EXPECT_NEAR(
208       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
209   EXPECT_NEAR(
210       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
211   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
212               40000,
213               1);
214 }
215
216 TEST_F(QuadCullerTest, CullWhenChildOpacityNotOne) {
217   DECLARE_AND_INITIALIZE_TEST_QUADS();
218
219   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
220                                                     gfx::Transform(),
221                                                     root_rect,
222                                                     1.f,
223                                                     true,
224                                                     gfx::Rect(),
225                                                     render_surface_layer_list);
226   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
227                                                      child_transform,
228                                                      child_rect,
229                                                      0.9f,
230                                                      true,
231                                                      gfx::Rect(),
232                                                      render_surface_layer_list);
233   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
234   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
235
236   AppendQuads(&quad_list,
237               &shared_state_list,
238               child_layer.get(),
239               &it,
240               &occlusion_tracker);
241   AppendQuads(&quad_list,
242               &shared_state_list,
243               root_layer.get(),
244               &it,
245               &occlusion_tracker);
246   EXPECT_EQ(13u, quad_list.size());
247   EXPECT_NEAR(
248       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
249   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
250               40000,
251               1);
252   EXPECT_NEAR(
253       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
254 }
255
256 TEST_F(QuadCullerTest, CullWhenChildOpaqueFlagFalse) {
257   DECLARE_AND_INITIALIZE_TEST_QUADS();
258
259   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
260                                                     gfx::Transform(),
261                                                     root_rect,
262                                                     1.f,
263                                                     true,
264                                                     gfx::Rect(),
265                                                     render_surface_layer_list);
266   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
267                                                      child_transform,
268                                                      child_rect,
269                                                      1.f,
270                                                      false,
271                                                      gfx::Rect(),
272                                                      render_surface_layer_list);
273   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
274   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
275
276   AppendQuads(&quad_list,
277               &shared_state_list,
278               child_layer.get(),
279               &it,
280               &occlusion_tracker);
281   AppendQuads(&quad_list,
282               &shared_state_list,
283               root_layer.get(),
284               &it,
285               &occlusion_tracker);
286   EXPECT_EQ(13u, quad_list.size());
287   EXPECT_NEAR(
288       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
289   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
290               40000,
291               1);
292   EXPECT_NEAR(
293       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
294 }
295
296 TEST_F(QuadCullerTest, CullCenterTileOnly) {
297   DECLARE_AND_INITIALIZE_TEST_QUADS();
298
299   child_transform.Translate(50, 50);
300   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
301                                                     gfx::Transform(),
302                                                     root_rect,
303                                                     1.f,
304                                                     true,
305                                                     gfx::Rect(),
306                                                     render_surface_layer_list);
307   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
308                                                      child_transform,
309                                                      child_rect,
310                                                      1.f,
311                                                      true,
312                                                      gfx::Rect(),
313                                                      render_surface_layer_list);
314   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
315   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
316
317   AppendQuads(&quad_list,
318               &shared_state_list,
319               child_layer.get(),
320               &it,
321               &occlusion_tracker);
322   AppendQuads(&quad_list,
323               &shared_state_list,
324               root_layer.get(),
325               &it,
326               &occlusion_tracker);
327   ASSERT_EQ(quad_list.size(), 12u);
328
329   gfx::Rect quad_visible_rect1 = quad_list[5]->visible_rect;
330   EXPECT_EQ(50, quad_visible_rect1.height());
331
332   gfx::Rect quad_visible_rect3 = quad_list[7]->visible_rect;
333   EXPECT_EQ(50, quad_visible_rect3.width());
334
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());
339
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());
343
344   EXPECT_NEAR(
345       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 100000, 1);
346   EXPECT_NEAR(
347       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
348   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
349               30000,
350               1);
351 }
352
353 TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize1) {
354   DECLARE_AND_INITIALIZE_TEST_QUADS();
355
356   child_transform.Translate(100, 100);
357
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);
363
364   root_rect = child_rect = gfx::Rect(0, 0, 100, 100);
365
366   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
367                                                     root_transform,
368                                                     root_rect,
369                                                     1.f,
370                                                     true,
371                                                     gfx::Rect(),
372                                                     render_surface_layer_list);
373   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
374                                                      child_transform,
375                                                      child_rect,
376                                                      1.f,
377                                                      true,
378                                                      gfx::Rect(),
379                                                      render_surface_layer_list);
380   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
381   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
382
383   AppendQuads(&quad_list,
384               &shared_state_list,
385               child_layer.get(),
386               &it,
387               &occlusion_tracker);
388   AppendQuads(&quad_list,
389               &shared_state_list,
390               root_layer.get(),
391               &it,
392               &occlusion_tracker);
393   EXPECT_EQ(2u, quad_list.size());
394
395   EXPECT_NEAR(
396       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 20363, 1);
397   EXPECT_NEAR(
398       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
399   EXPECT_NEAR(
400       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
401 }
402
403 TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize2) {
404   DECLARE_AND_INITIALIZE_TEST_QUADS();
405
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
408   // due to rounding.
409   child_transform.Translate(100.1f, 100.1f);
410   child_transform.Scale(0.982f, 0.982f);
411
412   gfx::Transform root_transform;
413   root_transform.Translate(100, 100);
414
415   root_rect = child_rect = gfx::Rect(0, 0, 100, 100);
416
417   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
418                                                     root_transform,
419                                                     root_rect,
420                                                     1.f,
421                                                     true,
422                                                     gfx::Rect(),
423                                                     render_surface_layer_list);
424   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
425                                                      child_transform,
426                                                      child_rect,
427                                                      1.f,
428                                                      true,
429                                                      gfx::Rect(),
430                                                      render_surface_layer_list);
431   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
432   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
433
434   AppendQuads(&quad_list,
435               &shared_state_list,
436               child_layer.get(),
437               &it,
438               &occlusion_tracker);
439   AppendQuads(&quad_list,
440               &shared_state_list,
441               root_layer.get(),
442               &it,
443               &occlusion_tracker);
444   EXPECT_EQ(2u, quad_list.size());
445
446   EXPECT_NEAR(
447       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 19643, 1);
448   EXPECT_NEAR(
449       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
450   EXPECT_NEAR(
451       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
452 }
453
454 TEST_F(QuadCullerTest, CullChildLinesUpBottomRight) {
455   DECLARE_AND_INITIALIZE_TEST_QUADS();
456
457   child_transform.Translate(100, 100);
458   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
459                                                     gfx::Transform(),
460                                                     root_rect,
461                                                     1.f,
462                                                     true,
463                                                     gfx::Rect(),
464                                                     render_surface_layer_list);
465   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
466                                                      child_transform,
467                                                      child_rect,
468                                                      1.f,
469                                                      true,
470                                                      gfx::Rect(),
471                                                      render_surface_layer_list);
472   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
473   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
474
475   AppendQuads(&quad_list,
476               &shared_state_list,
477               child_layer.get(),
478               &it,
479               &occlusion_tracker);
480   AppendQuads(&quad_list,
481               &shared_state_list,
482               root_layer.get(),
483               &it,
484               &occlusion_tracker);
485   EXPECT_EQ(9u, quad_list.size());
486   EXPECT_NEAR(
487       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
488   EXPECT_NEAR(
489       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
490   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
491               40000,
492               1);
493 }
494
495 TEST_F(QuadCullerTest, CullSubRegion) {
496   DECLARE_AND_INITIALIZE_TEST_QUADS();
497
498   child_transform.Translate(50, 50);
499   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
500                                                     gfx::Transform(),
501                                                     root_rect,
502                                                     1.f,
503                                                     true,
504                                                     gfx::Rect(),
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(),
511                                                      child_transform,
512                                                      child_rect,
513                                                      1.f,
514                                                      false,
515                                                      child_opaque_rect,
516                                                      render_surface_layer_list);
517   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
518   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
519
520   AppendQuads(&quad_list,
521               &shared_state_list,
522               child_layer.get(),
523               &it,
524               &occlusion_tracker);
525   AppendQuads(&quad_list,
526               &shared_state_list,
527               root_layer.get(),
528               &it,
529               &occlusion_tracker);
530   EXPECT_EQ(12u, quad_list.size());
531   EXPECT_NEAR(
532       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
533   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
534               30000,
535               1);
536   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
537               10000,
538               1);
539 }
540
541 TEST_F(QuadCullerTest, CullSubRegion2) {
542   DECLARE_AND_INITIALIZE_TEST_QUADS();
543
544   child_transform.Translate(50, 10);
545   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
546                                                     gfx::Transform(),
547                                                     root_rect,
548                                                     1.f,
549                                                     true,
550                                                     gfx::Rect(),
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(),
557                                                      child_transform,
558                                                      child_rect,
559                                                      1.f,
560                                                      false,
561                                                      child_opaque_rect,
562                                                      render_surface_layer_list);
563   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
564   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
565
566   AppendQuads(&quad_list,
567               &shared_state_list,
568               child_layer.get(),
569               &it,
570               &occlusion_tracker);
571   AppendQuads(&quad_list,
572               &shared_state_list,
573               root_layer.get(),
574               &it,
575               &occlusion_tracker);
576   EXPECT_EQ(12u, quad_list.size());
577   EXPECT_NEAR(
578       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
579   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
580               25000,
581               1);
582   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
583               15000,
584               1);
585 }
586
587 TEST_F(QuadCullerTest, CullSubRegionCheckOvercull) {
588   DECLARE_AND_INITIALIZE_TEST_QUADS();
589
590   child_transform.Translate(50, 49);
591   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
592                                                     gfx::Transform(),
593                                                     root_rect,
594                                                     1.f,
595                                                     true,
596                                                     gfx::Rect(),
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(),
603                                                      child_transform,
604                                                      child_rect,
605                                                      1.f,
606                                                      false,
607                                                      child_opaque_rect,
608                                                      render_surface_layer_list);
609   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
610   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
611
612   AppendQuads(&quad_list,
613               &shared_state_list,
614               child_layer.get(),
615               &it,
616               &occlusion_tracker);
617   AppendQuads(&quad_list,
618               &shared_state_list,
619               root_layer.get(),
620               &it,
621               &occlusion_tracker);
622   EXPECT_EQ(13u, quad_list.size());
623   EXPECT_NEAR(
624       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 90000, 1);
625   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(),
626               30000,
627               1);
628   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
629               10000,
630               1);
631 }
632
633 TEST_F(QuadCullerTest, NonAxisAlignedQuadsDontOcclude) {
634   DECLARE_AND_INITIALIZE_TEST_QUADS();
635
636   // Use a small rotation so as to not disturb the geometry significantly.
637   child_transform.Rotate(1);
638
639   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
640                                                     gfx::Transform(),
641                                                     root_rect,
642                                                     1.f,
643                                                     true,
644                                                     gfx::Rect(),
645                                                     render_surface_layer_list);
646   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
647                                                      child_transform,
648                                                      child_rect,
649                                                      1.f,
650                                                      true,
651                                                      gfx::Rect(),
652                                                      render_surface_layer_list);
653   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
654   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
655
656   AppendQuads(&quad_list,
657               &shared_state_list,
658               child_layer.get(),
659               &it,
660               &occlusion_tracker);
661   AppendQuads(&quad_list,
662               &shared_state_list,
663               root_layer.get(),
664               &it,
665               &occlusion_tracker);
666   EXPECT_EQ(13u, quad_list.size());
667   EXPECT_NEAR(
668       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 130000, 1);
669   EXPECT_NEAR(
670       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
671   EXPECT_NEAR(
672       occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
673 }
674
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
680 // should be culled.
681 TEST_F(QuadCullerTest, NonAxisAlignedQuadsSafelyCulled) {
682   DECLARE_AND_INITIALIZE_TEST_QUADS();
683
684   // Use a small rotation so as to not disturb the geometry significantly.
685   gfx::Transform parent_transform;
686   parent_transform.Rotate(1);
687
688   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
689                                                     parent_transform,
690                                                     root_rect,
691                                                     1.f,
692                                                     true,
693                                                     gfx::Rect(),
694                                                     render_surface_layer_list);
695   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
696                                                      gfx::Transform(),
697                                                      child_rect,
698                                                      1.f,
699                                                      true,
700                                                      gfx::Rect(),
701                                                      render_surface_layer_list);
702   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000));
703   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
704
705   AppendQuads(&quad_list,
706               &shared_state_list,
707               child_layer.get(),
708               &it,
709               &occlusion_tracker);
710   AppendQuads(&quad_list,
711               &shared_state_list,
712               root_layer.get(),
713               &it,
714               &occlusion_tracker);
715   EXPECT_EQ(12u, quad_list.size());
716   EXPECT_NEAR(
717       occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque(), 100600, 1);
718   EXPECT_NEAR(
719       occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent(), 0, 1);
720   EXPECT_NEAR(occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(),
721               29400,
722               1);
723 }
724
725 TEST_F(QuadCullerTest, WithoutMetrics) {
726   DECLARE_AND_INITIALIZE_TEST_QUADS();
727   scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
728                                                     gfx::Transform(),
729                                                     root_rect,
730                                                     1.f,
731                                                     true,
732                                                     gfx::Rect(),
733                                                     render_surface_layer_list);
734   scoped_ptr<TiledLayerImpl> child_layer = MakeLayer(root_layer.get(),
735                                                      gfx::Transform(),
736                                                      child_rect,
737                                                      1.f,
738                                                      true,
739                                                      gfx::Rect(),
740                                                      render_surface_layer_list);
741   bool record_metrics = false;
742   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(-100, -100, 1000, 1000),
743                                              record_metrics);
744   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
745
746   AppendQuads(&quad_list,
747               &shared_state_list,
748               child_layer.get(),
749               &it,
750               &occlusion_tracker);
751   AppendQuads(&quad_list,
752               &shared_state_list,
753               root_layer.get(),
754               &it,
755               &occlusion_tracker);
756   EXPECT_EQ(9u, quad_list.size());
757   EXPECT_EQ(0.f,
758             occlusion_tracker.overdraw_metrics()->pixels_drawn_opaque());
759   EXPECT_EQ(0.f,
760             occlusion_tracker.overdraw_metrics()->pixels_drawn_translucent());
761   EXPECT_EQ(0.f,
762             occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing());
763 }
764
765 TEST_F(QuadCullerTest, PartialCullingNotDestroyed) {
766   DECLARE_AND_INITIALIZE_TEST_QUADS();
767
768   scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
769                                                      gfx::Transform(),
770                                                      gfx::Rect(),
771                                                      1.f,
772                                                      true,
773                                                      gfx::Rect(),
774                                                      render_surface_layer_list);
775
776   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
777   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
778
779   QuadCuller culler(&quad_list,
780                     &shared_state_list,
781                     dummy_layer.get(),
782                     occlusion_tracker,
783                     false,
784                     false);
785
786   SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
787
788   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
789   color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
790
791   scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
792   pass_quad->SetNew(sqs,
793                     gfx::Rect(100, 100),
794                     RenderPass::Id(10, 10),
795                     false,
796                     0,
797                     gfx::Rect(),
798                     gfx::RectF(),
799                     FilterOperations(),
800                     FilterOperations());
801
802   scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
803   replica_quad->SetNew(sqs,
804                        gfx::Rect(100, 100),
805                        RenderPass::Id(10, 10),
806                        true,
807                        0,
808                        gfx::Rect(),
809                        gfx::RectF(),
810                        FilterOperations(),
811                        FilterOperations());
812
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);
817
818   // Nothing is occluding.
819   occlusion_tracker.EnterLayer(it);
820
821   EXPECT_EQ(0u, quad_list.size());
822
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);
827
828   ASSERT_EQ(3u, quad_list.size());
829
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());
837 }
838
839 TEST_F(QuadCullerTest, PartialCullingWithOcclusionNotDestroyed) {
840   DECLARE_AND_INITIALIZE_TEST_QUADS();
841
842   scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
843                                                      gfx::Transform(),
844                                                      gfx::Rect(),
845                                                      1.f,
846                                                      true,
847                                                      gfx::Rect(),
848                                                      render_surface_layer_list);
849
850   TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
851   LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
852
853   QuadCuller culler(&quad_list,
854                     &shared_state_list,
855                     dummy_layer.get(),
856                     occlusion_tracker,
857                     false,
858                     false);
859
860   SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
861
862   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
863   color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
864
865   scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
866   pass_quad->SetNew(sqs,
867                     gfx::Rect(100, 100),
868                     RenderPass::Id(10, 10),
869                     false,
870                     0,
871                     gfx::Rect(),
872                     gfx::RectF(),
873                     FilterOperations(),
874                     FilterOperations());
875
876   scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
877   replica_quad->SetNew(sqs,
878                        gfx::Rect(100, 100),
879                        RenderPass::Id(10, 10),
880                        true,
881                        0,
882                        gfx::Rect(),
883                        gfx::RectF(),
884                        FilterOperations(),
885                        FilterOperations());
886
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);
891
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));
895
896   EXPECT_EQ(0u, quad_list.size());
897
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);
902
903   ASSERT_EQ(3u, quad_list.size());
904
905   // The partial culling is preserved, while the left side of the quads is newly
906   // occluded.
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());
913 }
914
915 }  // namespace
916 }  // namespace cc