// Copyright 2013 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 "content/renderer/android/synchronous_layer_tree_frame_sink.h"

#include <vector>

#include "base/auto_reset.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/render_pass.h"
#include "components/viz/common/quads/surface_draw_quad.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/output_surface_frame.h"
#include "components/viz/service/display/software_output_device.h"
#include "components/viz/service/display/texture_deleter.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/common/view_messages.h"
#include "content/renderer/android/synchronous_compositor_registry.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/render_thread_impl.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_sender.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"

namespace content {

namespace {

const int64_t kFallbackTickTimeoutInMilliseconds = 100;
const viz::FrameSinkId kRootFrameSinkId(1, 1);
const viz::FrameSinkId kChildFrameSinkId(1, 2);

// Do not limit number of resources, so use an unrealistically high value.
const size_t kNumResourcesLimit = 10 * 1000 * 1000;

class SoftwareDevice : public viz::SoftwareOutputDevice {
 public:
  SoftwareDevice(SkCanvas** canvas) : canvas_(canvas) {}

  void Resize(const gfx::Size& pixel_size, float device_scale_factor) override {
    // Intentional no-op: canvas size is controlled by the embedder.
  }
  SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
    DCHECK(*canvas_) << "BeginPaint with no canvas set";
    return *canvas_;
  }
  void EndPaint() override {}

 private:
  SkCanvas** canvas_;

  DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
};

}  // namespace

class SynchronousLayerTreeFrameSink::SoftwareOutputSurface
    : public viz::OutputSurface {
 public:
  SoftwareOutputSurface(std::unique_ptr<SoftwareDevice> software_device)
      : viz::OutputSurface(std::move(software_device)) {}

  // viz::OutputSurface implementation.
  void BindToClient(viz::OutputSurfaceClient* client) override {}
  void EnsureBackbuffer() override {}
  void DiscardBackbuffer() override {}
  void BindFramebuffer() override {}
  void SetDrawRectangle(const gfx::Rect& rect) override {}
  void SwapBuffers(viz::OutputSurfaceFrame frame) override {}
#if BUILDFLAG(ENABLE_VULKAN)
  gpu::VulkanSurface* GetVulkanSurface() override {
    NOTIMPLEMENTED();
    return nullptr;
  }
#endif
  void Reshape(const gfx::Size& size,
               float scale_factor,
               const gfx::ColorSpace& color_space,
               bool has_alpha,
               bool use_stencil) override {}
  uint32_t GetFramebufferCopyTextureFormat() override { return 0; }
  viz::OverlayCandidateValidator* GetOverlayCandidateValidator()
      const override {
    return nullptr;
  }
  bool IsDisplayedAsOverlayPlane() const override { return false; }
  unsigned GetOverlayTextureId() const override { return 0; }
  gfx::BufferFormat GetOverlayBufferFormat() const override {
    return gfx::BufferFormat::RGBX_8888;
  }
  bool HasExternalStencilTest() const override { return false; }
  void ApplyExternalStencil() override {}
  unsigned UpdateGpuFence() override { return 0; }
};

