// 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 "services/gfx/compositor/backend/gpu_output.h"

#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "services/gfx/compositor/backend/gpu_rasterizer.h"
#include "services/gfx/compositor/render/render_frame.h"

namespace compositor {
namespace {
// Maximum number of frames to hold in the queue for rendering.
constexpr size_t kMaxPipelineDepth = 1;
}

template <typename T>
static void Drop(scoped_ptr<T> ptr) {}

static scoped_ptr<base::MessagePump> CreateMessagePumpMojo() {
  return base::MessageLoop::CreateMessagePumpForType(
      base::MessageLoop::TYPE_DEFAULT);
}

GpuOutput::GpuOutput(
    mojo::InterfaceHandle<mojo::ContextProvider> context_provider,
    const SchedulerCallbacks& scheduler_callbacks,
    const base::Closure& error_callback)
    : scheduler_(new VsyncScheduler(base::MessageLoop::current()->task_runner(),
                                    scheduler_callbacks)),
      rasterizer_delegate_(make_scoped_ptr(new RasterizerDelegate())) {
  DCHECK(context_provider);

  rasterizer_delegate_->PostInitialize(
      std::move(context_provider), scheduler_,
      base::MessageLoop::current()->task_runner(), error_callback);
}

GpuOutput::~GpuOutput() {
  // Ensure destruction happens on the correct thread.
  rasterizer_delegate_->PostDestroy(rasterizer_delegate_.Pass());
}

Scheduler* GpuOutput::GetScheduler() {
  return scheduler_.get();
}

void GpuOutput::SubmitFrame(const scoped_refptr<RenderFrame>& frame) {
  rasterizer_delegate_->PostFrame(frame);
}

GpuOutput::RasterizerDelegate::RasterizerDelegate() {
  base::Thread::Options options;
  options.message_pump_factory = base::Bind(&CreateMessagePumpMojo);

  thread_.reset(new base::Thread("gpu_rasterizer"));
  thread_->StartWithOptions(options);
  task_runner_ = thread_->message_loop()->task_runner();
}

GpuOutput::RasterizerDelegate::~RasterizerDelegate() {}

void GpuOutput::RasterizerDelegate::PostInitialize(
    mojo::InterfaceHandle<mojo::ContextProvider> context_provider,
    const scoped_refptr<VsyncScheduler>& scheduler,
    const scoped_refptr<base::TaskRunner>& task_runner,
    const base::Closure& error_callback) {
  task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&RasterizerDelegate::InitializeTask, base::Unretained(this),
                 base::Passed(std::move(context_provider)), scheduler,
                 base::MessageLoop::current()->task_runner(), error_callback));
}

void GpuOutput::RasterizerDelegate::PostDestroy(
    scoped_ptr<RasterizerDelegate> self) {
  task_runner_->PostTask(
      FROM_HERE, base::Bind(&Drop<RasterizerDelegate>, base::Passed(&self)));
}

void GpuOutput::RasterizerDelegate::PostFrame(
    const scoped_refptr<RenderFrame>& frame) {
  bool was_empty;
  scoped_refptr<RenderFrame> dropped_frame;
  {
    std::lock_guard<std::mutex> lock(mutex_);
    was_empty = frames_.empty();
    if (frames_.size() == kMaxPipelineDepth) {
      // TODO(jeffbrown): Adjust scheduler behavior to compensate.
      LOG(ERROR) << "Renderer pipeline stalled, dropping a frame to catch up.";
      dropped_frame = frames_.front();  // drop an old frame outside the lock
      frames_.pop();
    }
    frames_.push(frame);
  }

  if (was_empty)
    PostSubmit();
}

void GpuOutput::RasterizerDelegate::PostSubmit() {
  TRACE_EVENT0("gfx", "GpuOutput::RasterizerDelegate::PostSubmit");
  task_runner_->PostTask(FROM_HERE, base::Bind(&RasterizerDelegate::SubmitTask,
                                               base::Unretained(this)));
}

void GpuOutput::RasterizerDelegate::InitializeTask(
    mojo::InterfaceHandle<mojo::ContextProvider> context_provider,
    const scoped_refptr<VsyncScheduler>& scheduler,
    const scoped_refptr<base::TaskRunner>& task_runner,
    const base::Closure& error_callback) {
  rasterizer_.reset(new GpuRasterizer(
      mojo::ContextProviderPtr::Create(std::move(context_provider)), scheduler,
      task_runner, error_callback));
}

void GpuOutput::RasterizerDelegate::SubmitTask() {
  TRACE_EVENT0("gfx", "GpuOutput::RasterizerDelegate::SubmitTask");
  bool have_more;
  scoped_refptr<RenderFrame> frame;
  {
    std::lock_guard<std::mutex> lock(mutex_);
    DCHECK(!frames_.empty());
    frame = frames_.front();
    frames_.pop();
    have_more = !frames_.empty();
  }

  if (have_more)
    PostSubmit();

  int64_t submit_time = MojoGetTimeTicksNow();
  rasterizer_->SubmitFrame(
      frame, base::Bind(&RasterizerDelegate::OnFrameSubmitted,
                        base::Unretained(this), frame->frame_info().frame_time,
                        frame->frame_info().presentation_time, submit_time));
}

void GpuOutput::RasterizerDelegate::OnFrameSubmitted(int64_t frame_time,
                                                     int64_t presentation_time,
                                                     int64_t submit_time,
                                                     bool presented) {
  TRACE_EVENT0("gfx", "GpuOutput::RasterizerDelegate::OnFrameSubmitted");
  // TODO(jeffbrown): Adjust scheduler behavior based on observed timing.
  // Note: These measurements don't account for systematic downstream delay
  // in the display pipeline (how long it takes pixels to actually light up).
  int64_t complete_time = MojoGetTimeTicksNow();
  if (presented) {
    DVLOG(3) << "Frame presented: submission latency "
             << (submit_time - frame_time) << " us, rasterization latency "
             << (complete_time - submit_time) << " us, total latency "
             << (complete_time - frame_time) << " us, presentation time error "
             << (complete_time - presentation_time);
  } else {
    DVLOG(3) << "Frame deferred.";
  }
}

}  // namespace compositor
