// Copyright 2013 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/service/async_pixel_transfer_manager_egl.h"

#include <list>
#include <string>

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/scoped_binders.h"

namespace gpu {

namespace {

bool CheckErrors(const char* file, int line) {
  EGLint eglerror;
  GLenum glerror;
  bool success = true;
  while ((eglerror = eglGetError()) != EGL_SUCCESS) {
     LOG(ERROR) << "Async transfer EGL error at "
                << file << ":" << line << " " << eglerror;
     success = false;
  }
  while ((glerror = glGetError()) != GL_NO_ERROR) {
     LOG(ERROR) << "Async transfer OpenGL error at "
                << file << ":" << line << " " << glerror;
     success = false;
  }
  return success;
}
#define CHECK_GL() CheckErrors(__FILE__, __LINE__)

const char kAsyncTransferThreadName[] = "AsyncTransferThread";

// Regular glTexImage2D call.
void DoTexImage2D(const AsyncTexImage2DParams& tex_params, void* data) {
  glTexImage2D(
      GL_TEXTURE_2D, tex_params.level, tex_params.internal_format,
      tex_params.width, tex_params.height,
      tex_params.border, tex_params.format, tex_params.type, data);
}

// Regular glTexSubImage2D call.
void DoTexSubImage2D(const AsyncTexSubImage2DParams& tex_params, void* data) {
  glTexSubImage2D(
      GL_TEXTURE_2D, tex_params.level,
      tex_params.xoffset, tex_params.yoffset,
      tex_params.width, tex_params.height,
      tex_params.format, tex_params.type, data);
}

// Full glTexSubImage2D call, from glTexImage2D params.
void DoFullTexSubImage2D(const AsyncTexImage2DParams& tex_params, void* data) {
  glTexSubImage2D(
      GL_TEXTURE_2D, tex_params.level,
      0, 0, tex_params.width, tex_params.height,
      tex_params.format, tex_params.type, data);
}

void SetGlParametersForEglImageTexture() {
  // These params are needed for EGLImage creation to succeed on several
  // Android devices. I couldn't find this requirement in the EGLImage
  // extension spec, but several devices fail without it.
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

void PerformNotifyCompletion(
    AsyncMemoryParams mem_params,
    ScopedSafeSharedMemory* safe_shared_memory,
    scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
  TRACE_EVENT0("gpu", "PerformNotifyCompletion");
  AsyncMemoryParams safe_mem_params = mem_params;
  safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
  observer->DidComplete(safe_mem_params);
}

class TransferThread : public base::Thread {
 public:
  TransferThread() : base::Thread(kAsyncTransferThreadName) {
    Start();
#if defined(OS_ANDROID) || defined(OS_LINUX)
    SetPriority(base::kThreadPriority_Background);
#endif
  }
  virtual ~TransferThread() {
    Stop();
  }

  virtual void Init() OVERRIDE {
    gfx::GLShareGroup* share_group = NULL;
    surface_ = new gfx::PbufferGLSurfaceEGL(gfx::Size(1, 1));
    surface_->Initialize();
    context_ = gfx::GLContext::CreateGLContext(
        share_group, surface_.get(), gfx::PreferDiscreteGpu);
    bool is_current = context_->MakeCurrent(surface_.get());
    DCHECK(is_current);
  }

  virtual void CleanUp() OVERRIDE {
    surface_ = NULL;
    context_->ReleaseCurrent(surface_.get());
    context_ = NULL;
  }

  SafeSharedMemoryPool* safe_shared_memory_pool() {
      return &safe_shared_memory_pool_;
  }

 private:
  scoped_refptr<gfx::GLContext> context_;
  scoped_refptr<gfx::GLSurface> surface_;

  SafeSharedMemoryPool safe_shared_memory_pool_;

  DISALLOW_COPY_AND_ASSIGN(TransferThread);
};

base::LazyInstance<TransferThread>
    g_transfer_thread = LAZY_INSTANCE_INITIALIZER;

base::MessageLoopProxy* transfer_message_loop_proxy() {
  return g_transfer_thread.Pointer()->message_loop_proxy().get();
}

SafeSharedMemoryPool* safe_shared_memory_pool() {
  return g_transfer_thread.Pointer()->safe_shared_memory_pool();
}

// Class which holds async pixel transfers state (EGLImage).
// The EGLImage is accessed by either thread, but everything
// else accessed only on the main thread.
class TransferStateInternal
    : public base::RefCountedThreadSafe<TransferStateInternal> {
 public:
  TransferStateInternal(GLuint texture_id,
                        const AsyncTexImage2DParams& define_params,
                        bool wait_for_uploads,
                        bool wait_for_creation,
                        bool use_image_preserved)
      : texture_id_(texture_id),
        thread_texture_id_(0),
        transfer_completion_(true, true),
        egl_image_(EGL_NO_IMAGE_KHR),
        wait_for_uploads_(wait_for_uploads),
        wait_for_creation_(wait_for_creation),
        use_image_preserved_(use_image_preserved) {
    define_params_ = define_params;
  }

  bool TransferIsInProgress() {
    return !transfer_completion_.IsSignaled();
  }

  void BindTransfer() {
    TRACE_EVENT2("gpu", "BindAsyncTransfer glEGLImageTargetTexture2DOES",
                 "width", define_params_.width,
                 "height", define_params_.height);
    DCHECK(texture_id_);
    if (EGL_NO_IMAGE_KHR == egl_image_)
      return;

    glBindTexture(GL_TEXTURE_2D, texture_id_);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_);
    bind_callback_.Run();

    DCHECK(CHECK_GL());
  }

  void CreateEglImage(GLuint texture_id) {
    TRACE_EVENT0("gpu", "eglCreateImageKHR");
    DCHECK(texture_id);
    DCHECK_EQ(egl_image_, EGL_NO_IMAGE_KHR);

    EGLDisplay egl_display = eglGetCurrentDisplay();
    EGLContext egl_context = eglGetCurrentContext();
    EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR;
    EGLClientBuffer egl_buffer =
        reinterpret_cast<EGLClientBuffer>(texture_id);

    EGLint image_preserved = use_image_preserved_ ? EGL_TRUE : EGL_FALSE;
    EGLint egl_attrib_list[] = {
        EGL_GL_TEXTURE_LEVEL_KHR, 0, // mip-level.
        EGL_IMAGE_PRESERVED_KHR, image_preserved,
        EGL_NONE
    };
    egl_image_ = eglCreateImageKHR(
        egl_display,
        egl_context,
        egl_target,
        egl_buffer,
        egl_attrib_list);

    DLOG_IF(ERROR, EGL_NO_IMAGE_KHR == egl_image_)
        << "eglCreateImageKHR failed";
  }

  void CreateEglImageOnUploadThread() {
    CreateEglImage(thread_texture_id_);
  }

  void CreateEglImageOnMainThreadIfNeeded() {
    if (egl_image_ == EGL_NO_IMAGE_KHR) {
      CreateEglImage(texture_id_);
      if (wait_for_creation_) {
        TRACE_EVENT0("gpu", "glFinish creation");
        glFinish();
      }
    }
  }

  void WaitForLastUpload() {
    // This glFinish is just a safe-guard for if uploads have some
    // GPU action that needs to occur. We could use fences and try
    // to do this less often. However, on older drivers fences are
    // not always reliable (eg. Mali-400 just blocks forever).
    if (wait_for_uploads_) {
      TRACE_EVENT0("gpu", "glFinish");
      glFinish();
    }
  }

  void MarkAsTransferIsInProgress() {
    transfer_completion_.Reset();
  }

  void MarkAsCompleted() {
    transfer_completion_.Signal();
  }

  void WaitForTransferCompletion() {
    TRACE_EVENT0("gpu", "WaitForTransferCompletion");
    // TODO(backer): Deschedule the channel rather than blocking the main GPU
    // thread (crbug.com/240265).
    transfer_completion_.Wait();
  }

  void PerformAsyncTexImage2D(
      AsyncTexImage2DParams tex_params,
      AsyncMemoryParams mem_params,
      ScopedSafeSharedMemory* safe_shared_memory,
      scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
    TRACE_EVENT2("gpu",
                 "PerformAsyncTexImage",
                 "width",
                 tex_params.width,
                 "height",
                 tex_params.height);
    DCHECK(!thread_texture_id_);
    DCHECK_EQ(0, tex_params.level);
    if (EGL_NO_IMAGE_KHR != egl_image_) {
      MarkAsCompleted();
      return;
    }

    void* data =
        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);

    base::TimeTicks begin_time;
    if (texture_upload_stats.get())
      begin_time = base::TimeTicks::HighResNow();

    {
      TRACE_EVENT0("gpu", "glTexImage2D no data");
      glGenTextures(1, &thread_texture_id_);
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, thread_texture_id_);

      SetGlParametersForEglImageTexture();

      // If we need to use image_preserved, we pass the data with
      // the allocation. Otherwise we use a NULL allocation to
      // try to avoid any costs associated with creating the EGLImage.
      if (use_image_preserved_)
        DoTexImage2D(tex_params, data);
      else
        DoTexImage2D(tex_params, NULL);
    }

