| Index: cc/layers/scrollbar_layer_unittest.cc
 | 
| diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
 | 
| index bb76720a1ffcb56f33964edad01d2fe68e130fa5..2d01af7289db11f50c91955a9dab07485f31f687 100644
 | 
| --- a/cc/layers/scrollbar_layer_unittest.cc
 | 
| +++ b/cc/layers/scrollbar_layer_unittest.cc
 | 
| @@ -66,7 +66,8 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer) {
 | 
|        static_cast<PaintedScrollbarLayerImpl*>(
 | 
|            layer_impl_tree_root->children()[1]);
 | 
|  
 | 
| -  EXPECT_EQ(cc_child1->horizontal_scrollbar_layer(), cc_child2);
 | 
| +  EXPECT_EQ(cc_child1->scrollbars()->size(), 1UL);
 | 
| +  EXPECT_EQ(*(cc_child1->scrollbars()->begin()), cc_child2);
 | 
|  }
 | 
|  
 | 
|  TEST(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) {
 | 
| @@ -80,7 +81,8 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) {
 | 
|            layer_impl_tree_root->children()[0]);
 | 
|    LayerImpl* cc_child2 = layer_impl_tree_root->children()[1];
 | 
|  
 | 
| -  EXPECT_EQ(cc_child2->horizontal_scrollbar_layer(), cc_child1);
 | 
| +  EXPECT_EQ(cc_child2->scrollbars()->size(), 1UL);
 | 
| +  EXPECT_EQ(*(cc_child2->scrollbars()->begin()), cc_child1);
 | 
|  }
 | 
|  
 | 
|  TEST(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) {
 | 
| @@ -121,19 +123,24 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) {
 | 
|  
 | 
|    scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
 | 
|    scoped_refptr<Layer> layer_tree_root = Layer::Create();
 | 
| +  scoped_refptr<Layer> scroll_layer = Layer::Create();
 | 
|    scoped_refptr<Layer> content_layer = Layer::Create();
 | 
|    scoped_refptr<Layer> scrollbar_layer =
 | 
|        PaintedScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id());
 | 
|  
 | 
| -  layer_tree_root->SetScrollable(true);
 | 
| -  layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20));
 | 
| -  layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50));
 | 
| -  layer_tree_root->SetBounds(gfx::Size(100, 200));
 | 
| +  // Choose bounds to give max_scroll_offset = (30, 50).
 | 
| +  layer_tree_root->SetBounds(gfx::Size(70, 150));
 | 
| +  scroll_layer->SetScrollClipLayerId(layer_tree_root->id());
 | 
| +  scroll_layer->SetScrollOffset(gfx::Vector2d(10, 20));
 | 
| +  scroll_layer->SetBounds(gfx::Size(100, 200));
 | 
|    content_layer->SetBounds(gfx::Size(100, 200));
 | 
|  
 | 
|    host->SetRootLayer(layer_tree_root);
 | 
| -  layer_tree_root->AddChild(content_layer);
 | 
| +  layer_tree_root->AddChild(scroll_layer);
 | 
| +  scroll_layer->AddChild(content_layer);
 | 
|    layer_tree_root->AddChild(scrollbar_layer);
 | 
| +  scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
 | 
| +  scrollbar_layer->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id());
 | 
|  
 | 
|    layer_tree_root->SavePaintProperties();
 | 
|    content_layer->SavePaintProperties();
 | 
| @@ -147,10 +154,11 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) {
 | 
|    EXPECT_EQ(10.f, cc_scrollbar_layer->current_pos());
 | 
|    EXPECT_EQ(30, cc_scrollbar_layer->maximum());
 | 
|  
 | 
| -  layer_tree_root->SetScrollOffset(gfx::Vector2d(100, 200));
 | 
| -  layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(300, 500));
 | 
| -  layer_tree_root->SetBounds(gfx::Size(1000, 2000));
 | 
| +  layer_tree_root->SetBounds(gfx::Size(700, 1500));
 | 
|    layer_tree_root->SavePaintProperties();
 | 
