// 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/gles2_conform_support/egl/display.h"

#include <vector>
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_lib.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/value_state.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include "gpu/command_buffer/service/valuebuffer_manager.h"
#include "gpu/gles2_conform_support/egl/config.h"
#include "gpu/gles2_conform_support/egl/surface.h"

namespace {
const int32 kCommandBufferSize = 1024 * 1024;
const int32 kTransferBufferSize = 512 * 1024;
}

namespace egl {

Display::Display(EGLNativeDisplayType display_id)
    : display_id_(display_id),
      is_initialized_(false),
#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
      exit_manager_(new base::AtExitManager),
#endif
      create_offscreen_(false),
      create_offscreen_width_(0),
      create_offscreen_height_(0),
      next_fence_sync_release_(1) {
}

Display::~Display() {
  gles2::Terminate();
}

bool Display::Initialize() {
  gles2::Initialize();
  is_initialized_ = true;
  return true;
}

bool Display::IsValidConfig(EGLConfig config) {
  return (config != NULL) && (config == config_.get());
}

bool Display::ChooseConfigs(EGLConfig* configs,
                            EGLint config_size,
                            EGLint* num_config) {
  // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
  // does not support finding or choosing configs.
  *num_config = 1;
  if (configs != NULL) {
    if (config_ == NULL) {
      config_.reset(new Config);
    }
    configs[0] = config_.get();
  }
  return true;
}

bool Display::GetConfigs(EGLConfig* configs,
                         EGLint config_size,
                         EGLint* num_config) {
  // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
  // does not support finding or choosing configs.
  *num_config = 1;
  if (configs != NULL) {
    if (config_ == NULL) {
      config_.reset(new Config);
    }
    configs[0] = config_.get();
  }
  return true;
}

bool Display::GetConfigAttrib(EGLConfig config,
                              EGLint attribute,
                              EGLint* value) {
  const egl::Config* cfg = static_cast<egl::Config*>(config);
  return cfg->GetAttrib(attribute, value);
}

bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
#if defined OS_WIN
  return ::IsWindow(win) != FALSE;
#else
  // TODO(alokp): Validate window handle.
  return true;
#endif  // OS_WIN
}

bool Display::IsValidSurface(EGLSurface surface) {
  return (surface != NULL) && (surface == surface_.get());
}

EGLSurface Display::CreateWindowSurface(EGLConfig config,
                                        EGLNativeWindowType win,
                                        const EGLint* attrib_list) {
  if (surface_ != NULL) {
    // We do not support more than one window surface.
    return EGL_NO_SURFACE;
  }

  {
    gpu::TransferBufferManager* manager =
        new gpu::TransferBufferManager(nullptr);
    transfer_buffer_manager_ = manager;
    manager->Initialize();
  }
  scoped_ptr<gpu::CommandBufferService> command_buffer(
      new gpu::CommandBufferService(transfer_buffer_manager_.get()));
  if (!command_buffer->Initialize())
    return NULL;

  scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
      NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
      new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));

  decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
  if (!decoder_.get())
    return EGL_NO_SURFACE;

  gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
                                             decoder_.get(),
                                             NULL));

  decoder_->set_engine(gpu_scheduler_.get());
  gfx::Size size(create_offscreen_width_, create_offscreen_height_);
  if (create_offscreen_) {
    gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
    create_offscreen_ = false;
    create_offscreen_width_ = 0;
    create_offscreen_height_ = 0;
  } else {
    gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
  }
  if (!gl_surface_.get())
    return EGL_NO_SURFACE;

  gl_context_ = gfx::GLContext::CreateGLContext(NULL,
                                                gl_surface_.get(),
                                                gfx::PreferDiscreteGpu);
  if (!gl_context_.get())
    return EGL_NO_SURFACE;

  gl_context_->MakeCurrent(gl_surface_.get());

  EGLint depth_size = 0;
  EGLint alpha_size = 0;
  EGLint stencil_size = 0;
  GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
  GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
  GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
  std::vector<int32> attribs;
  attribs.push_back(EGL_DEPTH_SIZE);
  attribs.push_back(depth_size);
  attribs.push_back(EGL_ALPHA_SIZE);
  attribs.push_back(alpha_size);
  attribs.push_back(EGL_STENCIL_SIZE);
  attribs.push_back(stencil_size);
  // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
  attribs.push_back(EGL_NONE);

  if (!decoder_->Initialize(gl_surface_.get(),
                            gl_context_.get(),
                            gl_surface_->IsOffscreen(),
                            size,
                            gpu::gles2::DisallowedFeatures(),
                            attribs)) {
    return EGL_NO_SURFACE;
  }

  command_buffer->SetPutOffsetChangeCallback(
      base::Bind(&gpu::GpuScheduler::PutChanged,
                 base::Unretained(gpu_scheduler_.get())));
  command_buffer->SetGetBufferChangeCallback(
      base::Bind(&gpu::GpuScheduler::SetGetBuffer,
                 base::Unretained(gpu_scheduler_.get())));

  scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
      new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
  if (!cmd_helper->Initialize(kCommandBufferSize))
    return NULL;

  scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
      cmd_helper.get()));

  command_buffer_.reset(command_buffer.release());
  transfer_buffer_.reset(transfer_buffer.release());
  gles2_cmd_helper_.reset(cmd_helper.release());
  surface_.reset(new Surface(win));

  return surface_.get();
}

