// 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 "cc/raster/zero_copy_raster_buffer_provider.h"

#include <stdint.h>

#include <algorithm>

#include "base/macros.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/resources/layer_tree_resource_provider.h"
#include "cc/resources/resource_pool.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/platform_color.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace cc {
namespace {

constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;

// Subclass for InUsePoolResource that holds ownership of a zero-copy backing
// and does cleanup of the backing when destroyed.
class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
 public:
  ~ZeroCopyGpuBacking() override {
    gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
    if (returned_sync_token.HasData())
      gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
    if (texture_id)
      gl->DeleteTextures(1, &texture_id);
    if (image_id)
      gl->DestroyImageCHROMIUM(image_id);
  }

  base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
      uint64_t tracing_process_id) override {
    if (!gpu_memory_buffer)
      return {};
    return gpu_memory_buffer->GetGUIDForTracing(tracing_process_id);
  }

  base::UnguessableToken SharedMemoryGuid() override {
    if (!gpu_memory_buffer)
      return {};
    return gpu_memory_buffer->GetHandle().handle.GetGUID();
  }

  // The ContextProvider used to clean up the texture and image ids.
  viz::ContextProvider* compositor_context_provider = nullptr;
  // The backing for zero-copy gpu resources. The |texture_id| is bound to
  // this.
  std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
  // The texture id bound to the GpuMemoryBuffer.
  uint32_t texture_id = 0;
  // The image id that associates the |gpu_memory_buffer| and the
  // |texture_id|.
  uint32_t image_id = 0;
};

// RasterBuffer for the zero copy upload, which is given to the raster worker
// threads for raster/upload.
class ZeroCopyRasterBufferImpl : public RasterBuffer {
 public:
  ZeroCopyRasterBufferImpl(
      viz::ContextProvider* context_provider,
      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
      const ResourcePool::InUsePoolResource& in_use_resource,
      ZeroCopyGpuBacking* backing)
      : backing_(backing),
        gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
        resource_size_(in_use_resource.size()),
        resource_format_(in_use_resource.format()),
        resource_color_space_(in_use_resource.color_space()),
        gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}

  ~ZeroCopyRasterBufferImpl() override {
    // This is destroyed on the compositor thread when raster is complete, but
    // before the backing is prepared for export to the display compositor. So
    // we can set up the texture and SyncToken here.
    // TODO(danakj): This could be done with the worker context in Playback. Do
    // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
    gpu::gles2::GLES2Interface* gl =
        backing_->compositor_context_provider->ContextGL();
    const gpu::Capabilities& caps =
        backing_->compositor_context_provider->ContextCapabilities();

    if (backing_->returned_sync_token.HasData()) {
      gl->WaitSyncTokenCHROMIUM(backing_->returned_sync_token.GetConstData());
      backing_->returned_sync_token = gpu::SyncToken();
    }

    if (!backing_->texture_id) {
      // Make a texture and a mailbox for export of the GpuMemoryBuffer to the
      // display compositor.
      gl->GenTextures(1, &backing_->texture_id);
      backing_->texture_target = gpu::GetBufferTextureTarget(
          kBufferUsage, viz::BufferFormat(resource_format_), caps);
      backing_->mailbox = gpu::Mailbox::Generate();
      gl->ProduceTextureDirectCHROMIUM(backing_->texture_id,
                                       backing_->mailbox.name);
      backing_->overlay_candidate = true;
      // This RasterBufferProvider will modify the resource outside of the
      // GL command stream. So resources should not become available for reuse
      // until they are not in use by the gpu anymore, which a fence is used to
      // determine.
      backing_->wait_on_fence_required = true;

      gl->BindTexture(backing_->texture_target, backing_->texture_id);
      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MIN_FILTER,
                        GL_LINEAR);
      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MAG_FILTER,
                        GL_LINEAR);
      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_S,
                        GL_CLAMP_TO_EDGE);
      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_T,
                        GL_CLAMP_TO_EDGE);
    } else {
      gl->BindTexture(backing_->texture_target, backing_->texture_id);
    }

    if (!backing_->image_id) {
      // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
      // we don't have anything to give to the display compositor, but also no
      // way to report an error, so we just make a texture but don't bind
      // anything to it..
      if (gpu_memory_buffer_) {
        backing_->image_id = gl->CreateImageCHROMIUM(
            gpu_memory_buffer_->AsClientBuffer(), resource_size_.width(),
            resource_size_.height(), viz::GLInternalFormat(resource_format_));
        gl->BindTexImage2DCHROMIUM(backing_->texture_target,
                                   backing_->image_id);
      }
    } else {
      gl->ReleaseTexImage2DCHROMIUM(backing_->texture_target,
                                    backing_->image_id);
      gl->BindTexImage2DCHROMIUM(backing_->texture_target, backing_->image_id);
    }
    gl->BindTexture(backing_->texture_target, 0);

    backing_->mailbox_sync_token =
        LayerTreeResourceProvider::GenerateSyncTokenHelper(gl);
    backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
  }

  // Overridden from RasterBuffer:
  void Playback(
      const RasterSource* raster_source,
      const gfx::Rect& raster_full_rect,
      const gfx::Rect& raster_dirty_rect,
      uint64_t new_content_id,
      const gfx::AxisTransform2d& transform,
      const RasterSource::PlaybackSettings& playback_settings) override {
    TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");

    if (!gpu_memory_buffer_) {
      gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
          resource_size_, viz::BufferFormat(resource_format_), kBufferUsage,
          gpu::kNullSurfaceHandle);
      // GpuMemoryBuffer allocation can fail (https://crbug.com/554541).
      if (!gpu_memory_buffer_)
        return;
    }

    DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(
                      gpu_memory_buffer_->GetFormat()));
    bool rv = gpu_memory_buffer_->Map();
    DCHECK(rv);
    DCHECK(gpu_memory_buffer_->memory(0));
    // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
    DCHECK_GE(gpu_memory_buffer_->stride(0), 0);

    // TODO(danakj): Implement partial raster with raster_dirty_rect.
    RasterBufferProvider::PlaybackToMemory(
        gpu_memory_buffer_->memory(0), resource_format_, resource_size_,
        gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
        raster_full_rect, transform, resource_color_space_, playback_settings);
    gpu_memory_buffer_->Unmap();
  }

 private:
  // This field may only be used on the compositor thread.
  ZeroCopyGpuBacking* backing_;

  // These fields are for use on the worker thread.
  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
  gfx::Size resource_size_;
  viz::ResourceFormat resource_format_;
  gfx::ColorSpace resource_color_space_;
  std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;

  DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferImpl);
};

}  // namespace

ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
    LayerTreeResourceProvider* resource_provider,
    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
    viz::ContextProvider* compositor_context_provider,
    viz::ResourceFormat preferred_tile_format)
    : resource_provider_(resource_provider),
      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
      compositor_context_provider_(compositor_context_provider),
      preferred_tile_format_(preferred_tile_format) {}

ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;

