| 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 |