// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/navigation_transitions/physics_model.h"

#include <algorithm>
#include <numbers>
#include <vector>

#include "base/logging.h"
#include "base/notreached.h"
#include "base/numerics/ranges.h"
#include "base/time/time.h"

// TODO(liuwilliam): The velocity and positions should have the same direction.
//
// Notes:
// - Directions: for offsets/positions and the velocity of the cancel spring,
//   the right edge direction is "+" and the left is "-"; for commit pending and
//   invoke spring velocities, the right edge direction for is "-" and the left
//   is "+".
// - The physics model internally operates in the normalized viewport space
//   while takes/returns physical pixel values as input/output. The spacial
//   variables are suffixed with `_viewport` or `_physical` to avoid confusion.

namespace content {

namespace {

// The tolerance value for which two floats are consider equal.
constexpr float kFloatTolerance = 0.001f;

// Used to replace NaN and Inf.
constexpr float kInvalidVelocity = 999.f;

// Springs.
//
// Determines when the spring is stabilized (the damped amplitude no longer
// changes significantly). Larger the value, the longer the spring takes to
// stabilize, but the spring amplitude is damped more gently.
constexpr int kSpringResponse = 708;

// How much the spring overshoots. Smaller the value, more bouncy the spring.
constexpr float kSpringDampingRatio = 0.81f;

// The size of the spring location history.
constexpr int kSpringHistorySize = 10;

// A spring is considered at rest if it has used at least
// `kSpringAtRestThreshold`*`kSpringHistorySize` amount of energy.
constexpr int kSpringAtRestThreshold = 10;

// Physics model.
//
// The size of the touch points store in `PhysicsModel`. Used to interpolate
// the finger's terminal velocity when the model switches from the finger drag
// curve driven to spring driven.
constexpr int kPhysicsModelHistorySize = 10;

bool IsValidVelocity(float velocity) {
  return !base::IsApproximatelyEqual(velocity, kInvalidVelocity,
                                     kFloatTolerance);
}

// Solves `positions`=`slope`*`timestamps`+ displacement(not calculated).
void SolveLeastSquare(const std::vector<float>& timestamps,
                      const std::vector<float>& positions,
                      float* slope) {
  CHECK_EQ(timestamps.size(), positions.size());

  const size_t num_pts = timestamps.size();
  if (num_pts <= 1) {
    DLOG(WARNING) << "Interpolating velocity with " << num_pts << " points";
    if (slope) {
      *slope = kInvalidVelocity;
    }
    return;
  }

  float sum_timestamps = 0;
  float sum_positions = 0;
  float sum_times_positions = 0;
  float sum_timestamps_sq = 0;

  for (size_t i = 0; i < num_pts; ++i) {
    float t = timestamps[i];
    float p = positions[i];
    sum_timestamps += t;
    sum_positions += p;
    sum_times_positions += t * p;
    sum_timestamps_sq += t * t;
  }

  if (slope) {
    float denominator =
        (sum_timestamps_sq - sum_timestamps * sum_timestamps / num_pts);
    if (base::IsApproximatelyEqual(denominator, 0.f, kFloatTolerance)) {
      *slope = kInvalidVelocity;
    } else {
      *slope =
          (sum_times_positions - sum_timestamps * sum_positions / num_pts) /
          denominator;
    }
  }
}

}  // namespace

class Spring {
 public:
  struct Position {
    // Calculated offset of the spring's position w.r.t. its equilibrium.
    float equilibrium_offset_viewport;

    // The amount of time delta since the spring is released (i.e., the start of
    // the animation).
    base::TimeDelta timestamp;

    // If the spring is at rest then it won't bounce anymore. A spring is at
    // rest if it has lost enough energe, or it is <= 1 pixel away from its
    // equilibrium.
    bool at_rest;
  };