SynchronousLayerTreeFrameSink::SynchronousLayerTreeFrameSink(
    scoped_refptr<viz::ContextProvider> context_provider,
    scoped_refptr<viz::RasterContextProvider> worker_context_provider,
    scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
    IPC::Sender* sender,
    int routing_id,
    uint32_t layer_tree_frame_sink_id,
    std::unique_ptr<viz::BeginFrameSource> synthetic_begin_frame_source,
    SynchronousCompositorRegistry* registry,
    scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
    : cc::LayerTreeFrameSink(std::move(context_provider),
                             std::move(worker_context_provider),
                             std::move(compositor_task_runner),
                             gpu_memory_buffer_manager),
      routing_id_(routing_id),
      layer_tree_frame_sink_id_(layer_tree_frame_sink_id),
      registry_(registry),
      sender_(sender),
      memory_policy_(0u),
      frame_swap_message_queue_(frame_swap_message_queue),
      parent_local_surface_id_allocator_(
          new viz::ParentLocalSurfaceIdAllocator),
      synthetic_begin_frame_source_(std::move(synthetic_begin_frame_source)) {
  DCHECK(registry_);
  DCHECK(sender_);
  if (!synthetic_begin_frame_source_) {
    external_begin_frame_source_ =
        std::make_unique<viz::ExternalBeginFrameSource>(this);
  }
  thread_checker_.DetachFromThread();
  memory_policy_.priority_cutoff_when_visible =
      gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
}

SynchronousLayerTreeFrameSink::~SynchronousLayerTreeFrameSink() = default;

void SynchronousLayerTreeFrameSink::SetSyncClient(
    SynchronousLayerTreeFrameSinkClient* compositor) {
  sync_client_ = compositor;
}

bool SynchronousLayerTreeFrameSink::BindToClient(
    cc::LayerTreeFrameSinkClient* sink_client) {
  DCHECK(CalledOnValidThread());
  if (!cc::LayerTreeFrameSink::BindToClient(sink_client))
    return false;

  // The SharedBitmapManager is null since software compositing is not supported
  // or used on Android.
  frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>(
      /*shared_bitmap_manager=*/nullptr);

  client_->SetBeginFrameSource(synthetic_begin_frame_source_
                                   ? synthetic_begin_frame_source_.get()
                                   : external_begin_frame_source_.get());
  client_->SetMemoryPolicy(memory_policy_);
  client_->SetTreeActivationCallback(
      base::Bind(&SynchronousLayerTreeFrameSink::DidActivatePendingTree,
                 base::Unretained(this)));
  registry_->RegisterLayerTreeFrameSink(routing_id_, this);

  constexpr bool root_support_is_root = true;
  constexpr bool child_support_is_root = false;
  constexpr bool needs_sync_points = true;
  root_support_ = std::make_unique<viz::CompositorFrameSinkSupport>(
      this, frame_sink_manager_.get(), kRootFrameSinkId, root_support_is_root,
      needs_sync_points);
  child_support_ = std::make_unique<viz::CompositorFrameSinkSupport>(
      this, frame_sink_manager_.get(), kChildFrameSinkId, child_support_is_root,
      needs_sync_points);

  viz::RendererSettings software_renderer_settings;

  auto output_surface = std::make_unique<SoftwareOutputSurface>(
      std::make_unique<SoftwareDevice>(&current_sw_canvas_));
  software_output_surface_ = output_surface.get();

  // The gpu_memory_buffer_manager here is null as the Display is only used for
  // resourcesless software draws, where no resources are included in the frame
  // swapped from the compositor. So there is no need for it.
  // The shared_bitmap_manager_ is provided for the Display to allocate
  // resources.
  // TODO(crbug.com/692814): The Display never sends its resources out of
  // process so there is no reason for it to use a SharedBitmapManager.
  display_ = std::make_unique<viz::Display>(
      &shared_bitmap_manager_, software_renderer_settings, kRootFrameSinkId,
      std::move(output_surface), nullptr /* scheduler */,
      nullptr /* current_task_runner */);
  display_->Initialize(&display_client_,
                       frame_sink_manager_->surface_manager());
  display_->SetVisible(true);
  return true;
}

void SynchronousLayerTreeFrameSink::DetachFromClient() {
  DCHECK(CalledOnValidThread());
  client_->SetBeginFrameSource(nullptr);
  // Destroy the begin frame source on the same thread it was bound on.
  synthetic_begin_frame_source_ = nullptr;
  external_begin_frame_source_ = nullptr;
  if (sync_client_)
    sync_client_->SinkDestroyed();
  registry_->UnregisterLayerTreeFrameSink(routing_id_, this);
  client_->SetTreeActivationCallback(base::Closure());
  root_support_.reset();
  child_support_.reset();
  software_output_surface_ = nullptr;
  display_ = nullptr;
  parent_local_surface_id_allocator_ = nullptr;
  frame_sink_manager_ = nullptr;
  cc::LayerTreeFrameSink::DetachFromClient();
  CancelFallbackTick();
}

void SynchronousLayerTreeFrameSink::SubmitCompositorFrame(
    viz::CompositorFrame frame,
    bool show_hit_test_borders) {
  DCHECK(CalledOnValidThread());
  DCHECK(sync_client_);

  if (fallback_tick_running_) {
    DCHECK(frame.resource_list.empty());
    std::vector<viz::ReturnedResource> return_resources;
    ReclaimResources(return_resources);
    did_submit_frame_ = true;
    return;
  }

  viz::CompositorFrame submit_frame;

  if (in_software_draw_) {
    // The frame we send to the client is actually just the metadata. Preserve
    // the |frame| for the software path below.
    submit_frame.metadata = frame.metadata.Clone();

    // The layer compositor should be giving a frame that covers the
    // |sw_viewport_for_current_draw_| but at 0,0.
    gfx::Size child_size = sw_viewport_for_current_draw_.size();
    DCHECK(gfx::Rect(child_size) == frame.render_pass_list.back()->output_rect);

    // Make a size that covers from 0,0 and includes the area coming from the
    // layer compositor.
    gfx::Size display_size(sw_viewport_for_current_draw_.right(),
                           sw_viewport_for_current_draw_.bottom());
    display_->Resize(display_size);

    if (!root_local_surface_id_.is_valid() || display_size_ != display_size ||
        device_scale_factor_ != frame.metadata.device_scale_factor) {
      parent_local_surface_id_allocator_->GenerateId();
      root_local_surface_id_ =
          parent_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
      display_size_ = display_size;
      device_scale_factor_ = frame.metadata.device_scale_factor;
    }

    if (!child_local_surface_id_.is_valid() || child_size_ != child_size ||
        device_scale_factor_ != frame.metadata.device_scale_factor) {
      parent_local_surface_id_allocator_->GenerateId();
      child_local_surface_id_ =
          parent_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
      child_size_ = child_size;
      device_scale_factor_ = frame.metadata.device_scale_factor;
    }

    display_->SetLocalSurfaceId(root_local_surface_id_,
                                frame.metadata.device_scale_factor);

    // The offset for the child frame relative to the origin of the canvas being
    // drawn into.
    gfx::Transform child_transform;
    child_transform.Translate(
        gfx::Vector2dF(sw_viewport_for_current_draw_.OffsetFromOrigin()));

    // Make a root frame that embeds the frame coming from the layer compositor
    // and positions it based on the provided viewport.
    // TODO(danakj): We could apply the transform here instead of passing it to
    // the LayerTreeFrameSink client too? (We'd have to do the same for
    // hardware frames in SurfacesInstance?)
    viz::CompositorFrame embed_frame;
    embed_frame.metadata.begin_frame_ack = frame.metadata.begin_frame_ack;
    embed_frame.metadata.device_scale_factor =
        frame.metadata.device_scale_factor;
    embed_frame.render_pass_list.push_back(viz::RenderPass::Create());

    // The embedding RenderPass covers the entire Display's area.
    const auto& embed_render_pass = embed_frame.render_pass_list.back();
    embed_render_pass->SetNew(1, gfx::Rect(display_size),
                              gfx::Rect(display_size), gfx::Transform());
    embed_render_pass->has_transparent_background = false;

    // The RenderPass has a single SurfaceDrawQuad (and SharedQuadState for it).
    bool are_contents_opaque =
        !frame.render_pass_list.back()->has_transparent_background;
    auto* shared_quad_state =
        embed_render_pass->CreateAndAppendSharedQuadState();
    auto* surface_quad =
        embed_render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
    shared_quad_state->SetAll(
        child_transform, gfx::Rect(child_size), gfx::Rect(child_size),
        gfx::Rect() /* clip_rect */, false /* is_clipped */,
        are_contents_opaque /* are_contents_opaque */, 1.f /* opacity */,
        SkBlendMode::kSrcOver, 0 /* sorting_context_id */);
    surface_quad->SetNew(
        shared_quad_state, gfx::Rect(child_size), gfx::Rect(child_size),
        viz::SurfaceRange(
            base::nullopt,
            viz::SurfaceId(kChildFrameSinkId, child_local_surface_id_)),
        SK_ColorWHITE, false);

    child_support_->SubmitCompositorFrame(child_local_surface_id_,
                                          std::move(frame));
    root_support_->SubmitCompositorFrame(root_local_surface_id_,
                                         std::move(embed_frame));
    display_->DrawAndSwap();
  } else {
    // For hardware draws we send the whole frame to the client so it can draw
    // the content in it.
    submit_frame = std::move(frame);
  }

  sync_client_->SubmitCompositorFrame(layer_tree_frame_sink_id_,
                                      std::move(submit_frame));
  did_submit_frame_ = true;
}

void SynchronousLayerTreeFrameSink::DidNotProduceFrame(
    const viz::BeginFrameAck& ack) {
}

void SynchronousLayerTreeFrameSink::DidAllocateSharedBitmap(
    mojo::ScopedSharedBufferHandle buffer,
    const viz::SharedBitmapId& id) {
  // Webview does not use software compositing (other than resourceless draws,
  // but this is called for software /resources/).
  NOTREACHED();
}

void SynchronousLayerTreeFrameSink::DidDeleteSharedBitmap(
    const viz::SharedBitmapId& id) {
  // Webview does not use software compositing (other than resourceless draws,
  // but this is called for software /resources/).
  NOTREACHED();
}

void SynchronousLayerTreeFrameSink::CancelFallbackTick() {
  fallback_tick_.Cancel();
  fallback_tick_pending_ = false;
}

void SynchronousLayerTreeFrameSink::FallbackTickFired() {
  DCHECK(CalledOnValidThread());
  TRACE_EVENT0("renderer", "SynchronousLayerTreeFrameSink::FallbackTickFired");
  base::AutoReset<bool> in_fallback_tick(&fallback_tick_running_, true);
  frame_swap_message_queue_->NotifyFramesAreDiscarded(true);
  SkBitmap bitmap;
  bitmap.allocN32Pixels(1, 1);
  bitmap.eraseColor(0);
  SkCanvas canvas(bitmap);
  fallback_tick_pending_ = false;
  DemandDrawSw(&canvas);
  frame_swap_message_queue_->NotifyFramesAreDiscarded(false);
}

void SynchronousLayerTreeFrameSink::Invalidate(bool needs_draw) {
  DCHECK(CalledOnValidThread());
  if (sync_client_)
    sync_client_->Invalidate(needs_draw);

  if (!fallback_tick_pending_) {
    fallback_tick_.Reset(
        base::Bind(&SynchronousLayerTreeFrameSink::FallbackTickFired,
                   base::Unretained(this)));
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, fallback_tick_.callback(),
        base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
    fallback_tick_pending_ = true;
  }
}

void SynchronousLayerTreeFrameSink::DemandDrawHw(
    const gfx::Size& viewport_size,
    const gfx::Rect& viewport_rect_for_tile_priority,
    const gfx::Transform& transform_for_tile_priority) {
  DCHECK(CalledOnValidThread());
  DCHECK(HasClient());
  DCHECK(context_provider_.get());
  CancelFallbackTick();

  client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority,
                                              transform_for_tile_priority);
  InvokeComposite(gfx::Transform(), gfx::Rect(viewport_size));
}

