// Copyright 2017 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 "ash/fast_ink/fast_ink_host.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>

#include <memory>

#include "ash/public/cpp/ash_switches.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/base/math_util.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/viz/common/frame_timing_details.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace fast_ink {

// static
gfx::Rect FastInkHost::BufferRectFromWindowRect(
    const gfx::Transform& window_to_buffer_transform,
    const gfx::Size& buffer_size,
    const gfx::Rect& window_rect) {
  gfx::Rect buffer_rect = cc::MathUtil::MapEnclosingClippedRect(
      window_to_buffer_transform, window_rect);
  // Buffer rect is not bigger than actual buffer.
  buffer_rect.Intersect(gfx::Rect(buffer_size));
  return buffer_rect;
}

struct FastInkHost::Resource {
  Resource() = default;
  ~Resource() {
    // context_provider might be null in unit tests when ran with --mash
    // TODO(kaznacheev) Have MASH provide a context provider for tests
    // when https://crbug/772562 is fixed
    if (!context_provider)
      return;
    gpu::SharedImageInterface* sii = context_provider->SharedImageInterface();
    DCHECK(!mailbox.IsZero());
    sii->DestroySharedImage(sync_token, mailbox);
  }
  scoped_refptr<viz::ContextProvider> context_provider;
  gpu::Mailbox mailbox;
  gpu::SyncToken sync_token;
  bool damaged = true;
};

