// Copyright 2015 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 "services/gfx/compositor/backend/vsync_scheduler.h"

#include <algorithm>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"

namespace compositor {

constexpr int64_t VsyncScheduler::kMinVsyncInterval;
constexpr int64_t VsyncScheduler::kMaxVsyncInterval;

VsyncScheduler::VsyncScheduler(
    const scoped_refptr<base::TaskRunner>& task_runner,
    const SchedulerCallbacks& callbacks)
    : VsyncScheduler(task_runner, callbacks, base::Bind(&MojoGetTimeTicksNow)) {
}

VsyncScheduler::VsyncScheduler(
    const scoped_refptr<base::TaskRunner>& task_runner,
    const SchedulerCallbacks& callbacks,
    const Clock& clock)
    : state_(std::make_shared<State>(task_runner, callbacks, clock)) {}

VsyncScheduler::~VsyncScheduler() {}

void VsyncScheduler::ScheduleFrame(SchedulingMode scheduling_mode) {
  state_->ScheduleFrame(scheduling_mode);
}

VsyncScheduler::State::State(const scoped_refptr<base::TaskRunner>& task_runner,
                             const SchedulerCallbacks& callbacks,
                             const Clock& clock)
    : task_runner_(task_runner), callbacks_(callbacks), clock_(clock) {}

VsyncScheduler::State::~State() {}

bool VsyncScheduler::State::Start(int64_t vsync_timebase,
                                  int64_t vsync_interval,
                                  int64_t update_phase,
                                  int64_t snapshot_phase,
                                  int64_t presentation_phase) {
  // Be slightly paranoid.  Timing glitches are hard to find and the
  // vsync parameters will typically come from other services.
  // Ensure vsync timing is anchored on actual observations from the past.
  MojoTimeTicks now = GetTimeTicksNow();
  if (vsync_timebase > now) {
    LOG(WARNING) << "Vsync timebase is in the future: vsync_timebase="
                 << vsync_timebase << ", now=" << now;
    return false;
  }
  if (vsync_interval < kMinVsyncInterval ||
      vsync_interval > kMaxVsyncInterval) {
    LOG(WARNING) << "Vsync interval is invalid: vsync_interval="
                 << vsync_interval << ", min=" << kMinVsyncInterval
                 << ", max=" << kMaxVsyncInterval;
    return false;
  }
  if (snapshot_phase < update_phase ||
      snapshot_phase > update_phase + vsync_interval ||
      presentation_phase < snapshot_phase) {
    // Updating and snapshotting must happen within the same frame interval
    // to avoid having multiple updates in progress simultanteously (which
    // doesn't make much sense if we're already compute bound).
    LOG(WARNING) << "Vsync scheduling phases are invalid: update_phase="
                 << update_phase << ", snapshot_phase=" << snapshot_phase
                 << ", presentation_phase=" << presentation_phase;
    return false;
  }

  {
    std::lock_guard<std::mutex> lock(mutex_);

    // Suppress spurious updates.
    if (running_ && vsync_timebase_ == vsync_timebase &&
        vsync_interval_ == vsync_interval && update_phase_ == update_phase &&
        snapshot_phase_ == snapshot_phase &&
        presentation_phase_ == presentation_phase)
      return true;

    // Get running with these new parameters.
    // Note that |last_delivered_update_time_| and
    // |last_delivered_presentation_time_| are preserved.
    running_ = true;
    generation_++;  // cancels pending undelivered callbacks
    vsync_timebase_ = vsync_timebase;
    vsync_interval_ = vsync_interval;
    update_phase_ = update_phase;
    snapshot_phase_ = snapshot_phase;
    presentation_phase_ = presentation_phase;
    need_update_ = true;
    pending_dispatch_ = false;
    ScheduleLocked(now);
    return true;
  }
}

void VsyncScheduler::State::Stop() {
  std::lock_guard<std::mutex> lock(mutex_);
  running_ = false;
}

void VsyncScheduler::State::ScheduleFrame(SchedulingMode scheduling_mode) {
  MojoTimeTicks now = GetTimeTicksNow();

  {
    std::lock_guard<std::mutex> lock(mutex_);
    if (running_) {
      if (scheduling_mode == SchedulingMode::kUpdateAndSnapshot)
        need_update_ = true;
      ScheduleLocked(now);
    }
  }
}

void VsyncScheduler::State::ScheduleLocked(MojoTimeTicks now) {
  TRACE_EVENT2("gfx", "VsyncScheduler::ScheduleLocked", "pending_dispatch",
               pending_dispatch_, "need_update", need_update_);

  DCHECK(running_);
  DCHECK(now >= vsync_timebase_);

  if (pending_dispatch_)
    return;

  // Determine the time of the earliest achievable frame snapshot in
  // the near future.
  int64_t snapshot_timebase = vsync_timebase_ + snapshot_phase_;
  uint64_t snapshot_offset = (now - snapshot_timebase) % vsync_interval_;
  int64_t snapshot_time = now - snapshot_offset + vsync_interval_;
  DCHECK(snapshot_time >= now);

  // Determine when the update that produced this snapshot must have begun.
  // This time may be in the past.
  int64_t update_time = snapshot_time - snapshot_phase_ + update_phase_;
  DCHECK(update_time <= snapshot_time);
  int64_t presentation_time =
      snapshot_time - snapshot_phase_ + presentation_phase_;

  // When changing vsync parameters, it's possible for the next update or
  // presentation time to regress.  Prevent applications from observing that
  // by skipping frames if needed to preserve monotonicity.
  if (update_time <= last_delivered_update_time_ ||
      presentation_time <= last_delivered_presentation_time_) {
    int64_t delay =
        std::max(last_delivered_update_time_ - update_time,
                 last_delivered_presentation_time_ - presentation_time);
    int64_t frames = delay / vsync_interval_ + 1;
    int64_t adjustment = frames * vsync_interval_;
    update_time += adjustment;
    snapshot_time += adjustment;
  }

  // Schedule dispatching at that time.
  if (update_time >= now) {
    PostDispatchLocked(now, update_time, Action::kUpdate, update_time);
  } else {
    PostDispatchLocked(now, snapshot_time, Action::kEarlySnapshot, update_time);
  }

  pending_dispatch_ = true;
}

void VsyncScheduler::State::PostDispatchLocked(int64_t now,
                                               int64_t delivery_time,
                                               Action action,
                                               int64_t update_time) {
  TRACE_EVENT2("gfx", "VsyncScheduler::PostDispatchLocked", "delivery_time",
               delivery_time, "update_time", update_time);

  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&VsyncScheduler::State::DispatchThunk, shared_from_this(),
                 generation_, action, update_time),
      base::TimeDelta::FromMicroseconds(
          std::max(delivery_time - now, static_cast<int64_t>(0))));
}

