// 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 "android_webview/browser/hardware_renderer.h"

#include <utility>

#include "android_webview/browser/aw_gl_surface.h"
#include "android_webview/browser/aw_render_thread_context_provider.h"
#include "android_webview/browser/parent_compositor_draw_constraints.h"
#include "android_webview/browser/render_thread_manager.h"
#include "android_webview/browser/surfaces_instance.h"
#include "android_webview/public/browser/draw_gl.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "cc/output/compositor_frame.h"
#include "cc/surfaces/compositor_frame_sink_support.h"
#include "cc/surfaces/local_surface_id_allocator.h"
#include "cc/surfaces/surface_manager.h"
#include "ui/gfx/transform.h"
#include "ui/gl/gl_bindings.h"

namespace android_webview {

HardwareRenderer::HardwareRenderer(RenderThreadManager* state)
    : render_thread_manager_(state),
      last_egl_context_(eglGetCurrentContext()),
      surfaces_(SurfacesInstance::GetOrCreateInstance()),
      frame_sink_id_(surfaces_->AllocateFrameSinkId()),
      local_surface_id_allocator_(
          base::MakeUnique<cc::LocalSurfaceIdAllocator>()),
      last_committed_compositor_frame_sink_id_(0u),
      last_submitted_compositor_frame_sink_id_(0u) {
  DCHECK(last_egl_context_);
  surfaces_->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_);
  CreateNewCompositorFrameSinkSupport();
}

HardwareRenderer::~HardwareRenderer() {
  // Must reset everything before |surface_factory_| to ensure all
  // resources are returned before resetting.
  if (child_id_.is_valid())
    DestroySurface();
  support_.reset();
  surfaces_->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);

  // Reset draw constraints.
  render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
      ParentCompositorDrawConstraints());
  for (auto& child_frame : child_frame_queue_) {
    child_frame->WaitOnFutureIfNeeded();
    ReturnChildFrame(std::move(child_frame));
  }
}

void HardwareRenderer::CommitFrame() {
  TRACE_EVENT0("android_webview", "CommitFrame");
  scroll_offset_ = render_thread_manager_->GetScrollOffsetOnRT();
  ChildFrameQueue child_frames = render_thread_manager_->PassFramesOnRT();
  // |child_frames| should have at most one non-empty frame, and one current
  // and unwaited frame, in that order.
  DCHECK_LE(child_frames.size(), 2u);
  if (child_frames.empty())
    return;
  // Insert all except last, ie current frame.
  while (child_frames.size() > 1u) {
    child_frame_queue_.emplace_back(std::move(child_frames.front()));
    child_frames.pop_front();
  }
  for (auto& pruned_frame : WaitAndPruneFrameQueue(&child_frame_queue_))
    ReturnChildFrame(std::move(pruned_frame));
  DCHECK_LE(child_frame_queue_.size(), 1u);
  child_frame_queue_.emplace_back(std::move(child_frames.front()));
}

void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info) {
  TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");

  for (auto& pruned_frame : WaitAndPruneFrameQueue(&child_frame_queue_))
    ReturnChildFrame(std::move(pruned_frame));
  DCHECK_LE(child_frame_queue_.size(), 1u);
  if (!child_frame_queue_.empty()) {
    child_frame_ = std::move(child_frame_queue_.front());
    child_frame_queue_.clear();
  }
  if (child_frame_) {
    last_committed_compositor_frame_sink_id_ =
        child_frame_->compositor_frame_sink_id;
  }

  // We need to watch if the current Android context has changed and enforce
  // a clean-up in the compositor.
  EGLContext current_context = eglGetCurrentContext();
  DCHECK(current_context) << "DrawGL called without EGLContext";

  // TODO(boliu): Handle context loss.
  if (last_egl_context_ != current_context)
    DLOG(WARNING) << "EGLContextChanged";

  // SurfaceFactory::SubmitCompositorFrame might call glFlush. So calling it
  // during "kModeSync" stage (which does not allow GL) might result in extra
  // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid
  // unnecessary kModeProcess.
  if (child_frame_.get() && child_frame_->frame.get()) {
    if (!compositor_id_.Equals(child_frame_->compositor_id) ||
        last_submitted_compositor_frame_sink_id_ !=
            child_frame_->compositor_frame_sink_id) {
      if (child_id_.is_valid())
        DestroySurface();

      CreateNewCompositorFrameSinkSupport();
      compositor_id_ = child_frame_->compositor_id;
      last_submitted_compositor_frame_sink_id_ =
          child_frame_->compositor_frame_sink_id;
    }

    std::unique_ptr<cc::CompositorFrame> child_compositor_frame =
        std::move(child_frame_->frame);

    gfx::Size frame_size =
        child_compositor_frame->render_pass_list.back()->output_rect.size();
    bool size_changed = frame_size != frame_size_;
    frame_size_ = frame_size;
    if (!child_id_.is_valid() || size_changed) {
      if (child_id_.is_valid())
        DestroySurface();
      AllocateSurface();
    }

    support_->SubmitCompositorFrame(child_id_,
                                    std::move(*child_compositor_frame));
  }

  gfx::Transform transform(gfx::Transform::kSkipInitialization);
  transform.matrix().setColMajorf(draw_info->transform);
  transform.Translate(scroll_offset_.x(), scroll_offset_.y());

  gfx::Size viewport(draw_info->width, draw_info->height);
  // Need to post the new transform matrix back to child compositor
  // because there is no onDraw during a Render Thread animation, and child
  // compositor might not have the tiles rasterized as the animation goes on.
  ParentCompositorDrawConstraints draw_constraints(
      draw_info->is_layer, transform, viewport.IsEmpty());
  if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) {
    render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
        draw_constraints);
  }

  if (!child_id_.is_valid())
    return;

  gfx::Rect clip(draw_info->clip_left, draw_info->clip_top,
                 draw_info->clip_right - draw_info->clip_left,
                 draw_info->clip_bottom - draw_info->clip_top);
  surfaces_->DrawAndSwap(viewport, clip, transform, frame_size_,
                         cc::SurfaceId(frame_sink_id_, child_id_));
}

