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