// 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_source.h"

#include "base/auto_reset.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/scheduler.h"
#include "ui/gfx/frame_time.h"

#ifdef NDEBUG
#define DEBUG_FRAMES(...)
#else
#define DEBUG_FRAMES(name, arg1_name, arg1_val, arg2_name, arg2_val)   \
  TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), \
               name,                                                   \
               arg1_name,                                              \
               arg1_val,                                               \
               arg2_name,                                              \
               arg2_val);
#endif

namespace cc {

// BeginFrameObserverMixIn -----------------------------------------------
BeginFrameObserverMixIn::BeginFrameObserverMixIn()
    : last_begin_frame_args_(), dropped_begin_frame_args_(0) {
}

const BeginFrameArgs BeginFrameObserverMixIn::LastUsedBeginFrameArgs() const {
  return last_begin_frame_args_;
}
void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) {
  DEBUG_FRAMES("BeginFrameObserverMixIn::OnBeginFrame",
               "last args",
               last_begin_frame_args_.AsValue(),
               "new args",
               args.AsValue());
  DCHECK(args.IsValid());
  DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
  bool used = OnBeginFrameMixInDelegate(args);
  if (used) {
    last_begin_frame_args_ = args;
  } else {
    ++dropped_begin_frame_args_;
  }
}

void BeginFrameObserverMixIn::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  dict->BeginDictionary("last_begin_frame_args_");
  last_begin_frame_args_.AsValueInto(dict);
  dict->EndDictionary();
  dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_);
}

// BeginFrameSourceMixIn ------------------------------------------------------
BeginFrameSourceMixIn::BeginFrameSourceMixIn()
    : observer_(NULL),
      needs_begin_frames_(false),
      inside_as_value_into_(false) {
  DCHECK(!observer_);
  DCHECK_EQ(inside_as_value_into_, false);
}

bool BeginFrameSourceMixIn::NeedsBeginFrames() const {
  return needs_begin_frames_;
}

void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) {
  DEBUG_FRAMES("BeginFrameSourceMixIn::SetNeedsBeginFrames",
               "current state",
               needs_begin_frames_,
               "new state",
               needs_begin_frames);
  if (needs_begin_frames_ != needs_begin_frames) {
    needs_begin_frames_ = needs_begin_frames;
    OnNeedsBeginFramesChange(needs_begin_frames);
  }
}

void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) {
  DEBUG_FRAMES("BeginFrameSourceMixIn::AddObserver",
               "current observer",
               observer_,
               "to add observer",
               obs);
  DCHECK(!observer_);
  observer_ = obs;
}

void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) {
  DEBUG_FRAMES("BeginFrameSourceMixIn::RemoveObserver",
               "current observer",
               observer_,
               "to remove observer",
               obs);
  DCHECK_EQ(observer_, obs);
  observer_ = NULL;
}

void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) {
  DEBUG_FRAMES("BeginFrameSourceMixIn::CallOnBeginFrame",
               "current observer",
               observer_,
               "args",
               args.AsValue());
  if (observer_) {
    return observer_->OnBeginFrame(args);
  }
}

// Tracing support
void BeginFrameSourceMixIn::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  // As the observer might try to trace the source, prevent an infinte loop
  // from occuring.
  if (inside_as_value_into_) {
    dict->SetString("observer", "<loop detected>");
    return;
  }

  if (observer_) {
    base::AutoReset<bool> prevent_loops(
        const_cast<bool*>(&inside_as_value_into_), true);
    dict->BeginDictionary("observer");
    observer_->AsValueInto(dict);
    dict->EndDictionary();
  } else {
    dict->SetString("observer", "NULL");
  }
  dict->SetBoolean("needs_begin_frames", NeedsBeginFrames());
}

// BackToBackBeginFrameSourceMixIn --------------------------------------------
scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create(
    base::SingleThreadTaskRunner* task_runner) {
  return make_scoped_ptr(new BackToBackBeginFrameSource(task_runner));
}

BackToBackBeginFrameSource::BackToBackBeginFrameSource(
    base::SingleThreadTaskRunner* task_runner)
    : BeginFrameSourceMixIn(),
      task_runner_(task_runner),
      send_begin_frame_posted_(false),
      weak_factory_(this) {
  DCHECK(task_runner);
  DCHECK_EQ(needs_begin_frames_, false);
  DCHECK_EQ(send_begin_frame_posted_, false);
}

BackToBackBeginFrameSource::~BackToBackBeginFrameSource() {
}

base::TimeTicks BackToBackBeginFrameSource::Now() {
  return gfx::FrameTime::Now();
}