| +  scroll_layer->SetBounds(gfx::Size(1000, 2000));
 | 
| +  scroll_layer->SetScrollOffset(gfx::Vector2d(100, 200));
 | 
| +  scroll_layer->SavePaintProperties();
 | 
|    content_layer->SetBounds(gfx::Size(1000, 2000));
 | 
|    content_layer->SavePaintProperties();
 | 
|  
 | 
| @@ -163,65 +171,73 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) {
 | 
|    EXPECT_EQ(100.f, cc_scrollbar_layer->current_pos());
 | 
|    EXPECT_EQ(300, cc_scrollbar_layer->maximum());
 | 
|  
 | 
| -  layer_impl_tree_root->ScrollBy(gfx::Vector2d(12, 34));
 | 
| +  LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0];
 | 
| +  scroll_layer_impl->ScrollBy(gfx::Vector2d(12, 34));
 | 
|  
 | 
|    EXPECT_EQ(112.f, cc_scrollbar_layer->current_pos());
 | 
|    EXPECT_EQ(300, cc_scrollbar_layer->maximum());
 | 
|  }
 | 
|  
 | 
| +#define UPDATE_AND_EXTRACT_LAYER_POINTERS()                         \
 | 
| +  do {                                                              \
 | 
| +    scrollbar_layer->UpdateThumbAndTrackGeometry();                 \
 | 
| +    root_clip_layer_impl = host->CommitAndCreateLayerImplTree();    \
 | 
| +    root_layer_impl = root_clip_layer_impl->children()[0];          \
 | 
| +    scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \
 | 
| +        root_layer_impl->children()[1]);                            \
 | 
| +    scrollbar_layer_impl->ScrollbarParametersDidChange();           \
 | 
| +  } while (false)
 | 
| +
 | 
|  TEST(ScrollbarLayerTest, ThumbRect) {
 | 
|    scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
 | 
| +  scoped_refptr<Layer> root_clip_layer = Layer::Create();
 | 
|    scoped_refptr<Layer> root_layer = Layer::Create();
 | 
|    scoped_refptr<Layer> content_layer = Layer::Create();
 | 
|    scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
 | 
|        FakePaintedScrollbarLayer::Create(false, true, root_layer->id());
 | 
|  
 | 
| -  root_layer->SetScrollable(true);
 | 
| -  root_layer->SetMaxScrollOffset(gfx::Vector2d(80, 0));
 | 
| +  root_layer->SetScrollClipLayerId(root_clip_layer->id());
 | 
| +  // Give the root-clip a size that will result in MaxScrollOffset = (80, 0).
 | 
| +  root_clip_layer->SetBounds(gfx::Size(20, 50));
 | 
|    root_layer->SetBounds(gfx::Size(100, 50));
 | 
|    content_layer->SetBounds(gfx::Size(100, 50));
 | 
|  
 | 
| -  host->SetRootLayer(root_layer);
 | 
| +  host->SetRootLayer(root_clip_layer);
 | 
| +  root_clip_layer->AddChild(root_layer);
 | 
|    root_layer->AddChild(content_layer);
 | 
|    root_layer->AddChild(scrollbar_layer);
 | 
|  
 | 
|    root_layer->SetScrollOffset(gfx::Vector2d(0, 0));
 | 
|    scrollbar_layer->SetBounds(gfx::Size(70, 10));
 | 
| +  scrollbar_layer->SetScrollLayer(root_layer->id());
 | 
| +  scrollbar_layer->SetClipLayer(root_clip_layer->id());
 | 
|    scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10));
 | 
|    scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
 | 
|    scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10);
 | 
|    scrollbar_layer->fake_scrollbar()->set_thumb_length(4);
 | 
|    scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| +  LayerImpl* root_clip_layer_impl = NULL;
 | 
|    LayerImpl* root_layer_impl = NULL;
 | 
|    PaintedScrollbarLayerImpl* scrollbar_layer_impl = NULL;
 | 
|  
 | 
|    // Thumb is at the edge of the scrollbar (should be inset to
 | 
|    // the start of the track within the scrollbar layer's
 | 
