// Copyright 2011 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 CC_SCHEDULER_SCHEDULER_H_
#define CC_SCHEDULER_SCHEDULER_H_

#include <memory>
#include <string>

#include "base/cancelable_callback.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/scheduler/begin_frame_tracker.h"
#include "cc/scheduler/draw_result.h"
#include "cc/scheduler/scheduler_settings.h"
#include "cc/scheduler/scheduler_state_machine.h"
#include "cc/tiles/tile_priority.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"

namespace base {
namespace trace_event {
class ConvertableToTraceFormat;
}
class SingleThreadTaskRunner;
}

namespace cc {

class CompositorTimingHistory;

class SchedulerClient {
 public:
  // Returns whether the frame has damage.
  virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args) = 0;
  virtual void ScheduledActionSendBeginMainFrame(
      const viz::BeginFrameArgs& args) = 0;
  virtual DrawResult ScheduledActionDrawIfPossible() = 0;
  virtual DrawResult ScheduledActionDrawForced() = 0;

  // The Commit step occurs when the client received the BeginFrame from the
  // source and we perform at most one commit per BeginFrame. In this step the
  // main thread collects all updates then blocks and gives control to the
  // compositor thread, which allows Compositor thread to update its layer tree
  // to match the state of the layer tree on the main thread.
  virtual void ScheduledActionCommit() = 0;
  virtual void ScheduledActionActivateSyncTree() = 0;
  virtual void ScheduledActionBeginLayerTreeFrameSinkCreation() = 0;
  virtual void ScheduledActionPrepareTiles() = 0;
  virtual void ScheduledActionInvalidateLayerTreeFrameSink(
      bool needs_redraw) = 0;
  virtual void ScheduledActionPerformImplSideInvalidation() = 0;
  virtual void DidFinishImplFrame() = 0;
  virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack) = 0;
  virtual void WillNotReceiveBeginFrame() = 0;
  virtual void SendBeginMainFrameNotExpectedSoon() = 0;
  virtual void ScheduledActionBeginMainFrameNotExpectedUntil(
      base::TimeTicks time) = 0;
  virtual void FrameIntervalUpdated(base::TimeDelta interval) = 0;

  // Functions used for reporting animation targeting UMA, crbug.com/758439.
  virtual size_t CompositedAnimationsCount() const = 0;
  virtual size_t MainThreadAnimationsCount() const = 0;
  virtual bool CurrentFrameHadRAF() const = 0;
  virtual bool NextFrameHasPendingRAF() const = 0;

 protected:
  virtual ~SchedulerClient() {}
};

