Defer scrollbar geometry (e.g., thumb length) updates

Before this patch, scrollbar geometry was synchronously updated when any
layer property changed. This patch defers this update until PrepareToDraw
by using a dirty bit pattern: changes that can affect scrollbar geometry
mark the LayerTreeImpl as needing a geometry update. Later in PrepareToDraw,
all scrollbar geometries are updated if needed.

This has three advantages:
1) The scrollbar update can DCHECK that the lifecycle allows layer
property access. This simplifies the code because it is now clear
that the scrollbar update uses up-to-date layer properties. This was
previously safe because scrollbars were updated after any scrollbar
property change.
2) LayerTreeImpl::RegisterScrollbar no longer calls LayerIdByElementId.
3) LayerTreeImpl's clip_scroll_map_ has been removed. This was a
cache of LayerImpl::scroll_clip_layer and gets us closer to
removing scroll_clip_layer.

This patch also adds a test of viewport scrollbars getting pushed by
the browser controls (HidingBrowserControlsAdjustsScrollbarPosition).

BUG=723263

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ic6b582cb01fba3e1f71e5aa7d6787582c25ab29c
Reviewed-on: https://chromium-review.googlesource.com/517762
Commit-Queue: Philip Rogers <[email protected]>
Reviewed-by: enne <[email protected]>
Reviewed-by: Chris harrelson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#476796}
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 57cb1b4..aa992b6 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -94,7 +94,6 @@
 LayerImpl::~LayerImpl() {
   DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
 
-  layer_tree_impl_->UnregisterScrollLayer(this);
   layer_tree_impl_->UnregisterLayer(this);
 
   layer_tree_impl_->RemoveFromElementMap(this);
@@ -275,10 +274,12 @@
 void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) {
   if (scroll_clip_layer_id_ == scroll_clip_layer_id)
     return;
-
-  layer_tree_impl()->UnregisterScrollLayer(this);
   scroll_clip_layer_id_ = scroll_clip_layer_id;
+
   layer_tree_impl()->RegisterScrollLayer(this);
+
+  // The scrolling bounds are determined from the scroll clip layer's bounds.
+  layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
 }
 
 LayerImpl* LayerImpl::scroll_clip_layer() const {
@@ -516,7 +517,8 @@
 
   bounds_ = bounds;
 
-  layer_tree_impl()->DidUpdateScrollState(id());
+  // Scrollbar positions depend on scrolling bounds and scroll clip bounds.
+  layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
 
   NoteLayerPropertyChanged();
 }
@@ -543,7 +545,9 @@
       NOTREACHED();
   }
 
-  layer_tree_impl()->DidUpdateScrollState(id());
+  // Viewport scrollbar positions are determined using the viewport bounds
+  // delta.
+  layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
 
   if (masks_to_bounds()) {
     // If layer is clipping, then update the clip node using the new bounds.