    CreateEglImageOnUploadThread();

    {
      TRACE_EVENT0("gpu", "glTexSubImage2D with data");

      // If we didn't use image_preserved, we haven't uploaded
      // the data yet, so we do this with a full texSubImage.
      if (!use_image_preserved_)
        DoFullTexSubImage2D(tex_params, data);
    }

    WaitForLastUpload();
    MarkAsCompleted();

    DCHECK(CHECK_GL());
    if (texture_upload_stats.get()) {
      texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() -
                                      begin_time);
    }
  }

  void PerformAsyncTexSubImage2D(
      AsyncTexSubImage2DParams tex_params,
      AsyncMemoryParams mem_params,
      ScopedSafeSharedMemory* safe_shared_memory,
      scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
    TRACE_EVENT2("gpu",
                 "PerformAsyncTexSubImage2D",
                 "width",
                 tex_params.width,
                 "height",
                 tex_params.height);

    DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
    DCHECK_EQ(0, tex_params.level);

    void* data =
        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);

    base::TimeTicks begin_time;
    if (texture_upload_stats.get())
      begin_time = base::TimeTicks::HighResNow();

    if (!thread_texture_id_) {
      TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES");
      glGenTextures(1, &thread_texture_id_);
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, thread_texture_id_);
      glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_);
    } else {
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, thread_texture_id_);
    }
    {
      TRACE_EVENT0("gpu", "glTexSubImage2D");
      DoTexSubImage2D(tex_params, data);
    }
    WaitForLastUpload();
    MarkAsCompleted();

    DCHECK(CHECK_GL());
    if (texture_upload_stats.get()) {
      texture_upload_stats->AddUpload(base::TimeTicks::HighResNow() -
                                      begin_time);
    }
  }

 protected:
  friend class base::RefCountedThreadSafe<TransferStateInternal>;
  friend class gpu::AsyncPixelTransferDelegateEGL;

  static void DeleteTexture(GLuint id) {
    glDeleteTextures(1, &id);
  }

  virtual ~TransferStateInternal() {
    if (egl_image_ != EGL_NO_IMAGE_KHR) {
      EGLDisplay display = eglGetCurrentDisplay();
      eglDestroyImageKHR(display, egl_image_);
    }
    if (thread_texture_id_) {
      transfer_message_loop_proxy()->PostTask(FROM_HERE,
          base::Bind(&DeleteTexture, thread_texture_id_));
    }
  }

  // The 'real' texture.
  GLuint texture_id_;

  // The EGLImage sibling on the upload thread.
  GLuint thread_texture_id_;

  // Definition params for texture that needs binding.
  AsyncTexImage2DParams define_params_;

  // Indicates that an async transfer is in progress.
  base::WaitableEvent transfer_completion_;

  // It would be nice if we could just create a new EGLImage for
  // every upload, but I found that didn't work, so this stores
  // one for the lifetime of the texture.
  EGLImageKHR egl_image_;

  // Callback to invoke when AsyncTexImage2D is complete
  // and the client can safely use the texture. This occurs
  // during BindCompletedAsyncTransfers().
  base::Closure bind_callback_;

  // Customize when we block on fences (these are work-arounds).
  bool wait_for_uploads_;
  bool wait_for_creation_;
  bool use_image_preserved_;
};

}  // namespace

