// Copyright 2018 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 "ui/gl/gl_image_io_surface_egl.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/yuv_to_rgb_converter.h"

// Enums for the EGL_ANGLE_iosurface_client_buffer extension
#define EGL_IOSURFACE_ANGLE 0x3454
#define EGL_IOSURFACE_PLANE_ANGLE 0x345A
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
#define EGL_TEXTURE_TYPE_ANGLE 0x345C
#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D

namespace gl {

namespace {

struct InternalFormatType {
  InternalFormatType(GLenum format, GLenum type) : format(format), type(type) {}

  GLenum format;
  GLenum type;
};

// Convert a gfx::BufferFormat to a (internal format, type) combination from the
// EGL_ANGLE_iosurface_client_buffer extension spec.
InternalFormatType BufferFormatToInternalFormatType(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::R_8:
      return {GL_RED, GL_UNSIGNED_BYTE};
    case gfx::BufferFormat::R_16:
      return {GL_RED_INTEGER, GL_UNSIGNED_SHORT};
    case gfx::BufferFormat::RG_88:
      return {GL_RG, GL_UNSIGNED_BYTE};
    case gfx::BufferFormat::BGRA_8888:
    case gfx::BufferFormat::BGRX_8888:  // See https://crbug.com/595948.
    case gfx::BufferFormat::RGBA_8888:
      return {GL_BGRA_EXT, GL_UNSIGNED_BYTE};
    case gfx::BufferFormat::RGBA_F16:
      return {GL_RGBA, GL_HALF_FLOAT};
    case gfx::BufferFormat::UYVY_422:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::BGRX_1010102:
      NOTIMPLEMENTED();
      return {GL_NONE, GL_NONE};
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBX_1010102:
    case gfx::BufferFormat::YVU_420:
      NOTREACHED();
      return {GL_NONE, GL_NONE};
  }

  NOTREACHED();
  return {GL_NONE, GL_NONE};
}

}  // anonymous namespace

GLImageIOSurfaceEGL::GLImageIOSurfaceEGL(const gfx::Size& size,
                                         unsigned internalformat)
    : GLImageIOSurface(size, internalformat),
      display_(GLSurfaceEGL::GetHardwareDisplay()),
      pbuffer_(EGL_NO_SURFACE),
      dummy_config_(nullptr),
      texture_bound_(false) {
  DCHECK(display_ != EGL_NO_DISPLAY);

  // When creating a pbuffer we need to supply an EGLConfig. On ANGLE and
  // Swiftshader on Mac, there's only ever one config. Query it from EGL.
  EGLint numConfigs = 0;
  EGLBoolean result =
      eglChooseConfig(display_, nullptr, &dummy_config_, 1, &numConfigs);
  DCHECK(result == EGL_TRUE);
  DCHECK(numConfigs = 1);
  DCHECK(dummy_config_ != nullptr);
}

GLImageIOSurfaceEGL::~GLImageIOSurfaceEGL() {
  if (pbuffer_ != EGL_NO_SURFACE) {
    EGLBoolean result = eglDestroySurface(display_, pbuffer_);
    DCHECK(result == EGL_TRUE);
  }
}

void GLImageIOSurfaceEGL::ReleaseTexImage(unsigned target) {
  DCHECK(target == GL_TEXTURE_RECTANGLE_ARB);
  DCHECK(pbuffer_ != EGL_NO_SURFACE);
  DCHECK(texture_bound_);

  EGLBoolean result = eglReleaseTexImage(display_, pbuffer_, EGL_BACK_BUFFER);
  DCHECK(result == EGL_TRUE);
  texture_bound_ = false;
}

bool GLImageIOSurfaceEGL::BindTexImageImpl(unsigned internalformat) {
  // TODO(cwallez@chromium.org): internalformat is used by Blink's
  // DrawingBuffer::SetupRGBEmulationForBlitFramebuffer to bind an RGBA
  // IOSurface as RGB. We should support this.
  if (internalformat != 0) {
    LOG(ERROR) << "GLImageIOSurfaceEGL doesn't support binding with a custom "
                  "internal format yet.";
    return false;
  }

  // Create the pbuffer representing this IOSurface lazily because we don't know
  // in the constructor if we're going to be used to bind plane 0 to a texture,
  // or to transform YUV to RGB.
  if (pbuffer_ == EGL_NO_SURFACE) {
    InternalFormatType formatType = BufferFormatToInternalFormatType(format_);

    // clang-format off
    const EGLint attribs[] = {
      EGL_WIDTH,                         size_.width(),
      EGL_HEIGHT,                        size_.height(),
      EGL_IOSURFACE_PLANE_ANGLE,         0,
      EGL_TEXTURE_TARGET,                EGL_TEXTURE_RECTANGLE_ANGLE,
      EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, formatType.format,
      EGL_TEXTURE_FORMAT,                EGL_TEXTURE_RGBA,
      EGL_TEXTURE_TYPE_ANGLE,            formatType.type,
      EGL_NONE,                          EGL_NONE,
    };
    // clang-format on

    pbuffer_ = eglCreatePbufferFromClientBuffer(display_, EGL_IOSURFACE_ANGLE,
        io_surface_.get(), dummy_config_, attribs);
    if (pbuffer_ == EGL_NO_SURFACE) {
      LOG(ERROR) << "eglCreatePbufferFromClientBuffer failed, EGL error is "
                 << eglGetError();
      return false;
    }
  }

  DCHECK(!texture_bound_);
  EGLBoolean result = eglBindTexImage(display_, pbuffer_, EGL_BACK_BUFFER);

  if (result != EGL_TRUE) {
    LOG(ERROR) << "eglBindTexImage failed, EGL error is "
               << eglGetError();
    return false;
  }

  texture_bound_ = true;
  return true;
}

