// Copyright (c) 2012 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 "gpu/command_buffer/client/gl_in_process_context.h"

#include <set>
#include <utility>
#include <vector>

#include <GLES2/gl2.h>
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#include "ui/gfx/size.h"
#include "ui/gl/gl_image.h"

#if defined(OS_ANDROID)
#include "ui/gl/android/surface_texture.h"
#endif

namespace gpu {

namespace {

const int32 kDefaultCommandBufferSize = 1024 * 1024;
const unsigned int kDefaultStartTransferBufferSize = 4 * 1024 * 1024;
const unsigned int kDefaultMinTransferBufferSize = 1 * 256 * 1024;
const unsigned int kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;

class GLInProcessContextImpl
    : public GLInProcessContext,
      public base::SupportsWeakPtr<GLInProcessContextImpl> {
 public:
  explicit GLInProcessContextImpl(
      const GLInProcessContextSharedMemoryLimits& mem_limits);
  virtual ~GLInProcessContextImpl();

  bool Initialize(
      scoped_refptr<gfx::GLSurface> surface,
      bool is_offscreen,
      bool use_global_share_group,
      GLInProcessContext* share_context,
      gfx::AcceleratedWidget window,
      const gfx::Size& size,
      const gpu::gles2::ContextCreationAttribHelper& attribs,
      gfx::GpuPreference gpu_preference,
      const scoped_refptr<InProcessCommandBuffer::Service>& service);

  // GLInProcessContext implementation:
  virtual void SetContextLostCallback(const base::Closure& callback) override;
  virtual gles2::GLES2Implementation* GetImplementation() override;
  virtual size_t GetMappedMemoryLimit() override;

#if defined(OS_ANDROID)
  virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
      uint32 stream_id) override;
#endif

 private:
  void Destroy();
  void OnContextLost();
  void OnSignalSyncPoint(const base::Closure& callback);

  scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_;
  scoped_ptr<TransferBuffer> transfer_buffer_;
  scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
  scoped_ptr<InProcessCommandBuffer> command_buffer_;

  const GLInProcessContextSharedMemoryLimits mem_limits_;
  bool context_lost_;
  base::Closure context_lost_callback_;

  DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl);
};

base::LazyInstance<base::Lock> g_all_shared_contexts_lock =
    LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts =
    LAZY_INSTANCE_INITIALIZER;

GLInProcessContextImpl::GLInProcessContextImpl(
    const GLInProcessContextSharedMemoryLimits& mem_limits)
    : mem_limits_(mem_limits), context_lost_(false) {
}

GLInProcessContextImpl::~GLInProcessContextImpl() {
  {
    base::AutoLock lock(g_all_shared_contexts_lock.Get());
    g_all_shared_contexts.Get().erase(this);
  }
  Destroy();
}

gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() {
  return gles2_implementation_.get();
}

size_t GLInProcessContextImpl::GetMappedMemoryLimit() {
  return mem_limits_.mapped_memory_reclaim_limit;
}

void GLInProcessContextImpl::SetContextLostCallback(
    const base::Closure& callback) {
  context_lost_callback_ = callback;
}

void GLInProcessContextImpl::OnContextLost() {
  context_lost_ = true;
  if (!context_lost_callback_.is_null()) {
    context_lost_callback_.Run();
  }
}

