diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-13 21:30:56 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-13 21:30:56 +0000 |
commit | 630c1f381c85b69064ce2adfd5999c0f3c136ed3 (patch) | |
tree | 27f652915b4abee2f552d4121f2999fcc3dd71fc | |
parent | fabc9afb40110ca98859a93cb48c0140e070374b (diff) | |
download | chromium_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/DEPS | 3 | ||||
-rw-r--r-- | chrome/browser/gpu_process_host.cc | 115 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 2 | ||||
-rw-r--r-- | chrome/gpu/gpu_channel.cc | 8 | ||||
-rw-r--r-- | chrome/gpu/gpu_channel.h | 13 | ||||
-rw-r--r-- | chrome/gpu/gpu_command_buffer_stub.cc | 13 | ||||
-rw-r--r-- | chrome/gpu/gpu_main.cc | 2 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.cc | 16 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.h | 9 | ||||
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 4 |
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', |