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

#include "cc/scheduler/scheduler.h"

#include <algorithm>
#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "ui/gfx/frame_time.h"

namespace cc {

Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource(
    Scheduler* scheduler,
    base::SingleThreadTaskRunner* task_runner)
    : scheduler_(scheduler) {
  if (gfx::FrameTime::TimestampsAreHighRes()) {
    time_source_ = DelayBasedTimeSourceHighRes::Create(
        scheduler_->VSyncInterval(), task_runner);
  } else {
    time_source_ = DelayBasedTimeSource::Create(scheduler_->VSyncInterval(),
                                                task_runner);
  }
  time_source_->SetClient(this);
}

Scheduler::SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
}

void Scheduler::SyntheticBeginFrameSource::CommitVSyncParameters(
    base::TimeTicks timebase,
    base::TimeDelta interval) {
  time_source_->SetTimebaseAndInterval(timebase, interval);
}

void Scheduler::SyntheticBeginFrameSource::SetNeedsBeginFrame(
    bool needs_begin_frame,
    std::deque<BeginFrameArgs>* begin_retro_frame_args) {
  DCHECK(begin_retro_frame_args);
  base::TimeTicks missed_tick_time =
      time_source_->SetActive(needs_begin_frame);
  if (!missed_tick_time.is_null()) {
    begin_retro_frame_args->push_back(
        CreateSyntheticBeginFrameArgs(missed_tick_time));
  }
}

bool Scheduler::SyntheticBeginFrameSource::IsActive() const {
  return time_source_->Active();
}

void Scheduler::SyntheticBeginFrameSource::OnTimerTick() {
  BeginFrameArgs begin_frame_args(
      CreateSyntheticBeginFrameArgs(time_source_->LastTickTime()));
  scheduler_->BeginFrame(begin_frame_args);
}

scoped_ptr<base::Value> Scheduler::SyntheticBeginFrameSource::AsValue() const {
  return time_source_->AsValue();
}

BeginFrameArgs
Scheduler::SyntheticBeginFrameSource::CreateSyntheticBeginFrameArgs(
    base::TimeTicks frame_time) {
  base::TimeTicks deadline = time_source_->NextTickTime();
  return BeginFrameArgs::Create(
      frame_time, deadline, scheduler_->VSyncInterval());
}

Scheduler::Scheduler(
    SchedulerClient* client,
    const SchedulerSettings& scheduler_settings,
    int layer_tree_host_id,
    const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner)
    : settings_(scheduler_settings),
      client_(client),
      layer_tree_host_id_(layer_tree_host_id),
      impl_task_runner_(impl_task_runner),
      vsync_interval_(BeginFrameArgs::DefaultInterval()),
      last_set_needs_begin_frame_(false),
      begin_unthrottled_frame_posted_(false),
      begin_retro_frame_posted_(false),
      state_machine_(scheduler_settings),
      inside_process_scheduled_actions_(false),
      inside_action_(SchedulerStateMachine::ACTION_NONE),
      weak_factory_(this) {
  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
               "Scheduler::Scheduler",
               "settings",
               ToTrace(settings_));
  DCHECK(client_);
  DCHECK(!state_machine_.BeginFrameNeeded());
  if (settings_.main_frame_before_activation_enabled) {
    DCHECK(settings_.main_frame_before_draw_enabled);
  }

  begin_retro_frame_closure_ =
      base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
  begin_unthrottled_frame_closure_ =
      base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
  begin_impl_frame_deadline_closure_ = base::Bind(
      &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
  poll_for_draw_triggers_closure_ = base::Bind(
      &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
  advance_commit_state_closure_ = base::Bind(
      &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());

  if (!settings_.begin_frame_scheduling_enabled) {
    SetupSyntheticBeginFrames();
  }
}

Scheduler::~Scheduler() {
  if (synthetic_begin_frame_source_) {
    synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
                                                      &begin_retro_frame_args_);
  }
}

void Scheduler::SetupSyntheticBeginFrames() {
  DCHECK(!synthetic_begin_frame_source_);
  synthetic_begin_frame_source_.reset(
      new SyntheticBeginFrameSource(this, impl_task_runner_.get()));
}

