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

#include "cc/trees/image_animation_controller.h"

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
#include "cc/paint/image_animation_count.h"

namespace cc {
namespace {

// The maximum number of time an animation can be delayed before it is reset to
// start from the beginning, instead of fast-forwarding to catch up to the
// desired frame.
const base::TimeDelta kAnimationResyncCutoff = base::TimeDelta::FromMinutes(5);

// Given the |desired_frame_time|, returns the time of the tick it should be
// snapped to.
base::TimeTicks SnappedTickTimeFromFrameTime(
    const viz::BeginFrameArgs& args,
    base::TimeTicks desired_frame_time) {
  auto snapped_tick_time =
      desired_frame_time.SnappedToNextTick(args.frame_time, args.interval);
  DCHECK_GE(snapped_tick_time, desired_frame_time);

  if (snapped_tick_time != desired_frame_time)
    snapped_tick_time -= args.interval;
  return snapped_tick_time;
}

}  //  namespace

ImageAnimationController::ImageAnimationController(
    base::SingleThreadTaskRunner* task_runner,
    Client* client,
    bool enable_image_animation_resync)
    : scheduler_(task_runner, client),
      enable_image_animation_resync_(enable_image_animation_resync) {}

ImageAnimationController::~ImageAnimationController() = default;

void ImageAnimationController::UpdateAnimatedImage(
    const DiscardableImageMap::AnimatedImageMetadata& data) {
  AnimationState& animation_state = animation_state_map_[data.paint_image_id];
  animation_state.UpdateMetadata(data);
}

void ImageAnimationController::RegisterAnimationDriver(
    PaintImage::Id paint_image_id,
    AnimationDriver* driver) {
  auto it = animation_state_map_.find(paint_image_id);
  DCHECK(it != animation_state_map_.end());
  it->second.AddDriver(driver);
  registered_animations_.insert(paint_image_id);
}

void ImageAnimationController::UnregisterAnimationDriver(
    PaintImage::Id paint_image_id,
    AnimationDriver* driver) {
  auto it = animation_state_map_.find(paint_image_id);
  DCHECK(it != animation_state_map_.end());
  it->second.RemoveDriver(driver);
  if (!it->second.has_drivers())
    registered_animations_.erase(paint_image_id);
}

const PaintImageIdFlatSet& ImageAnimationController::AnimateForSyncTree(
    const viz::BeginFrameArgs& args) {
  TRACE_EVENT1("cc", "ImageAnimationController::AnimateImagesForSyncTree",
               "frame_time_from_now",
               (base::TimeTicks::Now() - args.frame_time).InMillisecondsF());
  DCHECK(images_animated_on_sync_tree_.empty());

  scheduler_.WillAnimate();
  base::Optional<base::TimeTicks> next_invalidation_time;

  for (auto id : registered_animations_) {
    auto it = animation_state_map_.find(id);
    DCHECK(it != animation_state_map_.end());
    AnimationState& state = it->second;

    // Is anyone still interested in animating this image?
    state.UpdateStateFromDrivers();
    if (!state.ShouldAnimate()) {
      TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                           "ShouldAnimate - early out",
                           TRACE_EVENT_SCOPE_THREAD);
      continue;
    }

    // If we were able to advance this animation, invalidate it on the sync
    // tree.
    if (state.AdvanceFrame(args, enable_image_animation_resync_))
      images_animated_on_sync_tree_.insert(id);

    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                         "AnimationState", TRACE_EVENT_SCOPE_THREAD, "state",
                         state.ToString());
    // Update the next invalidation time to the earliest time at which we need
    // a frame to animate an image.
    // Note its important to check ShouldAnimate() here again since advancing to
    // a new frame on the sync tree means we might not need to animate this
    // image any longer.
    if (!state.ShouldAnimate())
      continue;

    DCHECK_GT(state.next_desired_tick_time(), args.frame_time);
    if (!next_invalidation_time.has_value()) {
      next_invalidation_time.emplace(state.next_desired_tick_time());
    } else {
      next_invalidation_time = std::min(state.next_desired_tick_time(),
                                        next_invalidation_time.value());
    }
  }

  if (next_invalidation_time.has_value())
    scheduler_.Schedule(next_invalidation_time.value());
  else
    scheduler_.Cancel();

  return images_animated_on_sync_tree_;
}

