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

#include "flutter/sky/shell/ui/animator.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "flutter/services/rasterizer/rasterizer.mojom.h"

namespace sky {
namespace shell {

const int kPipelineDepth = 3;

Animator::Animator(const Engine::Config& config,
                   rasterizer::RasterizerPtr rasterizer,
                   Engine* engine)
    : config_(config),
      rasterizer_(rasterizer.Pass()),
      engine_(engine),
      outstanding_requests_(0),
      did_defer_frame_request_(false),
      engine_requested_frame_(false),
      paused_(false),
      is_ready_to_draw_(false),
      weak_factory_(this) {}

Animator::~Animator() {}

void Animator::RequestFrame() {
  if (engine_requested_frame_)
    return;
  TRACE_EVENT_ASYNC_BEGIN0("flutter", "Frame request pending", this);
  engine_requested_frame_ = true;

  DCHECK(!did_defer_frame_request_);
  outstanding_requests_++;
  TRACE_COUNTER1("flutter", "outstanding_requests_", outstanding_requests_);
  if (outstanding_requests_ >= kPipelineDepth) {
    TRACE_EVENT_INSTANT1("flutter", "Frame request deferred",
                         TRACE_EVENT_SCOPE_THREAD, "outstanding_requests_",
                         outstanding_requests_);
    did_defer_frame_request_ = true;
    return;
  }

  if (!AwaitVSync()) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr(), 0),
        base::TimeDelta::FromMilliseconds(16));
  }
}

void Animator::FlushRealTimeEvents() {
  if (outstanding_requests_ > 0)
    rasterizer_.WaitForIncomingResponseWithTimeout(0);

  if (engine_requested_frame_ && vsync_provider_)
    vsync_provider_.WaitForIncomingResponseWithTimeout(0);
}

void Animator::Stop() {
  paused_ = true;
}

void Animator::Start() {
  Reset();
  RequestFrame();
}

void Animator::Animate(mojo::gfx::composition::FrameInfoPtr frame_info) {
  BeginFrame(frame_info->frame_time);
}

void Animator::BeginFrame(int64_t time_stamp) {
  TRACE_EVENT_ASYNC_END0("flutter", "Frame request pending", this);
  DCHECK(engine_requested_frame_);
  DCHECK(outstanding_requests_ > 0);
  DCHECK(outstanding_requests_ <= kPipelineDepth) << outstanding_requests_;

  engine_requested_frame_ = false;

  if (paused_) {
    OnFrameComplete();
    return;
  }

  begin_time_ = ftl::TimePoint::Now();
  ftl::TimePoint frame_time =
      time_stamp
          ? ftl::TimePoint() + ftl::TimeDelta::FromMicroseconds(time_stamp)
          : begin_time_;

  is_ready_to_draw_ = true;
  engine_->BeginFrame(frame_time);
  bool was_ready_to_draw = is_ready_to_draw_;
  is_ready_to_draw_ = false;

  // If we were still ready to draw when done with the frame, that means we
  // didn't draw anything this frame and we should acknowledge the frame
  // ourselves instead of waiting for the rasterizer to acknowledge it.
  if (was_ready_to_draw)
    OnFrameComplete();
}

void Animator::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
  if (!is_ready_to_draw_)
    return;  // Only draw once per frame.
  is_ready_to_draw_ = false;

  layer_tree->set_construction_time(ftl::TimePoint::Now() - begin_time_);

  // TODO(abarth): Doesn't this leak if OnFrameComplete never runs?
  rasterizer_->Draw(
      reinterpret_cast<uint64_t>(layer_tree.release()),
      base::Bind(&Animator::OnFrameComplete, weak_factory_.GetWeakPtr()));
}

void Animator::OnFrameComplete() {
  DCHECK(outstanding_requests_ > 0);
  --outstanding_requests_;
  TRACE_COUNTER1("flutter", "outstanding_requests_", outstanding_requests_);
  if (paused_)
    return;

  if (did_defer_frame_request_) {
    did_defer_frame_request_ = false;

    if (!AwaitVSync())
      BeginFrame(0);
  }
}

bool Animator::AwaitVSync() {
  if (frame_scheduler_) {
    frame_scheduler_->ScheduleFrame(
        base::Bind(&Animator::Animate, weak_factory_.GetWeakPtr()));
    return true;
  } else if (vsync_provider_) {
    vsync_provider_->AwaitVSync(
        base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr()));
    return true;
  }
  return false;
}

void Animator::Reset() {
  weak_factory_.InvalidateWeakPtrs();

  outstanding_requests_ = 0;
  TRACE_COUNTER1("flutter", "outstanding_requests_", outstanding_requests_);
  did_defer_frame_request_ = false;
  engine_requested_frame_ = false;
  paused_ = false;
}

void Animator::set_vsync_provider(vsync::VSyncProviderPtr vsync_provider) {
  DCHECK(!engine_requested_frame_);
  vsync_provider_ = vsync_provider.Pass();
}

}  // namespace shell
}  // namespace sky
