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 "base/memory/weak_ptr.h"
      8 #include "cc/layers/content_layer.h"
      9 #include "cc/layers/layer.h"
     10 #include "cc/layers/layer_impl.h"
     11 #include "cc/test/fake_content_layer_client.h"
     12 #include "cc/test/fake_layer_tree_host_client.h"
     13 #include "cc/test/geometry_test_utils.h"
     14 #include "cc/test/layer_tree_test.h"
     15 #include "cc/trees/layer_tree_impl.h"
     16 #include "ui/gfx/point_conversions.h"
     17 #include "ui/gfx/size_conversions.h"
     18 #include "ui/gfx/vector2d_conversions.h"
     19 
     20 namespace cc {
     21 namespace {
     22 
     23 class LayerTreeHostScrollTest : public LayerTreeTest {};
     24 
     25 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
     26  public:
     27   LayerTreeHostScrollTestScrollSimple()
     28       : initial_scroll_(10, 20),
     29         second_scroll_(40, 5),
     30         scroll_amount_(2, -1),
     31         num_scrolls_(0) {}
     32 
     33   virtual void BeginTest() OVERRIDE {
     34     layer_tree_host()->root_layer()->SetScrollable(true);
     35     layer_tree_host()->root_layer()
     36         ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
     37     layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_);
     38     PostSetNeedsCommitToMainThread();
     39   }
     40 
     41   virtual void Layout() OVERRIDE {
     42     Layer* root = layer_tree_host()->root_layer();
     43     if (!layer_tree_host()->source_frame_number()) {
     44       EXPECT_VECTOR_EQ(initial_scroll_, root->scroll_offset());
     45     } else {
     46       EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_, root->scroll_offset());
     47 
     48       // Pretend like Javascript updated the scroll position itself.
     49       root->SetScrollOffset(second_scroll_);
     50     }
     51   }
     52 
     53   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
     54     LayerImpl* root = impl->active_tree()->root_layer();
     55     EXPECT_VECTOR_EQ(gfx::Vector2d(), root->ScrollDelta());
     56 
     57     root->SetScrollable(true);
     58     root->SetMaxScrollOffset(gfx::Vector2d(100, 100));
     59     root->ScrollBy(scroll_amount_);
     60 
     61     switch (impl->active_tree()->source_frame_number()) {
     62       case 0:
     63         EXPECT_VECTOR_EQ(initial_scroll_, root->scroll_offset());
     64         EXPECT_VECTOR_EQ(scroll_amount_, root->ScrollDelta());
     65         PostSetNeedsCommitToMainThread();
     66         break;
     67       case 1:
     68         EXPECT_VECTOR_EQ(root->scroll_offset(), second_scroll_);
     69         EXPECT_VECTOR_EQ(root->ScrollDelta(), scroll_amount_);
     70         EndTest();
     71         break;
     72     }
     73   }
     74 
     75   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
     76                                    float scale) OVERRIDE {
     77     num_scrolls_++;
     78   }
     79 
     80   virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
     81 
     82  private:
     83   gfx::Vector2d initial_scroll_;
     84   gfx::Vector2d second_scroll_;
     85   gfx::Vector2d scroll_amount_;
     86   int num_scrolls_;
     87 };
     88 
     89 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
     90 
     91 class LayerTreeHostScrollTestScrollMultipleRedraw
     92     : public LayerTreeHostScrollTest {
     93  public:
     94   LayerTreeHostScrollTestScrollMultipleRedraw()
     95       : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
     96 
     97   virtual void BeginTest() OVERRIDE {
     98     layer_tree_host()->root_layer()->SetScrollable(true);
     99     layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_);
    100     layer_tree_host()->root_layer()->SetBounds(gfx::Size(200, 200));
    101     layer_tree_host()->root_layer()
    102         ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    103     PostSetNeedsCommitToMainThread();
    104   }
    105 
    106   virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    107     Layer* root = layer_tree_host()->root_layer();
    108     switch (layer_tree_host()->source_frame_number()) {
    109       case 0:
    110         EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    111         break;
    112       case 1:
    113         EXPECT_VECTOR_EQ(root->scroll_offset(),
    114                          initial_scroll_ + scroll_amount_ + scroll_amount_);
    115       case 2:
    116         EXPECT_VECTOR_EQ(root->scroll_offset(),
    117                          initial_scroll_ + scroll_amount_ + scroll_amount_);
    118         break;
    119     }
    120   }
    121 
    122   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    123     LayerImpl* root = impl->active_tree()->root_layer();
    124     if (impl->active_tree()->source_frame_number() == 0 &&
    125         impl->SourceAnimationFrameNumber() == 1) {
    126       // First draw after first commit.
    127       EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d());
    128       root->ScrollBy(scroll_amount_);
    129       EXPECT_VECTOR_EQ(root->ScrollDelta(), scroll_amount_);
    130 
    131       EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    132       PostSetNeedsRedrawToMainThread();
    133     } else if (impl->active_tree()->source_frame_number() == 0 &&
    134                impl->SourceAnimationFrameNumber() == 2) {
    135       // Second draw after first commit.
    136       EXPECT_EQ(root->ScrollDelta(), scroll_amount_);
    137       root->ScrollBy(scroll_amount_);
    138       EXPECT_VECTOR_EQ(root->ScrollDelta(), scroll_amount_ + scroll_amount_);
    139 
    140       EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    141       PostSetNeedsCommitToMainThread();
    142     } else if (impl->active_tree()->source_frame_number() == 1) {
    143       // Third or later draw after second commit.
    144       EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
    145       EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d());
    146       EXPECT_VECTOR_EQ(root->scroll_offset(),
    147                        initial_scroll_ + scroll_amount_ + scroll_amount_);
    148       EndTest();
    149     }
    150   }
    151 
    152   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
    153                                    float scale) OVERRIDE {
    154     num_scrolls_++;
    155   }
    156 
    157   virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
    158 
    159  private:
    160   gfx::Vector2d initial_scroll_;
    161   gfx::Vector2d scroll_amount_;
    162   int num_scrolls_;
    163 };
    164 
    165 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
    166 
    167 class LayerTreeHostScrollTestScrollAbortedCommit
    168     : public LayerTreeHostScrollTest {
    169  public:
    170   LayerTreeHostScrollTestScrollAbortedCommit()
    171       : initial_scroll_(50, 60),
    172         impl_scroll_(-3, 2),
    173         second_main_scroll_(14, -3),
    174         impl_scale_(2.f),
    175         num_will_begin_main_frames_(0),
    176         num_did_begin_main_frames_(0),
    177         num_will_commits_(0),
    178         num_did_commits_(0),
    179         num_impl_commits_(0),
    180         num_impl_scrolls_(0) {}
    181 
    182   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
    183 
    184   virtual void SetupTree() OVERRIDE {
    185     LayerTreeHostScrollTest::SetupTree();
    186     scoped_refptr<Layer> root_scroll_layer = Layer::Create();
    187     root_scroll_layer->SetScrollable(true);
    188     root_scroll_layer->SetScrollOffset(initial_scroll_);
    189     root_scroll_layer->SetBounds(gfx::Size(200, 200));
    190     root_scroll_layer->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    191     root_scroll_layer->SetIsDrawable(true);
    192     layer_tree_host()->root_layer()->AddChild(root_scroll_layer);
    193 
    194     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
    195   }
    196 
    197   virtual void WillBeginMainFrame() OVERRIDE {
    198     num_will_begin_main_frames_++;
    199     Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0];
    200     switch (num_will_begin_main_frames_) {
    201       case 1:
    202         // This will not be aborted because of the initial prop changes.
    203         EXPECT_EQ(0, num_impl_scrolls_);
    204         EXPECT_EQ(0, layer_tree_host()->source_frame_number());
    205         EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
    206         EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
    207         break;
    208       case 2:
    209         // This commit will be aborted, and another commit will be
    210         // initiated from the redraw.
    211         EXPECT_EQ(1, num_impl_scrolls_);
    212         EXPECT_EQ(1, layer_tree_host()->source_frame_number());
    213         EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
    214                          initial_scroll_ + impl_scroll_);
    215         EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
    216         PostSetNeedsRedrawToMainThread();
    217         break;
    218       case 3:
    219         // This commit will not be aborted because of the scroll change.
    220         EXPECT_EQ(2, num_impl_scrolls_);
    221         EXPECT_EQ(1, layer_tree_host()->source_frame_number());
    222         EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
    223                          initial_scroll_ + impl_scroll_ + impl_scroll_);
    224         EXPECT_EQ(impl_scale_ * impl_scale_,
    225                   layer_tree_host()->page_scale_factor());
    226         root_scroll_layer->SetScrollOffset(root_scroll_layer->scroll_offset() +
    227                                            second_main_scroll_);
    228         break;
    229       case 4:
    230         // This commit will also be aborted.
    231         EXPECT_EQ(3, num_impl_scrolls_);
    232         EXPECT_EQ(2, layer_tree_host()->source_frame_number());
    233         EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
    234                          initial_scroll_ + impl_scroll_ + impl_scroll_ +
    235                              impl_scroll_ + second_main_scroll_);
    236         // End the test by drawing to verify this commit is also aborted.
    237         PostSetNeedsRedrawToMainThread();
    238         break;
    239     }
    240   }
    241 
    242   virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; }
    243 
    244   virtual void WillCommit() OVERRIDE { num_will_commits_++; }
    245 
    246   virtual void DidCommit() OVERRIDE { num_did_commits_++; }
    247 
    248   virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    249     num_impl_commits_++;
    250   }
    251 
    252   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    253     LayerImpl* root_scroll_layer =
    254         impl->active_tree()->root_layer()->children()[0];
    255 
    256     if (impl->active_tree()->source_frame_number() == 0 &&
    257         impl->SourceAnimationFrameNumber() == 1) {
    258       // First draw
    259       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
    260       root_scroll_layer->ScrollBy(impl_scroll_);
    261       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
    262       EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
    263 
    264       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
    265       EXPECT_EQ(1.f, impl->active_tree()->total_page_scale_factor());
    266       impl->active_tree()->SetPageScaleDelta(impl_scale_);
    267       EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
    268       EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
    269 
    270       // To simplify the testing flow, don't redraw here, just commit.
    271       impl->SetNeedsCommit();
    272     } else if (impl->active_tree()->source_frame_number() == 0 &&
    273                impl->SourceAnimationFrameNumber() == 2) {
    274       // Test a second draw after an aborted commit.
    275       // The scroll/scale values should be baked into the offset/scale factor
    276       // since the main thread consumed but aborted the begin frame.
    277       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
    278       root_scroll_layer->ScrollBy(impl_scroll_);
    279       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
    280       EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
    281                        initial_scroll_ + impl_scroll_);
    282 
    283       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
    284       EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
    285       impl->active_tree()->SetPageScaleDelta(impl_scale_);
    286       EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
    287       EXPECT_EQ(impl_scale_ * impl_scale_,
    288                 impl->active_tree()->total_page_scale_factor());
    289 
    290       impl->SetNeedsCommit();
    291     } else if (impl->active_tree()->source_frame_number() == 1 &&
    292                impl->SourceAnimationFrameNumber() == 3) {
    293       // Third draw after the second full commit.
    294       EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
    295       root_scroll_layer->ScrollBy(impl_scroll_);
    296       impl->SetNeedsCommit();
    297       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
    298       EXPECT_VECTOR_EQ(
    299           root_scroll_layer->scroll_offset(),
    300           initial_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_);
    301     } else if (impl->active_tree()->source_frame_number() == 1 &&
    302                impl->SourceAnimationFrameNumber() == 4) {
    303       // Final draw after the second aborted commit.
    304       EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
    305       EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
    306                        initial_scroll_ + impl_scroll_ + impl_scroll_ +
    307                            impl_scroll_ + second_main_scroll_);
    308       EndTest();
    309     }
    310   }
    311 
    312   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
    313                                    float scale) OVERRIDE {
    314     num_impl_scrolls_++;
    315   }
    316 
    317   virtual void AfterTest() OVERRIDE {
    318     EXPECT_EQ(3, num_impl_scrolls_);
    319     // Verify that the embedder sees aborted commits as real commits.
    320     EXPECT_EQ(4, num_will_begin_main_frames_);
    321     EXPECT_EQ(4, num_did_begin_main_frames_);
    322     EXPECT_EQ(4, num_will_commits_);
    323     EXPECT_EQ(4, num_did_commits_);
    324     // ...but the compositor thread only sees two real ones.
    325     EXPECT_EQ(2, num_impl_commits_);
    326   }
    327 
    328  private:
    329   gfx::Vector2d initial_scroll_;
    330   gfx::Vector2d impl_scroll_;
    331   gfx::Vector2d second_main_scroll_;
    332   float impl_scale_;
    333   int num_will_begin_main_frames_;
    334   int num_did_begin_main_frames_;
    335   int num_will_commits_;
    336   int num_did_commits_;
    337   int num_impl_commits_;
    338   int num_impl_scrolls_;
    339 };
    340 
    341 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
    342 
    343 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
    344  public:
    345   LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
    346 
    347   virtual void BeginTest() OVERRIDE {
    348     layer_tree_host()->root_layer()->SetScrollable(true);
    349     layer_tree_host()->root_layer()
    350         ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    351     PostSetNeedsCommitToMainThread();
    352   }
    353 
    354   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    355     LayerImpl* root = impl->active_tree()->root_layer();
    356 
    357     // Check that a fractional scroll delta is correctly accumulated over
    358     // multiple commits.
    359     switch (impl->active_tree()->source_frame_number()) {
    360       case 0:
    361         EXPECT_VECTOR_EQ(root->scroll_offset(), gfx::Vector2d(0, 0));
    362         EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d(0, 0));
    363         PostSetNeedsCommitToMainThread();
    364         break;
    365       case 1:
    366         EXPECT_VECTOR_EQ(root->scroll_offset(),
    367                          gfx::ToFlooredVector2d(scroll_amount_));
    368         EXPECT_VECTOR_EQ(root->ScrollDelta(),
    369                          gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
    370         PostSetNeedsCommitToMainThread();
    371         break;
    372       case 2:
    373         EXPECT_VECTOR_EQ(
    374             root->scroll_offset(),
    375             gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
    376         EXPECT_VECTOR_EQ(
    377             root->ScrollDelta(),
    378             gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
    379         EndTest();
    380         break;
    381     }
    382     root->ScrollBy(scroll_amount_);
    383   }
    384 
    385   virtual void AfterTest() OVERRIDE {}
    386 
    387  private:
    388   gfx::Vector2dF scroll_amount_;
    389 };
    390 
    391 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
    392 
    393 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
    394  public:
    395   LayerTreeHostScrollTestCaseWithChild()
    396       : initial_offset_(10, 20),
    397         javascript_scroll_(40, 5),
    398         scroll_amount_(2, -1),
    399         num_scrolls_(0) {}
    400 
    401   virtual void SetupTree() OVERRIDE {
    402     layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
    403 
    404     scoped_refptr<Layer> root_layer = Layer::Create();
    405     root_layer->SetBounds(gfx::Size(10, 10));
    406 
    407     root_scroll_layer_ = ContentLayer::Create(&fake_content_layer_client_);
    408     root_scroll_layer_->SetBounds(gfx::Size(110, 110));
    409 
    410     root_scroll_layer_->SetPosition(gfx::Point());
    411     root_scroll_layer_->SetAnchorPoint(gfx::PointF());
    412 
    413     root_scroll_layer_->SetIsDrawable(true);
    414     root_scroll_layer_->SetScrollable(true);
    415     root_scroll_layer_->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    416     root_layer->AddChild(root_scroll_layer_);
    417 
    418     child_layer_ = ContentLayer::Create(&fake_content_layer_client_);
    419     child_layer_->set_did_scroll_callback(
    420         base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
    421                    base::Unretained(this)));
    422     child_layer_->SetBounds(gfx::Size(110, 110));
    423 
    424     if (scroll_child_layer_) {
    425       // Scrolls on the child layer will happen at 5, 5. If they are treated
    426       // like device pixels, and device scale factor is 2, then they will
    427       // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
    428       child_layer_->SetPosition(gfx::Point(5, 5));
    429     } else {
    430       // Adjust the child layer horizontally so that scrolls will never hit it.
    431       child_layer_->SetPosition(gfx::Point(60, 5));
    432     }
    433     child_layer_->SetAnchorPoint(gfx::PointF());
    434 
    435     child_layer_->SetIsDrawable(true);
    436     child_layer_->SetScrollable(true);
    437     child_layer_->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    438     root_scroll_layer_->AddChild(child_layer_);
    439 
    440     if (scroll_child_layer_) {
    441       expected_scroll_layer_ = child_layer_;
    442       expected_no_scroll_layer_ = root_scroll_layer_;
    443     } else {
    444       expected_scroll_layer_ = root_scroll_layer_;
    445       expected_no_scroll_layer_ = child_layer_;
    446     }
    447 
    448     expected_scroll_layer_->SetScrollOffset(initial_offset_);
    449 
    450     layer_tree_host()->SetRootLayer(root_layer);
    451     LayerTreeHostScrollTest::SetupTree();
    452   }
    453 
    454   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
    455 
    456   virtual void WillCommit() OVERRIDE {
    457     // Keep the test committing (otherwise the early out for no update
    458     // will stall the test).
    459     if (layer_tree_host()->source_frame_number() < 2) {
    460       layer_tree_host()->SetNeedsCommit();
    461     }
    462   }
    463 
    464   void DidScroll() {
    465     final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
    466   }
    467 
    468   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
    469                                    float scale) OVERRIDE {
    470     num_scrolls_++;
    471   }
    472 
    473   virtual void Layout() OVERRIDE {
    474     EXPECT_VECTOR_EQ(gfx::Vector2d(),
    475                      expected_no_scroll_layer_->scroll_offset());
    476 
    477     switch (layer_tree_host()->source_frame_number()) {
    478       case 0:
    479         EXPECT_VECTOR_EQ(initial_offset_,
    480                          expected_scroll_layer_->scroll_offset());
    481         break;
    482       case 1:
    483         EXPECT_VECTOR_EQ(initial_offset_ + scroll_amount_,
    484                          expected_scroll_layer_->scroll_offset());
    485 
    486         // Pretend like Javascript updated the scroll position itself.
    487         expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
    488         break;
    489       case 2:
    490         EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
    491                          expected_scroll_layer_->scroll_offset());
    492         break;
    493     }
    494   }
    495 
    496   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    497     LayerImpl* root_impl = impl->active_tree()->root_layer();
    498     LayerImpl* root_scroll_layer_impl = root_impl->children()[0];
    499     LayerImpl* child_layer_impl = root_scroll_layer_impl->children()[0];
    500 
    501     LayerImpl* expected_scroll_layer_impl = NULL;
    502     LayerImpl* expected_no_scroll_layer_impl = NULL;
    503     if (scroll_child_layer_) {
    504       expected_scroll_layer_impl = child_layer_impl;
    505       expected_no_scroll_layer_impl = root_scroll_layer_impl;
    506     } else {
    507       expected_scroll_layer_impl = root_scroll_layer_impl;
    508       expected_no_scroll_layer_impl = child_layer_impl;
    509     }
    510 
    511     EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
    512     EXPECT_VECTOR_EQ(gfx::Vector2d(),
    513                      expected_no_scroll_layer_impl->ScrollDelta());
    514 
    515     // Ensure device scale factor is affecting the layers.
    516     gfx::Size expected_content_bounds = gfx::ToCeiledSize(
    517         gfx::ScaleSize(root_scroll_layer_impl->bounds(), device_scale_factor_));
    518     EXPECT_SIZE_EQ(expected_content_bounds,
    519                    root_scroll_layer_->content_bounds());
    520 
    521     expected_content_bounds = gfx::ToCeiledSize(
    522         gfx::ScaleSize(child_layer_impl->bounds(), device_scale_factor_));
    523     EXPECT_SIZE_EQ(expected_content_bounds, child_layer_->content_bounds());
    524 
    525     switch (impl->active_tree()->source_frame_number()) {
    526       case 0: {
    527         // Gesture scroll on impl thread.
    528         InputHandler::ScrollStatus status = impl->ScrollBegin(
    529             gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
    530                                gfx::Vector2dF(0.5f, 0.5f)),
    531             InputHandler::Gesture);
    532         EXPECT_EQ(InputHandler::ScrollStarted, status);
    533         impl->ScrollBy(gfx::Point(), scroll_amount_);
    534         impl->ScrollEnd();
    535 
    536         // Check the scroll is applied as a delta.
    537         EXPECT_VECTOR_EQ(initial_offset_,
    538                          expected_scroll_layer_impl->scroll_offset());
    539         EXPECT_VECTOR_EQ(scroll_amount_,
    540                          expected_scroll_layer_impl->ScrollDelta());
    541         break;
    542       }
    543       case 1: {
    544         // Wheel scroll on impl thread.
    545         InputHandler::ScrollStatus status = impl->ScrollBegin(
    546             gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
    547                                gfx::Vector2dF(0.5f, 0.5f)),
    548             InputHandler::Wheel);
    549         EXPECT_EQ(InputHandler::ScrollStarted, status);
    550         impl->ScrollBy(gfx::Point(), scroll_amount_);
    551         impl->ScrollEnd();
    552 
    553         // Check the scroll is applied as a delta.
    554         EXPECT_VECTOR_EQ(javascript_scroll_,
    555                          expected_scroll_layer_impl->scroll_offset());
    556         EXPECT_VECTOR_EQ(scroll_amount_,
    557                          expected_scroll_layer_impl->ScrollDelta());
    558         break;
    559       }
    560       case 2:
    561 
    562         EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
    563                          expected_scroll_layer_impl->scroll_offset());
    564         EXPECT_VECTOR_EQ(gfx::Vector2d(),
    565                          expected_scroll_layer_impl->ScrollDelta());
    566 
    567         EndTest();
    568         break;
    569     }
    570   }
    571 
    572   virtual void AfterTest() OVERRIDE {
    573     if (scroll_child_layer_) {
    574       EXPECT_EQ(0, num_scrolls_);
    575       EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
    576                        final_scroll_offset_);
    577     } else {
    578       EXPECT_EQ(2, num_scrolls_);
    579       EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_);
    580     }
    581   }
    582 
    583  protected:
    584   float device_scale_factor_;
    585   bool scroll_child_layer_;
    586 
    587   gfx::Vector2d initial_offset_;
    588   gfx::Vector2d javascript_scroll_;
    589   gfx::Vector2d scroll_amount_;
    590   int num_scrolls_;
    591   gfx::Vector2d final_scroll_offset_;
    592 
    593   FakeContentLayerClient fake_content_layer_client_;
    594 
    595   scoped_refptr<Layer> root_scroll_layer_;
    596   scoped_refptr<Layer> child_layer_;
    597   scoped_refptr<Layer> expected_scroll_layer_;
    598   scoped_refptr<Layer> expected_no_scroll_layer_;
    599 };
    600 
    601 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    602        DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint) {
    603   device_scale_factor_ = 1.f;
    604   scroll_child_layer_ = true;
    605   RunTest(true, false, false);
    606 }
    607 
    608 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    609        DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint) {
    610   device_scale_factor_ = 1.f;
    611   scroll_child_layer_ = true;
    612   RunTest(true, false, true);
    613 }
    614 
    615 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    616        DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint) {
    617   device_scale_factor_ = 1.f;
    618   scroll_child_layer_ = true;
    619   RunTest(true, true, false);
    620 }
    621 
    622 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    623        DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint) {
    624   device_scale_factor_ = 1.f;
    625   scroll_child_layer_ = true;
    626   RunTest(true, true, true);
    627 }
    628 
    629 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    630        DeviceScaleFactor15_ScrollChild_DirectRenderer) {
    631   device_scale_factor_ = 1.5f;
    632   scroll_child_layer_ = true;
    633   RunTest(true, false, true);
    634 }
    635 
    636 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    637        DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
    638   device_scale_factor_ = 1.5f;
    639   scroll_child_layer_ = true;
    640   RunTest(true, true, true);
    641 }
    642 
    643 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    644        DeviceScaleFactor2_ScrollChild_DirectRenderer) {
    645   device_scale_factor_ = 2.f;
    646   scroll_child_layer_ = true;
    647   RunTest(true, false, true);
    648 }
    649 
    650 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    651        DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
    652   device_scale_factor_ = 2.f;
    653   scroll_child_layer_ = true;
    654   RunTest(true, true, true);
    655 }
    656 
    657 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    658        DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
    659   device_scale_factor_ = 1.f;
    660   scroll_child_layer_ = false;
    661   RunTest(true, false, true);
    662 }
    663 
    664 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    665        DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
    666   device_scale_factor_ = 1.f;
    667   scroll_child_layer_ = false;
    668   RunTest(true, true, true);
    669 }
    670 
    671 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    672        DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
    673   device_scale_factor_ = 1.5f;
    674   scroll_child_layer_ = false;
    675   RunTest(true, false, true);
    676 }
    677 
    678 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    679        DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
    680   device_scale_factor_ = 1.5f;
    681   scroll_child_layer_ = false;
    682   RunTest(true, true, true);
    683 }
    684 
    685 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    686        DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint) {
    687   device_scale_factor_ = 2.f;
    688   scroll_child_layer_ = false;
    689   RunTest(true, false, false);
    690 }
    691 
    692 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    693        DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint) {
    694   device_scale_factor_ = 2.f;
    695   scroll_child_layer_ = false;
    696   RunTest(true, false, true);
    697 }
    698 
    699 TEST_F(LayerTreeHostScrollTestCaseWithChild,
    700        DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
    701   device_scale_factor_ = 2.f;
    702   scroll_child_layer_ = false;
    703   RunTest(true, true, true);
    704 }
    705 
    706 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
    707  public:
    708   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
    709     settings->impl_side_painting = true;
    710   }
    711 
    712   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    713     if (impl->pending_tree())
    714       impl->SetNeedsRedraw();
    715   }
    716 };
    717 
    718 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
    719  public:
    720   ImplSidePaintingScrollTestSimple()
    721       : initial_scroll_(10, 20),
    722         main_thread_scroll_(40, 5),
    723         impl_thread_scroll1_(2, -1),
    724         impl_thread_scroll2_(-3, 10),
    725         num_scrolls_(0) {}
    726 
    727   virtual void BeginTest() OVERRIDE {
    728     layer_tree_host()->root_layer()->SetScrollable(true);
    729     layer_tree_host()->root_layer()
    730         ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    731     layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_);
    732     PostSetNeedsCommitToMainThread();
    733   }
    734 
    735   virtual void Layout() OVERRIDE {
    736     Layer* root = layer_tree_host()->root_layer();
    737     if (!layer_tree_host()->source_frame_number()) {
    738       EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    739     } else {
    740       EXPECT_VECTOR_EQ(root->scroll_offset(),
    741                        initial_scroll_ + impl_thread_scroll1_);
    742 
    743       // Pretend like Javascript updated the scroll position itself with a
    744       // change of main_thread_scroll.
    745       root->SetScrollOffset(initial_scroll_ + main_thread_scroll_ +
    746                             impl_thread_scroll1_);
    747     }
    748   }
    749 
    750   virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    751     // We force a second draw here of the first commit before activating
    752     // the second commit.
    753     if (impl->active_tree()->source_frame_number() == 0)
    754       impl->SetNeedsRedraw();
    755   }
    756 
    757   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    758     ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
    759 
    760     LayerImpl* root = impl->active_tree()->root_layer();
    761     LayerImpl* pending_root =
    762         impl->active_tree()->FindPendingTreeLayerById(root->id());
    763 
    764     switch (impl->active_tree()->source_frame_number()) {
    765       case 0:
    766         if (!impl->pending_tree()) {
    767           impl->BlockNotifyReadyToActivateForTesting(true);
    768           EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d());
    769           root->ScrollBy(impl_thread_scroll1_);
    770 
    771           EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    772           EXPECT_VECTOR_EQ(root->ScrollDelta(), impl_thread_scroll1_);
    773           EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d());
    774           PostSetNeedsCommitToMainThread();
    775 
    776           // CommitCompleteOnThread will trigger this function again
    777           // and cause us to take the else clause.
    778         } else {
    779           impl->BlockNotifyReadyToActivateForTesting(false);
    780           ASSERT_TRUE(pending_root);
    781           EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
    782 
    783           root->ScrollBy(impl_thread_scroll2_);
    784           EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    785           EXPECT_VECTOR_EQ(root->ScrollDelta(),
    786                            impl_thread_scroll1_ + impl_thread_scroll2_);
    787           EXPECT_VECTOR_EQ(root->sent_scroll_delta(), impl_thread_scroll1_);
    788 
    789           EXPECT_VECTOR_EQ(
    790               pending_root->scroll_offset(),
    791               initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
    792           EXPECT_VECTOR_EQ(pending_root->ScrollDelta(), impl_thread_scroll2_);
    793           EXPECT_VECTOR_EQ(pending_root->sent_scroll_delta(), gfx::Vector2d());
    794         }
    795         break;
    796       case 1:
    797         EXPECT_FALSE(impl->pending_tree());
    798         EXPECT_VECTOR_EQ(
    799             root->scroll_offset(),
    800             initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
    801         EXPECT_VECTOR_EQ(root->ScrollDelta(), impl_thread_scroll2_);
    802         EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d());
    803         EndTest();
    804         break;
    805     }
    806   }
    807 
    808   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
    809                                    float scale) OVERRIDE {
    810     num_scrolls_++;
    811   }
    812 
    813   virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
    814 
    815  private:
    816   gfx::Vector2d initial_scroll_;
    817   gfx::Vector2d main_thread_scroll_;
    818   gfx::Vector2d impl_thread_scroll1_;
    819   gfx::Vector2d impl_thread_scroll2_;
    820   int num_scrolls_;
    821 };
    822 
    823 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
    824 
    825 // This test makes sure that layers pick up scrolls that occur between
    826 // beginning a commit and finishing a commit (aka scroll deltas not
    827 // included in sent scroll delta) still apply to layers that don't
    828 // push properties.
    829 class ImplSidePaintingScrollTestImplOnlyScroll
    830     : public ImplSidePaintingScrollTest {
    831  public:
    832   ImplSidePaintingScrollTestImplOnlyScroll()
    833       : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
    834 
    835   virtual void BeginTest() OVERRIDE {
    836     layer_tree_host()->root_layer()->SetScrollable(true);
    837     layer_tree_host()->root_layer()->SetMaxScrollOffset(
    838         gfx::Vector2d(100, 100));
    839     layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_);
    840     PostSetNeedsCommitToMainThread();
    841   }
    842 
    843   virtual void WillCommit() OVERRIDE {
    844     Layer* root = layer_tree_host()->root_layer();
    845     switch (layer_tree_host()->source_frame_number()) {
    846       case 0:
    847         EXPECT_TRUE(root->needs_push_properties());
    848         break;
    849       case 1:
    850         // Even if this layer doesn't need push properties, it should
    851         // still pick up scrolls that happen on the active layer during
    852         // commit.
    853         EXPECT_FALSE(root->needs_push_properties());
    854         break;
    855     }
    856   }
    857 
    858   virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    859     // Scroll after the 2nd commit has started.
    860     if (impl->active_tree()->source_frame_number() == 0) {
    861       LayerImpl* active_root = impl->active_tree()->root_layer();
    862       ASSERT_TRUE(active_root);
    863       active_root->ScrollBy(impl_thread_scroll_);
    864     }
    865   }
    866 
    867   virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    868     // We force a second draw here of the first commit before activating
    869     // the second commit.
    870     LayerImpl* active_root = impl->active_tree()->root_layer();
    871     LayerImpl* pending_root = impl->pending_tree()->root_layer();
    872 
    873     ASSERT_TRUE(pending_root);
    874     switch (impl->pending_tree()->source_frame_number()) {
    875       case 0:
    876         EXPECT_VECTOR_EQ(pending_root->scroll_offset(), initial_scroll_);
    877         EXPECT_VECTOR_EQ(pending_root->ScrollDelta(), gfx::Vector2d());
    878         EXPECT_VECTOR_EQ(pending_root->sent_scroll_delta(), gfx::Vector2d());
    879         EXPECT_FALSE(active_root);
    880         break;
    881       case 1:
    882         // Even though the scroll happened during the commit, both layers
    883         // should have the appropriate scroll delta.
    884         EXPECT_VECTOR_EQ(pending_root->scroll_offset(), initial_scroll_);
    885         EXPECT_VECTOR_EQ(pending_root->ScrollDelta(), impl_thread_scroll_);
    886         EXPECT_VECTOR_EQ(pending_root->sent_scroll_delta(), gfx::Vector2d());
    887         ASSERT_TRUE(active_root);
    888         EXPECT_VECTOR_EQ(active_root->scroll_offset(), initial_scroll_);
    889         EXPECT_VECTOR_EQ(active_root->ScrollDelta(), impl_thread_scroll_);
    890         EXPECT_VECTOR_EQ(active_root->sent_scroll_delta(), gfx::Vector2d());
    891         break;
    892       case 2:
    893         // On the next commit, this delta should have been sent and applied.
    894         EXPECT_VECTOR_EQ(pending_root->scroll_offset(),
    895                          initial_scroll_ + impl_thread_scroll_);
    896         EXPECT_VECTOR_EQ(pending_root->ScrollDelta(), gfx::Vector2d());
    897         EXPECT_VECTOR_EQ(pending_root->sent_scroll_delta(), gfx::Vector2d());
    898         EndTest();
    899         break;
    900     }
    901   }
    902 
    903   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    904     ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
    905 
    906     LayerImpl* root = impl->active_tree()->root_layer();
    907 
    908     switch (impl->active_tree()->source_frame_number()) {
    909       case 0:
    910         EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    911         EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d());
    912         EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d());
    913         PostSetNeedsCommitToMainThread();
    914         break;
    915       case 1:
    916         EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
    917         EXPECT_VECTOR_EQ(root->ScrollDelta(), impl_thread_scroll_);
    918         EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d());
    919         PostSetNeedsCommitToMainThread();
    920         break;
    921     }
    922   }
    923 
    924   virtual void AfterTest() OVERRIDE {}
    925 
    926  private:
    927   gfx::Vector2d initial_scroll_;
    928   gfx::Vector2d impl_thread_scroll_;
    929 };
    930 
    931 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
    932 
    933 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
    934     : public LayerTreeHostScrollTest {
    935  public:
    936   LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
    937 
    938   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
    939 
    940   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    941     LayerImpl* root = impl->active_tree()->root_layer();
    942     root->SetScrollable(true);
    943 
    944     root->SetMaxScrollOffset(gfx::Vector2d(100, 100));
    945     EXPECT_EQ(InputHandler::ScrollStarted,
    946               root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture));
    947 
    948     root->SetMaxScrollOffset(gfx::Vector2d(0, 0));
    949     EXPECT_EQ(InputHandler::ScrollIgnored,
    950               root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture));
    951 
    952     root->SetMaxScrollOffset(gfx::Vector2d(-100, -100));
    953     EXPECT_EQ(InputHandler::ScrollIgnored,
    954               root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture));
    955 
    956     EndTest();
    957   }
    958 
    959   virtual void AfterTest() OVERRIDE {}
    960 };
    961 
    962 SINGLE_AND_MULTI_THREAD_TEST_F(
    963     LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
    964 
    965 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
    966  public:
    967   ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
    968                                    bool* received_stop_flinging)
    969       : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
    970 
    971   virtual void WillShutdown() OVERRIDE {
    972     if (!received_stop_flinging_)
    973       ADD_FAILURE() << "WillShutdown() called before fling stopped";
    974   }
    975 
    976   virtual void Animate(base::TimeTicks time) OVERRIDE {
    977     if (!task_runner_->BelongsToCurrentThread())
    978       ADD_FAILURE() << "Animate called on wrong thread";
    979   }
    980 
    981   virtual void MainThreadHasStoppedFlinging() OVERRIDE {
    982     if (!task_runner_->BelongsToCurrentThread())
    983       ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
    984     *received_stop_flinging_ = true;
    985   }
    986 
    987   virtual void DidOverscroll(const DidOverscrollParams& params) OVERRIDE {
    988     if (!task_runner_->BelongsToCurrentThread())
    989       ADD_FAILURE() << "DidOverscroll called on wrong thread";
    990   }
    991 
    992  private:
    993   base::SingleThreadTaskRunner* task_runner_;
    994   bool* received_stop_flinging_;
    995 };
    996 
    997 void BindInputHandlerOnCompositorThread(
    998     const base::WeakPtr<InputHandler>& input_handler,
    999     ThreadCheckingInputHandlerClient* client) {
   1000   input_handler->BindToClient(client);
   1001 }
   1002 
   1003 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
   1004   base::Thread impl_thread("cc");
   1005   ASSERT_TRUE(impl_thread.Start());
   1006 
   1007   bool received_stop_flinging = false;
   1008   LayerTreeSettings settings;
   1009 
   1010   ThreadCheckingInputHandlerClient input_handler_client(
   1011           impl_thread.message_loop_proxy().get(), &received_stop_flinging);
   1012   FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
   1013 
   1014   ASSERT_TRUE(impl_thread.message_loop_proxy().get());
   1015   scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::CreateThreaded(
   1016       &client, NULL, settings, impl_thread.message_loop_proxy());
   1017 
   1018   impl_thread.message_loop_proxy()
   1019       ->PostTask(FROM_HERE,
   1020                  base::Bind(&BindInputHandlerOnCompositorThread,
   1021                             layer_tree_host->GetInputHandler(),
   1022                             base::Unretained(&input_handler_client)));
   1023 
   1024   layer_tree_host->DidStopFlinging();
   1025   layer_tree_host.reset();
   1026   impl_thread.Stop();
   1027   EXPECT_TRUE(received_stop_flinging);
   1028 }
   1029 
   1030 class LayerTreeHostScrollTestLayerStructureChange
   1031     : public LayerTreeHostScrollTest {
   1032  public:
   1033   LayerTreeHostScrollTestLayerStructureChange()
   1034       : scroll_destroy_whole_tree_(false) {}
   1035 
   1036   virtual void SetupTree() OVERRIDE {
   1037     scoped_refptr<Layer> root_layer = Layer::Create();
   1038     root_layer->SetBounds(gfx::Size(10, 10));
   1039 
   1040     Layer* root_scroll_layer =
   1041         CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
   1042     CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
   1043     CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
   1044 
   1045     layer_tree_host()->SetRootLayer(root_layer);
   1046     LayerTreeHostScrollTest::SetupTree();
   1047   }
   1048 
   1049   virtual void BeginTest() OVERRIDE {
   1050     PostSetNeedsCommitToMainThread();
   1051   }
   1052 
   1053   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
   1054     LayerImpl* root = impl->active_tree()->root_layer();
   1055     switch (impl->active_tree()->source_frame_number()) {
   1056       case 0:
   1057         root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
   1058         root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
   1059         root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
   1060         PostSetNeedsCommitToMainThread();
   1061         break;
   1062       case 1:
   1063         EndTest();
   1064         break;
   1065     }
   1066   }
   1067 
   1068   virtual void AfterTest() OVERRIDE {}
   1069 
   1070   virtual void DidScroll(Layer* layer) {
   1071     if (scroll_destroy_whole_tree_) {
   1072       layer_tree_host()->SetRootLayer(NULL);
   1073       EndTest();
   1074       return;
   1075     }
   1076     layer->RemoveFromParent();
   1077   }
   1078 
   1079  protected:
   1080   class FakeLayerScrollClient {
   1081    public:
   1082     void DidScroll() {
   1083       owner_->DidScroll(layer_);
   1084     }
   1085     LayerTreeHostScrollTestLayerStructureChange* owner_;
   1086     Layer* layer_;
   1087   };
   1088 
   1089   Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
   1090     scoped_refptr<Layer> scroll_layer =
   1091         ContentLayer::Create(&fake_content_layer_client_);
   1092     scroll_layer->SetBounds(gfx::Size(110, 110));
   1093     scroll_layer->SetPosition(gfx::Point(0, 0));
   1094     scroll_layer->SetAnchorPoint(gfx::PointF());
   1095     scroll_layer->SetIsDrawable(true);
   1096     scroll_layer->SetScrollable(true);
   1097     scroll_layer->SetMaxScrollOffset(gfx::Vector2d(100, 100));
   1098     scroll_layer->set_did_scroll_callback(base::Bind(
   1099         &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
   1100     client->owner_ = this;
   1101     client->layer_ = scroll_layer.get();
   1102     parent->AddChild(scroll_layer);
   1103     return scroll_layer.get();
   1104   }
   1105 
   1106   FakeLayerScrollClient root_scroll_layer_client_;
   1107   FakeLayerScrollClient sibling_scroll_layer_client_;
   1108   FakeLayerScrollClient child_scroll_layer_client_;
   1109 
   1110   FakeContentLayerClient fake_content_layer_client_;
   1111 
   1112   bool scroll_destroy_whole_tree_;
   1113 };
   1114 
   1115 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
   1116     RunTest(true, false, false);
   1117 }
   1118 
   1119 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
   1120     scroll_destroy_whole_tree_ = true;
   1121     RunTest(true, false, false);
   1122 }
   1123 
   1124 }  // namespace
   1125 }  // namespace cc
   1126