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/layer_tree_host.h"
      6 
      7 #include "cc/layers/layer.h"
      8 #include "cc/output/copy_output_request.h"
      9 #include "cc/output/copy_output_result.h"
     10 #include "cc/test/layer_tree_test.h"
     11 #include "cc/test/occlusion_tracker_test_common.h"
     12 
     13 namespace cc {
     14 namespace {
     15 
     16 class TestLayer : public Layer {
     17  public:
     18   static scoped_refptr<TestLayer> Create() {
     19     return make_scoped_refptr(new TestLayer());
     20   }
     21 
     22   virtual bool Update(
     23       ResourceUpdateQueue* update_queue,
     24       const OcclusionTracker* occlusion) OVERRIDE {
     25     if (!occlusion)
     26       return false;
     27 
     28     // Gain access to internals of the OcclusionTracker.
     29     const TestOcclusionTracker* test_occlusion =
     30         static_cast<const TestOcclusionTracker*>(occlusion);
     31     occlusion_ = UnionRegions(
     32         test_occlusion->occlusion_from_inside_target(),
     33         test_occlusion->occlusion_from_outside_target());
     34     return false;
     35   }
     36 
     37   const Region& occlusion() const { return occlusion_; }
     38   const Region& expected_occlusion() const { return expected_occlusion_; }
     39   void set_expected_occlusion(const Region& occlusion) {
     40     expected_occlusion_ = occlusion;
     41   }
     42 
     43  private:
     44   TestLayer() : Layer() {
     45     SetIsDrawable(true);
     46   }
     47   virtual ~TestLayer() {}
     48 
     49   Region occlusion_;
     50   Region expected_occlusion_;
     51 };
     52 
     53 class LayerTreeHostOcclusionTest : public LayerTreeTest {
     54  public:
     55   LayerTreeHostOcclusionTest()
     56       : root_(TestLayer::Create()),
     57         child_(TestLayer::Create()),
     58         child2_(TestLayer::Create()),
     59         grand_child_(TestLayer::Create()),
     60         mask_(TestLayer::Create()) {
     61   }
     62 
     63   virtual void BeginTest() OVERRIDE {
     64     PostSetNeedsCommitToMainThread();
     65   }
     66 
     67   virtual void DidCommit() OVERRIDE {
     68     TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer());
     69     VerifyOcclusion(root);
     70 
     71     EndTest();
     72   }
     73 
     74   virtual void AfterTest() OVERRIDE {}
     75 
     76   void VerifyOcclusion(TestLayer* layer) const {
     77     EXPECT_EQ(layer->expected_occlusion().ToString(),
     78               layer->occlusion().ToString());
     79 
     80     for (size_t i = 0; i < layer->children().size(); ++i) {
     81       TestLayer* child = static_cast<TestLayer*>(layer->children()[i].get());
     82       VerifyOcclusion(child);
     83     }
     84   }
     85 
     86   void SetLayerPropertiesForTesting(TestLayer* layer,
     87                                     TestLayer* parent,
     88                                     const gfx::Transform& transform,
     89                                     gfx::PointF position,
     90                                     gfx::Size bounds,
     91                                     bool opaque) const {
     92     layer->RemoveAllChildren();
     93     if (parent)
     94       parent->AddChild(layer);
     95     layer->SetTransform(transform);
     96     layer->SetPosition(position);
     97     layer->SetBounds(bounds);
     98     layer->SetContentsOpaque(opaque);
     99 
    100     layer->SetAnchorPoint(gfx::PointF());
    101   }
    102 
    103  protected:
    104   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
    105     settings->minimum_occlusion_tracking_size = gfx::Size();
    106   }
    107 
    108   scoped_refptr<TestLayer> root_;
    109   scoped_refptr<TestLayer> child_;
    110   scoped_refptr<TestLayer> child2_;
    111   scoped_refptr<TestLayer> grand_child_;
    112   scoped_refptr<TestLayer> mask_;
    113 
    114   gfx::Transform identity_matrix_;
    115 };
    116 
    117 
    118 class LayerTreeHostOcclusionTestOcclusionSurfaceClipping
    119     : public LayerTreeHostOcclusionTest {
    120  public:
    121   virtual void SetupTree() OVERRIDE {
    122     // The child layer is a surface and the grand_child is opaque, but clipped
    123     // to the child and root
    124     SetLayerPropertiesForTesting(
    125         root_.get(), NULL, identity_matrix_,
    126         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    127     SetLayerPropertiesForTesting(
    128         child_.get(), root_.get(), identity_matrix_,
    129         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
    130     SetLayerPropertiesForTesting(
    131         grand_child_.get(), child_.get(), identity_matrix_,
    132         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    133 
    134     child_->SetMasksToBounds(true);
    135     child_->SetForceRenderSurface(true);
    136 
    137     child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    138     root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190));
    139 
    140     layer_tree_host()->SetRootLayer(root_);
    141     LayerTreeTest::SetupTree();
    142   }
    143 };
    144 
    145 SINGLE_AND_MULTI_THREAD_TEST_F(
    146     LayerTreeHostOcclusionTestOcclusionSurfaceClipping);
    147 
    148 class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque
    149     : public LayerTreeHostOcclusionTest {
    150  public:
    151   virtual void SetupTree() OVERRIDE {
    152     // If the child layer is opaque, then it adds to the occlusion seen by the
    153     // root_.
    154     SetLayerPropertiesForTesting(
    155         root_.get(), NULL, identity_matrix_,
    156         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    157     SetLayerPropertiesForTesting(
    158         child_.get(), root_.get(), identity_matrix_,
    159         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    160     SetLayerPropertiesForTesting(
    161         grand_child_.get(), child_.get(), identity_matrix_,
    162         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    163 
    164     child_->SetMasksToBounds(true);
    165     child_->SetForceRenderSurface(true);
    166 
    167     child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    168     root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
    169 
    170     layer_tree_host()->SetRootLayer(root_);
    171     LayerTreeTest::SetupTree();
    172   }
    173 };
    174 
    175 SINGLE_AND_MULTI_THREAD_TEST_F(
    176     LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque);
    177 
    178 class LayerTreeHostOcclusionTestOcclusionTwoChildren
    179     : public LayerTreeHostOcclusionTest {
    180  public:
    181   virtual void SetupTree() OVERRIDE {
    182     // Add a second child to the root layer and the regions should merge
    183     SetLayerPropertiesForTesting(
    184         root_.get(), NULL, identity_matrix_,
    185         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    186     SetLayerPropertiesForTesting(
    187         child_.get(), root_.get(), identity_matrix_,
    188         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
    189     SetLayerPropertiesForTesting(
    190         grand_child_.get(), child_.get(), identity_matrix_,
    191         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    192     SetLayerPropertiesForTesting(
    193         child2_.get(), root_.get(), identity_matrix_,
    194         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    195 
    196     child_->SetMasksToBounds(true);
    197     child_->SetForceRenderSurface(true);
    198 
    199     grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    200     child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    201     root_->set_expected_occlusion(gfx::Rect(10, 10, 20, 190));
    202 
    203     layer_tree_host()->SetRootLayer(root_);
    204     LayerTreeTest::SetupTree();
    205   }
    206 };
    207 
    208 SINGLE_AND_MULTI_THREAD_TEST_F(
    209     LayerTreeHostOcclusionTestOcclusionTwoChildren);
    210 
    211 class LayerTreeHostOcclusionTestOcclusionMask
    212     : public LayerTreeHostOcclusionTest {
    213  public:
    214   virtual void SetupTree() OVERRIDE {
    215     // If the child layer has a mask on it, then it shouldn't contribute to
    216     // occlusion on stuff below it.
    217     SetLayerPropertiesForTesting(
    218         root_.get(), NULL, identity_matrix_,
    219         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    220     SetLayerPropertiesForTesting(
    221         child2_.get(), root_.get(), identity_matrix_,
    222         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    223     SetLayerPropertiesForTesting(
    224         child_.get(), root_.get(), identity_matrix_,
    225         gfx::PointF(20.f, 20.f), gfx::Size(500, 500), true);
    226     SetLayerPropertiesForTesting(
    227         grand_child_.get(), child_.get(), identity_matrix_,
    228         gfx::PointF(-10.f, -10.f), gfx::Size(500, 500), true);
    229 
    230     child_->SetMasksToBounds(true);
    231     child_->SetForceRenderSurface(true);
    232     child_->SetMaskLayer(mask_.get());
    233 
    234     child_->set_expected_occlusion(gfx::Rect(0, 0, 180, 180));
    235     root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));
    236 
    237     layer_tree_host()->SetRootLayer(root_);
    238     LayerTreeTest::SetupTree();
    239   }
    240 };
    241 
    242 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask);
    243 
    244 class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion
    245     : public LayerTreeHostOcclusionTest {
    246  public:
    247   virtual void SetupTree() OVERRIDE {
    248     // If the child layer with a mask is below child2, then child2 should
    249     // contribute to occlusion on everything, and child shouldn't contribute
    250     // to the root_.
    251     SetLayerPropertiesForTesting(
    252         root_.get(), NULL, identity_matrix_,
    253         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    254     SetLayerPropertiesForTesting(
    255         child_.get(), root_.get(), identity_matrix_,
    256         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    257     SetLayerPropertiesForTesting(
    258         grand_child_.get(), child_.get(), identity_matrix_,
    259         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    260     SetLayerPropertiesForTesting(
    261         child2_.get(), root_.get(), identity_matrix_,
    262         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    263 
    264     child_->SetMasksToBounds(true);
    265     child_->SetForceRenderSurface(true);
    266     child_->SetMaskLayer(mask_.get());
    267 
    268     grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    269     child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    270     root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
    271 
    272     layer_tree_host()->SetRootLayer(root_);
    273     LayerTreeTest::SetupTree();
    274   }
    275 };
    276 
    277 SINGLE_AND_MULTI_THREAD_TEST_F(
    278     LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion);
    279 
    280 class LayerTreeHostOcclusionTestOcclusionOpacity
    281     : public LayerTreeHostOcclusionTest {
    282  public:
    283   virtual void SetupTree() OVERRIDE {
    284     // If the child layer has a non-opaque opacity, then it shouldn't
    285     // contribute to occlusion on stuff below it
    286     SetLayerPropertiesForTesting(
    287         root_.get(), NULL, identity_matrix_,
    288         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    289     SetLayerPropertiesForTesting(
    290         child2_.get(), root_.get(), identity_matrix_,
    291         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    292     SetLayerPropertiesForTesting(
    293         child_.get(), root_.get(), identity_matrix_,
    294         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    295     SetLayerPropertiesForTesting(
    296         grand_child_.get(), child_.get(), identity_matrix_,
    297         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    298 
    299     child_->SetMasksToBounds(true);
    300     child_->SetForceRenderSurface(true);
    301     child_->SetOpacity(0.5f);
    302 
    303     child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    304     root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
    305 
    306     layer_tree_host()->SetRootLayer(root_);
    307     LayerTreeTest::SetupTree();
    308   }
    309 };
    310 
    311 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity);
    312 
    313 class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion
    314     : public LayerTreeHostOcclusionTest {
    315  public:
    316   virtual void SetupTree() OVERRIDE {
    317     // If the child layer with non-opaque opacity is below child2, then
    318     // child2 should contribute to occlusion on everything, and child shouldn't
    319     // contribute to the root_.
    320     SetLayerPropertiesForTesting(
    321         root_.get(), NULL, identity_matrix_,
    322         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    323     SetLayerPropertiesForTesting(
    324         child_.get(), root_.get(), identity_matrix_,
    325         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    326     SetLayerPropertiesForTesting(
    327         grand_child_.get(), child_.get(), identity_matrix_,
    328         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    329     SetLayerPropertiesForTesting(
    330         child2_.get(), root_.get(), identity_matrix_,
    331         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    332 
    333     child_->SetMasksToBounds(true);
    334     child_->SetForceRenderSurface(true);
    335     child_->SetOpacity(0.5f);
    336 
    337     grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    338     child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    339     root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
    340 
    341     layer_tree_host()->SetRootLayer(root_);
    342     LayerTreeTest::SetupTree();
    343   }
    344 };
    345 
    346 SINGLE_AND_MULTI_THREAD_TEST_F(
    347     LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion);
    348 
    349 class LayerTreeHostOcclusionTestOcclusionBlending
    350     : public LayerTreeHostOcclusionTest {
    351  public:
    352   virtual void SetupTree() OVERRIDE {
    353     // If the child layer has a blend mode, then it shouldn't
    354     // contribute to occlusion on stuff below it
    355     SetLayerPropertiesForTesting(
    356         root_.get(), NULL, identity_matrix_,
    357         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    358     SetLayerPropertiesForTesting(
    359         child2_.get(), root_.get(), identity_matrix_,
    360         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    361     SetLayerPropertiesForTesting(
    362         child_.get(), root_.get(), identity_matrix_,
    363         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    364     SetLayerPropertiesForTesting(
    365         grand_child_.get(), child_.get(), identity_matrix_,
    366         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    367 
    368     child_->SetMasksToBounds(true);
    369     child_->SetBlendMode(SkXfermode::kMultiply_Mode);
    370     child_->SetForceRenderSurface(true);
    371 
    372     child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    373     root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
    374 
    375     layer_tree_host()->SetRootLayer(root_);
    376     LayerTreeTest::SetupTree();
    377   }
    378 };
    379 
    380 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionBlending);
    381 
    382 class LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion
    383     : public LayerTreeHostOcclusionTest {
    384  public:
    385   virtual void SetupTree() OVERRIDE {
    386     // If the child layer with a blend mode is below child2, then
    387     // child2 should contribute to occlusion on everything, and child shouldn't
    388     // contribute to the root_.
    389     SetLayerPropertiesForTesting(
    390         root_.get(), NULL, identity_matrix_,
    391         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    392     SetLayerPropertiesForTesting(
    393         child_.get(), root_.get(), identity_matrix_,
    394         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    395     SetLayerPropertiesForTesting(
    396         grand_child_.get(), child_.get(), identity_matrix_,
    397         gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    398     SetLayerPropertiesForTesting(
    399         child2_.get(), root_.get(), identity_matrix_,
    400         gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    401 
    402     child_->SetMasksToBounds(true);
    403     child_->SetBlendMode(SkXfermode::kMultiply_Mode);
    404 
    405     grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    406     child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    407     root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));
    408 
    409     layer_tree_host()->SetRootLayer(root_);
    410     LayerTreeTest::SetupTree();
    411   }
    412 };
    413 
    414 SINGLE_AND_MULTI_THREAD_TEST_F(
    415     LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion);
    416 
    417 class LayerTreeHostOcclusionTestOcclusionOpacityFilter
    418     : public LayerTreeHostOcclusionTest {
    419  public:
    420   virtual void SetupTree() OVERRIDE {
    421     gfx::Transform child_transform;
    422     child_transform.Translate(250.0, 250.0);
    423     child_transform.Rotate(90.0);
    424     child_transform.Translate(-250.0, -250.0);
    425 
    426     FilterOperations filters;
    427     filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
    428 
    429     // If the child layer has a filter that changes alpha values, and is below
    430     // child2, then child2 should contribute to occlusion on everything,
    431     // and child shouldn't contribute to the root
    432     SetLayerPropertiesForTesting(
    433         root_.get(), NULL, identity_matrix_,
    434         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    435     SetLayerPropertiesForTesting(
    436         child_.get(), root_.get(), child_transform,
    437         gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
    438     SetLayerPropertiesForTesting(
    439         grand_child_.get(), child_.get(), identity_matrix_,
    440         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    441     SetLayerPropertiesForTesting(
    442         child2_.get(), root_.get(), identity_matrix_,
    443         gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);
    444 
    445     child_->SetMasksToBounds(true);
    446     child_->SetFilters(filters);
    447 
    448     grand_child_->set_expected_occlusion(gfx::Rect(40, 330, 130, 190));
    449     child_->set_expected_occlusion(UnionRegions(
    450         gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20)));
    451     root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));
    452 
    453     layer_tree_host()->SetRootLayer(root_);
    454     LayerTreeTest::SetupTree();
    455   }
    456 };
    457 
    458 SINGLE_AND_MULTI_THREAD_TEST_F(
    459     LayerTreeHostOcclusionTestOcclusionOpacityFilter);
    460 
    461 class LayerTreeHostOcclusionTestOcclusionBlurFilter
    462     : public LayerTreeHostOcclusionTest {
    463  public:
    464   virtual void SetupTree() OVERRIDE {
    465     gfx::Transform child_transform;
    466     child_transform.Translate(250.0, 250.0);
    467     child_transform.Rotate(90.0);
    468     child_transform.Translate(-250.0, -250.0);
    469 
    470     FilterOperations filters;
    471     filters.Append(FilterOperation::CreateBlurFilter(10.f));
    472 
    473     // If the child layer has a filter that moves pixels/changes alpha, and is
    474     // below child2, then child should not inherit occlusion from outside its
    475     // subtree, and should not contribute to the root
    476     SetLayerPropertiesForTesting(
    477         root_.get(), NULL, identity_matrix_,
    478         gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    479     SetLayerPropertiesForTesting(
    480         child_.get(), root_.get(), child_transform,
    481         gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
    482     SetLayerPropertiesForTesting(
    483         grand_child_.get(), child_.get(), identity_matrix_,
    484         gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    485     SetLayerPropertiesForTesting(
    486         child2_.get(), root_.get(), identity_matrix_,
    487         gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);
    488 
    489     child_->SetMasksToBounds(true);
    490     child_->SetFilters(filters);
    491 
    492     child_->set_expected_occlusion(gfx::Rect(10, 330, 160, 170));
    493     root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));
    494 
    495     layer_tree_host()->SetRootLayer(root_);
    496     LayerTreeTest::SetupTree();
    497   }
    498 };
    499 
    500 SINGLE_AND_MULTI_THREAD_TEST_F(
    501     LayerTreeHostOcclusionTestOcclusionBlurFilter);
    502 
    503 class LayerTreeHostOcclusionTestOcclusionCopyRequest
    504     : public LayerTreeHostOcclusionTest {
    505  public:
    506   static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
    507 
    508   virtual void SetupTree() OVERRIDE {
    509     // If the child layer has copy request, and is below child2,
    510     // then child should not inherit occlusion from outside its subtree.
    511     // The child layer will still receive occlusion from inside, and
    512     // the root layer will recive occlusion from child.
    513     SetLayerPropertiesForTesting(
    514         root_.get(), NULL, identity_matrix_,
    515         gfx::PointF(), gfx::Size(100, 100), true);
    516     SetLayerPropertiesForTesting(
    517         child_.get(), root_.get(), identity_matrix_,
    518         gfx::PointF(), gfx::Size(75, 75), true);
    519     SetLayerPropertiesForTesting(
    520         grand_child_.get(), child_.get(), identity_matrix_,
    521         gfx::PointF(), gfx::Size(75, 50), true);
    522     SetLayerPropertiesForTesting(
    523         child2_.get(), root_.get(), identity_matrix_,
    524         gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);
    525 
    526     child_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
    527         base::Bind(&CopyOutputCallback)));
    528     EXPECT_TRUE(child_->HasCopyRequest());
    529 
    530     child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
    531     root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));
    532 
    533     layer_tree_host()->SetRootLayer(root_);
    534     LayerTreeTest::SetupTree();
    535   }
    536 };
    537 
    538 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionCopyRequest);
    539 
    540 class LayerTreeHostOcclusionTestOcclusionReplica
    541     : public LayerTreeHostOcclusionTest {
    542  public:
    543   virtual void SetupTree() OVERRIDE {
    544     // If the child layer has copy request, and is below child2,
    545     // then child should not inherit occlusion from outside its subtree.
    546     // The child layer will still receive occlusion from inside, and
    547     // the root layer will recive occlusion from child.
    548     SetLayerPropertiesForTesting(
    549         root_.get(), NULL, identity_matrix_,
    550         gfx::PointF(), gfx::Size(100, 100), true);
    551     SetLayerPropertiesForTesting(
    552         child_.get(), root_.get(), identity_matrix_,
    553         gfx::PointF(), gfx::Size(75, 75), true);
    554     SetLayerPropertiesForTesting(
    555         grand_child_.get(), child_.get(), identity_matrix_,
    556         gfx::PointF(), gfx::Size(75, 50), true);
    557     SetLayerPropertiesForTesting(
    558         child2_.get(), root_.get(), identity_matrix_,
    559         gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);
    560 
    561     scoped_refptr<Layer> replica_layer(Layer::Create());
    562     child_->SetReplicaLayer(replica_layer.get());
    563     EXPECT_TRUE(child_->has_replica());
    564 
    565     child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
    566     root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));
    567 
    568     layer_tree_host()->SetRootLayer(root_);
    569     LayerTreeTest::SetupTree();
    570   }
    571 };
    572 
    573 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionReplica);
    574 
    575 class LayerTreeHostOcclusionTestManySurfaces
    576     : public LayerTreeHostOcclusionTest {
    577  public:
    578   virtual void SetupTree() OVERRIDE {
    579     // We create enough RenderSurfaces that it will trigger Vector reallocation
    580     // while computing occlusion.
    581     std::vector<scoped_refptr<TestLayer> > layers;
    582     int num_surfaces = 200;
    583     int root_width = 400;
    584     int root_height = 400;
    585 
    586     for (int i = 0; i < num_surfaces; ++i) {
    587       layers.push_back(TestLayer::Create());
    588       if (i == 0) {
    589         SetLayerPropertiesForTesting(
    590             layers.back().get(), NULL, identity_matrix_,
    591             gfx::PointF(0.f, 0.f),
    592             gfx::Size(root_width, root_height), true);
    593       } else {
    594         SetLayerPropertiesForTesting(
    595             layers.back().get(), layers[layers.size() - 2].get(),
    596             identity_matrix_,
    597             gfx::PointF(1.f, 1.f),
    598             gfx::Size(root_width-i, root_height-i), true);
    599         layers.back()->SetForceRenderSurface(true);
    600       }
    601     }
    602 
    603     for (int i = 1; i < num_surfaces; ++i) {
    604       scoped_refptr<TestLayer> child = TestLayer::Create();
    605       SetLayerPropertiesForTesting(
    606           child.get(), layers[i].get(), identity_matrix_,
    607           gfx::PointF(0.f, 0.f), gfx::Size(root_width, root_height), false);
    608     }
    609 
    610     for (int i = 0; i < num_surfaces-1; ++i) {
    611       gfx::Rect expected_occlusion(1, 1, root_width-i-1, root_height-i-1);
    612       layers[i]->set_expected_occlusion(expected_occlusion);
    613     }
    614 
    615     layer_tree_host()->SetRootLayer(layers[0]);
    616     LayerTreeTest::SetupTree();
    617   }
    618 };
    619 
    620 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestManySurfaces);
    621 
    622 }  // namespace
    623 }  // namespace cc
    624