std::unique_ptr<RasterBuffer>
ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
    const ResourcePool::InUsePoolResource& resource,
    uint64_t resource_content_id,
    uint64_t previous_content_id) {
  if (!resource.gpu_backing()) {
    auto backing = std::make_unique<ZeroCopyGpuBacking>();
    backing->compositor_context_provider = compositor_context_provider_;
    resource.set_gpu_backing(std::move(backing));
  }
  ZeroCopyGpuBacking* backing =
      static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());

  return std::make_unique<ZeroCopyRasterBufferImpl>(
      compositor_context_provider_, gpu_memory_buffer_manager_, resource,
      backing);
}

void ZeroCopyRasterBufferProvider::Flush() {}

viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat(
    bool must_support_alpha) const {
  if (resource_provider_->IsTextureFormatSupported(preferred_tile_format_)) {
    if (!must_support_alpha)
      return preferred_tile_format_;
    if (DoesResourceFormatSupportAlpha(preferred_tile_format_))
      return preferred_tile_format_;
  }
  return resource_provider_->best_texture_format();
}

bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired(
    bool must_support_alpha) const {
  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
}

bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
    const {
  return false;
}

bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
    const ResourcePool::InUsePoolResource& resource) const {
  // Zero-copy resources are immediately ready to draw.
  return true;
}

uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
    const std::vector<const ResourcePool::InUsePoolResource*>& resources,
    const base::Closure& callback,
    uint64_t pending_callback_id) const {
  // Zero-copy resources are immediately ready to draw.
  return 0;
}

void ZeroCopyRasterBufferProvider::Shutdown() {}

}  // namespace cc