void ImageAnimationController::UpdateStateFromDrivers() {
  TRACE_EVENT0("cc", "UpdateStateFromAnimationDrivers");

  base::Optional<base::TimeTicks> next_invalidation_time;
  for (auto image_id : registered_animations_) {
    auto it = animation_state_map_.find(image_id);
    DCHECK(it != animation_state_map_.end());
    AnimationState& state = it->second;
    state.UpdateStateFromDrivers();

    // Note that by not updating the |next_invalidation_time| from this image
    // here, we will cancel any pending invalidation scheduled for this image
    // when updating the |scheduler_| at the end of this loop.
    if (!state.ShouldAnimate())
      continue;

    if (!next_invalidation_time.has_value()) {
      next_invalidation_time.emplace(state.next_desired_tick_time());
    } else {
      next_invalidation_time = std::min(next_invalidation_time.value(),
                                        state.next_desired_tick_time());
    }
  }

  if (next_invalidation_time.has_value())
    scheduler_.Schedule(next_invalidation_time.value());
  else
    scheduler_.Cancel();
}

void ImageAnimationController::DidActivate() {
  TRACE_EVENT0("cc", "ImageAnimationController::WillActivate");

  for (auto id : images_animated_on_sync_tree_) {
    auto it = animation_state_map_.find(id);
    DCHECK(it != animation_state_map_.end());
    it->second.PushPendingToActive();
  }
  images_animated_on_sync_tree_.clear();

  // We would retain state for images with no drivers (no recordings) to allow
  // resuming of animations. However, since the animation will be re-started
  // from the beginning after navigation, we can avoid maintaining the state.
  if (did_navigate_) {
    for (auto it = animation_state_map_.begin();
         it != animation_state_map_.end();) {
      if (it->second.has_drivers())
        it++;
      else
        it = animation_state_map_.erase(it);
    }
    did_navigate_ = false;
  }
}

size_t ImageAnimationController::GetFrameIndexForImage(
    PaintImage::Id paint_image_id,
    WhichTree tree) const {
  const auto& it = animation_state_map_.find(paint_image_id);
  DCHECK(it != animation_state_map_.end());
  return tree == WhichTree::PENDING_TREE ? it->second.pending_index()
                                         : it->second.active_index();
}

void ImageAnimationController::WillBeginImplFrame(
    const viz::BeginFrameArgs& args) {
  scheduler_.WillBeginImplFrame(args);
}

const base::flat_set<ImageAnimationController::AnimationDriver*>&
ImageAnimationController::GetDriversForTesting(
    PaintImage::Id paint_image_id) const {
  const auto& it = animation_state_map_.find(paint_image_id);
  DCHECK(it != animation_state_map_.end());
  return it->second.drivers_for_testing();
}

size_t ImageAnimationController::GetLastNumOfFramesSkippedForTesting(
    PaintImage::Id paint_image_id) const {
  const auto& it = animation_state_map_.find(paint_image_id);
  DCHECK(it != animation_state_map_.end());
  return it->second.last_num_frames_skipped_for_testing();
}

ImageAnimationController::AnimationState::AnimationState() = default;

ImageAnimationController::AnimationState::AnimationState(
    AnimationState&& other) = default;

ImageAnimationController::AnimationState&
ImageAnimationController::AnimationState::operator=(AnimationState&& other) =
    default;

ImageAnimationController::AnimationState::~AnimationState() {
  DCHECK(drivers_.empty());
}

bool ImageAnimationController::AnimationState::ShouldAnimate() const {
  DCHECK(repetitions_completed_ == 0 || is_complete());

  // If we have no drivers for this image, no need to animate it.
  if (!should_animate_from_drivers_)
    return false;

  switch (requested_repetitions_) {
    case kAnimationLoopOnce:
      if (repetitions_completed_ >= 1)
        return false;
      break;
    case kAnimationNone:
      NOTREACHED() << "We shouldn't be tracking kAnimationNone images";
      break;
    case kAnimationLoopInfinite:
      break;
    default:
      if (requested_repetitions_ <= repetitions_completed_)
        return false;
  }

  // If we have not yet received all data for this image, we can not advance to
  // an incomplete frame.
  if (!frames_[NextFrameIndex()].complete)
    return false;

  // If we don't have all data for this image, we can not trust the frame count
  // and loop back to the first frame.
  size_t last_frame_index = frames_.size() - 1;
  if (completion_state_ != PaintImage::CompletionState::DONE &&
      pending_index_ == last_frame_index) {
    return false;
  }

  return true;
}

