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 @@ ...@@ -10,7 +10,6 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/debug/alias.h" #include "base/debug/alias.h"
#include "base/numerics/safe_math.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
...@@ -35,8 +34,6 @@ ...@@ -35,8 +34,6 @@
#include "content/common/cookie_data.h" #include "content/common/cookie_data.h"
#include "content/common/desktop_notification_messages.h" #include "content/common/desktop_notification_messages.h"
#include "content/common/frame_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/host_shared_bitmap_manager.h"
#include "content/common/media/media_param_traits.h" #include "content/common/media/media_param_traits.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
...@@ -73,9 +70,7 @@ ...@@ -73,9 +70,7 @@
#include "ui/gfx/color_profile.h" #include "ui/gfx/color_profile.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
#include "content/common/mac/font_descriptor.h" #include "content/common/mac/font_descriptor.h"
#include "ui/gl/io_surface_support_mac.h"
#else #else
#include "gpu/GLES2/gl2extchromium.h" #include "gpu/GLES2/gl2extchromium.h"
#include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2.h"
...@@ -89,8 +84,6 @@ ...@@ -89,8 +84,6 @@
#include "content/common/sandbox_win.h" #include "content/common/sandbox_win.h"
#endif #endif
#if defined(OS_ANDROID) #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" #include "media/base/android/webaudio_media_codec_bridge.h"
#endif #endif
...@@ -222,23 +215,6 @@ class OpenChannelToPpapiBrokerCallback ...@@ -222,23 +215,6 @@ class OpenChannelToPpapiBrokerCallback
int routing_id_; 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 } // namespace
class RenderMessageFilter::OpenChannelToNpapiPluginCallback class RenderMessageFilter::OpenChannelToNpapiPluginCallback
...@@ -376,9 +352,6 @@ void RenderMessageFilter::OnChannelClosing() { ...@@ -376,9 +352,6 @@ void RenderMessageFilter::OnChannelClosing() {
} }
#endif // defined(ENABLE_PLUGINS) #endif // defined(ENABLE_PLUGINS)
plugin_host_clients_.clear(); plugin_host_clients_.clear();
#if defined(OS_ANDROID)
CompositorImpl::DestroyAllSurfaceTextures(render_process_id_);
#endif
} }
void RenderMessageFilter::OnChannelConnected(int32 peer_id) { void RenderMessageFilter::OnChannelConnected(int32 peer_id) {
...@@ -438,9 +411,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) { ...@@ -438,9 +411,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnAllocateSharedMemory) OnAllocateSharedMemory)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedBitmap, IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedBitmap,
OnAllocateSharedBitmap) OnAllocateSharedBitmap)
IPC_MESSAGE_HANDLER_DELAY_REPLY(
ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
OnAllocateGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap, IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap,
OnAllocatedSharedBitmap) OnAllocatedSharedBitmap)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap, IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap,
...@@ -1229,111 +1199,4 @@ void RenderMessageFilter::OnWebAudioMediaCodec( ...@@ -1229,111 +1199,4 @@ void RenderMessageFilter::OnWebAudioMediaCodec(
} }
#endif #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 } // namespace content
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include "ui/surface/transport_dib.h" #include "ui/surface/transport_dib.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "base/mac/scoped_cftyperef.h"
#include "content/common/mac/font_loader.h" #include "content/common/mac/font_loader.h"
#endif #endif
...@@ -53,11 +52,6 @@ class SharedMemory; ...@@ -53,11 +52,6 @@ class SharedMemory;
class TaskRunner; class TaskRunner;
} }
namespace gfx {
class Rect;
struct GpuMemoryBufferHandle;
}
namespace media { namespace media {
class AudioManager; class AudioManager;
struct MediaLogEvent; struct MediaLogEvent;
...@@ -273,14 +267,6 @@ class RenderMessageFilter : public BrowserMessageFilter { ...@@ -273,14 +267,6 @@ class RenderMessageFilter : public BrowserMessageFilter {
uint32_t data_size); uint32_t data_size);
#endif #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 // 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 // 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. // by the BrowserProcess, which has a wider scope than we do.
...@@ -319,10 +305,6 @@ class RenderMessageFilter : public BrowserMessageFilter { ...@@ -319,10 +305,6 @@ class RenderMessageFilter : public BrowserMessageFilter {
media::AudioManager* audio_manager_; media::AudioManager* audio_manager_;
MediaInternals* media_internals_; MediaInternals* media_internals_;
#if defined(OS_MACOSX)
base::ScopedCFTypeRef<CFTypeRef> last_io_surface_;
#endif
DISALLOW_COPY_AND_ASSIGN(RenderMessageFilter); DISALLOW_COPY_AND_ASSIGN(RenderMessageFilter);
}; };
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/numerics/safe_math.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -111,6 +112,8 @@ ...@@ -111,6 +112,8 @@
#include "content/common/child_process_host_impl.h" #include "content/common/child_process_host_impl.h"
#include "content/common/child_process_messages.h" #include "content/common/child_process_messages.h"
#include "content/common/content_switches_internal.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/gpu/gpu_messages.h"
#include "content/common/mojo/mojo_messages.h" #include "content/common/mojo/mojo_messages.h"
#include "content/common/resource_messages.h" #include "content/common/resource_messages.h"
...@@ -152,6 +155,13 @@ ...@@ -152,6 +155,13 @@
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "content/browser/media/android/browser_demuxer_android.h" #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 #endif
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -326,6 +336,23 @@ class RendererSandboxedProcessLauncherDelegate ...@@ -326,6 +336,23 @@ class RendererSandboxedProcessLauncherDelegate
#endif // OS_POSIX #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 } // namespace
RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
...@@ -500,6 +527,10 @@ RenderProcessHostImpl::~RenderProcessHostImpl() { ...@@ -500,6 +527,10 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&RemoveShaderInfo, GetID())); base::Bind(&RemoveShaderInfo, GetID()));
} }
#if defined(OS_ANDROID)
CompositorImpl::DestroyAllSurfaceTextures(GetID());
#endif
} }
void RenderProcessHostImpl::EnableSendQueue() { void RenderProcessHostImpl::EnableSendQueue() {
...@@ -1314,6 +1345,9 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) { ...@@ -1314,6 +1345,9 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction) OnUserMetricsRecordAction)
IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML) 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 // Adding single handlers for your service here is fine, but once your
// service needs more than one handler, please extract them into a new // service needs more than one handler, please extract them into a new
// message filter and add that filter to CreateMessageFilters(). // message filter and add that filter to CreateMessageFilters().
...@@ -2113,4 +2147,111 @@ void RenderProcessHostImpl::ConnectTo( ...@@ -2113,4 +2147,111 @@ void RenderProcessHostImpl::ConnectTo(
handle.Pass()); 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 } // namespace content
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
#include "ipc/ipc_platform_file.h" #include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/bindings/interface_ptr.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_cftyperef.h"
#endif
struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params; struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params;
namespace base { namespace base {
...@@ -31,6 +35,7 @@ class MessageLoop; ...@@ -31,6 +35,7 @@ class MessageLoop;
namespace gfx { namespace gfx {
class Size; class Size;
struct GpuMemoryBufferHandle;
} }
namespace content { namespace content {
...@@ -317,6 +322,15 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -317,6 +322,15 @@ class CONTENT_EXPORT RenderProcessHostImpl
void SendDisableAecDumpToRenderer(); void SendDisableAecDumpToRenderer();
#endif #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_; scoped_ptr<MojoApplicationHost> mojo_application_host_;
bool mojo_activation_required_; bool mojo_activation_required_;
...@@ -436,6 +450,10 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -436,6 +450,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_; base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
#if defined(OS_MACOSX)
base::ScopedCFTypeRef<CFTypeRef> last_io_surface_;
#endif
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl); 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