// Copyright 2014 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/begin_frame_tracker.h"

namespace cc {

BeginFrameTracker::BeginFrameTracker(const tracked_objects::Location& location)
    : location_(location),
      location_string_(location.ToString()),
      current_updated_at_(),
      current_args_(),
      current_finished_at_(base::TimeTicks::FromInternalValue(-1)) {}

BeginFrameTracker::~BeginFrameTracker() {
}

void BeginFrameTracker::Start(BeginFrameArgs new_args) {
  // Trace the frame time being passed between BeginFrameTrackers.
  TRACE_EVENT_FLOW_STEP0(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
      new_args.frame_time.ToInternalValue(), location_string_);

  // Trace this specific begin frame tracker Start/Finish times.
  TRACE_EVENT_COPY_ASYNC_BEGIN2(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
      location_string_.c_str(), new_args.frame_time.ToInternalValue(),
      "new args", new_args.AsValue(), "current args", current_args_.AsValue());

  // Check the new BeginFrameArgs are valid and monotonically increasing.
  DCHECK(new_args.IsValid());
  DCHECK_LE(current_args_.frame_time, new_args.frame_time);

  DCHECK(HasFinished())
      << "Tried to start a new frame before finishing an existing frame.";
  current_updated_at_ = base::TimeTicks::Now();
  current_args_ = new_args;
  current_finished_at_ = base::TimeTicks();

  // TODO(mithro): Add UMA tracking of delta between current_updated_at_ time
  // and the new_args.frame_time argument. This will give us how long after a
  // BeginFrameArgs message was created before we started processing it.
}

const BeginFrameArgs& BeginFrameTracker::Current() const {
  DCHECK(!HasFinished())
      << "Tried to use BeginFrameArgs after marking the frame finished.";
  DCHECK(current_args_.IsValid())
      << "Tried to use BeginFrameArgs before starting a frame!";
  return current_args_;
}

void BeginFrameTracker::Finish() {
  DCHECK(!HasFinished()) << "Tried to finish an already finished frame";
  current_finished_at_ = base::TimeTicks::Now();
  TRACE_EVENT_COPY_ASYNC_END0(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
      location_string_.c_str(), current_args_.frame_time.ToInternalValue());
}

const BeginFrameArgs& BeginFrameTracker::Last() const {
  DCHECK(current_args_.IsValid())
      << "Tried to use last BeginFrameArgs before starting a frame!";
  DCHECK(HasFinished())
      << "Tried to use last BeginFrameArgs before the frame is finished.";
  return current_args_;
}

base::TimeDelta BeginFrameTracker::Interval() const {
  base::TimeDelta interval = current_args_.interval;
  // Normal interval will be ~16ms, 200Hz (5ms) screens are the fastest
  // easily available so anything less than that is likely an error.
  if (interval < base::TimeDelta::FromMilliseconds(1)) {
    interval = BeginFrameArgs::DefaultInterval();
  }
  return interval;
}

void BeginFrameTracker::AsValueInto(
    base::TimeTicks now,
    base::trace_event::TracedValue* state) const {
  state->SetInteger("updated_at_us",
                    (current_updated_at_ - base::TimeTicks()).InMicroseconds());
  state->SetInteger("finished_at_us", (current_finished_at_ - base::TimeTicks())
                                          .InMicroseconds());
  if (HasFinished()) {
    state->SetString("state", "FINISHED");
    state->BeginDictionary("current_args_");
  } else {
    state->SetString("state", "USING");
    state->BeginDictionary("last_args_");
  }
  current_args_.AsValueInto(state);
  state->EndDictionary();

  base::TimeTicks frame_time = current_args_.frame_time;
  base::TimeTicks deadline = current_args_.deadline;
  base::TimeDelta interval = current_args_.interval;
  state->BeginDictionary("major_timestamps_in_ms");
  state->SetDouble("0_interval", interval.InMillisecondsF());
  state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
  state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
  state->SetDouble("3_frame_time_to_deadline",
                   (deadline - frame_time).InMillisecondsF());
  state->SetDouble("4_now", (now - base::TimeTicks()).InMillisecondsF());
  state->SetDouble("5_frame_time",
                   (frame_time - base::TimeTicks()).InMillisecondsF());
  state->SetDouble("6_deadline",
                   (deadline - base::TimeTicks()).InMillisecondsF());
  state->EndDictionary();
}

const BeginFrameArgs& BeginFrameTracker::DangerousMethodCurrentOrLast() const {
  if (!HasFinished()) {
    return Current();
  } else {
    return Last();
  }
}

}  // namespace cc