// Class which handles async pixel transfers using EGLImageKHR and another
// upload thread
class AsyncPixelTransferDelegateEGL
    : public AsyncPixelTransferDelegate,
      public base::SupportsWeakPtr<AsyncPixelTransferDelegateEGL> {
 public:
  AsyncPixelTransferDelegateEGL(
      AsyncPixelTransferManagerEGL::SharedState* shared_state,
      GLuint texture_id,
      const AsyncTexImage2DParams& define_params);
  virtual ~AsyncPixelTransferDelegateEGL();

  void BindTransfer() { state_->BindTransfer(); }

  // Implement AsyncPixelTransferDelegate:
  virtual void AsyncTexImage2D(
      const AsyncTexImage2DParams& tex_params,
      const AsyncMemoryParams& mem_params,
      const base::Closure& bind_callback) OVERRIDE;
  virtual void AsyncTexSubImage2D(
      const AsyncTexSubImage2DParams& tex_params,
      const AsyncMemoryParams& mem_params) OVERRIDE;
  virtual bool TransferIsInProgress() OVERRIDE;
  virtual void WaitForTransferCompletion() OVERRIDE;

 private:
  // Returns true if a work-around was used.
  bool WorkAroundAsyncTexImage2D(
      const AsyncTexImage2DParams& tex_params,
      const AsyncMemoryParams& mem_params,
      const base::Closure& bind_callback);
  bool WorkAroundAsyncTexSubImage2D(
      const AsyncTexSubImage2DParams& tex_params,
      const AsyncMemoryParams& mem_params);

  // A raw pointer is safe because the SharedState is owned by the Manager,
  // which owns this Delegate.
  AsyncPixelTransferManagerEGL::SharedState* shared_state_;
  scoped_refptr<TransferStateInternal> state_;

  DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateEGL);
};