void VsyncScheduler::State::DispatchThunk(
    const std::weak_ptr<State>& state_weak,
    int32_t generation,
    Action action,
    int64_t update_time) {
  std::shared_ptr<State> state = state_weak.lock();
  if (state)
    state->Dispatch(generation, action, update_time);
}

void VsyncScheduler::State::Dispatch(int32_t generation,
                                     Action action,
                                     int64_t update_time) {
  TRACE_EVENT2("gfx", "VsyncScheduler::Dispatch", "action",
               static_cast<int>(action), "update_time", update_time);

  MojoTimeTicks now = GetTimeTicksNow();
  DCHECK(update_time <= now);

  // Time may have passed since the callback was originally scheduled and
  // it's possible that we completely missed the deadline we were aiming for.
  // Reevaluate the schedule and jump ahead if necessary.
  mojo::gfx::composition::FrameInfo frame_info;
  {
    std::lock_guard<std::mutex> lock(mutex_);
    if (!running_ || generation_ != generation)
      return;

    DCHECK(pending_dispatch_);

    // Check whether we missed any deadlines.
    bool missed_deadline = false;
    if (action == Action::kUpdate) {
      int64_t update_deadline = update_time - update_phase_ + snapshot_phase_;
      if (now > update_deadline) {
        DLOG(WARNING) << "Compositor missed update deadline by "
                      << (now - update_deadline) << " us";
        missed_deadline = true;
      }
    } else {
      int64_t snapshot_deadline = update_time + vsync_interval_;
      if (now > snapshot_deadline) {
        DLOG(WARNING) << "Compositor missed snapshot deadline by "
                      << (now - snapshot_deadline) << " us";
        missed_deadline = true;
      }
    }
    if (missed_deadline) {
      uint64_t offset = (now - update_time) % vsync_interval_;
      update_time = now - offset;
      DCHECK(update_time > now - vsync_interval_ && update_time <= now);
    }

    // Schedule the corresponding snapshot for the update.
    if (action == Action::kUpdate) {
      int64_t snapshot_time = update_time - update_phase_ + snapshot_phase_;
      PostDispatchLocked(now, snapshot_time, Action::kLateSnapshot,
                         update_time);
      need_update_ = false;
    } else if (need_update_) {
      int64_t next_update_time = update_time + vsync_interval_;
      PostDispatchLocked(now, next_update_time, Action::kUpdate,
                         next_update_time);

      // If we missed the deadline on an early snapshot, then just skip it
      // and wait for the following update instead.
      if (action == Action::kEarlySnapshot && missed_deadline) {
        TRACE_EVENT_INSTANT0(
            "gfx", "VsyncScheduler::StateDispatch Skipped early snapshot",
            TRACE_EVENT_SCOPE_THREAD);
        return;
      }
    } else {
      pending_dispatch_ = false;
    }

    SetFrameInfoLocked(&frame_info, update_time);
    last_delivered_update_time_ = update_time;
    last_delivered_presentation_time_ = frame_info.presentation_time;
  }

  if (action == Action::kUpdate) {
    callbacks_.update_callback.Run(frame_info);
  } else {
    callbacks_.snapshot_callback.Run(frame_info);
  }
}

void VsyncScheduler::State::SetFrameInfoLocked(
    mojo::gfx::composition::FrameInfo* frame_info,
    int64_t update_time) {
  DCHECK(frame_info);
  frame_info->frame_time = update_time;
  frame_info->frame_interval = vsync_interval_;
  frame_info->frame_deadline = update_time - update_phase_ + snapshot_phase_;
  frame_info->presentation_time =
      update_time - update_phase_ + presentation_phase_;
}

}  // namespace compositor