void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
                                      base::TimeDelta interval) {
  // TODO(brianderson): We should not be receiving 0 intervals.
  if (interval == base::TimeDelta())
    interval = BeginFrameArgs::DefaultInterval();
  vsync_interval_ = interval;
  if (!settings_.begin_frame_scheduling_enabled)
    synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval);
}

void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
  DCHECK_GE(draw_time.ToInternalValue(), 0);
  estimated_parent_draw_time_ = draw_time;
}

void Scheduler::SetCanStart() {
  state_machine_.SetCanStart();
  ProcessScheduledActions();
}

void Scheduler::SetVisible(bool visible) {
  state_machine_.SetVisible(visible);
  ProcessScheduledActions();
}

void Scheduler::SetCanDraw(bool can_draw) {
  state_machine_.SetCanDraw(can_draw);
  ProcessScheduledActions();
}

void Scheduler::NotifyReadyToActivate() {
  state_machine_.NotifyReadyToActivate();
  ProcessScheduledActions();
}

void Scheduler::SetNeedsCommit() {
  state_machine_.SetNeedsCommit();
  ProcessScheduledActions();
}

void Scheduler::SetNeedsRedraw() {
  state_machine_.SetNeedsRedraw();
  ProcessScheduledActions();
}

void Scheduler::SetNeedsAnimate() {
  state_machine_.SetNeedsAnimate();
  ProcessScheduledActions();
}

void Scheduler::SetNeedsManageTiles() {
  DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_MANAGE_TILES));
  state_machine_.SetNeedsManageTiles();
  ProcessScheduledActions();
}

void Scheduler::SetMaxSwapsPending(int max) {
  state_machine_.SetMaxSwapsPending(max);
}

void Scheduler::DidSwapBuffers() {
  state_machine_.DidSwapBuffers();

  // There is no need to call ProcessScheduledActions here because
  // swapping should not trigger any new actions.
  if (!inside_process_scheduled_actions_) {
    DCHECK_EQ(state_machine_.NextAction(), SchedulerStateMachine::ACTION_NONE);
  }
}

void Scheduler::SetSwapUsedIncompleteTile(bool used_incomplete_tile) {
  state_machine_.SetSwapUsedIncompleteTile(used_incomplete_tile);
  ProcessScheduledActions();
}

void Scheduler::DidSwapBuffersComplete() {
  state_machine_.DidSwapBuffersComplete();
  ProcessScheduledActions();
}

void Scheduler::SetSmoothnessTakesPriority(bool smoothness_takes_priority) {
  state_machine_.SetSmoothnessTakesPriority(smoothness_takes_priority);
  ProcessScheduledActions();
}

void Scheduler::NotifyReadyToCommit() {
  TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
  state_machine_.NotifyReadyToCommit();
  ProcessScheduledActions();
}

void Scheduler::BeginMainFrameAborted(bool did_handle) {
  TRACE_EVENT0("cc", "Scheduler::BeginMainFrameAborted");
  state_machine_.BeginMainFrameAborted(did_handle);
  ProcessScheduledActions();
}

void Scheduler::DidManageTiles() {
  state_machine_.DidManageTiles();
}

void Scheduler::DidLoseOutputSurface() {
  TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
  state_machine_.DidLoseOutputSurface();
  last_set_needs_begin_frame_ = false;
  if (!settings_.begin_frame_scheduling_enabled) {
    synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
                                                      &begin_retro_frame_args_);
  }
  begin_retro_frame_args_.clear();
  ProcessScheduledActions();
}

void Scheduler::DidCreateAndInitializeOutputSurface() {
  TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
  DCHECK(!last_set_needs_begin_frame_);
  DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
  state_machine_.DidCreateAndInitializeOutputSurface();
  ProcessScheduledActions();
}

void Scheduler::NotifyBeginMainFrameStarted() {
  TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
  state_machine_.NotifyBeginMainFrameStarted();
}

base::TimeTicks Scheduler::AnticipatedDrawTime() const {
  if (!last_set_needs_begin_frame_ ||
      begin_impl_frame_args_.interval <= base::TimeDelta())
    return base::TimeTicks();

  base::TimeTicks now = gfx::FrameTime::Now();
  base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
                                      begin_impl_frame_args_.deadline);
  int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
  return timebase + (begin_impl_frame_args_.interval * intervals);
}

