Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(574)

Unified Diff: content/browser/gpu/browser_gpu_memory_buffer_manager.cc

Issue 1189943002: content: Fix lost context handling when using native GpuMemoryBuffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 b6162ba5c4549fc2f22e1644687edb831b0c1828..094f8f87b0c837adeec0527ce5c3372344fc09cc 100644
--- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -6,26 +6,86 @@
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
+#include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_switches.h"
+#include "gpu/GLES2/gl2extchromium.h"
+
+#if defined(OS_MACOSX)
+#include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
+#endif
+
+#if defined(OS_ANDROID)
+#include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
+#endif
+
+#if defined(USE_OZONE)
+#include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h"
+#endif
namespace content {
namespace {
-BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
+bool IsGpuMemoryBufferFactoryConfigurationSupported(
+ gfx::GpuMemoryBufferType type,
+ const GpuMemoryBufferFactory::Configuration& configuration) {
+ switch (type) {
+ case gfx::SHARED_MEMORY_BUFFER:
+ return GpuMemoryBufferFactorySharedMemory::
+ IsGpuMemoryBufferConfigurationSupported(configuration.format,
+ configuration.usage);
+#if defined(OS_MACOSX)
+ case gfx::IO_SURFACE_BUFFER:
+ return GpuMemoryBufferFactoryIOSurface::
+ IsGpuMemoryBufferConfigurationSupported(configuration.format,
+ configuration.usage);
+#endif
+#if defined(OS_ANDROID)
+ case gfx::SURFACE_TEXTURE_BUFFER:
+ return GpuMemoryBufferFactorySurfaceTexture::
+ IsGpuMemoryBufferConfigurationSupported(configuration.format,
+ configuration.usage);
+#endif
+#if defined(USE_OZONE)
+ case gfx::OZONE_NATIVE_BUFFER:
+ return GpuMemoryBufferFactoryOzoneNativeBuffer::
+ IsGpuMemoryBufferConfigurationSupported(configuration.format,
+ configuration.usage);
+#endif
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+gfx::GpuMemoryBufferType GetGpuMemoryBufferFactoryType() {
+ std::vector<gfx::GpuMemoryBufferType> supported_types;
+ GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
+ DCHECK(!supported_types.empty());
+
+ // The GPU service will always use the preferred type.
+ return supported_types[0];
+}
// Global atomic to generate gpu memory buffer unique IDs.
base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id;
const char kMemoryAllocatorName[] = "gpumemorybuffer";
+base::LazyInstance<BrowserGpuMemoryBufferManager>::Leaky
piman 2015/06/19 19:29:48 I'm not crazy about leaving this Leaky, because it
reveman 2015/06/22 17:09:12 Makes sense. Done.
+ g_gpu_memory_buffer_manager = LAZY_INSTANCE_INITIALIZER;
+
} // namespace
struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
@@ -50,23 +110,19 @@ struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
scoped_ptr<gfx::GpuMemoryBuffer> result;
};
-BrowserGpuMemoryBufferManager::BrowserGpuMemoryBufferManager(
- GpuMemoryBufferFactoryHost* gpu_memory_buffer_factory_host,
- int gpu_client_id)
- : gpu_memory_buffer_factory_host_(gpu_memory_buffer_factory_host),
- gpu_client_id_(gpu_client_id),
- weak_ptr_factory_(this) {
- DCHECK(!g_gpu_memory_buffer_manager);
- g_gpu_memory_buffer_manager = this;
+BrowserGpuMemoryBufferManager::BrowserGpuMemoryBufferManager()
+ : factory_type_(GetGpuMemoryBufferFactoryType()),
+ supported_configurations_(
+ GetSupportedGpuMemoryBufferConfigurations(factory_type_)),
+ gpu_host_id_(0) {
}
BrowserGpuMemoryBufferManager::~BrowserGpuMemoryBufferManager() {
- g_gpu_memory_buffer_manager = nullptr;
}
// static
BrowserGpuMemoryBufferManager* BrowserGpuMemoryBufferManager::current() {
- return g_gpu_memory_buffer_manager;
+ return g_gpu_memory_buffer_manager.Pointer();
}
scoped_ptr<gfx::GpuMemoryBuffer>
@@ -74,7 +130,7 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer(
const gfx::Size& size,
gfx::GpuMemoryBuffer::Format format,
gfx::GpuMemoryBuffer::Usage usage) {
- return AllocateGpuMemoryBufferCommon(size, format, usage, 0);
+ return AllocateGpuMemoryBufferForSurface(size, format, usage, 0);
}
scoped_ptr<gfx::GpuMemoryBuffer>
@@ -83,46 +139,10 @@ BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout(
gfx::GpuMemoryBuffer::Format format,
int32 surface_id) {
DCHECK_GT(surface_id, 0);
- return AllocateGpuMemoryBufferCommon(
+ return AllocateGpuMemoryBufferForSurface(
size, format, gfx::GpuMemoryBuffer::SCANOUT, surface_id);
}
-scoped_ptr<gfx::GpuMemoryBuffer>
-BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferCommon(
- const gfx::Size& size,
- gfx::GpuMemoryBuffer::Format format,
- gfx::GpuMemoryBuffer::Usage usage,
- int32 surface_id) {
- DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Fallback to shared memory buffer if |format| and |usage| are not supported
- // by factory.
- if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported(
- format, usage)) {
- DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(format))
- << format;
- DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage)) << usage;
- return GpuMemoryBufferImplSharedMemory::Create(
- g_next_gpu_memory_buffer_id.GetNext(), size, format);
- }
-
- AllocateGpuMemoryBufferRequest request(size, format, usage, gpu_client_id_,
- surface_id);
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO,
- base::Unretained(this), // Safe as we wait for result below.
- 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,
@@ -134,39 +154,28 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext();
- BufferMap& buffers = clients_[child_client_id];
- DCHECK(buffers.find(new_id) == buffers.end());
-
- // Fallback to shared memory buffer if |format| and |usage| are not supported
- // by factory.
- if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported(
- format, usage)) {
- // Early out if we cannot fallback to shared memory buffer.
- if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
- !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
- !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) {
- callback.Run(gfx::GpuMemoryBufferHandle());
- return;
- }
+ // Use service side allocation if this is a supported configuration.
+ if (IsGpuMemoryBufferConfigurationSupported(format, usage)) {
+ AllocateGpuMemoryBufferOnIO(new_id, size, format, usage, child_client_id, 0,
+ callback);
+ return;
+ }
- buffers[new_id] = BufferInfo(size, format, gfx::SHARED_MEMORY_BUFFER);
- callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
- new_id, size, format, child_process_handle));
+ // Early out if we cannot fallback to shared memory buffer.
+ if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
+ !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
+ !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) {
+ callback.Run(gfx::GpuMemoryBufferHandle());
return;
}
- // 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] = BufferInfo(size, format, gfx::EMPTY_BUFFER);
-
- gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer(
- new_id, size, format, usage, child_client_id, 0,
- base::Bind(&BrowserGpuMemoryBufferManager::
- GpuMemoryBufferAllocatedForChildProcess,
- weak_ptr_factory_.GetWeakPtr(), new_id, child_client_id,
- callback));
+ BufferMap& buffers = clients_[child_client_id];
+ DCHECK(buffers.find(new_id) == buffers.end());
+
+ // Allocate shared memory buffer as fallback.
+ buffers[new_id] = BufferInfo(size, format, gfx::SHARED_MEMORY_BUFFER, 0);
+ callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
+ new_id, size, format, child_process_handle));
}
gfx::GpuMemoryBuffer*
@@ -213,38 +222,34 @@ bool BrowserGpuMemoryBufferManager::OnMemoryDump(
return true;
}
+uint32 BrowserGpuMemoryBufferManager::GetImageTextureTarget(
+ gfx::GpuMemoryBuffer::Format format,
+ gfx::GpuMemoryBuffer::Usage usage) const {
+ if (!IsGpuMemoryBufferConfigurationSupported(format, usage))
+ return GL_TEXTURE_2D;
+
+ switch (factory_type_) {
+ case gfx::SURFACE_TEXTURE_BUFFER:
+ case gfx::OZONE_NATIVE_BUFFER:
+ // GPU memory buffers that are shared with the GL using EGLImages require
+ // TEXTURE_EXTERNAL_OES.
+ return GL_TEXTURE_EXTERNAL_OES;
+ case gfx::IO_SURFACE_BUFFER:
+ // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB.
+ return GL_TEXTURE_RECTANGLE_ARB;
+ default:
+ return GL_TEXTURE_2D;
+ }
+}
+
void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
base::ProcessHandle child_process_handle,
int child_client_id,
uint32 sync_point) {
DCHECK_CURRENTLY_ON(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.type == gfx::EMPTY_BUFFER) {
- LOG(ERROR) << "Invalid GpuMemoryBuffer type.";
- return;
- }
-
- // Buffers allocated using the factory need to be destroyed through the
- // factory.
- if (buffer_it->second.type != gfx::SHARED_MEMORY_BUFFER) {
- gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id,
- child_client_id,
- sync_point);
- }
- buffers.erase(buffer_it);
+ DestroyGpuMemoryBufferOnIO(id, child_client_id, sync_point);
}
void BrowserGpuMemoryBufferManager::ProcessRemoved(
@@ -263,29 +268,131 @@ void BrowserGpuMemoryBufferManager::ProcessRemoved(
if (buffer.second.type == gfx::EMPTY_BUFFER)
continue;
- // Skip shared memory buffers as they were not allocated using the factory.
- if (buffer.second.type == gfx::SHARED_MEMORY_BUFFER)
- continue;
-
- gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(buffer.first,
- client_id, 0);
+ GpuProcessHost* host = GpuProcessHost::FromID(buffer.second.gpu_host_id);
+ if (host)
+ host->DestroyGpuMemoryBuffer(buffer.first, client_id, 0);
}
clients_.erase(client_it);
}
-void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
+// static
+std::vector<GpuMemoryBufferFactory::Configuration>
+BrowserGpuMemoryBufferManager::GetSupportedGpuMemoryBufferConfigurations(
+ gfx::GpuMemoryBufferType type) {
+ std::vector<GpuMemoryBufferFactory::Configuration> configurations;
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNativeGpuMemoryBuffers)) {
+ const GpuMemoryBufferFactory::Configuration kNativeConfigurations[] = {
+ {gfx::GpuMemoryBuffer::R_8, gfx::GpuMemoryBuffer::MAP},
+ {gfx::GpuMemoryBuffer::R_8, gfx::GpuMemoryBuffer::PERSISTENT_MAP},
+ {gfx::GpuMemoryBuffer::RGBA_4444, gfx::GpuMemoryBuffer::MAP},
+ {gfx::GpuMemoryBuffer::RGBA_4444, gfx::GpuMemoryBuffer::PERSISTENT_MAP},
+ {gfx::GpuMemoryBuffer::RGBA_8888, gfx::GpuMemoryBuffer::MAP},
+ {gfx::GpuMemoryBuffer::RGBA_8888, gfx::GpuMemoryBuffer::PERSISTENT_MAP},
+ {gfx::GpuMemoryBuffer::BGRA_8888, gfx::GpuMemoryBuffer::MAP},
+ {gfx::GpuMemoryBuffer::BGRA_8888,
+ gfx::GpuMemoryBuffer::PERSISTENT_MAP}};
+ for (auto& configuration : kNativeConfigurations) {
+ if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
+ configurations.push_back(configuration);
+ }
+ }
+
+#if defined(USE_OZONE)
+ const GpuMemoryBufferFactory::Configuration kScanoutConfigurations[] = {
+ {gfx::GpuMemoryBuffer::BGRA_8888, gfx::GpuMemoryBuffer::SCANOUT},
+ {gfx::GpuMemoryBuffer::RGBX_8888, gfx::GpuMemoryBuffer::SCANOUT}};
+ for (auto& configuration : kScanoutConfigurations) {
+ if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
+ configurations.push_back(configuration);
+ }
+#endif
+
+ return configurations;
+}
+
+scoped_ptr<gfx::GpuMemoryBuffer>
+BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface(
+ const gfx::Size& size,
+ gfx::GpuMemoryBuffer::Format format,
+ gfx::GpuMemoryBuffer::Usage usage,
+ int32 surface_id) {
+ DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ AllocateGpuMemoryBufferRequest request(
+ size, format, usage,
+ BrowserGpuChannelHostFactory::instance()->GetGpuChannelId(), surface_id);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO,
+ base::Unretained(this), base::Unretained(&request)));
+
+ // We're blocking the UI thread, which is generally undesirable.
+ TRACE_EVENT0(
+ "browser",
+ "BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface");
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ request.event.Wait();
+ return request.result.Pass();
+}
+
+void BrowserGpuMemoryBufferManager::GpuMemoryBufferDeleted(
+ gfx::GpuMemoryBufferId id,
+ int client_id,
+ uint32 sync_point) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
+ base::Unretained(this), id, client_id, sync_point));
+}
+
+bool BrowserGpuMemoryBufferManager::IsGpuMemoryBufferConfigurationSupported(
+ gfx::GpuMemoryBuffer::Format format,
+ gfx::GpuMemoryBuffer::Usage usage) const {
+ for (auto& configuration : supported_configurations_) {
+ if (configuration.format == format && configuration.usage == usage)
+ return true;
+ }
+ return false;
+}
+
+void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
AllocateGpuMemoryBufferRequest* request) {
- // Note: Unretained is safe as this is only used for synchronous allocation
- // from a non-IO thread.
- gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer(
- g_next_gpu_memory_buffer_id.GetNext(), request->size, request->format,
- request->usage, request->client_id, request->surface_id,
- base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
- base::Unretained(this), base::Unretained(request)));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext();
+
+ // Use service side allocation if this is a supported configuration.
+ if (IsGpuMemoryBufferConfigurationSupported(request->format,
+ request->usage)) {
+ AllocateGpuMemoryBufferOnIO(
+ new_id, request->size, request->format, request->usage,
+ request->client_id, request->surface_id,
+ base::Bind(&BrowserGpuMemoryBufferManager::
+ GpuMemoryBufferAllocatedForSurfaceOnIO,
+ base::Unretained(this), base::Unretained(request)));
+ return;
+ }
+
+ DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format))
+ << request->format;
+ DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
+ << request->usage;
+
+ BufferMap& buffers = clients_[request->client_id];
+ DCHECK(buffers.find(new_id) == buffers.end());
+
+ // Allocate shared memory buffer as fallback.
+ buffers[new_id] =
+ BufferInfo(request->size, request->format, gfx::SHARED_MEMORY_BUFFER, 0);
+ request->result = GpuMemoryBufferImplSharedMemory::Create(
+ new_id, request->size, request->format);
+ request->event.Signal();
}
-void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
+void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForSurfaceOnIO(
AllocateGpuMemoryBufferRequest* request,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -296,39 +403,66 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
return;
}
- DCHECK_NE(handle.type, gfx::SHARED_MEMORY_BUFFER);
request->result = GpuMemoryBufferImpl::CreateFromHandle(
handle, request->size, request->format, request->usage,
base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferDeleted,
- weak_ptr_factory_.GetWeakPtr(), handle.id,
- request->client_id));
+ base::Unretained(this), handle.id, request->client_id));
request->event.Signal();
}
-void BrowserGpuMemoryBufferManager::GpuMemoryBufferDeleted(
+void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::GpuMemoryBuffer::Format format,
+ gfx::GpuMemoryBuffer::Usage usage,
int client_id,
- uint32 sync_point) {
- gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id,
- client_id,
- sync_point);
+ int surface_id,
+ const AllocationCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ BufferMap& buffers = clients_[client_id];
+ DCHECK(buffers.find(id) == buffers.end());
+
+ GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
+ if (!host) {
+ host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE);
+ if (!host) {
+ LOG(ERROR) << "Failed to launch GPU process.";
+ callback.Run(gfx::GpuMemoryBufferHandle());
+ return;
+ }
+ gpu_host_id_ = host->host_id();
+ }
+
+ // Note: Handling of cases where the client 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[id] = BufferInfo(size, format, gfx::EMPTY_BUFFER, 0);
+
+ host->CreateGpuMemoryBuffer(
+ id, size, format, usage, client_id, surface_id,
+ base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
+ base::Unretained(this), id, client_id, gpu_host_id_,
+ callback));
}
-void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForChildProcess(
+void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO(
gfx::GpuMemoryBufferId id,
- int child_client_id,
+ int client_id,
+ int gpu_host_id,
const AllocationCallback& callback,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- ClientMap::iterator client_it = clients_.find(child_client_id);
+ ClientMap::iterator client_it = clients_.find(client_id);
- // This can happen if the child process is removed while the buffer is being
- // allocated.
+ // This can happen if client is removed while the buffer is being allocated.
if (client_it == clients_.end()) {
if (!handle.is_null()) {
- gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(
- handle.id, child_client_id, 0);
+ GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id);
+ if (host)
+ host->DestroyGpuMemoryBuffer(handle.id, client_id, 0);
}
callback.Run(gfx::GpuMemoryBufferHandle());
return;
@@ -343,19 +477,48 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedForChildProcess(
// If the handle isn't valid, that means that the GPU process crashed or is
// misbehaving so we remove the buffer entry and run the allocation callback
// with an empty handle to indicate failure.
- bool valid_handle = !handle.is_null() && handle.id == id &&
- handle.type != gfx::SHARED_MEMORY_BUFFER;
+ bool valid_handle = !handle.is_null() && handle.id == id;
if (!valid_handle) {
piman 2015/06/19 19:29:48 Do you need retry logic, like we do for the channe
reveman 2015/06/22 17:09:12 Good point. Added retry logic to latest patch. No
buffers.erase(buffer_it);
callback.Run(gfx::GpuMemoryBufferHandle());
return;
}
- // Store the type of this buffer so it can be cleaned up if the child
- // process is removed.
+ // Store the type and host id of this buffer so it can be cleaned up if the
+ // client is removed.
buffer_it->second.type = handle.type;
+ buffer_it->second.gpu_host_id = gpu_host_id;
callback.Run(handle);
}
+void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
+ gfx::GpuMemoryBufferId id,
+ int client_id,
+ uint32 sync_point) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(clients_.find(client_id) != clients_.end());
+
+ BufferMap& buffers = clients_[client_id];
+
+ BufferMap::iterator buffer_it = buffers.find(id);
+ if (buffer_it == buffers.end()) {
+ LOG(ERROR) << "Invalid GpuMemoryBuffer ID for client.";
+ return;
+ }
+
+ // This can happen if a client managed to call this while a buffer is in the
+ // process of being allocated.
+ if (buffer_it->second.type == gfx::EMPTY_BUFFER) {
+ LOG(ERROR) << "Invalid GpuMemoryBuffer type.";
+ return;
+ }
+
+ GpuProcessHost* host = GpuProcessHost::FromID(buffer_it->second.gpu_host_id);
+ if (host)
+ host->DestroyGpuMemoryBuffer(id, client_id, sync_point);
+
+ buffers.erase(buffer_it);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698