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