- add sources.
[platform/framework/web/crosswalk.git] / src / cc / trees / occlusion_tracker_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/occlusion_tracker.h"
6
7 #include "cc/animation/layer_animation_controller.h"
8 #include "cc/base/math_util.h"
9 #include "cc/debug/overdraw_metrics.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/output/copy_output_request.h"
13 #include "cc/output/copy_output_result.h"
14 #include "cc/output/filter_operation.h"
15 #include "cc/output/filter_operations.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_layer_tree_host_impl.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/occlusion_tracker_test_common.h"
22 #include "cc/trees/layer_tree_host_common.h"
23 #include "cc/trees/single_thread_proxy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/transform.h"
27
28 namespace cc {
29 namespace {
30
31 class TestContentLayer : public Layer {
32  public:
33   TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
34     SetIsDrawable(true);
35   }
36
37   virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
38     if (override_opaque_contents_rect_)
39       return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
40     return Layer::VisibleContentOpaqueRegion();
41   }
42   void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
43     override_opaque_contents_rect_ = true;
44     opaque_contents_rect_ = opaque_contents_rect;
45   }
46
47  private:
48   virtual ~TestContentLayer() {}
49
50   bool override_opaque_contents_rect_;
51   gfx::Rect opaque_contents_rect_;
52 };
53
54 class TestContentLayerImpl : public LayerImpl {
55  public:
56   TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
57       : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
58     SetDrawsContent(true);
59   }
60
61   virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
62     if (override_opaque_contents_rect_)
63       return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
64     return LayerImpl::VisibleContentOpaqueRegion();
65   }
66   void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
67     override_opaque_contents_rect_ = true;
68     opaque_contents_rect_ = opaque_contents_rect;
69   }
70
71  private:
72   bool override_opaque_contents_rect_;
73   gfx::Rect opaque_contents_rect_;
74 };
75
76 static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
77   return layer->draw_transform_is_animating();
78 }
79 static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
80   return false;
81 }
82
83 template <typename LayerType, typename RenderSurfaceType>
84 class TestOcclusionTrackerWithClip
85     : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
86  public:
87   TestOcclusionTrackerWithClip(gfx::Rect viewport_rect,
88                                bool record_metrics_for_frame)
89       : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
90             viewport_rect,
91             record_metrics_for_frame) {}
92   explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect)
93       : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
94                                                                false) {}
95
96   bool OccludedLayer(const LayerType* layer,
97                      gfx::Rect content_rect) const {
98     DCHECK(layer->visible_content_rect().Contains(content_rect));
99     return this->Occluded(layer->render_target(),
100                           content_rect,
101                           layer->draw_transform(),
102                           LayerImplDrawTransformIsUnknown(layer));
103   }
104
105   // Gives an unoccluded sub-rect of |content_rect| in the content space of the
106   // layer. Simple wrapper around UnoccludedContentRect.
107   gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
108                                        gfx::Rect content_rect) const {
109     DCHECK(layer->visible_content_rect().Contains(content_rect));
110     return this->UnoccludedContentRect(
111         layer->render_target(),
112         content_rect,
113         layer->draw_transform(),
114         LayerImplDrawTransformIsUnknown(layer));
115   }
116 };
117
118 struct OcclusionTrackerTestMainThreadTypes {
119   typedef Layer LayerType;
120   typedef FakeLayerTreeHost HostType;
121   typedef RenderSurface RenderSurfaceType;
122   typedef TestContentLayer ContentLayerType;
123   typedef scoped_refptr<Layer> LayerPtrType;
124   typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
125   typedef LayerIterator<Layer,
126                         RenderSurfaceLayerList,
127                         RenderSurface,
128                         LayerIteratorActions::FrontToBack> TestLayerIterator;
129   typedef OcclusionTracker OcclusionTrackerType;
130
131   static LayerPtrType CreateLayer(HostType*  host) { return Layer::Create(); }
132   static ContentLayerPtrType CreateContentLayer(HostType* host) {
133     return make_scoped_refptr(new ContentLayerType());
134   }
135
136   static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
137     LayerPtrType ref(*layer);
138     *layer = NULL;
139     return ref;
140   }
141
142   static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
143     LayerPtrType ref(*layer);
144     *layer = NULL;
145     return ref;
146   }
147
148   static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
149 };
150
151 struct OcclusionTrackerTestImplThreadTypes {
152   typedef LayerImpl LayerType;
153   typedef LayerTreeImpl HostType;
154   typedef RenderSurfaceImpl RenderSurfaceType;
155   typedef TestContentLayerImpl ContentLayerType;
156   typedef scoped_ptr<LayerImpl> LayerPtrType;
157   typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
158   typedef LayerIterator<LayerImpl,
159                         LayerImplList,
160                         RenderSurfaceImpl,
161                         LayerIteratorActions::FrontToBack> TestLayerIterator;
162   typedef OcclusionTrackerImpl OcclusionTrackerType;
163
164   static LayerPtrType CreateLayer(HostType* host) {
165     return LayerImpl::Create(host, next_layer_impl_id++);
166   }
167   static ContentLayerPtrType CreateContentLayer(HostType* host) {
168     return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
169   }
170   static int next_layer_impl_id;
171
172   static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
173     return layer->Pass();
174   }
175
176   static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
177     return layer->PassAs<LayerType>();
178   }
179
180   static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
181 };
182
183 int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
184
185 template <typename Types> class OcclusionTrackerTest : public testing::Test {
186  protected:
187   explicit OcclusionTrackerTest(bool opaque_layers)
188       : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {}
189
190   virtual void RunMyTest() = 0;
191
192   virtual void TearDown() {
193     Types::DestroyLayer(&root_);
194     render_surface_layer_list_.reset();
195     render_surface_layer_list_impl_.clear();
196     replica_layers_.clear();
197     mask_layers_.clear();
198   }
199
200   typename Types::HostType* GetHost();
201
202   typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
203                                                gfx::PointF position,
204                                                gfx::Size bounds) {
205     typename Types::ContentLayerPtrType layer(
206         Types::CreateContentLayer(GetHost()));
207     typename Types::ContentLayerType* layer_ptr = layer.get();
208     SetProperties(layer_ptr, transform, position, bounds);
209
210     DCHECK(!root_.get());
211     root_ = Types::PassLayerPtr(&layer);
212
213     SetRootLayerOnMainThread(layer_ptr);
214
215     return layer_ptr;
216   }
217
218   typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
219                                          const gfx::Transform& transform,
220                                          gfx::PointF position,
221                                          gfx::Size bounds) {
222     typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
223     typename Types::LayerType* layer_ptr = layer.get();
224     SetProperties(layer_ptr, transform, position, bounds);
225     parent->AddChild(Types::PassLayerPtr(&layer));
226     return layer_ptr;
227   }
228
229   typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
230                                            const gfx::Transform& transform,
231                                            gfx::PointF position,
232                                            gfx::Size bounds) {
233     typename Types::LayerType* layer =
234         CreateLayer(parent, transform, position, bounds);
235     layer->SetForceRenderSurface(true);
236     return layer;
237   }
238
239   typename Types::ContentLayerType* CreateDrawingLayer(
240       typename Types::LayerType* parent,
241       const gfx::Transform& transform,
242       gfx::PointF position,
243       gfx::Size bounds,
244       bool opaque) {
245     typename Types::ContentLayerPtrType layer(
246         Types::CreateContentLayer(GetHost()));
247     typename Types::ContentLayerType* layer_ptr = layer.get();
248     SetProperties(layer_ptr, transform, position, bounds);
249
250     if (opaque_layers_) {
251       layer_ptr->SetContentsOpaque(opaque);
252     } else {
253       layer_ptr->SetContentsOpaque(false);
254       if (opaque)
255         layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
256       else
257         layer_ptr->SetOpaqueContentsRect(gfx::Rect());
258     }
259
260     parent->AddChild(Types::PassLayerPtr(&layer));
261     return layer_ptr;
262   }
263
264   typename Types::LayerType* CreateReplicaLayer(
265       typename Types::LayerType* owning_layer,
266       const gfx::Transform& transform,
267       gfx::PointF position,
268       gfx::Size bounds) {
269     typename Types::ContentLayerPtrType layer(
270         Types::CreateContentLayer(GetHost()));
271     typename Types::ContentLayerType* layer_ptr = layer.get();
272     SetProperties(layer_ptr, transform, position, bounds);
273     SetReplica(owning_layer, Types::PassLayerPtr(&layer));
274     return layer_ptr;
275   }
276
277   typename Types::LayerType* CreateMaskLayer(
278       typename Types::LayerType* owning_layer,
279       gfx::Size bounds) {
280     typename Types::ContentLayerPtrType layer(
281         Types::CreateContentLayer(GetHost()));
282     typename Types::ContentLayerType* layer_ptr = layer.get();
283     SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
284     SetMask(owning_layer, Types::PassLayerPtr(&layer));
285     return layer_ptr;
286   }
287
288   typename Types::ContentLayerType* CreateDrawingSurface(
289       typename Types::LayerType* parent,
290       const gfx::Transform& transform,
291       gfx::PointF position,
292       gfx::Size bounds,
293       bool opaque) {
294     typename Types::ContentLayerType* layer =
295         CreateDrawingLayer(parent, transform, position, bounds, opaque);
296     layer->SetForceRenderSurface(true);
297     return layer;
298   }
299
300
301   void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
302
303   void AddCopyRequest(Layer* layer) {
304     layer->RequestCopyOfOutput(
305         CopyOutputRequest::CreateBitmapRequest(base::Bind(
306             &OcclusionTrackerTest<Types>::CopyOutputCallback,
307             base::Unretained(this))));
308   }
309
310   void AddCopyRequest(LayerImpl* layer) {
311     ScopedPtrVector<CopyOutputRequest> requests;
312     requests.push_back(
313         CopyOutputRequest::CreateBitmapRequest(base::Bind(
314             &OcclusionTrackerTest<Types>::CopyOutputCallback,
315             base::Unretained(this))));
316     layer->PassCopyRequests(&requests);
317   }
318
319   void CalcDrawEtc(TestContentLayerImpl* root) {
320     DCHECK(root == root_.get());
321     DCHECK(!root->render_surface());
322
323     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
324         root, root->bounds(), &render_surface_layer_list_impl_);
325     inputs.can_adjust_raster_scales = true;
326     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
327
328     layer_iterator_ = layer_iterator_begin_ =
329         Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
330   }
331
332   void CalcDrawEtc(TestContentLayer* root) {
333     DCHECK(root == root_.get());
334     DCHECK(!root->render_surface());
335
336     render_surface_layer_list_.reset(new RenderSurfaceLayerList);
337     LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
338         root, root->bounds(), render_surface_layer_list_.get());
339     inputs.can_adjust_raster_scales = true;
340     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
341
342     layer_iterator_ = layer_iterator_begin_ =
343         Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
344   }
345
346   void SetDrawsContent(LayerImpl* layer_impl, bool draws_content) {
347     layer_impl->SetDrawsContent(draws_content);
348   }
349
350   void SetDrawsContent(Layer* layer, bool draws_content) {
351     layer->SetIsDrawable(draws_content);
352   }
353
354   void EnterLayer(typename Types::LayerType* layer,
355                   typename Types::OcclusionTrackerType* occlusion,
356                   bool prevent_occlusion) {
357     ASSERT_EQ(layer, *layer_iterator_);
358     ASSERT_TRUE(layer_iterator_.represents_itself());
359     occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
360   }
361
362   void LeaveLayer(typename Types::LayerType* layer,
363                   typename Types::OcclusionTrackerType* occlusion) {
364     ASSERT_EQ(layer, *layer_iterator_);
365     ASSERT_TRUE(layer_iterator_.represents_itself());
366     occlusion->LeaveLayer(layer_iterator_);
367     ++layer_iterator_;
368   }
369
370   void VisitLayer(typename Types::LayerType* layer,
371                   typename Types::OcclusionTrackerType* occlusion) {
372     EnterLayer(layer, occlusion, false);
373     LeaveLayer(layer, occlusion);
374   }
375
376   void EnterContributingSurface(
377       typename Types::LayerType* layer,
378       typename Types::OcclusionTrackerType* occlusion,
379       bool prevent_occlusion) {
380     ASSERT_EQ(layer, *layer_iterator_);
381     ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
382     occlusion->EnterLayer(layer_iterator_, false);
383     occlusion->LeaveLayer(layer_iterator_);
384     ++layer_iterator_;
385     ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
386     occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
387   }
388
389   void LeaveContributingSurface(
390       typename Types::LayerType* layer,
391       typename Types::OcclusionTrackerType* occlusion) {
392     ASSERT_EQ(layer, *layer_iterator_);
393     ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
394     occlusion->LeaveLayer(layer_iterator_);
395     ++layer_iterator_;
396   }
397
398   void VisitContributingSurface(
399       typename Types::LayerType* layer,
400       typename Types::OcclusionTrackerType* occlusion) {
401     EnterContributingSurface(layer, occlusion, false);
402     LeaveContributingSurface(layer, occlusion);
403   }
404
405   void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
406
407   const gfx::Transform identity_matrix;
408
409  private:
410   void SetRootLayerOnMainThread(Layer* root) {
411     host_->SetRootLayer(scoped_refptr<Layer>(root));
412   }
413
414   void SetRootLayerOnMainThread(LayerImpl* root) {}
415
416   void SetBaseProperties(typename Types::LayerType* layer,
417                          const gfx::Transform& transform,
418                          gfx::PointF position,
419                          gfx::Size bounds) {
420     layer->SetTransform(transform);
421     layer->SetSublayerTransform(gfx::Transform());
422     layer->SetAnchorPoint(gfx::PointF());
423     layer->SetPosition(position);
424     layer->SetBounds(bounds);
425   }
426
427   void SetProperties(Layer* layer,
428                      const gfx::Transform& transform,
429                      gfx::PointF position,
430                      gfx::Size bounds) {
431     SetBaseProperties(layer, transform, position, bounds);
432   }
433
434   void SetProperties(LayerImpl* layer,
435                      const gfx::Transform& transform,
436                      gfx::PointF position,
437                      gfx::Size bounds) {
438     SetBaseProperties(layer, transform, position, bounds);
439
440     layer->SetContentBounds(layer->bounds());
441   }
442
443   void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
444     owning_layer->SetReplicaLayer(layer.get());
445     replica_layers_.push_back(layer);
446   }
447
448   void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
449     owning_layer->SetReplicaLayer(layer.Pass());
450   }
451
452   void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
453     owning_layer->SetMaskLayer(layer.get());
454     mask_layers_.push_back(layer);
455   }
456
457   void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
458     owning_layer->SetMaskLayer(layer.Pass());
459   }
460
461   bool opaque_layers_;
462   scoped_ptr<FakeLayerTreeHost> host_;
463   // These hold ownership of the layers for the duration of the test.
464   typename Types::LayerPtrType root_;
465   scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
466   LayerImplList render_surface_layer_list_impl_;
467   typename Types::TestLayerIterator layer_iterator_begin_;
468   typename Types::TestLayerIterator layer_iterator_;
469   typename Types::LayerType* last_layer_visited_;
470   LayerList replica_layers_;
471   LayerList mask_layers_;
472 };
473
474 template <>
475 FakeLayerTreeHost*
476 OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
477   return host_.get();
478 }
479
480 template <>
481 LayerTreeImpl*
482 OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
483   return host_->host_impl()->active_tree();
484 }
485
486 #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                          \
487   class ClassName##MainThreadOpaqueLayers                                      \
488       : public ClassName<OcclusionTrackerTestMainThreadTypes> {                \
489    public: /* NOLINT(whitespace/indent) */                                     \
490     ClassName##MainThreadOpaqueLayers()                                        \
491         : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {}              \
492   };                                                                           \
493   TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
494 #define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)                          \
495   class ClassName##MainThreadOpaquePaints                                      \
496       : public ClassName<OcclusionTrackerTestMainThreadTypes> {                \
497    public: /* NOLINT(whitespace/indent) */                                     \
498     ClassName##MainThreadOpaquePaints()                                        \
499         : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {}             \
500   };                                                                           \
501   TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
502
503 #define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)                          \
504   class ClassName##ImplThreadOpaqueLayers                                      \
505       : public ClassName<OcclusionTrackerTestImplThreadTypes> {                \
506    public: /* NOLINT(whitespace/indent) */                                     \
507     ClassName##ImplThreadOpaqueLayers()                                        \
508         : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {}              \
509   };                                                                           \
510   TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
511 #define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)                          \
512   class ClassName##ImplThreadOpaquePaints                                      \
513       : public ClassName<OcclusionTrackerTestImplThreadTypes> {                \
514    public: /* NOLINT(whitespace/indent) */                                     \
515     ClassName##ImplThreadOpaquePaints()                                        \
516         : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {}             \
517   };                                                                           \
518   TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
519
520 #define ALL_OCCLUSIONTRACKER_TEST(ClassName)                                   \
521   RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                                \
522       RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)                            \
523       RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)                            \
524       RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
525
526 #define MAIN_THREAD_TEST(ClassName)                                            \
527   RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
528
529 #define IMPL_THREAD_TEST(ClassName)                                            \
530   RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
531
532 #define MAIN_AND_IMPL_THREAD_TEST(ClassName)                                   \
533   RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                                \
534       RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
535
536 template <class Types>
537 class OcclusionTrackerTestIdentityTransforms
538     : public OcclusionTrackerTest<Types> {
539  protected:
540   explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
541       : OcclusionTrackerTest<Types>(opaque_layers) {}
542
543   void RunMyTest() {
544     typename Types::ContentLayerType* root = this->CreateRoot(
545         this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
546     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
547         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
548     typename Types::ContentLayerType* layer =
549         this->CreateDrawingLayer(parent,
550                                  this->identity_matrix,
551                                  gfx::PointF(30.f, 30.f),
552                                  gfx::Size(500, 500),
553                                  true);
554     parent->SetMasksToBounds(true);
555     this->CalcDrawEtc(root);
556
557     TestOcclusionTrackerWithClip<typename Types::LayerType,
558                                  typename Types::RenderSurfaceType> occlusion(
559         gfx::Rect(0, 0, 1000, 1000), false);
560
561     this->VisitLayer(layer, &occlusion);
562     this->EnterLayer(parent, &occlusion, false);
563
564     EXPECT_EQ(gfx::Rect().ToString(),
565               occlusion.occlusion_from_outside_target().ToString());
566     EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
567               occlusion.occlusion_from_inside_target().ToString());
568
569     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
570     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
571     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
572     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
573     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
574
575     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
576         parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
577     EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
578                    occlusion.UnoccludedLayerContentRect(
579                        parent, gfx::Rect(29, 30, 70, 70)));
580     EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
581                    occlusion.UnoccludedLayerContentRect(
582                        parent, gfx::Rect(29, 29, 70, 70)));
583     EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
584                    occlusion.UnoccludedLayerContentRect(
585                        parent, gfx::Rect(30, 29, 70, 70)));
586     EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
587                    occlusion.UnoccludedLayerContentRect(
588                        parent, gfx::Rect(31, 29, 69, 70)));
589     EXPECT_RECT_EQ(gfx::Rect(),
590                    occlusion.UnoccludedLayerContentRect(
591                        parent, gfx::Rect(31, 30, 69, 70)));
592     EXPECT_RECT_EQ(gfx::Rect(),
593                    occlusion.UnoccludedLayerContentRect(
594                        parent, gfx::Rect(31, 31, 69, 69)));
595     EXPECT_RECT_EQ(gfx::Rect(),
596                    occlusion.UnoccludedLayerContentRect(
597                        parent, gfx::Rect(30, 31, 70, 69)));
598     EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
599                    occlusion.UnoccludedLayerContentRect(
600                        parent, gfx::Rect(29, 31, 70, 69)));
601   }
602 };
603
604 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
605
606 template <class Types>
607 class OcclusionTrackerTestQuadsMismatchLayer
608     : public OcclusionTrackerTest<Types> {
609  protected:
610   explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
611       : OcclusionTrackerTest<Types>(opaque_layers) {}
612   void RunMyTest() {
613     gfx::Transform layer_transform;
614     layer_transform.Translate(10.0, 10.0);
615
616     typename Types::ContentLayerType* parent = this->CreateRoot(
617         this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
618     typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
619         parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
620     typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
621         layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
622     this->CalcDrawEtc(parent);
623
624     TestOcclusionTrackerWithClip<typename Types::LayerType,
625                                  typename Types::RenderSurfaceType> occlusion(
626         gfx::Rect(0, 0, 1000, 1000));
627
628     this->VisitLayer(layer2, &occlusion);
629     this->EnterLayer(layer1, &occlusion, false);
630
631     EXPECT_EQ(gfx::Rect().ToString(),
632               occlusion.occlusion_from_outside_target().ToString());
633     EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
634               occlusion.occlusion_from_inside_target().ToString());
635
636     // This checks cases where the quads don't match their "containing"
637     // layers, e.g. in terms of transforms or clip rect. This is typical for
638     // DelegatedRendererLayer.
639
640     gfx::Transform quad_transform;
641     quad_transform.Translate(30.0, 30.0);
642
643     EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
644                                                 gfx::Rect(0, 0, 10, 10),
645                                                 quad_transform,
646                                                 false).IsEmpty());
647     EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
648                    occlusion.UnoccludedContentRect(parent,
649                                                    gfx::Rect(0, 0, 10, 10),
650                                                    quad_transform,
651                                                    true));
652     EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
653                    occlusion.UnoccludedContentRect(parent,
654                                                    gfx::Rect(40, 40, 10, 10),
655                                                    quad_transform,
656                                                    false));
657     EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
658                    occlusion.UnoccludedContentRect(parent,
659                                                    gfx::Rect(35, 30, 10, 10),
660                                                    quad_transform,
661                                                    false));
662   }
663 };
664
665 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);
666
667 template <class Types>
668 class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
669  protected:
670   explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
671       : OcclusionTrackerTest<Types>(opaque_layers) {}
672   void RunMyTest() {
673     gfx::Transform layer_transform;
674     layer_transform.Translate(250.0, 250.0);
675     layer_transform.Rotate(90.0);
676     layer_transform.Translate(-250.0, -250.0);
677
678     typename Types::ContentLayerType* root = this->CreateRoot(
679         this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
680     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
681         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
682     typename Types::ContentLayerType* layer =
683         this->CreateDrawingLayer(parent,
684                                  layer_transform,
685                                  gfx::PointF(30.f, 30.f),
686                                  gfx::Size(500, 500),
687                                  true);
688     parent->SetMasksToBounds(true);
689     this->CalcDrawEtc(root);
690
691     TestOcclusionTrackerWithClip<typename Types::LayerType,
692                                  typename Types::RenderSurfaceType> occlusion(
693         gfx::Rect(0, 0, 1000, 1000));
694
695     this->VisitLayer(layer, &occlusion);
696     this->EnterLayer(parent, &occlusion, false);
697
698     EXPECT_EQ(gfx::Rect().ToString(),
699               occlusion.occlusion_from_outside_target().ToString());
700     EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
701               occlusion.occlusion_from_inside_target().ToString());
702
703     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
704     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
705     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
706     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70)));
707     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69)));
708
709     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
710         parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
711     EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
712                    occlusion.UnoccludedLayerContentRect(
713                        parent, gfx::Rect(29, 30, 69, 70)));
714     EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
715                    occlusion.UnoccludedLayerContentRect(
716                        parent, gfx::Rect(29, 29, 70, 70)));
717     EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
718                    occlusion.UnoccludedLayerContentRect(
719                        parent, gfx::Rect(30, 29, 70, 70)));
720     EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
721                    occlusion.UnoccludedLayerContentRect(
722                        parent, gfx::Rect(31, 29, 69, 70)));
723     EXPECT_RECT_EQ(gfx::Rect(),
724                    occlusion.UnoccludedLayerContentRect(
725                        parent, gfx::Rect(31, 30, 69, 70)));
726     EXPECT_RECT_EQ(gfx::Rect(),
727                    occlusion.UnoccludedLayerContentRect(
728                        parent, gfx::Rect(31, 31, 69, 69)));
729     EXPECT_RECT_EQ(gfx::Rect(),
730                    occlusion.UnoccludedLayerContentRect(
731                        parent, gfx::Rect(30, 31, 70, 69)));
732     EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
733                    occlusion.UnoccludedLayerContentRect(
734                        parent, gfx::Rect(29, 31, 70, 69)));
735   }
736 };
737
738 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
739
740 template <class Types>
741 class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
742  protected:
743   explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
744       : OcclusionTrackerTest<Types>(opaque_layers) {}
745   void RunMyTest() {
746     gfx::Transform layer_transform;
747     layer_transform.Translate(20.0, 20.0);
748
749     typename Types::ContentLayerType* root = this->CreateRoot(
750         this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
751     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
752         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
753     typename Types::ContentLayerType* layer =
754         this->CreateDrawingLayer(parent,
755                                  layer_transform,
756                                  gfx::PointF(30.f, 30.f),
757                                  gfx::Size(500, 500),
758                                  true);
759     parent->SetMasksToBounds(true);
760     this->CalcDrawEtc(root);
761
762     TestOcclusionTrackerWithClip<typename Types::LayerType,
763                                  typename Types::RenderSurfaceType> occlusion(
764         gfx::Rect(0, 0, 1000, 1000));
765
766     this->VisitLayer(layer, &occlusion);
767     this->EnterLayer(parent, &occlusion, false);
768
769     EXPECT_EQ(gfx::Rect().ToString(),
770               occlusion.occlusion_from_outside_target().ToString());
771     EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
772               occlusion.occlusion_from_inside_target().ToString());
773
774     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
775     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
776     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
777     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50)));
778     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49)));
779
780     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
781         parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
782     EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
783                    occlusion.UnoccludedLayerContentRect(
784                        parent, gfx::Rect(49, 50, 50, 50)));
785     EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
786                    occlusion.UnoccludedLayerContentRect(
787                        parent, gfx::Rect(49, 49, 50, 50)));
788     EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
789                    occlusion.UnoccludedLayerContentRect(
790                        parent, gfx::Rect(50, 49, 50, 50)));
791     EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
792                    occlusion.UnoccludedLayerContentRect(
793                        parent, gfx::Rect(51, 49, 49, 50)));
794     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
795         parent, gfx::Rect(51, 50, 49, 50)).IsEmpty());
796     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
797         parent, gfx::Rect(51, 51, 49, 49)).IsEmpty());
798     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
799         parent, gfx::Rect(50, 51, 50, 49)).IsEmpty());
800     EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
801                    occlusion.UnoccludedLayerContentRect(
802                        parent, gfx::Rect(49, 51, 50, 49)));
803   }
804 };
805
806 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
807
808 template <class Types>
809 class OcclusionTrackerTestChildInRotatedChild
810     : public OcclusionTrackerTest<Types> {
811  protected:
812   explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
813       : OcclusionTrackerTest<Types>(opaque_layers) {}
814   void RunMyTest() {
815     gfx::Transform child_transform;
816     child_transform.Translate(250.0, 250.0);
817     child_transform.Rotate(90.0);
818     child_transform.Translate(-250.0, -250.0);
819
820     typename Types::ContentLayerType* parent = this->CreateRoot(
821         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
822     parent->SetMasksToBounds(true);
823     typename Types::LayerType* child = this->CreateSurface(
824         parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
825     child->SetMasksToBounds(true);
826     typename Types::ContentLayerType* layer =
827         this->CreateDrawingLayer(child,
828                                  this->identity_matrix,
829                                  gfx::PointF(10.f, 10.f),
830                                  gfx::Size(500, 500),
831                                  true);
832     this->CalcDrawEtc(parent);
833
834     TestOcclusionTrackerWithClip<typename Types::LayerType,
835                                  typename Types::RenderSurfaceType> occlusion(
836         gfx::Rect(0, 0, 1000, 1000));
837
838     this->VisitLayer(layer, &occlusion);
839     this->EnterContributingSurface(child, &occlusion, false);
840
841     EXPECT_EQ(gfx::Rect().ToString(),
842               occlusion.occlusion_from_outside_target().ToString());
843     EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
844               occlusion.occlusion_from_inside_target().ToString());
845
846     this->LeaveContributingSurface(child, &occlusion);
847     this->EnterLayer(parent, &occlusion, false);
848
849     EXPECT_EQ(gfx::Rect().ToString(),
850               occlusion.occlusion_from_outside_target().ToString());
851     EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
852               occlusion.occlusion_from_inside_target().ToString());
853
854     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
855     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
856     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
857     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60)));
858     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59)));
859
860     /* Justification for the above occlusion from |layer|:
861                   100
862          +---------------------+
863          |                     |
864          |    30               |           rotate(90)
865          | 30 + ---------------------------------+
866      100 |    |  10            |                 |            ==>
867          |    |10+---------------------------------+
868          |    |  |             |                 | |
869          |    |  |             |                 | |
870          |    |  |             |                 | |
871          +----|--|-------------+                 | |
872               |  |                               | |
873               |  |                               | |
874               |  |                               | |500
875               |  |                               | |
876               |  |                               | |
877               |  |                               | |
878               |  |                               | |
879               +--|-------------------------------+ |
880                  |                                 |
881                  +---------------------------------+
882                                 500
883
884         +---------------------+
885         |                     |30  Visible region of |layer|: /////
886         |                     |
887         |     +---------------------------------+
888      100|     |               |10               |
889         |  +---------------------------------+  |
890         |  |  |///////////////|     420      |  |
891         |  |  |///////////////|60            |  |
892         |  |  |///////////////|              |  |
893         +--|--|---------------+              |  |
894          20|10|     70                       |  |
895            |  |                              |  |
896            |  |                              |  |
897            |  |                              |  |
898            |  |                              |  |
899            |  |                              |  |
900            |  |                              |10|
901            |  +------------------------------|--+
902            |                 490             |
903            +---------------------------------+
904                           500
905
906      */
907   }
908 };
909
910 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
911
912 template <class Types>
913 class OcclusionTrackerTestScaledRenderSurface
914     : public OcclusionTrackerTest<Types> {
915  protected:
916   explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
917       : OcclusionTrackerTest<Types>(opaque_layers) {}
918
919   void RunMyTest() {
920     typename Types::ContentLayerType* parent = this->CreateRoot(
921         this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
922
923     gfx::Transform layer1_matrix;
924     layer1_matrix.Scale(2.0, 2.0);
925     typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
926         parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
927     layer1->SetForceRenderSurface(true);
928
929     gfx::Transform layer2_matrix;
930     layer2_matrix.Translate(25.0, 25.0);
931     typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
932         layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
933     typename Types::ContentLayerType* occluder =
934         this->CreateDrawingLayer(parent,
935                                  this->identity_matrix,
936                                  gfx::PointF(100.f, 100.f),
937                                  gfx::Size(500, 500),
938                                  true);
939     this->CalcDrawEtc(parent);
940
941     TestOcclusionTrackerWithClip<typename Types::LayerType,
942                                  typename Types::RenderSurfaceType> occlusion(
943         gfx::Rect(0, 0, 1000, 1000));
944
945     this->VisitLayer(occluder, &occlusion);
946     this->EnterLayer(layer2, &occlusion, false);
947
948     EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
949               occlusion.occlusion_from_outside_target().ToString());
950     EXPECT_EQ(gfx::Rect().ToString(),
951               occlusion.occlusion_from_inside_target().ToString());
952
953     EXPECT_RECT_EQ(
954         gfx::Rect(0, 0, 25, 25),
955         occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
956     EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
957                    occlusion.UnoccludedLayerContentRect(
958                        layer2, gfx::Rect(10, 25, 25, 25)));
959     EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
960                    occlusion.UnoccludedLayerContentRect(
961                        layer2, gfx::Rect(25, 10, 25, 25)));
962     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
963         layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
964   }
965 };
966
967 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
968
969 template <class Types>
970 class OcclusionTrackerTestVisitTargetTwoTimes
971     : public OcclusionTrackerTest<Types> {
972  protected:
973   explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
974       : OcclusionTrackerTest<Types>(opaque_layers) {}
975   void RunMyTest() {
976     gfx::Transform child_transform;
977     child_transform.Translate(250.0, 250.0);
978     child_transform.Rotate(90.0);
979     child_transform.Translate(-250.0, -250.0);
980
981     typename Types::ContentLayerType* root = this->CreateRoot(
982         this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
983     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
984         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
985     parent->SetMasksToBounds(true);
986     typename Types::LayerType* child = this->CreateSurface(
987         parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
988     child->SetMasksToBounds(true);
989     typename Types::ContentLayerType* layer =
990         this->CreateDrawingLayer(child,
991                                  this->identity_matrix,
992                                  gfx::PointF(10.f, 10.f),
993                                  gfx::Size(500, 500),
994                                  true);
995     // |child2| makes |parent|'s surface get considered by OcclusionTracker
996     // first, instead of |child|'s. This exercises different code in
997     // LeaveToRenderTarget, as the target surface has already been seen.
998     typename Types::ContentLayerType* child2 =
999         this->CreateDrawingLayer(parent,
1000                                  this->identity_matrix,
1001                                  gfx::PointF(30.f, 30.f),
1002                                  gfx::Size(60, 20),
1003                                  true);
1004     this->CalcDrawEtc(root);
1005
1006     TestOcclusionTrackerWithClip<typename Types::LayerType,
1007                                  typename Types::RenderSurfaceType> occlusion(
1008         gfx::Rect(0, 0, 1000, 1000));
1009
1010     this->VisitLayer(child2, &occlusion);
1011
1012     EXPECT_EQ(gfx::Rect().ToString(),
1013               occlusion.occlusion_from_outside_target().ToString());
1014     EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
1015               occlusion.occlusion_from_inside_target().ToString());
1016
1017     this->VisitLayer(layer, &occlusion);
1018
1019     EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1020               occlusion.occlusion_from_outside_target().ToString());
1021     EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1022               occlusion.occlusion_from_inside_target().ToString());
1023
1024     this->EnterContributingSurface(child, &occlusion, false);
1025
1026     EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
1027               occlusion.occlusion_from_outside_target().ToString());
1028     EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1029               occlusion.occlusion_from_inside_target().ToString());
1030
1031     // Occlusion in |child2| should get merged with the |child| surface we are
1032     // leaving now.
1033     this->LeaveContributingSurface(child, &occlusion);
1034     this->EnterLayer(parent, &occlusion, false);
1035
1036     EXPECT_EQ(gfx::Rect().ToString(),
1037               occlusion.occlusion_from_outside_target().ToString());
1038     EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
1039                   .ToString(),
1040               occlusion.occlusion_from_inside_target().ToString());
1041
1042     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
1043     EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
1044                    occlusion.UnoccludedLayerContentRect(
1045                        parent, gfx::Rect(30, 30, 70, 70)));
1046
1047     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
1048     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
1049     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
1050     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
1051     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));
1052
1053     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1054     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1055     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1056
1057     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1058         parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
1059     EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
1060                    occlusion.UnoccludedLayerContentRect(
1061                        parent, gfx::Rect(29, 30, 60, 10)));
1062     EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
1063                    occlusion.UnoccludedLayerContentRect(
1064                        parent, gfx::Rect(30, 29, 60, 10)));
1065     EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
1066                    occlusion.UnoccludedLayerContentRect(
1067                        parent, gfx::Rect(31, 30, 60, 10)));
1068     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1069         parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());
1070
1071     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1072         parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1073     EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1074                    occlusion.UnoccludedLayerContentRect(
1075                        parent, gfx::Rect(29, 40, 70, 60)));
1076     // This rect is mostly occluded by |child2|.
1077     EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
1078                    occlusion.UnoccludedLayerContentRect(
1079                        parent, gfx::Rect(30, 39, 70, 60)));
1080     // This rect extends past top/right ends of |child2|.
1081     EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
1082                    occlusion.UnoccludedLayerContentRect(
1083                        parent, gfx::Rect(30, 29, 70, 70)));
1084     // This rect extends past left/right ends of |child2|.
1085     EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
1086                    occlusion.UnoccludedLayerContentRect(
1087                        parent, gfx::Rect(20, 39, 80, 60)));
1088     EXPECT_RECT_EQ(gfx::Rect(),
1089                    occlusion.UnoccludedLayerContentRect(
1090                        parent, gfx::Rect(31, 40, 69, 60)));
1091     EXPECT_RECT_EQ(gfx::Rect(),
1092                    occlusion.UnoccludedLayerContentRect(
1093                        parent, gfx::Rect(30, 41, 70, 59)));
1094
1095     /* Justification for the above occlusion from |layer|:
1096                100
1097       +---------------------+
1098       |                     |
1099       |    30               |           rotate(90)
1100       | 30 + ------------+--------------------+
1101   100 |    |  10         |  |                 |            ==>
1102       |    |10+----------|----------------------+
1103       |    + ------------+  |                 | |
1104       |    |  |             |                 | |
1105       |    |  |             |                 | |
1106       +----|--|-------------+                 | |
1107            |  |                               | |
1108            |  |                               | |
1109            |  |                               | |500
1110            |  |                               | |
1111            |  |                               | |
1112            |  |                               | |
1113            |  |                               | |
1114            +--|-------------------------------+ |
1115               |                                 |
1116               +---------------------------------+
1117                              500
1118
1119
1120        +---------------------+
1121        |                     |30  Visible region of |layer|: /////
1122        |     30   60         |    |child2|: \\\\\
1123        |  30 +------------+--------------------+
1124        |     |\\\\\\\\\\\\|  |10               |
1125        |  +--|\\\\\\\\\\\\|-----------------+  |
1126        |  |  +------------+//|     420      |  |
1127        |  |  |///////////////|60            |  |
1128        |  |  |///////////////|              |  |
1129        +--|--|---------------+              |  |
1130         20|10|     70                       |  |
1131           |  |                              |  |
1132           |  |                              |  |
1133           |  |                              |  |
1134           |  |                              |  |
1135           |  |                              |  |
1136           |  |                              |10|
1137           |  +------------------------------|--+
1138           |                 490             |
1139           +---------------------------------+
1140                          500
1141      */
1142   }
1143 };
1144
1145 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
1146
1147 template <class Types>
1148 class OcclusionTrackerTestSurfaceRotatedOffAxis
1149     : public OcclusionTrackerTest<Types> {
1150  protected:
1151   explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
1152       : OcclusionTrackerTest<Types>(opaque_layers) {}
1153   void RunMyTest() {
1154     gfx::Transform child_transform;
1155     child_transform.Translate(250.0, 250.0);
1156     child_transform.Rotate(95.0);
1157     child_transform.Translate(-250.0, -250.0);
1158
1159     gfx::Transform layer_transform;
1160     layer_transform.Translate(10.0, 10.0);
1161
1162     typename Types::ContentLayerType* root = this->CreateRoot(
1163         this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1164     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1165         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1166     typename Types::LayerType* child = this->CreateLayer(
1167         parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
1168     child->SetMasksToBounds(true);
1169     typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
1170         child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
1171     this->CalcDrawEtc(root);
1172
1173     TestOcclusionTrackerWithClip<typename Types::LayerType,
1174                                  typename Types::RenderSurfaceType> occlusion(
1175         gfx::Rect(0, 0, 1000, 1000));
1176
1177     gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
1178         layer_transform, layer->visible_content_rect());
1179
1180     this->VisitLayer(layer, &occlusion);
1181     this->EnterContributingSurface(child, &occlusion, false);
1182
1183     EXPECT_EQ(gfx::Rect().ToString(),
1184               occlusion.occlusion_from_outside_target().ToString());
1185     EXPECT_EQ(clipped_layer_in_child.ToString(),
1186               occlusion.occlusion_from_inside_target().ToString());
1187
1188     this->LeaveContributingSurface(child, &occlusion);
1189     this->EnterLayer(parent, &occlusion, false);
1190
1191     EXPECT_EQ(gfx::Rect().ToString(),
1192               occlusion.occlusion_from_outside_target().ToString());
1193     EXPECT_EQ(gfx::Rect().ToString(),
1194               occlusion.occlusion_from_inside_target().ToString());
1195
1196     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
1197     EXPECT_RECT_EQ(
1198         gfx::Rect(75, 55, 1, 1),
1199         occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
1200   }
1201 };
1202
1203 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
1204
1205 template <class Types>
1206 class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
1207     : public OcclusionTrackerTest<Types> {
1208  protected:
1209   explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
1210       : OcclusionTrackerTest<Types>(opaque_layers) {}
1211   void RunMyTest() {
1212     gfx::Transform child_transform;
1213     child_transform.Translate(250.0, 250.0);
1214     child_transform.Rotate(90.0);
1215     child_transform.Translate(-250.0, -250.0);
1216
1217     typename Types::ContentLayerType* root = this->CreateRoot(
1218         this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
1219     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
1220         root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
1221     parent->SetMasksToBounds(true);
1222     typename Types::ContentLayerType* child =
1223         this->CreateDrawingSurface(parent,
1224                                  child_transform,
1225                                  gfx::PointF(30.f, 30.f),
1226                                  gfx::Size(500, 500),
1227                                  false);
1228     child->SetMasksToBounds(true);
1229     typename Types::ContentLayerType* layer1 =
1230         this->CreateDrawingLayer(child,
1231                                  this->identity_matrix,
1232                                  gfx::PointF(10.f, 10.f),
1233                                  gfx::Size(500, 500),
1234                                  true);
1235     typename Types::ContentLayerType* layer2 =
1236         this->CreateDrawingLayer(child,
1237                                  this->identity_matrix,
1238                                  gfx::PointF(10.f, 450.f),
1239                                  gfx::Size(500, 60),
1240                                  true);
1241     this->CalcDrawEtc(root);
1242
1243     TestOcclusionTrackerWithClip<typename Types::LayerType,
1244                                  typename Types::RenderSurfaceType> occlusion(
1245         gfx::Rect(0, 0, 1000, 1000));
1246
1247     this->VisitLayer(layer2, &occlusion);
1248     this->VisitLayer(layer1, &occlusion);
1249     this->VisitLayer(child, &occlusion);
1250     this->EnterContributingSurface(child, &occlusion, false);
1251
1252     EXPECT_EQ(gfx::Rect().ToString(),
1253               occlusion.occlusion_from_outside_target().ToString());
1254     EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
1255               occlusion.occlusion_from_inside_target().ToString());
1256
1257     EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
1258     EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
1259     EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70)));
1260     EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69)));
1261
1262     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1263         child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
1264     EXPECT_RECT_EQ(
1265         gfx::Rect(9, 430, 1, 70),
1266         occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
1267     EXPECT_RECT_EQ(gfx::Rect(),
1268                    occlusion.UnoccludedLayerContentRect(
1269                        child, gfx::Rect(11, 430, 59, 70)));
1270     EXPECT_RECT_EQ(gfx::Rect(),
1271                    occlusion.UnoccludedLayerContentRect(
1272                        child, gfx::Rect(10, 431, 60, 69)));
1273
1274     this->LeaveContributingSurface(child, &occlusion);
1275     this->EnterLayer(parent, &occlusion, false);
1276
1277     EXPECT_EQ(gfx::Rect().ToString(),
1278               occlusion.occlusion_from_outside_target().ToString());
1279     EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
1280               occlusion.occlusion_from_inside_target().ToString());
1281
1282     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
1283     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
1284     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
1285
1286     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
1287         parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
1288     EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
1289                    occlusion.UnoccludedLayerContentRect(
1290                        parent, gfx::Rect(29, 40, 70, 60)));
1291     EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
1292                    occlusion.UnoccludedLayerContentRect(
1293                        parent, gfx::Rect(30, 39, 70, 60)));
1294     EXPECT_RECT_EQ(gfx::Rect(),
1295                    occlusion.UnoccludedLayerContentRect(
1296                        parent, gfx::Rect(31, 40, 69, 60)));
1297     EXPECT_RECT_EQ(gfx::Rect(),
1298                    occlusion.UnoccludedLayerContentRect(
1299                        parent, gfx::Rect(30, 41, 70, 59)));
1300
1301     /* Justification for the above occlusion from |layer1| and |layer2|:
1302
1303            +---------------------+
1304            |                     |30  Visible region of |layer1|: /////
1305            |                     |    Visible region of |layer2|: \\\\\
1306            |     +---------------------------------+
1307            |     |               |10               |
1308            |  +---------------+-----------------+  |
1309            |  |  |\\\\\\\\\\\\|//|     420      |  |
1310            |  |  |\\\\\\\\\\\\|//|60            |  |
1311            |  |  |\\\\\\\\\\\\|//|              |  |
1312            +--|--|------------|--+              |  |
1313             20|10|     70     |                 |  |
1314               |  |            |                 |  |
1315               |  |            |                 |  |
1316               |  |            |                 |  |
1317               |  |            |                 |  |
1318               |  |            |                 |  |
1319               |  |            |                 |10|
1320               |  +------------|-----------------|--+
1321               |               | 490             |
1322               +---------------+-----------------+
1323                      60               440
1324          */
1325   }
1326 };
1327
1328 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
1329
1330 template <class Types>
1331 class OcclusionTrackerTestOverlappingSurfaceSiblings
1332     : public OcclusionTrackerTest<Types> {
1333  protected:
1334   explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
1335       : OcclusionTrackerTest<Types>(opaque_layers) {}
1336   void RunMyTest() {
1337     gfx::Transform child_transform;
1338     child_transform.Translate(250.0, 250.0);
1339     child_transform.Rotate(90.0);
1340     child_transform.Translate(-250.0, -250.0);
1341
1342     typename Types::ContentLayerType* parent = this->CreateRoot(
1343         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1344     parent->SetMasksToBounds(true);
1345     typename Types::LayerType* child1 = this->CreateSurface(
1346         parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
1347     typename Types::LayerType* child2 = this->CreateSurface(
1348         parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
1349     typename Types::ContentLayerType* layer1 =
1350         this->CreateDrawingLayer(child1,
1351                                  this->identity_matrix,
1352                                  gfx::PointF(-10.f, -10.f),
1353                                  gfx::Size(510, 510),
1354                                  true);
1355     typename Types::ContentLayerType* layer2 =
1356         this->CreateDrawingLayer(child2,
1357                                  this->identity_matrix,
1358                                  gfx::PointF(-10.f, -10.f),
1359                                  gfx::Size(510, 510),
1360                                  true);
1361     this->CalcDrawEtc(parent);
1362
1363     TestOcclusionTrackerWithClip<typename Types::LayerType,
1364                                  typename Types::RenderSurfaceType> occlusion(
1365         gfx::Rect(0, 0, 1000, 1000));
1366
1367     this->VisitLayer(layer2, &occlusion);
1368     this->EnterContributingSurface(child2, &occlusion, false);
1369
1370     EXPECT_EQ(gfx::Rect().ToString(),
1371               occlusion.occlusion_from_outside_target().ToString());
1372     EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1373               occlusion.occlusion_from_inside_target().ToString());
1374
1375     // There is nothing above child2's surface in the z-order.
1376     EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1377                    occlusion.UnoccludedContributingSurfaceContentRect(
1378                        child2, false, gfx::Rect(-10, 420, 70, 80)));
1379
1380     this->LeaveContributingSurface(child2, &occlusion);
1381     this->VisitLayer(layer1, &occlusion);
1382     this->EnterContributingSurface(child1, &occlusion, false);
1383
1384     EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
1385               occlusion.occlusion_from_outside_target().ToString());
1386     EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
1387               occlusion.occlusion_from_inside_target().ToString());
1388
1389     // child2's contents will occlude child1 below it.
1390     EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
1391                    occlusion.UnoccludedContributingSurfaceContentRect(
1392                        child1, false, gfx::Rect(-10, 430, 80, 70)));
1393
1394     this->LeaveContributingSurface(child1, &occlusion);
1395     this->EnterLayer(parent, &occlusion, false);
1396
1397     EXPECT_EQ(gfx::Rect().ToString(),
1398               occlusion.occlusion_from_outside_target().ToString());
1399     EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
1400                   .ToString(),
1401               occlusion.occlusion_from_inside_target().ToString());
1402
1403     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));
1404
1405     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
1406     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
1407     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));
1408
1409     EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
1410     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
1411     EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));
1412
1413     /* Justification for the above occlusion:
1414                100
1415       +---------------------+
1416       |    20               |       layer1
1417       |  30+ ---------------------------------+
1418   100 |  30|                |     layer2      |
1419       |20+----------------------------------+ |
1420       |  | |                |               | |
1421       |  | |                |               | |
1422       |  | |                |               | |
1423       +--|-|----------------+               | |
1424          | |                                | | 510
1425          | |                                | |
1426          | |                                | |
1427          | |                                | |
1428          | |                                | |
1429          | |                                | |
1430          | |                                | |
1431          | +--------------------------------|-+
1432          |                                  |
1433          +----------------------------------+
1434                          510
1435      */
1436   }
1437 };
1438
1439 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
1440
1441 template <class Types>
1442 class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
1443     : public OcclusionTrackerTest<Types> {
1444  protected:
1445   explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
1446       bool opaque_layers)
1447       : OcclusionTrackerTest<Types>(opaque_layers) {}
1448   void RunMyTest() {
1449     gfx::Transform child1_transform;
1450     child1_transform.Translate(250.0, 250.0);
1451     child1_transform.Rotate(-90.0);
1452     child1_transform.Translate(-250.0, -250.0);
1453
1454     gfx::Transform child2_transform;
1455     child2_transform.Translate(250.0, 250.0);
1456     child2_transform.Rotate(90.0);
1457     child2_transform.Translate(-250.0, -250.0);
1458
1459     typename Types::ContentLayerType* parent = this->CreateRoot(
1460         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1461     parent->SetMasksToBounds(true);
1462     typename Types::LayerType* child1 = this->CreateSurface(
1463         parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
1464     typename Types::LayerType* child2 =
1465         this->CreateDrawingSurface(parent,
1466                                    child2_transform,
1467                                    gfx::PointF(20.f, 40.f),
1468                                    gfx::Size(10, 10),
1469                                    false);
1470     typename Types::ContentLayerType* layer1 =
1471         this->CreateDrawingLayer(child1,
1472                                  this->identity_matrix,
1473                                  gfx::PointF(-10.f, -20.f),
1474                                  gfx::Size(510, 510),
1475                                  true);
1476     typename Types::ContentLayerType* layer2 =
1477         this->CreateDrawingLayer(child2,
1478                                  this->identity_matrix,
1479                                  gfx::PointF(-10.f, -10.f),
1480                                  gfx::Size(510, 510),
1481                                  true);
1482     this->CalcDrawEtc(parent);
1483
1484     TestOcclusionTrackerWithClip<typename Types::LayerType,
1485                                  typename Types::RenderSurfaceType> occlusion(
1486         gfx::Rect(0, 0, 1000, 1000));
1487
1488     this->VisitLayer(layer2, &occlusion);
1489     this->EnterLayer(child2, &occlusion, false);
1490
1491     EXPECT_EQ(gfx::Rect().ToString(),
1492               occlusion.occlusion_from_outside_target().ToString());
1493     EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
1494               occlusion.occlusion_from_inside_target().ToString());
1495
1496     this->LeaveLayer(child2, &occlusion);
1497     this->EnterContributingSurface(child2, &occlusion, false);
1498
1499     // There is nothing above child2's surface in the z-order.
1500     EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
1501                    occlusion.UnoccludedContributingSurfaceContentRect(
1502                        child2, false, gfx::Rect(-10, 420, 70, 80)));
1503
1504     this->LeaveContributingSurface(child2, &occlusion);
1505     this->VisitLayer(layer1, &occlusion);
1506     this->EnterContributingSurface(child1, &occlusion, false);
1507
1508     EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
1509               occlusion.occlusion_from_outside_target().ToString());
1510     EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
1511               occlusion.occlusion_from_inside_target().ToString());
1512
1513     // child2's contents will occlude child1 below it.
1514     EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
1515                    occlusion.UnoccludedContributingSurfaceContentRect(
1516                        child1, false, gfx::Rect(420, -20, 80, 90)));
1517     EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
1518                    occlusion.UnoccludedContributingSurfaceContentRect(
1519                        child1, false, gfx::Rect(420, -10, 80, 90)));
1520     EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
1521                    occlusion.UnoccludedContributingSurfaceContentRect(
1522                        child1, false, gfx::Rect(420, -20, 70, 90)));
1523
1524     this->LeaveContributingSurface(child1, &occlusion);
1525     this->EnterLayer(parent, &occlusion, false);
1526
1527     EXPECT_EQ(gfx::Rect().ToString(),
1528               occlusion.occlusion_from_outside_target().ToString());
1529     EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
1530               occlusion.occlusion_from_inside_target().ToString());
1531
1532     /* Justification for the above occlusion:
1533                   100
1534         +---------------------+
1535         |20                   |       layer1
1536        10+----------------------------------+
1537     100 || 30                 |     layer2  |
1538         |20+----------------------------------+
1539         || |                  |             | |
1540         || |                  |             | |
1541         || |                  |             | |
1542         +|-|------------------+             | |
1543          | |                                | | 510
1544          | |                            510 | |
1545          | |                                | |
1546          | |                                | |
1547          | |                                | |
1548          | |                                | |
1549          | |                520             | |
1550          +----------------------------------+ |
1551            |                                  |
1552            +----------------------------------+
1553                            510
1554      */
1555   }
1556 };
1557
1558 ALL_OCCLUSIONTRACKER_TEST(
1559     OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
1560
1561 template <class Types>
1562 class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
1563  protected:
1564   explicit OcclusionTrackerTestFilters(bool opaque_layers)
1565       : OcclusionTrackerTest<Types>(opaque_layers) {}
1566   void RunMyTest() {
1567     gfx::Transform layer_transform;
1568     layer_transform.Translate(250.0, 250.0);
1569     layer_transform.Rotate(90.0);
1570     layer_transform.Translate(-250.0, -250.0);
1571
1572     typename Types::ContentLayerType* parent = this->CreateRoot(
1573         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
1574     parent->SetMasksToBounds(true);
1575     typename Types::ContentLayerType* blur_layer =
1576         this->CreateDrawingLayer(parent,
1577                                  layer_transform,
1578                                  gfx::PointF(30.f, 30.f),
1579                                  gfx::Size(500, 500),
1580                                  true);
1581     typename Types::ContentLayerType* opaque_layer =
1582         this->CreateDrawingLayer(parent,
1583                                  layer_transform,
1584                                  gfx::PointF(30.f, 30.f),
1585                                  gfx::Size(500, 500),
1586                                  true);
1587     typename Types::ContentLayerType* opacity_layer =
1588         this->CreateDrawingLayer(parent,
1589                                  layer_transform,
1590                                  gfx::PointF(30.f, 30.f),
1591                                  gfx::Size(500, 500),
1592                                  true);
1593
1594     FilterOperations filters;
1595     filters.Append(FilterOperation::CreateBlurFilter(10.f));
1596     blur_layer->SetFilters(filters);
1597
1598     filters.Clear();
1599     filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
1600     opaque_layer->SetFilters(filters);
1601
1602     filters.Clear();
1603     filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1604     opacity_layer->SetFilters(filters);
1605
1606     this->CalcDrawEtc(parent);
1607
1608     TestOcclusionTrackerWithClip<typename Types::LayerType,
1609                                  typename Types::RenderSurfaceType> occlusion(
1610         gfx::Rect(0, 0, 1000, 1000));
1611
1612     // Opacity layer won't contribute to occlusion.
1613     this->VisitLayer(opacity_layer, &occlusion);
1614     this->EnterContributingSurface(opacity_layer, &occlusion, false);
1615
1616     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1617     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1618
1619     // And has nothing to contribute to its parent surface.
1620     this->LeaveContributingSurface(opacity_layer, &occlusion);
1621     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1622     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1623
1624     // Opaque layer will contribute to occlusion.
1625     this->VisitLayer(opaque_layer, &occlusion);
1626     this->EnterContributingSurface(opaque_layer, &occlusion, false);
1627
1628     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1629     EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
1630               occlusion.occlusion_from_inside_target().ToString());
1631
1632     // And it gets translated to the parent surface.
1633     this->LeaveContributingSurface(opaque_layer, &occlusion);
1634     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1635     EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1636               occlusion.occlusion_from_inside_target().ToString());
1637
1638     // The blur layer needs to throw away any occlusion from outside its
1639     // subtree.
1640     this->EnterLayer(blur_layer, &occlusion, false);
1641     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1642     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1643
1644     // And it won't contribute to occlusion.
1645     this->LeaveLayer(blur_layer, &occlusion);
1646     this->EnterContributingSurface(blur_layer, &occlusion, false);
1647     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1648     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1649
1650     // But the opaque layer's occlusion is preserved on the parent.
1651     this->LeaveContributingSurface(blur_layer, &occlusion);
1652     this->EnterLayer(parent, &occlusion, false);
1653     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1654     EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
1655               occlusion.occlusion_from_inside_target().ToString());
1656   }
1657 };
1658
1659 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
1660
1661 template <class Types>
1662 class OcclusionTrackerTestReplicaDoesOcclude
1663     : public OcclusionTrackerTest<Types> {
1664  protected:
1665   explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
1666       : OcclusionTrackerTest<Types>(opaque_layers) {}
1667   void RunMyTest() {
1668     typename Types::ContentLayerType* parent = this->CreateRoot(
1669         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1670     typename Types::LayerType* surface =
1671         this->CreateDrawingSurface(parent,
1672                                    this->identity_matrix,
1673                                    gfx::PointF(0.f, 100.f),
1674                                    gfx::Size(50, 50),
1675                                    true);
1676     this->CreateReplicaLayer(
1677         surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1678     this->CalcDrawEtc(parent);
1679
1680     TestOcclusionTrackerWithClip<typename Types::LayerType,
1681                                  typename Types::RenderSurfaceType> occlusion(
1682         gfx::Rect(0, 0, 1000, 1000));
1683
1684     this->VisitLayer(surface, &occlusion);
1685
1686     EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1687               occlusion.occlusion_from_inside_target().ToString());
1688
1689     this->VisitContributingSurface(surface, &occlusion);
1690     this->EnterLayer(parent, &occlusion, false);
1691
1692     // The surface and replica should both be occluding the parent.
1693     EXPECT_EQ(
1694         UnionRegions(gfx::Rect(0, 100, 50, 50),
1695                      gfx::Rect(50, 150, 50, 50)).ToString(),
1696         occlusion.occlusion_from_inside_target().ToString());
1697   }
1698 };
1699
1700 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
1701
1702 template <class Types>
1703 class OcclusionTrackerTestReplicaWithClipping
1704     : public OcclusionTrackerTest<Types> {
1705  protected:
1706   explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
1707       : OcclusionTrackerTest<Types>(opaque_layers) {}
1708   void RunMyTest() {
1709     typename Types::ContentLayerType* parent = this->CreateRoot(
1710         this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
1711     parent->SetMasksToBounds(true);
1712     typename Types::LayerType* surface =
1713         this->CreateDrawingSurface(parent,
1714                                    this->identity_matrix,
1715                                    gfx::PointF(0.f, 100.f),
1716                                    gfx::Size(50, 50),
1717                                    true);
1718     this->CreateReplicaLayer(
1719         surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1720     this->CalcDrawEtc(parent);
1721
1722     TestOcclusionTrackerWithClip<typename Types::LayerType,
1723                                  typename Types::RenderSurfaceType> occlusion(
1724         gfx::Rect(0, 0, 1000, 1000));
1725
1726     this->VisitLayer(surface, &occlusion);
1727
1728     EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1729               occlusion.occlusion_from_inside_target().ToString());
1730
1731     this->VisitContributingSurface(surface, &occlusion);
1732     this->EnterLayer(parent, &occlusion, false);
1733
1734     // The surface and replica should both be occluding the parent.
1735     EXPECT_EQ(
1736         UnionRegions(gfx::Rect(0, 100, 50, 50),
1737                      gfx::Rect(50, 150, 50, 20)).ToString(),
1738         occlusion.occlusion_from_inside_target().ToString());
1739   }
1740 };
1741
1742 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
1743
1744 template <class Types>
1745 class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
1746  protected:
1747   explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
1748       : OcclusionTrackerTest<Types>(opaque_layers) {}
1749   void RunMyTest() {
1750     typename Types::ContentLayerType* parent = this->CreateRoot(
1751         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
1752     typename Types::LayerType* surface =
1753         this->CreateDrawingSurface(parent,
1754                                    this->identity_matrix,
1755                                    gfx::PointF(0.f, 100.f),
1756                                    gfx::Size(50, 50),
1757                                    true);
1758     typename Types::LayerType* replica = this->CreateReplicaLayer(
1759         surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
1760     this->CreateMaskLayer(replica, gfx::Size(10, 10));
1761     this->CalcDrawEtc(parent);
1762
1763     TestOcclusionTrackerWithClip<typename Types::LayerType,
1764                                  typename Types::RenderSurfaceType> occlusion(
1765         gfx::Rect(0, 0, 1000, 1000));
1766
1767     this->VisitLayer(surface, &occlusion);
1768
1769     EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
1770               occlusion.occlusion_from_inside_target().ToString());
1771
1772     this->VisitContributingSurface(surface, &occlusion);
1773     this->EnterLayer(parent, &occlusion, false);
1774
1775     // The replica should not be occluding the parent, since it has a mask
1776     // applied to it.
1777     EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
1778               occlusion.occlusion_from_inside_target().ToString());
1779   }
1780 };
1781
1782 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
1783
1784 template <class Types>
1785 class OcclusionTrackerTestOpaqueContentsRegionEmpty
1786     : public OcclusionTrackerTest<Types> {
1787  protected:
1788   explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
1789       : OcclusionTrackerTest<Types>(opaque_layers) {}
1790   void RunMyTest() {
1791     typename Types::ContentLayerType* parent = this->CreateRoot(
1792         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1793     typename Types::ContentLayerType* layer =
1794         this->CreateDrawingSurface(parent,
1795                                    this->identity_matrix,
1796                                    gfx::PointF(),
1797                                    gfx::Size(200, 200),
1798                                    false);
1799     this->CalcDrawEtc(parent);
1800
1801     TestOcclusionTrackerWithClip<typename Types::LayerType,
1802                                  typename Types::RenderSurfaceType> occlusion(
1803         gfx::Rect(0, 0, 1000, 1000));
1804     this->EnterLayer(layer, &occlusion, false);
1805
1806     EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
1807     EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
1808     EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
1809     EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
1810
1811     this->LeaveLayer(layer, &occlusion);
1812     this->VisitContributingSurface(layer, &occlusion);
1813     this->EnterLayer(parent, &occlusion, false);
1814
1815     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1816   }
1817 };
1818
1819 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
1820
1821 template <class Types>
1822 class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
1823     : public OcclusionTrackerTest<Types> {
1824  protected:
1825   explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
1826       : OcclusionTrackerTest<Types>(opaque_layers) {}
1827   void RunMyTest() {
1828     typename Types::ContentLayerType* parent = this->CreateRoot(
1829         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1830     typename Types::ContentLayerType* layer =
1831         this->CreateDrawingLayer(parent,
1832                                  this->identity_matrix,
1833                                  gfx::PointF(100.f, 100.f),
1834                                  gfx::Size(200, 200),
1835                                  false);
1836     this->CalcDrawEtc(parent);
1837     {
1838       TestOcclusionTrackerWithClip<typename Types::LayerType,
1839                                    typename Types::RenderSurfaceType> occlusion(
1840           gfx::Rect(0, 0, 1000, 1000));
1841       layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
1842
1843       this->ResetLayerIterator();
1844       this->VisitLayer(layer, &occlusion);
1845       this->EnterLayer(parent, &occlusion, false);
1846
1847       EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
1848                 occlusion.occlusion_from_inside_target().ToString());
1849
1850       EXPECT_FALSE(
1851           occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1852       EXPECT_TRUE(
1853           occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1854       EXPECT_FALSE(
1855           occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1856     }
1857     {
1858       TestOcclusionTrackerWithClip<typename Types::LayerType,
1859                                    typename Types::RenderSurfaceType> occlusion(
1860           gfx::Rect(0, 0, 1000, 1000));
1861       layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
1862
1863       this->ResetLayerIterator();
1864       this->VisitLayer(layer, &occlusion);
1865       this->EnterLayer(parent, &occlusion, false);
1866
1867       EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
1868                 occlusion.occlusion_from_inside_target().ToString());
1869
1870       EXPECT_FALSE(
1871           occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1872       EXPECT_FALSE(
1873           occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1874       EXPECT_TRUE(
1875           occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1876     }
1877     {
1878       TestOcclusionTrackerWithClip<typename Types::LayerType,
1879                                    typename Types::RenderSurfaceType> occlusion(
1880           gfx::Rect(0, 0, 1000, 1000));
1881       layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
1882
1883       this->ResetLayerIterator();
1884       this->VisitLayer(layer, &occlusion);
1885       this->EnterLayer(parent, &occlusion, false);
1886
1887       EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
1888                 occlusion.occlusion_from_inside_target().ToString());
1889
1890       EXPECT_FALSE(
1891           occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
1892       EXPECT_FALSE(
1893           occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
1894       EXPECT_FALSE(
1895           occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
1896     }
1897   }
1898 };
1899
1900 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
1901
1902 template <class Types>
1903 class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
1904  protected:
1905   explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
1906       : OcclusionTrackerTest<Types>(opaque_layers) {}
1907   void RunMyTest() {
1908     gfx::Transform transform;
1909     transform.RotateAboutYAxis(30.0);
1910
1911     typename Types::ContentLayerType* parent = this->CreateRoot(
1912         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1913     typename Types::LayerType* container = this->CreateLayer(
1914         parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1915     typename Types::ContentLayerType* layer =
1916         this->CreateDrawingLayer(container,
1917                                  transform,
1918                                  gfx::PointF(100.f, 100.f),
1919                                  gfx::Size(200, 200),
1920                                  true);
1921     this->CalcDrawEtc(parent);
1922
1923     TestOcclusionTrackerWithClip<typename Types::LayerType,
1924                                  typename Types::RenderSurfaceType> occlusion(
1925         gfx::Rect(0, 0, 1000, 1000));
1926     this->EnterLayer(layer, &occlusion, false);
1927
1928     // The layer is rotated in 3d but without preserving 3d, so it only gets
1929     // resized.
1930     EXPECT_RECT_EQ(
1931         gfx::Rect(0, 0, 200, 200),
1932         occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
1933   }
1934 };
1935
1936 MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);
1937
1938 template <class Types>
1939 class OcclusionTrackerTestUnsorted3dLayers
1940     : public OcclusionTrackerTest<Types> {
1941  protected:
1942   explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
1943       : OcclusionTrackerTest<Types>(opaque_layers) {}
1944   void RunMyTest() {
1945     // Currently, The main thread layer iterator does not iterate over 3d items
1946     // in sorted order, because layer sorting is not performed on the main
1947     // thread.  Because of this, the occlusion tracker cannot assume that a 3d
1948     // layer occludes other layers that have not yet been iterated over. For
1949     // now, the expected behavior is that a 3d layer simply does not add any
1950     // occlusion to the occlusion tracker.
1951
1952     gfx::Transform translation_to_front;
1953     translation_to_front.Translate3d(0.0, 0.0, -10.0);
1954     gfx::Transform translation_to_back;
1955     translation_to_front.Translate3d(0.0, 0.0, -100.0);
1956
1957     typename Types::ContentLayerType* parent = this->CreateRoot(
1958         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
1959     typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
1960         parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
1961     typename Types::ContentLayerType* child2 =
1962         this->CreateDrawingLayer(parent,
1963                                  translation_to_front,
1964                                  gfx::PointF(50.f, 50.f),
1965                                  gfx::Size(100, 100),
1966                                  true);
1967     parent->SetPreserves3d(true);
1968
1969     this->CalcDrawEtc(parent);
1970
1971     TestOcclusionTrackerWithClip<typename Types::LayerType,
1972                                  typename Types::RenderSurfaceType> occlusion(
1973         gfx::Rect(0, 0, 1000, 1000));
1974     this->VisitLayer(child2, &occlusion);
1975     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1976     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1977
1978     this->VisitLayer(child1, &occlusion);
1979     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
1980     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
1981   }
1982 };
1983
1984 // This test will have different layer ordering on the impl thread; the test
1985 // will only work on the main thread.
1986 MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
1987
1988 template <class Types>
1989 class OcclusionTrackerTestPerspectiveTransform
1990     : public OcclusionTrackerTest<Types> {
1991  protected:
1992   explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
1993       : OcclusionTrackerTest<Types>(opaque_layers) {}
1994   void RunMyTest() {
1995     gfx::Transform transform;
1996     transform.Translate(150.0, 150.0);
1997     transform.ApplyPerspectiveDepth(400.0);
1998     transform.RotateAboutXAxis(-30.0);
1999     transform.Translate(-150.0, -150.0);
2000
2001     typename Types::ContentLayerType* parent = this->CreateRoot(
2002         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2003     typename Types::LayerType* container = this->CreateLayer(
2004         parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2005     typename Types::ContentLayerType* layer =
2006         this->CreateDrawingLayer(container,
2007                                  transform,
2008                                  gfx::PointF(100.f, 100.f),
2009                                  gfx::Size(200, 200),
2010                                  true);
2011     container->SetPreserves3d(true);
2012     layer->SetPreserves3d(true);
2013     this->CalcDrawEtc(parent);
2014
2015     TestOcclusionTrackerWithClip<typename Types::LayerType,
2016                                  typename Types::RenderSurfaceType> occlusion(
2017         gfx::Rect(0, 0, 1000, 1000));
2018     this->EnterLayer(layer, &occlusion, false);
2019
2020     EXPECT_RECT_EQ(
2021         gfx::Rect(0, 0, 200, 200),
2022         occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
2023   }
2024 };
2025
2026 // This test requires accumulating occlusion of 3d layers, which are skipped by
2027 // the occlusion tracker on the main thread. So this test should run on the impl
2028 // thread.
2029 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);
2030
2031 template <class Types>
2032 class OcclusionTrackerTestPerspectiveTransformBehindCamera
2033     : public OcclusionTrackerTest<Types> {
2034  protected:
2035   explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
2036       bool opaque_layers)
2037       : OcclusionTrackerTest<Types>(opaque_layers) {}
2038   void RunMyTest() {
2039     // This test is based on the platform/chromium/compositing/3d-corners.html
2040     // layout test.
2041     gfx::Transform transform;
2042     transform.Translate(250.0, 50.0);
2043     transform.ApplyPerspectiveDepth(10.0);
2044     transform.Translate(-250.0, -50.0);
2045     transform.Translate(250.0, 50.0);
2046     transform.RotateAboutXAxis(-167.0);
2047     transform.Translate(-250.0, -50.0);
2048
2049     typename Types::ContentLayerType* parent = this->CreateRoot(
2050         this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
2051     typename Types::LayerType* container = this->CreateLayer(
2052         parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2053     typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2054         container, transform, gfx::PointF(), gfx::Size(500, 500), true);
2055     container->SetPreserves3d(true);
2056     layer->SetPreserves3d(true);
2057     this->CalcDrawEtc(parent);
2058
2059     TestOcclusionTrackerWithClip<typename Types::LayerType,
2060                                  typename Types::RenderSurfaceType> occlusion(
2061         gfx::Rect(0, 0, 1000, 1000));
2062     this->EnterLayer(layer, &occlusion, false);
2063
2064     // The bottom 11 pixel rows of this layer remain visible inside the
2065     // container, after translation to the target surface. When translated back,
2066     // this will include many more pixels but must include at least the bottom
2067     // 11 rows.
2068     EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
2069         layer, gfx::Rect(0, 26, 500, 474)).
2070             Contains(gfx::Rect(0, 489, 500, 11)));
2071   }
2072 };
2073
2074 // This test requires accumulating occlusion of 3d layers, which are skipped by
2075 // the occlusion tracker on the main thread. So this test should run on the impl
2076 // thread.
2077 IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);
2078
2079 template <class Types>
2080 class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
2081     : public OcclusionTrackerTest<Types> {
2082  protected:
2083   explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
2084       bool opaque_layers)
2085       : OcclusionTrackerTest<Types>(opaque_layers) {}
2086   void RunMyTest() {
2087     gfx::Transform transform;
2088     transform.Translate(50.0, 50.0);
2089     transform.ApplyPerspectiveDepth(100.0);
2090     transform.Translate3d(0.0, 0.0, 110.0);
2091     transform.Translate(-50.0, -50.0);
2092
2093     typename Types::ContentLayerType* parent = this->CreateRoot(
2094         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2095     typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2096         parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2097     parent->SetPreserves3d(true);
2098     layer->SetPreserves3d(true);
2099     this->CalcDrawEtc(parent);
2100
2101     TestOcclusionTrackerWithClip<typename Types::LayerType,
2102                                  typename Types::RenderSurfaceType> occlusion(
2103         gfx::Rect(0, 0, 1000, 1000));
2104
2105     // The |layer| is entirely behind the camera and should not occlude.
2106     this->VisitLayer(layer, &occlusion);
2107     this->EnterLayer(parent, &occlusion, false);
2108     EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
2109     EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
2110   }
2111 };
2112
2113 // This test requires accumulating occlusion of 3d layers, which are skipped by
2114 // the occlusion tracker on the main thread. So this test should run on the impl
2115 // thread.
2116 IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);
2117
2118 template <class Types>
2119 class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
2120     : public OcclusionTrackerTest<Types> {
2121  protected:
2122   explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
2123       bool opaque_layers)
2124       : OcclusionTrackerTest<Types>(opaque_layers) {}
2125   void RunMyTest() {
2126     gfx::Transform transform;
2127     transform.Translate(50.0, 50.0);
2128     transform.ApplyPerspectiveDepth(100.0);
2129     transform.Translate3d(0.0, 0.0, 99.0);
2130     transform.Translate(-50.0, -50.0);
2131
2132     typename Types::ContentLayerType* parent = this->CreateRoot(
2133         this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
2134     parent->SetMasksToBounds(true);
2135     typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
2136         parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
2137     parent->SetPreserves3d(true);
2138     layer->SetPreserves3d(true);
2139     this->CalcDrawEtc(parent);
2140
2141     TestOcclusionTrackerWithClip<typename Types::LayerType,
2142                                  typename Types::RenderSurfaceType> occlusion(
2143         gfx::Rect(0, 0, 1000, 1000));
2144
2145     // This is very close to the camera, so pixels in its visible_content_rect()
2146     // will actually go outside of the layer's clip rect.  Ensure that those
2147     // pixels don't occlude things outside the clip rect.
2148     this->VisitLayer(layer, &occlusion);
2149     this->EnterLayer(parent, &occlusion, false);
2150     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2151               occlusion.occlusion_from_inside_target().ToString());
2152     EXPECT_EQ(gfx::Rect().ToString(),
2153               occlusion.occlusion_from_outside_target().ToString());
2154   }
2155 };
2156
2157 // This test requires accumulating occlusion of 3d layers, which are skipped by
2158 // the occlusion tracker on the main thread. So this test should run on the impl
2159 // thread.
2160 IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);
2161
2162 template <class Types>
2163 class OcclusionTrackerTestAnimationOpacity1OnMainThread
2164     : public OcclusionTrackerTest<Types> {
2165  protected:
2166   explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
2167       : OcclusionTrackerTest<Types>(opaque_layers) {}
2168   void RunMyTest() {
2169     // parent
2170     // +--layer
2171     // +--surface
2172     // |  +--surface_child
2173     // |  +--surface_child2
2174     // +--parent2
2175     // +--topmost
2176
2177     typename Types::ContentLayerType* parent = this->CreateRoot(
2178         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2179     typename Types::ContentLayerType* layer =
2180         this->CreateDrawingLayer(parent,
2181                                  this->identity_matrix,
2182                                  gfx::PointF(),
2183                                  gfx::Size(300, 300),
2184                                  true);
2185     typename Types::ContentLayerType* surface =
2186         this->CreateDrawingSurface(parent,
2187                                    this->identity_matrix,
2188                                    gfx::PointF(),
2189                                    gfx::Size(300, 300),
2190                                    true);
2191     typename Types::ContentLayerType* surface_child =
2192         this->CreateDrawingLayer(surface,
2193                                  this->identity_matrix,
2194                                  gfx::PointF(),
2195                                  gfx::Size(200, 300),
2196                                  true);
2197     typename Types::ContentLayerType* surface_child2 =
2198         this->CreateDrawingLayer(surface,
2199                                  this->identity_matrix,
2200                                  gfx::PointF(),
2201                                  gfx::Size(100, 300),
2202                                  true);
2203     typename Types::ContentLayerType* parent2 =
2204         this->CreateDrawingLayer(parent,
2205                                  this->identity_matrix,
2206                                  gfx::PointF(),
2207                                  gfx::Size(300, 300),
2208                                  false);
2209     typename Types::ContentLayerType* topmost =
2210         this->CreateDrawingLayer(parent,
2211                                  this->identity_matrix,
2212                                  gfx::PointF(250.f, 0.f),
2213                                  gfx::Size(50, 300),
2214                                  true);
2215
2216     AddOpacityTransitionToController(
2217         layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2218     AddOpacityTransitionToController(
2219         surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
2220     this->CalcDrawEtc(parent);
2221
2222     EXPECT_TRUE(layer->draw_opacity_is_animating());
2223     EXPECT_FALSE(surface->draw_opacity_is_animating());
2224     EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2225
2226     TestOcclusionTrackerWithClip<typename Types::LayerType,
2227                                  typename Types::RenderSurfaceType> occlusion(
2228         gfx::Rect(0, 0, 1000, 1000));
2229
2230     this->VisitLayer(topmost, &occlusion);
2231     this->EnterLayer(parent2, &occlusion, false);
2232     // This occlusion will affect all surfaces.
2233     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2234               occlusion.occlusion_from_inside_target().ToString());
2235     EXPECT_EQ(gfx::Rect().ToString(),
2236               occlusion.occlusion_from_outside_target().ToString());
2237     EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
2238               occlusion.UnoccludedLayerContentRect(
2239                   parent2, gfx::Rect(0, 0, 300, 300)).ToString());
2240     this->LeaveLayer(parent2, &occlusion);
2241
2242     this->VisitLayer(surface_child2, &occlusion);
2243     this->EnterLayer(surface_child, &occlusion, false);
2244     EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2245               occlusion.occlusion_from_inside_target().ToString());
2246     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2247               occlusion.occlusion_from_outside_target().ToString());
2248     EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2249                    occlusion.UnoccludedLayerContentRect(
2250                        surface_child, gfx::Rect(0, 0, 200, 300)));
2251     this->LeaveLayer(surface_child, &occlusion);
2252     this->EnterLayer(surface, &occlusion, false);
2253     EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2254               occlusion.occlusion_from_inside_target().ToString());
2255     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2256               occlusion.occlusion_from_outside_target().ToString());
2257     EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2258                    occlusion.UnoccludedLayerContentRect(
2259                        surface, gfx::Rect(0, 0, 300, 300)));
2260     this->LeaveLayer(surface, &occlusion);
2261
2262     this->EnterContributingSurface(surface, &occlusion, false);
2263     // Occlusion within the surface is lost when leaving the animating surface.
2264     EXPECT_EQ(gfx::Rect().ToString(),
2265               occlusion.occlusion_from_inside_target().ToString());
2266     EXPECT_EQ(gfx::Rect().ToString(),
2267               occlusion.occlusion_from_outside_target().ToString());
2268     EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2269                    occlusion.UnoccludedContributingSurfaceContentRect(
2270                        surface, false, gfx::Rect(0, 0, 300, 300)));
2271     this->LeaveContributingSurface(surface, &occlusion);
2272
2273     // Occlusion from outside the animating surface still exists.
2274     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2275               occlusion.occlusion_from_inside_target().ToString());
2276     EXPECT_EQ(gfx::Rect().ToString(),
2277               occlusion.occlusion_from_outside_target().ToString());
2278
2279     this->VisitLayer(layer, &occlusion);
2280     this->EnterLayer(parent, &occlusion, false);
2281
2282     // Occlusion is not added for the animating |layer|.
2283     EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2284                    occlusion.UnoccludedLayerContentRect(
2285                        parent, gfx::Rect(0, 0, 300, 300)));
2286   }
2287 };
2288
2289 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
2290
2291 template <class Types>
2292 class OcclusionTrackerTestAnimationOpacity0OnMainThread
2293     : public OcclusionTrackerTest<Types> {
2294  protected:
2295   explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
2296       : OcclusionTrackerTest<Types>(opaque_layers) {}
2297   void RunMyTest() {
2298     typename Types::ContentLayerType* parent = this->CreateRoot(
2299         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2300     typename Types::ContentLayerType* layer =
2301         this->CreateDrawingLayer(parent,
2302                                  this->identity_matrix,
2303                                  gfx::PointF(),
2304                                  gfx::Size(300, 300),
2305                                  true);
2306     typename Types::ContentLayerType* surface =
2307         this->CreateDrawingSurface(parent,
2308                                    this->identity_matrix,
2309                                    gfx::PointF(),
2310                                    gfx::Size(300, 300),
2311                                    true);
2312     typename Types::ContentLayerType* surface_child =
2313         this->CreateDrawingLayer(surface,
2314                                  this->identity_matrix,
2315                                  gfx::PointF(),
2316                                  gfx::Size(200, 300),
2317                                  true);
2318     typename Types::ContentLayerType* surface_child2 =
2319         this->CreateDrawingLayer(surface,
2320                                  this->identity_matrix,
2321                                  gfx::PointF(),
2322                                  gfx::Size(100, 300),
2323                                  true);
2324     typename Types::ContentLayerType* parent2 =
2325         this->CreateDrawingLayer(parent,
2326                                  this->identity_matrix,
2327                                  gfx::PointF(),
2328                                  gfx::Size(300, 300),
2329                                  false);
2330     typename Types::ContentLayerType* topmost =
2331         this->CreateDrawingLayer(parent,
2332                                  this->identity_matrix,
2333                                  gfx::PointF(250.f, 0.f),
2334                                  gfx::Size(50, 300),
2335                                  true);
2336
2337     AddOpacityTransitionToController(
2338         layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2339     AddOpacityTransitionToController(
2340         surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2341     this->CalcDrawEtc(parent);
2342
2343     EXPECT_TRUE(layer->draw_opacity_is_animating());
2344     EXPECT_FALSE(surface->draw_opacity_is_animating());
2345     EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
2346
2347     TestOcclusionTrackerWithClip<typename Types::LayerType,
2348                                  typename Types::RenderSurfaceType> occlusion(
2349         gfx::Rect(0, 0, 1000, 1000));
2350
2351     this->VisitLayer(topmost, &occlusion);
2352     this->EnterLayer(parent2, &occlusion, false);
2353     // This occlusion will affect all surfaces.
2354     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2355               occlusion.occlusion_from_inside_target().ToString());
2356     EXPECT_EQ(gfx::Rect().ToString(),
2357               occlusion.occlusion_from_outside_target().ToString());
2358     EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2359                    occlusion.UnoccludedLayerContentRect(
2360                        parent, gfx::Rect(0, 0, 300, 300)));
2361     this->LeaveLayer(parent2, &occlusion);
2362
2363     this->VisitLayer(surface_child2, &occlusion);
2364     this->EnterLayer(surface_child, &occlusion, false);
2365     EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2366               occlusion.occlusion_from_inside_target().ToString());
2367     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2368               occlusion.occlusion_from_outside_target().ToString());
2369     EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
2370                    occlusion.UnoccludedLayerContentRect(
2371                        surface_child, gfx::Rect(0, 0, 200, 300)));
2372     this->LeaveLayer(surface_child, &occlusion);
2373     this->EnterLayer(surface, &occlusion, false);
2374     EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
2375               occlusion.occlusion_from_inside_target().ToString());
2376     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2377               occlusion.occlusion_from_outside_target().ToString());
2378     EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
2379                    occlusion.UnoccludedLayerContentRect(
2380                        surface, gfx::Rect(0, 0, 300, 300)));
2381     this->LeaveLayer(surface, &occlusion);
2382
2383     this->EnterContributingSurface(surface, &occlusion, false);
2384     // Occlusion within the surface is lost when leaving the animating surface.
2385     EXPECT_EQ(gfx::Rect().ToString(),
2386               occlusion.occlusion_from_inside_target().ToString());
2387     EXPECT_EQ(gfx::Rect().ToString(),
2388               occlusion.occlusion_from_outside_target().ToString());
2389     EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2390                    occlusion.UnoccludedContributingSurfaceContentRect(
2391                        surface, false, gfx::Rect(0, 0, 300, 300)));
2392     this->LeaveContributingSurface(surface, &occlusion);
2393
2394     // Occlusion from outside the animating surface still exists.
2395     EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
2396               occlusion.occlusion_from_inside_target().ToString());
2397     EXPECT_EQ(gfx::Rect().ToString(),
2398               occlusion.occlusion_from_outside_target().ToString());
2399
2400     this->VisitLayer(layer, &occlusion);
2401     this->EnterLayer(parent, &occlusion, false);
2402
2403     // Occlusion is not added for the animating |layer|.
2404     EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
2405                    occlusion.UnoccludedLayerContentRect(
2406                        parent, gfx::Rect(0, 0, 300, 300)));
2407   }
2408 };
2409
2410 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
2411
2412 template <class Types>
2413 class OcclusionTrackerTestAnimationTranslateOnMainThread
2414     : public OcclusionTrackerTest<Types> {
2415  protected:
2416   explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
2417       bool opaque_layers)
2418       : OcclusionTrackerTest<Types>(opaque_layers) {}
2419   void RunMyTest() {
2420     typename Types::ContentLayerType* parent = this->CreateRoot(
2421         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2422     typename Types::ContentLayerType* layer =
2423         this->CreateDrawingLayer(parent,
2424                                  this->identity_matrix,
2425                                  gfx::PointF(),
2426                                  gfx::Size(300, 300),
2427                                  true);
2428     typename Types::ContentLayerType* surface =
2429         this->CreateDrawingSurface(parent,
2430                                    this->identity_matrix,
2431                                    gfx::PointF(),
2432                                    gfx::Size(300, 300),
2433                                    true);
2434     typename Types::ContentLayerType* surface_child =
2435         this->CreateDrawingLayer(surface,
2436                                  this->identity_matrix,
2437                                  gfx::PointF(),
2438                                  gfx::Size(200, 300),
2439                                  true);
2440     typename Types::ContentLayerType* surface_child2 =
2441         this->CreateDrawingLayer(surface,
2442                                  this->identity_matrix,
2443                                  gfx::PointF(),
2444                                  gfx::Size(100, 300),
2445                                  true);
2446     typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
2447         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
2448
2449     AddAnimatedTransformToController(
2450         layer->layer_animation_controller(), 10.0, 30, 0);
2451     AddAnimatedTransformToController(
2452         surface->layer_animation_controller(), 10.0, 30, 0);
2453     AddAnimatedTransformToController(
2454         surface_child->layer_animation_controller(), 10.0, 30, 0);
2455     this->CalcDrawEtc(parent);
2456
2457     EXPECT_TRUE(layer->draw_transform_is_animating());
2458     EXPECT_TRUE(layer->screen_space_transform_is_animating());
2459     EXPECT_TRUE(
2460         surface->render_surface()->target_surface_transforms_are_animating());
2461     EXPECT_TRUE(
2462         surface->render_surface()->screen_space_transforms_are_animating());
2463     // The surface owning layer doesn't animate against its own surface.
2464     EXPECT_FALSE(surface->draw_transform_is_animating());
2465     EXPECT_TRUE(surface->screen_space_transform_is_animating());
2466     EXPECT_TRUE(surface_child->draw_transform_is_animating());
2467     EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
2468
2469     TestOcclusionTrackerWithClip<typename Types::LayerType,
2470                                  typename Types::RenderSurfaceType> occlusion(
2471         gfx::Rect(0, 0, 1000, 1000));
2472
2473     this->VisitLayer(surface2, &occlusion);
2474     this->EnterContributingSurface(surface2, &occlusion, false);
2475
2476     EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
2477               occlusion.occlusion_from_inside_target().ToString());
2478
2479     this->LeaveContributingSurface(surface2, &occlusion);
2480     this->EnterLayer(surface_child2, &occlusion, false);
2481
2482     // surface_child2 is moving in screen space but not relative to its target,
2483     // so occlusion should happen in its target space only.  It also means that
2484     // things occluding from outside the target (e.g. surface2) cannot occlude
2485     // this layer.
2486     EXPECT_EQ(gfx::Rect().ToString(),
2487               occlusion.occlusion_from_outside_target().ToString());
2488
2489     EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
2490                    occlusion.UnoccludedLayerContentRect(
2491                        surface_child2, gfx::Rect(0, 0, 100, 300)));
2492     EXPECT_FALSE(
2493         occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2494
2495     this->LeaveLayer(surface_child2, &occlusion);
2496     this->EnterLayer(surface_child, &occlusion, false);
2497     EXPECT_FALSE(
2498         occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
2499     EXPECT_EQ(gfx::Rect().ToString(),
2500               occlusion.occlusion_from_outside_target().ToString());
2501     EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2502               occlusion.occlusion_from_inside_target().ToString());
2503     EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2504                    occlusion.UnoccludedLayerContentRect(
2505                        surface, gfx::Rect(0, 0, 300, 300)));
2506
2507     // The surface_child is occluded by the surface_child2, but is moving
2508     // relative its target, so it can't be occluded.
2509     EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
2510                    occlusion.UnoccludedLayerContentRect(
2511                        surface_child, gfx::Rect(0, 0, 200, 300)));
2512     EXPECT_FALSE(
2513         occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));
2514
2515     this->LeaveLayer(surface_child, &occlusion);
2516     this->EnterLayer(surface, &occlusion, false);
2517     // The surface_child is moving in screen space but not relative to its
2518     // target, so occlusion should happen from within the target only.
2519     EXPECT_EQ(gfx::Rect().ToString(),
2520               occlusion.occlusion_from_outside_target().ToString());
2521     EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
2522               occlusion.occlusion_from_inside_target().ToString());
2523     EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
2524                    occlusion.UnoccludedLayerContentRect(
2525                        surface, gfx::Rect(0, 0, 300, 300)));
2526
2527     this->LeaveLayer(surface, &occlusion);
2528     // The surface's owning layer is moving in screen space but not relative to
2529     // its target, so occlusion should happen within the target only.
2530     EXPECT_EQ(gfx::Rect().ToString(),
2531               occlusion.occlusion_from_outside_target().ToString());
2532     EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
2533               occlusion.occlusion_from_inside_target().ToString());
2534     EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2535                    occlusion.UnoccludedLayerContentRect(
2536                        surface, gfx::Rect(0, 0, 300, 300)));
2537
2538     this->EnterContributingSurface(surface, &occlusion, false);
2539     // The contributing |surface| is animating so it can't be occluded.
2540     EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
2541                    occlusion.UnoccludedContributingSurfaceContentRect(
2542                        surface, false, gfx::Rect(0, 0, 300, 300)));
2543     this->LeaveContributingSurface(surface, &occlusion);
2544
2545     this->EnterLayer(layer, &occlusion, false);
2546     // The |surface| is moving in the screen and in its target, so all occlusion
2547     // within the surface is lost when leaving it.
2548     EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2549                    occlusion.UnoccludedLayerContentRect(
2550                        parent, gfx::Rect(0, 0, 300, 300)));
2551     this->LeaveLayer(layer, &occlusion);
2552
2553     this->EnterLayer(parent, &occlusion, false);
2554     // The |layer| is animating in the screen and in its target, so no occlusion
2555     // is added.
2556     EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
2557                    occlusion.UnoccludedLayerContentRect(
2558                        parent, gfx::Rect(0, 0, 300, 300)));
2559   }
2560 };
2561
2562 MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
2563
2564 template <class Types>
2565 class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
2566     : public OcclusionTrackerTest<Types> {
2567  protected:
2568   explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
2569       bool opaque_layers)
2570       : OcclusionTrackerTest<Types>(opaque_layers) {}
2571   void RunMyTest() {
2572     gfx::Transform surface_transform;
2573     surface_transform.Translate(300.0, 300.0);
2574     surface_transform.Scale(2.0, 2.0);
2575     surface_transform.Translate(-150.0, -150.0);
2576
2577     typename Types::ContentLayerType* parent = this->CreateRoot(
2578         this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
2579     typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
2580         parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
2581     typename Types::ContentLayerType* surface2 =
2582         this->CreateDrawingSurface(parent,
2583                                    this->identity_matrix,
2584                                    gfx::PointF(50.f, 50.f),
2585                                    gfx::Size(300, 300),
2586                                    false);
2587     surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2588     surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
2589     this->CalcDrawEtc(parent);
2590
2591     TestOcclusionTrackerWithClip<typename Types::LayerType,
2592                                  typename Types::RenderSurfaceType> occlusion(
2593         gfx::Rect(0, 0, 1000, 1000));
2594
2595     this->VisitLayer(surface2, &occlusion);
2596     this->VisitContributingSurface(surface2, &occlusion);
2597
2598     EXPECT_EQ(gfx::Rect().ToString(),
2599               occlusion.occlusion_from_outside_target().ToString());
2600     EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
2601               occlusion.occlusion_from_inside_target().ToString());
2602
2603     // Clear any stored occlusion.
2604     occlusion.set_occlusion_from_outside_target(Region());
2605     occlusion.set_occlusion_from_inside_target(Region());
2606
2607     this->VisitLayer(surface, &occlusion);
2608     this->VisitContributingSurface(surface, &occlusion);
2609
2610     EXPECT_EQ(gfx::Rect().ToString(),
2611               occlusion.occlusion_from_outside_target().ToString());
2612     EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
2613               occlusion.occlusion_from_inside_target().ToString());
2614   }
2615 };
2616
2617 MAIN_AND_IMPL_THREAD_TEST(
2618     OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
2619
2620 template <class Types>
2621 class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
2622     : public OcclusionTrackerTest<Types> {
2623  protected:
2624   explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
2625       bool opaque_layers)
2626       : OcclusionTrackerTest<Types>(opaque_layers) {}
2627   void RunMyTest() {
2628     typename Types::ContentLayerType* parent = this->CreateRoot(
2629         this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
2630     parent->SetMasksToBounds(true);
2631     typename Types::ContentLayerType* surface =
2632         this->CreateDrawingSurface(parent,
2633                                    this->identity_matrix,
2634                                    gfx::PointF(),
2635                                    gfx::Size(500, 300),
2636                                    false);
2637     surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
2638     this->CalcDrawEtc(parent);
2639
2640     TestOcclusionTrackerWithClip<typename Types::LayerType,
2641                                  typename Types::RenderSurfaceType> occlusion(
2642         gfx::Rect(0, 0, 1000, 1000));
2643
2644     this->VisitLayer(surface, &occlusion);
2645     this->VisitContributingSurface(surface, &occlusion);
2646
2647     EXPECT_EQ(gfx::Rect().ToString(),
2648               occlusion.occlusion_from_outside_target().ToString());
2649     EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
2650               occlusion.occlusion_from_inside_target().ToString());
2651   }
2652 };
2653
2654 MAIN_AND_IMPL_THREAD_TEST(
2655     OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
2656
2657 template <class Types>
2658 class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
2659  protected:
2660   explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
2661       : OcclusionTrackerTest<Types>(opaque_layers) {}
2662   void RunMyTest() {
2663     typename Types::ContentLayerType* parent = this->CreateRoot(
2664         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2665     typename Types::LayerType* surface =
2666         this->CreateDrawingSurface(parent,
2667                                    this->identity_matrix,
2668                                    gfx::PointF(),
2669                                    gfx::Size(100, 100),
2670                                    true);
2671     this->CreateReplicaLayer(surface,
2672                              this->identity_matrix,
2673                              gfx::PointF(0.f, 100.f),
2674                              gfx::Size(100, 100));
2675     typename Types::LayerType* topmost =
2676         this->CreateDrawingLayer(parent,
2677                                  this->identity_matrix,
2678                                  gfx::PointF(0.f, 100.f),
2679                                  gfx::Size(100, 100),
2680                                  true);
2681     this->CalcDrawEtc(parent);
2682
2683     TestOcclusionTrackerWithClip<typename Types::LayerType,
2684                                  typename Types::RenderSurfaceType> occlusion(
2685         gfx::Rect(0, 0, 1000, 1000));
2686
2687     // |topmost| occludes the replica, but not the surface itself.
2688     this->VisitLayer(topmost, &occlusion);
2689
2690     EXPECT_EQ(gfx::Rect().ToString(),
2691               occlusion.occlusion_from_outside_target().ToString());
2692     EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2693               occlusion.occlusion_from_inside_target().ToString());
2694
2695     this->VisitLayer(surface, &occlusion);
2696
2697     EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
2698               occlusion.occlusion_from_outside_target().ToString());
2699     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2700               occlusion.occlusion_from_inside_target().ToString());
2701
2702     this->EnterContributingSurface(surface, &occlusion, false);
2703
2704     // Surface is not occluded so it shouldn't think it is.
2705     EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2706                    occlusion.UnoccludedContributingSurfaceContentRect(
2707                        surface, false, gfx::Rect(0, 0, 100, 100)));
2708   }
2709 };
2710
2711 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);
2712
2713 template <class Types>
2714 class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
2715     : public OcclusionTrackerTest<Types> {
2716  protected:
2717   explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
2718       : OcclusionTrackerTest<Types>(opaque_layers) {}
2719   void RunMyTest() {
2720     typename Types::ContentLayerType* parent = this->CreateRoot(
2721         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2722     typename Types::LayerType* surface =
2723         this->CreateDrawingSurface(parent,
2724                                    this->identity_matrix,
2725                                    gfx::PointF(),
2726                                    gfx::Size(100, 100),
2727                                    true);
2728     this->CreateReplicaLayer(surface,
2729                              this->identity_matrix,
2730                              gfx::PointF(0.f, 100.f),
2731                              gfx::Size(100, 100));
2732     typename Types::LayerType* topmost =
2733         this->CreateDrawingLayer(parent,
2734                                  this->identity_matrix,
2735                                  gfx::PointF(),
2736                                  gfx::Size(100, 110),
2737                                  true);
2738     this->CalcDrawEtc(parent);
2739
2740     TestOcclusionTrackerWithClip<typename Types::LayerType,
2741                                  typename Types::RenderSurfaceType> occlusion(
2742         gfx::Rect(0, 0, 1000, 1000));
2743
2744     // |topmost| occludes the surface, but not the entire surface's replica.
2745     this->VisitLayer(topmost, &occlusion);
2746
2747     EXPECT_EQ(gfx::Rect().ToString(),
2748               occlusion.occlusion_from_outside_target().ToString());
2749     EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2750               occlusion.occlusion_from_inside_target().ToString());
2751
2752     this->VisitLayer(surface, &occlusion);
2753
2754     EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
2755               occlusion.occlusion_from_outside_target().ToString());
2756     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2757               occlusion.occlusion_from_inside_target().ToString());
2758
2759     this->EnterContributingSurface(surface, &occlusion, false);
2760
2761     // Surface is occluded, but only the top 10px of the replica.
2762     EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
2763                    occlusion.UnoccludedContributingSurfaceContentRect(
2764                        surface, false, gfx::Rect(0, 0, 100, 100)));
2765     EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
2766                    occlusion.UnoccludedContributingSurfaceContentRect(
2767                        surface, true, gfx::Rect(0, 0, 100, 100)));
2768   }
2769 };
2770
2771 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
2772
2773 template <class Types>
2774 class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
2775     : public OcclusionTrackerTest<Types> {
2776  protected:
2777   explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
2778       bool opaque_layers)
2779       : OcclusionTrackerTest<Types>(opaque_layers) {}
2780   void RunMyTest() {
2781     typename Types::ContentLayerType* parent = this->CreateRoot(
2782         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2783     typename Types::LayerType* surface =
2784         this->CreateDrawingSurface(parent,
2785                                    this->identity_matrix,
2786                                    gfx::PointF(),
2787                                    gfx::Size(100, 100),
2788                                    true);
2789     this->CreateReplicaLayer(surface,
2790                              this->identity_matrix,
2791                              gfx::PointF(0.f, 100.f),
2792                              gfx::Size(100, 100));
2793     typename Types::LayerType* over_surface = this->CreateDrawingLayer(
2794         parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
2795     typename Types::LayerType* over_replica =
2796         this->CreateDrawingLayer(parent,
2797                                  this->identity_matrix,
2798                                  gfx::PointF(0.f, 100.f),
2799                                  gfx::Size(50, 100),
2800                                  true);
2801     this->CalcDrawEtc(parent);
2802
2803     TestOcclusionTrackerWithClip<typename Types::LayerType,
2804                                  typename Types::RenderSurfaceType> occlusion(
2805         gfx::Rect(0, 0, 1000, 1000));
2806
2807     // These occlude the surface and replica differently, so we can test each
2808     // one.
2809     this->VisitLayer(over_replica, &occlusion);
2810     this->VisitLayer(over_surface, &occlusion);
2811
2812     EXPECT_EQ(gfx::Rect().ToString(),
2813               occlusion.occlusion_from_outside_target().ToString());
2814     EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2815                   .ToString(),
2816               occlusion.occlusion_from_inside_target().ToString());
2817
2818     this->VisitLayer(surface, &occlusion);
2819
2820     EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
2821                   .ToString(),
2822               occlusion.occlusion_from_outside_target().ToString());
2823     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
2824               occlusion.occlusion_from_inside_target().ToString());
2825
2826     this->EnterContributingSurface(surface, &occlusion, false);
2827
2828     // Surface and replica are occluded different amounts.
2829     EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
2830                    occlusion.UnoccludedContributingSurfaceContentRect(
2831                        surface, false, gfx::Rect(0, 0, 100, 100)));
2832     EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
2833                    occlusion.UnoccludedContributingSurfaceContentRect(
2834                        surface, true, gfx::Rect(0, 0, 100, 100)));
2835   }
2836 };
2837
2838 ALL_OCCLUSIONTRACKER_TEST(
2839     OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);
2840
2841 template <class Types>
2842 class OcclusionTrackerTestSurfaceChildOfSurface
2843     : public OcclusionTrackerTest<Types> {
2844  protected:
2845   explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
2846       : OcclusionTrackerTest<Types>(opaque_layers) {}
2847   void RunMyTest() {
2848     // This test verifies that the surface cliprect does not end up empty and
2849     // clip away the entire unoccluded rect.
2850
2851     typename Types::ContentLayerType* parent = this->CreateRoot(
2852         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2853     typename Types::LayerType* surface =
2854         this->CreateDrawingSurface(parent,
2855                                    this->identity_matrix,
2856                                    gfx::PointF(),
2857                                    gfx::Size(100, 100),
2858                                    true);
2859     typename Types::LayerType* surface_child =
2860         this->CreateDrawingSurface(surface,
2861                                    this->identity_matrix,
2862                                    gfx::PointF(0.f, 10.f),
2863                                    gfx::Size(100, 50),
2864                                    true);
2865     typename Types::LayerType* topmost = this->CreateDrawingLayer(
2866         parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
2867     this->CalcDrawEtc(parent);
2868
2869     TestOcclusionTrackerWithClip<typename Types::LayerType,
2870                                  typename Types::RenderSurfaceType> occlusion(
2871         gfx::Rect(-100, -100, 1000, 1000));
2872
2873     // |topmost| occludes everything partially so we know occlusion is happening
2874     // at all.
2875     this->VisitLayer(topmost, &occlusion);
2876
2877     EXPECT_EQ(gfx::Rect().ToString(),
2878               occlusion.occlusion_from_outside_target().ToString());
2879     EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2880               occlusion.occlusion_from_inside_target().ToString());
2881
2882     this->VisitLayer(surface_child, &occlusion);
2883
2884     // surface_child increases the occlusion in the screen by a narrow sliver.
2885     EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
2886               occlusion.occlusion_from_outside_target().ToString());
2887     // In its own surface, surface_child is at 0,0 as is its occlusion.
2888     EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2889               occlusion.occlusion_from_inside_target().ToString());
2890
2891     // The root layer always has a clip rect. So the parent of |surface| has a
2892     // clip rect. However, the owning layer for |surface| does not mask to
2893     // bounds, so it doesn't have a clip rect of its own. Thus the parent of
2894     // |surface_child| exercises different code paths as its parent does not
2895     // have a clip rect.
2896
2897     this->EnterContributingSurface(surface_child, &occlusion, false);
2898     // The surface_child's parent does not have a clip rect as it owns a render
2899     // surface. Make sure the unoccluded rect does not get clipped away
2900     // inappropriately.
2901     EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
2902                    occlusion.UnoccludedContributingSurfaceContentRect(
2903                        surface_child, false, gfx::Rect(0, 0, 100, 50)));
2904     this->LeaveContributingSurface(surface_child, &occlusion);
2905
2906     // When the surface_child's occlusion is transformed up to its parent, make
2907     // sure it is not clipped away inappropriately also.
2908     this->EnterLayer(surface, &occlusion, false);
2909     EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
2910               occlusion.occlusion_from_outside_target().ToString());
2911     EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
2912               occlusion.occlusion_from_inside_target().ToString());
2913     this->LeaveLayer(surface, &occlusion);
2914
2915     this->EnterContributingSurface(surface, &occlusion, false);
2916     // The surface's parent does have a clip rect as it is the root layer.
2917     EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
2918                    occlusion.UnoccludedContributingSurfaceContentRect(
2919                        surface, false, gfx::Rect(0, 0, 100, 100)));
2920   }
2921 };
2922
2923 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
2924
2925 template <class Types>
2926 class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
2927     : public OcclusionTrackerTest<Types> {
2928  protected:
2929   explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
2930       bool opaque_layers)
2931       : OcclusionTrackerTest<Types>(opaque_layers) {}
2932   void RunMyTest() {
2933     // This test verifies that the top-most surface is considered occluded
2934     // outside of its target's clip rect and outside the viewport rect.
2935
2936     typename Types::ContentLayerType* parent = this->CreateRoot(
2937         this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
2938     typename Types::LayerType* surface =
2939         this->CreateDrawingSurface(parent,
2940                                    this->identity_matrix,
2941                                    gfx::PointF(),
2942                                    gfx::Size(100, 300),
2943                                    true);
2944     this->CalcDrawEtc(parent);
2945     {
2946       // Make a viewport rect that is larger than the root layer.
2947       TestOcclusionTrackerWithClip<typename Types::LayerType,
2948                                    typename Types::RenderSurfaceType> occlusion(
2949           gfx::Rect(0, 0, 1000, 1000));
2950
2951       this->VisitLayer(surface, &occlusion);
2952
2953       // The root layer always has a clip rect. So the parent of |surface| has a
2954       // clip rect giving the surface itself a clip rect.
2955       this->EnterContributingSurface(surface, &occlusion, false);
2956       // Make sure the parent's clip rect clips the unoccluded region of the
2957       // child surface.
2958       EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
2959                      occlusion.UnoccludedContributingSurfaceContentRect(
2960                          surface, false, gfx::Rect(0, 0, 100, 300)));
2961     }
2962     this->ResetLayerIterator();
2963     {
2964       // Make a viewport rect that is smaller than the root layer.
2965       TestOcclusionTrackerWithClip<typename Types::LayerType,
2966                                    typename Types::RenderSurfaceType> occlusion(
2967           gfx::Rect(0, 0, 100, 100));
2968
2969       this->VisitLayer(surface, &occlusion);
2970
2971       // The root layer always has a clip rect. So the parent of |surface| has a
2972       // clip rect giving the surface itself a clip rect.
2973       this->EnterContributingSurface(surface, &occlusion, false);
2974       // Make sure the viewport rect clips the unoccluded region of the child
2975       // surface.
2976       EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2977                      occlusion.UnoccludedContributingSurfaceContentRect(
2978                          surface, false, gfx::Rect(0, 0, 100, 300)));
2979     }
2980   }
2981 };
2982
2983 ALL_OCCLUSIONTRACKER_TEST(
2984     OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);
2985
2986 template <class Types>
2987 class OcclusionTrackerTestSurfaceChildOfClippingSurface
2988     : public OcclusionTrackerTest<Types> {
2989  protected:
2990   explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
2991       : OcclusionTrackerTest<Types>(opaque_layers) {}
2992   void RunMyTest() {
2993     // This test verifies that the surface cliprect does not end up empty and
2994     // clip away the entire unoccluded rect.
2995
2996     typename Types::ContentLayerType* parent = this->CreateRoot(
2997         this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
2998     parent->SetMasksToBounds(true);
2999     typename Types::LayerType* surface =
3000         this->CreateDrawingSurface(parent,
3001                                    this->identity_matrix,
3002                                    gfx::PointF(),
3003                                    gfx::Size(100, 100),
3004                                    true);
3005     typename Types::LayerType* surface_child =
3006         this->CreateDrawingSurface(surface,
3007                                    this->identity_matrix,
3008                                    gfx::PointF(),
3009                                    gfx::Size(100, 100),
3010                                    false);
3011     typename Types::LayerType* topmost = this->CreateDrawingLayer(
3012         parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
3013     this->CalcDrawEtc(parent);
3014
3015     TestOcclusionTrackerWithClip<typename Types::LayerType,
3016                                  typename Types::RenderSurfaceType> occlusion(
3017         gfx::Rect(0, 0, 1000, 1000));
3018
3019     // |topmost| occludes everything partially so we know occlusion is happening
3020     // at all.
3021     this->VisitLayer(topmost, &occlusion);
3022
3023     EXPECT_EQ(gfx::Rect().ToString(),
3024               occlusion.occlusion_from_outside_target().ToString());
3025     EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3026               occlusion.occlusion_from_inside_target().ToString());
3027
3028     // surface_child is not opaque and does not occlude, so we have a non-empty
3029     // unoccluded area on surface.
3030     this->VisitLayer(surface_child, &occlusion);
3031
3032     EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
3033               occlusion.occlusion_from_outside_target().ToString());
3034     EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
3035               occlusion.occlusion_from_inside_target().ToString());
3036
3037     // The root layer always has a clip rect. So the parent of |surface| has a
3038     // clip rect. However, the owning layer for |surface| does not mask to
3039     // bounds, so it doesn't have a clip rect of its own. Thus the parent of
3040     // |surface_child| exercises different code paths as its parent does not
3041     // have a clip rect.
3042
3043     this->EnterContributingSurface(surface_child, &occlusion, false);
3044     // The surface_child's parent does not have a clip rect as it owns a render
3045     // surface.
3046     EXPECT_EQ(
3047         gfx::Rect(0, 50, 80, 50).ToString(),
3048         occlusion.UnoccludedContributingSurfaceContentRect(
3049             surface_child, false, gfx::Rect(0, 0, 100, 100)).ToString());
3050     this->LeaveContributingSurface(surface_child, &occlusion);
3051
3052     this->VisitLayer(surface, &occlusion);
3053     this->EnterContributingSurface(surface, &occlusion, false);
3054     // The surface's parent does have a clip rect as it is the root layer.
3055     EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
3056               occlusion.UnoccludedContributingSurfaceContentRect(
3057                   surface, false, gfx::Rect(0, 0, 100, 100)).ToString());
3058   }
3059 };
3060
3061 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);
3062
3063 template <class Types>
3064 class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
3065     : public OcclusionTrackerTest<Types> {
3066  protected:
3067   explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
3068       bool opaque_layers)
3069       : OcclusionTrackerTest<Types>(opaque_layers) {}
3070   void RunMyTest() {
3071     gfx::Transform scale_by_half;
3072     scale_by_half.Scale(0.5, 0.5);
3073
3074     // Make a surface and its replica, each 50x50, that are completely
3075     // surrounded by opaque layers which are above them in the z-order.  The
3076     // surface is scaled to test that the pixel moving is done in the target
3077     // space, where the background filter is applied, but the surface appears at
3078     // 50, 50 and the replica at 200, 50.
3079     typename Types::ContentLayerType* parent = this->CreateRoot(
3080         this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3081     typename Types::LayerType* filtered_surface =
3082         this->CreateDrawingLayer(parent,
3083                                  scale_by_half,
3084                                  gfx::PointF(50.f, 50.f),
3085                                  gfx::Size(100, 100),
3086                                  false);
3087     this->CreateReplicaLayer(filtered_surface,
3088                              this->identity_matrix,
3089                              gfx::PointF(300.f, 0.f),
3090                              gfx::Size());
3091     typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
3092         parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
3093     typename Types::LayerType* occluding_layer2 =
3094         this->CreateDrawingLayer(parent,
3095                                  this->identity_matrix,
3096                                  gfx::PointF(0.f, 100.f),
3097                                  gfx::Size(300, 50),
3098                                  true);
3099     typename Types::LayerType* occluding_layer3 =
3100         this->CreateDrawingLayer(parent,
3101                                  this->identity_matrix,
3102                                  gfx::PointF(0.f, 50.f),
3103                                  gfx::Size(50, 50),
3104                                  true);
3105     typename Types::LayerType* occluding_layer4 =
3106         this->CreateDrawingLayer(parent,
3107                                  this->identity_matrix,
3108                                  gfx::PointF(100.f, 50.f),
3109                                  gfx::Size(100, 50),
3110                                  true);
3111     typename Types::LayerType* occluding_layer5 =
3112         this->CreateDrawingLayer(parent,
3113                                  this->identity_matrix,
3114                                  gfx::PointF(250.f, 50.f),
3115                                  gfx::Size(50, 50),
3116                                  true);
3117
3118     // Filters make the layer own a surface.
3119     FilterOperations filters;
3120     filters.Append(FilterOperation::CreateBlurFilter(10.f));
3121     filtered_surface->SetBackgroundFilters(filters);
3122
3123     // Save the distance of influence for the blur effect.
3124     int outset_top, outset_right, outset_bottom, outset_left;
3125     filters.GetOutsets(
3126         &outset_top, &outset_right, &outset_bottom, &outset_left);
3127
3128     this->CalcDrawEtc(parent);
3129
3130     TestOcclusionTrackerWithClip<typename Types::LayerType,
3131                                  typename Types::RenderSurfaceType> occlusion(
3132         gfx::Rect(0, 0, 1000, 1000));
3133
3134     // These layers occlude pixels directly beside the filtered_surface. Because
3135     // filtered surface blends pixels in a radius, it will need to see some of
3136     // the pixels (up to radius far) underneath the occluding layers.
3137     this->VisitLayer(occluding_layer5, &occlusion);
3138     this->VisitLayer(occluding_layer4, &occlusion);
3139     this->VisitLayer(occluding_layer3, &occlusion);
3140     this->VisitLayer(occluding_layer2, &occlusion);
3141     this->VisitLayer(occluding_layer1, &occlusion);
3142
3143     Region expected_occlusion;
3144     expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
3145     expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
3146     expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
3147     expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
3148     expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));
3149
3150     EXPECT_EQ(expected_occlusion.ToString(),
3151               occlusion.occlusion_from_inside_target().ToString());
3152     EXPECT_EQ(gfx::Rect().ToString(),
3153               occlusion.occlusion_from_outside_target().ToString());
3154
3155     this->VisitLayer(filtered_surface, &occlusion);
3156
3157     // The filtered layer/replica does not occlude.
3158     Region expected_occlusion_outside_surface;
3159     expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
3160     expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
3161     expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
3162     expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
3163     expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));
3164
3165     EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
3166               occlusion.occlusion_from_outside_target().ToString());
3167     EXPECT_EQ(gfx::Rect().ToString(),
3168               occlusion.occlusion_from_inside_target().ToString());
3169
3170     // The surface has a background blur, so it needs pixels that are currently
3171     // considered occluded in order to be drawn. So the pixels it needs should
3172     // be removed some the occluded area so that when we get to the parent they
3173     // are drawn.
3174     this->VisitContributingSurface(filtered_surface, &occlusion);
3175
3176     this->EnterLayer(parent, &occlusion, false);
3177
3178     Region expected_blurred_occlusion;
3179     expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
3180     expected_blurred_occlusion.Union(gfx::Rect(
3181         0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
3182     expected_blurred_occlusion.Union(
3183         gfx::Rect(100 + outset_right,
3184                   50 - outset_top,
3185                   100 - outset_right - outset_left,
3186                   50 + outset_top + outset_bottom));
3187     expected_blurred_occlusion.Union(
3188         gfx::Rect(250 + outset_right,
3189                   50 - outset_top,
3190                   50 - outset_right,
3191                   50 + outset_top + outset_bottom));
3192     expected_blurred_occlusion.Union(
3193         gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));
3194
3195     EXPECT_EQ(expected_blurred_occlusion.ToString(),
3196               occlusion.occlusion_from_inside_target().ToString());
3197     EXPECT_EQ(gfx::Rect().ToString(),
3198               occlusion.occlusion_from_outside_target().ToString());
3199
3200     gfx::Rect outset_rect;
3201     gfx::Rect test_rect;
3202
3203     // Nothing in the blur outsets for the filtered_surface is occluded.
3204     outset_rect = gfx::Rect(50 - outset_left,
3205                             50 - outset_top,
3206                             50 + outset_left + outset_right,
3207                             50 + outset_top + outset_bottom);
3208     test_rect = outset_rect;
3209     EXPECT_EQ(
3210         outset_rect.ToString(),
3211         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3212
3213     // Stuff outside the blur outsets is still occluded though.
3214     test_rect = outset_rect;
3215     test_rect.Inset(0, 0, -1, 0);
3216     EXPECT_EQ(
3217         outset_rect.ToString(),
3218         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3219     test_rect = outset_rect;
3220     test_rect.Inset(0, 0, 0, -1);
3221     EXPECT_EQ(
3222         outset_rect.ToString(),
3223         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3224     test_rect = outset_rect;
3225     test_rect.Inset(-1, 0, 0, 0);
3226     EXPECT_EQ(
3227         outset_rect.ToString(),
3228         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3229     test_rect = outset_rect;
3230     test_rect.Inset(0, -1, 0, 0);
3231     EXPECT_EQ(
3232         outset_rect.ToString(),
3233         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3234
3235     // Nothing in the blur outsets for the filtered_surface's replica is
3236     // occluded.
3237     outset_rect = gfx::Rect(200 - outset_left,
3238                             50 - outset_top,
3239                             50 + outset_left + outset_right,
3240                             50 + outset_top + outset_bottom);
3241     test_rect = outset_rect;
3242     EXPECT_EQ(
3243         outset_rect.ToString(),
3244         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3245
3246     // Stuff outside the blur outsets is still occluded though.
3247     test_rect = outset_rect;
3248     test_rect.Inset(0, 0, -1, 0);
3249     EXPECT_EQ(
3250         outset_rect.ToString(),
3251         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3252     test_rect = outset_rect;
3253     test_rect.Inset(0, 0, 0, -1);
3254     EXPECT_EQ(
3255         outset_rect.ToString(),
3256         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3257     test_rect = outset_rect;
3258     test_rect.Inset(-1, 0, 0, 0);
3259     EXPECT_EQ(
3260         outset_rect.ToString(),
3261         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3262     test_rect = outset_rect;
3263     test_rect.Inset(0, -1, 0, 0);
3264     EXPECT_EQ(
3265         outset_rect.ToString(),
3266         occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
3267   }
3268 };
3269
3270 ALL_OCCLUSIONTRACKER_TEST(
3271     OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
3272
3273 template <class Types>
3274 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
3275     : public OcclusionTrackerTest<Types> {
3276  protected:
3277   explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
3278       bool opaque_layers)
3279       : OcclusionTrackerTest<Types>(opaque_layers) {}
3280   void RunMyTest() {
3281     gfx::Transform scale_by_half;
3282     scale_by_half.Scale(0.5, 0.5);
3283
3284     // Makes two surfaces that completely cover |parent|. The occlusion both
3285     // above and below the filters will be reduced by each of them.
3286     typename Types::ContentLayerType* root = this->CreateRoot(
3287         this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
3288     typename Types::LayerType* parent = this->CreateSurface(
3289         root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
3290     parent->SetMasksToBounds(true);
3291     typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
3292         parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3293     typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
3294         parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
3295     typename Types::LayerType* occluding_layer_above =
3296         this->CreateDrawingLayer(parent,
3297                                  this->identity_matrix,
3298                                  gfx::PointF(100.f, 100.f),
3299                                  gfx::Size(50, 50),
3300                                  true);
3301
3302     // Filters make the layers own surfaces.
3303     FilterOperations filters;
3304     filters.Append(FilterOperation::CreateBlurFilter(1.f));
3305     filtered_surface1->SetBackgroundFilters(filters);
3306     filtered_surface2->SetBackgroundFilters(filters);
3307
3308     // Save the distance of influence for the blur effect.
3309     int outset_top, outset_right, outset_bottom, outset_left;
3310     filters.GetOutsets(
3311         &outset_top, &outset_right, &outset_bottom, &outset_left);
3312
3313     this->CalcDrawEtc(root);
3314
3315     TestOcclusionTrackerWithClip<typename Types::LayerType,
3316                                  typename Types::RenderSurfaceType> occlusion(
3317         gfx::Rect(0, 0, 1000, 1000));
3318
3319     this->VisitLayer(occluding_layer_above, &occlusion);
3320     EXPECT_EQ(gfx::Rect().ToString(),
3321               occlusion.occlusion_from_outside_target().ToString());
3322     EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
3323               occlusion.occlusion_from_inside_target().ToString());
3324
3325     this->VisitLayer(filtered_surface2, &occlusion);
3326     this->VisitContributingSurface(filtered_surface2, &occlusion);
3327     this->VisitLayer(filtered_surface1, &occlusion);
3328     this->VisitContributingSurface(filtered_surface1, &occlusion);
3329
3330     // Test expectations in the target.
3331     gfx::Rect expected_occlusion =
3332         gfx::Rect(100 / 2 + outset_right * 2,
3333                   100 / 2 + outset_bottom * 2,
3334                   50 / 2 - (outset_left + outset_right) * 2,
3335                   50 / 2 - (outset_top + outset_bottom) * 2);
3336     EXPECT_EQ(expected_occlusion.ToString(),
3337               occlusion.occlusion_from_inside_target().ToString());
3338
3339     // Test expectations in the screen are the same as in the target, as the
3340     // render surface is 1:1 with the screen.
3341     EXPECT_EQ(expected_occlusion.ToString(),
3342               occlusion.occlusion_from_outside_target().ToString());
3343   }
3344 };
3345
3346 ALL_OCCLUSIONTRACKER_TEST(
3347     OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
3348
3349 template <class Types>
3350 class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
3351     : public OcclusionTrackerTest<Types> {
3352  protected:
3353   explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
3354       bool opaque_layers)
3355       : OcclusionTrackerTest<Types>(opaque_layers) {}
3356   void RunMyTest() {
3357     gfx::Transform scale_by_half;
3358     scale_by_half.Scale(0.5, 0.5);
3359
3360     // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
3361     // centered below each.  The surface is scaled to test that the pixel moving
3362     // is done in the target space, where the background filter is applied, but
3363     // the surface appears at 50, 50 and the replica at 200, 50.
3364     typename Types::ContentLayerType* parent = this->CreateRoot(
3365         this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3366     typename Types::LayerType* behind_surface_layer =
3367         this->CreateDrawingLayer(parent,
3368                                  this->identity_matrix,
3369                                  gfx::PointF(60.f, 60.f),
3370                                  gfx::Size(30, 30),
3371                                  true);
3372     typename Types::LayerType* behind_replica_layer =
3373         this->CreateDrawingLayer(parent,
3374                                  this->identity_matrix,
3375                                  gfx::PointF(210.f, 60.f),
3376                                  gfx::Size(30, 30),
3377                                  true);
3378     typename Types::LayerType* filtered_surface =
3379         this->CreateDrawingLayer(parent,
3380                                  scale_by_half,
3381                                  gfx::PointF(50.f, 50.f),
3382                                  gfx::Size(100, 100),
3383                                  false);
3384     this->CreateReplicaLayer(filtered_surface,
3385                              this->identity_matrix,
3386                              gfx::PointF(300.f, 0.f),
3387                              gfx::Size());
3388
3389     // Filters make the layer own a surface.
3390     FilterOperations filters;
3391     filters.Append(FilterOperation::CreateBlurFilter(3.f));
3392     filtered_surface->SetBackgroundFilters(filters);
3393
3394     this->CalcDrawEtc(parent);
3395
3396     TestOcclusionTrackerWithClip<typename Types::LayerType,
3397                                  typename Types::RenderSurfaceType> occlusion(
3398         gfx::Rect(0, 0, 1000, 1000));
3399
3400     // The surface has a background blur, so it blurs non-opaque pixels below
3401     // it.
3402     this->VisitLayer(filtered_surface, &occlusion);
3403     this->VisitContributingSurface(filtered_surface, &occlusion);
3404
3405     this->VisitLayer(behind_replica_layer, &occlusion);
3406     this->VisitLayer(behind_surface_layer, &occlusion);
3407
3408     // The layers behind the surface are not blurred, and their occlusion does
3409     // not change, until we leave the surface.  So it should not be modified by
3410     // the filter here.
3411     gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
3412     gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);
3413
3414     Region expected_opaque_bounds =
3415         UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
3416     EXPECT_EQ(expected_opaque_bounds.ToString(),
3417               occlusion.occlusion_from_inside_target().ToString());
3418
3419     EXPECT_EQ(gfx::Rect().ToString(),
3420               occlusion.occlusion_from_outside_target().ToString());
3421   }
3422 };
3423
3424 ALL_OCCLUSIONTRACKER_TEST(
3425     OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
3426
3427 template <class Types>
3428 class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
3429     : public OcclusionTrackerTest<Types> {
3430  protected:
3431   explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
3432       bool opaque_layers)
3433       : OcclusionTrackerTest<Types>(opaque_layers) {}
3434   void RunMyTest() {
3435     gfx::Transform scale_by_half;
3436     scale_by_half.Scale(0.5, 0.5);
3437
3438     // Make a surface and its replica, each 50x50, that are completely occluded
3439     // by opaque layers which are above them in the z-order.  The surface is
3440     // scaled to test that the pixel moving is done in the target space, where
3441     // the background filter is applied, but the surface appears at 50, 50 and
3442     // the replica at 200, 50.
3443     typename Types::ContentLayerType* parent = this->CreateRoot(
3444         this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3445     typename Types::LayerType* filtered_surface =
3446         this->CreateDrawingLayer(parent,
3447                                  scale_by_half,
3448                                  gfx::PointF(50.f, 50.f),
3449                                  gfx::Size(100, 100),
3450                                  false);
3451     this->CreateReplicaLayer(filtered_surface,
3452                              this->identity_matrix,
3453                              gfx::PointF(300.f, 0.f),
3454                              gfx::Size());
3455     typename Types::LayerType* above_surface_layer =
3456         this->CreateDrawingLayer(parent,
3457                                  this->identity_matrix,
3458                                  gfx::PointF(50.f, 50.f),
3459                                  gfx::Size(50, 50),
3460                                  true);
3461     typename Types::LayerType* above_replica_layer =
3462         this->CreateDrawingLayer(parent,
3463                                  this->identity_matrix,
3464                                  gfx::PointF(200.f, 50.f),
3465                                  gfx::Size(50, 50),
3466                                  true);
3467
3468     // Filters make the layer own a surface.
3469     FilterOperations filters;
3470     filters.Append(FilterOperation::CreateBlurFilter(3.f));
3471     filtered_surface->SetBackgroundFilters(filters);
3472
3473     this->CalcDrawEtc(parent);
3474
3475     TestOcclusionTrackerWithClip<typename Types::LayerType,
3476                                  typename Types::RenderSurfaceType> occlusion(
3477         gfx::Rect(0, 0, 1000, 1000));
3478
3479     this->VisitLayer(above_replica_layer, &occlusion);
3480     this->VisitLayer(above_surface_layer, &occlusion);
3481
3482     this->VisitLayer(filtered_surface, &occlusion);
3483     {
3484       // The layers above the filtered surface occlude from outside.
3485       gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
3486       gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
3487       Region expected_opaque_region =
3488           UnionRegions(occlusion_above_surface, occlusion_above_replica);
3489
3490       EXPECT_EQ(gfx::Rect().ToString(),
3491                 occlusion.occlusion_from_inside_target().ToString());
3492       EXPECT_EQ(expected_opaque_region.ToString(),
3493                 occlusion.occlusion_from_outside_target().ToString());
3494     }
3495
3496     // The surface has a background blur, so it blurs non-opaque pixels below
3497     // it.
3498     this->VisitContributingSurface(filtered_surface, &occlusion);
3499     {
3500       // The filter is completely occluded, so it should not blur anything and
3501       // reduce any occlusion.
3502       gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
3503       gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
3504       Region expected_opaque_region =
3505           UnionRegions(occlusion_above_surface, occlusion_above_replica);
3506
3507       EXPECT_EQ(expected_opaque_region.ToString(),
3508                 occlusion.occlusion_from_inside_target().ToString());
3509       EXPECT_EQ(gfx::Rect().ToString(),
3510                 occlusion.occlusion_from_outside_target().ToString());
3511     }
3512   }
3513 };
3514
3515 ALL_OCCLUSIONTRACKER_TEST(
3516     OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
3517
3518 template <class Types>
3519 class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
3520     : public OcclusionTrackerTest<Types> {
3521  protected:
3522   explicit
3523   OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
3524       bool opaque_layers)
3525       : OcclusionTrackerTest<Types>(opaque_layers) {}
3526   void RunMyTest() {
3527     gfx::Transform scale_by_half;
3528     scale_by_half.Scale(0.5, 0.5);
3529
3530     // Make a surface and its replica, each 50x50, that are partially occluded
3531     // by opaque layers which are above them in the z-order.  The surface is
3532     // scaled to test that the pixel moving is done in the target space, where
3533     // the background filter is applied, but the surface appears at 50, 50 and
3534     // the replica at 200, 50.
3535     typename Types::ContentLayerType* parent = this->CreateRoot(
3536         this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
3537     typename Types::LayerType* filtered_surface =
3538         this->CreateDrawingLayer(parent,
3539                                  scale_by_half,
3540                                  gfx::PointF(50.f, 50.f),
3541                                  gfx::Size(100, 100),
3542                                  false);
3543     this->CreateReplicaLayer(filtered_surface,
3544                              this->identity_matrix,
3545                              gfx::PointF(300.f, 0.f),
3546                              gfx::Size());
3547     typename Types::LayerType* above_surface_layer =
3548         this->CreateDrawingLayer(parent,
3549                                  this->identity_matrix,
3550                                  gfx::PointF(70.f, 50.f),
3551                                  gfx::Size(30, 50),
3552                                  true);
3553     typename Types::LayerType* above_replica_layer =
3554         this->CreateDrawingLayer(parent,
3555                                  this->identity_matrix,
3556                                  gfx::PointF(200.f, 50.f),
3557                                  gfx::Size(30, 50),
3558                                  true);
3559     typename Types::LayerType* beside_surface_layer =
3560         this->CreateDrawingLayer(parent,
3561                                  this->identity_matrix,
3562                                  gfx::PointF(90.f, 40.f),
3563                                  gfx::Size(10, 10),
3564                                  true);
3565     typename Types::LayerType* beside_replica_layer =
3566         this->CreateDrawingLayer(parent,
3567                                  this->identity_matrix,
3568                                  gfx::PointF(200.f, 40.f),
3569                                  gfx::Size(10, 10),
3570                                  true);
3571
3572     // Filters make the layer own a surface.
3573     FilterOperations filters;
3574     filters.Append(FilterOperation::CreateBlurFilter(3.f));
3575     filtered_surface->SetBackgroundFilters(filters);
3576
3577     // Save the distance of influence for the blur effect.
3578     int outset_top, outset_right, outset_bottom, outset_left;
3579     filters.GetOutsets(
3580         &outset_top, &outset_right, &outset_bottom, &outset_left);
3581
3582     this->CalcDrawEtc(parent);
3583
3584     TestOcclusionTrackerWithClip<typename Types::LayerType,
3585                                  typename Types::RenderSurfaceType> occlusion(
3586         gfx::Rect(0, 0, 1000, 1000));
3587
3588     this->VisitLayer(beside_replica_layer, &occlusion);
3589     this->VisitLayer(beside_surface_layer, &occlusion);
3590     this->VisitLayer(above_replica_layer, &occlusion);
3591     this->VisitLayer(above_surface_layer, &occlusion);
3592
3593     // The surface has a background blur, so it blurs non-opaque pixels below
3594     // it.
3595     this->VisitLayer(filtered_surface, &occlusion);
3596     this->VisitContributingSurface(filtered_surface, &occlusion);
3597
3598     // The filter in the surface and replica are partially unoccluded. Only the
3599     // unoccluded parts should reduce occlusion.  This means it will push back
3600     // the occlusion that touches the unoccluded part (occlusion_above___), but
3601     // it will not touch occlusion_beside____ since that is not beside the
3602     // unoccluded part of the surface, even though it is beside the occluded
3603     // part of the surface.
3604     gfx::Rect occlusion_above_surface =
3605         gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
3606     gfx::Rect occlusion_above_replica =
3607         gfx::Rect(200, 50, 30 - outset_left, 50);
3608     gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
3609     gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);
3610
3611     Region expected_occlusion;
3612     expected_occlusion.Union(occlusion_above_surface);
3613     expected_occlusion.Union(occlusion_above_replica);
3614     expected_occlusion.Union(occlusion_beside_surface);
3615     expected_occlusion.Union(occlusion_beside_replica);
3616
3617     ASSERT_EQ(expected_occlusion.ToString(),
3618               occlusion.occlusion_from_inside_target().ToString());
3619     EXPECT_EQ(gfx::Rect().ToString(),
3620               occlusion.occlusion_from_outside_target().ToString());
3621
3622     Region::Iterator expected_rects(expected_occlusion);
3623     Region::Iterator target_surface_rects(
3624         occlusion.occlusion_from_inside_target());
3625     for (; expected_rects.has_rect();
3626          expected_rects.next(), target_surface_rects.next()) {
3627       ASSERT_TRUE(target_surface_rects.has_rect());
3628       EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
3629     }
3630   }
3631 };
3632
3633 ALL_OCCLUSIONTRACKER_TEST(
3634     OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
3635
3636 template <class Types>
3637 class OcclusionTrackerTestMinimumTrackingSize
3638     : public OcclusionTrackerTest<Types> {
3639  protected:
3640   explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
3641       : OcclusionTrackerTest<Types>(opaque_layers) {}
3642   void RunMyTest() {
3643     gfx::Size tracking_size(100, 100);
3644     gfx::Size below_tracking_size(99, 99);
3645
3646     typename Types::ContentLayerType* parent = this->CreateRoot(
3647         this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3648     typename Types::LayerType* large = this->CreateDrawingLayer(
3649         parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
3650     typename Types::LayerType* small =
3651         this->CreateDrawingLayer(parent,
3652                                  this->identity_matrix,
3653                                  gfx::PointF(),
3654                                  below_tracking_size,
3655                                  true);
3656     this->CalcDrawEtc(parent);
3657
3658     TestOcclusionTrackerWithClip<typename Types::LayerType,
3659                                  typename Types::RenderSurfaceType> occlusion(
3660         gfx::Rect(0, 0, 1000, 1000));
3661     occlusion.set_minimum_tracking_size(tracking_size);
3662
3663     // The small layer is not tracked because it is too small.
3664     this->VisitLayer(small, &occlusion);
3665
3666     EXPECT_EQ(gfx::Rect().ToString(),
3667               occlusion.occlusion_from_outside_target().ToString());
3668     EXPECT_EQ(gfx::Rect().ToString(),
3669               occlusion.occlusion_from_inside_target().ToString());
3670
3671     // The large layer is tracked as it is large enough.
3672     this->VisitLayer(large, &occlusion);
3673
3674     EXPECT_EQ(gfx::Rect().ToString(),
3675               occlusion.occlusion_from_outside_target().ToString());
3676     EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
3677               occlusion.occlusion_from_inside_target().ToString());
3678   }
3679 };
3680
3681 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
3682
3683 template <class Types>
3684 class OcclusionTrackerTestPreventOcclusionOnLayer
3685     : public OcclusionTrackerTest<Types> {
3686  protected:
3687   explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers)
3688       : OcclusionTrackerTest<Types>(opaque_layers) {}
3689   void RunMyTest() {
3690     typename Types::ContentLayerType* parent = this->CreateRoot(
3691         this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3692     typename Types::LayerType* unprevented = this->CreateDrawingLayer(
3693         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3694     typename Types::LayerType* prevented = this->CreateDrawingLayer(
3695         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3696     typename Types::LayerType* occluding = this->CreateDrawingLayer(
3697         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
3698     this->CalcDrawEtc(parent);
3699
3700     TestOcclusionTrackerWithClip<typename Types::LayerType,
3701                                  typename Types::RenderSurfaceType> occlusion(
3702         gfx::Rect(0, 0, 1000, 1000));
3703
3704     this->VisitLayer(occluding, &occlusion);
3705     this->EnterLayer(prevented, &occlusion, true);
3706
3707     // This layer is not occluded because it is prevented.
3708     EXPECT_FALSE(occlusion.OccludedLayer(prevented,
3709                                          gfx::Rect(50, 50)));
3710
3711     EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3712               occlusion.UnoccludedLayerContentRect(
3713                   prevented,
3714                   gfx::Rect(50, 50)).ToString());
3715
3716     this->LeaveLayer(prevented, &occlusion);
3717     this->EnterLayer(unprevented, &occlusion, false);
3718
3719     // This layer is fully occluded.
3720     EXPECT_TRUE(occlusion.OccludedLayer(unprevented,
3721                                         gfx::Rect(50, 50)));
3722
3723     EXPECT_EQ(gfx::Rect().ToString(),
3724               occlusion.UnoccludedLayerContentRect(
3725                   unprevented,
3726                   gfx::Rect(50, 50)).ToString());
3727
3728     this->LeaveLayer(unprevented, &occlusion);
3729   }
3730 };
3731
3732 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer)
3733
3734 template <class Types>
3735 class OcclusionTrackerTestPreventOcclusionOnContributingSurface
3736     : public OcclusionTrackerTest<Types> {
3737  protected:
3738   explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
3739       bool opaque_layers)
3740       : OcclusionTrackerTest<Types>(opaque_layers) {}
3741   void RunMyTest() {
3742     typename Types::ContentLayerType* parent = this->CreateRoot(
3743         this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3744     typename Types::LayerType* unprevented = this->CreateDrawingSurface(
3745         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3746     typename Types::LayerType* prevented = this->CreateDrawingSurface(
3747         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
3748     typename Types::LayerType* occluding = this->CreateDrawingLayer(
3749         parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
3750     this->CalcDrawEtc(parent);
3751
3752     TestOcclusionTrackerWithClip<typename Types::LayerType,
3753                                  typename Types::RenderSurfaceType> occlusion(
3754         gfx::Rect(0, 0, 1000, 1000));
3755
3756     this->VisitLayer(occluding, &occlusion);
3757     this->EnterLayer(prevented, &occlusion, true);
3758
3759     // This layer is not occluded because it is prevented.
3760     EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3761               occlusion.UnoccludedLayerContentRect(
3762                   prevented,
3763                   gfx::Rect(50, 50)).ToString());
3764
3765     this->LeaveLayer(prevented, &occlusion);
3766     this->EnterContributingSurface(prevented, &occlusion, true);
3767
3768     // This contributing surface is not occluded because it is prevented.
3769     EXPECT_EQ(gfx::Rect(50, 50).ToString(),
3770               occlusion.UnoccludedContributingSurfaceContentRect(
3771                   prevented,
3772                   false,  // is_replica
3773                   gfx::Rect(50, 50)).ToString());
3774
3775     this->LeaveContributingSurface(prevented, &occlusion);
3776     this->EnterLayer(unprevented, &occlusion, false);
3777
3778     // This layer is fully occluded from outside its surface.
3779     EXPECT_EQ(gfx::Rect().ToString(),
3780               occlusion.UnoccludedLayerContentRect(
3781                   unprevented,
3782                   gfx::Rect(50, 50)).ToString());
3783
3784     this->LeaveLayer(unprevented, &occlusion);
3785     this->EnterContributingSurface(unprevented, &occlusion, false);
3786
3787     // This contributing surface is fully occluded.
3788     EXPECT_EQ(gfx::Rect().ToString(),
3789               occlusion.UnoccludedContributingSurfaceContentRect(
3790                   unprevented,
3791                   false,  // is_replica
3792                   gfx::Rect(50, 50)).ToString());
3793
3794     this->LeaveContributingSurface(unprevented, &occlusion);
3795   }
3796 };
3797
3798 ALL_OCCLUSIONTRACKER_TEST(
3799     OcclusionTrackerTestPreventOcclusionOnContributingSurface)
3800
3801 template <class Types>
3802 class OcclusionTrackerTestScaledLayerIsClipped
3803     : public OcclusionTrackerTest<Types> {
3804  protected:
3805   explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
3806       : OcclusionTrackerTest<Types>(opaque_layers) {}
3807   void RunMyTest() {
3808     gfx::Transform scale_transform;
3809     scale_transform.Scale(512.0, 512.0);
3810
3811     typename Types::ContentLayerType* parent = this->CreateRoot(
3812         this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3813     typename Types::LayerType* clip = this->CreateLayer(parent,
3814                                                         this->identity_matrix,
3815                                                         gfx::PointF(10.f, 10.f),
3816                                                         gfx::Size(50, 50));
3817     clip->SetMasksToBounds(true);
3818     typename Types::LayerType* scale = this->CreateLayer(
3819         clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3820     typename Types::LayerType* scaled = this->CreateDrawingLayer(
3821         scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3822     this->CalcDrawEtc(parent);
3823
3824     TestOcclusionTrackerWithClip<typename Types::LayerType,
3825                                  typename Types::RenderSurfaceType> occlusion(
3826         gfx::Rect(0, 0, 1000, 1000));
3827
3828     this->VisitLayer(scaled, &occlusion);
3829
3830     EXPECT_EQ(gfx::Rect().ToString(),
3831               occlusion.occlusion_from_outside_target().ToString());
3832     EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3833               occlusion.occlusion_from_inside_target().ToString());
3834   }
3835 };
3836
3837 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
3838
3839 template <class Types>
3840 class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
3841     : public OcclusionTrackerTest<Types> {
3842  protected:
3843   explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
3844       : OcclusionTrackerTest<Types>(opaque_layers) {}
3845   void RunMyTest() {
3846     gfx::Transform scale_transform;
3847     scale_transform.Scale(512.0, 512.0);
3848
3849     typename Types::ContentLayerType* parent = this->CreateRoot(
3850         this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
3851     typename Types::LayerType* clip = this->CreateLayer(parent,
3852                                                         this->identity_matrix,
3853                                                         gfx::PointF(10.f, 10.f),
3854                                                         gfx::Size(50, 50));
3855     clip->SetMasksToBounds(true);
3856     typename Types::LayerType* surface = this->CreateDrawingSurface(
3857         clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
3858     typename Types::LayerType* scale = this->CreateLayer(
3859         surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
3860     typename Types::LayerType* scaled = this->CreateDrawingLayer(
3861         scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
3862     this->CalcDrawEtc(parent);
3863
3864     TestOcclusionTrackerWithClip<typename Types::LayerType,
3865                                  typename Types::RenderSurfaceType> occlusion(
3866         gfx::Rect(0, 0, 1000, 1000));
3867
3868     this->VisitLayer(scaled, &occlusion);
3869     this->VisitLayer(surface, &occlusion);
3870     this->VisitContributingSurface(surface, &occlusion);
3871
3872     EXPECT_EQ(gfx::Rect().ToString(),
3873               occlusion.occlusion_from_outside_target().ToString());
3874     EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
3875               occlusion.occlusion_from_inside_target().ToString());
3876   }
3877 };
3878
3879 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
3880
3881 template <class Types>
3882 class OcclusionTrackerTestCopyRequestDoesOcclude
3883     : public OcclusionTrackerTest<Types> {
3884  protected:
3885   explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
3886       : OcclusionTrackerTest<Types>(opaque_layers) {}
3887   void RunMyTest() {
3888     typename Types::ContentLayerType* root = this->CreateRoot(
3889         this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3890     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3891         root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3892     typename Types::LayerType* copy = this->CreateLayer(parent,
3893                                                         this->identity_matrix,
3894                                                         gfx::Point(100, 0),
3895                                                         gfx::Size(200, 400));
3896     this->AddCopyRequest(copy);
3897     typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3898         copy,
3899         this->identity_matrix,
3900         gfx::PointF(),
3901         gfx::Size(200, 400),
3902         true);
3903     this->CalcDrawEtc(root);
3904
3905     TestOcclusionTrackerWithClip<typename Types::LayerType,
3906                                  typename Types::RenderSurfaceType> occlusion(
3907         gfx::Rect(0, 0, 1000, 1000));
3908
3909     this->VisitLayer(copy_child, &occlusion);
3910     EXPECT_EQ(gfx::Rect().ToString(),
3911               occlusion.occlusion_from_outside_target().ToString());
3912     EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3913               occlusion.occlusion_from_inside_target().ToString());
3914
3915     // CopyRequests cause the layer to own a surface.
3916     this->VisitContributingSurface(copy, &occlusion);
3917
3918     // The occlusion from the copy should be kept.
3919     EXPECT_EQ(gfx::Rect().ToString(),
3920               occlusion.occlusion_from_outside_target().ToString());
3921     EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
3922               occlusion.occlusion_from_inside_target().ToString());
3923   }
3924 };
3925
3926 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
3927
3928 template <class Types>
3929 class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
3930     : public OcclusionTrackerTest<Types> {
3931  protected:
3932   explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
3933       bool opaque_layers)
3934       : OcclusionTrackerTest<Types>(opaque_layers) {}
3935   void RunMyTest() {
3936     typename Types::ContentLayerType* root = this->CreateRoot(
3937         this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3938     typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
3939         root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
3940     typename Types::LayerType* hide = this->CreateLayer(
3941         parent, this->identity_matrix, gfx::Point(), gfx::Size());
3942     typename Types::LayerType* copy = this->CreateLayer(
3943         hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
3944     this->AddCopyRequest(copy);
3945     typename Types::LayerType* copy_child = this->CreateDrawingLayer(
3946         copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
3947
3948     // The |copy| layer is hidden but since it is being copied, it will be
3949     // drawn.
3950     hide->SetHideLayerAndSubtree(true);
3951
3952     this->CalcDrawEtc(root);
3953
3954     TestOcclusionTrackerWithClip<typename Types::LayerType,
3955                                  typename Types::RenderSurfaceType> occlusion(
3956         gfx::Rect(0, 0, 1000, 1000));
3957
3958     this->VisitLayer(copy_child, &occlusion);
3959     EXPECT_EQ(gfx::Rect().ToString(),
3960               occlusion.occlusion_from_outside_target().ToString());
3961     EXPECT_EQ(gfx::Rect(200, 400).ToString(),
3962               occlusion.occlusion_from_inside_target().ToString());
3963
3964     // CopyRequests cause the layer to own a surface.
3965     this->VisitContributingSurface(copy, &occlusion);
3966
3967     // The occlusion from the copy should be dropped since it is hidden.
3968     EXPECT_EQ(gfx::Rect().ToString(),
3969               occlusion.occlusion_from_outside_target().ToString());
3970     EXPECT_EQ(gfx::Rect().ToString(),
3971               occlusion.occlusion_from_inside_target().ToString());
3972   }
3973 };
3974
3975 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
3976
3977 template <class Types>
3978 class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
3979     : public OcclusionTrackerTest<Types> {
3980  protected:
3981   explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
3982       bool opaque_layers)
3983       : OcclusionTrackerTest<Types>(opaque_layers) {}
3984   void RunMyTest() {
3985     typename Types::ContentLayerType* root = this->CreateRoot(
3986         this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
3987     typename Types::ContentLayerType* empty_layer = this->CreateDrawingLayer(
3988         root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), true);
3989     this->SetDrawsContent(empty_layer, false);
3990     empty_layer->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
3991
3992     this->CalcDrawEtc(root);
3993
3994     TestOcclusionTrackerWithClip<typename Types::LayerType,
3995                                  typename Types::RenderSurfaceType> occlusion(
3996         gfx::Rect(0, 0, 1000, 1000), false);
3997
3998     this->VisitLayer(empty_layer, &occlusion);
3999
4000     EXPECT_EQ(gfx::Rect().ToString(),
4001               occlusion.occlusion_from_outside_target().ToString());
4002     EXPECT_EQ(gfx::Rect().ToString(),
4003               occlusion.occlusion_from_inside_target().ToString());
4004   }
4005 };
4006
4007 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude)
4008
4009 }  // namespace
4010 }  // namespace cc