// Copyright 2015 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 "mojo/ui/gl_renderer.h"

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif
#include <GLES2/gl2.h>
#include <GLES2/gl2extmojo.h>

namespace mojo {
namespace ui {

GLRenderer::GLRenderer(const scoped_refptr<mojo::GLContext>& gl_context,
                       uint32_t max_recycled_textures)
    : gl_context_(gl_context),
      max_recycled_textures_(max_recycled_textures),
      weak_factory_(this) {
  DCHECK(gl_context_);
}

GLRenderer::~GLRenderer() {}

std::unique_ptr<mojo::GLTexture> GLRenderer::GetTexture(
    const mojo::GLContext::Scope& gl_scope,
    const mojo::Size& requested_size) {
  DCHECK(gl_scope.gl_context() == gl_context_);

  while (!recycled_textures_.empty()) {
    GLRecycledTextureInfo texture_info(std::move(recycled_textures_.front()));
    recycled_textures_.pop_front();
    if (texture_info.first->size().Equals(requested_size)) {
      glWaitSyncPointCHROMIUM(texture_info.second);
      return std::move(texture_info.first);
    }
  }

  return std::unique_ptr<GLTexture>(new GLTexture(gl_scope, requested_size));
}

mojo::gfx::composition::ResourcePtr GLRenderer::BindTextureResource(
    const mojo::GLContext::Scope& gl_scope,
    std::unique_ptr<GLTexture> gl_texture,
    mojo::gfx::composition::MailboxTextureResource::Origin origin) {
  DCHECK(gl_scope.gl_context() == gl_context_);
  DCHECK(gl_texture->gl_context() == gl_context_);

  // Produce the texture.
  glBindTexture(GL_TEXTURE_2D, gl_texture->texture_id());
  GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
  glGenMailboxCHROMIUM(mailbox);
  glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
  glBindTexture(GL_TEXTURE_2D, 0);
  GLuint sync_point = glInsertSyncPointCHROMIUM();

  // Populate the resource description.
  auto resource = mojo::gfx::composition::Resource::New();
  resource->set_mailbox_texture(
      mojo::gfx::composition::MailboxTextureResource::New());
  resource->get_mailbox_texture()->mailbox_name.resize(sizeof(mailbox));
  memcpy(resource->get_mailbox_texture()->mailbox_name.data(), mailbox,
         sizeof(mailbox));
  resource->get_mailbox_texture()->sync_point = sync_point;
  resource->get_mailbox_texture()->size = gl_texture->size().Clone();
  resource->get_mailbox_texture()->origin = origin;
  resource->get_mailbox_texture()->callback =
      (new GLTextureReleaser(
           weak_factory_.GetWeakPtr(),
           GLRecycledTextureInfo(std::move(gl_texture), sync_point)))
          ->StrongBind()
          .Pass();

  bound_textures_++;
  DVLOG(2) << "bind: bound_textures=" << bound_textures_;
  return resource;
}

mojo::gfx::composition::ResourcePtr GLRenderer::DrawGL(
    const mojo::GLContext::Scope& gl_scope,
    const mojo::Size& size,
    bool with_depth,
    const DrawGLCallback& callback) {
  DCHECK(gl_scope.gl_context() == gl_context_);

  std::unique_ptr<mojo::GLTexture> texture = GetTexture(gl_scope, size);
  DCHECK(texture);

  GLuint fbo = 0u;
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         texture->texture_id(), 0);

  GLuint depth_buffer = 0u;
  if (with_depth) {
    glGenRenderbuffers(1, &depth_buffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.width,
                          size.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, depth_buffer);
  }

  DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            glCheckFramebufferStatus(GL_FRAMEBUFFER));

  glViewport(0, 0, size.width, size.height);
  callback.Run(gl_scope, size);

  if (with_depth)
    glDeleteRenderbuffers(1, &depth_buffer);
  glDeleteFramebuffers(1, &fbo);

  return BindTextureResource(gl_scope, std::move(texture));
}

mojo::gfx::composition::ResourcePtr GLRenderer::DrawGL(
    const mojo::Size& size,
    bool with_depth,
    const DrawGLCallback& callback) {
  if (gl_context_->is_lost())
    return nullptr;
  mojo::GLContext::Scope gl_scope(gl_context_);
  return DrawGL(gl_scope, size, with_depth, callback);
}

void GLRenderer::ReleaseTexture(GLRecycledTextureInfo texture_info,
                                bool recyclable) {
  DCHECK(bound_textures_);
  bound_textures_--;
  if (recyclable && recycled_textures_.size() < max_recycled_textures_) {
    recycled_textures_.emplace_back(std::move(texture_info));
  }
  DVLOG(2) << "release: bound_textures=" << bound_textures_
           << ", recycled_textures=" << recycled_textures_.size();
}

GLRenderer::GLTextureReleaser::GLTextureReleaser(
    const base::WeakPtr<GLRenderer>& provider,
    GLRecycledTextureInfo info)
    : provider_(provider), texture_info_(std::move(info)), binding_(this) {}

GLRenderer::GLTextureReleaser::~GLTextureReleaser() {
  // It's possible for the object to be destroyed due to a connection
  // error on the callback pipe.  When this happens we don't want to
  // recycle the texture since we have too little knowledge about its
  // state to confirm that it will be safe to do so.
  Release(false /*recyclable*/);
}

mojo::gfx::composition::MailboxTextureCallbackPtr
GLRenderer::GLTextureReleaser::StrongBind() {
  mojo::gfx::composition::MailboxTextureCallbackPtr callback;
  binding_.Bind(mojo::GetProxy(&callback));
  return callback;
}

void GLRenderer::GLTextureReleaser::OnMailboxTextureReleased() {
  Release(true /*recyclable*/);
}

void GLRenderer::GLTextureReleaser::Release(bool recyclable) {
  if (provider_) {
    provider_->ReleaseTexture(std::move(texture_info_), recyclable);
    provider_.reset();
  }
}

}  // namespace ui
}  // namespace mojo
