Commit 0269a5cd authored by alexst's avatar alexst Committed by Commit bot

Enable sync allocation of GpuMemoryBuffers from the browser process.

This operation will be serviced on the IO thread in the GPU process and is expected to be very quick.

These sync allocations should be infrequent and happen mostly during startup to enable rendering via EGLImage.

BUG=380861

Review URL: https://codereview.chromium.org/540443002

Cr-Commit-Position: refs/heads/master@{#294109}
parent 4bf71ed7
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_memory_buffer_factory_host_impl.h"
#include "content/browser/gpu/gpu_process_host.h" #include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/gpu_surface_tracker.h" #include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/common/child_process_host_impl.h" #include "content/common/child_process_host_impl.h"
...@@ -231,8 +232,8 @@ void BrowserGpuChannelHostFactory::Terminate() { ...@@ -231,8 +232,8 @@ void BrowserGpuChannelHostFactory::Terminate() {
BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
: gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
shutdown_event_(new base::WaitableEvent(true, false)), shutdown_event_(new base::WaitableEvent(true, false)),
gpu_host_id_(0), gpu_memory_buffer_factory_host_(new GpuMemoryBufferFactoryHostImpl),
next_create_gpu_memory_buffer_request_id_(0) { gpu_host_id_(0) {
} }
BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
...@@ -370,6 +371,7 @@ void BrowserGpuChannelHostFactory::GpuChannelEstablished() { ...@@ -370,6 +371,7 @@ void BrowserGpuChannelHostFactory::GpuChannelEstablished() {
shutdown_event_.get()); shutdown_event_.get());
} }
gpu_host_id_ = pending_request_->gpu_host_id(); gpu_host_id_ = pending_request_->gpu_host_id();
gpu_memory_buffer_factory_host_->set_gpu_host_id(gpu_host_id_);
pending_request_ = NULL; pending_request_ = NULL;
for (size_t n = 0; n < established_callbacks_.size(); n++) for (size_t n = 0; n < established_callbacks_.size(); n++)
...@@ -409,45 +411,6 @@ void BrowserGpuChannelHostFactory::DeleteGpuMemoryBuffer( ...@@ -409,45 +411,6 @@ void BrowserGpuChannelHostFactory::DeleteGpuMemoryBuffer(
base::Passed(&buffer))); base::Passed(&buffer)));
} }
void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host) {
callback.Run(gfx::GpuMemoryBufferHandle());
return;
}
uint32 request_id = next_create_gpu_memory_buffer_request_id_++;
create_gpu_memory_buffer_requests_[request_id] = callback;
host->CreateGpuMemoryBuffer(
handle,
size,
internalformat,
usage,
base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated,
base::Unretained(this),
request_id));
}
void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host)
return;
host->DestroyGpuMemoryBuffer(handle, sync_point);
}
// static // static
void BrowserGpuChannelHostFactory::AddFilterOnIO( void BrowserGpuChannelHostFactory::AddFilterOnIO(
int host_id, int host_id,
...@@ -492,11 +455,12 @@ void BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO( ...@@ -492,11 +455,12 @@ void BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO(
return; return;
} }
request->result = GpuMemoryBufferImpl::Create( GpuMemoryBufferImpl::Create(
gfx::Size(request->width, request->height), gfx::Size(request->width, request->height),
request->internalformat, request->internalformat,
request->usage).PassAs<gfx::GpuMemoryBuffer>(); request->usage,
request->event.Signal(); base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated,
base::Unretained(request)));
} }
// static // static
...@@ -504,16 +468,14 @@ void BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO( ...@@ -504,16 +468,14 @@ void BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO(
scoped_ptr<gfx::GpuMemoryBuffer> buffer) { scoped_ptr<gfx::GpuMemoryBuffer> buffer) {
} }
// static
void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated(
uint32 request_id, AllocateGpuMemoryBufferRequest* request,
const gfx::GpuMemoryBufferHandle& handle) { scoped_ptr<GpuMemoryBufferImpl> buffer) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
CreateGpuMemoryBufferCallbackMap::iterator iter = request->result = buffer.PassAs<gfx::GpuMemoryBuffer>();
create_gpu_memory_buffer_requests_.find(request_id); request->event.Signal();
DCHECK(iter != create_gpu_memory_buffer_requests_.end());
iter->second.Run(handle);
create_gpu_memory_buffer_requests_.erase(iter);
} }
} // namespace content } // namespace content
...@@ -10,14 +10,14 @@ ...@@ -10,14 +10,14 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
#include "ipc/message_filter.h" #include "ipc/message_filter.h"
namespace content { namespace content {
class GpuMemoryBufferImpl;
class GpuMemoryBufferFactoryHostImpl;
class CONTENT_EXPORT BrowserGpuChannelHostFactory class CONTENT_EXPORT BrowserGpuChannelHostFactory
: public GpuChannelHostFactory, : public GpuChannelHostFactory {
public GpuMemoryBufferFactoryHost {
public: public:
static void Initialize(bool establish_gpu_channel); static void Initialize(bool establish_gpu_channel);
static void Terminate(); static void Terminate();
...@@ -41,16 +41,6 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory ...@@ -41,16 +41,6 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
virtual void DeleteGpuMemoryBuffer( virtual void DeleteGpuMemoryBuffer(
scoped_ptr<gfx::GpuMemoryBuffer> buffer) OVERRIDE; scoped_ptr<gfx::GpuMemoryBuffer> buffer) OVERRIDE;
// GpuMemoryBufferFactoryHost implementation.
virtual void CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) OVERRIDE;
virtual void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) OVERRIDE;
// Specify a task runner and callback to be used for a set of messages. The // Specify a task runner and callback to be used for a set of messages. The
// callback will be set up on the current GpuProcessHost, identified by // callback will be set up on the current GpuProcessHost, identified by
// GpuProcessHostId(). // GpuProcessHostId().
...@@ -91,19 +81,16 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory ...@@ -91,19 +81,16 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
AllocateGpuMemoryBufferRequest* request); AllocateGpuMemoryBufferRequest* request);
static void DeleteGpuMemoryBufferOnIO( static void DeleteGpuMemoryBufferOnIO(
scoped_ptr<gfx::GpuMemoryBuffer> buffer); scoped_ptr<gfx::GpuMemoryBuffer> buffer);
void OnGpuMemoryBufferCreated(uint32 request_id, static void OnGpuMemoryBufferCreated(AllocateGpuMemoryBufferRequest* request,
const gfx::GpuMemoryBufferHandle& handle); scoped_ptr<GpuMemoryBufferImpl> buffer);
const int gpu_client_id_; const int gpu_client_id_;
scoped_ptr<base::WaitableEvent> shutdown_event_; scoped_ptr<base::WaitableEvent> shutdown_event_;
scoped_refptr<GpuChannelHost> gpu_channel_; scoped_refptr<GpuChannelHost> gpu_channel_;
scoped_ptr<GpuMemoryBufferFactoryHostImpl> gpu_memory_buffer_factory_host_;
int gpu_host_id_; int gpu_host_id_;
scoped_refptr<EstablishRequest> pending_request_; scoped_refptr<EstablishRequest> pending_request_;
std::vector<base::Closure> established_callbacks_; std::vector<base::Closure> established_callbacks_;
uint32 next_create_gpu_memory_buffer_request_id_;
typedef std::map<uint32, CreateGpuMemoryBufferCallback>
CreateGpuMemoryBufferCallbackMap;
CreateGpuMemoryBufferCallbackMap create_gpu_memory_buffer_requests_;
static BrowserGpuChannelHostFactory* instance_; static BrowserGpuChannelHostFactory* instance_;
......
// Copyright (c) 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/gpu_memory_buffer_factory_host_impl.h"
#include "base/bind.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/gpu_memory_buffer.h"
namespace content {
GpuMemoryBufferFactoryHostImpl::GpuMemoryBufferFactoryHostImpl()
: gpu_host_id_(0), next_create_gpu_memory_buffer_request_id_(0) {
}
GpuMemoryBufferFactoryHostImpl::~GpuMemoryBufferFactoryHostImpl() {
}
void GpuMemoryBufferFactoryHostImpl::CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host) {
callback.Run(gfx::GpuMemoryBufferHandle());
return;
}
uint32 request_id = next_create_gpu_memory_buffer_request_id_++;
create_gpu_memory_buffer_requests_[request_id] = callback;
host->CreateGpuMemoryBuffer(
handle,
size,
internalformat,
usage,
base::Bind(&GpuMemoryBufferFactoryHostImpl::OnGpuMemoryBufferCreated,
base::Unretained(this),
request_id));
}
void GpuMemoryBufferFactoryHostImpl::DestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host)
return;
host->DestroyGpuMemoryBuffer(handle, sync_point);
}
void GpuMemoryBufferFactoryHostImpl::OnGpuMemoryBufferCreated(
uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
CreateGpuMemoryBufferCallbackMap::iterator iter =
create_gpu_memory_buffer_requests_.find(request_id);
DCHECK(iter != create_gpu_memory_buffer_requests_.end());
iter->second.Run(handle);
create_gpu_memory_buffer_requests_.erase(iter);
}
} // namespace content
// Copyright (c) 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.
#ifndef CONTENT_BROWSER_GPU_GPU_MEMORY_BUFFER_FACTORY_HOST_IMPL_H_
#define CONTENT_BROWSER_GPU_GPU_MEMORY_BUFFER_FACTORY_HOST_IMPL_H_
#include <map>
#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
namespace content {
class GpuMemoryBufferImpl;
class CONTENT_EXPORT GpuMemoryBufferFactoryHostImpl
: public GpuMemoryBufferFactoryHost {
public:
GpuMemoryBufferFactoryHostImpl();
virtual ~GpuMemoryBufferFactoryHostImpl();
// Overridden from GpuMemoryBufferFactoryHost:
virtual void CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) OVERRIDE;
virtual void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) OVERRIDE;
void set_gpu_host_id(int gpu_host_id) { gpu_host_id_ = gpu_host_id; }
private:
void OnGpuMemoryBufferCreated(uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle);
int gpu_host_id_;
uint32 next_create_gpu_memory_buffer_request_id_;
typedef std::map<uint32, CreateGpuMemoryBufferCallback>
CreateGpuMemoryBufferCallbackMap;
CreateGpuMemoryBufferCallbackMap create_gpu_memory_buffer_requests_;
DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactoryHostImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_GPU_GPU_MEMORY_BUFFER_FACTORY_HOST_IMPL_H_
...@@ -15,6 +15,8 @@ namespace content { ...@@ -15,6 +15,8 @@ namespace content {
// Provides common implementation of a GPU memory buffer. // Provides common implementation of a GPU memory buffer.
class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
public: public:
typedef base::Callback<void(scoped_ptr<GpuMemoryBufferImpl> buffer)>
CreationCallback;
typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)> typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
AllocationCallback; AllocationCallback;
...@@ -22,9 +24,10 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { ...@@ -22,9 +24,10 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
// Creates a GPU memory buffer instance with |size| and |internalformat| for // Creates a GPU memory buffer instance with |size| and |internalformat| for
// |usage|. // |usage|.
static scoped_ptr<GpuMemoryBufferImpl> Create(const gfx::Size& size, static void Create(const gfx::Size& size,
unsigned internalformat, unsigned internalformat,
unsigned usage); unsigned usage,
const CreationCallback& callback);
// Allocates a GPU memory buffer with |size| and |internalformat| for |usage| // Allocates a GPU memory buffer with |size| and |internalformat| for |usage|
// by |child_process| identified by |child_id|. The |handle| returned can be // by |child_process| identified by |child_id|. The |handle| returned can be
......
...@@ -10,21 +10,18 @@ ...@@ -10,21 +10,18 @@
namespace content { namespace content {
// static // static
scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create( void GpuMemoryBufferImpl::Create(const gfx::Size& size,
const gfx::Size& size, unsigned internalformat,
unsigned internalformat, unsigned usage,
unsigned usage) { const CreationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) { size, internalformat, usage)) {
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( GpuMemoryBufferImplSharedMemory::Create(
new GpuMemoryBufferImplSharedMemory(size, internalformat)); size, internalformat, usage, callback);
if (!buffer->Initialize()) return;
return scoped_ptr<GpuMemoryBufferImpl>();
return buffer.PassAs<GpuMemoryBufferImpl>();
} }
return scoped_ptr<GpuMemoryBufferImpl>(); callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
} }
// static // static
......
...@@ -9,21 +9,18 @@ ...@@ -9,21 +9,18 @@
namespace content { namespace content {
// static // static
scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create( void GpuMemoryBufferImpl::Create(const gfx::Size& size,
const gfx::Size& size, unsigned internalformat,
unsigned internalformat, unsigned usage,
unsigned usage) { const CreationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) { size, internalformat, usage)) {
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( GpuMemoryBufferImplSharedMemory::Create(
new GpuMemoryBufferImplSharedMemory(size, internalformat)); size, internalformat, usage, callback);
if (!buffer->Initialize()) return;
return scoped_ptr<GpuMemoryBufferImpl>();
return buffer.PassAs<GpuMemoryBufferImpl>();
} }
return scoped_ptr<GpuMemoryBufferImpl>(); callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
} }
// static // static
......
...@@ -10,21 +10,18 @@ ...@@ -10,21 +10,18 @@
namespace content { namespace content {
// static // static
scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create( void GpuMemoryBufferImpl::Create(const gfx::Size& size,
const gfx::Size& size, unsigned internalformat,
unsigned internalformat, unsigned usage,
unsigned usage) { const CreationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) { size, internalformat, usage)) {
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( GpuMemoryBufferImplSharedMemory::Create(
new GpuMemoryBufferImplSharedMemory(size, internalformat)); size, internalformat, usage, callback);
if (!buffer->Initialize()) return;
return scoped_ptr<GpuMemoryBufferImpl>();
return buffer.PassAs<GpuMemoryBufferImpl>();
} }
return scoped_ptr<GpuMemoryBufferImpl>(); callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
} }
// static // static
......
...@@ -10,21 +10,25 @@ ...@@ -10,21 +10,25 @@
namespace content { namespace content {
// static // static
scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create( void GpuMemoryBufferImpl::Create(const gfx::Size& size,
const gfx::Size& size, unsigned internalformat,
unsigned internalformat, unsigned usage,
unsigned usage) { const CreationCallback& callback) {
if (GpuMemoryBufferImplOzoneNativeBuffer::IsConfigurationSupported(
internalformat, usage)) {
GpuMemoryBufferImplOzoneNativeBuffer::Create(
size, internalformat, usage, callback);
return;
}
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) { size, internalformat, usage)) {
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( GpuMemoryBufferImplSharedMemory::Create(
new GpuMemoryBufferImplSharedMemory(size, internalformat)); size, internalformat, usage, callback);
if (!buffer->Initialize()) return;
return scoped_ptr<GpuMemoryBufferImpl>();
return buffer.PassAs<GpuMemoryBufferImpl>();
} }
return scoped_ptr<GpuMemoryBufferImpl>(); callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
} }
// static // static
......
...@@ -14,6 +14,15 @@ namespace { ...@@ -14,6 +14,15 @@ namespace {
base::StaticAtomicSequenceNumber g_next_buffer_id; base::StaticAtomicSequenceNumber g_next_buffer_id;
void AllocatedOzoneNativeBuffer(
const gfx::Size& size,
unsigned internalformat,
const GpuMemoryBufferImpl::CreationCallback& callback,
const gfx::GpuMemoryBufferHandle& handle) {
callback.Run(
GpuMemoryBufferImpl::CreateFromHandle(handle, size, internalformat));
}
} // namespace } // namespace
GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer( GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer(
...@@ -25,6 +34,26 @@ GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer( ...@@ -25,6 +34,26 @@ GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer(
GpuMemoryBufferImplOzoneNativeBuffer::~GpuMemoryBufferImplOzoneNativeBuffer() { GpuMemoryBufferImplOzoneNativeBuffer::~GpuMemoryBufferImplOzoneNativeBuffer() {
} }
// static
void GpuMemoryBufferImplOzoneNativeBuffer::Create(
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreationCallback& callback) {
gfx::GpuMemoryBufferHandle handle;
handle.global_id.primary_id = g_next_buffer_id.GetNext();
// This code makes an assumption that client_id for GPU channel using this
// buffer is zero.
handle.global_id.secondary_id = 0;
handle.type = gfx::OZONE_NATIVE_BUFFER;
GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer(
handle,
size,
internalformat,
usage,
base::Bind(&AllocatedOzoneNativeBuffer, size, internalformat, callback));
}
// static // static
void GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId( void GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId(
const gfx::Size& size, const gfx::Size& size,
...@@ -33,8 +62,7 @@ void GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId( ...@@ -33,8 +62,7 @@ void GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId(
int child_id, int child_id,
const AllocationCallback& callback) { const AllocationCallback& callback) {
gfx::GpuMemoryBufferHandle handle; gfx::GpuMemoryBufferHandle handle;
// +1 ensures we always get non-zero IDs. handle.global_id.primary_id = g_next_buffer_id.GetNext();
handle.global_id.primary_id = g_next_buffer_id.GetNext() + 1;
handle.global_id.secondary_id = child_id; handle.global_id.secondary_id = child_id;
handle.type = gfx::OZONE_NATIVE_BUFFER; handle.type = gfx::OZONE_NATIVE_BUFFER;
GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer( GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer(
......
...@@ -16,6 +16,11 @@ class GpuMemoryBufferImplOzoneNativeBuffer : public GpuMemoryBufferImpl { ...@@ -16,6 +16,11 @@ class GpuMemoryBufferImplOzoneNativeBuffer : public GpuMemoryBufferImpl {
unsigned internalformat); unsigned internalformat);
virtual ~GpuMemoryBufferImplOzoneNativeBuffer(); virtual ~GpuMemoryBufferImplOzoneNativeBuffer();
static void Create(const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreationCallback& callback);
// Allocates an Ozone native buffer backed GPU memory buffer with |size| and // Allocates an Ozone native buffer backed GPU memory buffer with |size| and
// |internalformat| with usage |usage| for use by |child_id|. // |internalformat| with usage |usage| for use by |child_id|.
static void AllocateOzoneNativeBufferForChildId( static void AllocateOzoneNativeBufferForChildId(
......
...@@ -18,6 +18,24 @@ GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory( ...@@ -18,6 +18,24 @@ GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory(
GpuMemoryBufferImplSharedMemory::~GpuMemoryBufferImplSharedMemory() { GpuMemoryBufferImplSharedMemory::~GpuMemoryBufferImplSharedMemory() {
} }
// static
void GpuMemoryBufferImplSharedMemory::Create(const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreationCallback& callback) {
DCHECK(GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage));
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer(
new GpuMemoryBufferImplSharedMemory(size, internalformat));
if (buffer->Initialize()) {
callback.Run(buffer.PassAs<GpuMemoryBufferImpl>());
return;
}
callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
}
// static // static
void GpuMemoryBufferImplSharedMemory::AllocateSharedMemoryForChildProcess( void GpuMemoryBufferImplSharedMemory::AllocateSharedMemoryForChildProcess(
const gfx::Size& size, const gfx::Size& size,
......
...@@ -16,6 +16,11 @@ class GpuMemoryBufferImplSharedMemory : public GpuMemoryBufferImpl { ...@@ -16,6 +16,11 @@ class GpuMemoryBufferImplSharedMemory : public GpuMemoryBufferImpl {
unsigned internalformat); unsigned internalformat);
virtual ~GpuMemoryBufferImplSharedMemory(); virtual ~GpuMemoryBufferImplSharedMemory();
static void Create(const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreationCallback& callback);
// Allocates a shared memory backed GPU memory buffer with |size| and // Allocates a shared memory backed GPU memory buffer with |size| and
// |internalformat| for use by |child_process|. // |internalformat| for use by |child_process|.
static void AllocateSharedMemoryForChildProcess( static void AllocateSharedMemoryForChildProcess(
......
...@@ -9,21 +9,18 @@ ...@@ -9,21 +9,18 @@
namespace content { namespace content {
// static // static
scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create( void GpuMemoryBufferImpl::Create(const gfx::Size& size,
const gfx::Size& size, unsigned internalformat,
unsigned internalformat, unsigned usage,
unsigned usage) { const CreationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) { size, internalformat, usage)) {
scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( GpuMemoryBufferImplSharedMemory::Create(
new GpuMemoryBufferImplSharedMemory(size, internalformat)); size, internalformat, usage, callback);
if (!buffer->Initialize()) return;
return scoped_ptr<GpuMemoryBufferImpl>();
return buffer.PassAs<GpuMemoryBufferImpl>();
} }
return scoped_ptr<GpuMemoryBufferImpl>(); callback.Run(scoped_ptr<GpuMemoryBufferImpl>());
} }
// static // static
......
...@@ -17,24 +17,69 @@ ...@@ -17,24 +17,69 @@
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_program_cache.h" #include "gpu/command_buffer/service/memory_program_cache.h"
#include "gpu/command_buffer/service/shader_translator_cache.h" #include "gpu/command_buffer/service/shader_translator_cache.h"
#include "ipc/message_filter.h"
#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_share_group.h" #include "ui/gl/gl_share_group.h"
namespace content { namespace content {
GpuChannelManager::GpuMemoryBufferOperation::GpuMemoryBufferOperation( namespace {
int32 sync_point,
base::Closure callback)
: sync_point(sync_point), callback(callback) {
}
GpuChannelManager::GpuMemoryBufferOperation::~GpuMemoryBufferOperation() { class GpuChannelManagerMessageFilter : public IPC::MessageFilter {
} public:
GpuChannelManagerMessageFilter(
GpuMemoryBufferFactory* gpu_memory_buffer_factory)
: sender_(NULL), gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {}
virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE {
DCHECK(!sender_);
sender_ = sender;
}
virtual void OnFilterRemoved() OVERRIDE {
DCHECK(sender_);
sender_ = NULL;
}
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
DCHECK(sender_);
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter, message)
IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
protected:
virtual ~GpuChannelManagerMessageFilter() {}
void OnCreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage) {
TRACE_EVENT2("gpu",
"GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
"primary_id",
handle.global_id.primary_id,
"secondary_id",
handle.global_id.secondary_id);
sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
handle, size, internalformat, usage)));
}
IPC::Sender* sender_;
GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
};
} // namespace
GpuChannelManager::GpuChannelManager(MessageRouter* router, GpuChannelManager::GpuChannelManager(MessageRouter* router,
GpuWatchdog* watchdog, GpuWatchdog* watchdog,
base::MessageLoopProxy* io_message_loop, base::MessageLoopProxy* io_message_loop,
base::WaitableEvent* shutdown_event) base::WaitableEvent* shutdown_event,
IPC::SyncChannel* channel)
: weak_factory_(this), : weak_factory_(this),
io_message_loop_(io_message_loop), io_message_loop_(io_message_loop),
shutdown_event_(shutdown_event), shutdown_event_(shutdown_event),
...@@ -44,10 +89,14 @@ GpuChannelManager::GpuChannelManager(MessageRouter* router, ...@@ -44,10 +89,14 @@ GpuChannelManager::GpuChannelManager(MessageRouter* router,
GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit), GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
watchdog_(watchdog), watchdog_(watchdog),
sync_point_manager_(new SyncPointManager), sync_point_manager_(new SyncPointManager),
gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()) { gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()),
channel_(channel),
filter_(new GpuChannelManagerMessageFilter(
gpu_memory_buffer_factory_.get())) {
DCHECK(router_); DCHECK(router_);
DCHECK(io_message_loop); DCHECK(io_message_loop);
DCHECK(shutdown_event); DCHECK(shutdown_event);
channel_->AddFilter(filter_.get());
} }
GpuChannelManager::~GpuChannelManager() { GpuChannelManager::~GpuChannelManager() {
...@@ -56,7 +105,6 @@ GpuChannelManager::~GpuChannelManager() { ...@@ -56,7 +105,6 @@ GpuChannelManager::~GpuChannelManager() {
default_offscreen_surface_->Destroy(); default_offscreen_surface_->Destroy();
default_offscreen_surface_ = NULL; default_offscreen_surface_ = NULL;
} }
DCHECK(gpu_memory_buffer_operations_.empty());
} }
gpu::gles2::ProgramCache* GpuChannelManager::program_cache() { gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
...@@ -110,7 +158,6 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) { ...@@ -110,7 +158,6 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel) IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer, IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
OnCreateViewCommandBuffer) OnCreateViewCommandBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer) IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader) IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
...@@ -188,37 +235,16 @@ void GpuChannelManager::OnCreateViewCommandBuffer( ...@@ -188,37 +235,16 @@ void GpuChannelManager::OnCreateViewCommandBuffer(
Send(new GpuHostMsg_CommandBufferCreated(result)); Send(new GpuHostMsg_CommandBufferCreated(result));
} }
void GpuChannelManager::DestroyGpuMemoryBuffer(
void GpuChannelManager::CreateGpuMemoryBuffer( const gfx::GpuMemoryBufferHandle& handle) {
const gfx::GpuMemoryBufferHandle& handle, io_message_loop_->PostTask(
const gfx::Size& size, FROM_HERE,
unsigned internalformat, base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
unsigned usage) { base::Unretained(this),
Send(new GpuHostMsg_GpuMemoryBufferCreated( handle));
gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
handle, size, internalformat, usage)));
}
void GpuChannelManager::OnCreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage) {
if (gpu_memory_buffer_operations_.empty()) {
CreateGpuMemoryBuffer(handle, size, internalformat, usage);
} else {
gpu_memory_buffer_operations_.push_back(new GpuMemoryBufferOperation(
0,
base::Bind(&GpuChannelManager::CreateGpuMemoryBuffer,
base::Unretained(this),
handle,
size,
internalformat,
usage)));
}
} }
void GpuChannelManager::DestroyGpuMemoryBuffer( void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
const gfx::GpuMemoryBufferHandle& handle) { const gfx::GpuMemoryBufferHandle& handle) {
gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(handle); gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(handle);
} }
...@@ -226,39 +252,14 @@ void GpuChannelManager::DestroyGpuMemoryBuffer( ...@@ -226,39 +252,14 @@ void GpuChannelManager::DestroyGpuMemoryBuffer(
void GpuChannelManager::OnDestroyGpuMemoryBuffer( void GpuChannelManager::OnDestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle, const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) { int32 sync_point) {
if (!sync_point && gpu_memory_buffer_operations_.empty()) { if (!sync_point) {
DestroyGpuMemoryBuffer(handle); DestroyGpuMemoryBuffer(handle);
} else { } else {
gpu_memory_buffer_operations_.push_back(new GpuMemoryBufferOperation( sync_point_manager()->AddSyncPointCallback(
sync_point, sync_point,
base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer, base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
base::Unretained(this), base::Unretained(this),
handle))); handle));
if (sync_point) {
sync_point_manager()->AddSyncPointCallback(
sync_point,
base::Bind(
&GpuChannelManager::OnDestroyGpuMemoryBufferSyncPointRetired,
base::Unretained(this),
gpu_memory_buffer_operations_.back()));
}
}
}
void GpuChannelManager::OnDestroyGpuMemoryBufferSyncPointRetired(
GpuMemoryBufferOperation* gpu_memory_buffer_operation) {
// Mark operation as no longer having a pending sync point.
gpu_memory_buffer_operation->sync_point = 0;
// De-queue operations until we reach a pending sync point.
while (!gpu_memory_buffer_operations_.empty()) {
// Check if operation has a pending sync point.
if (gpu_memory_buffer_operations_.front()->sync_point)
break;
gpu_memory_buffer_operations_.front()->callback.Run();
delete gpu_memory_buffer_operations_.front();
gpu_memory_buffer_operations_.pop_front();
} }
} }
......
...@@ -41,6 +41,8 @@ class ShaderTranslatorCache; ...@@ -41,6 +41,8 @@ class ShaderTranslatorCache;
namespace IPC { namespace IPC {
struct ChannelHandle; struct ChannelHandle;
class SyncChannel;
class MessageFilter;
} }
struct GPUCreateCommandBufferConfig; struct GPUCreateCommandBufferConfig;
...@@ -61,7 +63,8 @@ class GpuChannelManager : public IPC::Listener, ...@@ -61,7 +63,8 @@ class GpuChannelManager : public IPC::Listener,
GpuChannelManager(MessageRouter* router, GpuChannelManager(MessageRouter* router,
GpuWatchdog* watchdog, GpuWatchdog* watchdog,
base::MessageLoopProxy* io_message_loop, base::MessageLoopProxy* io_message_loop,
base::WaitableEvent* shutdown_event); base::WaitableEvent* shutdown_event,
IPC::SyncChannel* channel);
virtual ~GpuChannelManager(); virtual ~GpuChannelManager();
// Remove the channel for a particular renderer. // Remove the channel for a particular renderer.
...@@ -104,15 +107,7 @@ class GpuChannelManager : public IPC::Listener, ...@@ -104,15 +107,7 @@ class GpuChannelManager : public IPC::Listener,
} }
private: private:
struct GpuMemoryBufferOperation {
GpuMemoryBufferOperation(int32 sync_point, base::Closure callback);
~GpuMemoryBufferOperation();
int32 sync_point;
base::Closure callback;
};
typedef base::ScopedPtrHashMap<int, GpuChannel> GpuChannelMap; typedef base::ScopedPtrHashMap<int, GpuChannel> GpuChannelMap;
typedef std::deque<GpuMemoryBufferOperation*> GpuMemoryBufferOperationQueue;
// Message handlers. // Message handlers.
void OnEstablishChannel(int client_id, void OnEstablishChannel(int client_id,
...@@ -128,19 +123,10 @@ class GpuChannelManager : public IPC::Listener, ...@@ -128,19 +123,10 @@ class GpuChannelManager : public IPC::Listener,
const GPUCreateCommandBufferConfig& init_params, const GPUCreateCommandBufferConfig& init_params,
int32 route_id); int32 route_id);
void OnLoadedShader(std::string shader); void OnLoadedShader(std::string shader);
void CreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage);
void OnCreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage);
void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle); void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle);
void DestroyGpuMemoryBufferOnIO(const gfx::GpuMemoryBufferHandle& handle);
void OnDestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle, void OnDestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point); int32 sync_point);
void OnDestroyGpuMemoryBufferSyncPointRetired(
GpuMemoryBufferOperation* gpu_memory_buffer_operation);
void OnLoseAllContexts(); void OnLoseAllContexts();
...@@ -163,8 +149,9 @@ class GpuChannelManager : public IPC::Listener, ...@@ -163,8 +149,9 @@ class GpuChannelManager : public IPC::Listener,
scoped_ptr<gpu::gles2::ProgramCache> program_cache_; scoped_ptr<gpu::gles2::ProgramCache> program_cache_;
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_; scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
scoped_refptr<gfx::GLSurface> default_offscreen_surface_; scoped_refptr<gfx::GLSurface> default_offscreen_surface_;
GpuMemoryBufferOperationQueue gpu_memory_buffer_operations_;
scoped_ptr<GpuMemoryBufferFactory> gpu_memory_buffer_factory_; scoped_ptr<GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
IPC::SyncChannel* channel_;
scoped_refptr<IPC::MessageFilter> filter_;
DISALLOW_COPY_AND_ASSIGN(GpuChannelManager); DISALLOW_COPY_AND_ASSIGN(GpuChannelManager);
}; };
......
...@@ -700,6 +700,8 @@ ...@@ -700,6 +700,8 @@
'browser/gpu/gpu_data_manager_impl_private.h', 'browser/gpu/gpu_data_manager_impl_private.h',
'browser/gpu/gpu_internals_ui.cc', 'browser/gpu/gpu_internals_ui.cc',
'browser/gpu/gpu_internals_ui.h', 'browser/gpu/gpu_internals_ui.h',
'browser/gpu/gpu_memory_buffer_factory_host_impl.cc',
'browser/gpu/gpu_memory_buffer_factory_host_impl.h',
'browser/gpu/gpu_process_host.cc', 'browser/gpu/gpu_process_host.cc',
'browser/gpu/gpu_process_host.h', 'browser/gpu/gpu_process_host.h',
'browser/gpu/gpu_process_host_ui_shim.cc', 'browser/gpu/gpu_process_host_ui_shim.cc',
......
...@@ -163,7 +163,8 @@ void GpuChildThread::OnInitialize() { ...@@ -163,7 +163,8 @@ void GpuChildThread::OnInitialize() {
new GpuChannelManager(GetRouter(), new GpuChannelManager(GetRouter(),
watchdog_thread_.get(), watchdog_thread_.get(),
ChildProcess::current()->io_message_loop_proxy(), ChildProcess::current()->io_message_loop_proxy(),
ChildProcess::current()->GetShutDownEvent())); ChildProcess::current()->GetShutDownEvent(),
channel()));
#if defined(USE_OZONE) #if defined(USE_OZONE)
ui::OzonePlatform::GetInstance() ui::OzonePlatform::GetInstance()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment