diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 22:08:35 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 22:08:35 +0000 |
commit | 6217d397bf501ec1ec5b7270d493006badd4d87a (patch) | |
tree | fce6c8e9c15b79bab29a9535ce9929dd9d53735b /chrome | |
parent | 21dedcc12d21ccb288244249522d77bc074c501e (diff) | |
download | chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.zip chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.tar.gz chromium_src-6217d397bf501ec1ec5b7270d493006badd4d87a.tar.bz2 |
Calling OpenGL from the renderer process
- Added ability for renderer processes to render to a real window (Windows only so far).
- Added ability to create offscreen frame buffer objects that can be resized later.
- OpenGL context can have a "parent" context that can access its last swapped back buffer through a texture ID.
- Moved code to establish GPU channel from RenderWidget to RenderThread.
- Changed way service size command buffer object lifetimes are managed.
TEST=trybot and visual verification that OpenGL can clear the browser window to magenta.
BUG=none
Review URL: http://codereview.chromium.org/1136006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42679 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
29 files changed, 431 insertions, 189 deletions
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc index fc10107..9fa0092 100644 --- a/chrome/browser/gpu_process_host.cc +++ b/chrome/browser/gpu_process_host.cc @@ -126,13 +126,11 @@ void GpuProcessHost::RemoveRoute(int32 routing_id) { router_.RemoveRoute(routing_id); } -void GpuProcessHost::EstablishGpuChannel( - int renderer_id, - int routing_id) { +void GpuProcessHost::EstablishGpuChannel(int renderer_id) { if (Send(new GpuMsg_EstablishChannel(renderer_id))) - sent_requests_.push(ChannelRequest(renderer_id, routing_id)); + sent_requests_.push(ChannelRequest(renderer_id)); else - ReplyToRenderer(renderer_id, routing_id, IPC::ChannelHandle()); + ReplyToRenderer(renderer_id, IPC::ChannelHandle()); } void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { @@ -146,21 +144,19 @@ void GpuProcessHost::OnChannelEstablished( const IPC::ChannelHandle& channel_handle) { const ChannelRequest& request = sent_requests_.front(); - ReplyToRenderer(request.renderer_id, request.routing_id, channel_handle); + ReplyToRenderer(request.renderer_id, channel_handle); sent_requests_.pop(); } void GpuProcessHost::ReplyToRenderer( int renderer_id, - int routing_id, const IPC::ChannelHandle& channel) { // Check whether the renderer process is still around. RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id); if (!process_host) return; - CHECK(process_host->Send(new ViewMsg_GpuChannelEstablished(routing_id, - channel))); + CHECK(process_host->Send(new ViewMsg_GpuChannelEstablished(channel))); } void GpuProcessHost::PropagateBrowserCommandLineToGpu( diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h index 36d068f..4d74e00 100644 --- a/chrome/browser/gpu_process_host.h +++ b/chrome/browser/gpu_process_host.h @@ -13,6 +13,7 @@ #include "chrome/browser/child_process_launcher.h" #include "chrome/common/gpu_native_window_handle.h" #include "chrome/common/message_router.h" +#include "gfx/native_widget_types.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_channel_proxy.h" @@ -50,26 +51,20 @@ class GpuProcessHost : public IPC::Channel::Sender, // Tells the GPU process to create a new channel for communication with a // renderer. Will asynchronously send message to object with given routing id // on completion. - void EstablishGpuChannel(int renderer_id, int routing_id); + void EstablishGpuChannel(int renderer_id); private: friend struct DefaultSingletonTraits<GpuProcessHost>; // Used to queue pending channel requests. struct ChannelRequest { - ChannelRequest(int renderer_id, - int routing_id) : - renderer_id(renderer_id), - routing_id(routing_id) {} + explicit ChannelRequest(int renderer_id) : renderer_id(renderer_id) {} // Used to identify the renderer. The ID is used instead of a pointer to // the RenderProcessHost in case it is destroyed while the request is // pending. // TODO(apatrick): investigate whether these IDs are used for future // render processes. int renderer_id; - - // Routing ID of object to receive reply message. - int routing_id; }; GpuProcessHost(); @@ -81,7 +76,6 @@ class GpuProcessHost : public IPC::Channel::Sender, void OnChannelEstablished(const IPC::ChannelHandle& channel_handle); void ReplyToRenderer(int renderer_id, - int routing_id, const IPC::ChannelHandle& channel); // These are the channel requests that we have already sent to diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 0757d17..dccc34d 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -29,6 +29,7 @@ #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" +#include "chrome/browser/gpu_process_host.h" #include "chrome/browser/history/history.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/url_request_context_getter.h" @@ -45,6 +46,7 @@ #include "chrome/browser/visitedlink_master.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/child_process_info.h" +#include "chrome/common/gpu_messages.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" @@ -770,6 +772,8 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { OnExtensionRemoveListener) IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionCloseChannel, OnExtensionCloseChannel) + IPC_MESSAGE_HANDLER(ViewHostMsg_EstablishGpuChannel, + OnMsgEstablishGpuChannel) IPC_MESSAGE_HANDLER(ViewHostMsg_SpellChecker_RequestDictionary, OnSpellCheckerRequestDictionary) IPC_MESSAGE_UNHANDLED_ERROR() @@ -974,6 +978,10 @@ void BrowserRenderProcessHost::OnExtensionCloseChannel(int port_id) { } } +void BrowserRenderProcessHost::OnMsgEstablishGpuChannel() { + GpuProcessHost::Get()->EstablishGpuChannel(id()); +} + void BrowserRenderProcessHost::OnSpellCheckerRequestDictionary() { if (profile()->GetSpellCheckHost()) { // The spellchecker initialization already started and finished; just send diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 277a53e..372045a 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -110,6 +110,7 @@ class BrowserRenderProcessHost : public RenderProcessHost, void OnExtensionAddListener(const std::string& event_name); void OnExtensionRemoveListener(const std::string& event_name); void OnExtensionCloseChannel(int port_id); + void OnMsgEstablishGpuChannel(); // Initialize support for visited links. Send the renderer process its initial // set of visited links. diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 152aae1..5dc9badc 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -8,7 +8,6 @@ #include "base/histogram.h" #include "base/keyboard_codes.h" #include "base/message_loop.h" -#include "chrome/browser/gpu_process_host.h" #include "chrome/browser/renderer_host/backing_store.h" #include "chrome/browser/renderer_host/backing_store_manager.h" #include "chrome/browser/renderer_host/render_process_host.h" @@ -16,7 +15,6 @@ #include "chrome/browser/renderer_host/render_widget_host_painting_observer.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/video_layer.h" -#include "chrome/common/gpu_messages.h" #include "chrome/common/notification_service.h" #include "chrome/common/render_messages.h" #include "webkit/glue/webcursor.h" @@ -139,8 +137,6 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) - IPC_MESSAGE_HANDLER(ViewHostMsg_EstablishGpuChannel, - OnMsgEstablishGpuChannel) #if defined(OS_LINUX) IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer, OnMsgCreatePluginContainer) @@ -869,10 +865,6 @@ void RenderWidgetHost::OnMsgImeUpdateStatus(int control, } } -void RenderWidgetHost::OnMsgEstablishGpuChannel() { - GpuProcessHost::Get()->EstablishGpuChannel(process_->id(), routing_id_); -} - #if defined(OS_LINUX) void RenderWidgetHost::OnMsgCreatePluginContainer(gfx::PluginWindowHandle id) { diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index 5c95535..f8b8218 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -445,10 +445,6 @@ class RenderWidgetHost : public IPC::Channel::Listener, // having to bring in render_messages.h in a header file. void OnMsgImeUpdateStatus(int control, const gfx::Rect& caret_rect); - // Renderer process is requesting that the browser process establish a GPU - // channel. - void OnMsgEstablishGpuChannel(); - #if defined(OS_LINUX) void OnMsgCreatePluginContainer(gfx::PluginWindowHandle id); void OnMsgDestroyPluginContainer(gfx::PluginWindowHandle id); diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 55e2762..2d08f42 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -293,6 +293,15 @@ RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { void RenderWidgetHostViewWin::CreateWnd(HWND parent) { Create(parent); // ATL function to create the window. + + // Add a property indicating that a particular renderer is associated with + // this window. Used by the GPU process to validate window handles it + // receives from renderer processes. + int renderer_id = render_widget_host_->process()->id(); + SetProp(m_hWnd, + chrome::kChromiumRendererIdProperty, + reinterpret_cast<HANDLE>(renderer_id)); + // Uncommenting this will enable experimental out-of-process painting. // Contact brettw for more, // gpu_view_host_.reset(new GpuViewHost(render_widget_host_, m_hWnd)); diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index 38cf59e..a6ad651 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc @@ -134,6 +134,8 @@ const int kHistogramSynchronizerReservedSequenceNumber = 0; const int kMaxSessionHistoryEntries = 50; +const wchar_t kChromiumRendererIdProperty[] = L"ChromiumRendererId"; + } // namespace chrome #undef FPL diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 554a48b..456cea0 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h @@ -83,6 +83,8 @@ extern const int kHistogramSynchronizerReservedSequenceNumber; // The maximum number of session history entries per tab. extern const int kMaxSessionHistoryEntries; +extern const wchar_t kChromiumRendererIdProperty[]; + } // namespace chrome #endif // CHROME_COMMON_CHROME_CONSTANTS_H_ diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h index 6780a5e..9107aed 100644 --- a/chrome/common/gpu_messages_internal.h +++ b/chrome/common/gpu_messages_internal.h @@ -9,6 +9,7 @@ // This file needs to be included again, even though we're actually included // from it via utility_messages.h. #include "base/shared_memory.h" +#include "gfx/size.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_message_macros.h" @@ -96,9 +97,21 @@ IPC_END_MESSAGES(GpuHost) // These are messages from a renderer process to the GPU process. IPC_BEGIN_MESSAGES(GpuChannel) - // Tells the GPU process to create a new command buffer with the given - // id. A corresponding GpuCommandBufferStub is created. - IPC_SYNC_MESSAGE_CONTROL0_1(GpuChannelMsg_CreateCommandBuffer, + // Tells the GPU process to create a new command buffer that renders directly + // to a native view. A corresponding GpuCommandBufferStub is created. + IPC_SYNC_MESSAGE_CONTROL1_1(GpuChannelMsg_CreateViewCommandBuffer, + gfx::NativeViewId, /* view */ + int32 /* route_id */) + + // Tells the GPU process to create a new command buffer that renders to an + // offscreen frame buffer. If parent_route_id is not zero, the texture backing + // the frame buffer is mapped into the corresponding parent command buffer's + // namespace, with the name of parent_texture_id. This ID is in the parent's + // namespace. + IPC_SYNC_MESSAGE_CONTROL3_1(GpuChannelMsg_CreateOffscreenCommandBuffer, + int32, /* parent_route_id */ + gfx::Size, /* size */ + uint32, /* parent_texture_id */ int32 /* route_id */) // The CommandBufferProxy sends this to the GpuCommandBufferStub in its @@ -168,6 +181,10 @@ IPC_BEGIN_MESSAGES(GpuCommandBuffer) // repainted. IPC_MESSAGE_ROUTED0(GpuCommandBufferMsg_NotifyRepaint) + // Tells the GPU process to resize an offscreen frame buffer. + IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer, + gfx::Size /* size */) + #if defined(OS_MACOSX) // On Mac OS X the GPU plugin must be offscreen, because there is no // true cross-process window hierarchy. For this reason we must send diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index a0f5d14..0372a49 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -604,8 +604,8 @@ IPC_BEGIN_MESSAGES(View) // The browser sends this to a renderer process in response to a // ViewHostMsg_EstablishGpuChannel message. - IPC_MESSAGE_ROUTED1(ViewMsg_GpuChannelEstablished, - IPC::ChannelHandle /* handle to channel */) + IPC_MESSAGE_CONTROL1(ViewMsg_GpuChannelEstablished, + IPC::ChannelHandle /* handle to channel */) // Notifies the renderer of the appcache that has been selected for a // a particular host. This is sent in reply to AppCacheMsg_SelectCache. @@ -1340,7 +1340,7 @@ IPC_BEGIN_MESSAGES(ViewHost) // create connect to the GPU. The browser will create the GPU process if // necessary, and will return a handle to the channel via // a GpuChannelEstablished message. - IPC_MESSAGE_ROUTED0(ViewHostMsg_EstablishGpuChannel) + IPC_MESSAGE_CONTROL0(ViewHostMsg_EstablishGpuChannel) // A renderer sends this to the browser process when it wants to start // a new instance of the Native Client process. The browser will launch diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc index 4269022..b2b5bf9 100644 --- a/chrome/gpu/gpu_channel.cc +++ b/chrome/gpu/gpu_channel.cc @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if defined(OS_WIN) +#include <windows.h> +#endif + #include "chrome/gpu/gpu_channel.h" #include "base/command_line.h" @@ -11,6 +15,7 @@ #include "base/waitable_event.h" #include "build/build_config.h" #include "chrome/common/child_process.h" +#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_thread.h" @@ -27,44 +32,12 @@ class GpuReleaseTask : public Task { } }; -typedef base::hash_map<std::string, scoped_refptr<GpuChannel> > - GpuChannelMap; - // How long we wait before releasing the GPU process. const int kGpuReleaseTimeMS = 10000; - -GpuChannelMap g_gpu_channels; } // namespace anonymous -GpuChannel* GpuChannel::EstablishGpuChannel(int renderer_id) { - // Map renderer ID to a (single) channel to that process. - std::string channel_name = StringPrintf( - "%d.r%d", base::GetCurrentProcId(), renderer_id); - - scoped_refptr<GpuChannel> channel; - - GpuChannelMap::const_iterator iter = g_gpu_channels.find(channel_name); - if (iter == g_gpu_channels.end()) { - channel = new GpuChannel; - } else { - channel = iter->second; - } - - DCHECK(channel != NULL); - - if (!channel->channel_.get()) { - if (channel->Init(channel_name)) { - g_gpu_channels[channel_name] = channel; - } else { - channel = NULL; - } - } - - return channel.get(); -} - -GpuChannel::GpuChannel() - : renderer_id_(-1) +GpuChannel::GpuChannel(int renderer_id) + : renderer_id_(renderer_id) #if defined(OS_POSIX) , renderer_fd_(-1) #endif @@ -141,8 +114,10 @@ bool GpuChannel::Send(IPC::Message* message) { void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) - IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer, - OnCreateCommandBuffer) + IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateViewCommandBuffer, + OnCreateViewCommandBuffer) + IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer, + OnCreateOffscreenCommandBuffer) IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, OnDestroyCommandBuffer) IPC_MESSAGE_UNHANDLED_ERROR() @@ -154,11 +129,57 @@ int GpuChannel::GenerateRouteID() { return ++last_id; } -void GpuChannel::OnCreateCommandBuffer(int* route_id) { +void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, + int32* route_id) { + *route_id = 0; + #if defined(ENABLE_GPU) + +#if defined(OS_WIN) + gfx::NativeView view = gfx::NativeViewFromId(view_id); + + // Check that the calling renderer is allowed to render to this window. + // TODO(apatrick): consider killing the renderer process rather than failing. + int view_renderer_id = reinterpret_cast<int>( + GetProp(view, chrome::kChromiumRendererIdProperty)); + if (view_renderer_id != renderer_id_) + return; +#else + // TODO(apatrick): This needs to be something valid for mac and linux. + // Offscreen rendering will work on these platforms but not rendering to the + // window. + DCHECK_EQ(view_id, 0); + gfx::NativeView view = 0; +#endif + *route_id = GenerateRouteID(); scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( - this, *route_id); + this, view, NULL, gfx::Size(), 0, *route_id); + router_.AddRoute(*route_id, stub); + stubs_[*route_id] = stub; +#endif // ENABLE_GPU +} + +void GpuChannel::OnCreateOffscreenCommandBuffer(int32 parent_route_id, + const gfx::Size& size, + uint32 parent_texture_id, + int32* route_id) { +#if defined(ENABLE_GPU) + *route_id = GenerateRouteID(); + scoped_refptr<GpuCommandBufferStub> parent_stub; + if (parent_route_id != 0) { + StubMap::iterator it = stubs_.find(parent_route_id); + DCHECK(it != stubs_.end()); + parent_stub = it->second; + } + + scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( + this, + NULL, + parent_stub.get(), + size, + parent_texture_id, + *route_id); router_.AddRoute(*route_id, stub); stubs_[*route_id] = stub; #else @@ -166,7 +187,7 @@ void GpuChannel::OnCreateCommandBuffer(int* route_id) { #endif } -void GpuChannel::OnDestroyCommandBuffer(int route_id) { +void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { #if defined(ENABLE_GPU) StubMap::iterator it = stubs_.find(route_id); DCHECK(it != stubs_.end()); @@ -175,8 +196,13 @@ void GpuChannel::OnDestroyCommandBuffer(int route_id) { #endif } -bool GpuChannel::Init(const std::string& channel_name) { - channel_name_ = channel_name; +bool GpuChannel::Init() { + // Check whether we're already initialized. + if (channel_.get()) + return true; + + // Map renderer ID to a (single) channel to that process. + std::string channel_name = GetChannelName(); #if defined(OS_POSIX) // This gets called when the GpuChannel is initially created. At this // point, create the socketpair and assign the GPU side FD to the channel @@ -192,3 +218,7 @@ bool GpuChannel::Init(const std::string& channel_name) { ChildProcess::current()->GetShutDownEvent())); return true; } + +std::string GpuChannel::GetChannelName() { + return StringPrintf("%d.r%d", base::GetCurrentProcId(), renderer_id_); +} diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h index 17ea363..60dc906 100644 --- a/chrome/gpu/gpu_channel.h +++ b/chrome/gpu/gpu_channel.h @@ -13,6 +13,8 @@ #include "build/build_config.h" #include "chrome/common/message_router.h" #include "chrome/gpu/gpu_command_buffer_stub.h" +#include "gfx/native_widget_types.h" +#include "gfx/size.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sync_channel.h" @@ -23,17 +25,12 @@ class GpuChannel : public IPC::Channel::Listener, public IPC::Message::Sender, public base::RefCountedThreadSafe<GpuChannel> { public: - // Get a new GpuChannel object for the current process to talk to the - // given renderer process. The renderer ID is an opaque unique ID generated - // by the browser. - // - // POSIX only: If |channel_fd| > 0, use that file descriptor for the - // channel socket. - static GpuChannel* EstablishGpuChannel(int renderer_id); - + explicit GpuChannel(int renderer_id); virtual ~GpuChannel(); - std::string channel_name() const { return channel_name_; } + bool Init(); + + std::string GetChannelName(); base::ProcessHandle renderer_handle() const { return renderer_process_.handle(); @@ -60,21 +57,20 @@ class GpuChannel : public IPC::Channel::Listener, virtual bool Send(IPC::Message* msg); private: - // Called on the plugin thread - GpuChannel(); - - bool Init(const std::string& channel_name); - void OnControlMessageReceived(const IPC::Message& msg); int GenerateRouteID(); // Message handlers. - void OnCreateCommandBuffer(int* instance_id); - void OnDestroyCommandBuffer(int instance_id); + void OnCreateViewCommandBuffer(gfx::NativeViewId view, + int32* route_id); + void OnCreateOffscreenCommandBuffer(int32 parent_route_id, + const gfx::Size& size, + uint32 parent_texture_id, + int32* route_id); + void OnDestroyCommandBuffer(int32 route_id); scoped_ptr<IPC::SyncChannel> channel_; - std::string channel_name_; // Handle to the renderer process who is on the other side of the channel. base::ScopedOpenProcess renderer_process_; @@ -92,7 +88,7 @@ class GpuChannel : public IPC::Channel::Listener, MessageRouter router_; #if defined(ENABLE_GPU) - typedef base::hash_map<int, scoped_refptr<GpuCommandBufferStub> > StubMap; + typedef base::hash_map<int32, scoped_refptr<GpuCommandBufferStub> > StubMap; StubMap stubs_; #endif diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc index 6c3f5cc..5d6842d 100644 --- a/chrome/gpu/gpu_command_buffer_stub.cc +++ b/chrome/gpu/gpu_command_buffer_stub.cc @@ -6,6 +6,7 @@ #include "base/process_util.h" #include "base/shared_memory.h" +#include "build/build_config.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_command_buffer_stub.h" @@ -13,12 +14,23 @@ using gpu::Buffer; GpuCommandBufferStub::GpuCommandBufferStub(GpuChannel* channel, + gfx::NativeView view, + GpuCommandBufferStub* parent, + const gfx::Size& size, + uint32 parent_texture_id, int32 route_id) : channel_(channel), + view_(view), + parent_(parent), + initial_size_(size), + parent_texture_id_(parent_texture_id), route_id_(route_id) { } GpuCommandBufferStub::~GpuCommandBufferStub() { + if (processor_.get()) { + processor_->Destroy(); + } } void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { @@ -34,6 +46,8 @@ void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { OnDestroyTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer, OnGetTransferBuffer); + IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer, + OnResizeOffscreenFrameBuffer); IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() } @@ -55,8 +69,18 @@ void GpuCommandBufferStub::OnInitialize( if (command_buffer_->Initialize(size)) { Buffer buffer = command_buffer_->GetRingBuffer(); if (buffer.shared_memory) { - processor_ = new gpu::GPUProcessor(command_buffer_.get()); - if (processor_->Initialize(gfx::kNullPluginWindow)) { + gpu::GPUProcessor* parent_processor = + parent_ ? parent_->processor_.get() : NULL; + processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); + // TODO(apatrick): The reinterpret_cast below is only valid on windows. +#if !defined(OS_WIN) + DCHECK_EQ(view_, static_cast<gfx::NativeView>(0)); +#endif + if (processor_->Initialize( + reinterpret_cast<gfx::PluginWindowHandle>(view_), + parent_processor, + initial_size_, + parent_texture_id_)) { command_buffer_->SetPutOffsetChangeCallback( NewCallback(processor_.get(), &gpu::GPUProcessor::ProcessCommands)); @@ -66,7 +90,7 @@ void GpuCommandBufferStub::OnInitialize( buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), ring_buffer); } else { - processor_ = NULL; + processor_.reset(); command_buffer_.reset(); } } @@ -117,4 +141,8 @@ void GpuCommandBufferStub::OnGetTransferBuffer( } } +void GpuCommandBufferStub::OnResizeOffscreenFrameBuffer(const gfx::Size& size) { + processor_->ResizeOffscreenFrameBuffer(size); +} + #endif // ENABLE_GPU diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h index eb927a3..7aaf68a 100644 --- a/chrome/gpu/gpu_command_buffer_stub.h +++ b/chrome/gpu/gpu_command_buffer_stub.h @@ -10,6 +10,7 @@ #include "base/process.h" #include "base/ref_counted.h" #include "gfx/native_widget_types.h" +#include "gfx/size.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/gpu_processor.h" #include "ipc/ipc_channel.h" @@ -23,6 +24,10 @@ class GpuCommandBufferStub public base::RefCountedThreadSafe<GpuCommandBufferStub> { public: GpuCommandBufferStub(GpuChannel* channel, + gfx::NativeView view, + GpuCommandBufferStub* parent, + const gfx::Size& size, + uint32 parent_texture_id, int32 route_id); virtual ~GpuCommandBufferStub(); @@ -33,7 +38,7 @@ class GpuCommandBufferStub // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* msg); - int route_id() const { return route_id_; } + int32 route_id() const { return route_id_; } private: // Message handlers: @@ -47,12 +52,17 @@ class GpuCommandBufferStub void OnGetTransferBuffer(int32 id, base::SharedMemoryHandle* transfer_buffer, uint32* size); + void OnResizeOffscreenFrameBuffer(const gfx::Size& size); scoped_refptr<GpuChannel> channel_; - int route_id_; + gfx::NativeView view_; + scoped_refptr<GpuCommandBufferStub> parent_; + gfx::Size initial_size_; + uint32 parent_texture_id_; + int32 route_id_; scoped_ptr<gpu::CommandBufferService> command_buffer_; - scoped_refptr<gpu::GPUProcessor> processor_; + scoped_ptr<gpu::GPUProcessor> processor_; DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub); }; diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc index 1839412..9de441c 100644 --- a/chrome/gpu/gpu_thread.cc +++ b/chrome/gpu/gpu_thread.cc @@ -7,7 +7,6 @@ #include "build/build_config.h" #include "chrome/common/child_process.h" #include "chrome/common/gpu_messages.h" -#include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_config.h" #if defined(OS_WIN) @@ -47,11 +46,28 @@ void GpuThread::OnControlMessageReceived(const IPC::Message& msg) { } void GpuThread::OnEstablishChannel(int renderer_id) { - scoped_refptr<GpuChannel> channel = - GpuChannel::EstablishGpuChannel(renderer_id); + scoped_refptr<GpuChannel> channel; + + GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id); + if (iter == gpu_channels_.end()) { + channel = new GpuChannel(renderer_id); + } else { + channel = iter->second; + } + + DCHECK(channel != NULL); + + if (channel->Init()) { + // TODO(apatrick): figure out when to remove channels from the map. They + // will never be destroyed otherwise. + gpu_channels_[renderer_id] = channel; + } else { + channel = NULL; + } + IPC::ChannelHandle channel_handle; if (channel.get()) { - channel_handle.name = channel->channel_name(); + channel_handle.name = channel->GetChannelName(); #if defined(OS_POSIX) // On POSIX, pass the renderer-side FD. Also mark it as auto-close so that // it gets closed after it has been sent. diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h index c32b513..23b8ba1 100644 --- a/chrome/gpu/gpu_thread.h +++ b/chrome/gpu/gpu_thread.h @@ -10,6 +10,7 @@ #include "build/build_config.h" #include "chrome/common/child_thread.h" #include "chrome/common/gpu_native_window_handle.h" +#include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_config.h" #include "chrome/gpu/x_util.h" #include "gfx/native_widget_types.h" @@ -38,6 +39,9 @@ class GpuThread : public ChildThread { void OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window, int32 routing_id); + typedef base::hash_map<int, scoped_refptr<GpuChannel> > GpuChannelMap; + GpuChannelMap gpu_channels_; + #if defined(GPU_USE_GLX) Display* display_; scoped_ptr<GpuBackingStoreGLXContext> glx_context_; diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc index 7dc049c..de18db6 100644 --- a/chrome/plugin/command_buffer_stub.cc +++ b/chrome/plugin/command_buffer_stub.cc @@ -92,8 +92,8 @@ void CommandBufferStub::OnInitialize(int32 size, } // Initialize the GPUProcessor. - processor_ = new gpu::GPUProcessor(command_buffer_.get()); - if (!processor_->Initialize(window_)) { + processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); + if (!processor_->Initialize(window_, NULL, gfx::Size(), 0)) { Destroy(); return; } @@ -175,7 +175,7 @@ void CommandBufferStub::OnGetTransferBuffer( } void CommandBufferStub::Destroy() { - processor_ = NULL; + processor_.reset(); command_buffer_.reset(); DestroyPlatformSpecific(); diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h index 026110f..83564ca 100644 --- a/chrome/plugin/command_buffer_stub.h +++ b/chrome/plugin/command_buffer_stub.h @@ -73,7 +73,7 @@ class CommandBufferStub : public IPC::Channel::Listener, gfx::PluginWindowHandle window_; int route_id_; scoped_ptr<gpu::CommandBufferService> command_buffer_; - scoped_refptr<gpu::GPUProcessor> processor_; + scoped_ptr<gpu::GPUProcessor> processor_; }; #endif // ENABLE_GPU diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc index bd0f3a0..4a624a3 100644 --- a/chrome/renderer/command_buffer_proxy.cc +++ b/chrome/renderer/command_buffer_proxy.cc @@ -183,6 +183,10 @@ void CommandBufferProxy::SetParseError( NOTREACHED(); } +void CommandBufferProxy::ResizeOffscreenFrameBuffer(const gfx::Size& size) { + Send(new GpuCommandBufferMsg_ResizeOffscreenFrameBuffer(route_id_, size)); +} + #if defined(OS_MACOSX) void CommandBufferProxy::SetWindowSize(int32 width, int32 height) { Send(new GpuCommandBufferMsg_SetWindowSize(route_id_, width, height)); diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h index 5d72f2c..e6fce0a 100644 --- a/chrome/renderer/command_buffer_proxy.h +++ b/chrome/renderer/command_buffer_proxy.h @@ -15,6 +15,7 @@ #include "base/scoped_ptr.h" #include "base/shared_memory.h" #include "base/task.h" +#include "gfx/size.h" #include "gpu/command_buffer/common/command_buffer.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" @@ -51,6 +52,9 @@ class CommandBufferProxy : public gpu::CommandBuffer, virtual void SetToken(int32 token); virtual void SetParseError(gpu::error::Error error); + // Asynchronously resizes an offscreen frame buffer. + void ResizeOffscreenFrameBuffer(const gfx::Size& size); + // Set a task that will be invoked the next time the window becomes invalid // and needs to be repainted. Takes ownership of task. void SetNotifyRepaintTask(Task* task) { diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index b5c1d9d..2c41126 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -50,12 +50,21 @@ class GLES2Initializer { // Manages a GL context. class Context { public: - Context(); + Context(GpuChannelHost* channel, Context* parent); ~Context(); // Initialize a GGL context that can be used in association with a a GPU // channel acquired from a RenderWidget or RenderView. - bool Initialize(GpuChannelHost* channel); + bool Initialize(gfx::NativeViewId view, const gfx::Size& size); + + // Asynchronously resizes an offscreen frame buffer. + void ResizeOffscreen(const gfx::Size& size); + + // For an offscreen frame buffer context, return the frame buffer ID with + // respect to the parent. + uint32 parent_texture_id() const { + return parent_texture_id_; + } // Destroy all resources associated with the GGL context. void Destroy(); @@ -73,6 +82,8 @@ class Context { private: scoped_refptr<GpuChannelHost> channel_; + Context* parent_; + uint32 parent_texture_id_; CommandBufferProxy* command_buffer_; gpu::gles2::GLES2CmdHelper* gles2_helper_; int32 transfer_buffer_id_; @@ -81,31 +92,46 @@ class Context { DISALLOW_COPY_AND_ASSIGN(Context); }; -Context::Context() - : channel_(NULL), +Context::Context(GpuChannelHost* channel, Context* parent) + : channel_(channel), + parent_(parent), + parent_texture_id_(0), command_buffer_(NULL), gles2_helper_(NULL), transfer_buffer_id_(0), gles2_implementation_(NULL) { + DCHECK(channel); } Context::~Context() { Destroy(); } -bool Context::Initialize(GpuChannelHost* channel) { - DCHECK(channel); +bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) { + DCHECK(size.width() >= 0 && size.height() >= 0); - if (!channel->ready()) + if (!channel_->ready()) return false; - channel_ = channel; - // Ensure the gles2 library is initialized first in a thread safe way. Singleton<GLES2Initializer>::get(); + // Allocate a frame buffer ID with respect to the parent. + if (parent_) { + parent_->gles2_implementation_->MakeIds(1, &parent_texture_id_); + } + // Create a proxy to a command buffer in the GPU process. - command_buffer_ = channel_->CreateCommandBuffer(); + if (view) { + command_buffer_ = channel_->CreateViewCommandBuffer(view); + } else { + CommandBufferProxy* parent_command_buffer = + parent_ ? parent_->command_buffer_ : NULL; + command_buffer_ = channel_->CreateOffscreenCommandBuffer( + parent_command_buffer, + size, + parent_texture_id_); + } if (!command_buffer_) { Destroy(); return false; @@ -151,7 +177,15 @@ bool Context::Initialize(GpuChannelHost* channel) { return true; } +void Context::ResizeOffscreen(const gfx::Size& size) { + DCHECK(size.width() > 0 && size.height() > 0); + command_buffer_->ResizeOffscreenFrameBuffer(size); +} + void Context::Destroy() { + if (parent_ && parent_texture_id_ != 0) + parent_->gles2_implementation_->FreeIds(1, &parent_texture_id_); + delete gles2_implementation_; gles2_implementation_ = NULL; @@ -213,10 +247,10 @@ Error Context::GetError() { #endif // ENABLE_GPU -Context* CreateContext(GpuChannelHost* channel) { +Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view) { #if defined(ENABLE_GPU) - scoped_ptr<Context> context(new Context); - if (!context->Initialize(channel)) + scoped_ptr<Context> context(new Context(channel, NULL)); + if (!context->Initialize(view, gfx::Size())) return NULL; return context.release(); @@ -225,6 +259,34 @@ Context* CreateContext(GpuChannelHost* channel) { #endif } +Context* CreateOffscreenContext(GpuChannelHost* channel, + Context* parent, + const gfx::Size& size) { +#if defined(ENABLE_GPU) + scoped_ptr<Context> context(new Context(channel, parent)); + if (!context->Initialize(NULL, size)) + return NULL; + + return context.release(); +#else + return NULL; +#endif +} + +void ResizeOffscreenContext(Context* context, const gfx::Size& size) { +#if defined(ENABLE_GPU) + context->ResizeOffscreen(size); +#endif +} + +uint32 GetParentTextureId(Context* context) { +#if defined(ENABLE_GPU) + return context->parent_texture_id(); +#else + return 0; +#endif +} + bool MakeCurrent(Context* context) { #if defined(ENABLE_GPU) return Context::MakeCurrent(context); diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h index 26607ec..e5c661f 100644 --- a/chrome/renderer/ggl/ggl.h +++ b/chrome/renderer/ggl/ggl.h @@ -10,6 +10,9 @@ #ifndef CHROME_RENDERER_GGL_GGL_H_ #define CHROME_RENDERER_GGL_GGL_H_ +#include "gfx/native_widget_types.h" +#include "gfx/size.h" + class GpuChannelHost; namespace ggl { @@ -32,8 +35,30 @@ bool Initialize(); // have completed. bool Terminate(); -// Create A GGL context for an offscreen 1 x 1 pbuffer. -Context* CreateContext(GpuChannelHost* channel); +// Create a GGL context that renders directly to a view. +Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view); + +// Create a GGL context that renders to an offscreen frame buffer. If parent is +// not NULL, that context can access a copy of the created +// context's frame buffer that is updated every time SwapBuffers is called. It +// is not as general as shared contexts in other implementations of OpenGL. If +// parent is not NULL, it must be used on the same thread as the parent. A child +// context may not outlive its parent. +Context* CreateOffscreenContext(GpuChannelHost* channel, + Context* parent, + const gfx::Size& size); + +// Resize an offscreen frame buffer. The resize occurs on the next call to +// SwapBuffers. This is to avoid waiting until all pending GL calls have been +// executed by the GPU process. Everything rendered up to the call to +// SwapBuffers will be lost. A lost context will be reported if the resize +// fails. +void ResizeOffscreenContext(Context* context, const gfx::Size& size); + +// For an offscreen frame buffer context, return the texture ID with +// respect to the parent context. Returns zero if context does not have a +// parent. +uint32 GetParentTextureId(Context* context); // Set the current GGL context for the calling thread. bool MakeCurrent(Context* context); @@ -41,7 +66,10 @@ bool MakeCurrent(Context* context); // Get the calling thread's current GGL context. Context* GetCurrentContext(); -// Display everything that has been rendered since the last call. +// For a view context, display everything that has been rendered since the +// last call. For an offscreen context, resolve everything that has been +// rendered since the last call to a copy that can be accessed by the parent +// context. bool SwapBuffers(); // Destroy the given GGL context. diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc index 8e48b85..8d2cdd9 100644 --- a/chrome/renderer/gpu_channel_host.cc +++ b/chrome/renderer/gpu_channel_host.cc @@ -64,14 +64,43 @@ bool GpuChannelHost::Send(IPC::Message* message) { return channel_->Send(message); } -CommandBufferProxy* GpuChannelHost::CreateCommandBuffer() { +CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer( + gfx::NativeViewId view) { #if defined(ENABLE_GPU) // An error occurred. Need to get the host again to reinitialize it. if (!channel_.get()) return NULL; int32 route_id; - if (!Send(new GpuChannelMsg_CreateCommandBuffer(&route_id)) && + if (!Send(new GpuChannelMsg_CreateViewCommandBuffer(view, &route_id)) && + route_id != MSG_ROUTING_NONE) { + return NULL; + } + + CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id); + router_.AddRoute(route_id, command_buffer); + proxies_[route_id] = command_buffer; + return command_buffer; +#else + return NULL; +#endif +} + +CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer( + CommandBufferProxy* parent, + const gfx::Size& size, + uint32 parent_texture_id) { +#if defined(ENABLE_GPU) + // An error occurred. Need to get the host again to reinitialize it. + if (!channel_.get()) + return NULL; + + int32 parent_route_id = parent ? parent->route_id() : 0; + int32 route_id; + if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(parent_route_id, + size, + parent_texture_id, + &route_id)) && route_id != MSG_ROUTING_NONE) { return NULL; } @@ -99,3 +128,4 @@ void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) { delete command_buffer; #endif } + diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h index 00a6129..4b982bf 100644 --- a/chrome/renderer/gpu_channel_host.h +++ b/chrome/renderer/gpu_channel_host.h @@ -9,6 +9,8 @@ #include "base/hash_tables.h" #include "chrome/common/message_router.h" +#include "gfx/native_widget_types.h" +#include "gfx/size.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sync_channel.h" @@ -52,7 +54,13 @@ class GpuChannelHost : public IPC::Channel::Listener, virtual bool Send(IPC::Message* msg); // Create and connect to a command buffer in the GPU process. - CommandBufferProxy* CreateCommandBuffer(); + CommandBufferProxy* CreateViewCommandBuffer(gfx::NativeViewId view); + + // Create and connect to a command buffer in the GPU process. + CommandBufferProxy* CreateOffscreenCommandBuffer(CommandBufferProxy* parent, + const gfx::Size& size, + uint32 parent_texture_id); + // Destroy a command buffer created by this channel. void DestroyCommandBuffer(CommandBufferProxy* command_buffer); diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index ab97f2a..4fb0971 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -90,6 +90,10 @@ #include "chrome/app/breakpad_mac.h" #endif +#if defined(OS_POSIX) +#include "ipc/ipc_channel_posix.h" +#endif + using WebKit::WebCache; using WebKit::WebCrossOriginPreflightResultCache; using WebKit::WebFontCache; @@ -565,6 +569,7 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) { OnSpellCheckWordAdded) IPC_MESSAGE_HANDLER(ViewMsg_SpellChecker_EnableAutoSpellCorrect, OnSpellCheckEnableAutoSpellCorrect) + IPC_MESSAGE_HANDLER(ViewMsg_GpuChannelEstablished, OnGpuChannelEstablished) IPC_END_MESSAGE_MAP() } @@ -680,6 +685,34 @@ void RenderThread::UpdateActiveExtensions() { child_process_logging::SetActiveExtensions(active_extensions); } +void RenderThread::EstablishGpuChannel() { + if (gpu_channel_.get()) { + // Do nothing if we are already establishing GPU channel. + if (gpu_channel_->state() == GpuChannelHost::UNCONNECTED) + return; + + // Recreate the channel if it has been lost. + if (gpu_channel_->state() == GpuChannelHost::LOST) + gpu_channel_ = NULL; + } + + if (!gpu_channel_.get()) + gpu_channel_ = new GpuChannelHost; + + // Ask the browser for the channel name. + Send(new ViewHostMsg_EstablishGpuChannel()); +} + +GpuChannelHost* RenderThread::GetGpuChannel() { + if (!gpu_channel_.get()) + return NULL; + + if (gpu_channel_->state() != GpuChannelHost::CONNECTED) + return NULL; + + return gpu_channel_.get(); +} + static void* CreateHistogram( const char *name, int min, int max, size_t buckets) { if (min <= 0) @@ -940,3 +973,20 @@ void RenderThread::OnSpellCheckEnableAutoSpellCorrect(bool enable) { void RenderThread::OnSetIsIncognitoProcess(bool is_incognito_process) { is_incognito_process_ = is_incognito_process; } + +void RenderThread::OnGpuChannelEstablished( + const IPC::ChannelHandle& channel_handle) { +#if defined(OS_POSIX) + // If we received a ChannelHandle, register it now. + if (channel_handle.socket.fd >= 0) + IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); +#endif + + if (channel_handle.name.size() != 0) { + // Connect to the GPU process if a channel name was received. + gpu_channel_->Connect(channel_handle.name); + } else { + // Otherwise cancel the connection. + gpu_channel_ = NULL; + } +} diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index fea7e41..3caed00 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -18,9 +18,11 @@ #include "chrome/common/child_thread.h" #include "chrome/common/css_colors.h" #include "chrome/common/dom_storage_common.h" +#include "chrome/renderer/gpu_channel_host.h" #include "chrome/renderer/renderer_histogram_snapshots.h" #include "chrome/renderer/visitedlink_slave.h" #include "gfx/native_widget_types.h" +#include "ipc/ipc_channel_handle.h" #include "ipc/ipc_platform_file.h" class AppCacheDispatcher; @@ -165,6 +167,15 @@ class RenderThread : public RenderThreadBase, // Update the list of active extensions that will be reported when we crash. void UpdateActiveExtensions(); + // Asynchronously establish a channel to the GPU plugin if not previously + // established or if it has been lost (for example if the GPU plugin crashed). + // Use GetGpuChannel() to determine when the channel is ready for use. + void EstablishGpuChannel(); + + // Get the GPU channel. Returns NULL if the channel is not established or + // has been lost. + GpuChannelHost* GetGpuChannel(); + private: virtual void OnControlMessageReceived(const IPC::Message& msg); @@ -220,6 +231,8 @@ class RenderThread : public RenderThreadBase, void OnSpellCheckWordAdded(const std::string& word); void OnSpellCheckEnableAutoSpellCorrect(bool enable); + void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle); + // Gather usage statistics from the in-memory cache and inform our host. // These functions should be call periodically so that the host can make // decisions about how to allocation resources using current information. @@ -288,6 +301,9 @@ class RenderThread : public RenderThreadBase, // not idle, to ensure that IdleHandle gets called eventually. base::RepeatingTimer<RenderThread> forced_idle_timer_; + // The channel from the renderer process to the GPU process. + scoped_refptr<GpuChannelHost> gpu_channel_; + DISALLOW_COPY_AND_ASSIGN(RenderThread); }; diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index def6e47..50af08f 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -150,7 +150,6 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidget) IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) - IPC_MESSAGE_HANDLER(ViewMsg_GpuChannelEstablished, OnGpuChannelEstablished) IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -732,23 +731,6 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) { webwidget_->setTextDirection(direction); } -void RenderWidget::OnGpuChannelEstablished( - const IPC::ChannelHandle& channel_handle) { -#if defined(OS_POSIX) - // If we received a ChannelHandle, register it now. - if (channel_handle.socket.fd >= 0) - IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); -#endif - - if (channel_handle.name.size() != 0) { - // Connect to the GPU process if a channel name was received. - gpu_channel_->Connect(channel_handle.name); - } else { - // Otherwise cancel the connection. - gpu_channel_ = NULL; - } -} - void RenderWidget::SetHidden(bool hidden) { if (is_hidden_ == hidden) return; @@ -892,31 +874,3 @@ void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { } } -void RenderWidget::EstablishGpuChannel() { - if (gpu_channel_.get()) { - // Do nothing if we are already establishing GPU channel. - if (gpu_channel_->state() == GpuChannelHost::UNCONNECTED) - return; - - // Recreate the channel if it has been lost. - if (gpu_channel_->state() == GpuChannelHost::LOST) - gpu_channel_ = NULL; - } - - if (!gpu_channel_.get()) - gpu_channel_ = new GpuChannelHost; - - // Ask the browser for the channel name. - CHECK(Send(new ViewHostMsg_EstablishGpuChannel(routing_id_))); -} - -GpuChannelHost* RenderWidget::GetGpuChannel() { - if (!gpu_channel_.get()) - return NULL; - - if (gpu_channel_->state() != GpuChannelHost::CONNECTED) - return NULL; - - return gpu_channel_.get(); -} - diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index 4759e30..4781790 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -10,7 +10,6 @@ #include "base/basictypes.h" #include "base/ref_counted.h" #include "base/shared_memory.h" -#include "chrome/renderer/gpu_channel_host.h" #include "chrome/renderer/paint_aggregator.h" #include "chrome/renderer/render_process.h" #include "gfx/native_widget_types.h" @@ -18,7 +17,6 @@ #include "gfx/rect.h" #include "gfx/size.h" #include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_handle.h" #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebCompositionCommand.h" @@ -107,15 +105,6 @@ class RenderWidget : public IPC::Channel::Listener, // Close the underlying WebWidget. virtual void Close(); - // Asynchronously establish a channel to the GPU plugin if not previously - // established or if it has been lost (for example if the GPU plugin crashed). - // Use GetGpuChannel() to determine when the channel is ready for use. - void EstablishGpuChannel(); - - // Get the GPU channel. Returns NULL if the channel is not established or - // has been lost. - GpuChannelHost* GetGpuChannel(); - protected: // Friend RefCounted so that the dtor can be non-public. Using this class // without ref-counting is an error. @@ -171,7 +160,6 @@ class RenderWidget : public IPC::Channel::Listener, const string16& ime_string); void OnMsgRepaint(const gfx::Size& size_to_paint); void OnSetTextDirection(WebKit::WebTextDirection direction); - void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle); // Override point to notify derived classes that a paint has happened. // DidInitiatePaint happens when we've generated a new bitmap and sent it to @@ -332,9 +320,6 @@ class RenderWidget : public IPC::Channel::Listener, // Indicates if the next sequence of Char events should be suppressed or not. bool suppress_next_char_events_; - // The channel from the renderer process to the GPU process. - scoped_refptr<GpuChannelHost> gpu_channel_; - DISALLOW_COPY_AND_ASSIGN(RenderWidget); }; |