void BackToBackBeginFrameSource::OnNeedsBeginFramesChange(
    bool needs_begin_frames) {
  if (!needs_begin_frames)
    return;

  if (send_begin_frame_posted_)
    return;

  send_begin_frame_posted_ = true;
  task_runner_->PostTask(FROM_HERE,
                         base::Bind(&BackToBackBeginFrameSource::BeginFrame,
                                    weak_factory_.GetWeakPtr()));
}

void BackToBackBeginFrameSource::BeginFrame() {
  send_begin_frame_posted_ = false;

  if (!needs_begin_frames_)
    return;

  base::TimeTicks now = Now();
  BeginFrameArgs args = BeginFrameArgs::Create(
      BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(),
      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
  CallOnBeginFrame(args);
}

// BeginFrameSource support

void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) {
  if (remaining_frames == 0) {
    OnNeedsBeginFramesChange(NeedsBeginFrames());
  }
}

// Tracing support
void BackToBackBeginFrameSource::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  dict->SetString("type", "BackToBackBeginFrameSource");
  BeginFrameSourceMixIn::AsValueInto(dict);
  dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_);
}

// SyntheticBeginFrameSource ---------------------------------------------
scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create(
    base::SingleThreadTaskRunner* task_runner,
    base::TimeTicks initial_vsync_timebase,
    base::TimeDelta initial_vsync_interval) {
  scoped_refptr<DelayBasedTimeSource> time_source;
  if (gfx::FrameTime::TimestampsAreHighRes()) {
    time_source = DelayBasedTimeSourceHighRes::Create(initial_vsync_interval,
                                                      task_runner);
  } else {
    time_source =
        DelayBasedTimeSource::Create(initial_vsync_interval, task_runner);
  }

  return make_scoped_ptr(new SyntheticBeginFrameSource(time_source));
}

SyntheticBeginFrameSource::SyntheticBeginFrameSource(
    scoped_refptr<DelayBasedTimeSource> time_source)
    : BeginFrameSourceMixIn(), time_source_(time_source) {
  time_source_->SetActive(false);
  time_source_->SetClient(this);
}

SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
  if (NeedsBeginFrames())
    time_source_->SetActive(false);
}

void SyntheticBeginFrameSource::OnUpdateVSyncParameters(
    base::TimeTicks new_vsync_timebase,
    base::TimeDelta new_vsync_interval) {
  time_source_->SetTimebaseAndInterval(new_vsync_timebase, new_vsync_interval);
}

BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs(
    base::TimeTicks frame_time,
    BeginFrameArgs::BeginFrameArgsType type) {
  base::TimeTicks deadline = time_source_->NextTickTime();
  return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
                                time_source_->Interval(), type);
}

// TimeSourceClient support
void SyntheticBeginFrameSource::OnTimerTick() {
  CallOnBeginFrame(CreateBeginFrameArgs(time_source_->LastTickTime(),
                                        BeginFrameArgs::NORMAL));
}

// BeginFrameSourceMixIn support
void SyntheticBeginFrameSource::OnNeedsBeginFramesChange(
    bool needs_begin_frames) {
  base::TimeTicks missed_tick_time =
      time_source_->SetActive(needs_begin_frames);
  if (!missed_tick_time.is_null()) {
    CallOnBeginFrame(
        CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED));
  }
}

// Tracing support
void SyntheticBeginFrameSource::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  dict->SetString("type", "SyntheticBeginFrameSource");
  BeginFrameSourceMixIn::AsValueInto(dict);

  dict->BeginDictionary("time_source");
  time_source_->AsValueInto(dict);
  dict->EndDictionary();
}

// BeginFrameSourceMultiplexer -------------------------------------------
scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() {
  return make_scoped_ptr(new BeginFrameSourceMultiplexer());
}

BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
    : BeginFrameSourceMixIn(),
      minimum_interval_(base::TimeDelta()),
      active_source_(NULL),
      source_list_() {
}

BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer(
    base::TimeDelta minimum_interval)
    : BeginFrameSourceMixIn(),
      minimum_interval_(minimum_interval),
      active_source_(NULL),
      source_list_() {
}

BeginFrameSourceMultiplexer::~BeginFrameSourceMultiplexer() {
}

void BeginFrameSourceMultiplexer::SetMinimumInterval(
    base::TimeDelta new_minimum_interval) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetMinimumInterval",
               "current minimum (us)",
               minimum_interval_.InMicroseconds(),
               "new minimum (us)",
               new_minimum_interval.InMicroseconds());
  DCHECK_GE(new_minimum_interval.ToInternalValue(), 0);
  minimum_interval_ = new_minimum_interval;
}