void SynchronousLayerTreeFrameSink::DemandDrawSw(SkCanvas* canvas) {
  DCHECK(CalledOnValidThread());
  DCHECK(canvas);
  DCHECK(!current_sw_canvas_);
  CancelFallbackTick();

  base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas);

  SkIRect canvas_clip = canvas->getDeviceClipBounds();
  gfx::Rect viewport = gfx::SkIRectToRect(canvas_clip);

  gfx::Transform transform(gfx::Transform::kSkipInitialization);
  transform.matrix() = canvas->getTotalMatrix();  // Converts 3x3 matrix to 4x4.

  // We will resize the Display to ensure it covers the entire |viewport|, so
  // save it for later.
  sw_viewport_for_current_draw_ = viewport;

  base::AutoReset<bool> set_in_software_draw(&in_software_draw_, true);
  InvokeComposite(transform, viewport);
}

void SynchronousLayerTreeFrameSink::WillSkipDraw() {
  CancelFallbackTick();
  client_->OnDraw(gfx::Transform(), gfx::Rect(), in_software_draw_,
                  true /*skip_draw*/);
}

void SynchronousLayerTreeFrameSink::InvokeComposite(
    const gfx::Transform& transform,
    const gfx::Rect& viewport) {
  did_submit_frame_ = false;
  // Adjust transform so that the layer compositor draws the |viewport| rect
  // at its origin. The offset of the |viewport| we pass to the layer compositor
  // is ignored for drawing, so its okay to not match the transform.
  // TODO(danakj): Why do we pass a viewport origin and then not really use it
  // (only for comparing to the viewport passed in
  // SetExternalTilePriorityConstraints), surely this could be more clear?
  gfx::Transform adjusted_transform = transform;
  adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
  client_->OnDraw(adjusted_transform, viewport, in_software_draw_,
                  false /*skip_draw*/);

  if (did_submit_frame_) {
    // This must happen after unwinding the stack and leaving the compositor.
    // Usually it is a separate task but we just defer it until OnDraw completes
    // instead.
    client_->DidReceiveCompositorFrameAck();
  }
}