  Spring(int frequency_response,
         float damping_ratio,
         float device_scaling_factor)
      : frequency_response_(frequency_response),
        damping_ratio_(damping_ratio),
        device_scale_factor_(device_scaling_factor) {
    float stiffness =
        std::pow(2 * std::numbers::pi_v<float> / frequency_response_, 2) *
        mass_;
    undamped_natural_frequency_ = std::sqrt(stiffness / mass_);
    damped_natural_frequency_ =
        undamped_natural_frequency_ *
        std::sqrt(std::abs(1 - std::pow(damping_ratio_, 2)));
    // `damped_natural_frequency_` will be used as a denominator. It shouldn't
    // be zero.
    CHECK(!base::IsApproximatelyEqual(damped_natural_frequency_, 0.f,
                                      kFloatTolerance));
    CHECK(!base::IsApproximatelyEqual(device_scale_factor_, 0.f,
                                      kFloatTolerance));
  }
  Spring(const Spring&) = delete;
  Spring& operator=(const Spring&) = delete;
  ~Spring() = default;

  Position GetPosition(float start_offset, base::TimeDelta time) {
    // The general solution to a damped oscillator.
    const float a = undamped_natural_frequency_ * damping_ratio_;
    const float c =
        (initial_velocity_ + a * start_offset) / damped_natural_frequency_;
    const float ms = time.InMillisecondsF();
    const float offset =
        std::exp(-a * ms) *
        (c * std::sin(damped_natural_frequency_ * ms) +
         start_offset * std::cos(damped_natural_frequency_ * ms));

    spring_position_history_.push_back({.equilibrium_offset_viewport = offset,
                                        .timestamp = time,
                                        .at_rest = false});

    if (spring_position_history_.size() > kSpringHistorySize) {
      spring_position_history_.pop_front();
      float energy = 0;
      for (const auto& p : spring_position_history_) {
        // Energy is proportional to the square of the amplitude.
        energy += p.equilibrium_offset_viewport * p.equilibrium_offset_viewport;
      }
      // If the spring has used `kSpringAtRestThreshold * kSpringHistorySize`
      // amount energy in the last `kSpringHistorySize` locations, consider it
      // is at rest.
      spring_position_history_.back().at_rest |=
          energy < kSpringAtRestThreshold * kSpringHistorySize;
    }

    // Less than 1pixel from its equilibrium.
    spring_position_history_.back().at_rest |=
        offset <= 1.f / device_scale_factor_;

    return spring_position_history_.back();
  }

  float ComputeVelocity() {
    std::vector<float> timestamps;
    std::vector<float> positions;
    timestamps.reserve(spring_position_history_.size());
    positions.reserve(spring_position_history_.size());

    for (const auto& p : spring_position_history_) {
      timestamps.push_back(p.timestamp.InMillisecondsF());
      positions.push_back(p.equilibrium_offset_viewport);
    }

    float velocity = 0;
    SolveLeastSquare(timestamps, positions, &velocity);

    return velocity;
  }

  float initial_velocity() const { return initial_velocity_; }
  void set_initial_velocity(float velocity) { initial_velocity_ = velocity; }

 private:
  // Intrinsic properties of the spring.
  const int frequency_response_;
  const float damping_ratio_;
  const float device_scale_factor_;
  float undamped_natural_frequency_;
  float damped_natural_frequency_;
  const float mass_ = 1.f;

  // The initial velocity might not be zero: to enture the smooth animation
  // hand-off from spring A to spring B, we might set B's initial velocity to
  // A's terminal velocity.
  float initial_velocity_ = 0.f;

