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