/*
 * 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.
 */

#if defined(GLES3_SUPPORTED)

#include "cobalt/renderer/backend/egl/texture_data_pbo.h"

#include <GLES2/gl2ext.h>

#include "base/bind.h"
#include "base/logging.h"
#include "cobalt/renderer/backend/egl/graphics_context.h"
#include "cobalt/renderer/backend/egl/utils.h"

namespace cobalt {
namespace renderer {
namespace backend {

TextureDataPBO::TextureDataPBO(ResourceContext* resource_context,
                               const math::Size& size, GLenum format)
    : resource_context_(resource_context), size_(size), format_(format) {
  data_size_ = static_cast<int64>(GetPitchInBytes()) * size_.height();

  resource_context_->RunSynchronouslyWithinResourceContext(
      base::Bind(&TextureDataPBO::InitAndMapPBO, base::Unretained(this)));
}

void TextureDataPBO::InitAndMapPBO() {
  resource_context_->AssertWithinResourceContext();

  // Use the resource context to allocate a GL pixel unpack buffer with the
  // specified size.
  GL_CALL(glGenBuffers(1, &pixel_buffer_));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
  GL_CALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, data_size_, 0, GL_STATIC_DRAW));

  // Map the GL pixel buffer data to CPU addressable memory.  We pass the flags
  // MAP_INVALIDATE_BUFFER_BIT | MAP_UNSYNCHRONIZED_BIT to tell GL that it
  // we don't care about previous data in the buffer and it shouldn't try to
  // synchronize existing draw calls with it, both things which should be
  // implied anyways since this is a brand new buffer, but we specify just in
  // case.
  mapped_data_ = static_cast<GLubyte*>(glMapBufferRange(
      GL_PIXEL_UNPACK_BUFFER, 0, data_size_, GL_MAP_WRITE_BIT |
                                                 GL_MAP_INVALIDATE_BUFFER_BIT |
                                                 GL_MAP_UNSYNCHRONIZED_BIT));
  CHECK(mapped_data_);
  DCHECK_EQ(GL_NO_ERROR, glGetError());
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
}

TextureDataPBO::~TextureDataPBO() {
  // mapped_data_ will be non-null if ConvertToTexture() was never called.
  if (mapped_data_) {
    // In the case that we still have valid mapped_data_, we must release it,
    // and we do so on the resource context.
    resource_context_->RunSynchronouslyWithinResourceContext(
        base::Bind(&TextureDataPBO::UnmapAndDeletePBO, base::Unretained(this)));
  }
}

void TextureDataPBO::UnmapAndDeletePBO() {
  resource_context_->AssertWithinResourceContext();

  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
  GL_CALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
  GL_CALL(glDeleteBuffers(1, &pixel_buffer_));
}

GLuint TextureDataPBO::ConvertToTexture(GraphicsContextEGL* graphics_context,
                                        bool bgra_supported) {
  DCHECK(mapped_data_) << "ConvertToTexture() should only ever be called once.";

  // Since we wish to create a texture within the specified graphics context,
  // we do the texture creation work using that context.
  GraphicsContextEGL::ScopedMakeCurrent scoped_make_current(graphics_context);

  // Our texture data remains mapped until this method is called, so we begin
  // by unmapping it.
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
  GL_CALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));

  // Setup our texture.
  GLuint texture_handle;
  GL_CALL(glGenTextures(1, &texture_handle));
  GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_handle));
  SetupInitialTextureParameters();

  // Determine the texture's GL format.
  if (format_ == GL_BGRA_EXT) {
    DCHECK(bgra_supported);
  }

  // Create the texture.  Since a GL_PIXEL_UNPACK_BUFFER is currently bound,
  // the "data" field passed to glTexImage2D will refer to an offset into that
  // buffer.
  GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH,
                        GetPitchInBytes() / BytesPerPixelForGLFormat(format_)));
  GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format_, size_.width(), size_.height(),
                       0, format_, GL_UNSIGNED_BYTE, 0));
  GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
  GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

  // The buffer is now referenced by the texture, and we no longer need to
  // explicitly reference it.
  GL_CALL(glDeleteBuffers(1, &pixel_buffer_));
  mapped_data_ = NULL;

  return texture_handle;
}