void Display::DestroySurface(EGLSurface surface) {
  DCHECK(IsValidSurface(surface));
  gpu_scheduler_.reset();
  if (decoder_.get()) {
    decoder_->Destroy(true);
  }
  decoder_.reset();
  gl_surface_ = NULL;
  gl_context_ = NULL;
  surface_.reset();
}

void Display::SwapBuffers(EGLSurface surface) {
  DCHECK(IsValidSurface(surface));
  context_->SwapBuffers();
}

bool Display::IsValidContext(EGLContext ctx) {
  return (ctx != NULL) && (ctx == context_.get());
}

EGLContext Display::CreateContext(EGLConfig config,
                                  EGLContext share_ctx,
                                  const EGLint* attrib_list) {
  DCHECK(IsValidConfig(config));
  // TODO(alokp): Add support for shared contexts.
  if (share_ctx != NULL)
    return EGL_NO_CONTEXT;

  DCHECK(command_buffer_ != NULL);
  DCHECK(transfer_buffer_.get());

  bool bind_generates_resources = true;
  bool lose_context_when_out_of_memory = false;
  bool support_client_side_arrays = true;

  context_.reset(
      new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
                                          NULL,
                                          transfer_buffer_.get(),
                                          bind_generates_resources,
                                          lose_context_when_out_of_memory,
                                          support_client_side_arrays,
                                          this));

  if (!context_->Initialize(
      kTransferBufferSize,
      kTransferBufferSize / 2,
      kTransferBufferSize * 2,
      gpu::gles2::GLES2Implementation::kNoLimit)) {
    return EGL_NO_CONTEXT;
  }

  context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
  context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");

  return context_.get();
}

void Display::DestroyContext(EGLContext ctx) {
  DCHECK(IsValidContext(ctx));
  context_.reset();
  transfer_buffer_.reset();
}

bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
  if (ctx == EGL_NO_CONTEXT) {
    gles2::SetGLContext(NULL);
  } else {
    DCHECK(IsValidSurface(draw));
    DCHECK(IsValidSurface(read));
    DCHECK(IsValidContext(ctx));
    gles2::SetGLContext(context_.get());
    gl_context_->MakeCurrent(gl_surface_.get());
  }
  return true;
}

gpu::Capabilities Display::GetCapabilities() {
  return decoder_->GetCapabilities();
}

int32_t Display::CreateImage(ClientBuffer buffer,
                             size_t width,
                             size_t height,
                             unsigned internalformat) {
  NOTIMPLEMENTED();
  return -1;
}

void Display::DestroyImage(int32 id) {
  NOTIMPLEMENTED();
}

int32_t Display::CreateGpuMemoryBufferImage(size_t width,
                                            size_t height,
                                            unsigned internalformat,
                                            unsigned usage) {
  NOTIMPLEMENTED();
  return -1;
}

uint32 Display::InsertSyncPoint() {
  NOTIMPLEMENTED();
  return 0u;
}

uint32 Display::InsertFutureSyncPoint() {
  NOTIMPLEMENTED();
  return 0u;
}

void Display::RetireSyncPoint(uint32 sync_point) {
  NOTIMPLEMENTED();
}

void Display::SignalSyncPoint(uint32 sync_point,
                              const base::Closure& callback) {
  NOTIMPLEMENTED();
}

void Display::SignalQuery(uint32 query, const base::Closure& callback) {
  NOTIMPLEMENTED();
}

void Display::SetSurfaceVisible(bool visible) {
  NOTIMPLEMENTED();
}

uint32 Display::CreateStreamTexture(uint32 texture_id) {
  NOTIMPLEMENTED();
  return 0;
}

void Display::SetLock(base::Lock*) {
  NOTIMPLEMENTED();
}

bool Display::IsGpuChannelLost() {
  NOTIMPLEMENTED();
  return false;
}

gpu::CommandBufferNamespace Display::GetNamespaceID() const {
  return gpu::CommandBufferNamespace::IN_PROCESS;
}

uint64_t Display::GetCommandBufferID() const {
  return 0;
}

uint64_t Display::GenerateFenceSyncRelease() {
  return next_fence_sync_release_++;
}

bool Display::IsFenceSyncRelease(uint64_t release) {
  return release > 0 && release < next_fence_sync_release_;
}

bool Display::IsFenceSyncFlushed(uint64_t release) {
  return IsFenceSyncRelease(release);
}

bool Display::IsFenceSyncFlushReceived(uint64_t release) {
  return IsFenceSyncRelease(release);
}

void Display::SignalSyncToken(const gpu::SyncToken& sync_token,
                              const base::Closure& callback) {
  NOTIMPLEMENTED();
}

bool Display::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) {
  return false;
}

}  // namespace egl
