| 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
|
| index 07d2feff4ebc729834c1a37b1abd692476067504..b5bcebc05ea17c1a5adcc31d4063c462d094634b 100644
|
| --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
|
| +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
|
| @@ -16,14 +16,6 @@
|
| 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;
|
|
|
| // Global atomic to generate gpu memory buffer unique IDs.
|
| @@ -96,14 +88,30 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
|
| const AllocationCallback& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| + gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext();
|
| +
|
| + BufferMap& buffers = clients_[child_client_id];
|
| + DCHECK(buffers.find(new_id) == buffers.end());
|
| +
|
| + // Note: Handling of cases where the child process is removed before the
|
| + // allocation completes is less subtle if we set the buffer type to
|
| + // EMPTY_BUFFER here and verify that this has not changed when allocation
|
| + // completes.
|
| + buffers[new_id] = gfx::EMPTY_BUFFER;
|
| +
|
| GpuMemoryBufferImpl::AllocateForChildProcess(
|
| - g_next_gpu_memory_buffer_id.GetNext(),
|
| + new_id,
|
| size,
|
| format,
|
| usage,
|
| child_process_handle,
|
| child_client_id,
|
| - base::Bind(&GpuMemoryBufferAllocatedForChildProcess, callback));
|
| + base::Bind(&BrowserGpuMemoryBufferManager::
|
| + GpuMemoryBufferAllocatedForChildProcess,
|
| + base::Unretained(this),
|
| + child_process_handle,
|
| + child_client_id,
|
| + callback));
|
| }
|
|
|
| gfx::GpuMemoryBuffer*
|
| @@ -112,21 +120,108 @@ BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
|
| return GpuMemoryBufferImpl::FromClientBuffer(buffer);
|
| }
|
|
|
| +void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
|
| + gfx::GpuMemoryBuffer* buffer,
|
| + uint32 sync_point) {
|
| + static_cast<GpuMemoryBufferImpl*>(buffer)
|
| + ->set_destruction_sync_point(sync_point);
|
| +}
|
| +
|
| void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
|
| - gfx::GpuMemoryBufferType type,
|
| gfx::GpuMemoryBufferId id,
|
| base::ProcessHandle child_process_handle,
|
| int child_client_id,
|
| uint32 sync_point) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DCHECK(clients_.find(child_client_id) != clients_.end());
|
| +
|
| + BufferMap& buffers = clients_[child_client_id];
|
| +
|
| + BufferMap::iterator buffer_it = buffers.find(id);
|
| + if (buffer_it == buffers.end()) {
|
| + LOG(ERROR) << "Invalid GpuMemoryBuffer ID for child process.";
|
| + return;
|
| + }
|
| +
|
| + // This can happen if a child process managed to trigger a call to this while
|
| + // a buffer is in the process of being allocated.
|
| + if (buffer_it->second == gfx::EMPTY_BUFFER) {
|
| + LOG(ERROR) << "Invalid GpuMemoryBuffer type.";
|
| + return;
|
| + }
|
|
|
| GpuMemoryBufferImpl::DeletedByChildProcess(
|
| - type, id, child_process_handle, child_client_id, sync_point);
|
| + buffer_it->second, id, child_process_handle, child_client_id, sync_point);
|
| +
|
| + buffers.erase(buffer_it);
|
| }
|
|
|
| void BrowserGpuMemoryBufferManager::ProcessRemoved(
|
| - base::ProcessHandle process_handle) {
|
| - // TODO(reveman): Handle child process removal correctly.
|
| + base::ProcessHandle process_handle,
|
| + int client_id) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + ClientMap::iterator client_it = clients_.find(client_id);
|
| + if (client_it == clients_.end())
|
| + return;
|
| +
|
| + for (auto &buffer_it : client_it->second) {
|
| + // This might happen if buffer is currenlty in the process of being
|
| + // allocated. The buffer will in that case be cleaned up when allocation
|
| + // completes.
|
| + if (buffer_it.second == gfx::EMPTY_BUFFER)
|
| + continue;
|
| +
|
| + GpuMemoryBufferImpl::DeletedByChildProcess(buffer_it.second,
|
| + buffer_it.first,
|
| + process_handle,
|
| + client_id,
|
| + 0);
|
| + }
|
| +
|
| + clients_.erase(client_it);
|
| +}
|
| +
|
| +void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForChildProcess(
|
| + base::ProcessHandle child_process_handle,
|
| + int child_client_id,
|
| + const AllocationCallback& callback,
|
| + const gfx::GpuMemoryBufferHandle& handle) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + ClientMap::iterator client_it = clients_.find(child_client_id);
|
| +
|
| + // This can happen if the child process is removed while the buffer is being
|
| + // allocated.
|
| + if (client_it == clients_.end()) {
|
| + if (!handle.is_null()) {
|
| + GpuMemoryBufferImpl::DeletedByChildProcess(handle.type,
|
| + handle.id,
|
| + child_process_handle,
|
| + child_client_id,
|
| + 0);
|
| + }
|
| + callback.Run(gfx::GpuMemoryBufferHandle());
|
| + return;
|
| + }
|
| +
|
| + BufferMap& buffers = client_it->second;
|
| +
|
| + BufferMap::iterator buffer_it = buffers.find(handle.id);
|
| + DCHECK(buffer_it != buffers.end());
|
| + DCHECK_EQ(buffer_it->second, gfx::EMPTY_BUFFER);
|
| +
|
| + if (handle.is_null()) {
|
| + buffers.erase(buffer_it);
|
| + callback.Run(gfx::GpuMemoryBufferHandle());
|
| + return;
|
| + }
|
| +
|
| + // Store the type for this buffer so it can be cleaned up if the child
|
| + // process is removed.
|
| + buffer_it->second = handle.type;
|
| +
|
| + callback.Run(handle);
|
| }
|
|
|
| // static
|
| @@ -152,11 +247,4 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
|
| request->event.Signal();
|
| }
|
|
|
| -void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
|
| - gfx::GpuMemoryBuffer* buffer,
|
| - uint32 sync_point) {
|
| - static_cast<GpuMemoryBufferImpl*>(buffer)
|
| - ->set_destruction_sync_point(sync_point);
|
| -}
|
| -
|
| } // namespace content
|
|
|