bool GLImageIOSurfaceEGL::CopyTexImage(unsigned target) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (format_ != gfx::BufferFormat::YUV_420_BIPLANAR)
    return false;

  GLContext* gl_context = GLContext::GetCurrent();
  DCHECK(gl_context);

  YUVToRGBConverter* yuv_to_rgb_converter =
      gl_context->GetYUVToRGBConverter(color_space_for_yuv_to_rgb_);
  DCHECK(yuv_to_rgb_converter);

  // Note that state restoration is done explicitly instead of scoped binders to
  // avoid https://crbug.com/601729.
  GLint rgb_texture = 0;
  GLenum target_getter = 0;
  switch (target) {
    case GL_TEXTURE_2D:
      target_getter = GL_TEXTURE_BINDING_2D;
      break;
    case GL_TEXTURE_CUBE_MAP:
      target_getter = GL_TEXTURE_BINDING_CUBE_MAP;
      break;
    case GL_TEXTURE_EXTERNAL_OES:
      target_getter = GL_TEXTURE_BINDING_EXTERNAL_OES;
      break;
    case GL_TEXTURE_RECTANGLE_ARB:
      target_getter = GL_TEXTURE_BINDING_RECTANGLE_ARB;
      break;
    default:
      NOTIMPLEMENTED() << " Target not supported.";
      return false;
  }

  EGLSurface y_surface = EGL_NO_SURFACE;
  EGLSurface uv_surface = EGL_NO_SURFACE;

  glGetIntegerv(target_getter, &rgb_texture);
  base::ScopedClosureRunner destroy_resources_runner(
      base::BindOnce(base::RetainBlock(^{
        if (y_surface != EGL_NO_SURFACE) {
          EGLBoolean result =
              eglReleaseTexImage(display_, y_surface, EGL_BACK_BUFFER);
          DCHECK(result == EGL_TRUE);
          result = eglDestroySurface(display_, y_surface);
          DCHECK(result == EGL_TRUE);
        }
        if (uv_surface != EGL_NO_SURFACE) {
          EGLBoolean result =
              eglReleaseTexImage(display_, uv_surface, EGL_BACK_BUFFER);
          DCHECK(result == EGL_TRUE);
          result = eglDestroySurface(display_, uv_surface);
          DCHECK(result == EGL_TRUE);
        }
        glBindTexture(target, rgb_texture);
      })));

  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_to_rgb_converter->y_texture());
  if (glGetError() != GL_NO_ERROR) {
    LOG(ERROR) << "Can't bind Y texture";
    return false;
  }

  // clang-format off
  const EGLint yAttribs[] = {
    EGL_WIDTH,                         size_.width(),
    EGL_HEIGHT,                        size_.height(),
    EGL_IOSURFACE_PLANE_ANGLE,         0,
    EGL_TEXTURE_TARGET,                EGL_TEXTURE_RECTANGLE_ANGLE,
    EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RED,
    EGL_TEXTURE_FORMAT,                EGL_TEXTURE_RGBA,
    EGL_TEXTURE_TYPE_ANGLE,            GL_UNSIGNED_BYTE,
    EGL_NONE,                          EGL_NONE,
  };
  // clang-format on

  y_surface = eglCreatePbufferFromClientBuffer(display_, EGL_IOSURFACE_ANGLE,
                                               io_surface_.get(), dummy_config_,
                                               yAttribs);
  if (y_surface == EGL_NO_SURFACE) {
    LOG(ERROR) << "eglCreatePbufferFromClientBuffer failed, EGL error is "
               << eglGetError();
    return false;
  }

  EGLBoolean result = eglBindTexImage(display_, y_surface, EGL_BACK_BUFFER);
  if (result != EGL_TRUE) {
    LOG(ERROR) << "eglBindTexImage failed, EGL error is " << eglGetError();
    return false;
  }

  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_to_rgb_converter->uv_texture());
  if (glGetError() != GL_NO_ERROR) {
    LOG(ERROR) << "Can't bind UV texture";
    return false;
  }

  // clang-format off
  const EGLint uvAttribs[] = {
    EGL_WIDTH,                         size_.width() / 2,
    EGL_HEIGHT,                        size_.height() / 2,
    EGL_IOSURFACE_PLANE_ANGLE,         1,
    EGL_TEXTURE_TARGET,                EGL_TEXTURE_RECTANGLE_ANGLE,
    EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RG,
    EGL_TEXTURE_FORMAT,                EGL_TEXTURE_RGBA,
    EGL_TEXTURE_TYPE_ANGLE,            GL_UNSIGNED_BYTE,
    EGL_NONE,                          EGL_NONE,
  };
  // clang-format on

  uv_surface = eglCreatePbufferFromClientBuffer(display_, EGL_IOSURFACE_ANGLE,
                                                io_surface_.get(),
                                                dummy_config_, uvAttribs);
  if (uv_surface == EGL_NO_SURFACE) {
    LOG(ERROR) << "eglCreatePbufferFromClientBuffer failed, EGL error is "
               << eglGetError();
    return false;
  }

  result = eglBindTexImage(display_, uv_surface, EGL_BACK_BUFFER);
  if (result != EGL_TRUE) {
    LOG(ERROR) << "eglBindTexImage failed, EGL error is " << eglGetError();
    return false;
  }

  yuv_to_rgb_converter->CopyYUV420ToRGB(target, size_, rgb_texture);
  if (glGetError() != GL_NO_ERROR) {
    LOG(ERROR) << "Failed converting from YUV to RGB";
    return false;
  }

  return true;
}

}  // namespace gl
