1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/trace_event_synthetic_delay.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/weak_ptr.h"
12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/gl/scoped_binders.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace gpu {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static uint64 g_next_pixel_transfer_state_id = 1;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PerformNotifyCompletion(
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    AsyncMemoryParams mem_params,
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("gpu", "PerformNotifyCompletion");
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  observer->DidComplete(mem_params);
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Class which handles async pixel transfers in a platform
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// independent way.
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class AsyncPixelTransferDelegateIdle
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public AsyncPixelTransferDelegate,
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public base::SupportsWeakPtr<AsyncPixelTransferDelegateIdle> {
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AsyncPixelTransferDelegateIdle(
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      AsyncPixelTransferManagerIdle::SharedState* state,
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GLuint texture_id,
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const AsyncTexImage2DParams& define_params);
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~AsyncPixelTransferDelegateIdle();
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Implement AsyncPixelTransferDelegate:
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void AsyncTexImage2D(
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncTexImage2DParams& tex_params,
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncMemoryParams& mem_params,
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const base::Closure& bind_callback) OVERRIDE;
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void AsyncTexSubImage2D(
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncTexSubImage2DParams& tex_params,
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncMemoryParams& mem_params) OVERRIDE;
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool TransferIsInProgress() OVERRIDE;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void WaitForTransferCompletion() OVERRIDE;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void PerformAsyncTexImage2D(AsyncTexImage2DParams tex_params,
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              AsyncMemoryParams mem_params,
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              const base::Closure& bind_callback);
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void PerformAsyncTexSubImage2D(AsyncTexSubImage2DParams tex_params,
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 AsyncMemoryParams mem_params);
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  uint64 id_;
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GLuint texture_id_;
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool transfer_in_progress_;
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AsyncTexImage2DParams define_params_;
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Safe to hold a raw pointer because SharedState is owned by the Manager
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // which owns the Delegate.
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AsyncPixelTransferManagerIdle::SharedState* shared_state_;
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateIdle);
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle(
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    AsyncPixelTransferManagerIdle::SharedState* shared_state,
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GLuint texture_id,
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const AsyncTexImage2DParams& define_params)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : id_(g_next_pixel_transfer_state_id++),
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      texture_id_(texture_id),
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      transfer_in_progress_(false),
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      define_params_(define_params),
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      shared_state_(shared_state) {}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AsyncPixelTransferDelegateIdle::~AsyncPixelTransferDelegateIdle() {}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncTexImage2DParams& tex_params,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncMemoryParams& mem_params,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& bind_callback) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      id_,
924ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      this,
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 AsWeakPtr(),
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 tex_params,
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 mem_params,
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 bind_callback)));
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  transfer_in_progress_ = true;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncTexSubImage2DParams& tex_params,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncMemoryParams& mem_params) {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      id_,
1104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      this,
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 AsWeakPtr(),
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 tex_params,
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 mem_params)));
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  transfer_in_progress_ = true;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool  AsyncPixelTransferDelegateIdle::TransferIsInProgress() {
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return transfer_in_progress_;
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AsyncPixelTransferDelegateIdle::WaitForTransferCompletion() {
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (std::list<AsyncPixelTransferManagerIdle::Task>::iterator iter =
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           shared_state_->tasks.begin();
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != shared_state_->tasks.end();
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++iter) {
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (iter->transfer_id != id_)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter).task.Run();
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    shared_state_->tasks.erase(iter);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    break;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->ProcessNotificationTasks();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncTexImage2DParams tex_params,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncMemoryParams mem_params,
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const base::Closure& bind_callback) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "width", tex_params.width,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "height", tex_params.height);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* data = mem_params.GetDataAddress();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeTicks begin_time(base::TimeTicks::HighResNow());
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("gpu", "glTexImage2D");
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexImage2D(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.target,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.level,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.internal_format,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.width,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.height,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.border,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.format,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.type,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        data);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  transfer_in_progress_ = false;
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shared_state_->texture_upload_count++;
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shared_state_->total_texture_upload_time +=
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::TimeTicks::HighResNow() - begin_time;
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The texture is already fully bound so just call it now.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bind_callback.Run();
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncTexSubImage2DParams tex_params,
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    AsyncMemoryParams mem_params) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "width", tex_params.width,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "height", tex_params.height);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* data = mem_params.GetDataAddress();
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks begin_time(base::TimeTicks::HighResNow());
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If it's a full texture update, use glTexImage2D as it's faster.
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // TODO(epenner): Make this configurable (http://crbug.com/259924)
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (tex_params.xoffset == 0 &&
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tex_params.yoffset == 0 &&
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tex_params.target == define_params_.target &&
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tex_params.level  == define_params_.level &&
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tex_params.width  == define_params_.width &&
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tex_params.height == define_params_.height) {
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT0("gpu", "glTexImage2D");
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    glTexImage2D(
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.target,
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.level,
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.internal_format,
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.width,
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.height,
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        define_params_.border,
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        tex_params.format,
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        tex_params.type,
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        data);
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("gpu", "glTexSubImage2D");
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexSubImage2D(
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.target,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.level,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.xoffset,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.yoffset,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.width,
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.height,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.format,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.type,
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        data);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  transfer_in_progress_ = false;
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->texture_upload_count++;
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->total_texture_upload_time +=
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::TimeTicks::HighResNow() - begin_time;
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::Task::Task(
2294ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    uint64 transfer_id,
2304ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    AsyncPixelTransferDelegate* delegate,
2314ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    const base::Closure& task)
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : transfer_id(transfer_id),
2334ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      delegate(delegate),
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      task(task) {
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::Task::~Task() {}
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::SharedState::SharedState()
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : texture_upload_count(0) {}
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::SharedState::~SharedState() {}
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::SharedState::ProcessNotificationTasks() {
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  while (!tasks.empty()) {
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Stop when we reach a pixel transfer task.
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (tasks.front().transfer_id)
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tasks.front().task.Run();
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tasks.pop_front();
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle()
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  : shared_state_() {
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::~AsyncPixelTransferManagerIdle() {}
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::BindCompletedAsyncTransfers() {
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Everything is already bound.
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::AsyncNotifyCompletion(
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const AsyncMemoryParams& mem_params,
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AsyncPixelTransferCompletionObserver* observer) {
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (shared_state_.tasks.empty()) {
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    observer->DidComplete(mem_params);
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.push_back(
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Task(0,  // 0 transfer_id for notification tasks.
2754ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch           NULL,
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           base::Bind(
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               &PerformNotifyCompletion,
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               mem_params,
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               make_scoped_refptr(observer))));
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint32 AsyncPixelTransferManagerIdle::GetTextureUploadCount() {
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return shared_state_.texture_upload_count;
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::TimeDelta AsyncPixelTransferManagerIdle::GetTotalTextureUploadTime() {
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return shared_state_.total_texture_upload_time;
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::ProcessMorePendingTransfers() {
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (shared_state_.tasks.empty())
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // First task should always be a pixel transfer task.
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(shared_state_.tasks.front().transfer_id);
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.front().task.Run();
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.pop_front();
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.ProcessNotificationTasks();
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AsyncPixelTransferManagerIdle::NeedsProcessMorePendingTransfers() {
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return !shared_state_.tasks.empty();
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3064ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid AsyncPixelTransferManagerIdle::WaitAllAsyncTexImage2D() {
3074ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  if (shared_state_.tasks.empty())
3084ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    return;
3094ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
3104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  const Task& task = shared_state_.tasks.back();
3114ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  if (task.delegate)
3124ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    task.delegate->WaitForTransferCompletion();
3134ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch}
3144ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferDelegate*
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl(
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gles2::TextureRef* ref,
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const AsyncTexImage2DParams& define_params) {
3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return new AsyncPixelTransferDelegateIdle(&shared_state_,
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                            ref->service_id(),
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                            define_params);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace gpu
325