Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
=================================================================== |
--- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 93137) |
+++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy) |
@@ -479,6 +479,7 @@ |
virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback); |
virtual void SetSwapBuffersCallback(Callback0::Type* callback); |
+ virtual void SetLatchCallback(const base::Callback<void(bool)>& callback);; |
virtual bool GetServiceTextureId(uint32 client_texture_id, |
uint32* service_texture_id); |
@@ -1271,6 +1272,7 @@ |
scoped_ptr<Callback1<gfx::Size>::Type> resize_callback_; |
scoped_ptr<Callback0::Type> swap_buffers_callback_; |
+ base::Callback<void(bool)> latch_callback_; |
// The format of the back buffer_ |
GLenum back_buffer_color_format_; |
@@ -2358,6 +2360,11 @@ |
swap_buffers_callback_.reset(callback); |
} |
+void GLES2DecoderImpl::SetLatchCallback( |
+ const base::Callback<void(bool)>& callback) { |
+ latch_callback_ = callback; |
+} |
+ |
bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, |
uint32* service_texture_id) { |
TextureManager::TextureInfo* texture = |
@@ -6529,6 +6536,62 @@ |
return error::kNoError; |
} |
+error::Error GLES2DecoderImpl::HandleSetLatchCHROMIUM( |
+ uint32 immediate_data_size, const gles2::SetLatchCHROMIUM& c) { |
+ TRACE_EVENT1("gpu", "SetLatch", "latch_id", c.latch_id); |
+ // Ensure the side effects of previous commands are visible to other contexts. |
+ // There is no need to do this for ANGLE because it uses a |
+ // single D3D device for all contexts. |
+ if (!IsAngle()) |
+ glFlush(); |
+ |
+ int32 shm_id = gpu::kLatchSharedMemoryId; |
+ uint32 latch_id = c.latch_id; |
+ uint32 shm_offset = 0; |
+ base::subtle::Atomic32* latch; |
+ if (!SafeMultiplyUint32(latch_id, sizeof(*latch), &shm_offset)) { |
+ return error::kOutOfBounds; |
+ } |
+ latch = GetSharedMemoryAs<base::subtle::Atomic32*>( |
+ shm_id, shm_offset, sizeof(*latch)); |
+ if (!latch) { |
+ return error::kOutOfBounds; |
+ } |
+ base::subtle::Atomic32 old = |
+ base::subtle::NoBarrier_CompareAndSwap(latch, 0, 1); |
+ DCHECK(old == 0); |
+ if (!latch_callback_.is_null()) |
+ latch_callback_.Run(true); |
+ return error::kNoError; |
+} |
+ |
+error::Error GLES2DecoderImpl::HandleWaitLatchCHROMIUM( |
+ uint32 immediate_data_size, const gles2::WaitLatchCHROMIUM& c) { |
+ TRACE_EVENT1("gpu", "WaitLatch", "latch_id", c.latch_id); |
+ int32 shm_id = gpu::kLatchSharedMemoryId; |
+ uint32 latch_id = c.latch_id; |
+ uint32 shm_offset = 0; |
+ base::subtle::Atomic32* latch; |
+ if (!SafeMultiplyUint32(latch_id, sizeof(*latch), &shm_offset)) { |
+ return error::kOutOfBounds; |
+ } |
+ latch = GetSharedMemoryAs<base::subtle::Atomic32*>( |
+ shm_id, shm_offset, sizeof(*latch)); |
+ if (!latch) { |
+ return error::kOutOfBounds; |
+ } |
+ |
+ base::subtle::Atomic32 old = |
+ base::subtle::NoBarrier_CompareAndSwap(latch, 1, 0); |
+ if (old == 0) { |
+ if (!latch_callback_.is_null()) |
+ latch_callback_.Run(false); |
+ return error::kWaiting; |
+ } else { |
+ return error::kNoError; |
+ } |
+} |
+ |
error::Error GLES2DecoderImpl::HandleCommandBufferEnableCHROMIUM( |
uint32 immediate_data_size, const gles2::CommandBufferEnableCHROMIUM& c) { |
Bucket* bucket = GetBucket(c.bucket_id); |