|    // position).
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(10, 0, 4, 10).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  
 | 
|    // Under-scroll (thumb position should clamp and be unchanged).
 | 
|    root_layer->SetScrollOffset(gfx::Vector2d(-5, 0));
 | 
|  
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(10, 0, 4, 10).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  
 | 
|    // Over-scroll (thumb position should clamp on the far side).
 | 
|    root_layer->SetScrollOffset(gfx::Vector2d(85, 0));
 | 
|  
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(56, 0, 4, 10).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  
 | 
| @@ -229,10 +245,7 @@ TEST(ScrollbarLayerTest, ThumbRect) {
 | 
|    scrollbar_layer->fake_scrollbar()->set_thumb_thickness(4);
 | 
|    scrollbar_layer->fake_scrollbar()->set_thumb_length(6);
 | 
|  
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(54, 0, 6, 4).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  
 | 
| @@ -241,10 +254,7 @@ TEST(ScrollbarLayerTest, ThumbRect) {
 | 
|    scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(30, 10));
 | 
|    scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
 | 
|  
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  
 | 
| @@ -253,10 +263,7 @@ TEST(ScrollbarLayerTest, ThumbRect) {
 | 
|    // position).
 | 
|    scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 12, 50, 6));
 | 
|  
 | 
| -  scrollbar_layer->UpdateThumbAndTrackGeometry();
 | 
| -  root_layer_impl = host->CommitAndCreateLayerImplTree();
 | 
| -  scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -      root_layer_impl->children()[1]);
 | 
| +  UPDATE_AND_EXTRACT_LAYER_POINTERS();
 | 
|    EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(),
 | 
|              scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 | 
|  }
 | 
| @@ -332,22 +339,40 @@ TEST(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) {
 | 
|        FakeLayerTreeHost::Create(layer_tree_settings);
 | 
|  
 | 
|    scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
 | 
| -  LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
 | 
| -      host.get(), scrollbar.Pass(), false, true, kThumbThickness);
 | 
| +
 | 
| +  {
 | 
| +    scoped_refptr<Layer> layer_tree_root = Layer::Create();
 | 
| +    scoped_refptr<Layer> scroll_layer = Layer::Create();
 | 
| +    scroll_layer->SetScrollClipLayerId(layer_tree_root->id());
 | 
| +    scoped_refptr<Layer> child1 = Layer::Create();
 | 
| +    scoped_refptr<Layer> child2;
 | 
| +    const bool kIsLeftSideVerticalScrollbar = false;
 | 
| +    child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
 | 
| +                                              kThumbThickness,
 | 
| +                                              kIsLeftSideVerticalScrollbar,
 | 
| +                                              child1->id());
 | 
| +    child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
 | 
| +    child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id());
 | 
| +    scroll_layer->AddChild(child1);
 | 
| +    scroll_layer->InsertChild(child2, 1);
 | 
| +    layer_tree_root->AddChild(scroll_layer);
 | 
| +    host->SetRootLayer(layer_tree_root);
 | 
| +  }
 | 
| +  LayerImpl* layer_impl_tree_root = host->CommitAndCreateLayerImplTree();
 | 
| +  LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0];
 | 
| +
 | 
|    ScrollbarLayerImplBase* scrollbar_layer_impl =
 | 
| -      static_cast<PaintedScrollbarLayerImpl*>(
 | 
| -          layer_impl_tree_root->children()[1]);
 | 
| +      static_cast<PaintedScrollbarLayerImpl*>(scroll_layer_impl->children()[1]);
 | 
| +
 | 
| +  // Choose layer bounds to give max_scroll_offset = (8, 8).
 | 
| +  layer_impl_tree_root->SetBounds(gfx::Size(2, 2));
 | 
| +  scroll_layer_impl->SetBounds(gfx::Size(10, 10));
 | 
| +  scroll_layer_impl->ScrollBy(gfx::Vector2dF(4.f, 0.f));
 | 
|  
 | 
|    scrollbar_layer_impl->SetBounds(gfx::Size(kTrackLength, kThumbThickness));
 | 