// SCHEDULING
// The rate at which the animation progresses is decided by the frame duration,
// the time for which a particular frame should be displayed, specified in the
// metadata for the image. The animation is assumed to start from the frame_time
// of the first BeginFrame after the animation is registered and is visible.
// From here on, the time at which a frame should be displayed is the sum of
// durations for all previous frames of the animation.
// But, in order to align the work for the animation update with an impl frame,
// invalidations are requested at the beginning of the frame boundary in which
// the frame should be displayed.
bool ImageAnimationController::AnimationState::AdvanceFrame(
    const viz::BeginFrameArgs& args,
    bool enable_image_animation_resync) {
  DCHECK(ShouldAnimate());
  const base::TimeTicks next_tick_time = args.frame_time + args.interval;

  // Start the animation from the first frame, if not yet started. The code
  // falls through to catching up if the duration for the first frame is less
  // than the interval.
  if (!animation_started_) {
    DCHECK_EQ(pending_index_, 0u);

    animation_started_time_ = args.frame_time;
    next_desired_frame_time_ = args.frame_time + frames_[0].duration;
    next_desired_tick_time_ =
        SnappedTickTimeFromFrameTime(args, next_desired_frame_time_);
    animation_started_ = true;
  }

  // Don't advance the animation if its not time yet to move to the next frame.
  if (args.frame_time < next_desired_tick_time_)
    return needs_invalidation();

  // If the animation is more than 5 min out of date, we don't bother catching
  // up and start again from the current frame.
  // Note that we don't need to invalidate this image since the active tree
  // is already displaying the current frame.
  if (enable_image_animation_resync &&
      args.frame_time - next_desired_frame_time_ > kAnimationResyncCutoff) {
    TRACE_EVENT_INSTANT0("cc", "Resync - early out", TRACE_EVENT_SCOPE_THREAD);
    DCHECK_EQ(pending_index_, active_index_);
    next_desired_frame_time_ =
        args.frame_time + frames_[pending_index_].duration;
    next_desired_tick_time_ =
        std::max(SnappedTickTimeFromFrameTime(args, next_desired_frame_time_),
                 next_tick_time);
    return needs_invalidation();
  }

  // Keep catching up the animation until we reach the frame we should be
  // displaying now.
  const size_t last_frame_index = frames_.size() - 1;
  size_t num_of_frames_advanced = 0u;
  while (next_desired_tick_time_ < next_tick_time && ShouldAnimate()) {
    num_of_frames_advanced++;
    size_t next_frame_index = NextFrameIndex();
    TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                         "FrameDurationAndIndex", TRACE_EVENT_SCOPE_THREAD,
                         "frame_index", next_frame_index, "duration",
                         frames_[next_frame_index].duration.InMillisecondsF());
    base::TimeTicks next_desired_frame_time =
        next_desired_frame_time_ + frames_[next_frame_index].duration;

    // The image may load more slowly than it's supposed to animate, so that by
    // the time we reach the end of the first repetition, we're well behind.
    // Start the animation from the first frame in this case, so that we don't
    // skip frames (or whole iterations) trying to "catch up".  This is a
    // tradeoff: It guarantees users see the whole animation the second time
    // through and don't miss any repetitions, and is closer to what other
    // browsers do; on the other hand, it makes animations "less accurate" for
    // pages that try to sync an image and some other resource (e.g. audio),
    // especially if users switch tabs (and thus stop drawing the animation,
    // which will pause it) during that initial loop, then switch back later.
    if (enable_image_animation_resync && next_frame_index == 0u &&
        repetitions_completed_ == 1 &&
        next_desired_frame_time <= args.frame_time) {
      pending_index_ = 0u;
      next_desired_frame_time_ = args.frame_time + frames_[0].duration;
      next_desired_tick_time_ =
          std::max(SnappedTickTimeFromFrameTime(args, next_desired_frame_time_),
                   next_tick_time);
      repetitions_completed_ = 0;
      break;
    }

    pending_index_ = next_frame_index;
    next_desired_frame_time_ = next_desired_frame_time;
    next_desired_tick_time_ =
        SnappedTickTimeFromFrameTime(args, next_desired_frame_time_);

    // If we are advancing to the last frame and the image has been completely
    // loaded (which means that the frame count is known to be accurate), we
    // just finished a loop in the animation.
    if (pending_index_ == last_frame_index && is_complete())
      repetitions_completed_++;
  }

  // We should have advanced a single frame, anything more than that are frames
  // skipped trying to catch up.
  DCHECK_GT(num_of_frames_advanced, 0u);
  last_num_frames_skipped_ = num_of_frames_advanced - 1u;
  UMA_HISTOGRAM_COUNTS_100000("AnimatedImage.NumOfFramesSkipped.Compositor",
                              last_num_frames_skipped_);
  return needs_invalidation();
}