base::TimeTicks Scheduler::LastBeginImplFrameTime() {
  return begin_impl_frame_args_.frame_time;
}

void Scheduler::SetupNextBeginFrameIfNeeded() {
  bool needs_begin_frame = state_machine_.BeginFrameNeeded();

  if (settings_.throttle_frame_production) {
    SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame);
  } else {
    SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame);
  }
  SetupPollingMechanisms(needs_begin_frame);
}

// When we are throttling frame production, we request BeginFrames
// from the OutputSurface.
void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingEnabled(
    bool needs_begin_frame) {
  bool at_end_of_deadline =
      state_machine_.begin_impl_frame_state() ==
          SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;

  bool should_call_set_needs_begin_frame =
      // Always request the BeginFrame immediately if it wasn't needed before.
      (needs_begin_frame && !last_set_needs_begin_frame_) ||
      // Only stop requesting BeginFrames after a deadline.
      (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);

  if (should_call_set_needs_begin_frame) {
    if (settings_.begin_frame_scheduling_enabled) {
      client_->SetNeedsBeginFrame(needs_begin_frame);
    } else {
      synthetic_begin_frame_source_->SetNeedsBeginFrame(
          needs_begin_frame, &begin_retro_frame_args_);
    }
    last_set_needs_begin_frame_ = needs_begin_frame;
  }

  PostBeginRetroFrameIfNeeded();
}

// When we aren't throttling frame production, we initiate a BeginFrame
// as soon as one is needed.
void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled(
    bool needs_begin_frame) {
  last_set_needs_begin_frame_ = needs_begin_frame;

  if (!needs_begin_frame || begin_unthrottled_frame_posted_)
    return;

  if (state_machine_.begin_impl_frame_state() !=
          SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE &&
      state_machine_.begin_impl_frame_state() !=
          SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
    return;
  }

  begin_unthrottled_frame_posted_ = true;
  impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
}

// BeginUnthrottledFrame is used when we aren't throttling frame production.
// This will usually be because VSync is disabled.
void Scheduler::BeginUnthrottledFrame() {
  DCHECK(!settings_.throttle_frame_production);
  DCHECK(begin_retro_frame_args_.empty());

  base::TimeTicks now = gfx::FrameTime::Now();
  base::TimeTicks deadline = now + vsync_interval_;

  BeginFrameArgs begin_frame_args =
      BeginFrameArgs::Create(now, deadline, vsync_interval_);
  BeginImplFrame(begin_frame_args);

  begin_unthrottled_frame_posted_ = false;
}

// We may need to poll when we can't rely on BeginFrame to advance certain
// state or to avoid deadlock.
void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
  bool needs_advance_commit_state_timer = false;
  // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
  // aren't expecting any more BeginFrames. This should only be needed by
  // the synchronous compositor when BeginFrameNeeded is false.
  if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
    DCHECK(!state_machine_.SupportsProactiveBeginFrame());
    DCHECK(!needs_begin_frame);
    if (poll_for_draw_triggers_task_.IsCancelled()) {
      poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
      base::TimeDelta delay = begin_impl_frame_args_.IsValid()
                                  ? begin_impl_frame_args_.interval
                                  : BeginFrameArgs::DefaultInterval();
      impl_task_runner_->PostDelayedTask(
          FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
    }
  } else {
    poll_for_draw_triggers_task_.Cancel();

    // At this point we'd prefer to advance through the commit flow by
    // drawing a frame, however it's possible that the frame rate controller
    // will not give us a BeginFrame until the commit completes.  See
    // crbug.com/317430 for an example of a swap ack being held on commit. Thus
    // we set a repeating timer to poll on ProcessScheduledActions until we
    // successfully reach BeginFrame. Synchronous compositor does not use
    // frame rate controller or have the circular wait in the bug.
    if (IsBeginMainFrameSentOrStarted() &&
        !settings_.using_synchronous_renderer_compositor) {
      needs_advance_commit_state_timer = true;
    }
  }

  if (needs_advance_commit_state_timer) {
    if (advance_commit_state_task_.IsCancelled() &&
        begin_impl_frame_args_.IsValid()) {
      // Since we'd rather get a BeginImplFrame by the normal mechanism, we
      // set the interval to twice the interval from the previous frame.
      advance_commit_state_task_.Reset(advance_commit_state_closure_);
      impl_task_runner_->PostDelayedTask(FROM_HERE,
                                         advance_commit_state_task_.callback(),
                                         begin_impl_frame_args_.interval * 2);
    }
  } else {
    advance_commit_state_task_.Cancel();
  }
}

