Commit 056182d6 authored by alexst@chromium.org's avatar alexst@chromium.org

Plumb GpuMemoryBuffer allocation to GPU process.


BUG=368716

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276738 0039d316-1c4b-4281-b951-d872f2087c98
parent cb875c08
......@@ -208,7 +208,8 @@ void BrowserGpuChannelHostFactory::Terminate() {
BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
: gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
shutdown_event_(new base::WaitableEvent(true, false)),
gpu_host_id_(0) {
gpu_host_id_(0),
next_create_gpu_memory_buffer_request_id_(0) {
}
BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
......@@ -469,4 +470,90 @@ void BrowserGpuChannelHostFactory::SetHandlerForControlMessages(
filter));
}
void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
uint32 request_id = next_create_gpu_memory_buffer_request_id_++;
create_gpu_memory_buffer_requests_[request_id] = callback;
GetIOLoopProxy()->PostTask(
FROM_HERE,
base::Bind(&BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO,
base::Unretained(this),
handle,
size,
internalformat,
usage,
request_id));
}
void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GetIOLoopProxy()->PostTask(
FROM_HERE,
base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO,
base::Unretained(this),
handle,
sync_point));
}
void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
uint32 request_id) {
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host) {
GpuMemoryBufferCreatedOnIO(request_id, gfx::GpuMemoryBufferHandle());
return;
}
host->CreateGpuMemoryBuffer(
handle,
size,
internalformat,
usage,
base::Bind(&BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO,
base::Unretained(this),
request_id));
}
void BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO(
uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle) {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated,
base::Unretained(this),
request_id,
handle));
}
void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated(
uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle) {
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);
}
void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO(
const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) {
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
if (!host)
return;
host->DestroyGpuMemoryBuffer(handle, sync_point);
}
} // namespace content
......@@ -10,12 +10,14 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.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"
namespace content {
class CONTENT_EXPORT BrowserGpuChannelHostFactory
: public GpuChannelHostFactory {
: public GpuChannelHostFactory,
public GpuMemoryBufferFactoryHost {
public:
static void Initialize(bool establish_gpu_channel);
static void Terminate();
......@@ -42,6 +44,16 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
unsigned internalformat,
unsigned usage) 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
// callback will be set up on the current GpuProcessHost, identified by
// GpuProcessHostId().
......@@ -86,6 +98,20 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
static void AddFilterOnIO(int gpu_host_id,
scoped_refptr<IPC::MessageFilter> filter);
void CreateGpuMemoryBufferOnIO(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
uint32 request_id);
void GpuMemoryBufferCreatedOnIO(
uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle);
void OnGpuMemoryBufferCreated(
uint32 request_id,
const gfx::GpuMemoryBufferHandle& handle);
void DestroyGpuMemoryBufferOnIO(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point);
const int gpu_client_id_;
scoped_ptr<base::WaitableEvent> shutdown_event_;
scoped_refptr<GpuChannelHost> gpu_channel_;
......@@ -93,6 +119,11 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
scoped_refptr<EstablishRequest> pending_request_;
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_;
DISALLOW_COPY_AND_ASSIGN(BrowserGpuChannelHostFactory);
......
......@@ -566,6 +566,8 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated)
IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer, OnDestroyCommandBuffer)
IPC_MESSAGE_HANDLER(GpuHostMsg_ImageCreated, OnImageCreated)
IPC_MESSAGE_HANDLER(GpuHostMsg_GpuMemoryBufferCreated,
OnGpuMemoryBufferCreated)
IPC_MESSAGE_HANDLER(GpuHostMsg_DidCreateOffscreenContext,
OnDidCreateOffscreenContext)
IPC_MESSAGE_HANDLER(GpuHostMsg_DidLoseContext, OnDidLoseContext)
......@@ -671,6 +673,34 @@ void GpuProcessHost::DeleteImage(int client_id,
Send(new GpuMsg_DeleteImage(client_id, image_id, sync_point));
}
void GpuProcessHost::CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) {
TRACE_EVENT0("gpu", "GpuProcessHost::CreateGpuMemoryBuffer");
DCHECK(CalledOnValidThread());
if (Send(new GpuMsg_CreateGpuMemoryBuffer(
handle, size, internalformat, usage))) {
create_gpu_memory_buffer_requests_.push(callback);
} else {
callback.Run(gfx::GpuMemoryBufferHandle());
}
}
void GpuProcessHost::DestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
int sync_point) {
TRACE_EVENT0("gpu", "GpuProcessHost::DestroyGpuMemoryBuffer");
DCHECK(CalledOnValidThread());
Send(new GpuMsg_DestroyGpuMemoryBuffer(handle, sync_point));
}
void GpuProcessHost::OnInitialized(bool result, const gpu::GPUInfo& gpu_info) {
UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", result);
initialized_ = result;
......@@ -744,6 +774,19 @@ void GpuProcessHost::OnImageCreated(const gfx::Size size) {
callback.Run(size);
}
void GpuProcessHost::OnGpuMemoryBufferCreated(
const gfx::GpuMemoryBufferHandle& handle) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnGpuMemoryBufferCreated");
if (create_gpu_memory_buffer_requests_.empty())
return;
CreateGpuMemoryBufferCallback callback =
create_gpu_memory_buffer_requests_.front();
create_gpu_memory_buffer_requests_.pop();
callback.Run(handle);
}
void GpuProcessHost::OnDidCreateOffscreenContext(const GURL& url) {
urls_with_live_offscreen_contexts_.insert(url);
}
......
......@@ -34,6 +34,10 @@ struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
namespace gfx {
struct GpuMemoryBufferHandle;
}
namespace IPC {
struct ChannelHandle;
}
......@@ -63,6 +67,9 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
typedef base::Callback<void(const gfx::Size)> CreateImageCallback;
typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
CreateGpuMemoryBufferCallback;
static bool gpu_enabled() { return gpu_enabled_; }
// Creates a new GpuProcessHost or gets an existing one, resulting in the
......@@ -125,6 +132,14 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Tells the GPU process to delete image.
void DeleteImage(int client_id, int image_id, int sync_point);
void CreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback);
void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int sync_point);
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
......@@ -159,6 +174,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void OnCommandBufferCreated(bool succeeded);
void OnDestroyCommandBuffer(int32 surface_id);
void OnImageCreated(const gfx::Size size);
void OnGpuMemoryBufferCreated(const gfx::GpuMemoryBufferHandle& handle);
void OnDidCreateOffscreenContext(const GURL& url);
void OnDidLoseContext(bool offscreen,
gpu::error::ContextLostReason reason,
......@@ -196,6 +212,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// The pending create image requests we need to reply to.
std::queue<CreateImageCallback> create_image_requests_;
// The pending create gpu memory buffer requests we need to reply to.
std::queue<CreateGpuMemoryBufferCallback> create_gpu_memory_buffer_requests_;
// Qeueud messages to send when the process launches.
std::queue<IPC::Message*> queued_messages_;
......
......@@ -67,9 +67,15 @@ IPC_STRUCT_TRAITS_BEGIN(gfx::SurfaceTextureId)
IPC_STRUCT_TRAITS_END()
#endif
IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferId)
IPC_STRUCT_TRAITS_MEMBER(primary_id)
IPC_STRUCT_TRAITS_MEMBER(secondary_id)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferHandle)
IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(handle)
IPC_STRUCT_TRAITS_MEMBER(global_id)
#if defined(OS_MACOSX)
IPC_STRUCT_TRAITS_MEMBER(io_surface_id)
#endif
......
// 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.
#ifndef CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_FACTORY_HOST_H_
#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_FACTORY_HOST_H_
#include "base/callback.h"
namespace gfx {
class Size;
struct GpuMemoryBufferHandle;
}
namespace content {
class CONTENT_EXPORT GpuMemoryBufferFactoryHost {
public:
typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
CreateGpuMemoryBufferCallback;
virtual void CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage,
const CreateGpuMemoryBufferCallback& callback) = 0;
virtual void DestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) = 0;
protected:
virtual ~GpuMemoryBufferFactoryHost() {}
};
} // namespace content
#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_FACTORY_HOST_H_
......@@ -110,6 +110,8 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
OnCreateViewCommandBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_CreateImage, OnCreateImage)
IPC_MESSAGE_HANDLER(GpuMsg_DeleteImage, OnDeleteImage)
IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -255,6 +257,19 @@ void GpuChannelManager::OnDeleteImageSyncPointRetired(
}
}
void GpuChannelManager::OnCreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage) {
Send(new GpuHostMsg_GpuMemoryBufferCreated(gfx::GpuMemoryBufferHandle()));
}
void GpuChannelManager::OnDestroyGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point) {
}
void GpuChannelManager::OnLoadedShader(std::string program_proto) {
if (program_cache())
program_cache()->LoadProgram(program_proto);
......
......@@ -28,6 +28,7 @@ class WaitableEvent;
namespace gfx {
class GLShareGroup;
struct GpuMemoryBufferHandle;
}
namespace gpu {
......@@ -127,6 +128,12 @@ class GpuChannelManager : public IPC::Listener,
void OnDeleteImage(int32 client_id, int32 image_id, int32 sync_point);
void OnDeleteImageSyncPointRetired(ImageOperation*);
void OnLoadedShader(std::string shader);
void OnCreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat,
unsigned usage);
void OnDestroyGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
int32 sync_point);
void OnLoseAllContexts();
......
......@@ -282,6 +282,18 @@ IPC_MESSAGE_CONTROL3(GpuMsg_DeleteImage,
int32, /* image_id */
int32 /* sync_point */)
// Tells the GPU process to create a new gpu memory buffer for |handle|.
IPC_MESSAGE_CONTROL4(GpuMsg_CreateGpuMemoryBuffer,
gfx::GpuMemoryBufferHandle, /* handle */
gfx::Size, /* size */
unsigned, /* internalformat */
unsigned /* usage */)
// Tells the GPU process to destroy buffer.
IPC_MESSAGE_CONTROL2(GpuMsg_DestroyGpuMemoryBuffer,
gfx::GpuMemoryBufferHandle, /* handle */
int32 /* sync_point */)
// Tells the GPU process to create a context for collecting graphics card
// information.
IPC_MESSAGE_CONTROL0(GpuMsg_CollectGraphicsInfo)
......@@ -368,6 +380,10 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_DestroyCommandBuffer,
IPC_MESSAGE_CONTROL1(GpuHostMsg_ImageCreated,
gfx::Size /* size */)
// Response from GPU to a GpuMsg_CreateGpuMemoryBuffer message.
IPC_MESSAGE_CONTROL1(GpuHostMsg_GpuMemoryBufferCreated,
gfx::GpuMemoryBufferHandle /* handle */)
// Response from GPU to a GpuMsg_CollectGraphicsInfo.
IPC_MESSAGE_CONTROL1(GpuHostMsg_GraphicsInfoCollected,
gpu::GPUInfo /* GPU logging stats */)
......
......@@ -237,6 +237,7 @@
'common/gpu/client/gl_helper_scaling.h',
'common/gpu/client/gpu_channel_host.cc',
'common/gpu/client/gpu_channel_host.h',
'common/gpu/client/gpu_memory_buffer_factory_host.h',
'common/gpu/client/gpu_memory_buffer_impl.cc',
'common/gpu/client/gpu_memory_buffer_impl.h',
'common/gpu/client/gpu_memory_buffer_impl_android.cc',
......
......@@ -6,6 +6,20 @@
namespace gfx {
GpuMemoryBufferHandle::GpuMemoryBufferHandle()
: type(EMPTY_BUFFER),
handle(base::SharedMemory::NULLHandle())
#if defined(OS_MACOSX)
,
io_surface_id(0u)
#endif
#if defined(OS_ANDROID)
,
native_buffer(NULL)
#endif
{
}
GpuMemoryBuffer::GpuMemoryBuffer() {}
GpuMemoryBuffer::~GpuMemoryBuffer() {}
......
......@@ -24,6 +24,8 @@ enum GpuMemoryBufferType {
GPU_MEMORY_BUFFER_TYPE_LAST = SURFACE_TEXTURE_BUFFER
};
// TODO(alexst): Merge this with GpuMemoryBufferId as part of switchover to
// the new API for GpuMemoryBuffer allocation when it's done.
#if defined(OS_ANDROID)
struct SurfaceTextureId {
SurfaceTextureId() : primary_id(0), secondary_id(0) {}
......@@ -34,23 +36,20 @@ struct SurfaceTextureId {
};
#endif
struct GpuMemoryBufferHandle {
GpuMemoryBufferHandle()
: type(EMPTY_BUFFER),
handle(base::SharedMemory::NULLHandle())
#if defined(OS_MACOSX)
,
io_surface_id(0u)
#endif
#if defined(OS_ANDROID)
,
native_buffer(NULL)
#endif
{
}
struct GpuMemoryBufferId {
GpuMemoryBufferId() : primary_id(0), secondary_id(0) {}
GpuMemoryBufferId(int32 primary_id, int32 secondary_id)
: primary_id(primary_id), secondary_id(secondary_id) {}
int32 primary_id;
int32 secondary_id;
};
struct GFX_EXPORT GpuMemoryBufferHandle {
GpuMemoryBufferHandle();
bool is_null() const { return type == EMPTY_BUFFER; }
GpuMemoryBufferType type;
base::SharedMemoryHandle handle;
GpuMemoryBufferId global_id;
#if defined(OS_MACOSX)
uint32 io_surface_id;
#endif
......
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