AsyncPixelTransferDelegateEGL::AsyncPixelTransferDelegateEGL(
    AsyncPixelTransferManagerEGL::SharedState* shared_state,
    GLuint texture_id,
    const AsyncTexImage2DParams& define_params)
    : shared_state_(shared_state) {
  // We can't wait on uploads on imagination (it can take 200ms+).
  // In practice, they are complete when the CPU glTexSubImage2D completes.
  bool wait_for_uploads = !shared_state_->is_imagination;

  // Qualcomm runs into texture corruption problems if the same texture is
  // uploaded to with both async and normal uploads. Synchronize after EGLImage
  // creation on the main thread as a work-around.
  bool wait_for_creation = shared_state_->is_qualcomm;

  // Qualcomm has a race when using image_preserved=FALSE,
  // which can result in black textures even after the first upload.
  // Since using FALSE is mainly for performance (to avoid layout changes),
  // but Qualcomm itself doesn't seem to get any performance benefit,
  // we just using image_preservedd=TRUE on Qualcomm as a work-around.
  bool use_image_preserved =
      shared_state_->is_qualcomm || shared_state_->is_imagination;

  state_ = new TransferStateInternal(texture_id,
                                   define_params,
                                   wait_for_uploads,
                                   wait_for_creation,
                                   use_image_preserved);
}

AsyncPixelTransferDelegateEGL::~AsyncPixelTransferDelegateEGL() {}

bool AsyncPixelTransferDelegateEGL::TransferIsInProgress() {
  return state_->TransferIsInProgress();
}

void AsyncPixelTransferDelegateEGL::WaitForTransferCompletion() {
  if (state_->TransferIsInProgress()) {
#if defined(OS_ANDROID) || defined(OS_LINUX)
    g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Display);
#endif

    state_->WaitForTransferCompletion();
    DCHECK(!state_->TransferIsInProgress());

#if defined(OS_ANDROID) || defined(OS_LINUX)
    g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Background);
#endif
  }
}

void AsyncPixelTransferDelegateEGL::AsyncTexImage2D(
    const AsyncTexImage2DParams& tex_params,
    const AsyncMemoryParams& mem_params,
    const base::Closure& bind_callback) {
  if (WorkAroundAsyncTexImage2D(tex_params, mem_params, bind_callback))
    return;

  DCHECK(mem_params.shared_memory);
  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
            mem_params.shm_size);
  DCHECK(!state_->TransferIsInProgress());
  DCHECK_EQ(state_->egl_image_, EGL_NO_IMAGE_KHR);
  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
  DCHECK_EQ(tex_params.level, 0);

  // Mark the transfer in progress and save the late bind
  // callback, so we can notify the client when it is bound.
  shared_state_->pending_allocations.push_back(AsWeakPtr());
  state_->bind_callback_ = bind_callback;

  // Mark the transfer in progress.
  state_->MarkAsTransferIsInProgress();

  // Duplicate the shared memory so there is no way we can get
  // a use-after-free of the raw pixels.
  transfer_message_loop_proxy()->PostTask(FROM_HERE,
      base::Bind(
          &TransferStateInternal::PerformAsyncTexImage2D,
          state_,
          tex_params,
          mem_params,
          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
                                                 mem_params.shared_memory,
                                                 mem_params.shm_size)),
          shared_state_->texture_upload_stats));

  DCHECK(CHECK_GL());
}

