summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-13 21:30:56 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-13 21:30:56 +0000
commit630c1f381c85b69064ce2adfd5999c0f3c136ed3 (patch)
tree27f652915b4abee2f552d4121f2999fcc3dd71fc
parentfabc9afb40110ca98859a93cb48c0140e070374b (diff)
downloadchromium_src-630c1f381c85b69064ce2adfd5999c0f3c136ed3.zip
chromium_src-630c1f381c85b69064ce2adfd5999c0f3c136ed3.tar.gz
chromium_src-630c1f381c85b69064ce2adfd5999c0f3c136ed3.tar.bz2
GPU service now runs on new thread in browser process when --single-process is specified.
TEST=try BUG=none Review URL: http://codereview.chromium.org/6189008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71359 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/DEPS3
-rw-r--r--chrome/browser/gpu_process_host.cc115
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/gpu/gpu_channel.cc8
-rw-r--r--chrome/gpu/gpu_channel.h13
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.cc13
-rw-r--r--chrome/gpu/gpu_main.cc2
-rw-r--r--chrome/gpu/gpu_thread.cc16
-rw-r--r--chrome/gpu/gpu_thread.h9
-rw-r--r--chrome_frame/chrome_frame.gyp4
10 files changed, 130 insertions, 55 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 1d4653b..1cf13fc 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -37,7 +37,8 @@ include_rules = [
"+third_party/undoview",
"+v8/include", # Browser uses V8 to get the version and run the debugger.
- # FIXME: this should probably not be here, we need to find a better
+ # FIXME: these should probably not be here, we need to find a better
# structure for these includes.
"+chrome/renderer",
+ "+chrome/gpu",
]
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 8741e4e..ea5c0b7 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -22,6 +22,7 @@
#include "chrome/common/gpu_info.h"
#include "chrome/common/gpu_messages.h"
#include "chrome/common/render_messages.h"
+#include "chrome/gpu/gpu_thread.h"
#include "grit/browser_resources.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_switches.h"
@@ -83,6 +84,35 @@ void RouteOnUIThread(const IPC::Message& message) {
}
} // anonymous namespace
+class GpuMainThread : public base::Thread {
+ public:
+ explicit GpuMainThread(const std::string& channel_id)
+ : base::Thread("CrGpuMain"),
+ channel_id_(channel_id) {
+ }
+
+ ~GpuMainThread() {
+ Stop();
+ }
+
+ protected:
+ virtual void Init() {
+ // Must be created on GPU thread.
+ gpu_thread_.reset(new GpuThread(channel_id_));
+ gpu_thread_->Init(base::Time::Now());
+ }
+
+ virtual void CleanUp() {
+ // Must be destroyed on GPU thread.
+ gpu_thread_.reset();
+ }
+
+ private:
+ scoped_ptr<GpuThread> gpu_thread_;
+ std::string channel_id_;
+ DISALLOW_COPY_AND_ASSIGN(GpuMainThread);
+};
+
GpuProcessHost::GpuProcessHost()
: BrowserChildProcessHost(GPU_PROCESS, NULL),
initialized_(false),
@@ -543,48 +573,61 @@ bool GpuProcessHost::CanLaunchGpuProcess() const {
bool GpuProcessHost::LaunchGpuProcess() {
const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
- CommandLine::StringType gpu_launcher =
- browser_command_line.GetSwitchValueNative(switches::kGpuLauncher);
- FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty());
- if (exe_path.empty())
- return false;
+ // If the single-process switch is present, just launch the GPU service in a
+ // new thread in the browser process.
+ if (browser_command_line.HasSwitch(switches::kSingleProcess)) {
+ GpuMainThread* thread = new GpuMainThread(channel_id());
- CommandLine* cmd_line = new CommandLine(exe_path);
- cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
-
- // Propagate relevant command line switches.
- static const char* const kSwitchNames[] = {
- switches::kUseGL,
- switches::kDisableGpuVsync,
- switches::kDisableGpuWatchdog,
- switches::kDisableLogging,
- switches::kEnableAcceleratedDecoding,
- switches::kEnableLogging,
-#if defined(OS_MACOSX)
- switches::kEnableSandboxLogging,
-#endif
- switches::kGpuStartupDialog,
- switches::kLoggingLevel,
- switches::kNoGpuSandbox,
- switches::kNoSandbox,
- };
- cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
- arraysize(kSwitchNames));
-
- // If specified, prepend a launcher program to the command line.
- if (!gpu_launcher.empty())
- cmd_line->PrependWrapper(gpu_launcher);
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_UI;
- Launch(
+ if (!thread->StartWithOptions(options))
+ return false;
+ } else {
+ CommandLine::StringType gpu_launcher =
+ browser_command_line.GetSwitchValueNative(switches::kGpuLauncher);
+
+ FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty());
+ if (exe_path.empty())
+ return false;
+
+ CommandLine* cmd_line = new CommandLine(exe_path);
+ cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess);
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+
+ // Propagate relevant command line switches.
+ static const char* const kSwitchNames[] = {
+ switches::kUseGL,
+ switches::kDisableGpuVsync,
+ switches::kDisableGpuWatchdog,
+ switches::kDisableLogging,
+ switches::kEnableAcceleratedDecoding,
+ switches::kEnableLogging,
+ #if defined(OS_MACOSX)
+ switches::kEnableSandboxLogging,
+ #endif
+ switches::kGpuStartupDialog,
+ switches::kLoggingLevel,
+ switches::kNoGpuSandbox,
+ switches::kNoSandbox,
+ };
+ cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
+ arraysize(kSwitchNames));
+
+ // If specified, prepend a launcher program to the command line.
+ if (!gpu_launcher.empty())
+ cmd_line->PrependWrapper(gpu_launcher);
+
+ Launch(
#if defined(OS_WIN)
- FilePath(),
+ FilePath(),
#elif defined(OS_POSIX)
- false, // Never use the zygote (GPU plugin can't be sandboxed).
- base::environment_vector(),
+ false, // Never use the zygote (GPU plugin can't be sandboxed).
+ base::environment_vector(),
#endif
- cmd_line);
+ cmd_line);
+ }
UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
LAUNCED, GPU_PROCESS_LIFETIME_EVENT_MAX);
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 6dd7800..ca9aec5 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -26,6 +26,7 @@
'browser',
'common',
'renderer',
+ 'chrome_gpu',
'chrome_resources',
'chrome_strings',
'browser/sync/protocol/sync_proto.gyp:sync_proto_cpp',
@@ -3133,6 +3134,7 @@
'browser',
'common',
'renderer',
+ 'chrome_gpu',
'chrome_resources',
'chrome_strings',
'../app/app.gyp:app_base',
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc
index 79e9186..3ff6da2 100644
--- a/chrome/gpu/gpu_channel.cc
+++ b/chrome/gpu/gpu_channel.cc
@@ -23,8 +23,10 @@
#include "ipc/ipc_channel_posix.h"
#endif
-GpuChannel::GpuChannel(int renderer_id)
- : renderer_id_(renderer_id) {
+GpuChannel::GpuChannel(GpuThread* gpu_thread, int renderer_id)
+ : gpu_thread_(gpu_thread),
+ renderer_id_(renderer_id) {
+ DCHECK(gpu_thread);
const CommandLine* command_line = CommandLine::ForCurrentProcess();
log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
}
@@ -254,7 +256,7 @@ bool GpuChannel::Init() {
}
std::string GpuChannel::GetChannelName() {
- return StringPrintf("%d.r%d", base::GetCurrentProcId(), renderer_id_);
+ return StringPrintf("%d.r%d.gpu", base::GetCurrentProcId(), renderer_id_);
}
#if defined(OS_POSIX)
diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h
index 1706e03..75d57ca 100644
--- a/chrome/gpu/gpu_channel.h
+++ b/chrome/gpu/gpu_channel.h
@@ -24,17 +24,23 @@
#include "ipc/ipc_message.h"
#include "ipc/ipc_sync_channel.h"
+class GpuThread;
+
// 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:
- explicit GpuChannel(int renderer_id);
+ GpuChannel(GpuThread* gpu_thread, int renderer_id);
virtual ~GpuChannel();
bool Init();
+ // Get the GpuThread that owns this channel.
+ GpuThread* gpu_thread() const { return gpu_thread_; }
+
+ // Returns the name of the associated IPC channel.
std::string GetChannelName();
#if defined(OS_POSIX)
@@ -84,6 +90,11 @@ class GpuChannel : public IPC::Channel::Listener,
int32 decoder_host_id);
void OnDestroyVideoDecoder(int32 decoder_id);
+ // The lifetime of objects of this class is managed by a GpuThread. The
+ // GpuThreadss destroy all the GpuChannels that they own when they
+ // are destroyed. So a raw pointer is safe.
+ GpuThread* gpu_thread_;
+
scoped_ptr<IPC::SyncChannel> channel_;
// Handle to the renderer process who is on the other side of the channel.
diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc
index 592e04f..b51695d 100644
--- a/chrome/gpu/gpu_command_buffer_stub.cc
+++ b/chrome/gpu/gpu_command_buffer_stub.cc
@@ -11,6 +11,7 @@
#include "chrome/common/gpu_messages.h"
#include "chrome/gpu/gpu_channel.h"
#include "chrome/gpu/gpu_command_buffer_stub.h"
+#include "chrome/gpu/gpu_thread.h"
using gpu::Buffer;
@@ -81,7 +82,7 @@ bool GpuCommandBufferStub::CreateCompositorWindow() {
DCHECK(handle_ != gfx::kNullPluginWindow);
// Ask the browser to create the the host window.
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
gfx::PluginWindowHandle host_window_id = gfx::kNullPluginWindow;
gpu_thread->Send(new GpuHostMsg_GetCompositorHostWindow(
renderer_id_,
@@ -146,7 +147,7 @@ bool GpuCommandBufferStub::CreateCompositorWindow() {
}
void GpuCommandBufferStub::OnCompositorWindowPainted() {
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
gpu_thread->Send(new GpuHostMsg_ScheduleComposite(
renderer_id_, render_view_id_));
}
@@ -163,7 +164,7 @@ GpuCommandBufferStub::~GpuCommandBufferStub() {
compositor_window_ = NULL;
}
#elif defined(OS_LINUX)
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
gpu_thread->Send(
new GpuHostMsg_ReleaseXID(handle_));
#endif // defined(OS_WIN)
@@ -332,7 +333,7 @@ void GpuCommandBufferStub::OnSwapBuffers() {
#if defined(OS_MACOSX)
void GpuCommandBufferStub::OnSetWindowSize(const gfx::Size& size) {
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
// Try using the IOSurface version first.
uint64 new_backing_store = processor_->SetWindowSizeForIOSurface(size);
if (new_backing_store) {
@@ -354,7 +355,7 @@ void GpuCommandBufferStub::OnSetWindowSize(const gfx::Size& size) {
void GpuCommandBufferStub::SwapBuffersCallback() {
OnSwapBuffers();
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
params.renderer_id = renderer_id_;
params.render_view_id = render_view_id_;
@@ -378,7 +379,7 @@ void GpuCommandBufferStub::ResizeCallback(gfx::Size size) {
return;
#if defined(OS_LINUX)
- ChildThread* gpu_thread = ChildThread::current();
+ GpuThread* gpu_thread = channel_->gpu_thread();
bool result = false;
gpu_thread->Send(
new GpuHostMsg_ResizeXID(handle_, size, &result));
diff --git a/chrome/gpu/gpu_main.cc b/chrome/gpu/gpu_main.cc
index 9bd6568..d094760 100644
--- a/chrome/gpu/gpu_main.cc
+++ b/chrome/gpu/gpu_main.cc
@@ -71,7 +71,7 @@ int GpuMain(const MainFunctionParams& parameters) {
// this reason we defer all work related to the GPU until receiving
// the GpuMsg_Initialize message from the browser.
GpuProcess gpu_process;
- GpuThread* gpu_thread = new GpuThread(command_line);
+ GpuThread* gpu_thread = new GpuThread;
gpu_thread->Init(start_time);
gpu_process.set_main_thread(gpu_thread);
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index 58dd088..6e9b3da 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -44,8 +44,12 @@ bool InitializeGpuSandbox() {
} // namespace
-GpuThread::GpuThread(const CommandLine& command_line)
- : command_line_(command_line) {}
+GpuThread::GpuThread() {
+}
+
+GpuThread::GpuThread(const std::string& channel_id)
+ : ChildThread(channel_id) {
+}
GpuThread::~GpuThread() {
}
@@ -108,7 +112,8 @@ void GpuThread::OnInitialize() {
gpu_info_.SetInitializationTime(base::Time::Now() - process_start_time_);
// Note that kNoSandbox will also disable the GPU sandbox.
- bool no_gpu_sandbox = command_line_.HasSwitch(switches::kNoGpuSandbox);
+ bool no_gpu_sandbox = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kNoGpuSandbox);
if (!no_gpu_sandbox) {
if (!InitializeGpuSandbox()) {
LOG(ERROR) << "Failed to initialize the GPU sandbox";
@@ -124,7 +129,8 @@ void GpuThread::OnInitialize() {
// slowly. Also disable the watchdog on valgrind because the code is expected
// to run slowly in that case.
bool enable_watchdog =
- !command_line_.HasSwitch(switches::kDisableGpuWatchdog) &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableGpuWatchdog) &&
gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL &&
!RunningOnValgrind();
@@ -164,7 +170,7 @@ void GpuThread::OnEstablishChannel(int renderer_id) {
GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
if (iter == gpu_channels_.end())
- channel = new GpuChannel(renderer_id);
+ channel = new GpuChannel(this, renderer_id);
else
channel = iter->second;
diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h
index 1d0f434..6928645 100644
--- a/chrome/gpu/gpu_thread.h
+++ b/chrome/gpu/gpu_thread.h
@@ -6,6 +6,8 @@
#define CHROME_GPU_GPU_THREAD_H_
#pragma once
+#include <string>
+
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/scoped_ptr.h"
@@ -26,7 +28,11 @@ class GpuWatchdogThread;
class GpuThread : public ChildThread {
public:
- explicit GpuThread(const CommandLine& command_line);
+ GpuThread();
+
+ // For single-process mode.
+ explicit GpuThread(const std::string& channel_id);
+
~GpuThread();
void Init(const base::Time& process_start_time);
@@ -58,7 +64,6 @@ class GpuThread : public ChildThread {
static void SetDxDiagnostics(GpuThread* thread, const DxDiagNode& node);
#endif
- CommandLine command_line_;
base::Time process_start_time_;
scoped_refptr<GpuWatchdogThread> watchdog_thread_;
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 00785be..a50096f 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -269,6 +269,7 @@
'dependencies': [
'../base/base.gyp:test_support_base',
'../build/temp_gyp/googleurl.gyp:googleurl',
+ '../chrome/chrome.gyp:chrome_gpu',
'../chrome/chrome.gyp:chrome_version_header',
'../chrome/chrome.gyp:common',
'../chrome/chrome.gyp:utility',
@@ -383,6 +384,7 @@
'../base/base.gyp:base_i18n',
'../base/base.gyp:test_support_base',
'../build/temp_gyp/googleurl.gyp:googleurl',
+ '../chrome/chrome.gyp:chrome_gpu',
'../chrome/chrome.gyp:common',
'../chrome/chrome.gyp:browser',
'../chrome/chrome.gyp:debugger',
@@ -466,6 +468,7 @@
'dependencies': [
'../base/base.gyp:test_support_base',
'../chrome/chrome.gyp:browser',
+ '../chrome/chrome.gyp:chrome_gpu',
'../chrome/chrome.gyp:chrome_resources',
'../chrome/chrome.gyp:debugger',
'../chrome/chrome.gyp:renderer',
@@ -542,6 +545,7 @@
'../base/base.gyp:base',
'../base/base.gyp:test_support_base',
'../chrome/chrome.gyp:browser',
+ '../chrome/chrome.gyp:chrome_gpu',
'../chrome/chrome.gyp:debugger',
'../chrome/chrome.gyp:renderer',
'../chrome/chrome.gyp:test_support_common',