| Index: ui/gl/async_pixel_transfer_delegate_android.cc
|
| diff --git a/ui/gl/async_pixel_transfer_delegate_android.cc b/ui/gl/async_pixel_transfer_delegate_android.cc
|
| index db1b8c56ecd91c390247ce9c562164c551ecb434..362a5aadb077c5312d9b64fb628ce159b8893ebd 100644
|
| --- a/ui/gl/async_pixel_transfer_delegate_android.cc
|
| +++ b/ui/gl/async_pixel_transfer_delegate_android.cc
|
| @@ -70,15 +70,11 @@ SharedMemory* DuplicateSharedMemory(SharedMemory* shared_memory, uint32 size) {
|
| }
|
|
|
| // Gets the address of the data from shared memory.
|
| -void* GetAddress(SharedMemory* shared_memory,
|
| - uint32 shm_size,
|
| - uint32 shm_data_offset,
|
| - uint32 shm_data_size) {
|
| +void* GetAddress(SharedMemory* shared_memory, uint32 shm_data_offset) {
|
| // Memory bounds have already been validated, so there
|
| // is just DCHECKS here.
|
| DCHECK(shared_memory);
|
| DCHECK(shared_memory->memory());
|
| - DCHECK_LE(shm_data_offset + shm_data_size, shm_size);
|
| return static_cast<int8*>(shared_memory->memory()) + shm_data_offset;
|
| }
|
|
|
| @@ -163,16 +159,7 @@ class TransferStateInternal
|
| needs_late_bind_ = false;
|
| }
|
|
|
| - // Completion callbacks.
|
| - void TexImage2DCompleted() {
|
| - needs_late_bind_ = true;
|
| - transfer_in_progress_ = false;
|
| - }
|
| - void TexSubImage2DCompleted() {
|
| - transfer_in_progress_ = false;
|
| - }
|
| -
|
| -protected:
|
| + protected:
|
| friend class base::RefCountedThreadSafe<TransferStateInternal>;
|
| friend class AsyncPixelTransferDelegateAndroid;
|
|
|
| @@ -211,6 +198,9 @@ protected:
|
| // every upload, but I found that didn't work, so this stores
|
| // one for the lifetime of the texture.
|
| EGLImageKHR egl_image_;
|
| +
|
| + // Time spent performing last transfer.
|
| + base::TimeDelta last_transfer_time_;
|
| };
|
|
|
| // Android needs thread-safe ref-counting, so this just wraps
|
| @@ -232,10 +222,12 @@ class AsyncTransferStateAndroid : public AsyncPixelTransferState {
|
|
|
| // Class which handles async pixel transfers on Android (using
|
| // EGLImageKHR and another upload thread)
|
| -class AsyncPixelTransferDelegateAndroid : public AsyncPixelTransferDelegate {
|
| +class AsyncPixelTransferDelegateAndroid
|
| + : public AsyncPixelTransferDelegate,
|
| + public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> {
|
| public:
|
| - AsyncPixelTransferDelegateAndroid() {}
|
| - virtual ~AsyncPixelTransferDelegateAndroid() {}
|
| + AsyncPixelTransferDelegateAndroid();
|
| + virtual ~AsyncPixelTransferDelegateAndroid();
|
|
|
| // implement AsyncPixelTransferDelegate:
|
| virtual void AsyncNotifyCompletion(
|
| @@ -248,20 +240,30 @@ class AsyncPixelTransferDelegateAndroid : public AsyncPixelTransferDelegate {
|
| AsyncPixelTransferState* state,
|
| const AsyncTexSubImage2DParams& tex_params,
|
| const AsyncMemoryParams& mem_params) OVERRIDE;
|
| + virtual uint32 GetTextureUploadCount() OVERRIDE;
|
| + virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
|
|
|
| private:
|
| // implement AsyncPixelTransferDelegate:
|
| virtual AsyncPixelTransferState*
|
| CreateRawPixelTransferState(GLuint texture_id) OVERRIDE;
|
|
|
| + void AsyncTexImage2DCompleted(scoped_refptr<TransferStateInternal> state);
|
| + void AsyncTexSubImage2DCompleted(scoped_refptr<TransferStateInternal> state);
|
| +
|
| static void PerformAsyncTexImage2D(
|
| TransferStateInternal* state,
|
| AsyncTexImage2DParams tex_params,
|
| - AsyncMemoryParams mem_params);
|
| + base::SharedMemory* shared_memory,
|
| + uint32 shared_memory_data_offset);
|
| static void PerformAsyncTexSubImage2D(
|
| TransferStateInternal* state,
|
| AsyncTexSubImage2DParams tex_params,
|
| - AsyncMemoryParams mem_params);
|
| + base::SharedMemory* shared_memory,
|
| + uint32 shared_memory_data_offset);
|
| +
|
| + int texture_upload_count_;
|
| + base::TimeDelta total_texture_upload_time_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateAndroid);
|
| };
|
| @@ -299,6 +301,13 @@ scoped_ptr<AsyncPixelTransferDelegate>
|
| }
|
| }
|
|
|
| +AsyncPixelTransferDelegateAndroid::AsyncPixelTransferDelegateAndroid()
|
| + : texture_upload_count_(0) {
|
| +}
|
| +
|
| +AsyncPixelTransferDelegateAndroid::~AsyncPixelTransferDelegateAndroid() {
|
| +}
|
| +
|
| AsyncPixelTransferState*
|
| AsyncPixelTransferDelegateAndroid::
|
| CreateRawPixelTransferState(GLuint texture_id) {
|
| @@ -325,9 +334,11 @@ void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D(
|
| AsyncPixelTransferState* transfer_state,
|
| const AsyncTexImage2DParams& tex_params,
|
| const AsyncMemoryParams& mem_params) {
|
| - TransferStateInternal* state =
|
| + scoped_refptr<TransferStateInternal> state =
|
| static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
|
| DCHECK(mem_params.shared_memory);
|
| + DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
|
| + mem_params.shm_size);
|
| DCHECK(state);
|
| DCHECK(state->texture_id_);
|
| DCHECK(!state->needs_late_bind_);
|
| @@ -342,18 +353,17 @@ void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D(
|
|
|
| // Duplicate the shared memory so there are no way we can get
|
| // a use-after-free of the raw pixels.
|
| - // TODO: Could we pass an own pointer of the new SharedMemory to the task?
|
| - AsyncMemoryParams duped_mem = mem_params;
|
| - duped_mem.shared_memory = DuplicateSharedMemory(mem_params.shared_memory,
|
| - mem_params.shm_size);
|
| transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE,
|
| base::Bind(
|
| &AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D,
|
| - base::Unretained(state), // This is referenced in reply below.
|
| + base::Unretained(state.get()), // This is referenced in reply below.
|
| tex_params,
|
| - duped_mem),
|
| + base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
|
| + mem_params.shm_size)),
|
| + mem_params.shm_data_offset),
|
| base::Bind(
|
| - &TransferStateInternal::TexImage2DCompleted,
|
| + &AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted,
|
| + AsWeakPtr(),
|
| state));
|
|
|
| DCHECK(CHECK_GL());
|
| @@ -366,11 +376,13 @@ void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D(
|
| TRACE_EVENT2("gpu", "AsyncTexSubImage2D",
|
| "width", tex_params.width,
|
| "height", tex_params.height);
|
| - TransferStateInternal* state =
|
| + scoped_refptr<TransferStateInternal> state =
|
| static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
|
| DCHECK(state->texture_id_);
|
| DCHECK(!state->transfer_in_progress_);
|
| DCHECK(mem_params.shared_memory);
|
| + DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
|
| + mem_params.shm_size);
|
| DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
|
| DCHECK_EQ(tex_params.level, 0);
|
|
|
| @@ -400,23 +412,43 @@ void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D(
|
|
|
| // Duplicate the shared memory so there are no way we can get
|
| // a use-after-free of the raw pixels.
|
| - // TODO: Could we pass an own pointer of the new SharedMemory to the task?
|
| - AsyncMemoryParams duped_mem = mem_params;
|
| - duped_mem.shared_memory = DuplicateSharedMemory(mem_params.shared_memory,
|
| - mem_params.shm_size);
|
| transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE,
|
| base::Bind(
|
| &AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D,
|
| - base::Unretained(state), // This is referenced in reply below.
|
| + base::Unretained(state.get()), // This is referenced in reply below.
|
| tex_params,
|
| - duped_mem),
|
| + base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
|
| + mem_params.shm_size)),
|
| + mem_params.shm_data_offset),
|
| base::Bind(
|
| - &TransferStateInternal::TexSubImage2DCompleted,
|
| + &AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted,
|
| + AsWeakPtr(),
|
| state));
|
|
|
| DCHECK(CHECK_GL());
|
| }
|
|
|
| +uint32 AsyncPixelTransferDelegateAndroid::GetTextureUploadCount() {
|
| + return texture_upload_count_;
|
| +}
|
| +
|
| +base::TimeDelta AsyncPixelTransferDelegateAndroid::GetTotalTextureUploadTime() {
|
| + return total_texture_upload_time_;
|
| +}
|
| +
|
| +void AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted(
|
| + scoped_refptr<TransferStateInternal> state) {
|
| + state->needs_late_bind_ = true;
|
| + state->transfer_in_progress_ = false;
|
| +}
|
| +
|
| +void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted(
|
| + scoped_refptr<TransferStateInternal> state) {
|
| + state->transfer_in_progress_ = false;
|
| + texture_upload_count_++;
|
| + total_texture_upload_time_ += state->last_transfer_time_;
|
| +}
|
| +
|
| namespace {
|
| void WaitForGl() {
|
| TRACE_EVENT0("gpu", "eglWaitSync");
|
| @@ -440,7 +472,8 @@ void WaitForGl() {
|
| void AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D(
|
| TransferStateInternal* state,
|
| AsyncTexImage2DParams tex_params,
|
| - AsyncMemoryParams mem_params) {
|
| + base::SharedMemory* shared_memory,
|
| + uint32 shared_memory_data_offset) {
|
| TRACE_EVENT2("gpu", "PerformAsyncTexImage",
|
| "width", tex_params.width,
|
| "height", tex_params.height);
|
| @@ -449,14 +482,7 @@ void AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D(
|
| DCHECK_EQ(0, tex_params.level);
|
| DCHECK_EQ(EGL_NO_IMAGE_KHR, state->egl_image_);
|
|
|
| - // TODO(epenner): This is just to insure it is deleted. Could bind() do this?
|
| - scoped_ptr<SharedMemory> shared_memory =
|
| - make_scoped_ptr(mem_params.shared_memory);
|
| -
|
| - void* data = GetAddress(mem_params.shared_memory,
|
| - mem_params.shm_size,
|
| - mem_params.shm_data_offset,
|
| - mem_params.shm_data_size);
|
| + void* data = GetAddress(shared_memory, shared_memory_data_offset);
|
| {
|
| TRACE_EVENT0("gpu", "glTexImage2D no data");
|
| glGenTextures(1, &state->thread_texture_id_);
|
| @@ -523,7 +549,8 @@ void AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D(
|
| void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D(
|
| TransferStateInternal* state,
|
| AsyncTexSubImage2DParams tex_params,
|
| - AsyncMemoryParams mem_params) {
|
| + base::SharedMemory* shared_memory,
|
| + uint32 shared_memory_data_offset) {
|
| TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
|
| "width", tex_params.width,
|
| "height", tex_params.height);
|
| @@ -532,15 +559,9 @@ void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D(
|
| DCHECK_NE(EGL_NO_IMAGE_KHR, state->egl_image_);
|
| DCHECK_EQ(0, tex_params.level);
|
|
|
| - // TODO(epenner): This is just to insure it is deleted. Could bind() do this?
|
| - scoped_ptr<SharedMemory> shared_memory =
|
| - make_scoped_ptr(mem_params.shared_memory);
|
| -
|
| - void* data = GetAddress(mem_params.shared_memory,
|
| - mem_params.shm_size,
|
| - mem_params.shm_data_offset,
|
| - mem_params.shm_data_size);
|
| + void* data = GetAddress(shared_memory, shared_memory_data_offset);
|
|
|
| + base::TimeTicks begin_time(base::TimeTicks::HighResNow());
|
| if (!state->thread_texture_id_) {
|
| TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES");
|
| glGenTextures(1, &state->thread_texture_id_);
|
| @@ -567,6 +588,7 @@ void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D(
|
| WaitForGl();
|
|
|
| DCHECK(CHECK_GL());
|
| + state->last_transfer_time_ = base::TimeTicks::HighResNow() - begin_time;
|
| }
|
|
|
| } // namespace gfx
|
|
|