|    scrollbar_layer_impl->SetCurrentPos(4.f);
 | 
|    scrollbar_layer_impl->SetMaximum(8);
 | 
|  
 | 
| -  layer_impl_tree_root->SetScrollable(true);
 | 
| -  layer_impl_tree_root->SetHorizontalScrollbarLayer(scrollbar_layer_impl);
 | 
| -  layer_impl_tree_root->SetMaxScrollOffset(gfx::Vector2d(8, 8));
 | 
| -  layer_impl_tree_root->SetBounds(gfx::Size(2, 2));
 | 
| -  layer_impl_tree_root->ScrollBy(gfx::Vector2dF(4.f, 0.f));
 | 
| -
 | 
|    {
 | 
|      MockQuadCuller quad_culler;
 | 
|      AppendQuadsData data;
 | 
| @@ -368,13 +393,22 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test {
 | 
|  
 | 
|      const int kThumbThickness = 3;
 | 
|      const bool kIsLeftSideVerticalScrollbar = false;
 | 
| -
 | 
| -    horizontal_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create(
 | 
| -        host_impl_->active_tree(), 1, HORIZONTAL, kThumbThickness,
 | 
| -        kIsLeftSideVerticalScrollbar);
 | 
| -    vertical_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create(
 | 
| -        host_impl_->active_tree(), 2, VERTICAL, kThumbThickness,
 | 
| -        kIsLeftSideVerticalScrollbar);
 | 
| +    const bool kIsOverlayScrollbar = false;
 | 
| +
 | 
| +    horizontal_scrollbar_layer_ =
 | 
| +        SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(),
 | 
| +                                             1,
 | 
| +                                             HORIZONTAL,
 | 
| +                                             kThumbThickness,
 | 
| +                                             kIsLeftSideVerticalScrollbar,
 | 
| +                                             kIsOverlayScrollbar);
 | 
| +    vertical_scrollbar_layer_ =
 | 
| +        SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(),
 | 
| +                                             2,
 | 
| +                                             VERTICAL,
 | 
| +                                             kThumbThickness,
 | 
| +                                             kIsLeftSideVerticalScrollbar,
 | 
| +                                             kIsOverlayScrollbar);
 | 
|    }
 | 
|  
 | 
|   protected:
 | 
| @@ -456,16 +490,17 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest {
 | 
|    void SetScrollbarBounds(const gfx::Size& bounds) { bounds_ = bounds; }
 | 
|  
 | 
|    virtual void BeginTest() OVERRIDE {
 | 
| +    scroll_layer_ = Layer::Create();
 | 
| +    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 | 
| +
 | 
|      scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
 | 
| -    scrollbar_layer_ = PaintedScrollbarLayer::Create(scrollbar.Pass(), 1);
 | 
| +    scrollbar_layer_ =
 | 
| +        PaintedScrollbarLayer::Create(scrollbar.Pass(), scroll_layer_->id());
 | 
| +    scrollbar_layer_->SetScrollLayer(scroll_layer_->id());
 | 
|      scrollbar_layer_->SetLayerTreeHost(layer_tree_host());
 | 
|      scrollbar_layer_->SetBounds(bounds_);
 | 
|      layer_tree_host()->root_layer()->AddChild(scrollbar_layer_);
 | 
|  
 | 
| -    scroll_layer_ = Layer::Create();
 | 
| -    scrollbar_layer_->SetScrollLayerId(scroll_layer_->id());
 | 
| -    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 | 
| -
 | 
|      PostSetNeedsCommitToMainThread();
 | 
|    }
 | 
|  
 | 
| @@ -597,7 +632,6 @@ class ScrollbarLayerTestResourceCreation : public testing::Test {
 | 
|      scrollbar_layer->SetIsDrawable(true);
 | 
|      scrollbar_layer->SetBounds(gfx::Size(100, 100));
 | 
|      layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20));
 | 
| -    layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50));
 | 
|      layer_tree_root->SetBounds(gfx::Size(100, 200));
 | 
|      content_layer->SetBounds(gfx::Size(100, 200));
 | 
|      scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200);
 | 
| 
 |