class FastInkHost::LayerTreeFrameSinkHolder
    : public cc::LayerTreeFrameSinkClient,
      public aura::WindowObserver {
 public:
  LayerTreeFrameSinkHolder(FastInkHost* host,
                           std::unique_ptr<cc::LayerTreeFrameSink> frame_sink)
      : host_(host), frame_sink_(std::move(frame_sink)) {
    frame_sink_->BindToClient(this);
  }
  ~LayerTreeFrameSinkHolder() override {
    if (frame_sink_)
      frame_sink_->DetachFromClient();
    if (root_window_)
      root_window_->RemoveObserver(this);
  }
  LayerTreeFrameSinkHolder(const LayerTreeFrameSinkHolder&) = delete;
  LayerTreeFrameSinkHolder& operator=(const LayerTreeFrameSinkHolder&) = delete;

  // Delete frame sink after having reclaimed all exported resources.
  // Returns false if the it should be released instead of reset and it will
  // self destruct.
  // TODO(reveman): Find a better way to handle deletion of in-flight resources.
  // https://crbug.com/765763
  bool DeleteWhenLastResourceHasBeenReclaimed() {
    if (last_frame_size_in_pixels_.IsEmpty()) {
      // Delete sink holder immediately if no frame has been submitted.
      DCHECK(exported_resources_.empty());
      return true;
    }

    // Submit an empty frame to ensure that pending release callbacks will be
    // processed in a finite amount of time.
    viz::CompositorFrame frame;
    frame.metadata.begin_frame_ack.frame_id =
        viz::BeginFrameId(viz::BeginFrameArgs::kManualSourceId,
                          viz::BeginFrameArgs::kStartingFrameNumber);
    frame.metadata.begin_frame_ack.has_damage = true;
    frame.metadata.device_scale_factor = last_frame_device_scale_factor_;
    frame.metadata.frame_token = ++next_frame_token_;
    auto pass = viz::CompositorRenderPass::Create();
    pass->SetNew(viz::CompositorRenderPassId{1},
                 gfx::Rect(last_frame_size_in_pixels_),
                 gfx::Rect(last_frame_size_in_pixels_), gfx::Transform());
    frame.render_pass_list.push_back(std::move(pass));
    frame_sink_->SubmitCompositorFrame(std::move(frame),
                                       /*hit_test_data_changed=*/true,
                                       /*show_hit_test_borders=*/false);

    // Delete sink holder immediately if not waiting for exported resources to
    // be reclaimed.
    if (exported_resources_.empty())
      return true;

    // If we have exported resources to reclaim then extend the lifetime of
    // holder by deleting it later.
    // itself when the root window is removed or when all exported resources
    // have been reclaimed.
    root_window_ = host_->host_window()->GetRootWindow();

    // This can be null during shutdown.
    if (!root_window_)
      return true;

    root_window_->AddObserver(this);
    host_ = nullptr;
    return false;
  }

  void SubmitCompositorFrame(viz::CompositorFrame frame,
                             viz::ResourceId resource_id,
                             std::unique_ptr<Resource> resource) {
    exported_resources_[resource_id] = std::move(resource);
    last_frame_size_in_pixels_ = frame.size_in_pixels();
    last_frame_device_scale_factor_ = frame.metadata.device_scale_factor;
    frame.metadata.frame_token = ++next_frame_token_;
    frame_sink_->SubmitCompositorFrame(std::move(frame),
                                       /*hit_test_data_changed=*/true,
                                       /*show_hit_test_borders=*/false);
  }

  void DamageExportedResources() {
    for (auto& entry : exported_resources_)
      entry.second->damaged = true;
  }

  // Overridden from cc::LayerTreeFrameSinkClient:
  void SetBeginFrameSource(viz::BeginFrameSource* source) override {}
  base::Optional<viz::HitTestRegionList> BuildHitTestData() override {
    return {};
  }
  void ReclaimResources(
      const std::vector<viz::ReturnedResource>& resources) override {
    if (delete_pending_)
      return;
    for (auto& entry : resources) {
      auto it = exported_resources_.find(entry.id);
      DCHECK(it != exported_resources_.end());
      std::unique_ptr<Resource> resource = std::move(it->second);
      exported_resources_.erase(it);
      resource->sync_token = entry.sync_token;
      if (host_ && !entry.lost)
        host_->ReclaimResource(std::move(resource));
    }

    if (root_window_ && exported_resources_.empty())
      ScheduleDelete();
  }
  void SetTreeActivationCallback(base::RepeatingClosure callback) override {}
  void DidReceiveCompositorFrameAck() override {
    if (host_)
      host_->DidReceiveCompositorFrameAck();
  }
  void DidPresentCompositorFrame(
      uint32_t frame_token,
      const viz::FrameTimingDetails& details) override {
    if (host_)
      host_->DidPresentCompositorFrame(details.presentation_feedback);
  }
  void DidLoseLayerTreeFrameSink() override {
    exported_resources_.clear();
    if (root_window_)
      ScheduleDelete();
  }
  void OnDraw(const gfx::Transform& transform,
              const gfx::Rect& viewport,
              bool resourceless_software_draw,
              bool skip_draw) override {}
  void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {}
  void SetExternalTilePriorityConstraints(
      const gfx::Rect& viewport_rect,
      const gfx::Transform& transform) override {}

  void OnWindowDestroying(aura::Window* window) override {
    root_window_->RemoveObserver(this);
    root_window_ = nullptr;
    frame_sink_->DetachFromClient();
    frame_sink_.reset();
    ScheduleDelete();
  }

 private:
  void ScheduleDelete() {
    if (delete_pending_)
      return;
    delete_pending_ = true;
    base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
  }

  FastInkHost* host_;
  std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_;
  base::flat_map<viz::ResourceId, std::unique_ptr<Resource>>
      exported_resources_;
  viz::FrameTokenGenerator next_frame_token_;
  gfx::Size last_frame_size_in_pixels_;
  float last_frame_device_scale_factor_ = 1.0f;
  aura::Window* root_window_ = nullptr;
  bool delete_pending_ = false;
};

FastInkHost::FastInkHost(aura::Window* host_window,
                         const PresentationCallback& presentation_callback)
    : host_window_(host_window), presentation_callback_(presentation_callback) {
  // Take the root transform and apply this during buffer update instead of
  // leaving this up to the compositor. The benefit is that HW requirements
  // for being able to take advantage of overlays and direct scanout are
  // reduced significantly. Frames are submitted to the compositor with the
  // inverse transform to cancel out the transformation that would otherwise
  // be done by the compositor.
  window_to_buffer_transform_ = host_window_->GetHost()->GetRootTransform();
  gfx::Rect bounds(host_window_->GetBoundsInScreen().size());
  buffer_size_ =
      gfx::ToEnclosedRect(cc::MathUtil::MapClippedRect(
                              window_to_buffer_transform_,
                              gfx::RectF(bounds.width(), bounds.height())))
          .size();

  // Create a single GPU memory buffer. Content will be written into this
  // buffer without any buffering. The result is that we might be modifying
  // the buffer while it's being displayed. This provides minimal latency
  // but with potential tearing. Note that we have to draw into a temporary
  // surface and copy it into GPU memory buffer to avoid flicker.
  gpu_memory_buffer_ =
      aura::Env::GetInstance()
          ->context_factory()
          ->GetGpuMemoryBufferManager()
          ->CreateGpuMemoryBuffer(buffer_size_,
                                  SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888
                                               : gfx::BufferFormat::BGRA_8888,
                                  gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
                                  gpu::kNullSurfaceHandle);
  LOG_IF(ERROR, !gpu_memory_buffer_) << "Failed to create GPU memory buffer";

  if (ash::switches::ShouldClearFastInkBuffer()) {
    bool map_result = gpu_memory_buffer_->Map();
    LOG_IF(ERROR, !map_result) << "Failed to map gpu buffer";
    uint8_t* memory = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
    if (memory != nullptr) {
      gfx::Size size = gpu_memory_buffer_->GetSize();
      int stride = gpu_memory_buffer_->stride(0);
      // Clear the buffer before usage, since it may be uninitialized.
      // (http://b/168735625)
      for (int i = 0; i < size.height(); ++i)
        memset(memory + i * stride, 0, size.width() * 4);
    }
    gpu_memory_buffer_->Unmap();
  }

  frame_sink_holder_ = std::make_unique<LayerTreeFrameSinkHolder>(
      this, host_window_->CreateLayerTreeFrameSink());
}

