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