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_));
}