Commit e3d7088c authored by reveman@chromium.org's avatar reveman@chromium.org

content: Always allocate GpuMemoryBuffers on UI thread.

Prior to this change, the browser compositor allocated
buffers on the UI thread while the buffer allocation for
renderers was done on the IO thread.

This moves all allocation to the UI thread, which makes life
easier for GpuMemoryBuffer implementations and avoids
potentially expensive allocation costs on the IO thread.

BUG=

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274168 0039d316-1c4b-4281-b951-d872f2087c98
parent 10f7319e
......@@ -10,7 +10,6 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/numerics/safe_math.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
......@@ -35,8 +34,6 @@
#include "content/common/cookie_data.h"
#include "content/common/desktop_notification_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
#include "content/common/host_shared_bitmap_manager.h"
#include "content/common/media/media_param_traits.h"
#include "content/common/view_messages.h"
......@@ -73,9 +70,7 @@
#include "ui/gfx/color_profile.h"
#if defined(OS_MACOSX)
#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
#include "content/common/mac/font_descriptor.h"
#include "ui/gl/io_surface_support_mac.h"
#else
#include "gpu/GLES2/gl2extchromium.h"
#include "third_party/khronos/GLES2/gl2.h"
......@@ -89,8 +84,6 @@
#include "content/common/sandbox_win.h"
#endif
#if defined(OS_ANDROID)
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
#include "media/base/android/webaudio_media_codec_bridge.h"
#endif
......@@ -222,23 +215,6 @@ class OpenChannelToPpapiBrokerCallback
int routing_id_;
};
#if defined(OS_MACOSX)
void AddBooleanValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
bool value) {
CFDictionaryAddValue(
dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
}
void AddIntegerValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
int32 value) {
base::ScopedCFTypeRef<CFNumberRef> number(
CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
CFDictionaryAddValue(dictionary, key, number.get());
}
#endif
} // namespace
class RenderMessageFilter::OpenChannelToNpapiPluginCallback
......@@ -376,9 +352,6 @@ void RenderMessageFilter::OnChannelClosing() {
}
#endif // defined(ENABLE_PLUGINS)
plugin_host_clients_.clear();
#if defined(OS_ANDROID)
CompositorImpl::DestroyAllSurfaceTextures(render_process_id_);
#endif
}
void RenderMessageFilter::OnChannelConnected(int32 peer_id) {
......@@ -438,9 +411,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnAllocateSharedMemory)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedBitmap,
OnAllocateSharedBitmap)
IPC_MESSAGE_HANDLER_DELAY_REPLY(
ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
OnAllocateGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap,
OnAllocatedSharedBitmap)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap,
......@@ -1229,111 +1199,4 @@ void RenderMessageFilter::OnWebAudioMediaCodec(
}
#endif
void RenderMessageFilter::OnAllocateGpuMemoryBuffer(uint32 width,
uint32 height,
uint32 internalformat,
uint32 usage,
IPC::Message* reply) {
if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) ||
!GpuMemoryBufferImpl::IsUsageValid(usage)) {
GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
return;
}
base::CheckedNumeric<int> size = width;
size *= height;
if (!size.IsValid()) {
GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
return;
}
#if defined(OS_MACOSX)
// TODO(reveman): This should be moved to
// GpuMemoryBufferImpl::AllocateForChildProcess and
// GpuMemoryBufferImplIOSurface. crbug.com/325045, crbug.com/323304
if (GpuMemoryBufferImplIOSurface::IsConfigurationSupported(internalformat,
usage)) {
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
if (io_surface_support) {
base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
properties.reset(
CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceWidth(),
width);
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceHeight(),
height);
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceBytesPerElement(),
GpuMemoryBufferImpl::BytesPerPixel(internalformat));
AddIntegerValue(properties,
io_surface_support->GetKIOSurfacePixelFormat(),
GpuMemoryBufferImplIOSurface::PixelFormat(
internalformat));
// TODO(reveman): Remove this when using a mach_port_t to transfer
// IOSurface to renderer process. crbug.com/323304
AddBooleanValue(properties,
io_surface_support->GetKIOSurfaceIsGlobal(),
true);
base::ScopedCFTypeRef<CFTypeRef> io_surface(
io_surface_support->IOSurfaceCreate(properties));
if (io_surface) {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::IO_SURFACE_BUFFER;
handle.io_surface_id = io_surface_support->IOSurfaceGetID(io_surface);
// TODO(reveman): This makes the assumption that the renderer will
// grab a reference to the surface before sending another message.
// crbug.com/325045
last_io_surface_ = io_surface;
GpuMemoryBufferAllocated(reply, handle);
return;
}
}
}
#endif
#if defined(OS_ANDROID)
// TODO(reveman): This should be moved to
// GpuMemoryBufferImpl::AllocateForChildProcess and
// GpuMemoryBufferImplSurfaceTexture when adding support for out-of-process
// GPU service. crbug.com/368716
if (GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
internalformat, usage)) {
// Each surface texture is associated with a render process id. This allows
// the GPU service and Java Binder IPC to verify that a renderer is not
// trying to use a surface texture it doesn't own.
int surface_texture_id =
CompositorImpl::CreateSurfaceTexture(render_process_id_);
if (surface_texture_id != -1) {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SURFACE_TEXTURE_BUFFER;
handle.surface_texture_id =
gfx::SurfaceTextureId(surface_texture_id, render_process_id_);
GpuMemoryBufferAllocated(reply, handle);
return;
}
}
#endif
GpuMemoryBufferImpl::AllocateForChildProcess(
gfx::Size(width, height),
internalformat,
usage,
PeerHandle(),
base::Bind(&RenderMessageFilter::GpuMemoryBufferAllocated, this, reply));
}
void RenderMessageFilter::GpuMemoryBufferAllocated(
IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle) {
ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer::WriteReplyParams(reply,
handle);
Send(reply);
}
} // namespace content
......@@ -32,7 +32,6 @@
#include "ui/surface/transport_dib.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_cftyperef.h"
#include "content/common/mac/font_loader.h"
#endif
......@@ -53,11 +52,6 @@ class SharedMemory;
class TaskRunner;
}
namespace gfx {
class Rect;
struct GpuMemoryBufferHandle;
}
namespace media {
class AudioManager;
struct MediaLogEvent;
......@@ -273,14 +267,6 @@ class RenderMessageFilter : public BrowserMessageFilter {
uint32_t data_size);
#endif
void OnAllocateGpuMemoryBuffer(uint32 width,
uint32 height,
uint32 internalformat,
uint32 usage,
IPC::Message* reply);
void GpuMemoryBufferAllocated(IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle);
// Cached resource request dispatcher host and plugin service, guaranteed to
// be non-null if Init succeeds. We do not own the objects, they are managed
// by the BrowserProcess, which has a wider scope than we do.
......@@ -319,10 +305,6 @@ class RenderMessageFilter : public BrowserMessageFilter {
media::AudioManager* audio_manager_;
MediaInternals* media_internals_;
#if defined(OS_MACOSX)
base::ScopedCFTypeRef<CFTypeRef> last_io_surface_;
#endif
DISALLOW_COPY_AND_ASSIGN(RenderMessageFilter);
};
......
......@@ -26,6 +26,7 @@
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/numerics/safe_math.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
......@@ -111,6 +112,8 @@
#include "content/common/child_process_host_impl.h"
#include "content/common/child_process_messages.h"
#include "content/common/content_switches_internal.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/mojo/mojo_messages.h"
#include "content/common/resource_messages.h"
......@@ -152,6 +155,13 @@
#if defined(OS_ANDROID)
#include "content/browser/media/android/browser_demuxer_android.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
#endif
#if defined(OS_MACOSX)
#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
#include "ui/gl/io_surface_support_mac.h"
#endif
#if defined(OS_WIN)
......@@ -326,6 +336,23 @@ class RendererSandboxedProcessLauncherDelegate
#endif // OS_POSIX
};
#if defined(OS_MACOSX)
void AddBooleanValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
bool value) {
CFDictionaryAddValue(
dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
}
void AddIntegerValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
int32 value) {
base::ScopedCFTypeRef<CFNumberRef> number(
CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
CFDictionaryAddValue(dictionary, key, number.get());
}
#endif
} // namespace
RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
......@@ -500,6 +527,10 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&RemoveShaderInfo, GetID()));
}
#if defined(OS_ANDROID)
CompositorImpl::DestroyAllSurfaceTextures(GetID());
#endif
}
void RenderProcessHostImpl::EnableSendQueue() {
......@@ -1314,6 +1345,9 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction)
IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
IPC_MESSAGE_HANDLER_DELAY_REPLY(
ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
OnAllocateGpuMemoryBuffer)
// Adding single handlers for your service here is fine, but once your
// service needs more than one handler, please extract them into a new
// message filter and add that filter to CreateMessageFilters().
......@@ -2113,4 +2147,111 @@ void RenderProcessHostImpl::ConnectTo(
handle.Pass());
}
void RenderProcessHostImpl::OnAllocateGpuMemoryBuffer(uint32 width,
uint32 height,
uint32 internalformat,
uint32 usage,
IPC::Message* reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) ||
!GpuMemoryBufferImpl::IsUsageValid(usage)) {
GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
return;
}
base::CheckedNumeric<int> size = width;
size *= height;
if (!size.IsValid()) {
GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
return;
}
#if defined(OS_MACOSX)
// TODO(reveman): This should be moved to
// GpuMemoryBufferImpl::AllocateForChildProcess and
// GpuMemoryBufferImplIOSurface. crbug.com/325045, crbug.com/323304
if (GpuMemoryBufferImplIOSurface::IsConfigurationSupported(internalformat,
usage)) {
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
if (io_surface_support) {
base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
properties.reset(
CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
AddIntegerValue(
properties, io_surface_support->GetKIOSurfaceWidth(), width);
AddIntegerValue(
properties, io_surface_support->GetKIOSurfaceHeight(), height);
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceBytesPerElement(),
GpuMemoryBufferImpl::BytesPerPixel(internalformat));
AddIntegerValue(
properties,
io_surface_support->GetKIOSurfacePixelFormat(),
GpuMemoryBufferImplIOSurface::PixelFormat(internalformat));
// TODO(reveman): Remove this when using a mach_port_t to transfer
// IOSurface to renderer process. crbug.com/323304
AddBooleanValue(
properties, io_surface_support->GetKIOSurfaceIsGlobal(), true);
base::ScopedCFTypeRef<CFTypeRef> io_surface(
io_surface_support->IOSurfaceCreate(properties));
if (io_surface) {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::IO_SURFACE_BUFFER;
handle.io_surface_id = io_surface_support->IOSurfaceGetID(io_surface);
// TODO(reveman): This makes the assumption that the renderer will
// grab a reference to the surface before sending another message.
// crbug.com/325045
last_io_surface_ = io_surface;
GpuMemoryBufferAllocated(reply, handle);
return;
}
}
}
#endif
#if defined(OS_ANDROID)
// TODO(reveman): This should be moved to
// GpuMemoryBufferImpl::AllocateForChildProcess and
// GpuMemoryBufferImplSurfaceTexture when adding support for out-of-process
// GPU service. crbug.com/368716
if (GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
internalformat, usage)) {
// Each surface texture is associated with a render process id. This allows
// the GPU service and Java Binder IPC to verify that a renderer is not
// trying to use a surface texture it doesn't own.
int surface_texture_id = CompositorImpl::CreateSurfaceTexture(GetID());
if (surface_texture_id != -1) {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SURFACE_TEXTURE_BUFFER;
handle.surface_texture_id =
gfx::SurfaceTextureId(surface_texture_id, GetID());
GpuMemoryBufferAllocated(reply, handle);
return;
}
}
#endif
GpuMemoryBufferImpl::AllocateForChildProcess(
gfx::Size(width, height),
internalformat,
usage,
GetHandle(),
base::Bind(&RenderProcessHostImpl::GpuMemoryBufferAllocated,
weak_factory_.GetWeakPtr(),
reply));
}
void RenderProcessHostImpl::GpuMemoryBufferAllocated(
IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer::WriteReplyParams(reply,
handle);
Send(reply);
}
} // namespace content
......@@ -22,6 +22,10 @@
#include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_cftyperef.h"
#endif
struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params;
namespace base {
......@@ -31,6 +35,7 @@ class MessageLoop;
namespace gfx {
class Size;
struct GpuMemoryBufferHandle;
}
namespace content {
......@@ -317,6 +322,15 @@ class CONTENT_EXPORT RenderProcessHostImpl
void SendDisableAecDumpToRenderer();
#endif
// GpuMemoryBuffer allocation handler.
void OnAllocateGpuMemoryBuffer(uint32 width,
uint32 height,
uint32 internalformat,
uint32 usage,
IPC::Message* reply);
void GpuMemoryBufferAllocated(IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle);
scoped_ptr<MojoApplicationHost> mojo_application_host_;
bool mojo_activation_required_;
......@@ -436,6 +450,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
#if defined(OS_MACOSX)
base::ScopedCFTypeRef<CFTypeRef> last_io_surface_;
#endif
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
};
......
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