Make ScrollOffsetAnimationCurve::UpdateTarget use TimeDelta

Makes the method use TimeDelta instead of double to represent
duration.

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Id95aface04fa2b72bc919fd4ab52af062908f8df
Bug: 763980
Reviewed-on: https://chromium-review.googlesource.com/1140355
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Stephen McGruer <smcgruer@chromium.org>
Commit-Queue: Adithya Srinivasan <adithyas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577928}
diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc
index dad0ee2..39d75dc 100644
--- a/cc/animation/scroll_offset_animation_curve.cc
+++ b/cc/animation/scroll_offset_animation_curve.cc
@@ -171,35 +171,37 @@
   return curve_clone;
 }
 
-static double VelocityBasedDurationBound(gfx::Vector2dF old_delta,
-                                         double old_normalized_velocity,
-                                         double old_duration,
-                                         gfx::Vector2dF new_delta) {
+static base::TimeDelta VelocityBasedDurationBound(
+    gfx::Vector2dF old_delta,
+    double old_normalized_velocity,
+    base::TimeDelta old_duration,
+    gfx::Vector2dF new_delta) {
   double old_delta_max_dimension = MaximumDimension(old_delta);
   double new_delta_max_dimension = MaximumDimension(new_delta);
 
   // If we are already at the target, stop animating.
   if (std::abs(new_delta_max_dimension) < kEpsilon)
-    return 0;
+    return base::TimeDelta();
 
   // Guard against division by zero.
   if (std::abs(old_delta_max_dimension) < kEpsilon ||
       std::abs(old_normalized_velocity) < kEpsilon) {
-    return std::numeric_limits<double>::infinity();
+    return base::TimeDelta::Max();
   }
 
   // Estimate how long it will take to reach the new target at our present
   // velocity, with some fudge factor to account for the "ease out".
-  double old_true_velocity =
-      old_normalized_velocity * old_delta_max_dimension / old_duration;
+  double old_true_velocity = old_normalized_velocity * old_delta_max_dimension /
+                             old_duration.InSecondsF();
   double bound = (new_delta_max_dimension / old_true_velocity) * 2.5f;
 
   // If bound < 0 we are moving in the opposite direction.
-  return bound < 0 ? std::numeric_limits<double>::infinity() : bound;
+  return bound < 0 ? base::TimeDelta::Max()
+                   : base::TimeDelta::FromSecondsD(bound);
 }
 
 void ScrollOffsetAnimationCurve::UpdateTarget(
-    double t,
+    base::TimeDelta t,
     const gfx::ScrollOffset& new_target) {
   if (std::abs(MaximumDimension(target_value_.DeltaFrom(new_target))) <
       kEpsilon) {
@@ -207,41 +209,38 @@
     return;
   }
 
-  base::TimeDelta delayed_by = base::TimeDelta::FromSecondsD(
-      std::max(0.0, last_retarget_.InSecondsF() - t));
-  t = std::max(t, last_retarget_.InSecondsF());
+  base::TimeDelta delayed_by = std::max(base::TimeDelta(), last_retarget_ - t);
+  t = std::max(t, last_retarget_);
 
-  gfx::ScrollOffset current_position =
-      GetValue(base::TimeDelta::FromSecondsD(t));
+  gfx::ScrollOffset current_position = GetValue(t);
   gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_);
   gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);
 
   // The last segement was of zero duration.
   if ((total_animation_duration_ - last_retarget_).is_zero()) {
-    DCHECK_EQ(t, last_retarget_.InSecondsF());
+    DCHECK_EQ(t, last_retarget_);
     total_animation_duration_ =
         SegmentDuration(new_delta, duration_behavior_, delayed_by);
     target_value_ = new_target;
     return;
   }
 
-  double old_duration =
-      (total_animation_duration_ - last_retarget_).InSecondsF();
+  base::TimeDelta old_duration = total_animation_duration_ - last_retarget_;
   double old_normalized_velocity = timing_function_->Velocity(
-      (t - last_retarget_.InSecondsF()) / old_duration);
+      ((t - last_retarget_).InSecondsF()) / old_duration.InSecondsF());
 
   // Use the velocity-based duration bound when it is less than the constant
   // segment duration. This minimizes the "rubber-band" bouncing effect when
   // old_normalized_velocity is large and new_delta is small.
-  double new_duration = std::min(
-      SegmentDuration(new_delta, duration_behavior_, delayed_by).InSecondsF(),
-      VelocityBasedDurationBound(old_delta, old_normalized_velocity,
-                                 old_duration, new_delta));
+  base::TimeDelta new_duration =
+      std::min(SegmentDuration(new_delta, duration_behavior_, delayed_by),
+               VelocityBasedDurationBound(old_delta, old_normalized_velocity,
+                                          old_duration, new_delta));
 
