/*
 * Copyright 2023 The Cobalt Authors. All Rights Reserved.
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "glimp/gles/texture.h"

#include <utility>

#include "glimp/rect.h"
#include "starboard/common/pointer_arithmetic.h"

namespace glimp {
namespace gles {

Texture::Texture(std::unique_ptr<TextureImpl> impl)
    : impl_(std::move(impl)),
      texture_allocated_(false),
      bound_to_surface_(NULL) {}

void Texture::Initialize(GLint level,
                         PixelFormat pixel_format,
                         GLsizei width,
                         GLsizei height) {
  width_ = static_cast<int>(width);
  height_ = static_cast<int>(height);
  pixel_format_ = pixel_format;

  impl_->Initialize(level, pixel_format_, width_, height_);

  texture_allocated_ = true;
}

bool Texture::UpdateData(GLint level,
                         GLint xoffset,
                         GLint yoffset,
                         GLsizei width,
                         GLsizei height,
                         int pitch_in_bytes,
                         const GLvoid* pixels) {
  SB_DCHECK(pixels != NULL);
  return impl_->UpdateData(level,
                           nb::Rect<int>(xoffset, yoffset, width, height),
                           pitch_in_bytes, pixels);
}

void Texture::UpdateDataFromBuffer(
    GLint level,
    GLint xoffset,
    GLint yoffset,
    GLsizei width,
    GLsizei height,
    int pitch_in_bytes,
    const nb::scoped_refptr<Buffer>& pixel_unpack_buffer,
    uintptr_t buffer_offset) {
  SB_DCHECK(pixel_unpack_buffer);
  impl_->UpdateDataFromBuffer(
      level, nb::Rect<int>(xoffset, yoffset, width, height), pitch_in_bytes,
      pixel_unpack_buffer, buffer_offset);
}

bool Texture::BindToEGLSurface(egl::Surface* surface) {
  if (bound_to_surface_ != NULL) {
    SB_DLOG(WARNING) << "A EGLSurface is already bound to this texture.";
    return false;
  }

  width_ = surface->GetWidth();
  height_ = surface->GetHeight();

  SB_DCHECK(surface->GetTextureFormat() == EGL_TEXTURE_RGBA);
  pixel_format_ = kPixelFormatRGBA8;
  texture_allocated_ = true;

  impl_->BindToEGLSurface(surface);
  bound_to_surface_ = surface;

  return true;
}

bool Texture::ReleaseFromEGLSurface(egl::Surface* surface) {
  if (bound_to_surface_ != surface) {
    SB_DLOG(WARNING) << "Attempting to release a surface that this texture was "
                        "not bound to.";
    return false;
  }

  width_ = 0;
  height_ = 0;
  pixel_format_ = kPixelFormatInvalid;
  texture_allocated_ = false;
  bound_to_surface_ = NULL;

  impl_->Initialize(0, kPixelFormatInvalid, 0, 0);

  return true;
}

void Texture::ReadPixelsAsRGBA8(GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height,
                                int pitch_in_bytes,
                                GLvoid* pixels) {
  impl_->ReadPixelsAsRGBA8(nb::Rect<int>(x, y, width, height), pitch_in_bytes,
                           pixels);
}

bool Texture::CanBeAttachedToFramebuffer() const {
  return impl_->CanBeAttachedToFramebuffer();
}

}  // namespace gles
}  // namespace glimp
