Chromium Code Reviews| Index: content/common/gpu/client/gpu_channel_host.cc |
| diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc |
| index f7f5d823eedb84285f08f16f93c8b609bcd80793..95cfe5f0ac9e9604e9c246d50c6b166b4bec08e7 100644 |
| --- a/content/common/gpu/client/gpu_channel_host.cc |
| +++ b/content/common/gpu/client/gpu_channel_host.cc |
| @@ -50,7 +50,8 @@ GpuChannelHost::GpuChannelHost( |
| cc::GpuMemoryBufferManager* gpu_memory_buffer_manager) |
| : factory_(factory), |
| gpu_info_(gpu_info), |
| - gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { |
| + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
| + next_signal_id_(0) { |
| next_transfer_buffer_id_.GetNext(); |
| next_image_id_.GetNext(); |
| next_route_id_.GetNext(); |
| @@ -319,6 +320,73 @@ int32 GpuChannelHost::GenerateRouteID() { |
| return next_route_id_.GetNext(); |
| } |
| +namespace { |
| +class SyncPointTracker : public base::RefCounted<SyncPointTracker> { |
| + public: |
| + SyncPointTracker(const base::Closure& destruction_callback, |
| + scoped_refptr<MessageLoopProxy> caller_message_loop) |
| + : destruction_callback_(destruction_callback), |
| + caller_message_loop_(caller_message_loop) {} |
| + |
| + void Noop() {} |
| + |
| + private: |
| + friend class base::RefCounted<SyncPointTracker>; |
| + ~SyncPointTracker() { |
| + caller_message_loop_->PostTask(FROM_HERE, destruction_callback_); |
| + } |
| + |
| + base::Closure destruction_callback_; |
| + scoped_refptr<MessageLoopProxy> caller_message_loop_; |
| +}; |
| +} |
| + |
| +void GpuChannelHost::WaitForPendingGpuMemoryBufferUsageToComplete( |
| + const base::Closure& callback) { |
| + AutoLock lock(signal_lock_); |
| + uint32 signal_id = next_signal_id_++; |
| + signal_tasks_.insert(std::make_pair(signal_id, callback)); |
| + |
| + factory_->GetMainLoop()->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + &GpuChannelHost::WaitForPendingGpuMemoryBufferUsageToCompleteOnMain, |
| + base::Unretained(this), |
| + signal_id, |
| + base::MessageLoopProxy::current())); |
| +} |
| + |
| +void GpuChannelHost::WaitForPendingGpuMemoryBufferUsageToCompleteOnMain( |
| + uint32 id, |
| + scoped_refptr<base::MessageLoopProxy> caller_message_loop) { |
| + scoped_refptr<SyncPointTracker> tracker = new SyncPointTracker( |
| + base::Bind(&GpuChannelHost::WaitCompletedOnCallerThread, |
| + base::Unretained(this), |
| + id), |
| + caller_message_loop); |
| + |
| + AutoLock lock(context_lock_); |
| + for (ProxyMap::iterator it = proxies_.begin(); it != proxies_.end(); it++) { |
| + uint32 sync_point = it->second->InsertSyncPoint(); |
| + it->second->SignalSyncPoint(sync_point, |
| + base::Bind(&SyncPointTracker::Noop, tracker)); |
| + } |
|
reveman
2014/10/22 16:20:08
Could we make all this much simpler by just having
|
| +} |
| + |
| +void GpuChannelHost::WaitCompletedOnCallerThread(uint32 id) { |
| + base::Closure callback; |
| + { |
| + AutoLock lock(signal_lock_); |
| + SignalTaskMap::iterator it = signal_tasks_.find(id); |
| + DCHECK(it != signal_tasks_.end()); |
| + |
| + callback = it->second; |
| + signal_tasks_.erase(it); |
| + } |
| + |
| + callback.Run(); |
| +} |
| + |
| GpuChannelHost::~GpuChannelHost() { |
| // channel_ must be destroyed on the main thread. |
| if (!factory_->IsMainThread()) |