// 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/child_frame.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/trace_event/trace_event.h"
#include "cc/output/compositor_frame.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/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()),
      surface_id_allocator_(
          new cc::SurfaceIdAllocator(surfaces_->AllocateSurfaceClientId())),
      last_committed_output_surface_id_(0u),
      last_submitted_output_surface_id_(0u) {
  DCHECK(last_egl_context_);
  surfaces_->GetSurfaceManager()->RegisterSurfaceClientId(
      surface_id_allocator_->client_id());
  surfaces_->GetSurfaceManager()->RegisterSurfaceFactoryClient(
      surface_id_allocator_->client_id(), this);
}

HardwareRenderer::~HardwareRenderer() {
  // Must reset everything before |surface_factory_| to ensure all
  // resources are returned before resetting.
  if (!child_id_.is_null())
    DestroySurface();
  surface_factory_.reset();
  surfaces_->GetSurfaceManager()->UnregisterSurfaceFactoryClient(
      surface_id_allocator_->client_id());
  surfaces_->GetSurfaceManager()->InvalidateSurfaceClientId(
      surface_id_allocator_->client_id());

  // Reset draw constraints.
  render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
      ParentCompositorDrawConstraints());
  ReturnResourcesInChildFrame();
}

void HardwareRenderer::CommitFrame() {
  TRACE_EVENT0("android_webview", "CommitFrame");
  scroll_offset_ = render_thread_manager_->GetScrollOffsetOnRT();
  std::unique_ptr<ChildFrame> child_frame =
      render_thread_manager_->PassFrameOnRT();
  if (!child_frame.get())
    return;

  last_committed_output_surface_id_ = child_frame->output_surface_id;
  ReturnResourcesInChildFrame();
  child_frame_ = std::move(child_frame);
  DCHECK(child_frame_->frame.get());
  DCHECK(!child_frame_->frame->gl_frame_data);
}

void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info,
                              const ScopedAppGLStateRestore& gl_state) {
  TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");

  // 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_output_surface_id_ != child_frame_->output_surface_id) {
      if (!child_id_.is_null())
        DestroySurface();

      // This will return all the resources to the previous compositor.
      surface_factory_.reset();
      compositor_id_ = child_frame_->compositor_id;
      last_submitted_output_surface_id_ = child_frame_->output_surface_id;
      surface_factory_.reset(
          new cc::SurfaceFactory(surfaces_->GetSurfaceManager(), this));
    }

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

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

    surface_factory_->SubmitCompositorFrame(child_id_,
                                            std::move(*child_compositor_frame),
                                            cc::SurfaceFactory::DrawCallback());
  }

  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_null())
    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_, child_id_,
                         gl_state);
}

void HardwareRenderer::AllocateSurface() {
  DCHECK(child_id_.is_null());
  DCHECK(surface_factory_);
  child_id_ = surface_id_allocator_->GenerateId();
  surface_factory_->Create(child_id_);
  surfaces_->AddChildId(child_id_);
}

void HardwareRenderer::DestroySurface() {
  DCHECK(!child_id_.is_null());
  DCHECK(surface_factory_);
  surfaces_->RemoveChildId(child_id_);
  surface_factory_->Destroy(child_id_);
  child_id_ = cc::SurfaceId();
}

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

void HardwareRenderer::SetBeginFrameSource(
    cc::BeginFrameSource* begin_frame_source) {
  // TODO(tansell): Hook this up.
}

void HardwareRenderer::SetBackingFrameBufferObject(
    int framebuffer_binding_ext) {
  surfaces_->SetBackingFrameBufferObject(framebuffer_binding_ext);
}

void HardwareRenderer::ReturnResourcesInChildFrame() {
  if (child_frame_.get() && child_frame_->frame.get()) {
    cc::ReturnedResourceArray resources_to_return;
    cc::TransferableResource::ReturnResources(
        child_frame_->frame->delegated_frame_data->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_->output_surface_id);
  }
  child_frame_.reset();
}

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

}  // namespace android_webview
