Index: content/common/gpu/client/command_buffer_proxy_impl.cc |
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc |
index f80521dd4d17799cfe7fb49e797f43fe51d2ef7a..dbfed1da522e6eef8710a0eda2d35c946a32448b 100644 |
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc |
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc |
@@ -82,14 +82,15 @@ bool IsImageFormatCompatibleWithGpuMemoryBufferFormat( |
} // namespace |
-CommandBufferProxyImpl::CommandBufferProxyImpl( |
- GpuChannelHost* channel, |
- int route_id) |
+CommandBufferProxyImpl::CommandBufferProxyImpl(GpuChannelHost* channel, |
+ int route_id) |
: channel_(channel), |
route_id_(route_id), |
flush_count_(0), |
last_put_offset_(-1), |
- next_signal_id_(0) { |
+ next_signal_id_(0), |
+ main_loop_proxy_(base::MessageLoopProxy::current()), |
+ tracker_(new GpuMemoryBufferUsageTracker) { |
} |
CommandBufferProxyImpl::~CommandBufferProxyImpl() { |
@@ -259,6 +260,100 @@ void CommandBufferProxyImpl::SetSwapBuffersCompletionCallback( |
swap_buffers_completion_callback_ = callback; |
} |
+CommandBufferProxyImpl::CallbackMessageLoopPair::CallbackMessageLoopPair( |
+ const base::Closure& callback, |
+ scoped_refptr<base::MessageLoopProxy> message_loop) |
+ : callback(callback), message_loop(message_loop) { |
+} |
+ |
+CommandBufferProxyImpl::CallbackMessageLoopPair::~CallbackMessageLoopPair() { |
+} |
+ |
+CommandBufferProxyImpl::GpuMemoryBufferUsageTracker:: |
+ GpuMemoryBufferUsageTracker() |
+ : next_gpu_memory_buffer_usage_id_(0) { |
+} |
+ |
+void CommandBufferProxyImpl::GpuMemoryBufferUsageTracker::OnWillDeleteImpl() { |
+ base::AutoLock lock(gpu_memory_buffer_task_lock_); |
+ GpuMemoryBufferUsageCompletedMap::iterator it = |
+ gpu_memory_buffer_tasks_.begin(); |
+ for (; it != gpu_memory_buffer_tasks_.end(); it++) { |
+ it->second.message_loop->PostTask( |
+ FROM_HERE, |
+ base::Bind(&CommandBufferProxyImpl::GpuMemoryBufferUsageTracker:: |
+ UsageCompletedOnCaller, |
+ this, |
+ it->first)); |
+ } |
+} |
+ |
+uint32 CommandBufferProxyImpl::GpuMemoryBufferUsageTracker::AddUsage( |
+ const CallbackMessageLoopPair& task) { |
+ base::AutoLock lock(gpu_memory_buffer_task_lock_); |
+ uint32 usage_id = next_gpu_memory_buffer_usage_id_++; |
+ |
+ gpu_memory_buffer_tasks_.insert(std::make_pair(usage_id, task)); |
+ return usage_id; |
+} |
+ |
+void CommandBufferProxyImpl::GpuMemoryBufferUsageTracker::UsageCompleted( |
+ uint32 task_id) { |
+ base::AutoLock lock(gpu_memory_buffer_task_lock_); |
+ GpuMemoryBufferUsageCompletedMap::iterator it = |
+ gpu_memory_buffer_tasks_.find(task_id); |
+ DCHECK(it != gpu_memory_buffer_tasks_.end()); |
+ it->second.message_loop->PostTask( |
+ FROM_HERE, |
+ base::Bind(&CommandBufferProxyImpl::GpuMemoryBufferUsageTracker:: |
+ UsageCompletedOnCaller, |
+ this, |
+ task_id)); |
+} |
+ |
+CommandBufferProxyImpl::GpuMemoryBufferUsageTracker:: |
+ ~GpuMemoryBufferUsageTracker() { |
+} |
+ |
+void |
+CommandBufferProxyImpl::GpuMemoryBufferUsageTracker::UsageCompletedOnCaller( |
+ uint32 task_id) { |
+ base::Closure callback; |
+ { |
+ base::AutoLock lock(gpu_memory_buffer_task_lock_); |
+ GpuMemoryBufferUsageCompletedMap::iterator it = |
+ gpu_memory_buffer_tasks_.find(task_id); |
+ DCHECK(it != gpu_memory_buffer_tasks_.end()); |
+ |
+ callback = it->second.callback; |
+ gpu_memory_buffer_tasks_.erase(it); |
+ } |
+ callback.Run(); |
+} |
+ |
+void CommandBufferProxyImpl::WaitForPendingGpuMemoryBufferUsageToComplete( |
+ const base::Closure& callback) { |
+ uint32 usage_id = tracker_->AddUsage( |
+ CallbackMessageLoopPair(callback, base::MessageLoopProxy::current())); |
+ |
+ main_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&CommandBufferProxyImpl:: |
+ WaitForPendingGpuMemoryBufferUsageToCompleteOnMain, |
+ base::Unretained(this), |
+ usage_id)); |
+} |
+ |
+void CommandBufferProxyImpl::WaitForPendingGpuMemoryBufferUsageToCompleteOnMain( |
+ uint32 usage_id) { |
+ SignalSyncPoint( |
+ InsertSyncPoint(), |
+ base::Bind( |
+ &CommandBufferProxyImpl::GpuMemoryBufferUsageTracker::UsageCompleted, |
+ tracker_, |
+ usage_id)); |
+} |
+ |
void CommandBufferProxyImpl::WaitForTokenInRange(int32 start, int32 end) { |
TRACE_EVENT2("gpu", |
"CommandBufferProxyImpl::WaitForToken", |