Chromium Code Reviews| Index: gpu/command_buffer/service/in_process_command_buffer.cc |
| diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc |
| index 25d57013f2e1dd83f5ace9309efbf1e3fb350ed3..b5d30446c04e1fd0919c3e68006fbb997851740f 100644 |
| --- a/gpu/command_buffer/service/in_process_command_buffer.cc |
| +++ b/gpu/command_buffer/service/in_process_command_buffer.cc |
| @@ -20,6 +20,7 @@ |
| #include "base/logging.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| +#include "base/sequence_checker.h" |
| #include "base/threading/thread.h" |
| #include "gpu/command_buffer/common/id_allocator.h" |
| #include "gpu/command_buffer/service/command_buffer_service.h" |
| @@ -32,7 +33,6 @@ |
| #include "ui/gl/gl_context.h" |
| #include "ui/gl/gl_image.h" |
| #include "ui/gl/gl_share_group.h" |
| -#include "ui/gl/gl_surface.h" |
| namespace gpu { |
| @@ -244,6 +244,7 @@ InProcessCommandBuffer::~InProcessCommandBuffer() { |
| } |
| bool InProcessCommandBuffer::IsContextLost() { |
| + CheckSequencedThread(); |
| if (context_lost_ || !command_buffer_) { |
| return true; |
| } |
| @@ -252,11 +253,13 @@ bool InProcessCommandBuffer::IsContextLost() { |
| } |
| void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { |
| + CheckSequencedThread(); |
| DCHECK(!surface_->IsOffscreen()); |
| surface_->Resize(size); |
| } |
| bool InProcessCommandBuffer::MakeCurrent() { |
| + CheckSequencedThread(); |
| command_buffer_lock_.AssertAcquired(); |
| if (!context_lost_ && decoder_->MakeCurrent()) |
| @@ -268,6 +271,7 @@ bool InProcessCommandBuffer::MakeCurrent() { |
| } |
| void InProcessCommandBuffer::PumpCommands() { |
| + CheckSequencedThread(); |
| ScopedEvent handle_flush(&flush_event_); |
| command_buffer_lock_.AssertAcquired(); |
| @@ -281,12 +285,14 @@ void InProcessCommandBuffer::PumpCommands() { |
| } |
| bool InProcessCommandBuffer::GetBufferChanged(int32 transfer_buffer_id) { |
| + CheckSequencedThread(); |
| command_buffer_lock_.AssertAcquired(); |
| command_buffer_->SetGetBuffer(transfer_buffer_id); |
| return true; |
| } |
| bool InProcessCommandBuffer::Initialize( |
| + scoped_refptr<gfx::GLSurface> surface, |
| bool is_offscreen, |
| bool share_resources, |
| gfx::AcceleratedWidget window, |
| @@ -301,8 +307,13 @@ bool InProcessCommandBuffer::Initialize( |
| context_lost_callback_ = WrapCallback(context_lost_callback); |
| share_group_id_ = share_group_id; |
| - base::WaitableEvent completion(true, false); |
| - bool result = false; |
| + if (surface) { |
| + // GPU thread must be the same as client thread due to GLSurface not being |
| + // thread safe. |
| + sequence_checker_.reset(new base::SequenceChecker); |
| + surface_ = surface; |
| + } |
| + |
| base::Callback<bool(void)> init_task = |
| base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, |
| base::Unretained(this), |
| @@ -312,6 +323,9 @@ bool InProcessCommandBuffer::Initialize( |
| allowed_extensions, |
| attribs, |
| gpu_preference); |
| + |
| + base::WaitableEvent completion(true, false); |
| + bool result = false; |
| QueueTask( |
| base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); |
| completion.Wait(); |
| @@ -325,6 +339,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( |
| const char* allowed_extensions, |
| const std::vector<int32>& attribs, |
| gfx::GpuPreference gpu_preference) { |
| + CheckSequencedThread(); |
|
no sievers
2013/08/07 01:52:38
Does it make sense to always have a sequence check
boliu
2013/08/07 02:58:48
Can't use scoped_ptr anymore since they could both
|
| // Use one share group for all contexts. |
| CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, |
| (new gfx::GLShareGroup)); |
| @@ -381,10 +396,12 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( |
| decoder_->set_engine(gpu_scheduler_.get()); |
| - if (is_offscreen) |
| - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); |
| - else |
| - surface_ = gfx::GLSurface::CreateViewGLSurface(window); |
| + if (!surface_) { |
| + if (is_offscreen) |
| + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); |
| + else |
| + surface_ = gfx::GLSurface::CreateViewGLSurface(window); |
| + } |
| if (!surface_.get()) { |
| LOG(ERROR) << "Could not create GLSurface."; |
| @@ -452,6 +469,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( |
| } |
| void InProcessCommandBuffer::Destroy() { |
| + CheckSequencedThread(); |
| base::WaitableEvent completion(true, false); |
| bool result = false; |
| base::Callback<bool(void)> destroy_task = base::Bind( |
| @@ -462,6 +480,7 @@ void InProcessCommandBuffer::Destroy() { |
| } |
| bool InProcessCommandBuffer::DestroyOnGpuThread() { |
| + CheckSequencedThread(); |
| command_buffer_.reset(); |
| // Clean up GL resources if possible. |
| bool have_context = context_ && context_->MakeCurrent(surface_); |
| @@ -476,9 +495,15 @@ bool InProcessCommandBuffer::DestroyOnGpuThread() { |
| return true; |
| } |
| +void InProcessCommandBuffer::CheckSequencedThread() { |
| + DCHECK(!sequence_checker_ || |
| + sequence_checker_->CalledOnValidSequencedThread()); |
| +} |
| + |
| unsigned int InProcessCommandBuffer::CreateImageForGpuMemoryBuffer( |
| gfx::GpuMemoryBufferHandle buffer, |
| gfx::Size size) { |
| + CheckSequencedThread(); |
| unsigned int image_id; |
| { |
| // TODO: ID allocation should go through CommandBuffer |
| @@ -498,12 +523,14 @@ void InProcessCommandBuffer::CreateImageOnGpuThread( |
| gfx::GpuMemoryBufferHandle buffer, |
| gfx::Size size, |
| unsigned int image_id) { |
| + CheckSequencedThread(); |
| scoped_refptr<gfx::GLImage> gl_image = |
| gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer, size); |
| decoder_->GetContextGroup()->image_manager()->AddImage(gl_image, image_id); |
| } |
| void InProcessCommandBuffer::RemoveImage(unsigned int image_id) { |
| + CheckSequencedThread(); |
| { |
| // TODO: ID allocation should go through CommandBuffer |
| base::AutoLock lock(command_buffer_lock_); |
| @@ -518,10 +545,12 @@ void InProcessCommandBuffer::RemoveImage(unsigned int image_id) { |
| } |
| void InProcessCommandBuffer::RemoveImageOnGpuThread(unsigned int image_id) { |
| + CheckSequencedThread(); |
| decoder_->GetContextGroup()->image_manager()->RemoveImage(image_id); |
| } |
| void InProcessCommandBuffer::OnContextLost() { |
| + CheckSequencedThread(); |
| if (!context_lost_callback_.is_null()) { |
| context_lost_callback_.Run(); |
| context_lost_callback_.Reset(); |
| @@ -539,26 +568,34 @@ void InProcessCommandBuffer::OnContextLost() { |
| } |
| CommandBuffer::State InProcessCommandBuffer::GetStateFast() { |
| + CheckSequencedThread(); |
| base::AutoLock lock(command_buffer_lock_); |
| return last_state_ = command_buffer_->GetState(); |
| } |
| CommandBuffer::State InProcessCommandBuffer::GetState() { |
| + CheckSequencedThread(); |
| return GetStateFast(); |
| } |
| CommandBuffer::State InProcessCommandBuffer::GetLastState() { |
| + CheckSequencedThread(); |
| return last_state_; |
| } |
| -int32 InProcessCommandBuffer::GetLastToken() { return last_state_.token; } |
| +int32 InProcessCommandBuffer::GetLastToken() { |
| + CheckSequencedThread(); |
| + return last_state_.token; |
| +} |
| void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) { |
| + CheckSequencedThread(); |
| base::AutoLock lock(command_buffer_lock_); |
| command_buffer_->Flush(put_offset); |
| } |
| void InProcessCommandBuffer::Flush(int32 put_offset) { |
| + CheckSequencedThread(); |
| if (last_state_.error != gpu::error::kNoError) |
| return; |
| @@ -574,6 +611,7 @@ void InProcessCommandBuffer::Flush(int32 put_offset) { |
| CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset, |
| int32 last_known_get) { |
| + CheckSequencedThread(); |
| if (put_offset == last_known_get || last_state_.error != gpu::error::kNoError) |
| return last_state_; |
| @@ -589,6 +627,7 @@ CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset, |
| } |
| void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) { |
| + CheckSequencedThread(); |
| if (last_state_.error != gpu::error::kNoError) |
| return; |
| @@ -602,11 +641,13 @@ void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) { |
| gpu::Buffer InProcessCommandBuffer::CreateTransferBuffer(size_t size, |
| int32* id) { |
| + CheckSequencedThread(); |
| base::AutoLock lock(command_buffer_lock_); |
| return command_buffer_->CreateTransferBuffer(size, id); |
| } |
| void InProcessCommandBuffer::DestroyTransferBuffer(int32 id) { |
| + CheckSequencedThread(); |
| base::Closure task = base::Bind(&CommandBuffer::DestroyTransferBuffer, |
| base::Unretained(command_buffer_.get()), |
| id); |
| @@ -625,10 +666,12 @@ uint32 InProcessCommandBuffer::InsertSyncPoint() { |
| } |
| void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, |
| const base::Closure& callback) { |
| + CheckSequencedThread(); |
| QueueTask(WrapCallback(callback)); |
| } |
| gpu::error::Error InProcessCommandBuffer::GetLastError() { |
| + CheckSequencedThread(); |
| return last_state_.error; |
| } |