summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/child_process_host.cc10
-rw-r--r--chrome/browser/gpu_process_host.cc215
-rw-r--r--chrome/browser/gpu_process_host.h101
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.cc69
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.h56
-rw-r--r--chrome/browser/io_thread.cc3
-rw-r--r--chrome/browser/renderer_host/backing_store_proxy.cc16
-rw-r--r--chrome/browser/renderer_host/backing_store_proxy.h6
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc12
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.h6
-rw-r--r--chrome/browser/renderer_host/gpu_view_host.cc38
-rw-r--r--chrome/browser/renderer_host/gpu_view_host.h4
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc18
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h3
-rw-r--r--chrome/browser/renderer_host/video_layer_proxy.cc12
-rw-r--r--chrome/browser/renderer_host/video_layer_proxy.h6
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/common/gpu_messages_internal.h6
-rw-r--r--chrome/common/sandbox_policy.cc3
-rw-r--r--chrome/gpu/gpu_channel.cc6
-rw-r--r--chrome/gpu/gpu_thread.cc4
-rw-r--r--chrome/gpu/gpu_thread.h2
-rw-r--r--chrome/renderer/gpu_channel_host.cc1
-rw-r--r--chrome/renderer/render_thread.cc18
24 files changed, 377 insertions, 240 deletions
diff --git a/chrome/browser/child_process_host.cc b/chrome/browser/child_process_host.cc
index d9f5218..a9dcbd7 100644
--- a/chrome/browser/child_process_host.cc
+++ b/chrome/browser/child_process_host.cc
@@ -80,7 +80,8 @@ ChildProcessHost::ChildProcessHost(
ChildProcessHost::~ChildProcessHost() {
Singleton<ChildProcessList>::get()->remove(this);
- resource_dispatcher_host_->CancelRequestsForProcess(id());
+ if (resource_dispatcher_host_)
+ resource_dispatcher_host_->CancelRequestsForProcess(id());
}
// static
@@ -217,8 +218,11 @@ void ChildProcessHost::ListenerHook::OnMessageReceived(
#endif
bool msg_is_ok = true;
- bool handled = host_->resource_dispatcher_host_->OnMessageReceived(
- msg, host_, &msg_is_ok);
+ bool handled = false;
+
+ if (host_->resource_dispatcher_host_)
+ host_->resource_dispatcher_host_->OnMessageReceived(
+ msg, host_, &msg_is_ok);
if (!handled) {
if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID) {
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 9981133..cae8a35 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -5,41 +5,80 @@
#include "chrome/browser/gpu_process_host.h"
#include "base/command_line.h"
-#include "base/singleton.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
-#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/browser/chrome_thread.h"
+#include "chrome/browser/gpu_process_host_ui_shim.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) {
+namespace {
+
+// Tasks used by this file
+class RouteOnUIThreadTask : public Task {
+ public:
+ explicit RouteOnUIThreadTask(const IPC::Message& msg) {
+ msg_ = new IPC::Message(msg);
+ }
+
+ private:
+ void Run() {
+ GpuProcessHostUIShim::Get()->OnMessageReceived(*msg_);
+ delete msg_;
+ msg_ = NULL;
+ }
+ IPC::Message* msg_;
+};
+
+// Global GpuProcessHost instance.
+// We can not use Singleton<GpuProcessHost> because that gets
+// terminated on the wrong thread (main thread). We need the
+// GpuProcessHost to be terminated on the same thread on which it is
+// initialized, the IO thread.
+static GpuProcessHost* sole_instance_;
+
+} // anonymous namespace
+
+GpuProcessHost::GpuProcessHost()
+ : ChildProcessHost(GPU_PROCESS, NULL),
+ initialized_(false),
+ initialized_successfully_(false) {
+}
+
+GpuProcessHost::~GpuProcessHost() {
+ while (!queued_synchronization_replies_.empty()) {
+ delete queued_synchronization_replies_.front().reply;
+ queued_synchronization_replies_.pop();
+ }
+}
+
+bool GpuProcessHost::EnsureInitialized() {
+ if (!initialized_) {
+ initialized_ = true;
+ initialized_successfully_ = Init();
+ }
+ return initialized_successfully_;
+}
+
+bool GpuProcessHost::Init() {
+ if (!CreateChannel())
+ return false;
+
const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
std::wstring gpu_launcher =
browser_command_line.GetSwitchValue(switches::kGpuLauncher);
FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty());
if (exe_path.empty())
- return;
-
- std::string channel_id = ChildProcessInfo::GenerateRandomChannelID(this);
- channel_.reset(new IPC::ChannelProxy(
- channel_id,
- IPC::Channel::MODE_SERVER,
- this,
- NULL, // No filter (for now).
- g_browser_process->io_thread()->message_loop()));
+ return false;
CommandLine* cmd_line = new CommandLine(exe_path);
cmd_line->AppendSwitchWithValue(switches::kProcessType,
switches::kGpuProcess);
cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
- ASCIIToWide(channel_id));
+ ASCIIToWide(channel_id()));
const CommandLine& browser_cmd_line = *CommandLine::ForCurrentProcess();
PropagateBrowserCommandLineToGpu(browser_cmd_line, cmd_line);
@@ -48,108 +87,65 @@ GpuProcessHost::GpuProcessHost() : last_routing_id_(1) {
if (!gpu_launcher.empty())
cmd_line->PrependWrapper(gpu_launcher);
- // Spawn the child process asynchronously to avoid blocking the UI thread.
- child_process_.reset(new ChildProcessLauncher(
+ Launch(
#if defined(OS_WIN)
FilePath(),
#elif defined(POSIX)
false, // Never use the zygote (GPU plugin can't be sandboxed).
base::environment_vector(),
- channel_->GetClientFileDescriptor(),
#endif
- cmd_line,
- this));
-}
+ cmd_line);
-GpuProcessHost::~GpuProcessHost() {
- while (!queued_synchronization_replies_.empty()) {
- delete queued_synchronization_replies_.front();
- queued_synchronization_replies_.pop();
- }
+ return true;
}
// static
GpuProcessHost* GpuProcessHost::Get() {
- GpuProcessHost* host = Singleton<GpuProcessHost>::get();
- if (!host->child_process_.get())
- return NULL; // Failed to init.
- return host;
-}
-
-int32 GpuProcessHost::GetNextRoutingId() {
- return ++last_routing_id_;
+ if (sole_instance_ == NULL)
+ sole_instance_ = new GpuProcessHost();
+ return sole_instance_;
}
-int32 GpuProcessHost::NewRenderWidgetHostView(GpuNativeWindowHandle parent) {
- int32 routing_id = GetNextRoutingId();
- Send(new GpuMsg_NewRenderWidgetHostView(parent, routing_id));
- return routing_id;
+// static
+void GpuProcessHost::Shutdown() {
+ if (sole_instance_) {
+ delete sole_instance_;
+ sole_instance_ = NULL;
+ }
}
bool GpuProcessHost::Send(IPC::Message* msg) {
- if (!channel_.get()) {
- delete msg;
+ if (!EnsureInitialized())
return false;
- }
- if (child_process_.get() && child_process_->IsStarting()) {
- queued_messages_.push(msg);
- return true;
- }
-
- return channel_->Send(msg);
+ return ChildProcessHost::Send(msg);
}
void GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
if (message.routing_id() == MSG_ROUTING_CONTROL) {
OnControlMessageReceived(message);
} else {
- router_.OnMessageReceived(message);
+ // Need to transfer this message to the UI thread and the
+ // GpuProcessHostUIShim for dispatching via its message router.
+ ChromeThread::PostTask(ChromeThread::UI,
+ FROM_HERE,
+ new RouteOnUIThreadTask(message));
}
}
-void GpuProcessHost::OnChannelConnected(int32 peer_pid) {
-}
-
-void GpuProcessHost::OnChannelError() {
-}
-
-void GpuProcessHost::OnProcessLaunched() {
- while (!queued_messages_.empty()) {
- Send(queued_messages_.front());
- queued_messages_.pop();
+void GpuProcessHost::EstablishGpuChannel(int renderer_id,
+ ResourceMessageFilter* filter) {
+ if (Send(new GpuMsg_EstablishChannel(renderer_id))) {
+ sent_requests_.push(ChannelRequest(filter));
+ } else {
+ ReplyToRenderer(IPC::ChannelHandle(), filter);
}
}
-void GpuProcessHost::AddRoute(int32 routing_id,
- IPC::Channel::Listener* listener) {
- router_.AddRoute(routing_id, listener);
-}
-
-void GpuProcessHost::RemoveRoute(int32 routing_id) {
- router_.RemoveRoute(routing_id);
-}
-
-void GpuProcessHost::EstablishGpuChannel(int renderer_id) {
- if (Send(new GpuMsg_EstablishChannel(renderer_id)))
- sent_requests_.push(ChannelRequest(renderer_id));
- else
- ReplyToRenderer(renderer_id, IPC::ChannelHandle());
-}
-
-void GpuProcessHost::Synchronize(int renderer_id, IPC::Message* reply) {
- // ************
- // TODO(kbr): the handling of this synchronous message (which is
- // needed for proper initialization semantics of APIs like WebGL) is
- // currently broken on Windows because the renderer is sending a
- // synchronous message to the browser's UI thread. To fix this, the
- // GpuProcessHost needs to move to the IO thread, and any backing
- // store handling needs to remain on the UI thread in a new
- // GpuProcessHostProxy, where work is sent from the IO thread to the
- // UI thread via PostTask.
- // ************
- queued_synchronization_replies_.push(reply);
- CHECK(Send(new GpuMsg_Synchronize(renderer_id)));
+void GpuProcessHost::Synchronize(IPC::Message* reply,
+ ResourceMessageFilter* filter) {
+ queued_synchronization_replies_.push(SynchronizationRequest(reply, filter));
+ Send(new GpuMsg_Synchronize());
}
void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
@@ -163,37 +159,27 @@ void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
void GpuProcessHost::OnChannelEstablished(
const IPC::ChannelHandle& channel_handle) {
const ChannelRequest& request = sent_requests_.front();
-
- ReplyToRenderer(request.renderer_id, channel_handle);
+ ReplyToRenderer(channel_handle, request.filter);
sent_requests_.pop();
}
-void GpuProcessHost::OnSynchronizeReply(int renderer_id) {
- IPC::Message* reply = queued_synchronization_replies_.front();
+void GpuProcessHost::OnSynchronizeReply() {
+ const SynchronizationRequest& request =
+ queued_synchronization_replies_.front();
+ request.filter->Send(request.reply);
queued_synchronization_replies_.pop();
- RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id);
- if (!process_host) {
- delete reply;
- return;
- }
- CHECK(process_host->Send(reply));
}
void GpuProcessHost::ReplyToRenderer(
- int renderer_id,
- const IPC::ChannelHandle& channel) {
- // Check whether the renderer process is still around.
- RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id);
- if (!process_host)
- return;
-
- ViewMsg_GpuChannelEstablished* msg =
+ const IPC::ChannelHandle& channel,
+ ResourceMessageFilter* filter) {
+ ViewMsg_GpuChannelEstablished* message =
new ViewMsg_GpuChannelEstablished(channel);
// If the renderer process is performing synchronous initialization,
// it needs to handle this message before receiving the reply for
// the synchronous ViewHostMsg_SynchronizeGpu message.
- msg->set_unblock(true);
- CHECK(process_host->Send(msg));
+ message->set_unblock(true);
+ filter->Send(message);
}
void GpuProcessHost::PropagateBrowserCommandLineToGpu(
@@ -215,3 +201,14 @@ void GpuProcessHost::PropagateBrowserCommandLineToGpu(
}
}
}
+
+URLRequestContext* GpuProcessHost::GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+}
+
+bool GpuProcessHost::CanShutdown() {
+ return true;
+}
+
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index 27d3fe3..4065124 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -9,83 +9,74 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "base/singleton.h"
-#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"
+#include "chrome/browser/child_process_host.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
class ChildProcessLauncher;
class CommandBufferProxy;
-class GpuProcessHost : public IPC::Channel::Sender,
- public IPC::Channel::Listener,
- public ChildProcessLauncher::Client {
+class GpuProcessHost : public ChildProcessHost {
public:
// Getter for the singleton. This will return NULL on failure.
static GpuProcessHost* Get();
- int32 GetNextRoutingId();
+ // Shutdown routine, which should only be called upon process
+ // termination.
+ static void Shutdown();
- // Creates the new remote view and returns the routing ID for the view, or 0
- // on failure.
- int32 NewRenderWidgetHostView(GpuNativeWindowHandle parent);
-
- // IPC::Channel::Sender implementation.
virtual bool Send(IPC::Message* msg);
// IPC::Channel::Listener implementation.
virtual void OnMessageReceived(const IPC::Message& message);
- virtual void OnChannelConnected(int32 peer_pid);
- virtual void OnChannelError();
-
- // ChildProcessLauncher::Client implementation.
- virtual void OnProcessLaunched();
-
- // See documentation on MessageRouter for AddRoute and RemoveRoute
- 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);
+ void EstablishGpuChannel(int renderer_id,
+ ResourceMessageFilter* filter);
// Sends a reply message later when the next GpuHostMsg_SynchronizeReply comes
// in.
- void Synchronize(int renderer_id, IPC::Message* reply);
+ void Synchronize(IPC::Message* reply,
+ ResourceMessageFilter* filter);
private:
- friend struct DefaultSingletonTraits<GpuProcessHost>;
-
// Used to queue pending channel requests.
struct ChannelRequest {
- 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;
+ explicit ChannelRequest(ResourceMessageFilter* filter)
+ : filter(filter) {}
+ // Used to send the reply message back to the renderer.
+ scoped_refptr<ResourceMessageFilter> filter;
+ };
+
+ // Used to queue pending synchronization requests.
+ struct SynchronizationRequest {
+ SynchronizationRequest(IPC::Message* reply,
+ ResourceMessageFilter* filter)
+ : reply(reply),
+ filter(filter) {}
+ // The delayed reply message which needs to be sent to the
+ // renderer.
+ IPC::Message* reply;
+
+ // Used to send the reply message back to the renderer.
+ scoped_refptr<ResourceMessageFilter> filter;
};
GpuProcessHost();
virtual ~GpuProcessHost();
+ bool EnsureInitialized();
+ bool Init();
+
void OnControlMessageReceived(const IPC::Message& message);
// Message handlers.
void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
- void OnSynchronizeReply(int renderer_id);
+ void OnSynchronizeReply();
- void ReplyToRenderer(int renderer_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_;
+ void ReplyToRenderer(const IPC::ChannelHandle& channel,
+ ResourceMessageFilter* filter);
// Copies applicable command line switches from the given |browser_cmd| line
// flags to the output |gpu_cmd| line flags. Not all switches will be
@@ -93,24 +84,22 @@ class GpuProcessHost : public IPC::Channel::Sender,
void PropagateBrowserCommandLineToGpu(const CommandLine& browser_cmd,
CommandLine* gpu_cmd) const;
- 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 connect.
- scoped_ptr<IPC::ChannelProxy> channel_;
+ // ResourceDispatcherHost::Receiver implementation:
+ virtual URLRequestContext* GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data);
- int last_routing_id_;
+ virtual bool CanShutdown();
- MessageRouter router_;
+ bool initialized_;
+ bool initialized_successfully_;
- // Messages we queue while waiting for the process handle. We queue them here
- // instead of in the channel so that we ensure they're sent after init related
- // messages that are sent once the process handle is available. This is
- // because the queued messages may have dependencies on the init messages.
- std::queue<IPC::Message*> queued_messages_;
+ // 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_;
// The pending synchronization requests we need to reply to.
- std::queue<IPC::Message*> queued_synchronization_replies_;
+ std::queue<SynchronizationRequest> queued_synchronization_replies_;
DISALLOW_COPY_AND_ASSIGN(GpuProcessHost);
};
diff --git a/chrome/browser/gpu_process_host_ui_shim.cc b/chrome/browser/gpu_process_host_ui_shim.cc
new file mode 100644
index 0000000..0b25845
--- /dev/null
+++ b/chrome/browser/gpu_process_host_ui_shim.cc
@@ -0,0 +1,69 @@
+// 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/browser/gpu_process_host_ui_shim.h"
+
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/gpu_process_host.h"
+#include "chrome/common/gpu_messages.h"
+
+// Tasks used by this file
+namespace {
+
+class SendOnIOThreadTask : public Task {
+ public:
+ explicit SendOnIOThreadTask(IPC::Message* msg) : msg_(msg) {
+ }
+
+ private:
+ void Run() {
+ GpuProcessHost::Get()->Send(msg_);
+ }
+ IPC::Message* msg_;
+};
+
+} // namespace
+
+GpuProcessHostUIShim::GpuProcessHostUIShim() : last_routing_id_(1) {
+}
+
+GpuProcessHostUIShim::~GpuProcessHostUIShim() {
+}
+
+// static
+GpuProcessHostUIShim* GpuProcessHostUIShim::Get() {
+ return Singleton<GpuProcessHostUIShim>::get();
+}
+
+int32 GpuProcessHostUIShim::NewRenderWidgetHostView(
+ GpuNativeWindowHandle parent) {
+ int32 routing_id = GetNextRoutingId();
+ Send(new GpuMsg_NewRenderWidgetHostView(parent, routing_id));
+ return routing_id;
+}
+
+bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
+ ChromeThread::PostTask(ChromeThread::IO,
+ FROM_HERE,
+ new SendOnIOThreadTask(msg));
+ return true;
+}
+
+int32 GpuProcessHostUIShim::GetNextRoutingId() {
+ return ++last_routing_id_;
+}
+
+void GpuProcessHostUIShim::AddRoute(int32 routing_id,
+ IPC::Channel::Listener* listener) {
+ router_.AddRoute(routing_id, listener);
+}
+
+void GpuProcessHostUIShim::RemoveRoute(int32 routing_id) {
+ router_.RemoveRoute(routing_id);
+}
+
+void GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
+ router_.RouteMessage(message);
+}
+
diff --git a/chrome/browser/gpu_process_host_ui_shim.h b/chrome/browser/gpu_process_host_ui_shim.h
new file mode 100644
index 0000000..70696ca
--- /dev/null
+++ b/chrome/browser/gpu_process_host_ui_shim.h
@@ -0,0 +1,56 @@
+// 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_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_
+#define CHROME_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_
+
+// This class lives on the UI thread and supports classes like the
+// BackingStoreProxy, which must live on the UI thread. The IO thread
+// portion of this class, the GpuProcessHost, is responsible for
+// shuttling messages between the browser and GPU processes.
+
+#include "base/singleton.h"
+#include "chrome/common/gpu_native_window_handle.h"
+#include "chrome/common/message_router.h"
+#include "ipc/ipc_channel.h"
+#include "gfx/native_widget_types.h"
+
+class GpuProcessHostUIShim : public IPC::Channel::Sender,
+ public IPC::Channel::Listener {
+ public:
+ // Getter for the singleton. This will return NULL on failure.
+ static GpuProcessHostUIShim* Get();
+
+ int32 GetNextRoutingId();
+
+ // Creates the new remote view and returns the routing ID for the view, or 0
+ // on failure.
+ int32 NewRenderWidgetHostView(GpuNativeWindowHandle parent);
+
+ // IPC::Channel::Sender implementation.
+ virtual bool Send(IPC::Message* msg);
+
+ // IPC::Channel::Listener implementation.
+ // The GpuProcessHost causes this to be called on the UI thread to
+ // dispatch the incoming messages from the GPU process, which are
+ // actually received on the IO thread.
+ virtual void OnMessageReceived(const IPC::Message& message);
+
+ // See documentation on MessageRouter for AddRoute and RemoveRoute
+ void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
+ void RemoveRoute(int32 routing_id);
+
+ private:
+ friend struct DefaultSingletonTraits<GpuProcessHostUIShim>;
+
+ GpuProcessHostUIShim();
+ virtual ~GpuProcessHostUIShim();
+
+ int last_routing_id_;
+
+ MessageRouter router_;
+};
+
+#endif // CHROME_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_
+
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 60d0d4e..5f9236b 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/gpu_process_host.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/passive_log_collector.h"
@@ -169,6 +170,8 @@ void IOThread::CleanUp() {
globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
}
+ GpuProcessHost::Shutdown();
+
delete globals_;
globals_ = NULL;
diff --git a/chrome/browser/renderer_host/backing_store_proxy.cc b/chrome/browser/renderer_host/backing_store_proxy.cc
index c41900d..ba3538b 100644
--- a/chrome/browser/renderer_host/backing_store_proxy.cc
+++ b/chrome/browser/renderer_host/backing_store_proxy.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/renderer_host/backing_store_proxy.h"
#include "build/build_config.h"
-#include "chrome/browser/gpu_process_host.h"
+#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/common/gpu_messages.h"
@@ -18,17 +18,17 @@
BackingStoreProxy::BackingStoreProxy(RenderWidgetHost* widget,
const gfx::Size& size,
- GpuProcessHost* process,
+ GpuProcessHostUIShim* process_shim,
int32 routing_id)
: BackingStore(widget, size),
- process_(process),
+ process_shim_(process_shim),
routing_id_(routing_id),
waiting_for_paint_ack_(false) {
- process_->AddRoute(routing_id_, this);
+ process_shim_->AddRoute(routing_id_, this);
}
BackingStoreProxy::~BackingStoreProxy() {
- process_->RemoveRoute(routing_id_);
+ process_shim_->RemoveRoute(routing_id_);
}
void BackingStoreProxy::PaintToBackingStore(
@@ -46,7 +46,7 @@ void BackingStoreProxy::PaintToBackingStore(
process_id = process->GetHandle();
#endif
- if (process_->Send(new GpuMsg_PaintToBackingStore(
+ if (process_shim_->Send(new GpuMsg_PaintToBackingStore(
routing_id_, process_id, bitmap, bitmap_rect, copy_rects))) {
// Message sent successfully, so the caller can not destroy the
// TransportDIB. OnDonePaintingToBackingStore will free it later.
@@ -67,8 +67,8 @@ bool BackingStoreProxy::CopyFromBackingStore(const gfx::Rect& rect,
void BackingStoreProxy::ScrollBackingStore(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
- process_->Send(new GpuMsg_ScrollBackingStore(routing_id_, dx, dy,
- clip_rect, view_size));
+ process_shim_->Send(new GpuMsg_ScrollBackingStore(routing_id_, dx, dy,
+ clip_rect, view_size));
}
void BackingStoreProxy::OnMessageReceived(const IPC::Message& msg) {
diff --git a/chrome/browser/renderer_host/backing_store_proxy.h b/chrome/browser/renderer_host/backing_store_proxy.h
index 0b5059f..4d572b6 100644
--- a/chrome/browser/renderer_host/backing_store_proxy.h
+++ b/chrome/browser/renderer_host/backing_store_proxy.h
@@ -9,13 +9,13 @@
#include "chrome/browser/renderer_host/backing_store.h"
#include "ipc/ipc_channel.h"
-class GpuProcessHost;
+class GpuProcessHostUIShim;
class BackingStoreProxy : public BackingStore,
public IPC::Channel::Listener {
public:
BackingStoreProxy(RenderWidgetHost* widget, const gfx::Size& size,
- GpuProcessHost* process, int32 routing_id);
+ GpuProcessHostUIShim* process_shim, int32 routing_id);
virtual ~BackingStoreProxy();
// BackingStore implementation.
@@ -39,7 +39,7 @@ class BackingStoreProxy : public BackingStore,
// Message handlers.
void OnPaintToBackingStoreACK();
- GpuProcessHost* process_;
+ GpuProcessHostUIShim* process_shim_;
int32 routing_id_;
// Set to true when we're waiting for the GPU process to do a paint and send
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 7f72a79..15517fc 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -773,10 +773,6 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
OnExtensionRemoveListener)
IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionCloseChannel,
OnExtensionCloseChannel)
- IPC_MESSAGE_HANDLER(ViewHostMsg_EstablishGpuChannel,
- OnMsgEstablishGpuChannel)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SynchronizeGpu,
- OnMsgSynchronizeGpu)
IPC_MESSAGE_HANDLER(ViewHostMsg_SpellChecker_RequestDictionary,
OnSpellCheckerRequestDictionary)
IPC_MESSAGE_UNHANDLED_ERROR()
@@ -981,14 +977,6 @@ void BrowserRenderProcessHost::OnExtensionCloseChannel(int port_id) {
}
}
-void BrowserRenderProcessHost::OnMsgEstablishGpuChannel() {
- GpuProcessHost::Get()->EstablishGpuChannel(id());
-}
-
-void BrowserRenderProcessHost::OnMsgSynchronizeGpu(IPC::Message* reply) {
- GpuProcessHost::Get()->Synchronize(id(), reply);
-}
-
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 9a9c833..277a53e 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.h
+++ b/chrome/browser/renderer_host/browser_render_process_host.h
@@ -110,12 +110,6 @@ class BrowserRenderProcessHost : public RenderProcessHost,
void OnExtensionAddListener(const std::string& event_name);
void OnExtensionRemoveListener(const std::string& event_name);
void OnExtensionCloseChannel(int port_id);
- // Renderer process is requesting that the browser process establish a GPU
- // channel.
- void OnMsgEstablishGpuChannel();
- // Renderer process is requesting that outstanding asynchronous GPU-related
- // messages are processed.
- void OnMsgSynchronizeGpu(IPC::Message* reply);
// Initialize support for visited links. Send the renderer process its initial
// set of visited links.
diff --git a/chrome/browser/renderer_host/gpu_view_host.cc b/chrome/browser/renderer_host/gpu_view_host.cc
index a81db6b..fa8c19c 100644
--- a/chrome/browser/renderer_host/gpu_view_host.cc
+++ b/chrome/browser/renderer_host/gpu_view_host.cc
@@ -4,43 +4,47 @@
#include "chrome/browser/renderer_host/gpu_view_host.h"
-#include "chrome/browser/gpu_process_host.h"
+#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/renderer_host/backing_store_proxy.h"
#include "chrome/browser/renderer_host/video_layer_proxy.h"
#include "chrome/common/gpu_messages.h"
GpuViewHost::GpuViewHost(RenderWidgetHost* widget, GpuNativeWindowHandle parent)
: widget_(widget),
- process_(GpuProcessHost::Get()),
+ process_shim_(GpuProcessHostUIShim::Get()),
routing_id_(0) {
- if (!process_) {
+ if (!process_shim_) {
// TODO(brettw) handle error.
return;
}
- routing_id_ = process_->NewRenderWidgetHostView(parent);
+ routing_id_ = process_shim_->NewRenderWidgetHostView(parent);
}
GpuViewHost::~GpuViewHost() {
}
BackingStore* GpuViewHost::CreateBackingStore(const gfx::Size& size) {
- int32 backing_store_routing_id = process_->GetNextRoutingId();
- process_->Send(new GpuMsg_NewBackingStore(routing_id_,
- backing_store_routing_id,
- size));
- return new BackingStoreProxy(widget_, size,
- process_, backing_store_routing_id);
+ int32 backing_store_routing_id = process_shim_->GetNextRoutingId();
+ BackingStoreProxy* result =
+ new BackingStoreProxy(widget_, size,
+ process_shim_, backing_store_routing_id);
+ process_shim_->Send(new GpuMsg_NewBackingStore(routing_id_,
+ backing_store_routing_id,
+ size));
+ return result;
}
VideoLayer* GpuViewHost::CreateVideoLayer(const gfx::Size& size) {
- int32 video_layer_routing_id = process_->GetNextRoutingId();
- process_->Send(new GpuMsg_NewVideoLayer(routing_id_,
- video_layer_routing_id,
- size));
- return new VideoLayerProxy(widget_, size,
- process_, video_layer_routing_id);
+ int32 video_layer_routing_id = process_shim_->GetNextRoutingId();
+ VideoLayerProxy* result =
+ new VideoLayerProxy(widget_, size,
+ process_shim_, video_layer_routing_id);
+ process_shim_->Send(new GpuMsg_NewVideoLayer(routing_id_,
+ video_layer_routing_id,
+ size));
+ return result;
}
void GpuViewHost::OnWindowPainted() {
- process_->Send(new GpuMsg_WindowPainted(routing_id_));
+ process_shim_->Send(new GpuMsg_WindowPainted(routing_id_));
}
diff --git a/chrome/browser/renderer_host/gpu_view_host.h b/chrome/browser/renderer_host/gpu_view_host.h
index 910c978..8d19e07 100644
--- a/chrome/browser/renderer_host/gpu_view_host.h
+++ b/chrome/browser/renderer_host/gpu_view_host.h
@@ -9,7 +9,7 @@
#include "chrome/common/gpu_native_window_handle.h"
class BackingStore;
-class GpuProcessHost;
+class GpuProcessHostUIShim;
class RenderWidgetHost;
class VideoLayer;
@@ -40,7 +40,7 @@ class GpuViewHost {
private:
RenderWidgetHost* widget_;
- GpuProcessHost* process_;
+ GpuProcessHostUIShim* process_shim_;
int32 routing_id_;
DISALLOW_COPY_AND_ASSIGN(GpuViewHost);
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index de9e836..3dfcf63 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/geolocation/geolocation_permission_context.h"
#include "chrome/browser/geolocation/geolocation_dispatcher_host.h"
+#include "chrome/browser/gpu_process_host.h"
#include "chrome/browser/host_zoom_map.h"
#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
@@ -540,6 +541,10 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
#if defined(USE_TCMALLOC)
IPC_MESSAGE_HANDLER(ViewHostMsg_RendererTcmalloc, OnRendererTcmalloc)
#endif
+ IPC_MESSAGE_HANDLER(ViewHostMsg_EstablishGpuChannel,
+ OnEstablishGpuChannel)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SynchronizeGpu,
+ OnSynchronizeGpu)
IPC_MESSAGE_UNHANDLED(
handled = false)
IPC_END_MESSAGE_MAP_EX()
@@ -1411,6 +1416,19 @@ void ResourceMessageFilter::OnRendererTcmalloc(base::ProcessId pid,
}
#endif
+void ResourceMessageFilter::OnEstablishGpuChannel() {
+ GpuProcessHost::Get()->EstablishGpuChannel(id(), this);
+}
+
+void ResourceMessageFilter::OnSynchronizeGpu(IPC::Message* reply) {
+ // We handle this message (and the other GPU process messages) here
+ // rather than handing the message to the GpuProcessHost for
+ // dispatch so that we can use the DELAY_REPLY macro to synthesize
+ // the reply message, and also send down a "this" pointer so that
+ // the GPU process host can send the reply later.
+ GpuProcessHost::Get()->Synchronize(reply, this);
+}
+
void ResourceMessageFilter::OnGetExtensionMessageBundle(
const std::string& extension_id, IPC::Message* reply_msg) {
ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>(
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 2abc4c0..a69fd78 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -328,6 +328,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnTranslateText(ViewHostMsg_TranslateTextParam param);
+ void OnEstablishGpuChannel();
+ void OnSynchronizeGpu(IPC::Message* reply);
+
#if defined(USE_X11)
void SendDelayedReply(IPC::Message* reply_msg);
void DoOnGetScreenInfo(gfx::NativeViewId view, IPC::Message* reply_msg);
diff --git a/chrome/browser/renderer_host/video_layer_proxy.cc b/chrome/browser/renderer_host/video_layer_proxy.cc
index 1fdae24..3df1d25 100644
--- a/chrome/browser/renderer_host/video_layer_proxy.cc
+++ b/chrome/browser/renderer_host/video_layer_proxy.cc
@@ -4,23 +4,23 @@
#include "chrome/browser/renderer_host/video_layer_proxy.h"
-#include "chrome/browser/gpu_process_host.h"
+#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/gpu_messages.h"
#include "gfx/rect.h"
VideoLayerProxy::VideoLayerProxy(RenderWidgetHost* widget,
const gfx::Size& size,
- GpuProcessHost* process,
+ GpuProcessHostUIShim* process_shim,
int32 routing_id)
: VideoLayer(widget, size),
- process_(process),
+ process_shim_(process_shim),
routing_id_(routing_id) {
- process_->AddRoute(routing_id_, this);
+ process_shim_->AddRoute(routing_id_, this);
}
VideoLayerProxy::~VideoLayerProxy() {
- process_->RemoveRoute(routing_id_);
+ process_shim_->RemoveRoute(routing_id_);
}
void VideoLayerProxy::CopyTransportDIB(RenderProcessHost* process,
@@ -33,7 +33,7 @@ void VideoLayerProxy::CopyTransportDIB(RenderProcessHost* process,
process_id = process->GetHandle();
#endif
- if (process_->Send(new GpuMsg_PaintToVideoLayer(
+ if (process_shim_->Send(new GpuMsg_PaintToVideoLayer(
routing_id_, process_id, bitmap, bitmap_rect))) {
} else {
// TODO(scherkus): what to do ?!?!
diff --git a/chrome/browser/renderer_host/video_layer_proxy.h b/chrome/browser/renderer_host/video_layer_proxy.h
index 637525e..02b90ed 100644
--- a/chrome/browser/renderer_host/video_layer_proxy.h
+++ b/chrome/browser/renderer_host/video_layer_proxy.h
@@ -8,13 +8,13 @@
#include "chrome/browser/renderer_host/video_layer.h"
#include "ipc/ipc_channel.h"
-class GpuProcessHost;
+class GpuProcessHostUIShim;
// Proxies YUV video layer data to the GPU process for rendering.
class VideoLayerProxy : public VideoLayer, public IPC::Channel::Listener {
public:
VideoLayerProxy(RenderWidgetHost* widget, const gfx::Size& size,
- GpuProcessHost* process, int32 routing_id);
+ GpuProcessHostUIShim* process_shim, int32 routing_id);
virtual ~VideoLayerProxy();
// VideoLayer implementation.
@@ -32,7 +32,7 @@ class VideoLayerProxy : public VideoLayer, public IPC::Channel::Listener {
void OnPaintToVideoLayerACK();
// GPU process receiving our proxied requests.
- GpuProcessHost* process_;
+ GpuProcessHostUIShim* process_shim_;
// IPC routing ID to use when communicating with the GPU process.
int32 routing_id_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index cbd819bc..5335a20b 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1124,6 +1124,8 @@
'browser/google_util.h',
'browser/gpu_process_host.cc',
'browser/gpu_process_host.h',
+ 'browser/gpu_process_host_ui_shim.cc',
+ 'browser/gpu_process_host_ui_shim.h',
'browser/gtk/about_chrome_dialog.cc',
'browser/gtk/about_chrome_dialog.h',
'browser/gtk/accelerators_gtk.cc',
diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h
index 628671d..7c8f033 100644
--- a/chrome/common/gpu_messages_internal.h
+++ b/chrome/common/gpu_messages_internal.h
@@ -31,8 +31,7 @@ IPC_BEGIN_MESSAGES(Gpu)
// completed. (This message can't be synchronous because the
// GpuProcessHost uses an IPC::ChannelProxy, which sends all messages
// asynchronously.) Results in a GpuHostMsg_SynchronizeReply.
- IPC_MESSAGE_CONTROL1(GpuMsg_Synchronize,
- int /* renderer_id */)
+ IPC_MESSAGE_CONTROL0(GpuMsg_Synchronize)
IPC_MESSAGE_CONTROL2(GpuMsg_NewRenderWidgetHostView,
GpuNativeWindowHandle, /* parent window */
@@ -100,8 +99,7 @@ IPC_BEGIN_MESSAGES(GpuHost)
IPC::ChannelHandle /* channel_handle */)
// Response to a GpuMsg_Synchronize message.
- IPC_MESSAGE_CONTROL1(GpuHostMsg_SynchronizeReply,
- int /* renderer_id */)
+ IPC_MESSAGE_CONTROL0(GpuHostMsg_SynchronizeReply)
IPC_END_MESSAGES(GpuHost)
diff --git a/chrome/common/sandbox_policy.cc b/chrome/common/sandbox_policy.cc
index d0766e9..5153c4d 100644
--- a/chrome/common/sandbox_policy.cc
+++ b/chrome/common/sandbox_policy.cc
@@ -421,7 +421,8 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
(type != ChildProcessInfo::NACL_BROKER_PROCESS) &&
!browser_command_line.HasSwitch(switches::kNoSandbox) &&
(type != ChildProcessInfo::PLUGIN_PROCESS ||
- browser_command_line.HasSwitch(switches::kSafePlugins));
+ browser_command_line.HasSwitch(switches::kSafePlugins)) &&
+ (type != ChildProcessInfo::GPU_PROCESS);
#if !defined (GOOGLE_CHROME_BUILD)
if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) {
// In process plugins won't work if the sandbox is enabled.
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc
index b2b5bf9..b775acf 100644
--- a/chrome/gpu/gpu_channel.cc
+++ b/chrome/gpu/gpu_channel.cc
@@ -91,8 +91,10 @@ void GpuChannel::OnChannelError() {
#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());
+ for (StubMap::const_iterator iter = stubs_.begin();
+ iter != stubs_.end();
+ ++iter) {
+ router_.RemoveRoute(iter->second->route_id());
}
stubs_.clear();
#endif
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index 5e096a5..c2c190e 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -81,8 +81,8 @@ void GpuThread::OnEstablishChannel(int renderer_id) {
Send(new GpuHostMsg_ChannelEstablished(channel_handle));
}
-void GpuThread::OnSynchronize(int renderer_id) {
- Send(new GpuHostMsg_SynchronizeReply(renderer_id));
+void GpuThread::OnSynchronize() {
+ Send(new GpuHostMsg_SynchronizeReply());
}
void GpuThread::OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window,
diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h
index bc06051..fdef70b 100644
--- a/chrome/gpu/gpu_thread.h
+++ b/chrome/gpu/gpu_thread.h
@@ -36,7 +36,7 @@ class GpuThread : public ChildThread {
// Message handlers.
void OnEstablishChannel(int renderer_id);
- void OnSynchronize(int renderer_id);
+ void OnSynchronize();
void OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window,
int32 routing_id);
diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc
index 8d2cdd9..3562c0b 100644
--- a/chrome/renderer/gpu_channel_host.cc
+++ b/chrome/renderer/gpu_channel_host.cc
@@ -44,7 +44,6 @@ void GpuChannelHost::OnChannelError() {
// 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();
}
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index aff8fa6..81636c7 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -687,8 +687,10 @@ void RenderThread::UpdateActiveExtensions() {
void RenderThread::EstablishGpuChannel() {
if (gpu_channel_.get()) {
- // Do nothing if we are already establishing GPU channel.
- if (gpu_channel_->state() == GpuChannelHost::UNCONNECTED)
+ // Do nothing if we already have a GPU channel or are already
+ // establishing one.
+ if (gpu_channel_->state() == GpuChannelHost::UNCONNECTED ||
+ gpu_channel_->state() == GpuChannelHost::CONNECTED)
return;
// Recreate the channel if it has been lost.
@@ -704,8 +706,16 @@ void RenderThread::EstablishGpuChannel() {
}
GpuChannelHost* RenderThread::EstablishGpuChannelSync() {
- EstablishGpuChannel();
- Send(new ViewHostMsg_SynchronizeGpu());
+ // We may need to retry the connection establishment if an existing
+ // connection has gone bad, which will not be detected in
+ // EstablishGpuChannel since we do not send duplicate
+ // ViewHostMsg_EstablishGpuChannel messages -- doing so breaks the
+ // preexisting connection in bad ways.
+ bool retry = true;
+ for (int i = 0; i < 2 && retry; ++i) {
+ EstablishGpuChannel();
+ retry = !Send(new ViewHostMsg_SynchronizeGpu());
+ }
// TODO(kbr): the GPU channel is still in the unconnected state at this point.
// Need to figure out whether it is really safe to return it.
return gpu_channel_.get();