// BeginFrame is the mechanism that tells us that now is a good time to start
// making a frame. Usually this means that user input for the frame is complete.
// If the scheduler is busy, we queue the BeginFrame to be handled later as
// a BeginRetroFrame.
void Scheduler::BeginFrame(const BeginFrameArgs& args) {
  TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", ToTrace(args));
  DCHECK(settings_.throttle_frame_production);

  BeginFrameArgs adjusted_args(args);
  adjusted_args.deadline -= EstimatedParentDrawTime();

  bool should_defer_begin_frame;
  if (settings_.using_synchronous_renderer_compositor) {
    should_defer_begin_frame = false;
  } else {
    should_defer_begin_frame =
        !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
        !last_set_needs_begin_frame_ ||
        (state_machine_.begin_impl_frame_state() !=
         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
  }

  if (should_defer_begin_frame) {
    begin_retro_frame_args_.push_back(adjusted_args);
    TRACE_EVENT_INSTANT0(
        "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
    return;
  }

  BeginImplFrame(adjusted_args);
}

// BeginRetroFrame is called for BeginFrames that we've deferred because
// the scheduler was in the middle of processing a previous BeginFrame.
void Scheduler::BeginRetroFrame() {
  TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
  DCHECK(!settings_.using_synchronous_renderer_compositor);
  DCHECK(begin_retro_frame_posted_);
  begin_retro_frame_posted_ = false;

  // If there aren't any retroactive BeginFrames, then we've lost the
  // OutputSurface and should abort.
  if (begin_retro_frame_args_.empty())
    return;

  // Discard expired BeginRetroFrames
  // Today, we should always end up with at most one un-expired BeginRetroFrame
  // because deadlines will not be greater than the next frame time. We don't
  // DCHECK though because some systems don't always have monotonic timestamps.
  // TODO(brianderson): In the future, long deadlines could result in us not
  // draining the queue if we don't catch up. If we consistently can't catch
  // up, our fallback should be to lower our frame rate.
  base::TimeTicks now = gfx::FrameTime::Now();
  base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
  while (!begin_retro_frame_args_.empty() &&
         now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
                                              draw_duration_estimate)) {
    TRACE_EVENT1("cc",
                 "Scheduler::BeginRetroFrame discarding",
                 "frame_time",
                 begin_retro_frame_args_.front().frame_time);
    begin_retro_frame_args_.pop_front();
  }

  if (begin_retro_frame_args_.empty()) {
    DCHECK(settings_.throttle_frame_production);
    TRACE_EVENT_INSTANT0("cc",
                         "Scheduler::BeginRetroFrames all expired",
                         TRACE_EVENT_SCOPE_THREAD);
  } else {
    BeginImplFrame(begin_retro_frame_args_.front());
    begin_retro_frame_args_.pop_front();
  }
}

// There could be a race between the posted BeginRetroFrame and a new
// BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
// will check if there is a pending BeginRetroFrame to ensure we handle
// BeginFrames in FIFO order.
void Scheduler::PostBeginRetroFrameIfNeeded() {
  if (!last_set_needs_begin_frame_)
    return;

  if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
    return;

  // begin_retro_frame_args_ should always be empty for the
  // synchronous compositor.
  DCHECK(!settings_.using_synchronous_renderer_compositor);

  if (state_machine_.begin_impl_frame_state() !=
      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
    return;

  begin_retro_frame_posted_ = true;
  impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
}

// BeginImplFrame starts a compositor frame that will wait up until a deadline
// for a BeginMainFrame+activation to complete before it times out and draws
// any asynchronous animation and scroll/pinch updates.
void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
  TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", ToTrace(args));
  DCHECK(state_machine_.begin_impl_frame_state() ==
         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
  DCHECK(state_machine_.HasInitializedOutputSurface());

  advance_commit_state_task_.Cancel();

  base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
  begin_impl_frame_args_ = args;
  begin_impl_frame_args_.deadline -= draw_duration_estimate;

  if (!state_machine_.smoothness_takes_priority() &&
      state_machine_.MainThreadIsInHighLatencyMode() &&
      CanCommitAndActivateBeforeDeadline()) {
    state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
  }

  client_->WillBeginImplFrame(begin_impl_frame_args_);
  state_machine_.OnBeginImplFrame(begin_impl_frame_args_);
  devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);

  ProcessScheduledActions();

  state_machine_.OnBeginImplFrameDeadlinePending();
  ScheduleBeginImplFrameDeadline(
      AdjustedBeginImplFrameDeadline(args, draw_duration_estimate));
}

base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline(
    const BeginFrameArgs& args,
    base::TimeDelta draw_duration_estimate) const {
  if (settings_.using_synchronous_renderer_compositor) {
    // The synchronous compositor needs to draw right away.
    return base::TimeTicks();
  } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
    // We are ready to draw a new active tree immediately.
    return base::TimeTicks();
  } else if (state_machine_.needs_redraw()) {
    // We have an animation or fast input path on the impl thread that wants
    // to draw, so don't wait too long for a new active tree.
    return args.deadline - draw_duration_estimate;
  } else {
    // The impl thread doesn't have anything it wants to draw and we are just
    // waiting for a new active tree, so post the deadline for the next
    // expected BeginImplFrame start. This allows us to draw immediately when
    // there is a new active tree, instead of waiting for the next
    // BeginImplFrame.
    // TODO(brianderson): Handle long deadlines (that are past the next frame's
    // frame time) properly instead of using this hack.
    return args.frame_time + args.interval;
  }
}