void SynchronousLayerTreeFrameSink::ReclaimResources(
    uint32_t layer_tree_frame_sink_id,
    const std::vector<viz::ReturnedResource>& resources) {
  // Ignore message if it's a stale one coming from a different output surface
  // (e.g. after a lost context).
  if (layer_tree_frame_sink_id != layer_tree_frame_sink_id_)
    return;
  client_->ReclaimResources(resources);
}

void SynchronousLayerTreeFrameSink::SetMemoryPolicy(size_t bytes_limit) {
  DCHECK(CalledOnValidThread());
  bool became_zero = memory_policy_.bytes_limit_when_visible && !bytes_limit;
  bool became_non_zero =
      !memory_policy_.bytes_limit_when_visible && bytes_limit;
  memory_policy_.bytes_limit_when_visible = bytes_limit;
  memory_policy_.num_resources_limit = kNumResourcesLimit;

  if (client_)
    client_->SetMemoryPolicy(memory_policy_);

  if (became_zero) {
    // This is small hack to drop context resources without destroying it
    // when this compositor is put into the background.
    context_provider()->ContextSupport()->SetAggressivelyFreeResources(
        true /* aggressively_free_resources */);
  } else if (became_non_zero) {
    context_provider()->ContextSupport()->SetAggressivelyFreeResources(
        false /* aggressively_free_resources */);
  }
}

