| Index: chrome/browser/gpu_process_host.cc
|
| ===================================================================
|
| --- chrome/browser/gpu_process_host.cc (revision 75653)
|
| +++ chrome/browser/gpu_process_host.cc (working copy)
|
| @@ -1,287 +0,0 @@
|
| -// 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.h"
|
| -
|
| -#include "app/app_switches.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/ref_counted.h"
|
| -#include "base/string_piece.h"
|
| -#include "base/threading/thread.h"
|
| -#include "chrome/browser/browser_thread.h"
|
| -#include "chrome/browser/gpu_process_host_ui_shim.h"
|
| -#include "chrome/browser/renderer_host/render_widget_host.h"
|
| -#include "chrome/browser/renderer_host/render_widget_host_view.h"
|
| -#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/gpu_feature_flags.h"
|
| -#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 "ipc/ipc_channel_handle.h"
|
| -#include "ipc/ipc_switches.h"
|
| -#include "media/base/media_switches.h"
|
| -
|
| -#if defined(OS_LINUX)
|
| -#include "ui/gfx/gtk_native_view_id_manager.h"
|
| -#endif // defined(OS_LINUX)
|
| -
|
| -namespace {
|
| -
|
| -enum GPUProcessLifetimeEvent {
|
| - LAUNCHED,
|
| - DIED_FIRST_TIME,
|
| - DIED_SECOND_TIME,
|
| - DIED_THIRD_TIME,
|
| - DIED_FOURTH_TIME,
|
| - GPU_PROCESS_LIFETIME_EVENT_MAX
|
| - };
|
| -
|
| -class RouteOnUIThreadTask : public Task {
|
| - public:
|
| - RouteOnUIThreadTask(int host_id, const IPC::Message& msg)
|
| - : host_id_(host_id),
|
| - msg_(msg) {
|
| - }
|
| -
|
| - private:
|
| - virtual void Run() {
|
| - GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id_);
|
| - if (ui_shim)
|
| - ui_shim->OnMessageReceived(msg_);
|
| - }
|
| -
|
| - int host_id_;
|
| - IPC::Message msg_;
|
| -};
|
| -
|
| -// A global map from GPU process host ID to GpuProcessHost.
|
| -static IDMap<GpuProcessHost> g_hosts_by_id;
|
| -
|
| -// Number of times the gpu process has crashed in the current browser session.
|
| -static int g_gpu_crash_count = 0;
|
| -
|
| -// Maximum number of times the gpu process is allowed to crash in a session.
|
| -// Once this limit is reached, any request to launch the gpu process will fail.
|
| -static const int kGpuMaxCrashCount = 3;
|
| -
|
| -} // 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);
|
| -};
|
| -
|
| -// static
|
| -GpuProcessHost* GpuProcessHost::Create(int host_id) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| -
|
| - GpuProcessHost* host = new GpuProcessHost(host_id);
|
| - if (!host->Init()) {
|
| - delete host;
|
| - return NULL;
|
| - }
|
| -
|
| - return host;
|
| -}
|
| -
|
| -// static
|
| -GpuProcessHost* GpuProcessHost::FromID(int host_id) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| -
|
| - if (host_id == 0)
|
| - return NULL;
|
| -
|
| - return g_hosts_by_id.Lookup(host_id);
|
| -}
|
| -
|
| -GpuProcessHost::GpuProcessHost(int host_id)
|
| - : BrowserChildProcessHost(GPU_PROCESS, NULL),
|
| - host_id_(host_id) {
|
| - g_hosts_by_id.AddWithID(this, host_id_);
|
| -}
|
| -
|
| -GpuProcessHost::~GpuProcessHost() {
|
| -
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - g_hosts_by_id.Remove(host_id_);
|
| -
|
| - BrowserThread::PostTask(BrowserThread::UI,
|
| - FROM_HERE,
|
| - NewRunnableFunction(GpuProcessHostUIShim::Destroy,
|
| - host_id_));
|
| -}
|
| -
|
| -bool GpuProcessHost::Init() {
|
| - if (!CreateChannel())
|
| - return false;
|
| -
|
| - if (!CanLaunchGpuProcess())
|
| - return false;
|
| -
|
| - if (!LaunchGpuProcess())
|
| - return false;
|
| -
|
| - return Send(new GpuMsg_Initialize());
|
| -}
|
| -
|
| -void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) {
|
| - BrowserThread::PostTask(BrowserThread::UI,
|
| - FROM_HERE,
|
| - new RouteOnUIThreadTask(host_id_, message));
|
| -}
|
| -
|
| -bool GpuProcessHost::Send(IPC::Message* msg) {
|
| - DCHECK(CalledOnValidThread());
|
| - return BrowserChildProcessHost::Send(msg);
|
| -}
|
| -
|
| -bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
|
| - DCHECK(CalledOnValidThread());
|
| - RouteOnUIThread(message);
|
| - return true;
|
| -}
|
| -
|
| -bool GpuProcessHost::CanShutdown() {
|
| - return true;
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -void SendOutstandingRepliesDispatcher(int host_id) {
|
| - GpuProcessHostUIShim *ui_shim = GpuProcessHostUIShim::FromID(host_id);
|
| - DCHECK(ui_shim);
|
| - ui_shim->SendOutstandingReplies();
|
| -}
|
| -
|
| -void SendOutstandingReplies(int host_id) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::UI, FROM_HERE,
|
| - NewRunnableFunction(&SendOutstandingRepliesDispatcher, host_id));
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -void GpuProcessHost::OnChildDied() {
|
| - SendOutstandingReplies(host_id_);
|
| - // Located in OnChildDied because OnProcessCrashed suffers from a race
|
| - // condition on Linux.
|
| - UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
|
| - DIED_FIRST_TIME + g_gpu_crash_count,
|
| - GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| - BrowserChildProcessHost::OnChildDied();
|
| -}
|
| -
|
| -void GpuProcessHost::OnProcessCrashed(int exit_code) {
|
| - SendOutstandingReplies(host_id_);
|
| - if (++g_gpu_crash_count >= kGpuMaxCrashCount) {
|
| - // The gpu process is too unstable to use. Disable it for current session.
|
| - RenderViewHostDelegateHelper::set_gpu_enabled(false);
|
| - }
|
| - BrowserChildProcessHost::OnProcessCrashed(exit_code);
|
| -}
|
| -
|
| -bool GpuProcessHost::CanLaunchGpuProcess() const {
|
| - return RenderViewHostDelegateHelper::gpu_enabled();
|
| -}
|
| -
|
| -bool GpuProcessHost::LaunchGpuProcess() {
|
| - if (g_gpu_crash_count >= kGpuMaxCrashCount)
|
| - return false;
|
| -
|
| - const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
|
| -
|
| - // 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());
|
| -
|
| - base::Thread::Options options;
|
| -#if defined(OS_LINUX)
|
| - options.message_loop_type = MessageLoop::TYPE_IO;
|
| -#else
|
| - options.message_loop_type = MessageLoop::TYPE_UI;
|
| -#endif
|
| -
|
| - if (!thread->StartWithOptions(options))
|
| - return false;
|
| -
|
| - return true;
|
| - }
|
| -
|
| - 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());
|
| -
|
| - SetCrashReporterCommandLine(cmd_line);
|
| -
|
| - // 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(),
|
| -#elif defined(OS_POSIX)
|
| - false, // Never use the zygote (GPU plugin can't be sandboxed).
|
| - base::environment_vector(),
|
| -#endif
|
| - cmd_line);
|
| -
|
| - UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
|
| - LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
|
| - return true;
|
| -}
|
|
|