cc: Split animating and drawing into separate actions

Split impl-side animating and drawing into separate actions. This is
needed to allow for the possibility of a commit between animating and
drawing so that the main thread gets a chance to consume the new
animation state. In particular this allows the main thread to
synchronize with a fling animation using an onscroll handler.

BUG=347366,368064

Review URL: https://codereview.chromium.org/206793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267338 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 306fd79..42a4521b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -470,15 +470,11 @@
                                   duration.InSecondsF());
   }
 
-  SetNeedsRedraw();
+  SetNeedsAnimate();
   client_->SetNeedsCommitOnImplThread();
   client_->RenewTreePriority();
 }
 
-void LayerTreeHostImpl::ScheduleAnimation() {
-  SetNeedsRedraw();
-}
-
 bool LayerTreeHostImpl::HaveTouchEventHandlersAt(
     const gfx::Point& viewport_point) {
   if (!settings_.touch_hit_testing)
@@ -1743,6 +1739,11 @@
   renderer_->SetVisible(visible);
 }
 
+void LayerTreeHostImpl::SetNeedsAnimate() {
+  NotifySwapPromiseMonitorsOfSetNeedsRedraw();
+  client_->SetNeedsAnimateOnImplThread();
+}
+
 void LayerTreeHostImpl::SetNeedsRedraw() {
   NotifySwapPromiseMonitorsOfSetNeedsRedraw();
   client_->SetNeedsRedrawOnImplThread();
@@ -2054,6 +2055,7 @@
 void LayerTreeHostImpl::DidChangeTopControlsPosition() {
   UpdateInnerViewportContainerSize();
   SetNeedsRedraw();
+  SetNeedsAnimate();
   active_tree_->set_needs_update_draw_properties();
   SetFullRootLayerDamage();
 }
@@ -2738,6 +2740,8 @@
     page_scale_animation_.reset();
     client_->SetNeedsCommitOnImplThread();
     client_->RenewTreePriority();
+  } else {
+    SetNeedsAnimate();
   }
 }
 
@@ -2747,14 +2751,12 @@
   gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
   if (active_tree_->TotalScrollOffset().y() == 0.f)
     return;
-  if (scroll.IsZero()) {
-    // This may happen on the first animation step. Force redraw otherwise
-    // the animation would stop because of no new frames.
-    SetNeedsRedraw();
-  } else {
+  if (!scroll.IsZero()) {
     ScrollViewportBy(gfx::ScaleVector2d(
         scroll, 1.f / active_tree_->total_page_scale_factor()));
+    SetNeedsRedraw();
   }
+  SetNeedsAnimate();
 }
 
 void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) {
@@ -2776,7 +2778,7 @@
        ++iter)
     (*iter).second->Animate(monotonic_time_for_cc_animations);
 
-  SetNeedsRedraw();
+  SetNeedsAnimate();
 }
 
 void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
@@ -2798,6 +2800,8 @@
   if (!events->empty()) {
     client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass());
   }
+
+  SetNeedsAnimate();
 }
 
 void LayerTreeHostImpl::ActivateAnimations() {
@@ -2885,9 +2889,10 @@
       layer->scrollbar_animation_controller();
   if (scrollbar_controller && scrollbar_controller->Animate(time)) {
     TRACE_EVENT_INSTANT0(
-        "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
+        "cc",
+        "LayerTreeHostImpl::SetNeedsAnimate due to AnimateScrollbars",
         TRACE_EVENT_SCOPE_THREAD);
-    SetNeedsRedraw();
+    SetNeedsAnimate();
   }
 
   for (size_t i = 0; i < layer->children().size(); ++i)
@@ -2908,10 +2913,11 @@
       layer->scrollbar_animation_controller();
   if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
     base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
-    if (delay > base::TimeDelta())
+    if (delay > base::TimeDelta()) {
       client_->RequestScrollbarAnimationOnImplThread(delay);
-    else if (scrollbar_controller->Animate(time))
-      SetNeedsRedraw();
+    } else if (scrollbar_controller->Animate(time)) {
+      SetNeedsAnimate();
+    }
   }
 
   for (size_t i = 0; i < layer->children().size(); ++i)