  // The last few positions of the spring. Used to interpolate the velocity. It
  // has a max size of `kSpringHistorySize`.
  std::deque<Position> spring_position_history_;
};

PhysicsModel::PhysicsModel(int screen_width_physical, float device_scale_factor)
    : viewport_width_(screen_width_physical / device_scale_factor),
      device_scale_factor_(device_scale_factor) {
  spring_cancel_ = std::make_unique<Spring>(
      /*frequency_response=*/200,
      /*damping_ratio=*/0.9,
      /*device_scaling_factor=*/device_scale_factor_);
  spring_commit_pending_ = std::make_unique<Spring>(
      /*frequency_response=*/kSpringResponse,
      /*damping_ratio=*/kSpringDampingRatio,
      /*device_scaling_factor=*/device_scale_factor_);
  spring_invoke_ = std::make_unique<Spring>(
      /*frequency_response=*/200,
      /*damping_ratio=*/0.95, /*device_scaling_factor=*/device_scale_factor_);
}

PhysicsModel::~PhysicsModel() = default;

PhysicsModel::Result PhysicsModel::OnAnimate(
    base::TimeTicks request_animation_frame) {
  // `commit_pending_acceleration_start_` needs to be recorded before we switch
  // to the next driver.
  RecordCommitPendingAccelerationStartIfNeeded(request_animation_frame);

  AdvanceToNextAnimationDriver(request_animation_frame);

  base::TimeDelta raf_since_start =
      CalculateRequestAnimationFrameSinceStart(request_animation_frame);

  // Ask the animation driver for the offset of the next frame.
  Spring::Position spring_position;
  switch (animation_driver_) {
    case Driver::kSpringCommitPending: {
      spring_position = spring_commit_pending_->GetPosition(
          viewport_width_ * kTargetCommitPendingRatio -
              animation_start_offset_viewport_,
          raf_since_start);
      // Prevent overshoot the right edge.
      foreground_offset_viewport_ = std::min(
          viewport_width_, viewport_width_ * kTargetCommitPendingRatio -
                               spring_position.equilibrium_offset_viewport);
      // https://crbug.com/326850774: The commit-pending spring can also
      // overshoot the left edge.
      foreground_offset_viewport_ = std::max(0.f, foreground_offset_viewport_);
      break;
    }
    case Driver::kSpringInvoke: {
      spring_position = spring_invoke_->GetPosition(
          viewport_width_ - animation_start_offset_viewport_, raf_since_start);
      // Prevent overshoot the right edge.
      foreground_offset_viewport_ = std::min(
          viewport_width_,
          viewport_width_ - spring_position.equilibrium_offset_viewport);
      // https://crbug.com/326850774: The invoke spring can also overshoot the
      // left edge.
      foreground_offset_viewport_ = std::max(0.f, foreground_offset_viewport_);
      break;
    }
    case Driver::kSpringCancel: {
      spring_position = spring_cancel_->GetPosition(
          animation_start_offset_viewport_, raf_since_start);
      // Prevent overshoot the left edge.
      foreground_offset_viewport_ =
          std::max(spring_position.equilibrium_offset_viewport, 0.f);
      // https://crbug.com/326850774: The cancel spring can also overshoot the
      // right edge.
      foreground_offset_viewport_ =
          std::min(viewport_width_, foreground_offset_viewport_);
      break;
    }
    case Driver::kDragCurve: {
      NOTREACHED();
    }
  }

  foreground_has_reached_target_commit_pending_ |=
      foreground_offset_viewport_ >=
      kTargetCommitPendingRatio * viewport_width_;

  last_request_animation_frame_ = request_animation_frame;

  return Result{
      .foreground_offset_physical =
          std::round(foreground_offset_viewport_ * device_scale_factor_),
      .background_offset_physical =
          std::round(ForegroundToBackGroundOffset(foreground_offset_viewport_) *
                     device_scale_factor_),
      // Done only if we have finished playing the terminal animations.
      .done = (spring_position.at_rest &&
               (animation_driver_ == Driver::kSpringInvoke ||
                animation_driver_ == Driver::kSpringCancel)),
  };
}

// Note: we don't call `StartAnimating()` with the drag curve because
// `timestamp` for the drag curve is not from the wallclock. The non-wallclock
// time shouldn't be stored as `animation_start_time_`.
PhysicsModel::Result PhysicsModel::OnGestureProgressed(
    float movement_physical,
    base::TimeTicks timestamp) {
  CHECK_EQ(animation_driver_, Driver::kDragCurve);
  const float movement_viewport = movement_physical / device_scale_factor_;

  foreground_offset_viewport_ =
      std::max(0.f, FingerDragCurve(movement_viewport));
  touch_points_history_.push_back(TouchEvent{
      .position_viewport = foreground_offset_viewport_,
      .timestamp = timestamp,
  });
  if (touch_points_history_.size() > kPhysicsModelHistorySize) {
    touch_points_history_.pop_front();
  }
  return Result{
      .foreground_offset_physical =
          foreground_offset_viewport_ * device_scale_factor_,
      .background_offset_physical =
          ForegroundToBackGroundOffset(foreground_offset_viewport_) *
          device_scale_factor_,
      .done = false,
  };
}

void PhysicsModel::SwitchSpringForReason(SwitchSpringReason reason) {
  switch (reason) {
    case kGestureCancelled:
    case kGestureInvoked: {
      // The navigation just started by the caller in the same atomic callstack
      // if the user decides to start the navigation. The navigation hasn't
      // committed or been cancelled yet.
      CHECK_EQ(navigation_state_, NavigationState::kNotStarted);

      if (reason == kGestureCancelled) {
        navigation_state_ = NavigationState::kCancelled;
      }
      if (reason == kGestureInvoked) {
        navigation_state_ = NavigationState::kStarted;
      }
      // Next `OnAnimate()` call will switch to `kSpringCancel` or
      // `kSpringCommitPending`.
      break;
    }
    case kBeforeUnloadDispatched: {
      navigation_state_ = NavigationState::kBeforeUnloadDispatched;
      // On next `OnAnimate()`, `animation_driver_` will switch to
      // `kSpringCommitPending`.
      break;
    }
    case kBeforeUnloadShown: {
      CHECK_EQ(navigation_state_, NavigationState::kBeforeUnloadDispatched);

      navigation_state_ = NavigationState::kBeforeUnloadShown;
      // On next `OnAnimate()`, `animation_driver_` will switch to
      // `kSpringCancel`.
      break;
    }
    case kBeforeUnloadAckProceed: {
      CHECK_EQ(navigation_state_, NavigationState::kBeforeUnloadShown);
      navigation_state_ = NavigationState::kBeforeUnloadAckedProceed;
      // On next `OnAnimate()`, `animation_driver_` will switch to
      // `kSpringCommitPending`.
      break;
    }
    case kCancelledBeforeStart: {
      navigation_state_ = NavigationState::kCancelled;
    }
  }
}

void PhysicsModel::OnNavigationFinished(bool committed) {
  switch (navigation_state_) {
    // For a gesture navigation that doesn't have a BeforeUnload handler.
    case NavigationState::kStarted:
    // It's possible the navigation commits so fast that the commit-pending
    // spring hasn't played a single frame.
    case NavigationState::kBeforeUnloadDispatched:
    // A navigation starts after running the BeforeUnload handler.
    case NavigationState::kBeforeUnloadAckedProceed: {
      break;
    }
    // A navigation needs to start first.
    case NavigationState::kNotStarted:
    // Not reachable because the browser is waiting for the ack from the
    // renderer.
    case NavigationState::kBeforeUnloadShown:
    // A cancelled navigation should never commit.
    case NavigationState::kCancelled:
    // A navigation can only commit (finish) once.
    case NavigationState::kCommitted: {
      NOTREACHED();
    }
  }

  navigation_state_ =
      committed ? NavigationState::kCommitted : NavigationState::kCancelled;
}

bool PhysicsModel::ReachedCommitPending() const {
  return animation_driver_ == Driver::kSpringCommitPending &&
         foreground_has_reached_target_commit_pending_;
}

void PhysicsModel::StartAnimating(base::TimeTicks time) {
  animation_start_time_ = time;
  animation_start_offset_viewport_ = foreground_offset_viewport_;
}

float PhysicsModel::ForegroundToBackGroundOffset(float fg_offset_viewport) {
  float bg_offset_viewport = 0.f;

  if ((animation_driver_ == Driver::kSpringCommitPending ||
       animation_driver_ == Driver::kSpringInvoke) &&
      foreground_has_reached_target_commit_pending_) {
    // Do not bounce the background page when the foreground page has reached
    // the commit-pending point, once we have switched to the commit-pending
    // spring or the invoke spring.
    return bg_offset_viewport;
  }

  // Maps:
  // fg_offset_viewport      0 -> 0.85W -> W
  // To:
  // bg_offset_viewport -0.25W ->     0 -> 0
  const float fg_commit_position_viewport =
      viewport_width_ * kTargetCommitPendingRatio;
  // If the foreground has passed the commit position, the background should be
  // at origin.
  if (fg_offset_viewport > fg_commit_position_viewport) {
    return bg_offset_viewport;
  }
  const float fg_progress_to_commit_position =
      fg_offset_viewport / fg_commit_position_viewport;
  bg_offset_viewport = (1 - fg_progress_to_commit_position) *
                       kScreenshotInitialPositionRatio * viewport_width_;
  return bg_offset_viewport;
}

float PhysicsModel::FingerDragCurve(float movement_viewport) {
  return foreground_offset_viewport_ +
         kTargetCommitPendingRatio * movement_viewport;
}

float PhysicsModel::CalculateVelocity(base::TimeTicks time) {
  float velocity = 0;

  std::vector<float> timestamps;
  std::vector<float> positions;
  timestamps.reserve(touch_points_history_.size());
  positions.reserve(touch_points_history_.size());
  for (const auto& p : touch_points_history_) {
    timestamps.push_back((time - p.timestamp).InMillisecondsF());
    positions.push_back(p.position_viewport);
  }
  SolveLeastSquare(timestamps, positions, &velocity);
  return velocity;
}

void PhysicsModel::RecordCommitPendingAccelerationStartIfNeeded(
    base::TimeTicks request_animation_frame) {
  if (animation_driver_ == Driver::kSpringCommitPending &&
      navigation_state_ == NavigationState::kCommitted) {
    float vel = spring_commit_pending_->ComputeVelocity();
    if (IsValidVelocity(vel) && vel > kFloatTolerance) {
      // If the navigation is committed and `spring_commit_pending_` is moving
      // at the opposite direction of the invoke animation, record the first
      // requested frame's timestamp. This timestamp will be used to speed up
      // the opposite-moving animation of the commit-pending spring. Since the
      // navigation is committed, we should display the invoke animation as soon
      // as possible.
      if (commit_pending_acceleration_start_.is_null()) {
        commit_pending_acceleration_start_ = request_animation_frame;
      }
    } else {
      // `spring_commit_pending_` moves in the same direction as the invoke
      // animation. Reset `commit_pending_acceleration_start_`.
      commit_pending_acceleration_start_ = base::TimeTicks();
    }
  }
}

void PhysicsModel::AdvanceToNextAnimationDriver(
    base::TimeTicks request_animation_frame) {
  switch (animation_driver_) {
    case Driver::kDragCurve: {
      // We can only reach here for once, and once only.
      CHECK(last_request_animation_frame_.is_null());
      StartAnimating(request_animation_frame);
      float finger_vel = CalculateVelocity(request_animation_frame);
      if (navigation_state_ == NavigationState::kCancelled ||
          navigation_state_ == NavigationState::kBeforeUnloadShown) {
        animation_driver_ = Driver::kSpringCancel;
        // The sign of the velocities from the drag curve and the cancel spring
        // have opposite semantics, so we need to multiply by -1.
        spring_cancel_->set_initial_velocity(-finger_vel);
      } else if (navigation_state_ == NavigationState::kCommitted) {
        animation_driver_ = Driver::kSpringInvoke;
        spring_invoke_->set_initial_velocity(finger_vel);
      } else {
        CHECK(navigation_state_ == NavigationState::kStarted ||
              navigation_state_ == NavigationState::kBeforeUnloadDispatched ||
              // This can happen when the renderer sends the BeforeUnload ack
              // back to the browser so fast, that the cancel spring hasn't
              // played a single frame thus we are still at
              //`Driver::kDragCurve`. Typically this happens when the renderer
              // doesn't have a sticky UserActivation.
              navigation_state_ == NavigationState::kBeforeUnloadAckedProceed);
        animation_driver_ = Driver::kSpringCommitPending;
        spring_commit_pending_->set_initial_velocity(finger_vel);
      }
      break;
    }
    case Driver::kSpringCommitPending: {
      // It is rare but possible that we haven't played a single frame with
      // commit-pending spring, where `last_request_animation_frame_` is null.
      auto start_animating_raf = !last_request_animation_frame_.is_null()
                                     ? last_request_animation_frame_
                                     : request_animation_frame;
      if (commit_pending_acceleration_start_.is_null() &&
          navigation_state_ == NavigationState::kCommitted) {
        // Only switch from commit-pending spring to the invoke spring when:
        // - The commit-pending is moving in the same direction as the invoke
        //   animation, for which `commit_pending_acceleration_start_` is null.
        // - The navigation is committed.
        StartAnimating(start_animating_raf);
        animation_driver_ = Driver::kSpringInvoke;
        spring_invoke_->set_initial_velocity(
            spring_commit_pending_->ComputeVelocity());
      } else if (navigation_state_ == NavigationState::kCancelled ||
                 navigation_state_ == NavigationState::kBeforeUnloadShown) {
        StartAnimating(start_animating_raf);
        animation_driver_ = Driver::kSpringCancel;
        // TODO(crbug.com/40945408): Ditto.
        spring_cancel_->set_initial_velocity(1.f);
      } else {
        // Keep running the commit-pending animation if:
        // - The commit-pending animation is being accelerated, for which
        //   `last_request_animation_frame_` is non-null.
        // - The on-going navigation hasn't reached its final state
        //   (`OnDidFinishNavigation()` not yet called).
        // - If the browser has asked the renderer to run the BeforeUnload
        //   handler but the renderer hasn't ack'ed the message.
        const bool commit_pending_being_accelerated =
            (!last_request_animation_frame_.is_null() &&
             navigation_state_ == NavigationState::kCommitted);
        const bool nav_started =
            navigation_state_ == NavigationState::kStarted ||
            navigation_state_ == NavigationState::kBeforeUnloadAckedProceed;
        const bool nav_requested =
            navigation_state_ == NavigationState::kBeforeUnloadDispatched;
        CHECK(commit_pending_being_accelerated || nav_started || nav_requested);
      }
      break;
    }
    case Driver::kSpringCancel: {
      if (navigation_state_ == NavigationState::kBeforeUnloadAckedProceed) {
        // We only switch away from `kSpringCancel` when the renderer has acked
        // the BeforeUnload message and navigation should proceed. When the
        // BeforeUnload message is dispatched to the renderer, `kSpringCancel`
        // drives the animation. When the renderer acks to proceed the
        // navigation, we switch from `kSpringCancel` to `kSpringCommitPending`.

        // It's visually incorrect to use `last_request_animation_frame_` here.
        // Say the last frame is animated by `kSpringCancel` at time T and the
        // user interacts with the BeforeUnload prompt at T+10s to begin the
        // navigation. It's incorrect to tell `kSpringCommitPending` to animate
        // the first frame as if it has been 10 seconds since the last frame.
        StartAnimating(request_animation_frame);
        animation_driver_ = Driver::kSpringCommitPending;
        // Set the initial velocity to zero because the commit-pending (or
        // invoke) spring will move the active page across the entire viewport.
        // A high velocity would make the animation look like it's skipping
        // frames.
        spring_commit_pending_->set_initial_velocity(0.f);
      } else if (navigation_state_ == NavigationState::kCommitted)
          [[unlikely]] {
        // Also rare but possible (e.g., in tests) for the navigation to commit
        // so fast that the commit-pending spring hasn't played a single frame,
        // after BeforeUnload is executed with "proceed". Directly switch to the
        // invoke spring in this case.
        StartAnimating(request_animation_frame);
        animation_driver_ = Driver::kSpringInvoke;
        spring_invoke_->set_initial_velocity(0.f);
      }
      break;
    }
    // Shouldn't switch from the terminal states.
    case Driver::kSpringInvoke:
      return;
  }

  if (!IsValidVelocity(spring_invoke_->initial_velocity())) {
    spring_invoke_->set_initial_velocity(-2.0);
  }
  if (!IsValidVelocity(spring_commit_pending_->initial_velocity())) {
    spring_commit_pending_->set_initial_velocity(0.f);
  }
  if (!IsValidVelocity(spring_cancel_->initial_velocity())) {
    spring_cancel_->set_initial_velocity(-1.f);
  }
}

base::TimeDelta PhysicsModel::CalculateRequestAnimationFrameSinceStart(
    base::TimeTicks request_animation_frame) {
  // Shouldn't be called for the drag curve animation.
  CHECK_NE(animation_driver_, Driver::kDragCurve);

  base::TimeDelta raf_since_start =
      request_animation_frame - animation_start_time_;

  // Accelerate the commit-pending animation if necessary.
  if (!commit_pending_acceleration_start_.is_null()) {
    CHECK_EQ(navigation_state_, NavigationState::kCommitted);
    CHECK_EQ(animation_driver_, Driver::kSpringCommitPending);
    // Add a delta to all the left-moving frames. This is to "speed up" the
    // spring animation, so it can start to move to the right sooner, to display
    // the invoke animation.
    //
    // Ex:
    // - request animation frame timeline: [37, 39, 41, 43, 45 ...]
    // - raf timeline with the delta:      [37, 41, 45, 49, 53 ...]
    //
    // So the net effect is the animation is sped up twice.
    raf_since_start +=
        (request_animation_frame - commit_pending_acceleration_start_);
  }

  return raf_since_start;
}

}  // namespace content
