async_pixel_transfer_manager_idle.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h"
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/gl/scoped_binders.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace gpu {
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::LazyInstance<SafeSharedMemoryPool> g_safe_shared_memory_pool =
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeSharedMemoryPool* safe_shared_memory_pool() {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return g_safe_shared_memory_pool.Pointer();
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static uint64 g_next_pixel_transfer_state_id = 1;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PerformNotifyCompletion(
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    AsyncMemoryParams mem_params,
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ScopedSafeSharedMemory* safe_shared_memory,
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const AsyncPixelTransferManager::CompletionCallback& callback) {
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("gpu", "PerformNotifyCompletion");
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AsyncMemoryParams safe_mem_params = mem_params;
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(safe_mem_params);
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncPixelTransferStateImpl : public AsyncPixelTransferState {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(GLuint)> TransferCallback;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit AsyncPixelTransferStateImpl(GLuint texture_id)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : id_(g_next_pixel_transfer_state_id++),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        texture_id_(texture_id),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        transfer_in_progress_(false) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Implement AsyncPixelTransferState:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool TransferIsInProgress() OVERRIDE {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return transfer_in_progress_;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 id() const { return id_; }
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_transfer_in_progress(bool transfer_in_progress) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    transfer_in_progress_ = transfer_in_progress;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PerformTransfer(const TransferCallback& callback) {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(texture_id_);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(transfer_in_progress_);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(texture_id_);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    transfer_in_progress_ = false;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~AsyncPixelTransferStateImpl() {}
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 id_;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLuint texture_id_;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool transfer_in_progress_;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Class which handles async pixel transfers in a platform
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// independent way.
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class AsyncPixelTransferDelegateIdle : public AsyncPixelTransferDelegate,
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    public base::SupportsWeakPtr<AsyncPixelTransferDelegateIdle> {
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit AsyncPixelTransferDelegateIdle(
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncPixelTransferManagerIdle::SharedState* state);
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~AsyncPixelTransferDelegateIdle();
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Implement AsyncPixelTransferDelegate:
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual AsyncPixelTransferState* CreatePixelTransferState(
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GLuint texture_id,
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncTexImage2DParams& define_params) OVERRIDE;
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void AsyncTexImage2D(
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncPixelTransferState* transfer_state,
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncTexImage2DParams& tex_params,
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncMemoryParams& mem_params,
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const base::Closure& bind_callback) OVERRIDE;
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void AsyncTexSubImage2D(
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncPixelTransferState* transfer_state,
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncTexSubImage2DParams& tex_params,
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const AsyncMemoryParams& mem_params) OVERRIDE;
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void WaitForTransferCompletion(
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncPixelTransferState* transfer_state) OVERRIDE;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void PerformAsyncTexImage2D(
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncTexImage2DParams tex_params,
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncMemoryParams mem_params,
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const base::Closure& bind_callback,
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ScopedSafeSharedMemory* safe_shared_memory,
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GLuint texture_id);
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void PerformAsyncTexSubImage2D(
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncTexSubImage2DParams tex_params,
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AsyncMemoryParams mem_params,
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ScopedSafeSharedMemory* safe_shared_memory,
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GLuint texture_id);
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Safe to hold a raw pointer because SharedState is owned by the Manager
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // which owns the Delegate.
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AsyncPixelTransferManagerIdle::SharedState* shared_state_;
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateIdle);
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle(
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    AsyncPixelTransferManagerIdle::SharedState* shared_state)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : shared_state_(shared_state) {}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AsyncPixelTransferDelegateIdle::~AsyncPixelTransferDelegateIdle() {}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AsyncPixelTransferState* AsyncPixelTransferDelegateIdle::
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreatePixelTransferState(GLuint texture_id,
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const AsyncTexImage2DParams& define_params) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new AsyncPixelTransferStateImpl(texture_id);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncPixelTransferState* transfer_state,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncTexImage2DParams& tex_params,
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncMemoryParams& mem_params,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& bind_callback) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AsyncPixelTransferStateImpl* state =
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<AsyncPixelTransferStateImpl*>(transfer_state);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(mem_params.shared_memory);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mem_params.shm_size);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      state->id(),
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &AsyncPixelTransferStateImpl::PerformTransfer,
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::AsWeakPtr(state),
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::Bind(
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              &AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              AsWeakPtr(),
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              tex_params,
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              mem_params,
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              bind_callback,
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     mem_params.shared_memory,
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     mem_params.shm_size))))));
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->set_transfer_in_progress(true);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncPixelTransferState* transfer_state,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncTexSubImage2DParams& tex_params,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AsyncMemoryParams& mem_params) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AsyncPixelTransferStateImpl* state =
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<AsyncPixelTransferStateImpl*>(transfer_state);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(mem_params.shared_memory);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mem_params.shm_size);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      state->id(),
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &AsyncPixelTransferStateImpl::PerformTransfer,
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::AsWeakPtr(state),
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::Bind(
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              &AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              AsWeakPtr(),
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              tex_params,
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              mem_params,
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     mem_params.shared_memory,
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                     mem_params.shm_size))))));
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->set_transfer_in_progress(true);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::WaitForTransferCompletion(
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncPixelTransferState* transfer_state) {
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AsyncPixelTransferStateImpl* state =
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<AsyncPixelTransferStateImpl*>(transfer_state);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(state);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (std::list<AsyncPixelTransferManagerIdle::Task>::iterator iter =
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           shared_state_->tasks.begin();
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != shared_state_->tasks.end();
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++iter) {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter->transfer_id != state->id())
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter).task.Run();
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    shared_state_->tasks.erase(iter);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    break;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->ProcessNotificationTasks();
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncTexImage2DParams tex_params,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncMemoryParams mem_params,
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& bind_callback,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedSafeSharedMemory* safe_shared_memory,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLuint texture_id) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "width", tex_params.width,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "height", tex_params.height);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void* data = GetAddress(safe_shared_memory, mem_params);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("gpu", "glTexImage2D");
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexImage2D(
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.target,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.level,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.internal_format,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.width,
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.height,
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.border,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.format,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.type,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        data);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The texture is already fully bound so just call it now.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bind_callback.Run();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncTexSubImage2DParams tex_params,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncMemoryParams mem_params,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedSafeSharedMemory* safe_shared_memory,
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLuint texture_id) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "width", tex_params.width,
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "height", tex_params.height);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void* data = GetAddress(safe_shared_memory, mem_params);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks begin_time(base::TimeTicks::HighResNow());
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("gpu", "glTexSubImage2D");
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexSubImage2D(
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.target,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.level,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.xoffset,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.yoffset,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.width,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.height,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.format,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tex_params.type,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        data);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->texture_upload_count++;
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_->total_texture_upload_time +=
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::TimeTicks::HighResNow() - begin_time;
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::Task::Task(
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint64 transfer_id, const base::Closure& task)
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : transfer_id(transfer_id),
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      task(task) {
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::Task::~Task() {}
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::SharedState::SharedState()
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : texture_upload_count(0) {}
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::SharedState::~SharedState() {}
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::SharedState::ProcessNotificationTasks() {
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  while (!tasks.empty()) {
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Stop when we reach a pixel transfer task.
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (tasks.front().transfer_id)
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tasks.front().task.Run();
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tasks.pop_front();
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle()
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : shared_state_(),
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      delegate_(new AsyncPixelTransferDelegateIdle(&shared_state_)) {}
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::~AsyncPixelTransferManagerIdle() {}
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::BindCompletedAsyncTransfers() {
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Everything is already bound.
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::AsyncNotifyCompletion(
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const AsyncMemoryParams& mem_params,
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const CompletionCallback& callback) {
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (shared_state_.tasks.empty()) {
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback.Run(mem_params);
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.push_back(
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Task(0,  // 0 transfer_id for notification tasks.
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           base::Bind(
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               &PerformNotifyCompletion,
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               mem_params,
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                      mem_params.shared_memory,
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                      mem_params.shm_size)),
327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               callback)));
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint32 AsyncPixelTransferManagerIdle::GetTextureUploadCount() {
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return shared_state_.texture_upload_count;
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::TimeDelta AsyncPixelTransferManagerIdle::GetTotalTextureUploadTime() {
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return shared_state_.total_texture_upload_time;
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AsyncPixelTransferManagerIdle::ProcessMorePendingTransfers() {
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (shared_state_.tasks.empty())
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // First task should always be a pixel transfer task.
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(shared_state_.tasks.front().transfer_id);
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.front().task.Run();
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.tasks.pop_front();
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_state_.ProcessNotificationTasks();
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AsyncPixelTransferManagerIdle::NeedsProcessMorePendingTransfers() {
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return !shared_state_.tasks.empty();
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferDelegate*
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AsyncPixelTransferManagerIdle::GetAsyncPixelTransferDelegate() {
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return delegate_.get();
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace gpu
360