Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: ui/gl/async_pixel_transfer_delegate_android.cc

Issue 11659020: gpu: Report time spent performing async texture uploads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/async_pixel_transfer_delegate_android.h" 5 #include "ui/gl/async_pixel_transfer_delegate_android.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 return NULL; 63 return NULL;
64 scoped_ptr<SharedMemory> duped_shared_memory( 64 scoped_ptr<SharedMemory> duped_shared_memory(
65 new SharedMemory(duped_shared_memory_handle, false)); 65 new SharedMemory(duped_shared_memory_handle, false));
66 // Map the shared memory into this process. This validates the size. 66 // Map the shared memory into this process. This validates the size.
67 if (!duped_shared_memory->Map(size)) 67 if (!duped_shared_memory->Map(size))
68 return NULL; 68 return NULL;
69 return duped_shared_memory.release(); 69 return duped_shared_memory.release();
70 } 70 }
71 71
72 // Gets the address of the data from shared memory. 72 // Gets the address of the data from shared memory.
73 void* GetAddress(SharedMemory* shared_memory, 73 void* GetAddress(SharedMemory* shared_memory, uint32 shm_data_offset) {
74 uint32 shm_size,
75 uint32 shm_data_offset,
76 uint32 shm_data_size) {
77 // Memory bounds have already been validated, so there 74 // Memory bounds have already been validated, so there
78 // is just DCHECKS here. 75 // is just DCHECKS here.
79 DCHECK(shared_memory); 76 DCHECK(shared_memory);
80 DCHECK(shared_memory->memory()); 77 DCHECK(shared_memory->memory());
81 DCHECK_LE(shm_data_offset + shm_data_size, shm_size);
82 return static_cast<int8*>(shared_memory->memory()) + shm_data_offset; 78 return static_cast<int8*>(shared_memory->memory()) + shm_data_offset;
83 } 79 }
84 80
85 class TransferThread : public base::Thread { 81 class TransferThread : public base::Thread {
86 public: 82 public:
87 TransferThread() : base::Thread(kAsyncTransferThreadName) { 83 TransferThread() : base::Thread(kAsyncTransferThreadName) {
88 Start(); 84 Start();
89 } 85 }
90 virtual ~TransferThread() { 86 virtual ~TransferThread() {
91 Stop(); 87 Stop();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); 152 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
157 // We can only change the active texture and unit 0, 153 // We can only change the active texture and unit 0,
158 // as that is all that will be restored. 154 // as that is all that will be restored.
159 glActiveTexture(GL_TEXTURE0); 155 glActiveTexture(GL_TEXTURE0);
160 glBindTexture(GL_TEXTURE_2D, texture_id_); 156 glBindTexture(GL_TEXTURE_2D, texture_id_);
161 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_); 157 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_);
162 *bound_params = late_bind_define_params_; 158 *bound_params = late_bind_define_params_;
163 needs_late_bind_ = false; 159 needs_late_bind_ = false;
164 } 160 }
165 161
166 // Completion callbacks. 162 protected:
167 void TexImage2DCompleted() {
168 needs_late_bind_ = true;
169 transfer_in_progress_ = false;
170 }
171 void TexSubImage2DCompleted() {
172 transfer_in_progress_ = false;
173 }
174
175 protected:
176 friend class base::RefCountedThreadSafe<TransferStateInternal>; 163 friend class base::RefCountedThreadSafe<TransferStateInternal>;
177 friend class AsyncPixelTransferDelegateAndroid; 164 friend class AsyncPixelTransferDelegateAndroid;
178 165
179 static void DeleteTexture(GLuint id) { 166 static void DeleteTexture(GLuint id) {
180 glDeleteTextures(1, &id); 167 glDeleteTextures(1, &id);
181 } 168 }
182 169
183 virtual ~TransferStateInternal() { 170 virtual ~TransferStateInternal() {
184 if (egl_image_) { 171 if (egl_image_) {
185 EGLDisplay display = eglGetCurrentDisplay(); 172 EGLDisplay display = eglGetCurrentDisplay();
(...skipping 18 matching lines...) Expand all
204 // Definition params for texture that needs binding. 191 // Definition params for texture that needs binding.
205 AsyncTexImage2DParams late_bind_define_params_; 192 AsyncTexImage2DParams late_bind_define_params_;
206 193
207 // Indicates that an async transfer is in progress. 194 // Indicates that an async transfer is in progress.
208 bool transfer_in_progress_; 195 bool transfer_in_progress_;
209 196
210 // It would be nice if we could just create a new EGLImage for 197 // It would be nice if we could just create a new EGLImage for
211 // every upload, but I found that didn't work, so this stores 198 // every upload, but I found that didn't work, so this stores
212 // one for the lifetime of the texture. 199 // one for the lifetime of the texture.
213 EGLImageKHR egl_image_; 200 EGLImageKHR egl_image_;
201
202 // Time spent performing last transfer.
203 base::TimeDelta last_transfer_time_;
214 }; 204 };
215 205
216 // Android needs thread-safe ref-counting, so this just wraps 206 // Android needs thread-safe ref-counting, so this just wraps
217 // an internal thread-safe ref-counted state object. 207 // an internal thread-safe ref-counted state object.
218 class AsyncTransferStateAndroid : public AsyncPixelTransferState { 208 class AsyncTransferStateAndroid : public AsyncPixelTransferState {
219 public: 209 public:
220 explicit AsyncTransferStateAndroid(GLuint texture_id) 210 explicit AsyncTransferStateAndroid(GLuint texture_id)
221 : internal_(new TransferStateInternal(texture_id)) { 211 : internal_(new TransferStateInternal(texture_id)) {
222 } 212 }
223 virtual ~AsyncTransferStateAndroid() {} 213 virtual ~AsyncTransferStateAndroid() {}
224 virtual bool TransferIsInProgress() { 214 virtual bool TransferIsInProgress() {
225 return internal_->TransferIsInProgress(); 215 return internal_->TransferIsInProgress();
226 } 216 }
227 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) { 217 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) {
228 internal_->BindTransfer(bound_params); 218 internal_->BindTransfer(bound_params);
229 } 219 }
230 scoped_refptr<TransferStateInternal> internal_; 220 scoped_refptr<TransferStateInternal> internal_;
231 }; 221 };
232 222
233 // Class which handles async pixel transfers on Android (using 223 // Class which handles async pixel transfers on Android (using
234 // EGLImageKHR and another upload thread) 224 // EGLImageKHR and another upload thread)
235 class AsyncPixelTransferDelegateAndroid : public AsyncPixelTransferDelegate { 225 class AsyncPixelTransferDelegateAndroid
226 : public AsyncPixelTransferDelegate,
227 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> {
236 public: 228 public:
237 AsyncPixelTransferDelegateAndroid() {} 229 AsyncPixelTransferDelegateAndroid();
238 virtual ~AsyncPixelTransferDelegateAndroid() {} 230 virtual ~AsyncPixelTransferDelegateAndroid();
239 231
240 // implement AsyncPixelTransferDelegate: 232 // implement AsyncPixelTransferDelegate:
241 virtual void AsyncNotifyCompletion( 233 virtual void AsyncNotifyCompletion(
242 const base::Closure& task) OVERRIDE; 234 const base::Closure& task) OVERRIDE;
243 virtual void AsyncTexImage2D( 235 virtual void AsyncTexImage2D(
244 AsyncPixelTransferState* state, 236 AsyncPixelTransferState* state,
245 const AsyncTexImage2DParams& tex_params, 237 const AsyncTexImage2DParams& tex_params,
246 const AsyncMemoryParams& mem_params) OVERRIDE; 238 const AsyncMemoryParams& mem_params) OVERRIDE;
247 virtual void AsyncTexSubImage2D( 239 virtual void AsyncTexSubImage2D(
248 AsyncPixelTransferState* state, 240 AsyncPixelTransferState* state,
249 const AsyncTexSubImage2DParams& tex_params, 241 const AsyncTexSubImage2DParams& tex_params,
250 const AsyncMemoryParams& mem_params) OVERRIDE; 242 const AsyncMemoryParams& mem_params) OVERRIDE;
243 virtual uint32 GetTextureUploadCount() OVERRIDE;
244 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
251 245
252 private: 246 private:
253 // implement AsyncPixelTransferDelegate: 247 // implement AsyncPixelTransferDelegate:
254 virtual AsyncPixelTransferState* 248 virtual AsyncPixelTransferState*
255 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE; 249 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE;
256 250
251 void AsyncTexImage2DCompleted(scoped_refptr<TransferStateInternal> state);
252 void AsyncTexSubImage2DCompleted(scoped_refptr<TransferStateInternal> state);
253
257 static void PerformAsyncTexImage2D( 254 static void PerformAsyncTexImage2D(
258 TransferStateInternal* state, 255 TransferStateInternal* state,
259 AsyncTexImage2DParams tex_params, 256 AsyncTexImage2DParams tex_params,
260 AsyncMemoryParams mem_params); 257 base::SharedMemory* shared_memory,
258 uint32 shared_memory_data_offset);
261 static void PerformAsyncTexSubImage2D( 259 static void PerformAsyncTexSubImage2D(
262 TransferStateInternal* state, 260 TransferStateInternal* state,
263 AsyncTexSubImage2DParams tex_params, 261 AsyncTexSubImage2DParams tex_params,
264 AsyncMemoryParams mem_params); 262 base::SharedMemory* shared_memory,
263 uint32 shared_memory_data_offset);
264
265 int texture_upload_count_;
266 base::TimeDelta total_texture_upload_time_;
265 267
266 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateAndroid); 268 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateAndroid);
267 }; 269 };
268 270
269 namespace { 271 namespace {
270 // Imagination has some odd problems still. 272 // Imagination has some odd problems still.
271 bool IsImagination() { 273 bool IsImagination() {
272 std::string vendor; 274 std::string vendor;
273 vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); 275 vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
274 return vendor.find("Imagination") != std::string::npos; 276 return vendor.find("Imagination") != std::string::npos;
(...skipping 17 matching lines...) Expand all
292 static_cast<AsyncPixelTransferDelegate*>( 294 static_cast<AsyncPixelTransferDelegate*>(
293 new AsyncPixelTransferDelegateAndroid())); 295 new AsyncPixelTransferDelegateAndroid()));
294 } else { 296 } else {
295 LOG(INFO) << "Async pixel transfers not supported"; 297 LOG(INFO) << "Async pixel transfers not supported";
296 return make_scoped_ptr( 298 return make_scoped_ptr(
297 static_cast<AsyncPixelTransferDelegate*>( 299 static_cast<AsyncPixelTransferDelegate*>(
298 new AsyncPixelTransferDelegateStub())); 300 new AsyncPixelTransferDelegateStub()));
299 } 301 }
300 } 302 }
301 303
304 AsyncPixelTransferDelegateAndroid::AsyncPixelTransferDelegateAndroid()
305 : texture_upload_count_(0) {
306 }
307
308 AsyncPixelTransferDelegateAndroid::~AsyncPixelTransferDelegateAndroid() {
309 }
310
302 AsyncPixelTransferState* 311 AsyncPixelTransferState*
303 AsyncPixelTransferDelegateAndroid:: 312 AsyncPixelTransferDelegateAndroid::
304 CreateRawPixelTransferState(GLuint texture_id) { 313 CreateRawPixelTransferState(GLuint texture_id) {
305 return static_cast<AsyncPixelTransferState*>( 314 return static_cast<AsyncPixelTransferState*>(
306 new AsyncTransferStateAndroid(texture_id)); 315 new AsyncTransferStateAndroid(texture_id));
307 } 316 }
308 317
309 namespace { 318 namespace {
310 // Dummy function to measure completion on 319 // Dummy function to measure completion on
311 // the upload thread. 320 // the upload thread.
312 void NoOp() {} 321 void NoOp() {}
313 } // namespace 322 } // namespace
314 323
315 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion( 324 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion(
316 const base::Closure& task) { 325 const base::Closure& task) {
317 // Post a no-op task to the upload thread followed 326 // Post a no-op task to the upload thread followed
318 // by a reply to the callback. The reply will then occur after 327 // by a reply to the callback. The reply will then occur after
319 // all async transfers are complete. 328 // all async transfers are complete.
320 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 329 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE,
321 base::Bind(&NoOp), task); 330 base::Bind(&NoOp), task);
322 } 331 }
323 332
324 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D( 333 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D(
325 AsyncPixelTransferState* transfer_state, 334 AsyncPixelTransferState* transfer_state,
326 const AsyncTexImage2DParams& tex_params, 335 const AsyncTexImage2DParams& tex_params,
327 const AsyncMemoryParams& mem_params) { 336 const AsyncMemoryParams& mem_params) {
328 TransferStateInternal* state = 337 scoped_refptr<TransferStateInternal> state =
329 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); 338 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
330 DCHECK(mem_params.shared_memory); 339 DCHECK(mem_params.shared_memory);
340 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
341 mem_params.shm_size);
331 DCHECK(state); 342 DCHECK(state);
332 DCHECK(state->texture_id_); 343 DCHECK(state->texture_id_);
333 DCHECK(!state->needs_late_bind_); 344 DCHECK(!state->needs_late_bind_);
334 DCHECK(!state->transfer_in_progress_); 345 DCHECK(!state->transfer_in_progress_);
335 DCHECK_EQ(state->egl_image_, EGL_NO_IMAGE_KHR); 346 DCHECK_EQ(state->egl_image_, EGL_NO_IMAGE_KHR);
336 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target); 347 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
337 DCHECK_EQ(tex_params.level, 0); 348 DCHECK_EQ(tex_params.level, 0);
338 349
339 // Mark the transfer in progress and save define params for lazy binding. 350 // Mark the transfer in progress and save define params for lazy binding.
340 state->transfer_in_progress_ = true; 351 state->transfer_in_progress_ = true;
341 state->late_bind_define_params_ = tex_params; 352 state->late_bind_define_params_ = tex_params;
342 353
343 // Duplicate the shared memory so there are no way we can get 354 // Duplicate the shared memory so there are no way we can get
344 // a use-after-free of the raw pixels. 355 // a use-after-free of the raw pixels.
345 // TODO: Could we pass an own pointer of the new SharedMemory to the task?
346 AsyncMemoryParams duped_mem = mem_params;
347 duped_mem.shared_memory = DuplicateSharedMemory(mem_params.shared_memory,
348 mem_params.shm_size);
349 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 356 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE,
350 base::Bind( 357 base::Bind(
351 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D, 358 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D,
352 base::Unretained(state), // This is referenced in reply below. 359 base::Unretained(state.get()), // This is referenced in reply below.
353 tex_params, 360 tex_params,
354 duped_mem), 361 base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
362 mem_params.shm_size)),
363 mem_params.shm_data_offset),
355 base::Bind( 364 base::Bind(
356 &TransferStateInternal::TexImage2DCompleted, 365 &AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted,
366 AsWeakPtr(),
357 state)); 367 state));
358 368
359 DCHECK(CHECK_GL()); 369 DCHECK(CHECK_GL());
360 } 370 }
361 371
362 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D( 372 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D(
363 AsyncPixelTransferState* transfer_state, 373 AsyncPixelTransferState* transfer_state,
364 const AsyncTexSubImage2DParams& tex_params, 374 const AsyncTexSubImage2DParams& tex_params,
365 const AsyncMemoryParams& mem_params) { 375 const AsyncMemoryParams& mem_params) {
366 TRACE_EVENT2("gpu", "AsyncTexSubImage2D", 376 TRACE_EVENT2("gpu", "AsyncTexSubImage2D",
367 "width", tex_params.width, 377 "width", tex_params.width,
368 "height", tex_params.height); 378 "height", tex_params.height);
369 TransferStateInternal* state = 379 scoped_refptr<TransferStateInternal> state =
370 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); 380 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
371 DCHECK(state->texture_id_); 381 DCHECK(state->texture_id_);
372 DCHECK(!state->transfer_in_progress_); 382 DCHECK(!state->transfer_in_progress_);
373 DCHECK(mem_params.shared_memory); 383 DCHECK(mem_params.shared_memory);
384 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
385 mem_params.shm_size);
374 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target); 386 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
375 DCHECK_EQ(tex_params.level, 0); 387 DCHECK_EQ(tex_params.level, 0);
376 388
377 // Mark the transfer in progress. 389 // Mark the transfer in progress.
378 state->transfer_in_progress_ = true; 390 state->transfer_in_progress_ = true;
379 391
380 // Create the EGLImage if it hasn't already been created. 392 // Create the EGLImage if it hasn't already been created.
381 if (!state->egl_image_) { 393 if (!state->egl_image_) {
382 TRACE_EVENT0("gpu", "eglCreateImageKHR"); 394 TRACE_EVENT0("gpu", "eglCreateImageKHR");
383 EGLDisplay egl_display = eglGetCurrentDisplay(); 395 EGLDisplay egl_display = eglGetCurrentDisplay();
384 EGLContext egl_context = eglGetCurrentContext(); 396 EGLContext egl_context = eglGetCurrentContext();
385 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; 397 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR;
386 EGLClientBuffer egl_buffer = 398 EGLClientBuffer egl_buffer =
387 reinterpret_cast<EGLClientBuffer>(state->texture_id_); 399 reinterpret_cast<EGLClientBuffer>(state->texture_id_);
388 EGLint egl_attrib_list[] = { 400 EGLint egl_attrib_list[] = {
389 EGL_GL_TEXTURE_LEVEL_KHR, tex_params.level, // mip-level to reference. 401 EGL_GL_TEXTURE_LEVEL_KHR, tex_params.level, // mip-level to reference.
390 EGL_IMAGE_PRESERVED_KHR, EGL_FALSE, // throw away texture data. 402 EGL_IMAGE_PRESERVED_KHR, EGL_FALSE, // throw away texture data.
391 EGL_NONE 403 EGL_NONE
392 }; 404 };
393 state->egl_image_ = eglCreateImageKHR( 405 state->egl_image_ = eglCreateImageKHR(
394 egl_display, 406 egl_display,
395 egl_context, 407 egl_context,
396 egl_target, 408 egl_target,
397 egl_buffer, 409 egl_buffer,
398 egl_attrib_list); 410 egl_attrib_list);
399 } 411 }
400 412
401 // Duplicate the shared memory so there are no way we can get 413 // Duplicate the shared memory so there are no way we can get
402 // a use-after-free of the raw pixels. 414 // a use-after-free of the raw pixels.
403 // TODO: Could we pass an own pointer of the new SharedMemory to the task?
404 AsyncMemoryParams duped_mem = mem_params;
405 duped_mem.shared_memory = DuplicateSharedMemory(mem_params.shared_memory,
406 mem_params.shm_size);
407 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 415 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE,
408 base::Bind( 416 base::Bind(
409 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D, 417 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D,
410 base::Unretained(state), // This is referenced in reply below. 418 base::Unretained(state.get()), // This is referenced in reply below.
411 tex_params, 419 tex_params,
412 duped_mem), 420 base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
421 mem_params.shm_size)),
422 mem_params.shm_data_offset),
413 base::Bind( 423 base::Bind(
414 &TransferStateInternal::TexSubImage2DCompleted, 424 &AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted,
425 AsWeakPtr(),
415 state)); 426 state));
416 427
417 DCHECK(CHECK_GL()); 428 DCHECK(CHECK_GL());
418 } 429 }
419 430
431 uint32 AsyncPixelTransferDelegateAndroid::GetTextureUploadCount() {
432 return texture_upload_count_;
433 }
434
435 base::TimeDelta AsyncPixelTransferDelegateAndroid::GetTotalTextureUploadTime() {
436 return total_texture_upload_time_;
437 }
438
439 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted(
440 scoped_refptr<TransferStateInternal> state) {
441 state->needs_late_bind_ = true;
442 state->transfer_in_progress_ = false;
443 }
444
445 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted(
446 scoped_refptr<TransferStateInternal> state) {
447 state->transfer_in_progress_ = false;
448 texture_upload_count_++;
449 total_texture_upload_time_ += state->last_transfer_time_;
450 }
451
420 namespace { 452 namespace {
421 void WaitForGl() { 453 void WaitForGl() {
422 TRACE_EVENT0("gpu", "eglWaitSync"); 454 TRACE_EVENT0("gpu", "eglWaitSync");
423 455
424 // Uploads usually finish on the CPU, but just in case add a fence 456 // Uploads usually finish on the CPU, but just in case add a fence
425 // and guarantee the upload has completed. The flush bit is set to 457 // and guarantee the upload has completed. The flush bit is set to
426 // insure we don't wait forever. 458 // insure we don't wait forever.
427 EGLDisplay display = eglGetCurrentDisplay(); 459 EGLDisplay display = eglGetCurrentDisplay();
428 EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL); 460 EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
429 EGLint flags = EGL_SYNC_FLUSH_COMMANDS_BIT_KHR; 461 EGLint flags = EGL_SYNC_FLUSH_COMMANDS_BIT_KHR;
430 EGLTimeKHR time = EGL_FOREVER_KHR; 462 EGLTimeKHR time = EGL_FOREVER_KHR;
431 463
432 // This fence is basically like calling glFinish, which is fine if 464 // This fence is basically like calling glFinish, which is fine if
433 // uploads occur on the CPU. If some upload work occurs on the GPU, 465 // uploads occur on the CPU. If some upload work occurs on the GPU,
434 // we may want to delay blocking on the fence. 466 // we may want to delay blocking on the fence.
435 eglClientWaitSyncKHR(display, fence, flags, time); 467 eglClientWaitSyncKHR(display, fence, flags, time);
436 eglDestroySyncKHR(display, fence); 468 eglDestroySyncKHR(display, fence);
437 } 469 }
438 } // namespace 470 } // namespace
439 471
440 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D( 472 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D(
441 TransferStateInternal* state, 473 TransferStateInternal* state,
442 AsyncTexImage2DParams tex_params, 474 AsyncTexImage2DParams tex_params,
443 AsyncMemoryParams mem_params) { 475 base::SharedMemory* shared_memory,
476 uint32 shared_memory_data_offset) {
444 TRACE_EVENT2("gpu", "PerformAsyncTexImage", 477 TRACE_EVENT2("gpu", "PerformAsyncTexImage",
445 "width", tex_params.width, 478 "width", tex_params.width,
446 "height", tex_params.height); 479 "height", tex_params.height);
447 DCHECK(state); 480 DCHECK(state);
448 DCHECK(!state->thread_texture_id_); 481 DCHECK(!state->thread_texture_id_);
449 DCHECK_EQ(0, tex_params.level); 482 DCHECK_EQ(0, tex_params.level);
450 DCHECK_EQ(EGL_NO_IMAGE_KHR, state->egl_image_); 483 DCHECK_EQ(EGL_NO_IMAGE_KHR, state->egl_image_);
451 484
452 // TODO(epenner): This is just to insure it is deleted. Could bind() do this? 485 void* data = GetAddress(shared_memory, shared_memory_data_offset);
453 scoped_ptr<SharedMemory> shared_memory =
454 make_scoped_ptr(mem_params.shared_memory);
455
456 void* data = GetAddress(mem_params.shared_memory,
457 mem_params.shm_size,
458 mem_params.shm_data_offset,
459 mem_params.shm_data_size);
460 { 486 {
461 TRACE_EVENT0("gpu", "glTexImage2D no data"); 487 TRACE_EVENT0("gpu", "glTexImage2D no data");
462 glGenTextures(1, &state->thread_texture_id_); 488 glGenTextures(1, &state->thread_texture_id_);
463 glActiveTexture(GL_TEXTURE0); 489 glActiveTexture(GL_TEXTURE0);
464 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_); 490 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_);
465 491
466 // These params are needed for EGLImage creation to succeed on several 492 // These params are needed for EGLImage creation to succeed on several
467 // Android devices. I couldn't find this requirement in the EGLImage 493 // Android devices. I couldn't find this requirement in the EGLImage
468 // extension spec, but several devices fail without it. 494 // extension spec, but several devices fail without it.
469 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 data); 542 data);
517 } 543 }
518 544
519 WaitForGl(); 545 WaitForGl();
520 DCHECK(CHECK_GL()); 546 DCHECK(CHECK_GL());
521 } 547 }
522 548
523 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D( 549 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D(
524 TransferStateInternal* state, 550 TransferStateInternal* state,
525 AsyncTexSubImage2DParams tex_params, 551 AsyncTexSubImage2DParams tex_params,
526 AsyncMemoryParams mem_params) { 552 base::SharedMemory* shared_memory,
553 uint32 shared_memory_data_offset) {
527 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D", 554 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
528 "width", tex_params.width, 555 "width", tex_params.width,
529 "height", tex_params.height); 556 "height", tex_params.height);
530 557
531 DCHECK(state); 558 DCHECK(state);
532 DCHECK_NE(EGL_NO_IMAGE_KHR, state->egl_image_); 559 DCHECK_NE(EGL_NO_IMAGE_KHR, state->egl_image_);
533 DCHECK_EQ(0, tex_params.level); 560 DCHECK_EQ(0, tex_params.level);
534 561
535 // TODO(epenner): This is just to insure it is deleted. Could bind() do this? 562 void* data = GetAddress(shared_memory, shared_memory_data_offset);
536 scoped_ptr<SharedMemory> shared_memory =
537 make_scoped_ptr(mem_params.shared_memory);
538 563
539 void* data = GetAddress(mem_params.shared_memory, 564 base::TimeTicks begin_time(base::TimeTicks::HighResNow());
540 mem_params.shm_size,
541 mem_params.shm_data_offset,
542 mem_params.shm_data_size);
543
544 if (!state->thread_texture_id_) { 565 if (!state->thread_texture_id_) {
545 TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES"); 566 TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES");
546 glGenTextures(1, &state->thread_texture_id_); 567 glGenTextures(1, &state->thread_texture_id_);
547 glActiveTexture(GL_TEXTURE0); 568 glActiveTexture(GL_TEXTURE0);
548 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_); 569 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_);
549 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, state->egl_image_); 570 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, state->egl_image_);
550 } else { 571 } else {
551 glActiveTexture(GL_TEXTURE0); 572 glActiveTexture(GL_TEXTURE0);
552 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_); 573 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_);
553 } 574 }
554 { 575 {
555 TRACE_EVENT0("gpu", "glTexSubImage2D"); 576 TRACE_EVENT0("gpu", "glTexSubImage2D");
556 glTexSubImage2D( 577 glTexSubImage2D(
557 GL_TEXTURE_2D, 578 GL_TEXTURE_2D,
558 tex_params.level, 579 tex_params.level,
559 tex_params.xoffset, 580 tex_params.xoffset,
560 tex_params.yoffset, 581 tex_params.yoffset,
561 tex_params.width, 582 tex_params.width,
562 tex_params.height, 583 tex_params.height,
563 tex_params.format, 584 tex_params.format,
564 tex_params.type, 585 tex_params.type,
565 data); 586 data);
566 } 587 }
567 WaitForGl(); 588 WaitForGl();
568 589
569 DCHECK(CHECK_GL()); 590 DCHECK(CHECK_GL());
591 state->last_transfer_time_ = base::TimeTicks::HighResNow() - begin_time;
570 } 592 }
571 593
572 } // namespace gfx 594 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698