void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
  if (settings_.using_synchronous_renderer_compositor) {
    // The synchronous renderer compositor has to make its GL calls
    // within this call.
    // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
    // so the sychronous renderer compositor can take advantage of splitting
    // up the BeginImplFrame and deadline as well.
    OnBeginImplFrameDeadline();
    return;
  }
  begin_impl_frame_deadline_task_.Cancel();
  begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);

  base::TimeDelta delta = deadline - gfx::FrameTime::Now();
  if (delta <= base::TimeDelta())
    delta = base::TimeDelta();
  impl_task_runner_->PostDelayedTask(
      FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
}

void Scheduler::OnBeginImplFrameDeadline() {
  TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline");
  begin_impl_frame_deadline_task_.Cancel();

  // We split the deadline actions up into two phases so the state machine
  // has a chance to trigger actions that should occur durring and after
  // the deadline separately. For example:
  // * Sending the BeginMainFrame will not occur after the deadline in
  //     order to wait for more user-input before starting the next commit.
  // * Creating a new OuputSurface will not occur during the deadline in
  //     order to allow the state machine to "settle" first.
  state_machine_.OnBeginImplFrameDeadline();
  ProcessScheduledActions();
  state_machine_.OnBeginImplFrameIdle();
  ProcessScheduledActions();

  client_->DidBeginImplFrameDeadline();
}

void Scheduler::PollForAnticipatedDrawTriggers() {
  TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers");
  poll_for_draw_triggers_task_.Cancel();
  state_machine_.DidEnterPollForAnticipatedDrawTriggers();
  ProcessScheduledActions();
  state_machine_.DidLeavePollForAnticipatedDrawTriggers();
}

void Scheduler::PollToAdvanceCommitState() {
  TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
  advance_commit_state_task_.Cancel();
  ProcessScheduledActions();
}

bool Scheduler::IsBeginMainFrameSent() const {
  return state_machine_.commit_state() ==
         SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
}

void Scheduler::DrawAndSwapIfPossible() {
  DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
  state_machine_.DidDrawIfPossibleCompleted(result);
}