-  if (new_duration < kEpsilon) {
+  if (new_duration.InSecondsF() < kEpsilon) {
     // We are already at or very close to the new target. Stop animating.
     target_value_ = new_target;
-    total_animation_duration_ = base::TimeDelta::FromSecondsD(t);
+    total_animation_duration_ = t;
     return;
   }
 
@@ -249,13 +248,14 @@
   // To match the "true" velocity in px/sec we must adjust this slope for
   // differences in duration and scroll delta between old and new curves.
   double new_normalized_velocity =
-      old_normalized_velocity * (new_duration / old_duration) *
+      old_normalized_velocity *
+      (new_duration.InSecondsF() / old_duration.InSecondsF()) *
       (MaximumDimension(old_delta) / MaximumDimension(new_delta));
 
   initial_value_ = current_position;
   target_value_ = new_target;
-  total_animation_duration_ = base::TimeDelta::FromSecondsD(t + new_duration);
-  last_retarget_ = base::TimeDelta::FromSecondsD(t);
+  total_animation_duration_ = t + new_duration;
+  last_retarget_ = t;
   timing_function_ = EaseOutWithInitialVelocity(new_normalized_velocity);
 }
 
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h
index d471d2b..6924c1e 100644
--- a/cc/animation/scroll_offset_animation_curve.h
+++ b/cc/animation/scroll_offset_animation_curve.h
@@ -59,7 +59,7 @@
   // relative to the start of the animation.  The duration is recomputed based
   // on the DurationBehavior the curve was constructed with.  The timing
   // function is an ease-in-out cubic bezier modified to preserve velocity at t.
-  void UpdateTarget(double t, const gfx::ScrollOffset& new_target);
+  void UpdateTarget(base::TimeDelta t, const gfx::ScrollOffset& new_target);
 
   // Shifts the entire curve by a delta without affecting its shape or timing.
   // Used for scroll anchoring adjustments that happen during scroll animations
diff --git a/cc/animation/scroll_offset_animation_curve_unittest.cc b/cc/animation/scroll_offset_animation_curve_unittest.cc
index 522ea2d..cd308a70 100644
--- a/cc/animation/scroll_offset_animation_curve_unittest.cc
+++ b/cc/animation/scroll_offset_animation_curve_unittest.cc
@@ -148,7 +148,8 @@
               curve->GetValue(base::TimeDelta::FromSecondsD(duration)).y(),
               0.0002f);
 
-  curve->UpdateTarget(duration / 2, gfx::ScrollOffset(0.0, 9900.0));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(duration / 2),
+                      gfx::ScrollOffset(0.0, 9900.0));
 
   EXPECT_NEAR(duration * 1.5, curve->Duration().InSecondsF(), 0.0002f);
   EXPECT_NEAR(
@@ -163,7 +164,8 @@
       curve->GetValue(base::TimeDelta::FromSecondsD(duration * 1.5)).y(),
       0.0002f);
 
-  curve->UpdateTarget(duration, gfx::ScrollOffset(0.0, 7200.0));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(duration),
+                      gfx::ScrollOffset(0.0, 7200.0));
 
   // A closer target at high velocity reduces the duration.
   EXPECT_NEAR(duration * 1.0794, curve->Duration().InSecondsF(), 0.0002f);
@@ -187,16 +189,19 @@
   curve->SetInitialValue(gfx::ScrollOffset());
   double smallDeltaDuration = curve->Duration().InSecondsF();
 
-  curve->UpdateTarget(0.01f, gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.01f),
+                      gfx::ScrollOffset(0.f, 300.f));
   double mediumDeltaDuration = curve->Duration().InSecondsF();
 
-  curve->UpdateTarget(0.01f, gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.01f),
+                      gfx::ScrollOffset(0.f, 500.f));
   double largeDeltaDuration = curve->Duration().InSecondsF();
 
   EXPECT_GT(smallDeltaDuration, mediumDeltaDuration);
   EXPECT_GT(mediumDeltaDuration, largeDeltaDuration);
 
-  curve->UpdateTarget(0.01f, gfx::ScrollOffset(0.f, 5000.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.01f),
+                      gfx::ScrollOffset(0.f, 5000.f));
   EXPECT_EQ(largeDeltaDuration, curve->Duration().InSecondsF());
 }
 
@@ -215,7 +220,8 @@
                          base::TimeDelta::FromSecondsD(delay_in_seconds));
   EXPECT_NEAR(curve_duration, curve->Duration().InSecondsF(), 0.0002f);
 
-  curve->UpdateTarget(0.01f, gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.01f),
+                      gfx::ScrollOffset(0.f, 500.f));
   EXPECT_GT(curve_duration, curve->Duration().InSecondsF());
   EXPECT_EQ(gfx::ScrollOffset(0.f, 500.f), curve->target_value());
 }
@@ -232,7 +238,8 @@
   EXPECT_EQ(0.f, curve->Duration().InSecondsF());
 
   // Re-targeting when animation duration is 0.
