summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/gpu_process_host.cc42
-rw-r--r--chrome/browser/gpu_process_host.h39
-rw-r--r--chrome/browser/renderer_host/backing_store.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc8
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h6
-rwxr-xr-xchrome/chrome.gyp5
-rwxr-xr-xchrome/chrome_renderer.gypi2
-rw-r--r--chrome/common/command_buffer_messages.h44
-rw-r--r--chrome/common/command_buffer_messages_internal.h73
-rw-r--r--chrome/common/gpu_messages.h31
-rw-r--r--chrome/common/gpu_messages_internal.h107
-rw-r--r--chrome/common/plugin_messages_internal.h2
-rw-r--r--chrome/common/render_messages_internal.h11
-rw-r--r--chrome/gpu/DEPS3
-rw-r--r--chrome/gpu/gpu_channel.cc185
-rw-r--r--chrome/gpu/gpu_channel.h104
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.cc120
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.h62
-rw-r--r--chrome/gpu/gpu_thread.cc21
-rw-r--r--chrome/gpu/gpu_thread.h1
-rw-r--r--chrome/plugin/command_buffer_stub.cc24
-rw-r--r--chrome/plugin/command_buffer_stub_win.cc4
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc8
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h2
-rw-r--r--chrome/renderer/command_buffer_proxy.cc35
-rw-r--r--chrome/renderer/command_buffer_proxy.h8
-rw-r--r--chrome/renderer/gpu_channel_host.cc101
-rw-r--r--chrome/renderer/gpu_channel_host.h77
-rw-r--r--chrome/renderer/render_widget.cc41
-rw-r--r--chrome/renderer/render_widget.h15
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc27
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h2
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc15
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc235
-rw-r--r--gpu/command_buffer/service/gpu_processor_win.cc8
-rw-r--r--gpu/gpu.gyp2
-rw-r--r--ipc/ipc_channel_handle.h2
-rw-r--r--ipc/ipc_message_utils.h3
39 files changed, 1219 insertions, 259 deletions
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index f2cdc80..ef90edc 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -11,9 +11,11 @@
#include "chrome/browser/child_process_host.h"
#include "chrome/browser/child_process_launcher.h"
#include "chrome/browser/io_thread.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/child_process_info.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gpu_messages.h"
+#include "chrome/common/render_messages.h"
#include "ipc/ipc_switches.h"
GpuProcessHost::GpuProcessHost() : last_routing_id_(1) {
@@ -93,8 +95,7 @@ bool GpuProcessHost::Send(IPC::Message* msg) {
void GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
if (message.routing_id() == MSG_ROUTING_CONTROL) {
- // We don't currently have any control messages.
- // OnControlMessageReceived(message);
+ OnControlMessageReceived(message);
} else {
router_.OnMessageReceived(message);
}
@@ -121,3 +122,40 @@ void GpuProcessHost::AddRoute(int32 routing_id,
void GpuProcessHost::RemoveRoute(int32 routing_id) {
router_.RemoveRoute(routing_id);
}
+
+void GpuProcessHost::EstablishGpuChannel(
+ int renderer_id,
+ int routing_id) {
+ if (Send(new GpuMsg_EstablishChannel(renderer_id)))
+ sent_requests_.push(ChannelRequest(renderer_id, routing_id));
+ else
+ ReplyToRenderer(renderer_id, routing_id, IPC::ChannelHandle());
+}
+
+void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+}
+
+void GpuProcessHost::OnChannelEstablished(
+ const IPC::ChannelHandle& channel_handle) {
+ const ChannelRequest& request = sent_requests_.front();
+
+ ReplyToRenderer(request.renderer_id, request.routing_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)));
+}
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index d107b88..f64cdd8 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -13,9 +13,11 @@
#include "chrome/browser/child_process_launcher.h"
#include "chrome/common/gpu_native_window_handle.h"
#include "chrome/common/message_router.h"
+#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_channel_proxy.h"
class ChildProcessLauncher;
+class CommandBufferProxy;
class GpuProcessHost : public IPC::Channel::Sender,
public IPC::Channel::Listener,
@@ -45,16 +47,51 @@ class GpuProcessHost : public IPC::Channel::Sender,
void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
void RemoveRoute(int32 routing_id);
+ // 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);
+
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) {}
+ // 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();
virtual ~GpuProcessHost();
+ void OnControlMessageReceived(const IPC::Message& message);
+
+ // Message handlers.
+ 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
+ // the GPU process, but haven't heard back about yet.
+ std::queue<ChannelRequest> sent_requests_;
+
scoped_ptr<ChildProcessLauncher> child_process_;
// A proxy for our IPC::Channel that lives on the IO thread (see
- // browser_process.h). This will be NULL if the class failed to initialize.
+ // browser_process.h). This will be NULL if the class failed to connect.
scoped_ptr<IPC::ChannelProxy> channel_;
int last_routing_id_;
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h
index a60adc2..b32a0e2 100644
--- a/chrome/browser/renderer_host/backing_store.h
+++ b/chrome/browser/renderer_host/backing_store.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/gfx/rect.h"
#include "base/gfx/size.h"
#include "base/process.h"
#include "chrome/common/transport_dib.h"
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 44a36bd..2bee3e6 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -8,6 +8,7 @@
#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"
@@ -15,6 +16,7 @@
#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"
@@ -137,6 +139,8 @@ 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)
@@ -861,6 +865,10 @@ 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 f1b402e..a3fdfdf 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -13,6 +13,7 @@
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/timer.h"
+#include "ipc/ipc_channel_handle.h"
#include "chrome/common/edit_command.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/property_bag.h"
@@ -443,6 +444,11 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// Using int instead of ViewHostMsg_ImeControl for control's type to avoid
// 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/chrome.gyp b/chrome/chrome.gyp
index f6b8fd6..9b2dfeb 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -664,12 +664,17 @@
'msvs_guid': 'F10F1ECD-D84D-4C33-8468-9DDFE19F4D8A',
'dependencies': [
'../base/base.gyp:base',
+ '../gpu/gpu.gyp:command_buffer_service',
'common',
'../skia/skia.gyp:skia',
],
'sources': [
'gpu/gpu_backing_store_win.cc',
'gpu/gpu_backing_store_win.h',
+ 'gpu/gpu_channel.cc',
+ 'gpu/gpu_channel.h',
+ 'gpu/gpu_command_buffer_stub.cc',
+ 'gpu/gpu_command_buffer_stub.h',
'gpu/gpu_config.h',
'gpu/gpu_main.cc',
'gpu/gpu_process.cc',
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 7acf628..2f27359 100755
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -94,6 +94,8 @@
'renderer/form_manager.h',
'renderer/geolocation_dispatcher.cc',
'renderer/geolocation_dispatcher.h',
+ 'renderer/gpu_channel_host.cc',
+ 'renderer/gpu_channel_host.h',
'renderer/localized_error.cc',
'renderer/localized_error.h',
'renderer/navigation_state.h',
diff --git a/chrome/common/command_buffer_messages.h b/chrome/common/command_buffer_messages.h
deleted file mode 100644
index 144ff2f..0000000
--- a/chrome/common/command_buffer_messages.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2009 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 CHROME_COMMON_COMMAND_BUFFER_MESSAGES_H_
-#define CHROME_COMMON_COMMAND_BUFFER_MESSAGES_H_
-
-#include "chrome/common/common_param_traits.h"
-#include "gpu/command_buffer/common/command_buffer.h"
-
-namespace IPC {
-template <>
-struct ParamTraits<gpu::CommandBuffer::State> {
- typedef gpu::CommandBuffer::State param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteInt(p.size);
- m->WriteInt(p.get_offset);
- m->WriteInt(p.put_offset);
- m->WriteInt(p.token);
- m->WriteInt(p.error);
- }
- static bool Read(const Message* m, void** iter, param_type* p) {
- int32 temp;
- if (m->ReadInt(iter, &p->size) &&
- m->ReadInt(iter, &p->get_offset) &&
- m->ReadInt(iter, &p->put_offset) &&
- m->ReadInt(iter, &p->token) &&
- m->ReadInt(iter, &temp)) {
- p->error = static_cast<gpu::error::Error>(temp);
- return true;
- } else {
- return false;
- }
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"<CommandBuffer::State>");
- }
-};
-} // namespace IPC
-
-#define MESSAGES_INTERNAL_FILE "chrome/common/command_buffer_messages_internal.h"
-#include "ipc/ipc_message_macros.h"
-
-#endif // CHROME_COMMON_COMMAND_BUFFER_MESSAGES_H_
diff --git a/chrome/common/command_buffer_messages_internal.h b/chrome/common/command_buffer_messages_internal.h
deleted file mode 100644
index 5a62b00..0000000
--- a/chrome/common/command_buffer_messages_internal.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/shared_memory.h"
-#include "ipc/ipc_message_macros.h"
-
-IPC_BEGIN_MESSAGES(CommandBuffer)
- // Initialize a command buffer with the given number of command entries.
- // Returns the shared memory handle for the command buffer mapped to the
- // calling process.
- IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_Initialize,
- int32 /* size */,
- base::SharedMemoryHandle /* ring_buffer */)
-
- // Get the current state of the command buffer.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetState,
- gpu::CommandBuffer::State /* state */)
-
- // Get the current state of the command buffer asynchronously. State is
- // returned via UpdateState message.
- IPC_MESSAGE_ROUTED0(CommandBufferMsg_AsyncGetState)
-
- // Synchronize the put and get offsets of both processes. Caller passes its
- // current put offset. Current state (including get offset) is returned.
- IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_Flush,
- int32 /* put_offset */,
- gpu::CommandBuffer::State /* state */)
-
- // Asynchronously synchronize the put and get offsets of both processes.
- // Caller passes its current put offset. Current state (including get offset)
- // is returned via an UpdateState message.
- IPC_MESSAGE_ROUTED1(CommandBufferMsg_AsyncFlush,
- int32 /* put_offset */)
-
- // Return the current state of the command buffer following a request via
- // an AsyncGetState or AsyncFlush message.
- IPC_MESSAGE_ROUTED1(CommandBufferMsg_UpdateState,
- gpu::CommandBuffer::State /* state */)
-
- // Create a shared memory transfer buffer. Returns an id that can be used to
- // identify the transfer buffer from a comment.
- IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_CreateTransferBuffer,
- int32 /* size */,
- int32 /* id */)
-
- // Destroy a previously created transfer buffer.
- IPC_SYNC_MESSAGE_ROUTED1_0(CommandBufferMsg_DestroyTransferBuffer,
- int32 /* id */)
-
- // Get the shared memory handle for a transfer buffer mapped to the callers
- // process.
- IPC_SYNC_MESSAGE_ROUTED1_2(CommandBufferMsg_GetTransferBuffer,
- int32 /* id */,
- base::SharedMemoryHandle /* transfer_buffer */,
- uint32 /* size */)
-
- // Send from command buffer stub to proxy when window is invalid and must be
- // repainted.
- IPC_MESSAGE_ROUTED0(CommandBufferMsg_NotifyRepaint)
-
-#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
- // resize events explicitly to the command buffer stub so it can
- // reallocate its backing store and send the new one back to the
- // browser. This message is currently used only on 10.6 and later.
- IPC_MESSAGE_ROUTED2(CommandBufferMsg_SetWindowSize,
- int32 /* width */,
- int32 /* height */)
-#endif
-
-IPC_END_MESSAGES(CommandBuffer)
diff --git a/chrome/common/gpu_messages.h b/chrome/common/gpu_messages.h
index fc2a826..1bf9bac 100644
--- a/chrome/common/gpu_messages.h
+++ b/chrome/common/gpu_messages.h
@@ -15,11 +15,36 @@
#include "chrome/common/common_param_traits.h"
#include "chrome/common/gpu_native_window_handle.h"
#include "chrome/common/transport_dib.h"
+#include "gpu/command_buffer/common/command_buffer.h"
namespace IPC {
-
-// Potential new structures for messages go here.
-
+template <>
+struct ParamTraits<gpu::CommandBuffer::State> {
+ typedef gpu::CommandBuffer::State param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p.size);
+ m->WriteInt(p.get_offset);
+ m->WriteInt(p.put_offset);
+ m->WriteInt(p.token);
+ m->WriteInt(p.error);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int32 temp;
+ if (m->ReadInt(iter, &p->size) &&
+ m->ReadInt(iter, &p->get_offset) &&
+ m->ReadInt(iter, &p->put_offset) &&
+ m->ReadInt(iter, &p->token) &&
+ m->ReadInt(iter, &temp)) {
+ p->error = static_cast<gpu::error::Error>(temp);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<CommandBuffer::State>");
+ }
+};
} // namespace IPC
#define MESSAGES_INTERNAL_FILE \
diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h
index 0581e4c..6780a5e 100644
--- a/chrome/common/gpu_messages_internal.h
+++ b/chrome/common/gpu_messages_internal.h
@@ -8,13 +8,23 @@
// 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 "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
//------------------------------------------------------------------------------
-// Backing Store Messages
+// GPU Messages
// These are messages from the browser to the GPU process.
IPC_BEGIN_MESSAGES(Gpu)
+ // Tells the GPU process to create a new channel for communication with a
+ // given renderer. The channel name is returned in a
+ // GpuHostMsg_ChannelEstablished message. The renderer ID is passed so that
+ // the GPU process reuses an existing channel to that process if it exists.
+ // This ID is a unique opaque identifier generated by the browser process.
+ IPC_MESSAGE_CONTROL1(GpuMsg_EstablishChannel,
+ int /* renderer_id */)
+
IPC_MESSAGE_CONTROL2(GpuMsg_NewRenderWidgetHostView,
GpuNativeWindowHandle, /* parent window */
int32 /* view_id */)
@@ -61,7 +71,7 @@ IPC_BEGIN_MESSAGES(Gpu)
IPC_END_MESSAGES(Gpu)
//------------------------------------------------------------------------------
-// Backing Store Host Messagse
+// GPU Host Messages
// These are messages from the GPU process to the browser.
IPC_BEGIN_MESSAGES(GpuHost)
@@ -76,4 +86,97 @@ IPC_BEGIN_MESSAGES(GpuHost)
// Sent in response to GpuMsg_PaintToVideoLayer, see that for more.
IPC_MESSAGE_ROUTED0(GpuHostMsg_PaintToVideoLayer_ACK)
+ // Response to a GpuHostMsg_EstablishChannel message.
+ IPC_MESSAGE_CONTROL1(GpuHostMsg_ChannelEstablished,
+ IPC::ChannelHandle /* channel_handle */)
IPC_END_MESSAGES(GpuHost)
+
+//------------------------------------------------------------------------------
+// GPU Channel Messages
+// 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,
+ int32 /* route_id */)
+
+ // The CommandBufferProxy sends this to the GpuCommandBufferStub in its
+ // destructor, so that the stub deletes the actual WebPluginDelegateImpl
+ // object that it's hosting.
+ // TODO(apatrick): Implement this.
+ IPC_MESSAGE_CONTROL1(GpuChannelMsg_DestroyCommandBuffer,
+ int32 /* instance_id */)
+
+IPC_END_MESSAGES(GpuChannel)
+
+//------------------------------------------------------------------------------
+// GPU Command Buffer Messages
+// These are messages from a renderer process to the GPU process relating to a
+// single OpenGL context.
+IPC_BEGIN_MESSAGES(GpuCommandBuffer)
+ // Initialize a command buffer with the given number of command entries.
+ // Returns the shared memory handle for the command buffer mapped to the
+ // calling process.
+ IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_Initialize,
+ int32 /* size */,
+ base::SharedMemoryHandle /* ring_buffer */)
+
+ // Get the current state of the command buffer.
+ IPC_SYNC_MESSAGE_ROUTED0_1(GpuCommandBufferMsg_GetState,
+ gpu::CommandBuffer::State /* state */)
+
+ // Get the current state of the command buffer asynchronously. State is
+ // returned via UpdateState message.
+ IPC_MESSAGE_ROUTED0(GpuCommandBufferMsg_AsyncGetState)
+
+ // Synchronize the put and get offsets of both processes. Caller passes its
+ // current put offset. Current state (including get offset) is returned.
+ IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_Flush,
+ int32 /* put_offset */,
+ gpu::CommandBuffer::State /* state */)
+
+ // Asynchronously synchronize the put and get offsets of both processes.
+ // Caller passes its current put offset. Current state (including get offset)
+ // is returned via an UpdateState message.
+ IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_AsyncFlush,
+ int32 /* put_offset */)
+
+ // Return the current state of the command buffer following a request via
+ // an AsyncGetState or AsyncFlush message.
+ IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_UpdateState,
+ gpu::CommandBuffer::State /* state */)
+
+ // Create a shared memory transfer buffer. Returns an id that can be used to
+ // identify the transfer buffer from a comment.
+ IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_CreateTransferBuffer,
+ int32 /* size */,
+ int32 /* id */)
+
+ // Destroy a previously created transfer buffer.
+ IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_DestroyTransferBuffer,
+ int32 /* id */)
+
+ // Get the shared memory handle for a transfer buffer mapped to the callers
+ // process.
+ IPC_SYNC_MESSAGE_ROUTED1_2(GpuCommandBufferMsg_GetTransferBuffer,
+ int32 /* id */,
+ base::SharedMemoryHandle /* transfer_buffer */,
+ uint32 /* size */)
+
+ // Send from command buffer stub to proxy when window is invalid and must be
+ // repainted.
+ IPC_MESSAGE_ROUTED0(GpuCommandBufferMsg_NotifyRepaint)
+
+#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
+ // resize events explicitly to the command buffer stub so it can
+ // reallocate its backing store and send the new one back to the
+ // browser. This message is currently used only on 10.6 and later.
+ IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SetWindowSize,
+ int32 /* width */,
+ int32 /* height */)
+#endif
+
+IPC_END_MESSAGES(GpuCommandBuffer)
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index f83bfca..1f8dd54 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -294,6 +294,8 @@ IPC_BEGIN_MESSAGES(Plugin)
IPC_SYNC_MESSAGE_ROUTED0_1(PluginMsg_CreateCommandBuffer,
int /* route_id */)
+ IPC_MESSAGE_ROUTED0(PluginMsg_DestroyCommandBuffer)
+
IPC_MESSAGE_CONTROL1(PluginMsg_SignalModalDialogEvent,
gfx::NativeViewId /* containing_window */)
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index e4a9b72..dc852f7 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -607,6 +607,11 @@ IPC_BEGIN_MESSAGES(View)
// into a full window).
IPC_MESSAGE_ROUTED0(ViewMsg_DisassociateFromPopupCount)
+ // 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 */)
+
// Notifies the renderer of the appcache that has been selected for a
// a particular host. This is sent in reply to AppCacheMsg_SelectCache.
IPC_MESSAGE_CONTROL3(AppCacheMsg_CacheSelected,
@@ -1330,6 +1335,12 @@ IPC_BEGIN_MESSAGES(ViewHost)
IPC::ChannelHandle /* handle to channel */,
WebPluginInfo /* info */)
+ // A renderer sends this to the browser process when it wants to
+ // 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)
+
// 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
// the process and return a handle to an IMC channel.
diff --git a/chrome/gpu/DEPS b/chrome/gpu/DEPS
index beacfd9..f071f77 100644
--- a/chrome/gpu/DEPS
+++ b/chrome/gpu/DEPS
@@ -1,4 +1,5 @@
include_rules = [
- "+chrome/app",
+ "+chrome/app",
+ "+gpu/command_buffer",
]
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc
new file mode 100644
index 0000000..25bb951
--- /dev/null
+++ b/chrome/gpu/gpu_channel.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/gpu/gpu_channel.h"
+
+#include "base/command_line.h"
+#include "base/lock.h"
+#include "base/process_util.h"
+#include "base/string_util.h"
+#include "base/waitable_event.h"
+#include "build/build_config.h"
+#include "chrome/common/child_process.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_thread.h"
+
+#if defined(OS_POSIX)
+#include "ipc/ipc_channel_posix.h"
+#endif
+
+namespace {
+class GpuReleaseTask : public Task {
+ public:
+ void Run() {
+ ChildProcess::current()->ReleaseProcess();
+ }
+};
+
+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)
+#if defined(OS_POSIX)
+ , renderer_fd_(-1)
+#endif
+{
+ ChildProcess::current()->AddRefProcess();
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
+}
+
+GpuChannel::~GpuChannel() {
+#if defined(OS_POSIX)
+ // If we still have the renderer FD, close it.
+ if (renderer_fd_ != -1) {
+ close(renderer_fd_);
+ }
+#endif
+ ChildProcess::current()->io_message_loop()->PostDelayedTask(
+ FROM_HERE,
+ new GpuReleaseTask(),
+ kGpuReleaseTimeMS);
+}
+
+void GpuChannel::OnChannelConnected(int32 peer_pid) {
+ if (!renderer_process_.Open(peer_pid)) {
+ NOTREACHED();
+ }
+}
+
+void GpuChannel::OnMessageReceived(const IPC::Message& message) {
+ if (log_messages_) {
+ LOG(INFO) << "received message @" << &message << " on channel @" << this
+ << " with type " << message.type();
+ }
+
+ if (message.routing_id() == MSG_ROUTING_CONTROL) {
+ OnControlMessageReceived(message);
+ } else {
+ // The sender should know not to route messages to an object after it
+ // has been destroyed.
+ CHECK(router_.RouteMessage(message));
+ }
+}
+
+void GpuChannel::OnChannelError() {
+ // Destroy channel. This will cause the channel to be recreated if another
+ // attempt is made to establish a connection from the corresponding renderer.
+ channel_.reset();
+
+ // Close renderer process handle.
+ renderer_process_.Close();
+
+#if defined(ENABLE_GPU)
+ // Destroy all the stubs on this channel.
+ for (size_t i = 0; i < stubs_.size(); ++i) {
+ router_.RemoveRoute(stubs_[i]->route_id());
+ }
+ stubs_.clear();
+#endif
+}
+
+bool GpuChannel::Send(IPC::Message* message) {
+ if (log_messages_) {
+ LOG(INFO) << "sending message @" << message << " on channel @" << this
+ << " with type " << message->type();
+ }
+
+ if (!channel_.get()) {
+ delete message;
+ return false;
+ }
+
+ return channel_->Send(message);
+}
+
+void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer,
+ OnCreateCommandBuffer)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
+ OnDestroyCommandBuffer)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+}
+
+int GpuChannel::GenerateRouteID() {
+ static int last_id = 0;
+ return ++last_id;
+}
+
+void GpuChannel::OnCreateCommandBuffer(int* route_id) {
+#if defined(ENABLE_GPU)
+ *route_id = GenerateRouteID();
+ scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub(
+ this, *route_id);
+ router_.AddRoute(*route_id, stub);
+ stubs_[*route_id] = stub;
+#else
+ *route_id = 0;
+#endif
+}
+
+void GpuChannel::OnDestroyCommandBuffer(int route_id) {
+#if defined(ENABLE_GPU)
+ StubMap::iterator it = stubs_.find(route_id);
+ DCHECK(it != stubs_.end());
+ stubs_.erase(it);
+ router_.RemoveRoute(route_id);
+#endif
+}
+
+bool GpuChannel::Init(const std::string& channel_name) {
+ channel_name_ = channel_name;
+ channel_.reset(new IPC::SyncChannel(
+ channel_name, IPC::Channel::MODE_SERVER, this, NULL,
+ ChildProcess::current()->io_message_loop(), false,
+ ChildProcess::current()->GetShutDownEvent()));
+ return true;
+}
diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h
new file mode 100644
index 0000000..17ea363
--- /dev/null
+++ b/chrome/gpu/gpu_channel.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2010 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 CHROME_GPU_GPU_CHANNEL_H_
+#define CHROME_GPU_GPU_CHANNEL_H_
+
+#include <string>
+
+#include "base/hash_tables.h"
+#include "base/ref_counted.h"
+#include "base/scoped_open_process.h"
+#include "build/build_config.h"
+#include "chrome/common/message_router.h"
+#include "chrome/gpu/gpu_command_buffer_stub.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sync_channel.h"
+
+// Encapsulates an IPC channel between the GPU process and one renderer
+// process. On the renderer side there's a corresponding GpuChannelHost.
+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);
+
+ virtual ~GpuChannel();
+
+ std::string channel_name() const { return channel_name_; }
+
+ base::ProcessHandle renderer_handle() const {
+ return renderer_process_.handle();
+ }
+
+#if defined(OS_POSIX)
+ // When first created, the GpuChannel gets assigned the file descriptor
+ // for the renderer.
+ // After the first time we pass it through the IPC, we don't need it anymore,
+ // and we close it. At that time, we reset renderer_fd_ to -1.
+ int DisownRendererFd() {
+ int value = renderer_fd_;
+ renderer_fd_ = -1;
+ return value;
+ }
+#endif
+
+ // IPC::Channel::Listener implementation:
+ virtual void OnMessageReceived(const IPC::Message& msg);
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+
+ // IPC::Message::Sender implementation:
+ 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);
+
+ 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_;
+
+ // The id of the renderer who is on the other side of the channel.
+ int renderer_id_;
+
+#if defined(OS_POSIX)
+ // FD for the renderer end of the pipe. It is stored until we send it over
+ // IPC after which it is cleared. It will be closed by the IPC mechanism.
+ int renderer_fd_;
+#endif
+
+ // Used to implement message routing functionality to CommandBuffer objects
+ MessageRouter router_;
+
+#if defined(ENABLE_GPU)
+ typedef base::hash_map<int, scoped_refptr<GpuCommandBufferStub> > StubMap;
+ StubMap stubs_;
+#endif
+
+ bool log_messages_; // True if we should log sent and received messages.
+
+ DISALLOW_COPY_AND_ASSIGN(GpuChannel);
+};
+
+#endif // CHROME_GPU_GPU_CHANNEL_H_
diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc
new file mode 100644
index 0000000..6c3f5cc
--- /dev/null
+++ b/chrome/gpu/gpu_command_buffer_stub.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2010 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.
+
+#if defined(ENABLE_GPU)
+
+#include "base/process_util.h"
+#include "base/shared_memory.h"
+#include "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_channel.h"
+#include "chrome/gpu/gpu_command_buffer_stub.h"
+
+using gpu::Buffer;
+
+GpuCommandBufferStub::GpuCommandBufferStub(GpuChannel* channel,
+ int32 route_id)
+ : channel_(channel),
+ route_id_(route_id) {
+}
+
+GpuCommandBufferStub::~GpuCommandBufferStub() {
+}
+
+void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer,
+ OnCreateTransferBuffer);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
+ OnDestroyTransferBuffer);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer,
+ OnGetTransferBuffer);
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+}
+
+bool GpuCommandBufferStub::Send(IPC::Message* message) {
+ return channel_->Send(message);
+}
+
+void GpuCommandBufferStub::OnInitialize(
+ int32 size,
+ base::SharedMemoryHandle* ring_buffer) {
+ DCHECK(!command_buffer_.get());
+
+ *ring_buffer = base::SharedMemory::NULLHandle();
+
+ command_buffer_.reset(new gpu::CommandBufferService);
+
+ // Initialize the CommandBufferService and GPUProcessor.
+ 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)) {
+ command_buffer_->SetPutOffsetChangeCallback(
+ NewCallback(processor_.get(),
+ &gpu::GPUProcessor::ProcessCommands));
+
+ // Assume service is responsible for duplicating the handle from the
+ // calling process.
+ buffer.shared_memory->ShareToProcess(channel_->renderer_handle(),
+ ring_buffer);
+ } else {
+ processor_ = NULL;
+ command_buffer_.reset();
+ }
+ }
+ }
+}
+
+void GpuCommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
+ *state = command_buffer_->GetState();
+}
+
+void GpuCommandBufferStub::OnAsyncGetState() {
+ gpu::CommandBuffer::State state = command_buffer_->GetState();
+ Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
+}
+
+void GpuCommandBufferStub::OnFlush(int32 put_offset,
+ gpu::CommandBuffer::State* state) {
+ *state = command_buffer_->Flush(put_offset);
+}
+
+void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) {
+ gpu::CommandBuffer::State state = command_buffer_->Flush(put_offset);
+ Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
+}
+
+void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, int32* id) {
+ *id = command_buffer_->CreateTransferBuffer(size);
+}
+
+void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
+ command_buffer_->DestroyTransferBuffer(id);
+}
+
+void GpuCommandBufferStub::OnGetTransferBuffer(
+ int32 id,
+ base::SharedMemoryHandle* transfer_buffer,
+ uint32* size) {
+ *transfer_buffer = base::SharedMemoryHandle();
+ *size = 0;
+
+ Buffer buffer = command_buffer_->GetTransferBuffer(id);
+ if (buffer.shared_memory) {
+ // Assume service is responsible for duplicating the handle to the calling
+ // process.
+ buffer.shared_memory->ShareToProcess(channel_->renderer_handle(),
+ transfer_buffer);
+ *size = buffer.shared_memory->max_size();
+ }
+}
+
+#endif // ENABLE_GPU
diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h
new file mode 100644
index 0000000..f1446e8
--- /dev/null
+++ b/chrome/gpu/gpu_command_buffer_stub.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 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 CHROME_GPU_GPU_COMMAND_BUFFER_STUB_H_
+#define CHROME_GPU_GPU_COMMAND_BUFFER_STUB_H_
+
+#if defined(ENABLE_GPU)
+
+#include "app/gfx/native_widget_types.h"
+#include "base/process.h"
+#include "base/ref_counted.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
+#include "gpu/command_buffer/service/gpu_processor.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+
+class GpuChannel;
+
+class GpuCommandBufferStub
+ : public IPC::Channel::Listener,
+ public IPC::Message::Sender,
+ public base::RefCountedThreadSafe<GpuCommandBufferStub> {
+ public:
+ GpuCommandBufferStub(GpuChannel* channel,
+ int32 route_id);
+
+ virtual ~GpuCommandBufferStub();
+
+ // IPC::Channel::Listener implementation:
+ virtual void OnMessageReceived(const IPC::Message& message);
+
+ // IPC::Message::Sender implementation:
+ virtual bool Send(IPC::Message* msg);
+
+ int route_id() const { return route_id_; }
+
+ private:
+ // Message handlers:
+ void OnInitialize(int32 size, base::SharedMemoryHandle* ring_buffer);
+ void OnGetState(gpu::CommandBuffer::State* state);
+ void OnAsyncGetState();
+ void OnFlush(int32 put_offset, gpu::CommandBuffer::State* state);
+ void OnAsyncFlush(int32 put_offset);
+ void OnCreateTransferBuffer(int32 size, int32* id);
+ void OnDestroyTransferBuffer(int32 id);
+ void OnGetTransferBuffer(int32 id,
+ base::SharedMemoryHandle* transfer_buffer,
+ uint32* size);
+
+ scoped_refptr<GpuChannel> channel_;
+ int route_id_;
+
+ scoped_ptr<gpu::CommandBufferService> command_buffer_;
+ scoped_refptr<gpu::GPUProcessor> processor_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub);
+};
+
+#endif // ENABLE_GPU
+
+#endif // CHROME_GPU_GPU_COMMAND_BUFFER_STUB_H_
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index 4c9a974..1839412 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -5,7 +5,9 @@
#include "chrome/gpu/gpu_thread.h"
#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)
@@ -37,11 +39,30 @@ GpuBackingStoreGLXContext* GpuThread::GetGLXContext() {
void GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
bool msg_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(GpuThread, msg, msg_is_ok)
+ IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel,
+ OnEstablishChannel)
IPC_MESSAGE_HANDLER(GpuMsg_NewRenderWidgetHostView,
OnNewRenderWidgetHostView)
IPC_END_MESSAGE_MAP_EX()
}
+void GpuThread::OnEstablishChannel(int renderer_id) {
+ scoped_refptr<GpuChannel> channel =
+ GpuChannel::EstablishGpuChannel(renderer_id);
+ IPC::ChannelHandle channel_handle;
+ if (channel.get()) {
+ channel_handle.name = channel->channel_name();
+#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.
+ int renderer_fd = channel->DisownRendererFd();
+ channel_handle.socket = base::FileDescriptor(renderer_fd, true);
+#endif
+ }
+
+ Send(new GpuHostMsg_ChannelEstablished(channel_handle));
+}
+
void GpuThread::OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window,
int32 routing_id) {
// The GPUView class' lifetime is controlled by the host, which will send a
diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h
index f58db07..8224a9b 100644
--- a/chrome/gpu/gpu_thread.h
+++ b/chrome/gpu/gpu_thread.h
@@ -34,6 +34,7 @@ class GpuThread : public ChildThread {
virtual void OnControlMessageReceived(const IPC::Message& msg);
// Message handlers.
+ void OnEstablishChannel(int renderer_id);
void OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window,
int32 routing_id);
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index d8cc7d4..5ae203d 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -5,7 +5,7 @@
#include "base/callback.h"
#include "base/scoped_open_process.h"
#include "base/shared_memory.h"
-#include "chrome/common/command_buffer_messages.h"
+#include "chrome/common/gpu_messages.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/plugin/command_buffer_stub.h"
#include "chrome/plugin/plugin_channel.h"
@@ -29,19 +29,19 @@ CommandBufferStub::~CommandBufferStub() {
void CommandBufferStub::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, message)
- IPC_MESSAGE_HANDLER(CommandBufferMsg_Initialize, OnInitialize);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetState, OnGetState);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_AsyncGetState, OnAsyncGetState);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_Flush, OnFlush);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_AsyncFlush, OnAsyncFlush);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_CreateTransferBuffer,
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer,
OnCreateTransferBuffer);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_DestroyTransferBuffer,
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
OnDestroyTransferBuffer);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetTransferBuffer,
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer,
OnGetTransferBuffer);
#if defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER(CommandBufferMsg_SetWindowSize, OnSetWindowSize);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetWindowSize, OnSetWindowSize);
#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -127,7 +127,7 @@ void CommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
void CommandBufferStub::OnAsyncGetState() {
gpu::CommandBuffer::State state = command_buffer_->GetState();
- Send(new CommandBufferMsg_UpdateState(route_id_, state));
+ Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
}
void CommandBufferStub::OnFlush(int32 put_offset,
@@ -137,7 +137,7 @@ void CommandBufferStub::OnFlush(int32 put_offset,
void CommandBufferStub::OnAsyncFlush(int32 put_offset) {
gpu::CommandBuffer::State state = command_buffer_->Flush(put_offset);
- Send(new CommandBufferMsg_UpdateState(route_id_, state));
+ Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
}
void CommandBufferStub::OnCreateTransferBuffer(int32 size, int32* id) {
diff --git a/chrome/plugin/command_buffer_stub_win.cc b/chrome/plugin/command_buffer_stub_win.cc
index 656bbd1..abf13b1 100644
--- a/chrome/plugin/command_buffer_stub_win.cc
+++ b/chrome/plugin/command_buffer_stub_win.cc
@@ -4,7 +4,7 @@
#include <windows.h>
-#include "chrome/common/command_buffer_messages.h"
+#include "chrome/common/gpu_messages.h"
#include "chrome/plugin/command_buffer_stub.h"
namespace {
@@ -45,7 +45,7 @@ LRESULT WINAPI WndProc(HWND handle,
} // namespace anonymous
void CommandBufferStub::NotifyRepaint() {
- Send(new CommandBufferMsg_NotifyRepaint(route_id_));
+ Send(new GpuCommandBufferMsg_NotifyRepaint(route_id_));
}
bool CommandBufferStub::InitializePlatformSpecific() {
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index 7654058..e3d477e 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -140,6 +140,8 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
OnHTTPRangeRequestReply)
IPC_MESSAGE_HANDLER(PluginMsg_CreateCommandBuffer,
OnCreateCommandBuffer)
+ IPC_MESSAGE_HANDLER(PluginMsg_DestroyCommandBuffer,
+ OnDestroyCommandBuffer)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(PluginMsg_SetFakeGPUPluginWindowHandle,
OnSetFakeGPUPluginWindowHandle)
@@ -406,6 +408,12 @@ void WebPluginDelegateStub::OnCreateCommandBuffer(int* route_id) {
#endif // ENABLE_GPU
}
+void WebPluginDelegateStub::OnDestroyCommandBuffer() {
+#if defined(ENABLE_GPU)
+ command_buffer_stub_.reset();
+#endif
+}
+
void WebPluginDelegateStub::CreateSharedBuffer(
uint32 size,
base::SharedMemory* shared_buf,
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index 36fda08..1bbd04d 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -98,6 +98,8 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
int notify_id);
void OnHTTPRangeRequestReply(unsigned long resource_id, int range_request_id);
void OnCreateCommandBuffer(int* route_id);
+ void OnDestroyCommandBuffer();
+
void CreateSharedBuffer(uint32 size,
base::SharedMemory* shared_buf,
base::SharedMemoryHandle* remote_handle);
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index b2eaa86..bd0f3a0 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -4,7 +4,7 @@
#include "base/logging.h"
#include "base/process_util.h"
-#include "chrome/common/command_buffer_messages.h"
+#include "chrome/common/gpu_messages.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/renderer/command_buffer_proxy.h"
#include "chrome/renderer/plugin_channel_host.h"
@@ -13,12 +13,11 @@
using gpu::Buffer;
CommandBufferProxy::CommandBufferProxy(
- PluginChannelHost* channel,
+ IPC::Channel::Sender* channel,
int route_id)
: size_(0),
channel_(channel),
route_id_(route_id) {
- channel->AddRoute(route_id_, this, false);
}
CommandBufferProxy::~CommandBufferProxy() {
@@ -30,20 +29,24 @@ CommandBufferProxy::~CommandBufferProxy() {
delete it->second.shared_memory;
it->second.shared_memory = NULL;
}
-
- channel_->RemoveRoute(route_id_);
}
void CommandBufferProxy::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(CommandBufferProxy, message)
- IPC_MESSAGE_HANDLER(CommandBufferMsg_UpdateState, OnUpdateState);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_NotifyRepaint,
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateState, OnUpdateState);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_NotifyRepaint,
OnNotifyRepaint);
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
void CommandBufferProxy::OnChannelError() {
+ // Prevent any further messages from being sent.
+ channel_ = NULL;
+
+ // When the client sees that the context is lost, they should delete this
+ // CommandBufferProxy and create a new one.
+ last_state_.error = gpu::error::kLostContext;
}
bool CommandBufferProxy::Send(IPC::Message* msg) {
@@ -63,7 +66,7 @@ bool CommandBufferProxy::Initialize(int32 size) {
// process is responsible for duplicating the handle. This might not be true
// for NaCl.
base::SharedMemoryHandle handle;
- if (Send(new CommandBufferMsg_Initialize(route_id_, size, &handle)) &&
+ if (Send(new GpuCommandBufferMsg_Initialize(route_id_, size, &handle)) &&
base::SharedMemory::IsHandleValid(handle)) {
ring_buffer_.reset(new base::SharedMemory(handle, false));
if (ring_buffer_->Map(size * sizeof(int32))) {
@@ -87,12 +90,12 @@ Buffer CommandBufferProxy::GetRingBuffer() {
}
gpu::CommandBuffer::State CommandBufferProxy::GetState() {
- Send(new CommandBufferMsg_GetState(route_id_, &last_state_));
+ Send(new GpuCommandBufferMsg_GetState(route_id_, &last_state_));
return last_state_;
}
gpu::CommandBuffer::State CommandBufferProxy::Flush(int32 put_offset) {
- Send(new CommandBufferMsg_Flush(route_id_,
+ Send(new GpuCommandBufferMsg_Flush(route_id_,
put_offset,
&last_state_));
return last_state_;
@@ -105,7 +108,7 @@ void CommandBufferProxy::SetGetOffset(int32 get_offset) {
int32 CommandBufferProxy::CreateTransferBuffer(size_t size) {
int32 id;
- if (Send(new CommandBufferMsg_CreateTransferBuffer(route_id_, size, &id)))
+ if (Send(new GpuCommandBufferMsg_CreateTransferBuffer(route_id_, size, &id)))
return id;
return -1;
@@ -121,7 +124,7 @@ void CommandBufferProxy::DestroyTransferBuffer(int32 id) {
transfer_buffers_.erase(it);
- Send(new CommandBufferMsg_DestroyTransferBuffer(route_id_, id));
+ Send(new GpuCommandBufferMsg_DestroyTransferBuffer(route_id_, id));
}
Buffer CommandBufferProxy::GetTransferBuffer(int32 id) {
@@ -136,7 +139,7 @@ Buffer CommandBufferProxy::GetTransferBuffer(int32 id) {
// duplicating the handle. This might not be true for NaCl.
base::SharedMemoryHandle handle;
uint32 size;
- if (!Send(new CommandBufferMsg_GetTransferBuffer(route_id_,
+ if (!Send(new GpuCommandBufferMsg_GetTransferBuffer(route_id_,
id,
&handle,
&size))) {
@@ -182,12 +185,12 @@ void CommandBufferProxy::SetParseError(
#if defined(OS_MACOSX)
void CommandBufferProxy::SetWindowSize(int32 width, int32 height) {
- Send(new CommandBufferMsg_SetWindowSize(route_id_, width, height));
+ Send(new GpuCommandBufferMsg_SetWindowSize(route_id_, width, height));
}
#endif
void CommandBufferProxy::AsyncGetState(Task* completion_task) {
- IPC::Message* message = new CommandBufferMsg_AsyncGetState(route_id_);
+ IPC::Message* message = new GpuCommandBufferMsg_AsyncGetState(route_id_);
// Do not let a synchronous flush hold up this message. If this handler is
// deferred until after the synchronous flush completes, it will overwrite the
@@ -199,7 +202,7 @@ void CommandBufferProxy::AsyncGetState(Task* completion_task) {
}
void CommandBufferProxy::AsyncFlush(int32 put_offset, Task* completion_task) {
- IPC::Message* message = new CommandBufferMsg_AsyncFlush(route_id_,
+ IPC::Message* message = new GpuCommandBufferMsg_AsyncFlush(route_id_,
put_offset);
// Do not let a synchronous flush hold up this message. If this handler is
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index 990f6f3..5d72f2c 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -27,9 +27,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
public IPC::Channel::Listener,
public IPC::Message::Sender {
public:
- explicit CommandBufferProxy(
- PluginChannelHost* channel,
- int route_id);
+ CommandBufferProxy(IPC::Channel::Sender* channel, int route_id);
virtual ~CommandBufferProxy();
// IPC::Channel::Listener implementation:
@@ -39,6 +37,8 @@ class CommandBufferProxy : public gpu::CommandBuffer,
// IPC::Message::Sender implementation:
virtual bool Send(IPC::Message* msg);
+ int route_id() const { return route_id_; }
+
// CommandBuffer implementation:
virtual bool Initialize(int32 size);
virtual gpu::Buffer GetRingBuffer();
@@ -90,7 +90,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
// The last cached state received from the service.
State last_state_;
- scoped_refptr<PluginChannelHost> channel_;
+ IPC::Channel::Sender* channel_;
int route_id_;
// Pending asynchronous flush callbacks.
diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc
new file mode 100644
index 0000000..8e48b85
--- /dev/null
+++ b/chrome/renderer/gpu_channel_host.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/gpu_channel_host.h"
+
+#include "chrome/common/child_process.h"
+#include "chrome/common/gpu_messages.h"
+#include "chrome/renderer/command_buffer_proxy.h"
+
+GpuChannelHost::GpuChannelHost() : state_(UNCONNECTED) {
+}
+
+GpuChannelHost::~GpuChannelHost() {
+}
+
+void GpuChannelHost::Connect(const std::string& channel_name) {
+ // Open a channel to the GPU process.
+ channel_.reset(new IPC::SyncChannel(
+ channel_name, IPC::Channel::MODE_CLIENT, this, NULL,
+ ChildProcess::current()->io_message_loop(), true,
+ ChildProcess::current()->GetShutDownEvent()));
+}
+
+void GpuChannelHost::OnMessageReceived(const IPC::Message& message) {
+ DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);
+ if (!router_.RouteMessage(message)) {
+ NOTREACHED() << "GpuChannelHost failed to route message";
+ }
+}
+
+void GpuChannelHost::OnChannelConnected(int32 peer_pid) {
+ state_ = CONNECTED;
+}
+
+void GpuChannelHost::OnChannelError() {
+ state_ = LOST;
+
+ // Channel is invalid and will be reinitialized if this host is requested
+ // again.
+ channel_.reset();
+
+ // Inform all the proxies that an error has occured. This will be reported via
+ // OpenGL as a lost context.
+ for (ProxyMap::iterator iter = proxies_.begin();
+ iter != proxies_.end(); iter++) {
+ proxies_.erase(iter->first);
+ router_.RemoveRoute(iter->first);
+ iter->second->OnChannelError();
+ }
+
+ // The proxies are reference counted so this will not result in their
+ // destruction if the client still holds a reference. The proxy will report
+ // a lost context, indicating to the client that it needs to be recreated.
+ proxies_.clear();
+}
+
+bool GpuChannelHost::Send(IPC::Message* message) {
+ if (!channel_.get()) {
+ delete message;
+ return false;
+ }
+
+ return channel_->Send(message);
+}
+
+CommandBufferProxy* GpuChannelHost::CreateCommandBuffer() {
+#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)) &&
+ 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
+}
+
+void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) {
+#if defined(ENABLE_GPU)
+ Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id()));
+
+ // Check the proxy has not already been removed after a channel error.
+ int route_id = command_buffer->route_id();
+ if (proxies_.find(command_buffer->route_id()) != proxies_.end()) {
+ proxies_.erase(route_id);
+ router_.RemoveRoute(route_id);
+ }
+
+ delete command_buffer;
+#endif
+}
diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h
new file mode 100644
index 0000000..00a6129
--- /dev/null
+++ b/chrome/renderer/gpu_channel_host.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 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 CHROME_RENDERER_GPU_CHANNEL_HOST_H_
+#define CHROME_RENDERER_GPU_CHANNEL_HOST_H_
+
+#include <string>
+
+#include "base/hash_tables.h"
+#include "chrome/common/message_router.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sync_channel.h"
+
+class CommandBufferProxy;
+
+// Encapsulates an IPC channel between the renderer and one plugin process.
+// On the plugin side there's a corresponding GpuChannel.
+class GpuChannelHost : public IPC::Channel::Listener,
+ public IPC::Message::Sender,
+ public base::RefCountedThreadSafe<GpuChannelHost> {
+ public:
+ enum State {
+ // Not yet connected.
+ UNCONNECTED,
+ // Ready to use.
+ CONNECTED,
+ // An error caused the host to become disconnected. Recreate channel to
+ // reestablish connection.
+ LOST
+ };
+
+ // Called on the render thread
+ GpuChannelHost();
+ ~GpuChannelHost();
+
+ // Connect to GPU process channel.
+ void Connect(const std::string& channel_name);
+
+ State state() const { return state_; }
+
+ // Returns whether the channel to the GPU process is ready.
+ bool ready() const { return channel_.get() != NULL; }
+
+ // IPC::Channel::Listener implementation:
+ virtual void OnMessageReceived(const IPC::Message& msg);
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+
+ // IPC::Message::Sender implementation:
+ virtual bool Send(IPC::Message* msg);
+
+ // Create and connect to a command buffer in the GPU process.
+ CommandBufferProxy* CreateCommandBuffer();
+
+ // Destroy a command buffer created by this channel.
+ void DestroyCommandBuffer(CommandBufferProxy* command_buffer);
+
+ private:
+ State state_;
+
+ scoped_ptr<IPC::SyncChannel> channel_;
+
+ // Used to implement message routing functionality to CommandBufferProxy
+ // objects
+ MessageRouter router_;
+
+ // Keep track of all the registered CommandBufferProxies to
+ // inform about OnChannelError
+ typedef base::hash_map<int, IPC::Channel::Listener*> ProxyMap;
+ ProxyMap proxies_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
+};
+
+#endif // CHROME_RENDERER_GPU_CHANNEL_HOST_H_
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 343db541..7d59256 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -147,6 +147,7 @@ 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()
@@ -725,6 +726,17 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
webwidget_->setTextDirection(direction);
}
+void RenderWidget::OnGpuChannelEstablished(
+ const IPC::ChannelHandle& channel_handle) {
+ 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;
@@ -867,3 +879,32 @@ 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 ab591f0..cc32898 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -14,9 +14,11 @@
#include "base/gfx/size.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 "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"
@@ -105,6 +107,15 @@ 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.
@@ -160,6 +171,7 @@ 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 that a paint has happened. This fires after the
// browser side has updated the screen for a newly painted region.
@@ -317,6 +329,9 @@ 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);
};
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 5f09e65..e6efd40 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -123,6 +123,13 @@ void WebPluginDelegatePepper::DestroyInstance() {
// rendering commands after the GPU plugin has stopped processing them and
// responding to them.
if (nested_delegate_) {
+#if defined(ENABLE_GPU)
+ if (command_buffer_) {
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
+ }
+#endif
+
nested_delegate_->PluginDestroyed();
nested_delegate_ = NULL;
}
@@ -159,7 +166,7 @@ void WebPluginDelegatePepper::UpdateGeometry(
// Send the new window size to the command buffer service code so it
// can allocate a new backing store. The handle to the new backing
// store is sent back to the browser asynchronously.
- if (command_buffer_.get()) {
+ if (command_buffer_) {
command_buffer_->SetWindowSize(window_rect_.width(),
window_rect_.height());
}
@@ -364,8 +371,8 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
plugin_->SetAcceptsInputEvents(true);
// Ask the GPU plugin to create a command buffer and return a proxy.
- command_buffer_.reset(nested_delegate_->CreateCommandBuffer());
- if (command_buffer_.get()) {
+ command_buffer_ = nested_delegate_->CreateCommandBuffer();
+ if (command_buffer_) {
// Initialize the proxy command buffer.
if (command_buffer_->Initialize(config->commandBufferSize)) {
// Get the initial command buffer state.
@@ -395,14 +402,15 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
// Save the implementation information (the CommandBuffer).
Device3DImpl* impl = new Device3DImpl;
- impl->command_buffer = command_buffer_.get();
+ impl->command_buffer = command_buffer_;
context->reserved = impl;
return NPERR_NO_ERROR;
}
}
- command_buffer_.reset();
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
}
nested_delegate_->PluginDestroyed();
@@ -482,9 +490,12 @@ NPError WebPluginDelegatePepper::Device3DDestroyContext(
delete static_cast<Device3DImpl*>(context->reserved);
context->reserved = NULL;
- command_buffer_.reset();
-
if (nested_delegate_) {
+ if (command_buffer_) {
+ nested_delegate_->DestroyCommandBuffer(command_buffer_);
+ command_buffer_ = NULL;
+ }
+
nested_delegate_->PluginDestroyed();
nested_delegate_ = NULL;
}
@@ -849,7 +860,7 @@ void WebPluginDelegatePepper::Device3DUpdateState(
NPDeviceContext3D* context,
NPDeviceFlushContextCallbackPtr callback,
void* user_data) {
- if (command_buffer_.get()) {
+ if (command_buffer_) {
Synchronize3DContext(context, command_buffer_->GetLastState());
if (callback)
callback(npp, context, NPERR_NO_ERROR, user_data);
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index a67b530..181b40b 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -205,7 +205,7 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
#if defined(ENABLE_GPU)
// The command buffer used to issue commands to the nested GPU plugin.
- scoped_ptr<CommandBufferProxy> command_buffer_;
+ CommandBufferProxy* command_buffer_;
#endif
// Tells the browser out-of-band where the nested delegate lives on
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 4157a1f..1e64648 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -1280,12 +1280,25 @@ CommandBufferProxy* WebPluginDelegateProxy::CreateCommandBuffer() {
return NULL;
}
- return new CommandBufferProxy(channel_host_, command_buffer_id);
+ CommandBufferProxy* command_buffer =
+ new CommandBufferProxy(channel_host_, command_buffer_id);
+ channel_host_->AddRoute(command_buffer_id, command_buffer, NULL);
+ return command_buffer;
#else
return NULL;
#endif // ENABLE_GPU
}
+void WebPluginDelegateProxy::DestroyCommandBuffer(
+ CommandBufferProxy* command_buffer) {
+ DCHECK(command_buffer);
+#if defined(ENABLE_GPU)
+ Send(new PluginMsg_DestroyCommandBuffer(instance_id_));
+ channel_host_->RemoveRoute(command_buffer->route_id());
+ delete command_buffer;
+#endif
+}
+
gfx::PluginWindowHandle WebPluginDelegateProxy::GetPluginWindowHandle() {
return window_;
}
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 18d2704..212758e 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -106,6 +106,8 @@ class WebPluginDelegateProxy
unsigned long resource_id, int range_request_id);
CommandBufferProxy* CreateCommandBuffer();
+ void DestroyCommandBuffer(CommandBufferProxy* command_buffer);
+
gfx::PluginWindowHandle GetPluginWindowHandle();
protected:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index dbb49e9..e07dc99 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -287,8 +287,14 @@ class GLES2DecoderImpl : public GLES2Decoder {
return group_->texture_manager();
}
+#if defined(OS_WIN)
+ static bool InitializeOneOff(bool anti_aliased);
+#endif
+
+
bool InitPlatformSpecific();
- bool InitGlew();
+ static bool InitGlew();
+ void DestroyPlatformSpecific();
// Template to help call glGenXXX functions.
template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)>
@@ -615,8 +621,10 @@ class GLES2DecoderImpl : public GLES2Decoder {
#if defined(UNIT_TEST)
#elif defined(OS_WIN)
- HDC device_context_;
+ static int pixel_format_;
+ HDC gl_device_context_;
HGLRC gl_context_;
+ HPBUFFERARB pbuffer_;
#elif defined(OS_MACOSX)
CGLContextObj gl_context_;
CGLPBufferObj pbuffer_;
@@ -657,6 +665,11 @@ GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
return new GLES2DecoderImpl(group);
}
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
+int GLES2DecoderImpl::pixel_format_;
+#endif
+
GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
: GLES2Decoder(group),
error_bits_(0),
@@ -668,8 +681,9 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
black_cube_texture_id_(0),
#if defined(UNIT_TEST)
#elif defined(OS_WIN)
- device_context_(NULL),
+ gl_device_context_(NULL),
gl_context_(NULL),
+ pbuffer_(NULL),
#elif defined(OS_MACOSX)
gl_context_(NULL),
pbuffer_(NULL),
@@ -685,49 +699,62 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
}
bool GLES2DecoderImpl::Initialize() {
- bool success = false;
-
- if (InitPlatformSpecific()) {
- if (MakeCurrent()) {
- if (InitGlew()) {
- CHECK_GL_ERROR();
- success = group_->Initialize();
- if (success) {
- vertex_attrib_infos_.reset(
- new VertexAttribInfo[group_->max_vertex_attribs()]);
- texture_units_.reset(
- new TextureUnit[group_->max_texture_units()]);
- GLuint ids[2];
- glGenTextures(2, ids);
- // Make black textures for replacing non-renderable textures.
- black_2d_texture_id_ = ids[0];
- black_cube_texture_id_ = ids[1];
- static int8 black[] = {0, 0, 0, 0};
- glBindTexture(GL_TEXTURE_2D, black_2d_texture_id_);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, black);
- glBindTexture(GL_TEXTURE_2D, 0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, black_cube_texture_id_);
- static GLenum faces[] = {
- GL_TEXTURE_CUBE_MAP_POSITIVE_X,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
- };
- for (size_t ii = 0; ii < arraysize(faces); ++ii) {
- glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, black);
- }
- glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
- CHECK_GL_ERROR();
- }
- }
- }
+ if (!InitPlatformSpecific()) {
+ Destroy();
+ return false;
+ }
+ if (!MakeCurrent()) {
+ Destroy();
+ return false;
+ }
+
+ // This happens in InitializeOneOff in windows. TODO(apatrick): generalize to
+ // other platforms.
+#if !defined(OS_WIN)
+ if (!InitGlew()) {
+ Destroy();
+ return false;
+ }
+#endif
+
+ CHECK_GL_ERROR();
+
+ if (!group_->Initialize()) {
+ Destroy();
+ return false;
+ }
+
+ vertex_attrib_infos_.reset(
+ new VertexAttribInfo[group_->max_vertex_attribs()]);
+ texture_units_.reset(
+ new TextureUnit[group_->max_texture_units()]);
+ GLuint ids[2];
+ glGenTextures(2, ids);
+ // Make black textures for replacing non-renderable textures.
+ black_2d_texture_id_ = ids[0];
+ black_cube_texture_id_ = ids[1];
+ static int8 black[] = {0, 0, 0, 0};
+ glBindTexture(GL_TEXTURE_2D, black_2d_texture_id_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, black);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, black_cube_texture_id_);
+ static GLenum faces[] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ };
+ for (size_t ii = 0; ii < arraysize(faces); ++ii) {
+ glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, black);
}
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ CHECK_GL_ERROR();
- return success;
+ return true;
}
// TODO(kbr): the use of this anonymous namespace core dumps the
@@ -764,11 +791,9 @@ LRESULT CALLBACK IntermediateWindowProc(HWND window,
return ::DefWindowProc(window, message, w_param, l_param);
}
-// Helper routine that returns the highest quality pixel format supported on
-// the current platform. Returns true upon success.
-bool GetWindowsPixelFormat(HWND window,
- bool anti_aliased,
- int* pixel_format) {
+// Helper routine that does one-off initialization like determining the
+// pixel format and initializing glew.
+bool GLES2DecoderImpl::InitializeOneOff(bool anti_aliased) {
// We must initialize a GL context before we can determine the multi-sampling
// supported on the current hardware, so we create an intermediate window
// and context here.
@@ -815,9 +840,9 @@ bool GetWindowsPixelFormat(HWND window,
}
HDC intermediate_dc = ::GetDC(intermediate_window);
- int format_index = ::ChoosePixelFormat(intermediate_dc,
- &kPixelFormatDescriptor);
- if (format_index == 0) {
+ pixel_format_ = ::ChoosePixelFormat(intermediate_dc,
+ &kPixelFormatDescriptor);
+ if (pixel_format_ == 0) {
DLOG(ERROR) << "Unable to get the pixel format for GL context.";
::ReleaseDC(intermediate_window, intermediate_dc);
::DestroyWindow(intermediate_window);
@@ -825,7 +850,7 @@ bool GetWindowsPixelFormat(HWND window,
module_handle);
return false;
}
- if (!::SetPixelFormat(intermediate_dc, format_index,
+ if (!::SetPixelFormat(intermediate_dc, pixel_format_,
&kPixelFormatDescriptor)) {
DLOG(ERROR) << "Unable to set the pixel format for GL context.";
::ReleaseDC(intermediate_window, intermediate_dc);
@@ -835,18 +860,14 @@ bool GetWindowsPixelFormat(HWND window,
return false;
}
- // Store the pixel format without multisampling.
- *pixel_format = format_index;
+ // Create a temporary GL context to query for multisampled pixel formats.
HGLRC gl_context = ::wglCreateContext(intermediate_dc);
if (::wglMakeCurrent(intermediate_dc, gl_context)) {
// GL context was successfully created and applied to the window's DC.
// Startup GLEW, the GL extensions wrangler.
- GLenum glew_error = ::glewInit();
- if (glew_error == GLEW_OK) {
+ if (InitGlew()) {
DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION);
} else {
- DLOG(ERROR) << "Unable to initialise GLEW : "
- << ::glewGetErrorString(glew_error);
::wglMakeCurrent(intermediate_dc, NULL);
::wglDeleteContext(gl_context);
::ReleaseDC(intermediate_window, intermediate_dc);
@@ -887,7 +908,7 @@ bool GetWindowsPixelFormat(HWND window,
1,
&msaa_pixel_format,
&num_formats)) {
- *pixel_format = msaa_pixel_format;
+ pixel_format_ = msaa_pixel_format;
break;
}
}
@@ -968,11 +989,11 @@ bool GLES2DecoderImpl::MakeCurrent() {
#if defined(UNIT_TEST)
return true;
#elif defined(OS_WIN)
- if (::wglGetCurrentDC() == device_context_ &&
+ if (::wglGetCurrentDC() == gl_device_context_ &&
::wglGetCurrentContext() == gl_context_) {
return true;
}
- if (!::wglMakeCurrent(device_context_, gl_context_)) {
+ if (!::wglMakeCurrent(gl_device_context_, gl_context_)) {
DLOG(ERROR) << "Unable to make gl context current.";
return false;
}
@@ -1040,26 +1061,51 @@ void GLES2DecoderImpl::UnregisterObjects(
bool GLES2DecoderImpl::InitPlatformSpecific() {
#if defined(UNIT_TEST)
#elif defined(OS_WIN)
- device_context_ = ::GetDC(hwnd());
+ // Do one-off initialization.
+ static bool success = InitializeOneOff(anti_aliased_);
+ if (!success)
+ return false;
- int pixel_format;
+ if (hwnd()) {
+ // The GL context will render to this window.
+ gl_device_context_ = ::GetDC(hwnd());
- if (!GetWindowsPixelFormat(hwnd(),
- anti_aliased_,
- &pixel_format)) {
- DLOG(ERROR) << "Unable to determine optimal pixel format for GL context.";
+ if (!::SetPixelFormat(gl_device_context_,
+ pixel_format_,
+ &kPixelFormatDescriptor)) {
+ DLOG(ERROR) << "Unable to set the pixel format for GL context.";
+ DestroyPlatformSpecific();
return false;
- }
+ }
+ } else {
+ // Create a device context compatible with the primary display.
+ HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL);
+
+ // Create a 1 x 1 pbuffer suitable for use with the device.
+ const int kNoAttributes[] = { 0 };
+ pbuffer_ = ::wglCreatePbufferARB(display_device_context,
+ pixel_format_,
+ 1, 1,
+ kNoAttributes);
+ ::DeleteDC(display_device_context);
+ if (!pbuffer_) {
+ DLOG(ERROR) << "Unable to create pbuffer.";
+ DestroyPlatformSpecific();
+ return false;
+ }
- if (!::SetPixelFormat(device_context_, pixel_format,
- &kPixelFormatDescriptor)) {
- DLOG(ERROR) << "Unable to set the pixel format for GL context.";
- return false;
+ gl_device_context_ = ::wglGetPbufferDCARB(pbuffer_);
+ if (!gl_device_context_) {
+ DLOG(ERROR) << "Unable to get pbuffer device context.";
+ DestroyPlatformSpecific();
+ return false;
+ }
}
- gl_context_ = ::wglCreateContext(device_context_);
+ gl_context_ = ::wglCreateContext(gl_device_context_);
if (!gl_context_) {
DLOG(ERROR) << "Failed to create GL context.";
+ DestroyPlatformSpecific();
return false;
}
#elif defined(OS_LINUX)
@@ -1072,20 +1118,20 @@ bool GLES2DecoderImpl::InitPlatformSpecific() {
(CGLPixelFormatAttribute) kCGLPFAPBuffer,
(CGLPixelFormatAttribute) 0
};
- CGLPixelFormatObj pixelFormat;
- GLint numPixelFormats;
+ CGLPixelFormatObj pixel_format;
+ GLint num_pixel_formats;
if (CGLChoosePixelFormat(attribs,
- &pixelFormat,
- &numPixelFormats) != kCGLNoError) {
+ &pixel_format,
+ &num_pixel_formats) != kCGLNoError) {
DLOG(ERROR) << "Error choosing pixel format.";
return false;
}
- if (!pixelFormat) {
+ if (!pixel_format) {
return false;
}
CGLContextObj context;
- CGLError res = CGLCreateContext(pixelFormat, 0, &context);
- CGLDestroyPixelFormat(pixelFormat);
+ CGLError res = CGLCreateContext(pixel_format, 0, &context);
+ CGLDestroyPixelFormat(pixel_format);
if (res != kCGLNoError) {
DLOG(ERROR) << "Error creating context.";
return false;
@@ -1170,6 +1216,29 @@ bool GLES2DecoderImpl::InitGlew() {
return true;
}
+void GLES2DecoderImpl::DestroyPlatformSpecific() {
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
+ if (gl_context_) {
+ ::wglDeleteContext(gl_context_);
+ }
+
+ if (gl_device_context_) {
+ if (hwnd())
+ ::ReleaseDC(hwnd(), gl_device_context_);
+ else
+ ::wglReleasePbufferDCARB(pbuffer_, gl_device_context_);
+
+ gl_device_context_ = NULL;
+ }
+
+ if (pbuffer_) {
+ ::wglDestroyPbufferARB(pbuffer_);
+ pbuffer_ = NULL;
+ }
+#endif
+}
+
#if defined(OS_MACOSX)
#if !defined(UNIT_TEST)
static void AddBooleanValue(CFMutableDictionaryRef dictionary,
@@ -1402,6 +1471,8 @@ void GLES2DecoderImpl::Destroy() {
if (pbuffer_)
CGLDestroyPBuffer(pbuffer_);
#endif
+
+ DestroyPlatformSpecific();
}
const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
@@ -1652,7 +1723,7 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
void GLES2DecoderImpl::DoSwapBuffers() {
#if defined(UNIT_TEST)
#elif defined(OS_WIN)
- ::SwapBuffers(device_context_);
+ ::SwapBuffers(gl_device_context_);
#elif defined(OS_LINUX)
DCHECK(window());
window()->SwapBuffers();
diff --git a/gpu/command_buffer/service/gpu_processor_win.cc b/gpu/command_buffer/service/gpu_processor_win.cc
index bef34d8..bce783b 100644
--- a/gpu/command_buffer/service/gpu_processor_win.cc
+++ b/gpu/command_buffer/service/gpu_processor_win.cc
@@ -11,10 +11,8 @@ using ::base::SharedMemory;
namespace gpu {
bool GPUProcessor::Initialize(gfx::PluginWindowHandle handle) {
- DCHECK(handle);
-
// Cannot reinitialize.
- if (decoder_->hwnd() != NULL)
+ if (parser_.get())
return false;
// Map the ring buffer and create the parser.
@@ -37,8 +35,8 @@ bool GPUProcessor::Initialize(gfx::PluginWindowHandle handle) {
}
void GPUProcessor::Destroy() {
- // Destroy GAPI if window handle has not already become invalid.
- if (decoder_->hwnd()) {
+ // Destroy decoder if initialized.
+ if (parser_.get()) {
decoder_->Destroy();
decoder_->set_hwnd(NULL);
}
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 9fedfb3..81685c6 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -134,7 +134,7 @@
'target_name': 'gles2_cmd_helper',
'type': 'static_library',
'dependencies': [
- 'command_buffer_common',
+ 'command_buffer_client',
],
'sources': [
'command_buffer/client/gles2_cmd_helper.cc',
diff --git a/ipc/ipc_channel_handle.h b/ipc/ipc_channel_handle.h
index e3b2f3e..2342429 100644
--- a/ipc/ipc_channel_handle.h
+++ b/ipc/ipc_channel_handle.h
@@ -5,6 +5,8 @@
#ifndef IPC_IPC_CHANNEL_HANDLE_H_
#define IPC_IPC_CHANNEL_HANDLE_H_
+#include <string>
+
#include "build/build_config.h"
#if defined(OS_POSIX)
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index 9a8ccf4..670ce87 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -45,11 +45,12 @@ enum IPCMessageStart {
WorkerMsgStart,
WorkerHostMsgStart,
NaClProcessMsgStart,
- CommandBufferMsgStart,
+ GpuCommandBufferMsgStart,
UtilityMsgStart,
UtilityHostMsgStart,
GpuMsgStart,
GpuHostMsgStart,
+ GpuChannelMsgStart,
// NOTE: When you add a new message class, also update
// IPCStatusView::IPCStatusView to ensure logging works.
LastMsgIndex