void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D(
    const AsyncTexSubImage2DParams& tex_params,
    const AsyncMemoryParams& mem_params) {
  TRACE_EVENT2("gpu", "AsyncTexSubImage2D",
               "width", tex_params.width,
               "height", tex_params.height);
  if (WorkAroundAsyncTexSubImage2D(tex_params, mem_params))
    return;
  DCHECK(!state_->TransferIsInProgress());
  DCHECK(mem_params.shared_memory);
  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
            mem_params.shm_size);
  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
  DCHECK_EQ(tex_params.level, 0);

  // Mark the transfer in progress.
  state_->MarkAsTransferIsInProgress();

  // If this wasn't async allocated, we don't have an EGLImage yet.
  // Create the EGLImage if it hasn't already been created.
  state_->CreateEglImageOnMainThreadIfNeeded();

  // Duplicate the shared memory so there are no way we can get
  // a use-after-free of the raw pixels.
  transfer_message_loop_proxy()->PostTask(FROM_HERE,
      base::Bind(
          &TransferStateInternal::PerformAsyncTexSubImage2D,
          state_,
          tex_params,
          mem_params,
          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
                                                 mem_params.shared_memory,
                                                 mem_params.shm_size)),
          shared_state_->texture_upload_stats));

  DCHECK(CHECK_GL());
}

namespace {
bool IsPowerOfTwo (unsigned int x) {
  return ((x != 0) && !(x & (x - 1)));
}

bool IsMultipleOfEight(unsigned int x) {
  return (x & 7) == 0;
}

bool DimensionsSupportImgFastPath(int width, int height) {
  // Multiple of eight, but not a power of two.
  return IsMultipleOfEight(width) &&
         IsMultipleOfEight(height) &&
         !(IsPowerOfTwo(width) &&
           IsPowerOfTwo(height));
}
}  // namespace

// It is very difficult to stream uploads on Imagination GPUs:
// - glTexImage2D defers a swizzle/stall until draw-time
// - glTexSubImage2D will sleep for 16ms on a good day, and 100ms
//   or longer if OpenGL is in heavy use by another thread.
// The one combination that avoids these problems requires:
// a.) Allocations/Uploads must occur on different threads/contexts.
// b.) Texture size must be non-power-of-two.
// When using a+b, uploads will be incorrect/corrupt unless:
// c.) Texture size must be a multiple-of-eight.
//
// To achieve a.) we allocate synchronously on the main thread followed
// by uploading on the upload thread. When b/c are not true we fall back
// on purely synchronous allocation/upload on the main thread.

bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexImage2D(
    const AsyncTexImage2DParams& tex_params,
    const AsyncMemoryParams& mem_params,
    const base::Closure& bind_callback) {
  if (!shared_state_->is_imagination)
    return false;

  // On imagination we allocate synchronously all the time, even
  // if the dimensions support fast uploads. This is for part a.)
  // above, so allocations occur on a different thread/context as uploads.
  void* data = GetAddress(mem_params);
  SetGlParametersForEglImageTexture();

  {
    TRACE_EVENT0("gpu", "glTexImage2D with data");
    DoTexImage2D(tex_params, data);
  }

  // The allocation has already occured, so mark it as finished
  // and ready for binding.
  CHECK(!state_->TransferIsInProgress());

  // If the dimensions support fast async uploads, create the
  // EGLImage for future uploads. The late bind should not
  // be needed since the EGLImage was created from the main thread
  // texture, but this is required to prevent an imagination driver crash.
  if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height)) {
    state_->CreateEglImageOnMainThreadIfNeeded();
    shared_state_->pending_allocations.push_back(AsWeakPtr());
    state_->bind_callback_ = bind_callback;
  }

  DCHECK(CHECK_GL());
  return true;
}

bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D(
    const AsyncTexSubImage2DParams& tex_params,
    const AsyncMemoryParams& mem_params) {
  if (!shared_state_->is_imagination)
    return false;

  // If the dimensions support fast async uploads, we can use the
  // normal async upload path for uploads.
  if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height))
    return false;

  // Fall back on a synchronous stub as we don't have a known fast path.
  // Also, older ICS drivers crash when we do any glTexSubImage2D on the
  // same thread. To work around this we do glTexImage2D instead. Since
  // we didn't create an EGLImage for this texture (see above), this is
  // okay, but it limits this API to full updates for now.
  DCHECK(!state_->egl_image_);
  DCHECK_EQ(tex_params.xoffset, 0);
  DCHECK_EQ(tex_params.yoffset, 0);
  DCHECK_EQ(state_->define_params_.width, tex_params.width);
  DCHECK_EQ(state_->define_params_.height, tex_params.height);
  DCHECK_EQ(state_->define_params_.level, tex_params.level);
  DCHECK_EQ(state_->define_params_.format, tex_params.format);
  DCHECK_EQ(state_->define_params_.type, tex_params.type);

  void* data = GetAddress(mem_params);
  base::TimeTicks begin_time;
  if (shared_state_->texture_upload_stats.get())
    begin_time = base::TimeTicks::HighResNow();
  {
    TRACE_EVENT0("gpu", "glTexSubImage2D");
    // Note we use define_params_ instead of tex_params.
    // The DCHECKs above verify this is always the same.
    DoTexImage2D(state_->define_params_, data);
  }
  if (shared_state_->texture_upload_stats.get()) {
    shared_state_->texture_upload_stats
        ->AddUpload(base::TimeTicks::HighResNow() - begin_time);
  }

  DCHECK(CHECK_GL());
  return true;
}

AsyncPixelTransferManagerEGL::SharedState::SharedState()
    // TODO(reveman): Skip this if --enable-gpu-benchmarking is not present.
    : texture_upload_stats(new AsyncPixelTransferUploadStats) {
  std::string vendor;
  vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
  is_imagination = vendor.find("Imagination") != std::string::npos;
  is_qualcomm = vendor.find("Qualcomm") != std::string::npos;
}

AsyncPixelTransferManagerEGL::SharedState::~SharedState() {}

AsyncPixelTransferManagerEGL::AsyncPixelTransferManagerEGL() {}

AsyncPixelTransferManagerEGL::~AsyncPixelTransferManagerEGL() {}

void AsyncPixelTransferManagerEGL::BindCompletedAsyncTransfers() {
  scoped_ptr<gfx::ScopedTextureBinder> texture_binder;

  while(!shared_state_.pending_allocations.empty()) {
    if (!shared_state_.pending_allocations.front().get()) {
      shared_state_.pending_allocations.pop_front();
      continue;
    }
    AsyncPixelTransferDelegateEGL* delegate =
        shared_state_.pending_allocations.front().get();
    // Terminate early, as all transfers finish in order, currently.
    if (delegate->TransferIsInProgress())
      break;

    if (!texture_binder)
      texture_binder.reset(new gfx::ScopedTextureBinder(GL_TEXTURE_2D, 0));

    // If the transfer is finished, bind it to the texture
    // and remove it from pending list.
    delegate->BindTransfer();
    shared_state_.pending_allocations.pop_front();
  }
}

void AsyncPixelTransferManagerEGL::AsyncNotifyCompletion(
    const AsyncMemoryParams& mem_params,
    AsyncPixelTransferCompletionObserver* observer) {
  DCHECK(mem_params.shared_memory);
  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
            mem_params.shm_size);
  // Post a PerformNotifyCompletion task to the upload thread. This task
  // will run after all async transfers are complete.
  transfer_message_loop_proxy()->PostTask(
      FROM_HERE,
      base::Bind(&PerformNotifyCompletion,
                 mem_params,
                 base::Owned(
                     new ScopedSafeSharedMemory(safe_shared_memory_pool(),
                                                mem_params.shared_memory,
                                                mem_params.shm_size)),
                 make_scoped_refptr(observer)));
}

uint32 AsyncPixelTransferManagerEGL::GetTextureUploadCount() {
  return shared_state_.texture_upload_stats->GetStats(NULL);
}

base::TimeDelta AsyncPixelTransferManagerEGL::GetTotalTextureUploadTime() {
  base::TimeDelta total_texture_upload_time;
  shared_state_.texture_upload_stats->GetStats(&total_texture_upload_time);
  return total_texture_upload_time;
}

void AsyncPixelTransferManagerEGL::ProcessMorePendingTransfers() {
}

bool AsyncPixelTransferManagerEGL::NeedsProcessMorePendingTransfers() {
  return false;
}

AsyncPixelTransferDelegate*
AsyncPixelTransferManagerEGL::CreatePixelTransferDelegateImpl(
    gles2::TextureRef* ref,
    const AsyncTexImage2DParams& define_params) {
  return new AsyncPixelTransferDelegateEGL(
      &shared_state_, ref->service_id(), define_params);
}

}  // namespace gpu
