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