void ImageAnimationController::AnimationState::UpdateMetadata(
    const DiscardableImageMap::AnimatedImageMetadata& data) {
  paint_image_id_ = data.paint_image_id;

  DCHECK_NE(data.repetition_count, kAnimationNone);
  requested_repetitions_ = data.repetition_count;

  DCHECK(frames_.size() <= data.frames.size())
      << "Updated recordings can only append frames";
  frames_ = data.frames;
  DCHECK_GT(frames_.size(), 1u);

  DCHECK(completion_state_ != PaintImage::CompletionState::DONE ||
         data.completion_state == PaintImage::CompletionState::DONE)
      << "If the image was marked complete before, it can not be incomplete in "
         "a new update";
  completion_state_ = data.completion_state;

  // Update the repetition count in case we have displayed the last frame and
  // we now know the frame count to be accurate.
  size_t last_frame_index = frames_.size() - 1;
  if (pending_index_ == last_frame_index && is_complete() &&
      repetitions_completed_ == 0)
    repetitions_completed_++;

  // Reset the animation if the sequence id received in this recording was
  // incremented.
  if (reset_animation_sequence_id_ < data.reset_animation_sequence_id) {
    reset_animation_sequence_id_ = data.reset_animation_sequence_id;
    ResetAnimation();
  }
}

void ImageAnimationController::AnimationState::PushPendingToActive() {
  active_index_ = pending_index_;
}

void ImageAnimationController::AnimationState::AddDriver(
    AnimationDriver* driver) {
  drivers_.insert(driver);
}

void ImageAnimationController::AnimationState::RemoveDriver(
    AnimationDriver* driver) {
  drivers_.erase(driver);
}

void ImageAnimationController::AnimationState::UpdateStateFromDrivers() {
  should_animate_from_drivers_ = false;
  for (auto* driver : drivers_) {
    if (driver->ShouldAnimate(paint_image_id_)) {
      should_animate_from_drivers_ = true;
      break;
    }
  }
}

void ImageAnimationController::AnimationState::ResetAnimation() {
  animation_started_ = false;
  next_desired_frame_time_ = base::TimeTicks();
  repetitions_completed_ = 0;
  pending_index_ = 0u;
  // Don't reset the |active_index_|, tiles on the active tree still need it.
}

std::string ImageAnimationController::AnimationState::ToString() const {
  std::ostringstream str;
  str << "paint_image_id[" << paint_image_id_ << "]\nrequested_repetitions["
      << requested_repetitions_ << "]\nrepetitions_completed["
      << requested_repetitions_ << "]\ndrivers[" << drivers_.size()
      << "]\nactive_index[" << active_index_ << "]\npending_index["
      << pending_index_ << "]\nnext_desired_frame_time["
      << (next_desired_frame_time_ - animation_started_time_).InMillisecondsF()
      << "]\nnext_desired_tick_time["
      << (next_desired_tick_time_ - animation_started_time_).InMillisecondsF()
      << "]\nshould_animate_from_drivers[" << should_animate_from_drivers_
      << "]\ncompletion_state[" << static_cast<int>(completion_state_) << "]";
  return str.str();
}

size_t ImageAnimationController::AnimationState::NextFrameIndex() const {
  if (!animation_started_)
    return 0u;
  return (pending_index_ + 1) % frames_.size();
}

ImageAnimationController::InvalidationScheduler::InvalidationScheduler(
    base::SingleThreadTaskRunner* task_runner,
    Client* client)
    : task_runner_(task_runner), client_(client), weak_factory_(this) {
  DCHECK(task_runner_->BelongsToCurrentThread());
}