RawTextureMemoryPBO::RawTextureMemoryPBO(ResourceContext* resource_context,
                                         size_t size_in_bytes, size_t alignment)
    : size_in_bytes_(size_in_bytes),
      alignment_(alignment),
      resource_context_(resource_context) {
  resource_context_->RunSynchronouslyWithinResourceContext(
      base::Bind(&RawTextureMemoryPBO::InitAndMapPBO, base::Unretained(this)));
}

void RawTextureMemoryPBO::InitAndMapPBO() {
  resource_context_->AssertWithinResourceContext();

  int size_to_allocate = size_in_bytes_ + alignment_;

  // Allocate a GL pixel unpack buffer with the specified size, leaving enough
  // room such that we can adjust for alignment.
  GL_CALL(glGenBuffers(1, &pixel_buffer_));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
  GL_CALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_to_allocate, 0,
                       GL_STATIC_DRAW));

  // Map the GL pixel buffer data to CPU addressable memory.  We pass the flags
  // MAP_INVALIDATE_BUFFER_BIT | MAP_UNSYNCHRONIZED_BIT to tell GL that it
  // we don't care about previous data in the buffer and it shouldn't try to
  // synchronize existing draw calls with it, both things which should be
  // implied anyways since this is a brand new buffer, but we specify just in
  // case.
  mapped_data_ = static_cast<GLubyte*>(
      glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size_to_allocate,
                       GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT |
                           GL_MAP_UNSYNCHRONIZED_BIT));
  DCHECK_EQ(GL_NO_ERROR, glGetError());
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

  // Finally, determine the offset within |mapped_data_| necessary to acheive
  // the desired alignment.
  intptr_t alignment_remainder =
      reinterpret_cast<size_t>(mapped_data_) % alignment_;
  alignment_offset_ =
      alignment_remainder == 0 ? 0 : alignment_ - alignment_remainder;
}

RawTextureMemoryPBO::~RawTextureMemoryPBO() {
  resource_context_->RunSynchronouslyWithinResourceContext(
      base::Bind(&RawTextureMemoryPBO::DestroyPBO, base::Unretained(this)));
}

void RawTextureMemoryPBO::DestroyPBO() {
  resource_context_->AssertWithinResourceContext();

  if (mapped_data_) {
    // mapped_data_ will be non-null if we never call MakeConst() on it, in
    // which case we should unmap it before continuing.
    GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
    GL_CALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
    GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

    mapped_data_ = NULL;
  }

  // Clear our reference to the specified pixel buffer.
  GL_CALL(glDeleteBuffers(1, &pixel_buffer_));
}

void RawTextureMemoryPBO::MakeConst() {
  DCHECK(mapped_data_) << "MakeConst() should only ever be called once.";

  resource_context_->RunSynchronouslyWithinResourceContext(
      base::Bind(&RawTextureMemoryPBO::UnmapPBO, base::Unretained(this)));
}

void RawTextureMemoryPBO::UnmapPBO() {
  resource_context_->AssertWithinResourceContext();

  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));
  GL_CALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

  mapped_data_ = NULL;
}

GLuint RawTextureMemoryPBO::CreateTexture(GraphicsContextEGL* graphics_context,
                                          intptr_t offset,
                                          const math::Size& size, GLenum format,
                                          int pitch_in_bytes,
                                          bool bgra_supported) const {
  DCHECK(!mapped_data_)
      << "MakeConst() should be called before calling CreateTexture().";

  GLuint texture_handle;

  // Since we wish to create a texture within the specified graphics context,
  // we do the texture creation work using that context.
  GraphicsContextEGL::ScopedMakeCurrent scoped_make_current(graphics_context);

  // Our texture data remains mapped until this method is called, so we begin
  // by unmapping it.
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer_));

  // Setup our texture.
  GL_CALL(glGenTextures(1, &texture_handle));
  GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_handle));
  SetupInitialTextureParameters();

  // Determine the texture's GL format.
  if (format == GL_BGRA_EXT) {
    DCHECK(bgra_supported);
  }

  // Create the texture.  Since a GL_PIXEL_UNPACK_BUFFER is currently bound,
  // the "data" field passed to glTexImage2D will refer to an offset into that
  // buffer.
  GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH,
                        pitch_in_bytes / BytesPerPixelForGLFormat(format)));
  GL_CALL(
      glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0,
                   format, GL_UNSIGNED_BYTE,
                   reinterpret_cast<const void*>(alignment_offset_ + offset)));
  GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
  GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));
  GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

  return texture_handle;
}

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

#endif  // defined(GLES3_SUPPORTED)