-  curve->UpdateTarget(-0.01, gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.01),
+                      gfx::ScrollOffset(0.f, 300.f));
   double duration =
       ScrollOffsetAnimationCurve::SegmentDuration(
           gfx::Vector2dF(0.f, 200.f),
@@ -243,7 +250,8 @@
 
   // Re-targeting before last_retarget_, the  difference should be accounted for
   // in duration.
-  curve->UpdateTarget(-0.01, gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.01),
+                      gfx::ScrollOffset(0.f, 500.f));
   duration = ScrollOffsetAnimationCurve::SegmentDuration(
                  gfx::Vector2dF(0.f, 500.f),
                  ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
@@ -283,13 +291,15 @@
           base::TimeDelta())
           .InSecondsF() +
       0.05;
-  curve->UpdateTarget(0.05, gfx::ScrollOffset(0.f, 200.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.05),
+                      gfx::ScrollOffset(0.f, 200.f));
   EXPECT_NEAR(expected_duration, curve->Duration().InSecondsF(), 0.0002f);
 
   // Re-target 2, this should set total_animation_duration to t, which is
   // last_retarget_. This is what would cause the DCHECK failure in
   // crbug.com/645317.
-  curve->UpdateTarget(-0.145, gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.145),
+                      gfx::ScrollOffset(0.f, 300.f));
   EXPECT_NEAR(0.05, curve->Duration().InSecondsF(), 0.0002f);
 
   // Re-target 3, this should set total_animation_duration based on new_delta.
@@ -301,7 +311,8 @@
           ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
           base::TimeDelta::FromSecondsD(0.15))
           .InSecondsF();
-  curve->UpdateTarget(-0.1, gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.1),
+                      gfx::ScrollOffset(0.f, 500.f));
   EXPECT_NEAR(expected_duration, curve->Duration().InSecondsF(), 0.0002f);
 }
 
diff --git a/cc/animation/scroll_offset_animations_impl.cc b/cc/animation/scroll_offset_animations_impl.cc
index 2e1a274..00ce5bf 100644
--- a/cc/animation/scroll_offset_animations_impl.cc
+++ b/cc/animation/scroll_offset_animations_impl.cc
@@ -110,7 +110,7 @@
   // t = -delayed_by.
   trimmed -= delayed_by;
 
-  curve->UpdateTarget(trimmed.InSecondsF(), new_target);
+  curve->UpdateTarget(trimmed, new_target);
   TRACE_EVENT_INSTANT1("cc", "ScrollAnimationUpdateTarget",
                        TRACE_EVENT_SCOPE_THREAD, "UpdatedDuration",
                        curve->Duration().InMillisecondsF());
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
index 8e727fd6..1b339b18 100644
--- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
@@ -72,7 +72,7 @@
   return FloatPoint(target.x(), target.y());
 }
 
-void CompositorScrollOffsetAnimationCurve::UpdateTarget(double time,
+void CompositorScrollOffsetAnimationCurve::UpdateTarget(TimeDelta time,
                                                         FloatPoint new_target) {
   curve_->UpdateTarget(time, gfx::ScrollOffset(new_target.X(), new_target.Y()));
 }
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
index a4c0291..7b2dec4d 100644
--- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
+++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/platform/geometry/float_point.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/noncopyable.h"
+#include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace cc {
 class ScrollOffsetAnimationCurve;
@@ -49,7 +50,7 @@
   double Duration() const;
   FloatPoint TargetValue() const;
   void ApplyAdjustment(IntSize);
-  void UpdateTarget(double time, FloatPoint new_target);
+  void UpdateTarget(TimeDelta time, FloatPoint new_target);
 
   // CompositorAnimationCurve implementation.
   std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
diff --git a/third_party/blink/renderer/platform/scroll/scroll_animator.cc b/third_party/blink/renderer/platform/scroll/scroll_animator.cc
index 565abbe..d53a19e 100644
--- a/third_party/blink/renderer/platform/scroll/scroll_animator.cc
+++ b/third_party/blink/renderer/platform/scroll/scroll_animator.cc
@@ -169,7 +169,7 @@
     // of sending to the compositor.
     if (run_state_ == RunState::kRunningOnMainThread) {
       animation_curve_->UpdateTarget(
-          time_function_() - start_time_,
+          TimeDelta::FromSecondsD(time_function_() - start_time_),
           CompositorOffsetFromBlinkOffset(target_offset));
       return true;
     }
@@ -329,7 +329,7 @@
       // ::adjustScrollOffsetAnimation should have made the necessary
       // adjustment to the curve.
       animation_curve_->UpdateTarget(
-          time_function_() - start_time_,
+          TimeDelta::FromSecondsD(time_function_() - start_time_),
           CompositorOffsetFromBlinkOffset(target_offset_));
     }