void BeginFrameSourceMultiplexer::AddSource(BeginFrameSource* new_source) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::AddSource",
               "current active",
               active_source_,
               "source to remove",
               new_source);
  DCHECK(new_source);
  DCHECK(!HasSource(new_source));

  source_list_.insert(new_source);

  // If there is no active source, set the new one as the active one.
  if (!active_source_)
    SetActiveSource(new_source);
}

void BeginFrameSourceMultiplexer::RemoveSource(
    BeginFrameSource* existing_source) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::RemoveSource",
               "current active",
               active_source_,
               "source to remove",
               existing_source);
  DCHECK(existing_source);
  DCHECK(HasSource(existing_source));
  DCHECK_NE(existing_source, active_source_);
  source_list_.erase(existing_source);
}

void BeginFrameSourceMultiplexer::SetActiveSource(
    BeginFrameSource* new_source) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetActiveSource",
               "current active",
               active_source_,
               "to become active",
               new_source);

  DCHECK(HasSource(new_source) || new_source == NULL);

  bool needs_begin_frames = NeedsBeginFrames();
  if (active_source_) {
    if (needs_begin_frames)
      SetNeedsBeginFrames(false);

    // Technically we shouldn't need to remove observation, but this prevents
    // the case where SetNeedsBeginFrames message gets to the source after a
    // message has already been sent.
    active_source_->RemoveObserver(this);
    active_source_ = NULL;
  }
  DCHECK(!active_source_);
  active_source_ = new_source;

  if (active_source_) {
    active_source_->AddObserver(this);

    if (needs_begin_frames) {
      SetNeedsBeginFrames(true);
    }
  }
}

const BeginFrameSource* BeginFrameSourceMultiplexer::ActiveSource() {
  return active_source_;
}

// BeginFrameObserver support
void BeginFrameSourceMultiplexer::OnBeginFrame(const BeginFrameArgs& args) {
  if (!IsIncreasing(args)) {
    DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
                 "action",
                 "discarding",
                 "new args",
                 args.AsValue());
    return;
  }
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
               "action",
               "using",
               "new args",
               args.AsValue());
  CallOnBeginFrame(args);
}

const BeginFrameArgs BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs()
    const {
  if (observer_)
    return observer_->LastUsedBeginFrameArgs();
  else
    return BeginFrameArgs();
}

// BeginFrameSource support
void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange(
    bool needs_begin_frames) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange",
               "active_source", active_source_, "needs_begin_frames",
               needs_begin_frames);
  if (active_source_) {
    active_source_->SetNeedsBeginFrames(needs_begin_frames);
  } else {
    DCHECK(!needs_begin_frames);
  }
}

void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) {
  DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame",
               "active_source",
               active_source_,
               "remaining_frames",
               remaining_frames);
  if (active_source_) {
    active_source_->DidFinishFrame(remaining_frames);
  }
}

// Tracing support
void BeginFrameSourceMultiplexer::AsValueInto(
    base::trace_event::TracedValue* dict) const {
  dict->SetString("type", "BeginFrameSourceMultiplexer");

  dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds());
  if (observer_) {
    dict->BeginDictionary("last_begin_frame_args");
    observer_->LastUsedBeginFrameArgs().AsValueInto(dict);
    dict->EndDictionary();
  }

  if (active_source_) {
    dict->BeginDictionary("active_source");
    active_source_->AsValueInto(dict);
    dict->EndDictionary();
  } else {
    dict->SetString("active_source", "NULL");
  }

  dict->BeginArray("sources");
  for (std::set<BeginFrameSource*>::const_iterator it = source_list_.begin();
       it != source_list_.end();
       ++it) {
    dict->BeginDictionary();
    (*it)->AsValueInto(dict);
    dict->EndDictionary();
  }
  dict->EndArray();
}

// protected methods
bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) {
  return (source_list_.find(source) != source_list_.end());
}

bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) {
  DCHECK(args.IsValid());
  if (!observer_)
    return false;

  // If the last begin frame is invalid, then any new begin frame is valid.
  if (!observer_->LastUsedBeginFrameArgs().IsValid())
    return true;

  // Only allow new args have a *strictly bigger* frame_time value and statisfy
  // minimum interval requirement.
  return (args.frame_time >=
          observer_->LastUsedBeginFrameArgs().frame_time + minimum_interval_);
}

}  // namespace cc