FastInkHost::~FastInkHost() {
  if (!frame_sink_holder_->DeleteWhenLastResourceHasBeenReclaimed())
    frame_sink_holder_.release();
}

void FastInkHost::UpdateSurface(const gfx::Rect& content_rect,
                                const gfx::Rect& damage_rect,
                                bool auto_refresh) {
  content_rect_ = content_rect;
  damage_rect_.Union(damage_rect);
  auto_refresh_ = auto_refresh;
  pending_compositor_frame_ = true;

  if (!damage_rect.IsEmpty()) {
    frame_sink_holder_->DamageExportedResources();
    for (auto& resource : returned_resources_)
      resource->damaged = true;
  }

  if (!pending_compositor_frame_ack_)
    SubmitCompositorFrame();
}

void FastInkHost::SubmitCompositorFrame() {
  TRACE_EVENT1("ui", "FastInkHost::SubmitCompositorFrame", "damage",
               damage_rect_.ToString());

  float device_scale_factor = host_window_->layer()->device_scale_factor();

  gfx::Size window_size_in_dip = host_window_->GetBoundsInScreen().size();
  // TODO(crbug.com/1131619): Should this be ceil? Why do we choose floor?
  gfx::Size window_size_in_pixel = gfx::ToFlooredSize(
      gfx::ConvertSizeToPixels(window_size_in_dip, device_scale_factor));
  gfx::Rect output_rect(window_size_in_pixel);

  gfx::Rect quad_rect;
  gfx::Rect damage_rect;
  // Continuously redraw the full output rectangle when in auto-refresh mode.
  // This is necessary in order to allow single buffered updates without having
  // buffer changes outside the contents area cause artifacts.
  if (auto_refresh_) {
    quad_rect = gfx::Rect(buffer_size_);
    damage_rect = gfx::Rect(output_rect);
  } else {
    // Use minimal quad and damage rectangles when auto-refresh mode is off.
    quad_rect = BufferRectFromWindowRect(window_to_buffer_transform_,
                                         buffer_size_, content_rect_);
    damage_rect = gfx::ToEnclosingRect(
        gfx::ConvertRectToPixels(damage_rect_, device_scale_factor));
    damage_rect.Intersect(output_rect);
    pending_compositor_frame_ = false;
  }
  damage_rect_ = gfx::Rect();

  std::unique_ptr<Resource> resource;
  // Reuse returned resource if available.
  if (!returned_resources_.empty()) {
    resource = std::move(returned_resources_.back());
    returned_resources_.pop_back();
  }

  // Create new resource if needed.
  if (!resource)
    resource = std::make_unique<Resource>();

  if (resource->damaged) {
    // Acquire context provider for resource if needed.
    // Note: We make no attempts to recover if the context provider is later
    // lost. It is expected that this class is short-lived and requiring a
    // new instance to be created in lost context situations is acceptable and
    // keeps the code simple.
    if (!resource->context_provider) {
      resource->context_provider = aura::Env::GetInstance()
                                       ->context_factory()
                                       ->SharedMainThreadContextProvider();
      if (!resource->context_provider) {
        LOG(ERROR) << "Failed to acquire a context provider";
        return;
      }
    }

    gpu::SharedImageInterface* sii =
        resource->context_provider->SharedImageInterface();
    if (resource->mailbox.IsZero()) {
      DCHECK(!resource->sync_token.HasData());
      const uint32_t usage =
          gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
      gpu::GpuMemoryBufferManager* gmb_manager =
          aura::Env::GetInstance()
              ->context_factory()
              ->GetGpuMemoryBufferManager();
      resource->mailbox = sii->CreateSharedImage(
          gpu_memory_buffer_.get(), gmb_manager, gfx::ColorSpace(),
          kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage);
    } else {
      sii->UpdateSharedImage(resource->sync_token, resource->mailbox);
    }
    resource->sync_token = sii->GenVerifiedSyncToken();

    resource->damaged = false;
  }

  viz::TransferableResource transferable_resource;
  transferable_resource.id = next_resource_id_++;
  transferable_resource.format = viz::RGBA_8888;
  transferable_resource.filter = GL_LINEAR;
  transferable_resource.size = buffer_size_;
  transferable_resource.mailbox_holder = gpu::MailboxHolder(
      resource->mailbox, resource->sync_token, GL_TEXTURE_2D);
  // Use HW overlay if continuous updates are expected.
  transferable_resource.is_overlay_candidate = auto_refresh_;

  gfx::Transform target_to_buffer_transform(window_to_buffer_transform_);
  target_to_buffer_transform.Scale(1.f / device_scale_factor,
                                   1.f / device_scale_factor);

  gfx::Transform buffer_to_target_transform;
  bool rv = target_to_buffer_transform.GetInverse(&buffer_to_target_transform);
  DCHECK(rv);

  const viz::CompositorRenderPassId kRenderPassId{1};
  auto render_pass = viz::CompositorRenderPass::Create();
  render_pass->SetNew(kRenderPassId, output_rect, damage_rect,
                      buffer_to_target_transform);

  viz::SharedQuadState* quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  quad_state->SetAll(
      buffer_to_target_transform,
      /*quad_layer_rect=*/output_rect,
      /*visible_quad_layer_rect=*/output_rect,
      /*mask_filter_info=*/gfx::MaskFilterInfo(),
      /*clip_rect=*/gfx::Rect(),
      /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f,
      /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);

  viz::CompositorFrame frame;
  // TODO(eseckler): FastInkHost should use BeginFrames and set the ack
  // accordingly.
  frame.metadata.begin_frame_ack =
      viz::BeginFrameAck::CreateManualAckWithDamage();
  frame.metadata.device_scale_factor = device_scale_factor;

  viz::TextureDrawQuad* texture_quad =
      render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
  gfx::RectF uv_crop(quad_rect);
  uv_crop.Scale(1.f / buffer_size_.width(), 1.f / buffer_size_.height());
  texture_quad->SetNew(
      quad_state, quad_rect, quad_rect,
      /*needs_blending=*/true, transferable_resource.id,
      /*premultiplied_alpha=*/true, uv_crop.origin(), uv_crop.bottom_right(),
      /*background_color=*/SK_ColorTRANSPARENT, vertex_opacity,
      /*y_flipped=*/false,
      /*nearest_neighbor=*/false,
      /*secure_output_only=*/false, gfx::ProtectedVideoType::kClear);
  texture_quad->set_resource_size_in_pixels(transferable_resource.size);
  frame.resource_list.push_back(transferable_resource);

  DCHECK(!pending_compositor_frame_ack_);
  pending_compositor_frame_ack_ = true;

  frame.render_pass_list.push_back(std::move(render_pass));
  frame_sink_holder_->SubmitCompositorFrame(
      std::move(frame), transferable_resource.id, std::move(resource));
}

void FastInkHost::SubmitPendingCompositorFrame() {
  if (pending_compositor_frame_ && !pending_compositor_frame_ack_)
    SubmitCompositorFrame();
}

void FastInkHost::DidReceiveCompositorFrameAck() {
  pending_compositor_frame_ack_ = false;
  if (pending_compositor_frame_) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&FastInkHost::SubmitPendingCompositorFrame,
                                  weak_ptr_factory_.GetWeakPtr()));
  }
}

void FastInkHost::DidPresentCompositorFrame(
    const gfx::PresentationFeedback& feedback) {
  if (!presentation_callback_.is_null())
    presentation_callback_.Run(feedback);
}

void FastInkHost::ReclaimResource(std::unique_ptr<Resource> resource) {
  returned_resources_.push_back(std::move(resource));
}

}  // namespace fast_ink
