// Copyright 2014 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_memory.h"

#include <stdint.h>

#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_version_info.h"

using gfx::BufferFormat;

namespace gl {
namespace {

bool ValidInternalFormat(unsigned internalformat) {
  switch (internalformat) {
    case GL_ATC_RGB_AMD:
    case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
    case GL_ETC1_RGB8_OES:
    case GL_RED:
    case GL_RGB:
    case GL_RGBA:
    case GL_BGRA_EXT:
      return true;
    default:
      return false;
  }
}

bool ValidFormat(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
    case gfx::BufferFormat::R_8:
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRX_8888:
    case gfx::BufferFormat::BGRA_8888:
      return true;
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      return false;
  }

  NOTREACHED();
  return false;
}

bool IsCompressedFormat(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
      return true;
    case gfx::BufferFormat::R_8:
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRX_8888:
    case gfx::BufferFormat::BGRA_8888:
      return false;
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return false;
  }

  NOTREACHED();
  return false;
}

GLenum TextureFormat(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::ATC:
      return GL_ATC_RGB_AMD;
    case gfx::BufferFormat::ATCIA:
      return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
    case gfx::BufferFormat::DXT1:
      return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
    case gfx::BufferFormat::DXT5:
      return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
    case gfx::BufferFormat::ETC1:
      return GL_ETC1_RGB8_OES;
    case gfx::BufferFormat::R_8:
      return GL_RED;
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBA_8888:
      return GL_RGBA;
    case gfx::BufferFormat::BGRA_8888:
      return GL_BGRA_EXT;
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::BGRX_8888:
      return GL_RGB;
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

GLenum DataFormat(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::RGBX_8888:
      return GL_RGBA;
    case gfx::BufferFormat::BGRX_8888:
      return GL_BGRA_EXT;
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRA_8888:
    case gfx::BufferFormat::R_8:
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
      return TextureFormat(format);
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

GLenum DataType(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::BGR_565:
      return GL_UNSIGNED_SHORT_5_6_5_REV;
    case gfx::BufferFormat::RGBA_4444:
      return GL_UNSIGNED_SHORT_4_4_4_4;
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRX_8888:
    case gfx::BufferFormat::BGRA_8888:
    case gfx::BufferFormat::R_8:
      return GL_UNSIGNED_BYTE;
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

GLint DataRowLength(size_t stride, gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::BGR_565:
    case gfx::BufferFormat::RGBA_4444:
      return base::checked_cast<GLint>(stride) / 2;
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRX_8888:
    case gfx::BufferFormat::BGRA_8888:
      return base::checked_cast<GLint>(stride) / 4;
    case gfx::BufferFormat::R_8:
      return base::checked_cast<GLint>(stride);
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

template <typename F>
std::unique_ptr<uint8_t[]> GLES2RGBData(const gfx::Size& size,
                                        size_t stride,
                                        const uint8_t* data,
                                        F const& data_to_rgb,
                                        GLenum* data_format,
                                        GLenum* data_type,
                                        GLint* data_row_length) {
  TRACE_EVENT2("gpu", "GLES2RGBData", "width", size.width(), "height",
               size.height());

  // Four-byte row alignment as specified by glPixelStorei with argument
  // GL_UNPACK_ALIGNMENT set to 4.
  size_t gles2_rgb_data_stride = (size.width() * 3 + 3) & ~3;
  std::unique_ptr<uint8_t[]> gles2_rgb_data(
      new uint8_t[gles2_rgb_data_stride * size.height()]);

  for (int y = 0; y < size.height(); ++y) {
    for (int x = 0; x < size.width(); ++x) {
      data_to_rgb(&data[y * stride + x * 4],
                  &gles2_rgb_data[y * gles2_rgb_data_stride + x * 3]);
    }
  }

  *data_format = GL_RGB;
  *data_type = GL_UNSIGNED_BYTE;
  *data_row_length = size.width();
  return gles2_rgb_data;
}

std::unique_ptr<uint8_t[]> GLES2RGB565Data(const gfx::Size& size,
                                           size_t stride,
                                           const uint8_t* data,
                                           GLenum* data_format,
                                           GLenum* data_type,
                                           GLint* data_row_length) {
  TRACE_EVENT2("gpu", "GLES2RGB565Data", "width", size.width(), "height",
               size.height());

  // Four-byte row alignment as specified by glPixelStorei with argument
  // GL_UNPACK_ALIGNMENT set to 4.
  size_t gles2_rgb_data_stride = (size.width() * 2 + 3) & ~3;
  std::unique_ptr<uint8_t[]> gles2_rgb_data(
      new uint8_t[gles2_rgb_data_stride * size.height()]);

  for (int y = 0; y < size.height(); ++y) {
    for (int x = 0; x < size.width(); ++x) {
      const uint16_t* src =
          reinterpret_cast<const uint16_t*>(&data[y * stride + x * 2]);
      uint16_t* dst = reinterpret_cast<uint16_t*>(
          &gles2_rgb_data[y * gles2_rgb_data_stride + x * 2]);
      *dst = (((*src & 0x1f) >> 0) << 11) | (((*src & 0x7e0) >> 5) << 5) |
             (((*src & 0xf800) >> 11) << 5);
    }
  }

  *data_format = GL_RGB;
  *data_type = GL_UNSIGNED_SHORT_5_6_5;
  *data_row_length = size.width();
  return gles2_rgb_data;
}

std::unique_ptr<uint8_t[]> GLES2Data(const gfx::Size& size,
                                     gfx::BufferFormat format,
                                     size_t stride,
                                     const uint8_t* data,
                                     GLenum* data_format,
                                     GLenum* data_type,
                                     GLint* data_row_length) {
  TRACE_EVENT2("gpu", "GLES2Data", "width", size.width(), "height",
               size.height());

  switch (format) {
    case gfx::BufferFormat::RGBX_8888:
      return GLES2RGBData(size, stride, data,
                          [](const uint8_t* src, uint8_t* dst) {
                            dst[0] = src[0];
                            dst[1] = src[1];
                            dst[2] = src[2];
                          },
                          data_format, data_type, data_row_length);
    case gfx::BufferFormat::BGR_565:
      return GLES2RGB565Data(size, stride, data, data_format, data_type,
                             data_row_length);
    case gfx::BufferFormat::BGRX_8888:
      return GLES2RGBData(size, stride, data,
                          [](const uint8_t* src, uint8_t* dst) {
                            dst[0] = src[2];
                            dst[1] = src[1];
                            dst[2] = src[0];
                          },
                          data_format, data_type, data_row_length);
    case gfx::BufferFormat::RGBA_4444:
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::BGRA_8888:
    case gfx::BufferFormat::R_8: {
      size_t gles2_data_stride =
          RowSizeForBufferFormat(size.width(), format, 0);
      if (stride == gles2_data_stride ||
          g_driver_gl.ext.b_GL_EXT_unpack_subimage)
        return nullptr;  // No data conversion needed

      std::unique_ptr<uint8_t[]> gles2_data(
          new uint8_t[gles2_data_stride * size.height()]);
      for (int y = 0; y < size.height(); ++y) {
        memcpy(&gles2_data[y * gles2_data_stride], &data[y * stride],
               gles2_data_stride);
      }
      *data_row_length = size.width();
      return gles2_data;
    }
    case gfx::BufferFormat::ATC:
    case gfx::BufferFormat::ATCIA:
    case gfx::BufferFormat::DXT1:
    case gfx::BufferFormat::DXT5:
    case gfx::BufferFormat::ETC1:
      return nullptr;  // No data conversion needed
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
    case gfx::BufferFormat::UYVY_422:
      NOTREACHED();
      return nullptr;
  }

  NOTREACHED();
  return nullptr;
}

}  // namespace

GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
    : size_(size),
      internalformat_(internalformat),
      memory_(nullptr),
      format_(gfx::BufferFormat::RGBA_8888),
      stride_(0) {}

GLImageMemory::~GLImageMemory() {
  DCHECK(!memory_);
}

bool GLImageMemory::Initialize(const unsigned char* memory,
                               gfx::BufferFormat format,
                               size_t stride) {
  if (!ValidInternalFormat(internalformat_)) {
    LOG(ERROR) << "Invalid internalformat: " << internalformat_;
    return false;
  }

  if (!ValidFormat(format)) {
    LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
    return false;
  }

  if (stride < RowSizeForBufferFormat(size_.width(), format, 0) || stride & 3) {
    LOG(ERROR) << "Invalid stride: " << stride;
    return false;
  }

  DCHECK(memory);
  DCHECK(!memory_);
  DCHECK(!IsCompressedFormat(format) || size_.width() % 4 == 0);
  DCHECK(!IsCompressedFormat(format) || size_.height() % 4 == 0);
  memory_ = memory;
  format_ = format;
  stride_ = stride;
  return true;
}

void GLImageMemory::Destroy(bool have_context) {
  memory_ = nullptr;
}

gfx::Size GLImageMemory::GetSize() {
  return size_;
}

unsigned GLImageMemory::GetInternalFormat() {
  return internalformat_;
}

bool GLImageMemory::BindTexImage(unsigned target) {
  return false;
}

bool GLImageMemory::CopyTexImage(unsigned target) {
  TRACE_EVENT2("gpu", "GLImageMemory::CopyTexImage", "width", size_.width(),
               "height", size_.height());

  // GL_TEXTURE_EXTERNAL_OES is not a supported target.
  if (target == GL_TEXTURE_EXTERNAL_OES)
    return false;

  if (IsCompressedFormat(format_)) {
    glCompressedTexImage2D(
        target, 0, TextureFormat(format_), size_.width(), size_.height(), 0,
        static_cast<GLsizei>(BufferSizeForBufferFormat(size_, format_)),
        memory_);
  } else {
    GLenum data_format = DataFormat(format_);
    GLenum data_type = DataType(format_);
    GLint data_row_length = DataRowLength(stride_, format_);
    std::unique_ptr<uint8_t[]> gles2_data;

    if (GLContext::GetCurrent()->GetVersionInfo()->is_es) {
      gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format,
                             &data_type, &data_row_length);
    }

    if (data_row_length != size_.width())
      glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);

    glTexImage2D(target, 0, TextureFormat(format_), size_.width(),
                 size_.height(), 0, data_format, data_type,
                 gles2_data ? gles2_data.get() : memory_);

    if (data_row_length != size_.width())
      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  }

  return true;
}

bool GLImageMemory::CopyTexSubImage(unsigned target,
                                    const gfx::Point& offset,
                                    const gfx::Rect& rect) {
  TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(),
               "height", rect.height());

  // GL_TEXTURE_EXTERNAL_OES is not a supported target.
  if (target == GL_TEXTURE_EXTERNAL_OES)
    return false;

  // Sub width is not supported.
  if (rect.width() != size_.width())
    return false;

  const uint8_t* data = memory_ + rect.y() * stride_;
  if (IsCompressedFormat(format_)) {
    // Height must be a multiple of 4.
    if (rect.height() % 4)
      return false;

    glCompressedTexSubImage2D(
        target, 0, offset.x(), offset.y(), rect.width(), rect.height(),
        DataFormat(format_),
        static_cast<GLsizei>(BufferSizeForBufferFormat(rect.size(), format_)),
        data);
  } else {
    GLenum data_format = DataFormat(format_);
    GLenum data_type = DataType(format_);
    GLint data_row_length = DataRowLength(stride_, format_);
    std::unique_ptr<uint8_t[]> gles2_data;

    if (GLContext::GetCurrent()->GetVersionInfo()->is_es) {
      gles2_data = GLES2Data(rect.size(), format_, stride_, data, &data_format,
                             &data_type, &data_row_length);
    }

    if (data_row_length != rect.width())
      glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);

    glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
                    rect.height(), data_format, data_type,
                    gles2_data ? gles2_data.get() : data);

    if (data_row_length != rect.width())
      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  }

  return true;
}

bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
                                         int z_order,
                                         gfx::OverlayTransform transform,
                                         const gfx::Rect& bounds_rect,
                                         const gfx::RectF& crop_rect) {
  return false;
}

// static
unsigned GLImageMemory::GetInternalFormatForTesting(gfx::BufferFormat format) {
  DCHECK(ValidFormat(format));
  return TextureFormat(format);
}

}  // namespace gl