void SynchronousLayerTreeFrameSink::DidActivatePendingTree() {
  DCHECK(CalledOnValidThread());
  if (sync_client_)
    sync_client_->DidActivatePendingTree();
  DeliverMessages();
}

void SynchronousLayerTreeFrameSink::DeliverMessages() {
  std::vector<std::unique_ptr<IPC::Message>> messages;
  std::unique_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
      frame_swap_message_queue_->AcquireSendMessageScope();
  frame_swap_message_queue_->DrainMessages(&messages);
  for (auto& msg : messages) {
    Send(msg.release());
  }
}

bool SynchronousLayerTreeFrameSink::Send(IPC::Message* message) {
  DCHECK(CalledOnValidThread());
  return sender_->Send(message);
}

bool SynchronousLayerTreeFrameSink::CalledOnValidThread() const {
  return thread_checker_.CalledOnValidThread();
}

void SynchronousLayerTreeFrameSink::DidReceiveCompositorFrameAck(
    const std::vector<viz::ReturnedResource>& resources) {
  ReclaimResources(resources);
}

void SynchronousLayerTreeFrameSink::DidPresentCompositorFrame(
    uint32_t presentation_token,
    const gfx::PresentationFeedback& feedback) {}

void SynchronousLayerTreeFrameSink::OnBeginFrame(
    const viz::BeginFrameArgs& args) {}

void SynchronousLayerTreeFrameSink::ReclaimResources(
    const std::vector<viz::ReturnedResource>& resources) {
  DCHECK(resources.empty());
  client_->ReclaimResources(resources);
}

void SynchronousLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) {}

void SynchronousLayerTreeFrameSink::OnNeedsBeginFrames(
    bool needs_begin_frames) {
  if (sync_client_) {
    sync_client_->SetNeedsBeginFrames(needs_begin_frames);
  }
}

void SynchronousLayerTreeFrameSink::BeginFrame(
    const viz::BeginFrameArgs& args) {
  if (external_begin_frame_source_)
    external_begin_frame_source_->OnBeginFrame(args);
}

void SynchronousLayerTreeFrameSink::SetBeginFrameSourcePaused(bool paused) {
  if (external_begin_frame_source_)
    external_begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
}

}  // namespace content
