// Copyright 2015 The Cobalt Authors. 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 "cobalt/renderer/backend/egl/texture.h"

#include <utility>

#include "base/bind.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/renderer/backend/egl/framebuffer_render_target.h"
#include "cobalt/renderer/backend/egl/graphics_context.h"
#include "cobalt/renderer/backend/egl/pbuffer_render_target.h"
#include "cobalt/renderer/backend/egl/resource_context.h"
#include "cobalt/renderer/backend/egl/texture_data.h"
#include "cobalt/renderer/backend/egl/texture_data_cpu.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"
#include "starboard/configuration.h"


namespace cobalt {
namespace renderer {
namespace backend {

namespace {
void DoNothing() {}
}  // namespace

TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context,
                       std::unique_ptr<TextureDataEGL> texture_source_data,
                       bool bgra_supported)
    : graphics_context_(graphics_context),
      size_(texture_source_data->GetSize()),
      format_(texture_source_data->GetFormat()),
      target_(GL_TEXTURE_2D) {
  gl_handle_ =
      texture_source_data->ConvertToTexture(graphics_context_, bgra_supported);
}

TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context,
                       const RawTextureMemoryEGL* data, intptr_t offset,
                       const math::Size& size, GLenum format,
                       int pitch_in_bytes, bool bgra_supported)
    : graphics_context_(graphics_context),
      size_(size),
      format_(format),
      target_(GL_TEXTURE_2D) {
  gl_handle_ = data->CreateTexture(graphics_context_, offset, size, format,
                                   pitch_in_bytes, bgra_supported);
}

TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, GLuint gl_handle,
                       const math::Size& size, GLenum format, GLenum target,
                       base::OnceClosure&& delete_function)
    : graphics_context_(graphics_context),
      size_(size),
      format_(format),
      gl_handle_(gl_handle),
      target_(target),
      delete_function_(std::move(delete_function)) {}

TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context,
                       const scoped_refptr<RenderTargetEGL>& render_target)
    : graphics_context_(graphics_context),
      size_(render_target->GetSize()),
      format_(GL_RGBA),
      target_(GL_TEXTURE_2D) {
  GraphicsContextEGL::ScopedMakeCurrent scoped_make_current(graphics_context_);

  source_render_target_ = render_target;

  if (render_target->GetSurface() != EGL_NO_SURFACE) {
    // This is a PBufferRenderTargetEGL. Need to bind a texture to the surface.
    const PBufferRenderTargetEGL* pbuffer_target =
        base::polymorphic_downcast<const PBufferRenderTargetEGL*>(
            render_target.get());

    // First we create the OpenGL texture object and maintain a handle to it.
    GL_CALL(glGenTextures(1, &gl_handle_));
    GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_handle_));
    SetupInitialTextureParameters();

    // This call attaches the EGL PBuffer object to the currently bound OpenGL
    // texture object, effectively allowing the PBO render target to be used
    // as a texture by referencing gl_handle_ from now on.
    EGL_CALL(eglBindTexImage(pbuffer_target->display(),
                             pbuffer_target->GetSurface(), EGL_BACK_BUFFER));

    GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
  } else {
    // This is a FramebufferRenderTargetEGL. Wrap its color texture attachment.
    const FramebufferRenderTargetEGL* framebuffer_target =
        base::polymorphic_downcast<const FramebufferRenderTargetEGL*>(
            render_target.get());

    const TextureEGL* color_attachment = framebuffer_target->GetColorTexture();
    format_ = color_attachment->GetFormat();
    target_ = color_attachment->GetTarget();
    gl_handle_ = color_attachment->gl_handle();

    // Do not destroy the wrapped texture. Let the render target do that.
    delete_function_ = base::Bind(&DoNothing);
  }
}

TextureEGL::~TextureEGL() {
  GraphicsContextEGL::ScopedMakeCurrent scoped_make_current(graphics_context_);

  if (source_render_target_ &&
      source_render_target_->GetSurface() != EGL_NO_SURFACE) {
    const PBufferRenderTargetEGL* pbuffer_target =
        base::polymorphic_downcast<const PBufferRenderTargetEGL*>(
            source_render_target_.get());
    EGL_CALL(eglReleaseTexImage(pbuffer_target->display(),
                                pbuffer_target->GetSurface(), EGL_BACK_BUFFER));
  }

  if (!delete_function_.is_null()) {
    std::move(delete_function_).Run();
  } else {
    GL_CALL(glDeleteTextures(1, &gl_handle_));
  }
}

}  // namespace backend
}  // namespace renderer
}  // namespace cobalt
