// 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 "cobalt/renderer/backend/egl/texture.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#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"

namespace cobalt {
namespace renderer {
namespace backend {

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

TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context,
                       scoped_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,
                       const base::Closure& delete_function)
    : graphics_context_(graphics_context),
      size_(size),
      format_(format),
      gl_handle_(gl_handle),
      target_(target),
      delete_function_(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()) {
    delete_function_.Run();
  } else {
    GL_CALL(glDeleteTextures(1, &gl_handle_));
  }
}

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