bool GLInProcessContextImpl::Initialize(
    scoped_refptr<gfx::GLSurface> surface,
    bool is_offscreen,
    bool use_global_share_group,
    GLInProcessContext* share_context,
    gfx::AcceleratedWidget window,
    const gfx::Size& size,
    const gles2::ContextCreationAttribHelper& attribs,
    gfx::GpuPreference gpu_preference,
    const scoped_refptr<InProcessCommandBuffer::Service>& service) {
  DCHECK(!use_global_share_group || !share_context);
  DCHECK(size.width() >= 0 && size.height() >= 0);

  std::vector<int32> attrib_vector;
  attribs.Serialize(&attrib_vector);

  base::Closure wrapped_callback =
      base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr());
  command_buffer_.reset(new InProcessCommandBuffer(service));

  scoped_ptr<base::AutoLock> scoped_shared_context_lock;
  scoped_refptr<gles2::ShareGroup> share_group;
  InProcessCommandBuffer* share_command_buffer = NULL;
  if (use_global_share_group) {
    scoped_shared_context_lock.reset(
        new base::AutoLock(g_all_shared_contexts_lock.Get()));
    for (std::set<GLInProcessContextImpl*>::const_iterator it =
             g_all_shared_contexts.Get().begin();
         it != g_all_shared_contexts.Get().end();
         it++) {
      const GLInProcessContextImpl* context = *it;
      if (!context->context_lost_) {
        share_group = context->gles2_implementation_->share_group();
        share_command_buffer = context->command_buffer_.get();
        DCHECK(share_group.get());
        DCHECK(share_command_buffer);
        break;
      }
    }
  } else if (share_context) {
    GLInProcessContextImpl* impl =
        static_cast<GLInProcessContextImpl*>(share_context);
    share_group = impl->gles2_implementation_->share_group();
    share_command_buffer = impl->command_buffer_.get();
    DCHECK(share_group.get());
    DCHECK(share_command_buffer);
  }

  if (!command_buffer_->Initialize(surface,
                                   is_offscreen,
                                   window,
                                   size,
                                   attrib_vector,
                                   gpu_preference,
                                   wrapped_callback,
                                   share_command_buffer)) {
    LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
    return false;
  }

  // Create the GLES2 helper, which writes the command buffer protocol.
  gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
  if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) {
    LOG(ERROR) << "Failed to initialize GLES2CmdHelper";
    Destroy();
    return false;
  }

  // Create a transfer buffer.
  transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));

  // Check for consistency.
  DCHECK(!attribs.bind_generates_resource);
  bool bind_generates_resource = false;

  // Create the object exposing the OpenGL API.
  gles2_implementation_.reset(
      new gles2::GLES2Implementation(gles2_helper_.get(),
                                     share_group.get(),
                                     transfer_buffer_.get(),
                                     bind_generates_resource,
                                     attribs.lose_context_when_out_of_memory,
                                     command_buffer_.get()));

  if (use_global_share_group) {
    g_all_shared_contexts.Get().insert(this);
    scoped_shared_context_lock.reset();
  }

  if (!gles2_implementation_->Initialize(
          mem_limits_.start_transfer_buffer_size,
          mem_limits_.min_transfer_buffer_size,
          mem_limits_.max_transfer_buffer_size,
          mem_limits_.mapped_memory_reclaim_limit)) {
    return false;
  }

  return true;
}

void GLInProcessContextImpl::Destroy() {
  if (gles2_implementation_) {
    // First flush the context to ensure that any pending frees of resources
    // are completed. Otherwise, if this context is part of a share group,
    // those resources might leak. Also, any remaining side effects of commands
    // issued on this context might not be visible to other contexts in the
    // share group.
    gles2_implementation_->Flush();

    gles2_implementation_.reset();
  }

  transfer_buffer_.reset();
  gles2_helper_.reset();
  command_buffer_.reset();
}

#if defined(OS_ANDROID)
scoped_refptr<gfx::SurfaceTexture>
GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) {
  return command_buffer_->GetSurfaceTexture(stream_id);
}
#endif

}  // anonymous namespace

GLInProcessContextSharedMemoryLimits::GLInProcessContextSharedMemoryLimits()
    : command_buffer_size(kDefaultCommandBufferSize),
      start_transfer_buffer_size(kDefaultStartTransferBufferSize),
      min_transfer_buffer_size(kDefaultMinTransferBufferSize),
      max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
      mapped_memory_reclaim_limit(gles2::GLES2Implementation::kNoLimit) {
}

// static
GLInProcessContext* GLInProcessContext::Create(
    scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
    scoped_refptr<gfx::GLSurface> surface,
    bool is_offscreen,
    gfx::AcceleratedWidget window,
    const gfx::Size& size,
    GLInProcessContext* share_context,
    bool use_global_share_group,
    const ::gpu::gles2::ContextCreationAttribHelper& attribs,
    gfx::GpuPreference gpu_preference,
    const GLInProcessContextSharedMemoryLimits& memory_limits) {
  DCHECK(!use_global_share_group || !share_context);
  if (surface.get()) {
    DCHECK_EQ(surface->IsOffscreen(), is_offscreen);
    DCHECK(surface->GetSize() == size);
    DCHECK_EQ(gfx::kNullAcceleratedWidget, window);
  }

  scoped_ptr<GLInProcessContextImpl> context(
      new GLInProcessContextImpl(memory_limits));
  if (!context->Initialize(surface,
                           is_offscreen,
                           use_global_share_group,
                           share_context,
                           window,
                           size,
                           attribs,
                           gpu_preference,
                           service))
    return NULL;

  return context.release();
}

}  // namespace gpu
