// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/client/raster_implementation_gles.h"

#include <algorithm>
#include <cstddef>
#include <limits>
#include <set>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "cc/paint/decode_stashing_image_provider.h"
#include "cc/paint/display_item_list.h"  // nogncheck
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/transfer_cache_entry.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/gl_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace gpu {
namespace raster {

namespace {

// This is kill-switch for fixing error handling of ReadbackImagePixels
// function.
// TODO(crbug.com/40058879): Disable this work-around, once call-sites are
// handling failures correctly.
BASE_FEATURE(kDisableErrorHandlingForReadbackGLES,
             "kDisableErrorHandlingForReadbackGLES",
             base::FEATURE_ENABLED_BY_DEFAULT);

GLenum SkColorTypeToGLDataFormat(SkColorType color_type, bool supports_rg) {
  switch (color_type) {
    case kRGBA_8888_SkColorType:
      return GL_RGBA;
    case kBGRA_8888_SkColorType:
      return GL_BGRA_EXT;
    case kR8G8_unorm_SkColorType:
    case kR16G16_unorm_SkColorType:
      return GL_RG_EXT;
    case kGray_8_SkColorType:
      return supports_rg ? GL_RED : GL_LUMINANCE;
    case kAlpha_8_SkColorType:
    case kA16_unorm_SkColorType:
      return supports_rg ? GL_RED : GL_ALPHA;
    // kA16_float_SkColorType is only used by LUMINANCE_F16 format and hence
    // should only support GL_LUMINANCE.
    case kA16_float_SkColorType:
      return GL_LUMINANCE;
    case kRGBA_F16_SkColorType:
      return GL_RGBA16F;
    default:
      NOTREACHED() << "Unknown SkColorType " << color_type;
  }
}

GLenum SkColorTypeToGLDataType(SkColorType color_type) {
  switch (color_type) {
    case kRGBA_8888_SkColorType:
    case kBGRA_8888_SkColorType:
    case kR8G8_unorm_SkColorType:
    case kGray_8_SkColorType:
    case kAlpha_8_SkColorType:
      return GL_UNSIGNED_BYTE;
    case kA16_unorm_SkColorType:
    case kR16G16_unorm_SkColorType:
      return GL_UNSIGNED_SHORT;
    case kA16_float_SkColorType:
    case kRGBA_F16_SkColorType:
      return GL_HALF_FLOAT_OES;
    default:
      NOTREACHED() << "Unknown SkColorType " << color_type;
  }
}

}  // namespace

RasterImplementationGLES::RasterImplementationGLES(
    gles2::GLES2Interface* gl,
    ContextSupport* context_support,
    const gpu::Capabilities& caps)
    : gl_(gl), context_support_(context_support), capabilities_(caps) {}

RasterImplementationGLES::~RasterImplementationGLES() = default;

void RasterImplementationGLES::Finish() {
  gl_->Finish();
}

void RasterImplementationGLES::Flush() {
  gl_->Flush();
}

void RasterImplementationGLES::ShallowFlushCHROMIUM() {
  gl_->ShallowFlushCHROMIUM();
}

void RasterImplementationGLES::OrderingBarrierCHROMIUM() {
  gl_->OrderingBarrierCHROMIUM();
}

GLenum RasterImplementationGLES::GetError() {
  return gl_->GetError();
}

GLenum RasterImplementationGLES::GetGraphicsResetStatusKHR() {
  return gl_->GetGraphicsResetStatusKHR();
}

void RasterImplementationGLES::LoseContextCHROMIUM(GLenum current,
                                                   GLenum other) {
  gl_->LoseContextCHROMIUM(current, other);
}

void RasterImplementationGLES::GenQueriesEXT(GLsizei n, GLuint* queries) {
  gl_->GenQueriesEXT(n, queries);
}

void RasterImplementationGLES::DeleteQueriesEXT(GLsizei n,
                                                const GLuint* queries) {
  gl_->DeleteQueriesEXT(n, queries);
}

void RasterImplementationGLES::BeginQueryEXT(GLenum target, GLuint id) {
  gl_->BeginQueryEXT(target, id);
}

void RasterImplementationGLES::EndQueryEXT(GLenum target) {
  gl_->EndQueryEXT(target);
}

void RasterImplementationGLES::GetQueryObjectuivEXT(GLuint id,
                                                    GLenum pname,
                                                    GLuint* params) {
  gl_->GetQueryObjectuivEXT(id, pname, params);
}

void RasterImplementationGLES::CopySharedImage(
    const gpu::Mailbox& source_mailbox,
    const gpu::Mailbox& dest_mailbox,
    GLint xoffset,
    GLint yoffset,
    GLint x,
    GLint y,
    GLsizei width,
    GLsizei height) {
  if (width < 0) {
    LOG(ERROR) << "GL_INVALID_VALUE, glCopySharedImage, width < 0";
    return;
  }
  if (height < 0) {
    LOG(ERROR) << "GL_INVALID_VALUE, glCopySharedImage, height < 0";
    return;
  }
  GLbyte mailboxes[sizeof(source_mailbox.name) * 2];
  UNSAFE_TODO(
      memcpy(mailboxes, source_mailbox.name, sizeof(source_mailbox.name)));
  UNSAFE_TODO(memcpy(mailboxes + sizeof(source_mailbox.name), dest_mailbox.name,
                     sizeof(dest_mailbox.name)));
  gl_->CopySharedImageINTERNAL(xoffset, yoffset, x, y, width, height,
                               mailboxes);
}

void RasterImplementationGLES::CopySharedImage(
    const gpu::Mailbox& source_mailbox,
    const gpu::Mailbox& dest_mailbox,
    const gfx::Rect& source_rect,
    const gfx::Rect& dest_rect) {
  NOTREACHED();
}

void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
                                           int dst_x_offset,
                                           int dst_y_offset,
                                           GLenum texture_target,
                                           const SkPixmap& src_sk_pixmap) {
  const auto& src_info = src_sk_pixmap.info();
  const auto& src_row_bytes = src_sk_pixmap.rowBytes();
  DCHECK_GE(src_row_bytes, src_info.minRowBytes());
  GLuint texture_id =
      gl_->CreateAndTexStorage2DSharedImageCHROMIUM(dest_mailbox.name);
  gl_->BeginSharedImageAccessDirectCHROMIUM(
      texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);

  GLint old_align = 0;
  gl_->GetIntegerv(GL_UNPACK_ALIGNMENT, &old_align);
  gl_->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
  gl_->PixelStorei(GL_UNPACK_ROW_LENGTH,
                   src_row_bytes / src_info.bytesPerPixel());
  gl_->BindTexture(texture_target, texture_id);
  gl_->TexSubImage2D(
      texture_target, 0, dst_x_offset, dst_y_offset, src_info.width(),
      src_info.height(),
      SkColorTypeToGLDataFormat(src_info.colorType(), capabilities_.texture_rg),
      SkColorTypeToGLDataType(src_info.colorType()), src_sk_pixmap.addr());
  gl_->BindTexture(texture_target, 0);
  gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  gl_->PixelStorei(GL_UNPACK_ALIGNMENT, old_align);

  gl_->EndSharedImageAccessDirectCHROMIUM(texture_id);
  gl_->DeleteTextures(1u, &texture_id);
}

void RasterImplementationGLES::WritePixelsYUV(
    const gpu::Mailbox& dest_mailbox,
    const SkYUVAPixmaps& src_yuv_pixmap) {
  const auto& src_yuv_info = src_yuv_pixmap.yuvaInfo();
  const auto& src_yuv_pixmap_info = src_yuv_pixmap.pixmapsInfo();
  const std::array<SkPixmap, SkYUVAInfo::kMaxPlanes>& src_sk_pixmaps =
      src_yuv_pixmap.planes();

  gl_->WritePixelsYUVINTERNAL(
      dest_mailbox.name, src_sk_pixmaps[0].computeByteSize(),
      src_sk_pixmaps[1].computeByteSize(), src_sk_pixmaps[2].computeByteSize(),
      src_sk_pixmaps[3].computeByteSize(), src_yuv_info.width(),
      src_yuv_info.height(), static_cast<int>(src_yuv_info.planeConfig()),
      static_cast<int>(src_yuv_info.subsampling()),
      static_cast<int>(src_yuv_pixmap_info.dataType()),
      src_sk_pixmaps[0].rowBytes(), src_sk_pixmaps[1].rowBytes(),
      src_sk_pixmaps[2].rowBytes(), src_sk_pixmaps[3].rowBytes(),
      src_sk_pixmaps[0].addr(), src_sk_pixmaps[1].addr(),
      src_sk_pixmaps[2].addr(), src_sk_pixmaps[3].addr());
}

void RasterImplementationGLES::BeginRasterCHROMIUM(
    SkColor4f sk_color_4f,
    GLboolean needs_clear,
    GLuint msaa_sample_count,
    MsaaMode msaa_mode,
    GLboolean can_use_lcd_text,
    GLboolean visible,
    const gfx::ColorSpace& color_space,
    float hdr_headroom,
    const GLbyte* mailbox) {
  NOTREACHED();
}

void RasterImplementationGLES::RasterCHROMIUM(
    const cc::DisplayItemList* list,
    cc::ImageProvider* provider,
    const gfx::Size& content_size,
    const gfx::Rect& full_raster_rect,
    const gfx::Rect& playback_rect,
    const gfx::Vector2dF& post_translate,
    const gfx::Vector2dF& post_scale,
    bool requires_clear,
    const ScrollOffsetMap* raster_inducing_scroll_offsets,
    size_t* max_op_size_hint) {
  NOTREACHED();
}

void RasterImplementationGLES::SetActiveURLCHROMIUM(const char* url) {
  gl_->SetActiveURLCHROMIUM(url);
}

void RasterImplementationGLES::EndRasterCHROMIUM() {
  NOTREACHED();
}

void RasterImplementationGLES::ReadbackARGBPixelsAsync(
    const gpu::Mailbox& source_mailbox,
    GLenum source_target,
    GrSurfaceOrigin src_origin,
    const gfx::Size& source_size,
    const gfx::Point& source_starting_point,
    const SkImageInfo& dst_info,
    GLuint dst_row_bytes,
    base::span<uint8_t> out,
    base::OnceCallback<void(bool)> readback_done) {
  DCHECK(!readback_done.is_null());
  DCHECK(dst_info.colorType() == kRGBA_8888_SkColorType ||
         dst_info.colorType() == kBGRA_8888_SkColorType);
  GLenum format =
      dst_info.colorType() == kRGBA_8888_SkColorType ? GL_RGBA : GL_BGRA_EXT;
  gfx::Size dst_gfx_size(dst_info.width(), dst_info.height());
  GLuint texture_id =
      gl_->CreateAndTexStorage2DSharedImageCHROMIUM(source_mailbox.name);
  gl_->BeginSharedImageAccessDirectCHROMIUM(
      texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);

  // Convert bottom-left GL coordinates to top-left coordinates expected
  // by RI clients.
  bool flip_y;
  gfx::Point starting_point(source_starting_point);
  switch (src_origin) {
    case kTopLeft_GrSurfaceOrigin:
      flip_y = false;
      break;
    case kBottomLeft_GrSurfaceOrigin:
      // Since RI clients always expect top-left origin, two things need to be
      // done when texture's origin is bottom-left.

      // 1. Rows in the output buffer need to be switched vertically.
      flip_y = true;

      // 2. Starting of a target rectangle needs to be adjusted from top-left
      //    to bottom-left. That's how glReadPixels expects it.
      // It's okay if we accidentally go negative here, glReadPixels checks
      // its input.
      starting_point.set_y(source_size.height() - starting_point.y() -
                           dst_gfx_size.height());
      break;
  }

  GetGLHelper()->ReadbackTextureAsync(
      texture_id, source_target, starting_point, dst_gfx_size, out,
      dst_row_bytes, flip_y, format,
      base::BindOnce(&RasterImplementationGLES::OnReadARGBPixelsAsync,
                     weak_ptr_factory_.GetWeakPtr(), texture_id,
                     std::move(readback_done)));
}

void RasterImplementationGLES::OnReadARGBPixelsAsync(
    GLuint texture_id,
    base::OnceCallback<void(bool)> readback_done,
    bool success) {
  DCHECK(texture_id);
  gl_->EndSharedImageAccessDirectCHROMIUM(texture_id);
  gl_->DeleteTextures(1u, &texture_id);

  std::move(readback_done).Run(success);
}

void RasterImplementationGLES::ReadbackYUVPixelsAsync(
    const gpu::Mailbox& source_mailbox,
    GLenum source_target,
    const gfx::Size& source_size,
    const gfx::Rect& output_rect,
    bool vertically_flip_texture,
    int y_plane_row_stride_bytes,
    base::span<uint8_t> y_plane_data,
    int u_plane_row_stride_bytes,
    base::span<uint8_t> u_plane_data,
    int v_plane_row_stride_bytes,
    base::span<uint8_t> v_plane_data,
    const gfx::Point& paste_location,
    base::OnceCallback<void()> release_mailbox,
    base::OnceCallback<void(bool)> readback_done) {
  GLuint shared_texture_id =
      gl_->CreateAndTexStorage2DSharedImageCHROMIUM(source_mailbox.name);
  gl_->BeginSharedImageAccessDirectCHROMIUM(
      shared_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
  base::OnceCallback<void()> on_release_mailbox =
      base::BindOnce(&RasterImplementationGLES::OnReleaseMailbox,
                     weak_ptr_factory_.GetWeakPtr(), shared_texture_id,
                     std::move(release_mailbox));

  // The YUV readback path only works for 2D textures.
  GLuint texture_for_readback = shared_texture_id;
  GLuint copy_texture_id = 0;
  if (source_target != GL_TEXTURE_2D) {
    int width = source_size.width();
    int height = source_size.height();

    gl_->GenTextures(1, &copy_texture_id);
    gl_->BindTexture(GL_TEXTURE_2D, copy_texture_id);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                    GL_UNSIGNED_BYTE, nullptr);
    gl_->CopyTextureCHROMIUM(shared_texture_id, 0, GL_TEXTURE_2D,
                             copy_texture_id, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
                             0, 0);
    texture_for_readback = copy_texture_id;

    // |copy_texture_id| now contains the texture we want to copy, release the
    // pinned mailbox.
    std::move(on_release_mailbox).Run();
  }

  DCHECK(GetGLHelper());
  gpu::ReadbackYUVInterface* const yuv_reader =
      GetGLHelper()->GetReadbackPipelineYUV(vertically_flip_texture);
  yuv_reader->ReadbackYUV(
      texture_for_readback, source_size, gfx::Rect(source_size),
      y_plane_row_stride_bytes, y_plane_data, u_plane_row_stride_bytes,
      u_plane_data, v_plane_row_stride_bytes, v_plane_data, paste_location,
      base::BindOnce(&RasterImplementationGLES::OnReadYUVPixelsAsync,
                     weak_ptr_factory_.GetWeakPtr(), copy_texture_id,
                     std::move(on_release_mailbox), std::move(readback_done)));
}

void RasterImplementationGLES::OnReadYUVPixelsAsync(
    GLuint copy_texture_id,
    base::OnceCallback<void()> on_release_mailbox,
    base::OnceCallback<void(bool)> readback_done,
    bool success) {
  if (copy_texture_id) {
    DCHECK(on_release_mailbox.is_null());
    gl_->DeleteTextures(1, &copy_texture_id);
  } else {
    DCHECK(!on_release_mailbox.is_null());
    std::move(on_release_mailbox).Run();
  }

  std::move(readback_done).Run(success);
}

void RasterImplementationGLES::OnReleaseMailbox(
    GLuint shared_texture_id,
    base::OnceCallback<void()> release_mailbox) {
  DCHECK(shared_texture_id);
  DCHECK(!release_mailbox.is_null());

  gl_->EndSharedImageAccessDirectCHROMIUM(shared_texture_id);
  gl_->DeleteTextures(1u, &shared_texture_id);
  std::move(release_mailbox).Run();
}

bool RasterImplementationGLES::ReadbackImagePixels(
    const gpu::Mailbox& source_mailbox,
    const SkImageInfo& dst_info,
    GLuint dst_row_bytes,
    int src_x,
    int src_y,
    int plane_index,
    void* dst_pixels) {
  DCHECK_GE(dst_row_bytes, dst_info.minRowBytes());

  sk_sp<SkData> dst_color_space_data;
  if (dst_info.colorSpace()) {
    dst_color_space_data = dst_info.colorSpace()->serialize();
  }

  GLuint dst_size = dst_info.computeByteSize(dst_row_bytes);
  return gl_->ReadbackARGBImagePixelsINTERNAL(
             source_mailbox.name,
             dst_color_space_data ? dst_color_space_data->data() : nullptr,
             dst_color_space_data ? dst_color_space_data->size() : 0, dst_size,
             dst_info.width(), dst_info.height(), dst_info.colorType(),
             dst_info.alphaType(), dst_row_bytes, src_x, src_y, plane_index,
             dst_pixels) ||
         base::FeatureList::IsEnabled(kDisableErrorHandlingForReadbackGLES);
}

void RasterImplementationGLES::TraceBeginCHROMIUM(const char* category_name,
                                                  const char* trace_name) {
  gl_->TraceBeginCHROMIUM(category_name, trace_name);
}

void RasterImplementationGLES::TraceEndCHROMIUM() {
  gl_->TraceEndCHROMIUM();
}

// InterfaceBase implementation.
void RasterImplementationGLES::GenSyncTokenCHROMIUM(GLbyte* sync_token) {
  gl_->GenSyncTokenCHROMIUM(sync_token);
}
void RasterImplementationGLES::GenUnverifiedSyncTokenCHROMIUM(
    GLbyte* sync_token) {
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token);
}
void RasterImplementationGLES::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
                                                        GLsizei count) {
  gl_->VerifySyncTokensCHROMIUM(sync_tokens, count);
}
void RasterImplementationGLES::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
  gl_->WaitSyncTokenCHROMIUM(sync_token);
}

GLHelper* RasterImplementationGLES::GetGLHelper() {
  if (!gl_helper_) {
    DCHECK(gl_);
    DCHECK(context_support_);
    gl_helper_ = std::make_unique<GLHelper>(gl_, context_support_);
  }

  return gl_helper_.get();
}

}  // namespace raster
}  // namespace gpu