class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
 public:
  Scheduler(SchedulerClient* client,
            const SchedulerSettings& scheduler_settings,
            int layer_tree_host_id,
            base::SingleThreadTaskRunner* task_runner,
            std::unique_ptr<CompositorTimingHistory> compositor_timing_history);
  Scheduler(const Scheduler&) = delete;
  ~Scheduler() override;

  Scheduler& operator=(const Scheduler&) = delete;

  // This is needed so that the scheduler doesn't perform spurious actions while
  // the compositor is being torn down.
  void Stop();

  // BeginFrameObserverBase
  void OnBeginFrameSourcePausedChanged(bool paused) override;
  bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;

  void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw,
                                   bool skip_draw);

  const SchedulerSettings& settings() const { return settings_; }

  void SetVisible(bool visible);
  bool visible() { return state_machine_.visible(); }
  void SetCanDraw(bool can_draw);

  // We have 2 copies of the layer trees on the compositor thread: pending_tree
  // and active_tree. When we finish asynchronously rastering all tiles on
  // pending_tree, call this method to notify that this pending tree is ready to
  // be activated, that is to be copied to the active tree.
  void NotifyReadyToActivate();
  void NotifyReadyToDraw();
  void SetBeginFrameSource(viz::BeginFrameSource* source);

  using AnimationWorkletState = SchedulerStateMachine::AnimationWorkletState;
  using TreeType = SchedulerStateMachine::TreeType;

  // Sets whether asynchronous animation worklet mutations are running.
  // Mutations on the pending tree should block activiation. Mutations on the
  // active tree should delay draw to allow time for the mutations to complete.
  void NotifyAnimationWorkletStateChange(AnimationWorkletState state,
                                         TreeType tree);

  // Set |needs_begin_main_frame_| to true, which will cause the BeginFrame
  // source to be told to send BeginFrames to this client so that this client
  // can send a CompositorFrame to the display compositor with appropriate
  // timing.
  void SetNeedsBeginMainFrame();
  // Requests a single impl frame (after the current frame if there is one
  // active).
  void SetNeedsOneBeginImplFrame();

  void SetNeedsRedraw();

  void SetNeedsPrepareTiles();

  // Requests a pending tree should be created to invalidate content on the impl
  // thread, after the current tree is activated, if any. If the request
  // necessitates creating a pending tree only for impl-side invalidations, the
  // |client_| is informed to perform this action using
  // ScheduledActionRunImplSideInvalidation.
  // If ScheduledActionCommit is performed, the impl-side invalidations should
  // be merged with the main frame and the request is assumed to be completed.
  // If |needs_first_draw_on_activation| is set to true, an impl-side pending
  // tree creates for this invalidation must be drawn at least once before a
  // new tree can be activated.
  void SetNeedsImplSideInvalidation(bool needs_first_draw_on_activation);

  // Drawing should result in submitting a CompositorFrame to the
  // LayerTreeFrameSink and then calling this.
  void DidSubmitCompositorFrame();
  // The LayerTreeFrameSink acks when it is ready for a new frame which
  // should result in this getting called to unblock the next draw.
  void DidReceiveCompositorFrameAck();

  void SetTreePrioritiesAndScrollState(TreePriority tree_priority,
                                       ScrollHandlerState scroll_handler_state);

  // Commit step happens after the main thread has completed updating for a
  // BeginMainFrame request from the compositor, and blocks the main thread
  // to copy the layer tree to the compositor thread. Call this method when the
  // main thread updates are completed to signal it is ready for the commmit.
  void NotifyReadyToCommit();
  void BeginMainFrameAborted(CommitEarlyOutReason reason);
  void DidCommit();

  // In the PrepareTiles step, compositor thread divides the layers into tiles
  // to reduce cost of raster large layers. Then, each tile is rastered by a
  // dedicated thread.
  // |WillPrepareTiles| is called before PrepareTiles step to have the scheduler
  // track when PrepareTiles starts.
  void WillPrepareTiles();
  // |DidPrepareTiles| is called after PrepareTiles step to have the scheduler
  // track how long PrepareTiles takes.
  void DidPrepareTiles();

  void DidLoseLayerTreeFrameSink();
  void DidCreateAndInitializeLayerTreeFrameSink();

  // Tests do not want to shut down until all possible BeginMainFrames have
  // occured to prevent flakiness.
  bool MainFrameForTestingWillHappen() const {
    return state_machine_.CommitPending() ||
           state_machine_.CouldSendBeginMainFrame();
  }

  bool CommitPending() const { return state_machine_.CommitPending(); }
  bool RedrawPending() const { return state_machine_.RedrawPending(); }
  bool PrepareTilesPending() const {
    return state_machine_.PrepareTilesPending();
  }
  bool ImplLatencyTakesPriority() const {
    return state_machine_.ImplLatencyTakesPriority();
  }

  // Pass in a main_thread_start_time of base::TimeTicks() if it is not
  // known or not trustworthy (e.g. blink is running on a remote channel)
  // to signal that the start time isn't known and should not be used for
  // scheduling or statistics purposes.
  void NotifyBeginMainFrameStarted(base::TimeTicks main_thread_start_time);

  base::TimeTicks LastBeginImplFrameTime();

  // Deferring begin main frame prevents all document lkifecycle updates and
  // updates of new layer tree state.
  void SetDeferBeginMainFrame(bool defer_begin_main_frame);

  // Controls whether the BeginMainFrameNotExpected messages should be sent to
  // the main thread by the cc scheduler.
  void SetMainThreadWantsBeginMainFrameNotExpected(bool new_state);

  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;

  void AsValueInto(base::trace_event::TracedValue* state) const;

  void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);

  const viz::BeginFrameSource* begin_frame_source() const {
    return begin_frame_source_;
  }

  viz::BeginFrameAck CurrentBeginFrameAckForActiveTree() const;

  void ClearHistory();

 protected:
  // Virtual for testing.
  virtual base::TimeTicks Now() const;

  const SchedulerSettings settings_;
  SchedulerClient* const client_;
  const int layer_tree_host_id_;
  base::SingleThreadTaskRunner* task_runner_;

  viz::BeginFrameSource* begin_frame_source_ = nullptr;
  bool observing_begin_frame_source_ = false;

  bool skipped_last_frame_missed_exceeded_deadline_ = false;
  bool skipped_last_frame_to_reduce_latency_ = false;

  std::unique_ptr<CompositorTimingHistory> compositor_timing_history_;

  // What the latest deadline was, and when it was scheduled.
  base::TimeTicks deadline_;
  base::TimeTicks deadline_scheduled_at_;
  SchedulerStateMachine::BeginImplFrameDeadlineMode deadline_mode_;

  BeginFrameTracker begin_impl_frame_tracker_;
  viz::BeginFrameAck last_begin_frame_ack_;
  viz::BeginFrameArgs begin_main_frame_args_;

  // Task posted for the deadline or drawing phase of the scheduler. This task
  // can be rescheduled e.g. when the condition for the deadline is met, it is
  // scheduled to run immediately.
  // NOTE: Scheduler weak ptrs are not necessary if CancelableCallback is used.
  base::CancelableOnceClosure begin_impl_frame_deadline_task_;

  // This is used for queueing begin frames while scheduler is waiting for
  // previous frame's deadline, or if it's inside ProcessScheduledActions().
  // Only one such task is posted at any time, but the args are updated as we
  // get new begin frames.
  viz::BeginFrameArgs pending_begin_frame_args_;
  base::CancelableOnceClosure pending_begin_frame_task_;

  SchedulerStateMachine state_machine_;
  bool inside_process_scheduled_actions_ = false;
  bool inside_scheduled_action_ = false;
  SchedulerStateMachine::Action inside_action_ =
      SchedulerStateMachine::Action::NONE;

  bool stopped_ = false;

  // Keeps track of the begin frame interval from the last BeginFrameArgs to
  // arrive so that |client_| can be informed about changes.
  base::TimeDelta last_frame_interval_;

 private:
  // Posts the deadline task if needed by checking
  // SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode(). This only
  // happens when the scheduler is processing a begin frame
  // (BeginImplFrameState::INSIDE_BEGIN_FRAME).
  void ScheduleBeginImplFrameDeadline();

  // Starts or stops begin frames as needed by checking
  // SchedulerStateMachine::BeginFrameNeeded(). This only happens when the
  // scheduler is not processing a begin frame (BeginImplFrameState::IDLE).
  void StartOrStopBeginFrames();

  // This will only post a task if the args are valid and there's no existing
  // task. That implies that we're still expecting begin frames. If begin frames
  // aren't needed this will be a nop. This only happens when the scheduler is
  // not processing a begin frame (BeginImplFrameState::IDLE).
  void PostPendingBeginFrameTask();

  // Use |pending_begin_frame_args_| to begin a new frame like it was received
  // in OnBeginFrameDerivedImpl().
  void HandlePendingBeginFrame();

  // Used to drop the pending begin frame before we go idle.
  void CancelPendingBeginFrameTask();

  void BeginMainFrameNotExpectedUntil(base::TimeTicks time);
  void BeginMainFrameNotExpectedSoon();
  void DrawIfPossible();
  void DrawForced();
  void ProcessScheduledActions();
  void UpdateCompositorTimingHistoryRecordingEnabled();
  bool ShouldDropBeginFrame(const viz::BeginFrameArgs& args) const;
  bool ShouldRecoverMainLatency(const viz::BeginFrameArgs& args,
                                bool can_activate_before_deadline) const;
  bool ShouldRecoverImplLatency(const viz::BeginFrameArgs& args,
                                bool can_activate_before_deadline) const;
  bool CanBeginMainFrameAndActivateBeforeDeadline(
      const viz::BeginFrameArgs& args,
      base::TimeDelta bmf_to_activate_estimate,
      base::TimeTicks now) const;
  void AdvanceCommitStateIfPossible();
  bool IsBeginMainFrameSentOrStarted() const;

  void BeginImplFrameWithDeadline(const viz::BeginFrameArgs& args);
  void BeginImplFrameSynchronous(const viz::BeginFrameArgs& args);
  void BeginImplFrame(const viz::BeginFrameArgs& args, base::TimeTicks now);
  void FinishImplFrame();
  void SendDidNotProduceFrame(const viz::BeginFrameArgs& args);
  void OnBeginImplFrameDeadline();
  void PollToAdvanceCommitState();
  void BeginMainFrameAnimateAndLayoutOnly(const viz::BeginFrameArgs& args);

  bool IsInsideAction(SchedulerStateMachine::Action action) {
    return inside_action_ == action;
  }
};

}  // namespace cc

#endif  // CC_SCHEDULER_SCHEDULER_H_