ImageAnimationController::InvalidationScheduler::~InvalidationScheduler() {
  DCHECK(task_runner_->BelongsToCurrentThread());
}

void ImageAnimationController::InvalidationScheduler::Schedule(
    base::TimeTicks animation_time) {
  auto now = now_callback_for_testing_.is_null()
                 ? base::TimeTicks::Now()
                 : now_callback_for_testing_.Run();

  // If an animation or impl frame is already pending, don't schedule another
  // notification. We will schedule the next notification based on the latest
  // animation state during AnimateForSyncTree, or in WillBeginImplFrame if
  // needed.
  if (state_ == InvalidationState::kPendingInvalidation ||
      state_ == InvalidationState::kPendingImplFrame) {
    return;
  }

  // The requested notification time can be in the past. For instance, if an
  // animation was paused because the image became invisible.
  if (animation_time < now)
    animation_time = now;

  // If we already have a notification scheduled to run at this time, no need to
  // Cancel it.
  if (state_ == InvalidationState::kPendingRequestBeginFrame &&
      animation_time == next_animation_time_)
    return;

  // Cancel the pending notification since we the requested notification time
  // has changed.
  Cancel();

  base::TimeDelta delta = animation_time - now;
  TRACE_EVENT1("cc", "ScheduleFrameForImageAnimation", "delta",
               delta.InMillisecondsF());

  state_ = InvalidationState::kPendingRequestBeginFrame;
  next_animation_time_ = animation_time;
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&InvalidationScheduler::RequestBeginFrame,
                     weak_factory_.GetWeakPtr()),
      delta);
}

void ImageAnimationController::InvalidationScheduler::Cancel() {
  state_ = InvalidationState::kIdle;
  weak_factory_.InvalidateWeakPtrs();
}

void ImageAnimationController::InvalidationScheduler::RequestBeginFrame() {
  TRACE_EVENT0(
      "cc",
      "ImageAnimationController::InvalidationScheduler::RequestBeginFrame");
  DCHECK_EQ(state_, InvalidationState::kPendingRequestBeginFrame);

  state_ = InvalidationState::kPendingImplFrame;
  client_->RequestBeginFrameForAnimatedImages();
}

void ImageAnimationController::InvalidationScheduler::WillAnimate() {
  // Unless the sync tree came after we explicitly requested an invalidation,
  // we can't proceed to idle state.
  if (state_ != InvalidationState::kPendingInvalidation)
    return;

  state_ = InvalidationState::kIdle;
  next_animation_time_ = base::TimeTicks();
}

void ImageAnimationController::InvalidationScheduler::WillBeginImplFrame(
    const viz::BeginFrameArgs& args) {
  switch (state_) {
    case InvalidationState::kIdle:
    case InvalidationState::kPendingInvalidation:
      // We don't need an invalidation or one is already pending. In either
      // case, no state change is needed.
      break;
    case InvalidationState::kPendingRequestBeginFrame:
      if (args.frame_time >= next_animation_time_) {
        // If we can make progress on the animation in this impl frame request
        // an invalidation.
        RequestInvalidation();
      }
      // Otherwise the pending notification will ensure we get another impl
      // impl frame at the |next_animation_time_|.
      break;
    case InvalidationState::kPendingImplFrame:
      if (args.frame_time >= next_animation_time_) {
        // We received the impl frame needed for the animation, request an
        // invalidation.
        RequestInvalidation();
      } else {
        // Ideally this should be the impl frame we wanted, so we should always
        // be able to animate at this frame. But that might not be the case if
        // we get a missed BeginFrame. In that case, make a request for the next
        // impl frame.
        client_->RequestBeginFrameForAnimatedImages();
      }
      break;
  }
}

void ImageAnimationController::InvalidationScheduler::RequestInvalidation() {
  TRACE_EVENT0(
      "cc",
      "ImageAnimationController::InvalidationScheduler::RequestInvalidation");
  DCHECK_NE(state_, InvalidationState::kIdle);
  DCHECK_NE(state_, InvalidationState::kPendingInvalidation);

  // Any pending notification can/should be cancelled once an invalidation is
  // requested because each time we animate a sync tree, we schedule a task for
  // the next animation update if necessary.
  Cancel();

  state_ = InvalidationState::kPendingInvalidation;
  client_->RequestInvalidationForAnimatedImages();
}

}  // namespace cc
