Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / gpu / command_buffer / service / async_pixel_transfer_manager_idle.cc
blobb555ebb60bc7c638760dfdb235781ca6f66356d8
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h"
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/trace_event/trace_event.h"
11 #include "base/trace_event/trace_event_synthetic_delay.h"
12 #include "ui/gl/scoped_binders.h"
14 namespace gpu {
16 namespace {
18 static uint64 g_next_pixel_transfer_state_id = 1;
20 void PerformNotifyCompletion(
21 AsyncMemoryParams mem_params,
22 scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
23 TRACE_EVENT0("gpu", "PerformNotifyCompletion");
24 observer->DidComplete(mem_params);
27 } // namespace
29 // Class which handles async pixel transfers in a platform
30 // independent way.
31 class AsyncPixelTransferDelegateIdle
32 : public AsyncPixelTransferDelegate,
33 public base::SupportsWeakPtr<AsyncPixelTransferDelegateIdle> {
34 public:
35 typedef base::Callback<GLuint()> TextureIdCallback;
36 AsyncPixelTransferDelegateIdle(
37 AsyncPixelTransferManagerIdle::SharedState* state,
38 const TextureIdCallback& texture_id_callback,
39 const AsyncTexImage2DParams& define_params);
40 ~AsyncPixelTransferDelegateIdle() override;
42 // Implement AsyncPixelTransferDelegate:
43 void AsyncTexImage2D(const AsyncTexImage2DParams& tex_params,
44 const AsyncMemoryParams& mem_params,
45 const base::Closure& bind_callback) override;
46 void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
47 const AsyncMemoryParams& mem_params) override;
48 bool TransferIsInProgress() override;
49 void WaitForTransferCompletion() override;
51 private:
52 void PerformAsyncTexImage2D(AsyncTexImage2DParams tex_params,
53 AsyncMemoryParams mem_params,
54 const base::Closure& bind_callback);
55 void PerformAsyncTexSubImage2D(AsyncTexSubImage2DParams tex_params,
56 AsyncMemoryParams mem_params);
58 uint64 id_;
59 TextureIdCallback texture_id_callback_;
60 bool transfer_in_progress_;
61 AsyncTexImage2DParams define_params_;
63 // Safe to hold a raw pointer because SharedState is owned by the Manager
64 // which owns the Delegate.
65 AsyncPixelTransferManagerIdle::SharedState* shared_state_;
67 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateIdle);
70 AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle(
71 AsyncPixelTransferManagerIdle::SharedState* shared_state,
72 const TextureIdCallback& texture_id_callback,
73 const AsyncTexImage2DParams& define_params)
74 : id_(g_next_pixel_transfer_state_id++),
75 texture_id_callback_(texture_id_callback),
76 transfer_in_progress_(false),
77 define_params_(define_params),
78 shared_state_(shared_state) {}
80 AsyncPixelTransferDelegateIdle::~AsyncPixelTransferDelegateIdle() {}
82 void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
83 const AsyncTexImage2DParams& tex_params,
84 const AsyncMemoryParams& mem_params,
85 const base::Closure& bind_callback) {
86 TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
87 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
89 shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
90 id_,
91 this,
92 base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
93 AsWeakPtr(),
94 tex_params,
95 mem_params,
96 bind_callback)));
98 transfer_in_progress_ = true;
101 void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
102 const AsyncTexSubImage2DParams& tex_params,
103 const AsyncMemoryParams& mem_params) {
104 TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
105 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
107 shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
108 id_,
109 this,
110 base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
111 AsWeakPtr(),
112 tex_params,
113 mem_params)));
115 transfer_in_progress_ = true;
118 bool AsyncPixelTransferDelegateIdle::TransferIsInProgress() {
119 return transfer_in_progress_;
122 void AsyncPixelTransferDelegateIdle::WaitForTransferCompletion() {
123 for (std::list<AsyncPixelTransferManagerIdle::Task>::iterator iter =
124 shared_state_->tasks.begin();
125 iter != shared_state_->tasks.end();
126 ++iter) {
127 if (iter->transfer_id != id_)
128 continue;
130 (*iter).task.Run();
131 shared_state_->tasks.erase(iter);
132 break;
135 shared_state_->ProcessNotificationTasks();
138 void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
139 AsyncTexImage2DParams tex_params,
140 AsyncMemoryParams mem_params,
141 const base::Closure& bind_callback) {
142 TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
143 "width", tex_params.width,
144 "height", tex_params.height);
146 void* data = mem_params.GetDataAddress();
148 base::TimeTicks begin_time(base::TimeTicks::Now());
149 gfx::ScopedTextureBinder texture_binder(tex_params.target,
150 texture_id_callback_.Run());
153 TRACE_EVENT0("gpu", "glTexImage2D");
154 glTexImage2D(
155 tex_params.target,
156 tex_params.level,
157 tex_params.internal_format,
158 tex_params.width,
159 tex_params.height,
160 tex_params.border,
161 tex_params.format,
162 tex_params.type,
163 data);
166 TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
167 transfer_in_progress_ = false;
168 shared_state_->texture_upload_count++;
169 shared_state_->total_texture_upload_time +=
170 base::TimeTicks::Now() - begin_time;
172 // The texture is already fully bound so just call it now.
173 bind_callback.Run();
176 void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
177 AsyncTexSubImage2DParams tex_params,
178 AsyncMemoryParams mem_params) {
179 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
180 "width", tex_params.width,
181 "height", tex_params.height);
183 void* data = mem_params.GetDataAddress();
185 base::TimeTicks begin_time(base::TimeTicks::Now());
186 gfx::ScopedTextureBinder texture_binder(tex_params.target,
187 texture_id_callback_.Run());
189 if (shared_state_->use_teximage2d_over_texsubimage2d &&
190 tex_params.xoffset == 0 &&
191 tex_params.yoffset == 0 &&
192 tex_params.target == define_params_.target &&
193 tex_params.level == define_params_.level &&
194 tex_params.width == define_params_.width &&
195 tex_params.height == define_params_.height) {
196 TRACE_EVENT0("gpu", "glTexImage2D");
197 glTexImage2D(
198 define_params_.target,
199 define_params_.level,
200 define_params_.internal_format,
201 define_params_.width,
202 define_params_.height,
203 define_params_.border,
204 tex_params.format,
205 tex_params.type,
206 data);
207 } else {
208 TRACE_EVENT0("gpu", "glTexSubImage2D");
209 glTexSubImage2D(
210 tex_params.target,
211 tex_params.level,
212 tex_params.xoffset,
213 tex_params.yoffset,
214 tex_params.width,
215 tex_params.height,
216 tex_params.format,
217 tex_params.type,
218 data);
221 TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
222 transfer_in_progress_ = false;
223 shared_state_->texture_upload_count++;
224 shared_state_->total_texture_upload_time +=
225 base::TimeTicks::Now() - begin_time;
228 AsyncPixelTransferManagerIdle::Task::Task(
229 uint64 transfer_id,
230 AsyncPixelTransferDelegate* delegate,
231 const base::Closure& task)
232 : transfer_id(transfer_id),
233 delegate(delegate),
234 task(task) {
237 AsyncPixelTransferManagerIdle::Task::~Task() {}
239 AsyncPixelTransferManagerIdle::SharedState::SharedState(
240 bool use_teximage2d_over_texsubimage2d)
241 : use_teximage2d_over_texsubimage2d(use_teximage2d_over_texsubimage2d),
242 texture_upload_count(0) {
245 AsyncPixelTransferManagerIdle::SharedState::~SharedState() {}
247 void AsyncPixelTransferManagerIdle::SharedState::ProcessNotificationTasks() {
248 while (!tasks.empty()) {
249 // Stop when we reach a pixel transfer task.
250 if (tasks.front().transfer_id)
251 return;
253 tasks.front().task.Run();
254 tasks.pop_front();
258 AsyncPixelTransferManagerIdle::AsyncPixelTransferManagerIdle(
259 bool use_teximage2d_over_texsubimage2d)
260 : shared_state_(use_teximage2d_over_texsubimage2d) {
263 AsyncPixelTransferManagerIdle::~AsyncPixelTransferManagerIdle() {}
265 void AsyncPixelTransferManagerIdle::BindCompletedAsyncTransfers() {
266 // Everything is already bound.
269 void AsyncPixelTransferManagerIdle::AsyncNotifyCompletion(
270 const AsyncMemoryParams& mem_params,
271 AsyncPixelTransferCompletionObserver* observer) {
272 if (shared_state_.tasks.empty()) {
273 observer->DidComplete(mem_params);
274 return;
277 shared_state_.tasks.push_back(
278 Task(0, // 0 transfer_id for notification tasks.
279 NULL,
280 base::Bind(
281 &PerformNotifyCompletion,
282 mem_params,
283 make_scoped_refptr(observer))));
286 uint32 AsyncPixelTransferManagerIdle::GetTextureUploadCount() {
287 return shared_state_.texture_upload_count;
290 base::TimeDelta AsyncPixelTransferManagerIdle::GetTotalTextureUploadTime() {
291 return shared_state_.total_texture_upload_time;
294 void AsyncPixelTransferManagerIdle::ProcessMorePendingTransfers() {
295 if (shared_state_.tasks.empty())
296 return;
298 // First task should always be a pixel transfer task.
299 DCHECK(shared_state_.tasks.front().transfer_id);
300 shared_state_.tasks.front().task.Run();
301 shared_state_.tasks.pop_front();
303 shared_state_.ProcessNotificationTasks();
306 bool AsyncPixelTransferManagerIdle::NeedsProcessMorePendingTransfers() {
307 return !shared_state_.tasks.empty();
310 void AsyncPixelTransferManagerIdle::WaitAllAsyncTexImage2D() {
311 if (shared_state_.tasks.empty())
312 return;
314 const Task& task = shared_state_.tasks.back();
315 if (task.delegate)
316 task.delegate->WaitForTransferCompletion();
319 AsyncPixelTransferDelegate*
320 AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl(
321 gles2::TextureRef* ref,
322 const AsyncTexImage2DParams& define_params) {
323 return new AsyncPixelTransferDelegateIdle(
324 &shared_state_,
325 // Not directly passing texture_ref->service_id here because it can change
326 // if avoid_egl_image_target_texture_reuse workaround is in effect.
327 // Unretained is safe because AsyncPixelTransferManager observes
328 // TextureRef destruction and destroys the delegate before TextureRef
329 // is destroyed.
330 base::Bind(&gles2::TextureRef::service_id, base::Unretained(ref)),
331 define_params);
334 } // namespace gpu