OLD | NEW |
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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 126 |
127 base::MessageLoopProxy* transfer_message_loop_proxy() { | 127 base::MessageLoopProxy* transfer_message_loop_proxy() { |
128 return g_transfer_thread.Pointer()->message_loop_proxy(); | 128 return g_transfer_thread.Pointer()->message_loop_proxy(); |
129 } | 129 } |
130 | 130 |
131 } // namespace | 131 } // namespace |
132 | 132 |
133 // Class which holds async pixel transfers state (EGLImage). | 133 // Class which holds async pixel transfers state (EGLImage). |
134 // The EGLImage is accessed by either thread, but everything | 134 // The EGLImage is accessed by either thread, but everything |
135 // else accessed only on the main thread. | 135 // else accessed only on the main thread. |
136 class TransferStateInternal | 136 class TransferStateInternal : public base::RefCounted<TransferStateInternal> { |
137 : public base::RefCountedThreadSafe<TransferStateInternal> { | |
138 public: | 137 public: |
139 explicit TransferStateInternal(GLuint texture_id, | 138 explicit TransferStateInternal(GLuint texture_id, |
140 bool wait_for_uploads, | 139 bool wait_for_uploads, |
141 bool wait_for_egl_images) | 140 bool wait_for_egl_images) |
142 : texture_id_(texture_id), | 141 : texture_id_(texture_id), |
143 thread_texture_id_(0), | 142 thread_texture_id_(0), |
144 needs_late_bind_(false), | 143 needs_late_bind_(false), |
145 transfer_in_progress_(false), | 144 transfer_in_progress_(false), |
146 egl_image_(EGL_NO_IMAGE_KHR), | 145 egl_image_(EGL_NO_IMAGE_KHR), |
147 wait_for_uploads_(wait_for_uploads), | 146 wait_for_uploads_(wait_for_uploads), |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // GPU action that needs to occur. We could use fences and try | 226 // GPU action that needs to occur. We could use fences and try |
228 // to do this less often. However, on older drivers fences are | 227 // to do this less often. However, on older drivers fences are |
229 // not always reliable (eg. Mali-400 just blocks forever). | 228 // not always reliable (eg. Mali-400 just blocks forever). |
230 if (wait_for_uploads_) { | 229 if (wait_for_uploads_) { |
231 TRACE_EVENT0("gpu", "glFinish"); | 230 TRACE_EVENT0("gpu", "glFinish"); |
232 glFinish(); | 231 glFinish(); |
233 } | 232 } |
234 } | 233 } |
235 | 234 |
236 protected: | 235 protected: |
237 friend class base::RefCountedThreadSafe<TransferStateInternal>; | 236 friend class base::RefCounted<TransferStateInternal>; |
238 friend class AsyncPixelTransferDelegateAndroid; | 237 friend class AsyncPixelTransferDelegateAndroid; |
239 | 238 |
240 static void DeleteTexture(GLuint id) { | 239 static void DeleteTexture(GLuint id) { |
241 glDeleteTextures(1, &id); | 240 glDeleteTextures(1, &id); |
242 } | 241 } |
243 | 242 |
244 virtual ~TransferStateInternal() { | 243 virtual ~TransferStateInternal() { |
245 if (egl_image_ != EGL_NO_IMAGE_KHR) { | 244 if (egl_image_ != EGL_NO_IMAGE_KHR) { |
246 EGLDisplay display = eglGetCurrentDisplay(); | 245 EGLDisplay display = eglGetCurrentDisplay(); |
247 eglDestroyImageKHR(display, egl_image_); | 246 eglDestroyImageKHR(display, egl_image_); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 // EGLImageKHR and another upload thread) | 305 // EGLImageKHR and another upload thread) |
307 class AsyncPixelTransferDelegateAndroid | 306 class AsyncPixelTransferDelegateAndroid |
308 : public AsyncPixelTransferDelegate, | 307 : public AsyncPixelTransferDelegate, |
309 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> { | 308 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> { |
310 public: | 309 public: |
311 AsyncPixelTransferDelegateAndroid(); | 310 AsyncPixelTransferDelegateAndroid(); |
312 virtual ~AsyncPixelTransferDelegateAndroid(); | 311 virtual ~AsyncPixelTransferDelegateAndroid(); |
313 | 312 |
314 // implement AsyncPixelTransferDelegate: | 313 // implement AsyncPixelTransferDelegate: |
315 virtual void AsyncNotifyCompletion( | 314 virtual void AsyncNotifyCompletion( |
316 const base::Closure& task) OVERRIDE; | 315 const AsyncMemoryParams& mem_params, |
| 316 const CompletionCallback& callback) OVERRIDE; |
317 virtual void AsyncTexImage2D( | 317 virtual void AsyncTexImage2D( |
318 AsyncPixelTransferState* state, | 318 AsyncPixelTransferState* state, |
319 const AsyncTexImage2DParams& tex_params, | 319 const AsyncTexImage2DParams& tex_params, |
320 const AsyncMemoryParams& mem_params) OVERRIDE; | 320 const AsyncMemoryParams& mem_params) OVERRIDE; |
321 virtual void AsyncTexSubImage2D( | 321 virtual void AsyncTexSubImage2D( |
322 AsyncPixelTransferState* state, | 322 AsyncPixelTransferState* state, |
323 const AsyncTexSubImage2DParams& tex_params, | 323 const AsyncTexSubImage2DParams& tex_params, |
324 const AsyncMemoryParams& mem_params) OVERRIDE; | 324 const AsyncMemoryParams& mem_params) OVERRIDE; |
325 virtual uint32 GetTextureUploadCount() OVERRIDE; | 325 virtual uint32 GetTextureUploadCount() OVERRIDE; |
326 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; | 326 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; |
327 | 327 |
328 private: | 328 private: |
329 // implement AsyncPixelTransferDelegate: | 329 // implement AsyncPixelTransferDelegate: |
330 virtual AsyncPixelTransferState* | 330 virtual AsyncPixelTransferState* |
331 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE; | 331 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE; |
332 | 332 |
333 void AsyncTexImage2DCompleted(scoped_refptr<TransferStateInternal> state); | 333 void AsyncTexImage2DCompleted(scoped_refptr<TransferStateInternal> state); |
334 void AsyncTexSubImage2DCompleted(scoped_refptr<TransferStateInternal> state); | 334 void AsyncTexSubImage2DCompleted(scoped_refptr<TransferStateInternal> state); |
335 | 335 |
336 static void PerformAsyncTexImage2D( | 336 static void PerformAsyncTexImage2D( |
337 TransferStateInternal* state, | 337 TransferStateInternal* state, |
338 AsyncTexImage2DParams tex_params, | 338 AsyncTexImage2DParams tex_params, |
339 base::SharedMemory* shared_memory, | 339 base::SharedMemory* shared_memory, |
340 uint32 shared_memory_data_offset); | 340 uint32 shared_memory_data_offset); |
341 static void PerformAsyncTexSubImage2D( | 341 static void PerformAsyncTexSubImage2D( |
342 TransferStateInternal* state, | 342 TransferStateInternal* state, |
343 AsyncTexSubImage2DParams tex_params, | 343 AsyncTexSubImage2DParams tex_params, |
344 base::SharedMemory* shared_memory, | 344 base::SharedMemory* shared_memory, |
345 uint32 shared_memory_data_offset); | 345 uint32 shared_memory_data_offset); |
| 346 static void PerformNotifyCompletion( |
| 347 base::SharedMemory* shared_memory, |
| 348 uint32 shared_memory_size, |
| 349 uint32 shared_memory_data_offset, |
| 350 uint32 shared_memory_data_size, |
| 351 const CompletionCallback& callback); |
346 | 352 |
347 // Returns true if a work-around was used. | 353 // Returns true if a work-around was used. |
348 bool WorkAroundAsyncTexImage2D( | 354 bool WorkAroundAsyncTexImage2D( |
349 TransferStateInternal* state, | 355 TransferStateInternal* state, |
350 const AsyncTexImage2DParams& tex_params, | 356 const AsyncTexImage2DParams& tex_params, |
351 const AsyncMemoryParams& mem_params); | 357 const AsyncMemoryParams& mem_params); |
352 bool WorkAroundAsyncTexSubImage2D( | 358 bool WorkAroundAsyncTexSubImage2D( |
353 TransferStateInternal* state, | 359 TransferStateInternal* state, |
354 const AsyncTexSubImage2DParams& tex_params, | 360 const AsyncTexSubImage2DParams& tex_params, |
355 const AsyncMemoryParams& mem_params); | 361 const AsyncMemoryParams& mem_params); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 421 |
416 // We need to wait for EGLImage creation on Qualcomm. | 422 // We need to wait for EGLImage creation on Qualcomm. |
417 bool wait_for_egl_images = is_qualcomm_; | 423 bool wait_for_egl_images = is_qualcomm_; |
418 | 424 |
419 return static_cast<AsyncPixelTransferState*>( | 425 return static_cast<AsyncPixelTransferState*>( |
420 new AsyncTransferStateAndroid(texture_id, | 426 new AsyncTransferStateAndroid(texture_id, |
421 wait_for_uploads, | 427 wait_for_uploads, |
422 wait_for_egl_images)); | 428 wait_for_egl_images)); |
423 } | 429 } |
424 | 430 |
425 namespace { | |
426 // Dummy function to measure completion on | |
427 // the upload thread. | |
428 void NoOp() {} | |
429 } // namespace | |
430 | |
431 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion( | 431 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion( |
432 const base::Closure& task) { | 432 const AsyncMemoryParams& mem_params, |
433 // Post a no-op task to the upload thread followed | 433 const CompletionCallback& callback) { |
434 // by a reply to the callback. The reply will then occur after | 434 DCHECK(mem_params.shared_memory); |
435 // all async transfers are complete. | 435 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, |
436 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, | 436 mem_params.shm_size); |
437 base::Bind(&NoOp), task); | 437 // Post a PerformNotifyCompletion task to the upload thread. This task |
| 438 // will run after all async transfers are complete. |
| 439 transfer_message_loop_proxy()->PostTask( |
| 440 FROM_HERE, |
| 441 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion, |
| 442 base::Owned(DuplicateSharedMemory(mem_params.shared_memory, |
| 443 mem_params.shm_size)), |
| 444 mem_params.shm_size, |
| 445 mem_params.shm_data_offset, |
| 446 mem_params.shm_data_size, |
| 447 callback)); |
438 } | 448 } |
439 | 449 |
440 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D( | 450 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D( |
441 AsyncPixelTransferState* transfer_state, | 451 AsyncPixelTransferState* transfer_state, |
442 const AsyncTexImage2DParams& tex_params, | 452 const AsyncTexImage2DParams& tex_params, |
443 const AsyncMemoryParams& mem_params) { | 453 const AsyncMemoryParams& mem_params) { |
444 scoped_refptr<TransferStateInternal> state = | 454 scoped_refptr<TransferStateInternal> state = |
445 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); | 455 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); |
446 DCHECK(mem_params.shared_memory); | 456 DCHECK(mem_params.shared_memory); |
447 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, | 457 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 tex_params.format, | 663 tex_params.format, |
654 tex_params.type, | 664 tex_params.type, |
655 data); | 665 data); |
656 } | 666 } |
657 state->WaitForLastUpload(); | 667 state->WaitForLastUpload(); |
658 | 668 |
659 DCHECK(CHECK_GL()); | 669 DCHECK(CHECK_GL()); |
660 state->last_transfer_time_ = base::TimeTicks::HighResNow() - begin_time; | 670 state->last_transfer_time_ = base::TimeTicks::HighResNow() - begin_time; |
661 } | 671 } |
662 | 672 |
| 673 void AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion( |
| 674 base::SharedMemory* shared_memory, |
| 675 uint32 shared_memory_size, |
| 676 uint32 shared_memory_data_offset, |
| 677 uint32 shared_memory_data_size, |
| 678 const CompletionCallback& callback) { |
| 679 TRACE_EVENT0("gpu", "PerformNotifyCompletion"); |
| 680 gfx::AsyncMemoryParams mem_params; |
| 681 mem_params.shared_memory = shared_memory; |
| 682 mem_params.shm_size = shared_memory_size; |
| 683 mem_params.shm_data_offset = shared_memory_data_offset; |
| 684 mem_params.shm_data_size = shared_memory_data_size; |
| 685 callback.Run(mem_params); |
| 686 } |
663 | 687 |
664 namespace { | 688 namespace { |
665 bool IsPowerOfTwo (unsigned int x) { | 689 bool IsPowerOfTwo (unsigned int x) { |
666 return ((x != 0) && !(x & (x - 1))); | 690 return ((x != 0) && !(x & (x - 1))); |
667 } | 691 } |
668 | 692 |
669 bool IsMultipleOfEight(unsigned int x) { | 693 bool IsMultipleOfEight(unsigned int x) { |
670 return (x & 7) == 0; | 694 return (x & 7) == 0; |
671 } | 695 } |
672 | 696 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 data); | 793 data); |
770 } | 794 } |
771 texture_upload_count_++; | 795 texture_upload_count_++; |
772 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time; | 796 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time; |
773 | 797 |
774 DCHECK(CHECK_GL()); | 798 DCHECK(CHECK_GL()); |
775 return true; | 799 return true; |
776 } | 800 } |
777 | 801 |
778 } // namespace gfx | 802 } // namespace gfx |
OLD | NEW |