void Scheduler::ProcessScheduledActions() {
  // We do not allow ProcessScheduledActions to be recursive.
  // The top-level call will iteratively execute the next action for us anyway.
  if (inside_process_scheduled_actions_)
    return;

  base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);

  SchedulerStateMachine::Action action;
  do {
    action = state_machine_.NextAction();
    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
                 "SchedulerStateMachine",
                 "state",
                 ToTrace(this));
    state_machine_.UpdateState(action);
    base::AutoReset<SchedulerStateMachine::Action>
        mark_inside_action(&inside_action_, action);
    switch (action) {
      case SchedulerStateMachine::ACTION_NONE:
        break;
      case SchedulerStateMachine::ACTION_ANIMATE:
        client_->ScheduledActionAnimate();
        break;
      case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
        client_->ScheduledActionSendBeginMainFrame();
        break;
      case SchedulerStateMachine::ACTION_COMMIT:
        client_->ScheduledActionCommit();
        break;
      case SchedulerStateMachine::ACTION_UPDATE_VISIBLE_TILES:
        client_->ScheduledActionUpdateVisibleTiles();
        break;
      case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
        client_->ScheduledActionActivateSyncTree();
        break;
      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
        DrawAndSwapIfPossible();
        break;
      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED:
        client_->ScheduledActionDrawAndSwapForced();
        break;
      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT:
        // No action is actually performed, but this allows the state machine to
        // advance out of its waiting to draw state without actually drawing.
        break;
      case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
        client_->ScheduledActionBeginOutputSurfaceCreation();
        break;
      case SchedulerStateMachine::ACTION_MANAGE_TILES:
        client_->ScheduledActionManageTiles();
        break;
    }
  } while (action != SchedulerStateMachine::ACTION_NONE);

  SetupNextBeginFrameIfNeeded();
  client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());

  if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
    DCHECK(!settings_.using_synchronous_renderer_compositor);
    ScheduleBeginImplFrameDeadline(base::TimeTicks());
  }
}

bool Scheduler::WillDrawIfNeeded() const {
  return !state_machine_.PendingDrawsShouldBeAborted();
}

scoped_ptr<base::Value> Scheduler::AsValue() const {
  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
  state->Set("state_machine", state_machine_.AsValue().release());
  if (synthetic_begin_frame_source_)
    state->Set("synthetic_begin_frame_source_",
               synthetic_begin_frame_source_->AsValue().release());

  scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue);
  scheduler_state->SetDouble(
      "time_until_anticipated_draw_time_ms",
      (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
  scheduler_state->SetDouble("vsync_interval_ms",
                             vsync_interval_.InMillisecondsF());
  scheduler_state->SetDouble("estimated_parent_draw_time_ms",
                             estimated_parent_draw_time_.InMillisecondsF());
  scheduler_state->SetBoolean("last_set_needs_begin_frame_",
                              last_set_needs_begin_frame_);
  scheduler_state->SetBoolean("begin_unthrottled_frame_posted_",
                              begin_unthrottled_frame_posted_);
  scheduler_state->SetBoolean("begin_retro_frame_posted_",
                              begin_retro_frame_posted_);
  scheduler_state->SetInteger("begin_retro_frame_args_",
                              begin_retro_frame_args_.size());
  scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
                              !begin_impl_frame_deadline_task_.IsCancelled());
  scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
                              !poll_for_draw_triggers_task_.IsCancelled());
  scheduler_state->SetBoolean("advance_commit_state_task_",
                              !advance_commit_state_task_.IsCancelled());
  scheduler_state->Set("begin_impl_frame_args",
                       begin_impl_frame_args_.AsValue().release());

  state->Set("scheduler_state", scheduler_state.release());

  scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue);
  client_state->SetDouble("draw_duration_estimate_ms",
                          client_->DrawDurationEstimate().InMillisecondsF());
  client_state->SetDouble(
      "begin_main_frame_to_commit_duration_estimate_ms",
      client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
  client_state->SetDouble(
      "commit_to_activate_duration_estimate_ms",
      client_->CommitToActivateDurationEstimate().InMillisecondsF());
  state->Set("client_state", client_state.release());
  return state.PassAs<base::Value>();
}

bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
  // Check if the main thread computation and commit can be finished before the
  // impl thread's deadline.
  base::TimeTicks estimated_draw_time =
      begin_impl_frame_args_.frame_time +
      client_->BeginMainFrameToCommitDurationEstimate() +
      client_->CommitToActivateDurationEstimate();

  TRACE_EVENT2(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
      "CanCommitAndActivateBeforeDeadline",
      "time_left_after_drawing_ms",
      (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
      "state",
      ToTrace(this));

  return estimated_draw_time < begin_impl_frame_args_.deadline;
}

bool Scheduler::IsBeginMainFrameSentOrStarted() const {
  return (state_machine_.commit_state() ==
              SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
          state_machine_.commit_state() ==
              SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
}

}  // namespace cc
