// 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.

#ifndef SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_
#define SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_

#include <limits>
#include <memory>
#include <mutex>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/task_runner.h"
#include "services/gfx/compositor/backend/scheduler.h"

namespace compositor {

// Schedules work to coincide with vsync intervals.
//
// This object is thread-safe and it intended to be used to allow one thread
// to be scheduling work for itself while another thread concurrently updates
// timing parameters.
class VsyncScheduler : public Scheduler {
 public:
  // Limits on allowable parameters.  (Exposed for testing.)
  static constexpr int64_t kMinVsyncInterval = 1000;     // 1000 Hz
  static constexpr int64_t kMaxVsyncInterval = 1000000;  // 1 Hz

  // Time reference.  Should be MojoTimeTicksNow() except during testing.
  using Clock = base::Callback<MojoTimeTicks()>;

  VsyncScheduler(const scoped_refptr<base::TaskRunner>& task_runner,
                 const SchedulerCallbacks& callbacks);
  VsyncScheduler(const scoped_refptr<base::TaskRunner>& task_runner,
                 const SchedulerCallbacks& callbacks,
                 const Clock& clock);
  ~VsyncScheduler() override;

  // Starts scheduling work and sets the scheduling parameters.
  //
  // |vsync_timebase| is a value in the |MojoTimeTicks| timebase which
  // specifies when a recent vsync occurred and is used to determine the phase.
  //
  // |vsync_interval| is the number of microseconds between vsyncs which
  // also determines the |FrameInfo.frame_interval| value to deliver to
  // applications.
  //
  // |update_phase| specifies an offset relative to vsync for determining
  // when updates are scheduled and the |FrameInfo.frame_time| to deliver
  // to applications.
  //
  // |snapshot_phase| specifies an offset relative to vsync for
  // determining when snapshots are scheduled and the |FrameInfo.frame_deadline|
  // to deliver to applications.  Must be greater than or equal to
  // |update_phase|.
  //
  // |presentation_phase| specifies an offset relative to vsync for
  // determining when frames are shown on the display output and the
  // |FrameInfo.presentation_time| to deliver to applications.  Must be
  // greater than or equal to |snapshot_phase|.
  //
  // The notion of 'vsync' is somewhat abstract here.  It's just a reference
  // pulse but we usually interpret it as a deadline for preparing the next
  // frame and submitting it to the display hardware.
  //
  // The phases can be positive or negative but negative offsets from vsync
  // may be easier to interpret when computing deadlines.  To avoid
  // overflows, the values chosen for the phases should be close to 0.
  //
  // This function schedules an update and snapshot if not already scheduled.
  //
  // Returns true if the schedule was started successfully, false if the
  // parameters are invalid.
  bool Start(int64_t vsync_timebase,
             int64_t vsync_interval,
             int64_t update_phase,
             int64_t snapshot_phase,
             int64_t presentation_phase) {
    return state_->Start(vsync_timebase, vsync_interval, update_phase,
                         snapshot_phase, presentation_phase);
  }

  // Stops scheduling work.
  //
  // Previously scheduled callbacks may still be delivered.
  void Stop() { state_->Stop(); }

  // |Scheduler|:
  void ScheduleFrame(SchedulingMode scheduling_mode) override;

 private:
  // Internal state.  Held by a shared_ptr so that callbacks running on
  // other threads can reference it using a weak_ptr.
  class State : public std::enable_shared_from_this<State> {
   public:
    State(const scoped_refptr<base::TaskRunner>& task_runner,
          const SchedulerCallbacks& callbacks,
          const Clock& clock);
    ~State();

    MojoTimeTicks GetTimeTicksNow() { return clock_.Run(); }

    bool Start(int64_t vsync_timebase,
               int64_t vsync_interval,
               int64_t update_phase,
               int64_t snapshot_phase,
               int64_t presentation_phase);
    void Stop();
    void ScheduleFrame(SchedulingMode scheduling_mode);

   private:
    enum class Action {
      kUpdate,
      kEarlySnapshot,
      kLateSnapshot,
    };

    static void DispatchThunk(const std::weak_ptr<State>& state_weak,
                              int32_t generation,
                              Action action,
                              int64_t update_time);

    void ScheduleLocked(MojoTimeTicks now);
    void PostDispatchLocked(int64_t now,
                            int64_t delivery_time,
                            Action action,
                            int64_t update_time);

    void Dispatch(int32_t generation, Action action, int64_t update_time);
    void SetFrameInfoLocked(mojo::gfx::composition::FrameInfo* frame_info,
                            int64_t update_time);

    const scoped_refptr<base::TaskRunner> task_runner_;
    const SchedulerCallbacks callbacks_;
    const Clock clock_;

    // Parameters and state guarded by |mutex_|.
    std::mutex mutex_;
    bool running_ = false;
    int32_t generation_ = 0;
    int64_t vsync_timebase_ = 0;
    int64_t vsync_interval_ = 0;
    int64_t update_phase_ = 0;
    int64_t snapshot_phase_ = 0;
    int64_t presentation_phase_ = 0;
    bool need_update_ = false;
    bool pending_dispatch_ = false;
    int64_t last_delivered_update_time_ = std::numeric_limits<int64_t>::min();

    DISALLOW_COPY_AND_ASSIGN(State);
  };

  const std::shared_ptr<State> state_;

  DISALLOW_COPY_AND_ASSIGN(VsyncScheduler);
};

}  // namespace compositor

#endif  // SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_
