Index: content/browser/gpu/browser_gpu_memory_buffer_manager.cc |
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..58c12117d51ea4fd8486427593fb7e233a77fc3e |
--- /dev/null |
+++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc |
@@ -0,0 +1,146 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" |
+ |
+#include "base/bind.h" |
+#include "base/debug/trace_event.h" |
+#include "base/lazy_instance.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "base/threading/thread_restrictions.h" |
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h" |
+#include "content/public/browser/browser_thread.h" |
+ |
+namespace content { |
+namespace { |
+ |
+void GpuMemoryBufferAllocatedForChildProcess( |
+ const BrowserGpuMemoryBufferManager::AllocationCallback& callback, |
+ const gfx::GpuMemoryBufferHandle& handle) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ callback.Run(handle); |
+} |
+ |
+BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; |
+ |
+} // namespace |
+ |
+struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { |
+ AllocateGpuMemoryBufferRequest(const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format, |
+ gfx::GpuMemoryBuffer::Usage usage, |
+ int client_id) |
+ : event(true, false), |
+ size(size), |
+ format(format), |
+ usage(usage), |
+ client_id(client_id) {} |
+ ~AllocateGpuMemoryBufferRequest() {} |
+ base::WaitableEvent event; |
+ gfx::Size size; |
+ gfx::GpuMemoryBuffer::Format format; |
+ gfx::GpuMemoryBuffer::Usage usage; |
+ int client_id; |
+ scoped_ptr<gfx::GpuMemoryBuffer> result; |
+}; |
+ |
+BrowserGpuMemoryBufferManager::BrowserGpuMemoryBufferManager(int gpu_client_id) |
+ : gpu_client_id_(gpu_client_id) { |
+ DCHECK(!g_gpu_memory_buffer_manager); |
+ g_gpu_memory_buffer_manager = this; |
+} |
+ |
+BrowserGpuMemoryBufferManager::~BrowserGpuMemoryBufferManager() { |
+ g_gpu_memory_buffer_manager = nullptr; |
+} |
+ |
+// static |
+BrowserGpuMemoryBufferManager* BrowserGpuMemoryBufferManager::current() { |
+ return g_gpu_memory_buffer_manager; |
+} |
+ |
+scoped_ptr<gfx::GpuMemoryBuffer> |
+BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer( |
+ const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format, |
+ gfx::GpuMemoryBuffer::Usage usage) { |
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ AllocateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO, |
+ base::Unretained(&request))); |
+ |
+ // We're blocking the UI thread, which is generally undesirable. |
+ TRACE_EVENT0("browser", |
+ "BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer"); |
+ base::ThreadRestrictions::ScopedAllowWait allow_wait; |
+ request.event.Wait(); |
+ return request.result.Pass(); |
+} |
+ |
+void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess( |
+ const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format, |
+ gfx::GpuMemoryBuffer::Usage usage, |
+ base::ProcessHandle child_process_handle, |
+ int child_client_id, |
+ const AllocationCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ GpuMemoryBufferImpl::AllocateForChildProcess( |
+ size, |
+ format, |
+ usage, |
+ child_process_handle, |
+ child_client_id, |
+ base::Bind(&GpuMemoryBufferAllocatedForChildProcess, callback)); |
+} |
+ |
+gfx::GpuMemoryBuffer* |
+BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( |
+ ClientBuffer buffer) { |
+ return GpuMemoryBufferImpl::FromClientBuffer(buffer); |
+} |
+ |
+void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer( |
+ gfx::GpuMemoryBufferType type, |
+ const gfx::GpuMemoryBufferId& id, |
+ base::ProcessHandle child_process_handle) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ GpuMemoryBufferImpl::DeletedByChildProcess(type, id, child_process_handle); |
+} |
+ |
+void BrowserGpuMemoryBufferManager::ProcessRemoved( |
+ base::ProcessHandle process_handle) { |
+ // TODO(reveman): Handle child process removal correctly. |
+} |
+ |
+// static |
+void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO( |
+ AllocateGpuMemoryBufferRequest* request) { |
+ GpuMemoryBufferImpl::Create( |
+ request->size, |
+ request->format, |
+ request->usage, |
+ request->client_id, |
+ base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO, |
+ base::Unretained(request))); |
+} |
+ |
+// static |
+void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO( |
+ AllocateGpuMemoryBufferRequest* request, |
+ scoped_ptr<GpuMemoryBufferImpl> buffer) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ request->result = buffer.PassAs<gfx::GpuMemoryBuffer>(); |
+ request->event.Signal(); |
+} |
+ |
+} // namespace content |