void HardwareRenderer::AllocateSurface() {
  DCHECK(!child_id_.is_valid());
  child_id_ = local_surface_id_allocator_->GenerateId();
  surfaces_->AddChildId(cc::SurfaceId(frame_sink_id_, child_id_));
}

void HardwareRenderer::DestroySurface() {
  DCHECK(child_id_.is_valid());

  // Submit an empty frame to force any existing resources to be returned.
  support_->SubmitCompositorFrame(child_id_, cc::CompositorFrame());
  surfaces_->RemoveChildId(cc::SurfaceId(frame_sink_id_, child_id_));
  support_->EvictFrame();
  child_id_ = cc::LocalSurfaceId();
}

void HardwareRenderer::DidReceiveCompositorFrameAck() {}

void HardwareRenderer::OnBeginFrame(const cc::BeginFrameArgs& args) {
  // TODO(tansell): Hook this up.
}

void HardwareRenderer::ReclaimResources(
    const cc::ReturnedResourceArray& resources) {
  ReturnResourcesToCompositor(resources, compositor_id_,
                              last_submitted_compositor_frame_sink_id_);
}

void HardwareRenderer::WillDrawSurface(
    const cc::LocalSurfaceId& local_surface_id,
    const gfx::Rect& damage_rect) {}

// static
ChildFrameQueue HardwareRenderer::WaitAndPruneFrameQueue(
    ChildFrameQueue* child_frames_ptr) {
  ChildFrameQueue& child_frames = *child_frames_ptr;
  ChildFrameQueue pruned_frames;

  // First find the last non-empty frame.
  int last_non_empty_index = -1;
  for (size_t i = 0; i < child_frames.size(); ++i) {
    auto& child_frame = *child_frames[i];
    child_frame.WaitOnFutureIfNeeded();
    if (child_frame.frame)
      last_non_empty_index = i;
  }
  if (last_non_empty_index < 0) {
    child_frames.clear();
    return pruned_frames;
  }

  // Prune end.
  while (child_frames.size() > static_cast<size_t>(last_non_empty_index + 1)) {
    std::unique_ptr<ChildFrame> frame = std::move(child_frames.back());
    child_frames.pop_back();
    if (frame->frame)
      pruned_frames.emplace_back(std::move(frame));
  }

  // Prune front.
  while (child_frames.size() > 1) {
    std::unique_ptr<ChildFrame> frame = std::move(child_frames.front());
    child_frames.pop_front();
    if (frame->frame)
      pruned_frames.emplace_back(std::move(frame));
  }
  return pruned_frames;
}

void HardwareRenderer::ReturnChildFrame(
    std::unique_ptr<ChildFrame> child_frame) {
  if (!child_frame || !child_frame->frame)
    return;

  cc::ReturnedResourceArray resources_to_return;
  cc::TransferableResource::ReturnResources(child_frame->frame->resource_list,
                                            &resources_to_return);

  // The child frame's compositor id is not necessarily same as
  // compositor_id_.
  ReturnResourcesToCompositor(resources_to_return, child_frame->compositor_id,
                              child_frame->compositor_frame_sink_id);
}

void HardwareRenderer::ReturnResourcesToCompositor(
    const cc::ReturnedResourceArray& resources,
    const CompositorID& compositor_id,
    uint32_t compositor_frame_sink_id) {
  if (compositor_frame_sink_id != last_committed_compositor_frame_sink_id_)
    return;
  render_thread_manager_->InsertReturnedResourcesOnRT(resources, compositor_id,
                                                      compositor_frame_sink_id);
}

void HardwareRenderer::CreateNewCompositorFrameSinkSupport() {
  support_.reset();
  support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>(
      this, surfaces_->GetSurfaceManager(), frame_sink_id_, false /* is_root */,
      false /* handles_frame_sink_id_invalidation */,
      true /* needs_sync_points */);
}

}  // namespace android_webview
