Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: chrome/browser/gpu_process_host.cc

Issue 6538111: Move the rest of the core files in chrome\browser to content\browser.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gpu_process_host.h ('k') | chrome/browser/gpu_process_host_ui_shim.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/gpu_process_host.h"
6
7 #include "app/app_switches.h"
8 #include "base/metrics/histogram.h"
9 #include "base/ref_counted.h"
10 #include "base/string_piece.h"
11 #include "base/threading/thread.h"
12 #include "chrome/browser/browser_thread.h"
13 #include "chrome/browser/gpu_process_host_ui_shim.h"
14 #include "chrome/browser/renderer_host/render_widget_host.h"
15 #include "chrome/browser/renderer_host/render_widget_host_view.h"
16 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/gpu_feature_flags.h"
19 #include "chrome/common/gpu_info.h"
20 #include "chrome/common/gpu_messages.h"
21 #include "chrome/common/render_messages.h"
22 #include "chrome/gpu/gpu_thread.h"
23 #include "ipc/ipc_channel_handle.h"
24 #include "ipc/ipc_switches.h"
25 #include "media/base/media_switches.h"
26
27 #if defined(OS_LINUX)
28 #include "ui/gfx/gtk_native_view_id_manager.h"
29 #endif // defined(OS_LINUX)
30
31 namespace {
32
33 enum GPUProcessLifetimeEvent {
34 LAUNCHED,
35 DIED_FIRST_TIME,
36 DIED_SECOND_TIME,
37 DIED_THIRD_TIME,
38 DIED_FOURTH_TIME,
39 GPU_PROCESS_LIFETIME_EVENT_MAX
40 };
41
42 class RouteOnUIThreadTask : public Task {
43 public:
44 RouteOnUIThreadTask(int host_id, const IPC::Message& msg)
45 : host_id_(host_id),
46 msg_(msg) {
47 }
48
49 private:
50 virtual void Run() {
51 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id_);
52 if (ui_shim)
53 ui_shim->OnMessageReceived(msg_);
54 }
55
56 int host_id_;
57 IPC::Message msg_;
58 };
59
60 // A global map from GPU process host ID to GpuProcessHost.
61 static IDMap<GpuProcessHost> g_hosts_by_id;
62
63 // Number of times the gpu process has crashed in the current browser session.
64 static int g_gpu_crash_count = 0;
65
66 // Maximum number of times the gpu process is allowed to crash in a session.
67 // Once this limit is reached, any request to launch the gpu process will fail.
68 static const int kGpuMaxCrashCount = 3;
69
70 } // anonymous namespace
71
72 class GpuMainThread : public base::Thread {
73 public:
74 explicit GpuMainThread(const std::string& channel_id)
75 : base::Thread("CrGpuMain"),
76 channel_id_(channel_id) {
77 }
78
79 ~GpuMainThread() {
80 Stop();
81 }
82
83 protected:
84 virtual void Init() {
85 // Must be created on GPU thread.
86 gpu_thread_.reset(new GpuThread(channel_id_));
87 gpu_thread_->Init(base::Time::Now());
88 }
89
90 virtual void CleanUp() {
91 // Must be destroyed on GPU thread.
92 gpu_thread_.reset();
93 }
94
95 private:
96 scoped_ptr<GpuThread> gpu_thread_;
97 std::string channel_id_;
98 DISALLOW_COPY_AND_ASSIGN(GpuMainThread);
99 };
100
101 // static
102 GpuProcessHost* GpuProcessHost::Create(int host_id) {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
104
105 GpuProcessHost* host = new GpuProcessHost(host_id);
106 if (!host->Init()) {
107 delete host;
108 return NULL;
109 }
110
111 return host;
112 }
113
114 // static
115 GpuProcessHost* GpuProcessHost::FromID(int host_id) {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
117
118 if (host_id == 0)
119 return NULL;
120
121 return g_hosts_by_id.Lookup(host_id);
122 }
123
124 GpuProcessHost::GpuProcessHost(int host_id)
125 : BrowserChildProcessHost(GPU_PROCESS, NULL),
126 host_id_(host_id) {
127 g_hosts_by_id.AddWithID(this, host_id_);
128 }
129
130 GpuProcessHost::~GpuProcessHost() {
131
132 DCHECK(CalledOnValidThread());
133
134 g_hosts_by_id.Remove(host_id_);
135
136 BrowserThread::PostTask(BrowserThread::UI,
137 FROM_HERE,
138 NewRunnableFunction(GpuProcessHostUIShim::Destroy,
139 host_id_));
140 }
141
142 bool GpuProcessHost::Init() {
143 if (!CreateChannel())
144 return false;
145
146 if (!CanLaunchGpuProcess())
147 return false;
148
149 if (!LaunchGpuProcess())
150 return false;
151
152 return Send(new GpuMsg_Initialize());
153 }
154
155 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) {
156 BrowserThread::PostTask(BrowserThread::UI,
157 FROM_HERE,
158 new RouteOnUIThreadTask(host_id_, message));
159 }
160
161 bool GpuProcessHost::Send(IPC::Message* msg) {
162 DCHECK(CalledOnValidThread());
163 return BrowserChildProcessHost::Send(msg);
164 }
165
166 bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
167 DCHECK(CalledOnValidThread());
168 RouteOnUIThread(message);
169 return true;
170 }
171
172 bool GpuProcessHost::CanShutdown() {
173 return true;
174 }
175
176 namespace {
177
178 void SendOutstandingRepliesDispatcher(int host_id) {
179 GpuProcessHostUIShim *ui_shim = GpuProcessHostUIShim::FromID(host_id);
180 DCHECK(ui_shim);
181 ui_shim->SendOutstandingReplies();
182 }
183
184 void SendOutstandingReplies(int host_id) {
185 BrowserThread::PostTask(
186 BrowserThread::UI, FROM_HERE,
187 NewRunnableFunction(&SendOutstandingRepliesDispatcher, host_id));
188 }
189
190 } // namespace
191
192 void GpuProcessHost::OnChildDied() {
193 SendOutstandingReplies(host_id_);
194 // Located in OnChildDied because OnProcessCrashed suffers from a race
195 // condition on Linux.
196 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
197 DIED_FIRST_TIME + g_gpu_crash_count,
198 GPU_PROCESS_LIFETIME_EVENT_MAX);
199 BrowserChildProcessHost::OnChildDied();
200 }
201
202 void GpuProcessHost::OnProcessCrashed(int exit_code) {
203 SendOutstandingReplies(host_id_);
204 if (++g_gpu_crash_count >= kGpuMaxCrashCount) {
205 // The gpu process is too unstable to use. Disable it for current session.
206 RenderViewHostDelegateHelper::set_gpu_enabled(false);
207 }
208 BrowserChildProcessHost::OnProcessCrashed(exit_code);
209 }
210
211 bool GpuProcessHost::CanLaunchGpuProcess() const {
212 return RenderViewHostDelegateHelper::gpu_enabled();
213 }
214
215 bool GpuProcessHost::LaunchGpuProcess() {
216 if (g_gpu_crash_count >= kGpuMaxCrashCount)
217 return false;
218
219 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
220
221 // If the single-process switch is present, just launch the GPU service in a
222 // new thread in the browser process.
223 if (browser_command_line.HasSwitch(switches::kSingleProcess)) {
224 GpuMainThread* thread = new GpuMainThread(channel_id());
225
226 base::Thread::Options options;
227 #if defined(OS_LINUX)
228 options.message_loop_type = MessageLoop::TYPE_IO;
229 #else
230 options.message_loop_type = MessageLoop::TYPE_UI;
231 #endif
232
233 if (!thread->StartWithOptions(options))
234 return false;
235
236 return true;
237 }
238
239 CommandLine::StringType gpu_launcher =
240 browser_command_line.GetSwitchValueNative(switches::kGpuLauncher);
241
242 FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty());
243 if (exe_path.empty())
244 return false;
245
246 CommandLine* cmd_line = new CommandLine(exe_path);
247 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess);
248 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
249
250 SetCrashReporterCommandLine(cmd_line);
251
252 // Propagate relevant command line switches.
253 static const char* const kSwitchNames[] = {
254 switches::kUseGL,
255 switches::kDisableGpuVsync,
256 switches::kDisableGpuWatchdog,
257 switches::kDisableLogging,
258 switches::kEnableAcceleratedDecoding,
259 switches::kEnableLogging,
260 #if defined(OS_MACOSX)
261 switches::kEnableSandboxLogging,
262 #endif
263 switches::kGpuStartupDialog,
264 switches::kLoggingLevel,
265 switches::kNoGpuSandbox,
266 switches::kNoSandbox,
267 };
268 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
269 arraysize(kSwitchNames));
270
271 // If specified, prepend a launcher program to the command line.
272 if (!gpu_launcher.empty())
273 cmd_line->PrependWrapper(gpu_launcher);
274
275 Launch(
276 #if defined(OS_WIN)
277 FilePath(),
278 #elif defined(OS_POSIX)
279 false, // Never use the zygote (GPU plugin can't be sandboxed).
280 base::environment_vector(),
281 #endif
282 cmd_line);
283
284 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
285 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
286 return true;
287 }
OLDNEW
« no previous file with comments | « chrome/browser/gpu_process_host.h ('k') | chrome/browser/gpu_process_host_ui_shim.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698