OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/gpu/gpu_process_host.h" | 5 #include "content/browser/gpu/gpu_process_host.h" |
6 | 6 |
7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/process_util.h" | 14 #include "base/process_util.h" |
15 #include "base/string_piece.h" | |
16 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
17 #include "content/browser/browser_child_process_host_impl.h" | 16 #include "content/browser/browser_child_process_host_impl.h" |
18 #include "content/browser/gpu/gpu_data_manager_impl.h" | 17 #include "content/browser/gpu/gpu_data_manager_impl.h" |
19 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 18 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
20 #include "content/browser/gpu/gpu_surface_tracker.h" | 19 #include "content/browser/gpu/gpu_surface_tracker.h" |
21 #include "content/browser/renderer_host/render_widget_helper.h" | 20 #include "content/browser/renderer_host/render_widget_helper.h" |
22 #include "content/browser/renderer_host/render_widget_host_impl.h" | 21 #include "content/browser/renderer_host/render_widget_host_impl.h" |
23 #include "content/common/child_process_host_impl.h" | 22 #include "content/common/child_process_host_impl.h" |
24 #include "content/common/gpu/gpu_messages.h" | 23 #include "content/common/gpu/gpu_messages.h" |
25 #include "content/common/view_messages.h" | 24 #include "content/common/view_messages.h" |
26 #include "content/gpu/gpu_child_thread.h" | 25 #include "content/gpu/gpu_child_thread.h" |
27 #include "content/gpu/gpu_process.h" | 26 #include "content/gpu/gpu_process.h" |
28 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/content_browser_client.h" | 28 #include "content/public/browser/content_browser_client.h" |
30 #include "content/public/browser/render_process_host.h" | 29 #include "content/public/browser/render_process_host.h" |
31 #include "content/public/browser/render_widget_host_view.h" | 30 #include "content/public/browser/render_widget_host_view.h" |
32 #include "content/public/common/content_switches.h" | 31 #include "content/public/common/content_switches.h" |
33 #include "content/public/common/result_codes.h" | 32 #include "content/public/common/result_codes.h" |
34 #include "gpu/command_buffer/service/gpu_switches.h" | 33 #include "gpu/command_buffer/service/gpu_switches.h" |
35 #include "ipc/ipc_channel_handle.h" | 34 #include "ipc/ipc_channel_handle.h" |
36 #include "ipc/ipc_switches.h" | 35 #include "ipc/ipc_switches.h" |
37 #include "ui/gl/gl_context.h" | |
38 #include "ui/gl/gl_implementation.h" | |
39 #include "ui/gl/gl_switches.h" | 36 #include "ui/gl/gl_switches.h" |
40 | 37 |
41 #if defined(TOOLKIT_GTK) | 38 #if defined(TOOLKIT_GTK) |
42 #include "ui/gfx/gtk_native_view_id_manager.h" | 39 #include "ui/gfx/gtk_native_view_id_manager.h" |
43 #endif | 40 #endif |
44 | 41 |
45 #if defined(OS_WIN) | 42 #if defined(OS_WIN) |
46 #include "ui/surface/accelerated_surface_win.h" | 43 #include "ui/surface/accelerated_surface_win.h" |
47 #endif | 44 #endif |
48 | 45 |
49 namespace content { | 46 namespace content { |
50 | 47 |
51 bool GpuProcessHost::gpu_enabled_ = true; | 48 bool GpuProcessHost::gpu_enabled_ = true; |
52 bool GpuProcessHost::hardware_gpu_enabled_ = true; | 49 bool GpuProcessHost::hardware_gpu_enabled_ = true; |
53 | 50 |
54 namespace { | 51 namespace { |
55 | 52 |
56 enum GPUProcessLifetimeEvent { | 53 enum GPUProcessLifetimeEvent { |
57 LAUNCHED, | 54 LAUNCHED, |
58 DIED_FIRST_TIME, | 55 DIED_FIRST_TIME, |
59 DIED_SECOND_TIME, | 56 DIED_SECOND_TIME, |
60 DIED_THIRD_TIME, | 57 DIED_THIRD_TIME, |
61 DIED_FOURTH_TIME, | 58 DIED_FOURTH_TIME, |
62 GPU_PROCESS_LIFETIME_EVENT_MAX = 100 | 59 GPU_PROCESS_LIFETIME_EVENT_MAX = 100 |
63 }; | 60 }; |
64 | 61 |
65 // Indexed by GpuProcessKind. There is one of each kind maximum. This array may | 62 // Indexed by GpuProcessKind. There is one of each kind maximum. This array may |
66 // only be accessed from the IO thread. | 63 // only be accessed from the IO thread. |
67 static GpuProcessHost *g_gpu_process_hosts[ | 64 GpuProcessHost* g_gpu_process_hosts[GpuProcessHost::GPU_PROCESS_KIND_COUNT]; |
68 GpuProcessHost::GPU_PROCESS_KIND_COUNT]; | |
69 | |
70 // Number of times the gpu process has crashed in the current browser session. | |
71 static int g_gpu_crash_count = 0; | |
72 static int g_gpu_recent_crash_count = 0; | |
73 static double g_last_gpu_crash_time; | |
74 static bool g_crashed_before = false; | |
75 static int g_gpu_software_crash_count = 0; | |
76 | |
77 // Maximum number of times the gpu process is allowed to crash in a session. | |
78 // Once this limit is reached, any request to launch the gpu process will fail. | |
79 static const int kGpuMaxCrashCount = 3; | |
80 | |
81 int g_last_host_id = 0; | |
82 | 65 |
83 #if defined(TOOLKIT_GTK) | 66 #if defined(TOOLKIT_GTK) |
84 | 67 |
85 void ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface) { | 68 void ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface) { |
86 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); | 69 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); |
87 manager->ReleasePermanentXID(surface); | 70 manager->ReleasePermanentXID(surface); |
88 } | 71 } |
89 | 72 |
90 #endif | 73 #endif |
91 | 74 |
(...skipping 22 matching lines...) Expand all Loading... |
114 surface_handle, | 97 surface_handle, |
115 alive)); | 98 alive)); |
116 return; | 99 return; |
117 } | 100 } |
118 | 101 |
119 GpuProcessHost* host = GpuProcessHost::FromID(host_id); | 102 GpuProcessHost* host = GpuProcessHost::FromID(host_id); |
120 if (host) { | 103 if (host) { |
121 if (alive) { | 104 if (alive) { |
122 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | 105 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
123 ack_params.sync_point = 0; | 106 ack_params.sync_point = 0; |
124 host->Send(new AcceleratedSurfaceMsg_BufferPresented( | 107 host->Send( |
125 route_id, ack_params)); | 108 new AcceleratedSurfaceMsg_BufferPresented(route_id, ack_params)); |
126 } else { | 109 } else { |
127 host->ForceShutdown(); | 110 host->ForceShutdown(); |
128 } | 111 } |
129 } | 112 } |
130 } | 113 } |
131 | 114 |
132 #if defined(OS_WIN) | 115 #if defined(OS_WIN) |
133 // This sends a ViewMsg_SwapBuffers_ACK directly to the renderer process | 116 // This sends a ViewMsg_SwapBuffers_ACK directly to the renderer process |
134 // (RenderWidget). This path is currently not used with the threaded compositor. | 117 // (RenderWidget). |
135 void AcceleratedSurfaceBuffersSwappedCompletedForRenderer( | 118 void AcceleratedSurfaceBuffersSwappedCompletedForRenderer( |
136 int surface_id, | 119 int surface_id, |
137 base::TimeTicks timebase, | 120 base::TimeTicks timebase, |
138 base::TimeDelta interval) { | 121 base::TimeDelta interval) { |
139 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 122 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
140 BrowserThread::PostTask( | 123 BrowserThread::PostTask( |
141 BrowserThread::UI, | 124 BrowserThread::UI, |
142 FROM_HERE, | 125 FROM_HERE, |
143 base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForRenderer, | 126 base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForRenderer, |
144 surface_id, timebase, interval)); | 127 surface_id, timebase, interval)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 // with --in-process-gpu or --single-process. | 179 // with --in-process-gpu or --single-process. |
197 class GpuMainThread : public base::Thread { | 180 class GpuMainThread : public base::Thread { |
198 public: | 181 public: |
199 explicit GpuMainThread(const std::string& channel_id) | 182 explicit GpuMainThread(const std::string& channel_id) |
200 : base::Thread("Chrome_InProcGpuThread"), | 183 : base::Thread("Chrome_InProcGpuThread"), |
201 channel_id_(channel_id), | 184 channel_id_(channel_id), |
202 gpu_process_(NULL), | 185 gpu_process_(NULL), |
203 child_thread_(NULL) { | 186 child_thread_(NULL) { |
204 } | 187 } |
205 | 188 |
206 ~GpuMainThread() { | 189 virtual ~GpuMainThread() { |
207 Stop(); | 190 Stop(); |
208 } | 191 } |
209 | 192 |
210 protected: | 193 protected: |
211 virtual void Init() { | 194 virtual void Init() OVERRIDE { |
212 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) { | 195 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) { |
213 child_thread_ = new GpuChildThread(channel_id_); | 196 child_thread_ = new GpuChildThread(channel_id_); |
214 } else { | 197 } else { |
215 gpu_process_ = new GpuProcess(); | 198 gpu_process_ = new GpuProcess(); |
216 // The process object takes ownership of the thread object, so do not | 199 // The process object takes ownership of the thread object, so do not |
217 // save and delete the pointer. | 200 // save and delete the pointer. |
218 gpu_process_->set_main_thread(new GpuChildThread(channel_id_)); | 201 gpu_process_->set_main_thread(new GpuChildThread(channel_id_)); |
219 } | 202 } |
220 } | 203 } |
221 | 204 |
222 virtual void CleanUp() { | 205 virtual void CleanUp() OVERRIDE { |
223 delete gpu_process_; | 206 delete gpu_process_; |
224 if (child_thread_) | 207 if (child_thread_) |
225 delete child_thread_; | 208 delete child_thread_; |
226 } | 209 } |
227 | 210 |
228 private: | 211 private: |
229 std::string channel_id_; | 212 std::string channel_id_; |
230 // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. | 213 // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. |
231 GpuProcess* gpu_process_; | 214 GpuProcess* gpu_process_; |
232 GpuChildThread* child_thread_; | 215 GpuChildThread* child_thread_; |
233 | 216 |
234 DISALLOW_COPY_AND_ASSIGN(GpuMainThread); | 217 DISALLOW_COPY_AND_ASSIGN(GpuMainThread); |
235 }; | 218 }; |
236 | 219 |
237 // static | 220 // static |
238 bool GpuProcessHost::HostIsValid(GpuProcessHost* host) { | 221 bool GpuProcessHost::ValidateHost(GpuProcessHost* host) { |
239 if (!host) | 222 if (!host) |
240 return false; | 223 return false; |
241 | 224 |
242 // The Gpu process is invalid if it's not using software, the card is | 225 // The Gpu process is invalid if it's not using software, the card is |
243 // blacklisted, and we can kill it and start over. | 226 // blacklisted, and we can kill it and start over. |
244 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 227 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
245 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU) || | 228 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU) || |
246 (host->valid_ && | 229 (host->valid_ && |
247 (host->software_rendering() || | 230 (host->software_rendering() || |
248 !GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()))) { | 231 !GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()))) { |
249 return true; | 232 return true; |
250 } | 233 } |
251 | 234 |
252 host->ForceShutdown(); | 235 host->ForceShutdown(); |
253 return false; | 236 return false; |
254 } | 237 } |
255 | 238 |
256 // static | 239 // static |
257 GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, | 240 GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, |
258 CauseForGpuLaunch cause) { | 241 CauseForGpuLaunch cause) { |
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
260 | 243 |
261 // Don't grant further access to GPU if it is not allowed. | 244 // Don't grant further access to GPU if it is not allowed. |
262 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); | 245 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); |
263 DCHECK(gpu_data_manager); | 246 DCHECK(gpu_data_manager); |
264 if (!gpu_data_manager->GpuAccessAllowed()) | 247 if (!gpu_data_manager->GpuAccessAllowed()) |
265 return NULL; | 248 return NULL; |
266 | 249 |
267 if (g_gpu_process_hosts[kind] && HostIsValid(g_gpu_process_hosts[kind])) | 250 if (g_gpu_process_hosts[kind] && ValidateHost(g_gpu_process_hosts[kind])) |
268 return g_gpu_process_hosts[kind]; | 251 return g_gpu_process_hosts[kind]; |
269 | 252 |
270 if (cause == CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) | 253 if (cause == CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
271 return NULL; | 254 return NULL; |
272 | 255 |
| 256 static int last_host_id = 0; |
273 int host_id; | 257 int host_id; |
274 host_id = ++g_last_host_id; | 258 host_id = ++last_host_id; |
275 | 259 |
276 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", | 260 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
277 cause, | 261 cause, |
278 CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); | 262 CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); |
279 | 263 |
280 GpuProcessHost* host = new GpuProcessHost(host_id, kind); | 264 GpuProcessHost* host = new GpuProcessHost(host_id, kind); |
281 if (host->Init()) | 265 if (host->Init()) |
282 return host; | 266 return host; |
283 | 267 |
284 delete host; | 268 delete host; |
285 return NULL; | 269 return NULL; |
286 } | 270 } |
287 | 271 |
288 // static | 272 // static |
289 void GpuProcessHost::GetProcessHandles( | 273 void GpuProcessHost::GetProcessHandles( |
290 const GpuDataManager::GetGpuProcessHandlesCallback& callback) { | 274 const GpuDataManager::GetGpuProcessHandlesCallback& callback) { |
291 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 275 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
292 BrowserThread::PostTask( | 276 BrowserThread::PostTask( |
293 BrowserThread::IO, | 277 BrowserThread::IO, |
294 FROM_HERE, | 278 FROM_HERE, |
295 base::Bind(&GpuProcessHost::GetProcessHandles, callback)); | 279 base::Bind(&GpuProcessHost::GetProcessHandles, callback)); |
296 return; | 280 return; |
297 } | 281 } |
298 std::list<base::ProcessHandle> handles; | 282 std::list<base::ProcessHandle> handles; |
299 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { | 283 for (size_t i = 0; i < arraysize(g_gpu_process_hosts); ++i) { |
300 GpuProcessHost* host = g_gpu_process_hosts[i]; | 284 GpuProcessHost* host = g_gpu_process_hosts[i]; |
301 if (host && HostIsValid(host)) | 285 if (host && ValidateHost(host)) |
302 handles.push_back(host->process_->GetHandle()); | 286 handles.push_back(host->process_->GetHandle()); |
303 } | 287 } |
304 BrowserThread::PostTask( | 288 BrowserThread::PostTask( |
305 BrowserThread::UI, | 289 BrowserThread::UI, |
306 FROM_HERE, | 290 FROM_HERE, |
307 base::Bind(callback, handles)); | 291 base::Bind(callback, handles)); |
308 } | 292 } |
309 | 293 |
310 // static | 294 // static |
311 void GpuProcessHost::SendOnIO(GpuProcessKind kind, | 295 void GpuProcessHost::SendOnIO(GpuProcessKind kind, |
312 CauseForGpuLaunch cause, | 296 CauseForGpuLaunch cause, |
313 IPC::Message* message) { | 297 IPC::Message* message) { |
314 if (!BrowserThread::PostTask( | 298 if (!BrowserThread::PostTask( |
315 BrowserThread::IO, FROM_HERE, | 299 BrowserThread::IO, FROM_HERE, |
316 base::Bind( | 300 base::Bind( |
317 &SendGpuProcessMessage, kind, cause, message))) { | 301 &SendGpuProcessMessage, kind, cause, message))) { |
318 delete message; | 302 delete message; |
319 } | 303 } |
320 } | 304 } |
321 | 305 |
322 // static | 306 // static |
323 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 307 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
325 | 309 |
326 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { | 310 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { |
327 GpuProcessHost* host = g_gpu_process_hosts[i]; | 311 GpuProcessHost* host = g_gpu_process_hosts[i]; |
328 if (host && host->host_id_ == host_id && HostIsValid(host)) | 312 if (host && host->host_id_ == host_id && ValidateHost(host)) |
329 return host; | 313 return host; |
330 } | 314 } |
331 | 315 |
332 return NULL; | 316 return NULL; |
333 } | 317 } |
334 | 318 |
335 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) | 319 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) |
336 : host_id_(host_id), | 320 : host_id_(host_id), |
337 valid_(true), | 321 valid_(true), |
338 in_process_(false), | 322 in_process_(false), |
339 software_rendering_(false), | 323 software_rendering_(false), |
340 kind_(kind), | 324 kind_(kind), |
341 process_launched_(false) { | 325 process_launched_(false) { |
342 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 326 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
343 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) | 327 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) { |
344 in_process_ = true; | 328 in_process_ = true; |
| 329 } |
345 | 330 |
346 // If the 'single GPU process' policy ever changes, we still want to maintain | 331 // If the 'single GPU process' policy ever changes, we still want to maintain |
347 // it for 'gpu thread' mode and only create one instance of host and thread. | 332 // it for 'gpu thread' mode and only create one instance of host and thread. |
348 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); | 333 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); |
349 | 334 |
350 g_gpu_process_hosts[kind] = this; | 335 g_gpu_process_hosts[kind] = this; |
351 | 336 |
352 // Post a task to create the corresponding GpuProcessHostUIShim. The | 337 // Post a task to create the corresponding GpuProcessHostUIShim. The |
353 // GpuProcessHostUIShim will be destroyed if either the browser exits, | 338 // GpuProcessHostUIShim will be destroyed if either the browser exits, |
354 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the | 339 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the |
355 // GpuProcessHost is destroyed, which happens when the corresponding GPU | 340 // GpuProcessHost is destroyed, which happens when the corresponding GPU |
356 // process terminates or fails to launch. | 341 // process terminates or fails to launch. |
357 BrowserThread::PostTask( | 342 BrowserThread::PostTask( |
358 BrowserThread::UI, | 343 BrowserThread::UI, |
359 FROM_HERE, | 344 FROM_HERE, |
360 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); | 345 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); |
361 | 346 |
362 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this)); | 347 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this)); |
363 } | 348 } |
364 | 349 |
365 GpuProcessHost::~GpuProcessHost() { | 350 GpuProcessHost::~GpuProcessHost() { |
366 DCHECK(CalledOnValidThread()); | 351 DCHECK(CalledOnValidThread()); |
367 | 352 |
368 SendOutstandingReplies(); | 353 SendOutstandingReplies(); |
| 354 |
| 355 // Maximum number of times the gpu process is allowed to crash in a session. |
| 356 // Once this limit is reached, any request to launch the gpu process will |
| 357 // fail. |
| 358 const int kGpuMaxCrashCount = 3; |
| 359 |
| 360 // Number of times the gpu process has crashed in the current browser session. |
| 361 static int gpu_crash_count = 0; |
| 362 static int gpu_recent_crash_count = 0; |
| 363 static base::Time last_gpu_crash_time; |
| 364 static bool crashed_before = false; |
| 365 static int gpu_software_crash_count = 0; |
| 366 |
369 // Ending only acts as a failure if the GPU process was actually started and | 367 // Ending only acts as a failure if the GPU process was actually started and |
370 // was intended for actual rendering (and not just checking caps or other | 368 // was intended for actual rendering (and not just checking caps or other |
371 // options). | 369 // options). |
372 if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) { | 370 if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) { |
373 if (software_rendering_) { | 371 if (software_rendering_) { |
374 UMA_HISTOGRAM_ENUMERATION("GPU.SoftwareRendererLifetimeEvents", | 372 UMA_HISTOGRAM_ENUMERATION("GPU.SoftwareRendererLifetimeEvents", |
375 DIED_FIRST_TIME + g_gpu_software_crash_count, | 373 DIED_FIRST_TIME + gpu_software_crash_count, |
376 GPU_PROCESS_LIFETIME_EVENT_MAX); | 374 GPU_PROCESS_LIFETIME_EVENT_MAX); |
377 | 375 |
378 if (++g_gpu_software_crash_count >= kGpuMaxCrashCount) { | 376 if (++gpu_software_crash_count >= kGpuMaxCrashCount) { |
379 // The software renderer is too unstable to use. Disable it for current | 377 // The software renderer is too unstable to use. Disable it for current |
380 // session. | 378 // session. |
381 gpu_enabled_ = false; | 379 gpu_enabled_ = false; |
382 } | 380 } |
383 } else { | 381 } else { |
384 ++g_gpu_crash_count; | 382 ++gpu_crash_count; |
385 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", | 383 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", |
386 std::min(DIED_FIRST_TIME + g_gpu_crash_count, | 384 std::min(DIED_FIRST_TIME + gpu_crash_count, |
387 GPU_PROCESS_LIFETIME_EVENT_MAX - 1), | 385 GPU_PROCESS_LIFETIME_EVENT_MAX - 1), |
388 GPU_PROCESS_LIFETIME_EVENT_MAX); | 386 GPU_PROCESS_LIFETIME_EVENT_MAX); |
389 | 387 |
390 /* | 388 // Allow about 1 GPU crash per hour to be removed from the crash count, |
391 * Allow about 1 GPU crash per hour to be removed from the crash count, | 389 // so very occasional crashes won't eventually add up and prevent the |
392 * so very occasional crashes won't eventually add up and prevent the | 390 // GPU process from launching. |
393 * GPU process from launching. | 391 ++gpu_recent_crash_count; |
394 */ | |
395 ++g_gpu_recent_crash_count; | |
396 base::Time current_time = base::Time::Now(); | 392 base::Time current_time = base::Time::Now(); |
397 if (g_crashed_before) { | 393 if (crashed_before) { |
398 base::Time last_crash_time = | 394 int hours_different = (current_time - last_gpu_crash_time).InHours(); |
399 base::Time::FromDoubleT(g_last_gpu_crash_time); | 395 gpu_recent_crash_count = |
400 int hours_different = (current_time - last_crash_time).InHours(); | 396 std::max(0, gpu_recent_crash_count - hours_different); |
401 g_gpu_recent_crash_count = std::max(0, | |
402 g_gpu_recent_crash_count - hours_different); | |
403 } | 397 } |
404 | 398 |
405 g_crashed_before = true; | 399 crashed_before = true; |
406 g_last_gpu_crash_time = current_time.ToDoubleT(); | 400 last_gpu_crash_time = current_time; |
407 | 401 |
408 if (g_gpu_recent_crash_count >= kGpuMaxCrashCount) { | 402 if (gpu_recent_crash_count >= kGpuMaxCrashCount) { |
409 #if !defined(OS_CHROMEOS) | 403 #if !defined(OS_CHROMEOS) |
410 // The gpu process is too unstable to use. Disable it for current | 404 // The gpu process is too unstable to use. Disable it for current |
411 // session. | 405 // session. |
412 hardware_gpu_enabled_ = false; | 406 hardware_gpu_enabled_ = false; |
413 GpuDataManagerImpl::GetInstance()->BlacklistCard(); | 407 GpuDataManagerImpl::GetInstance()->BlacklistCard(); |
414 #endif | 408 #endif |
415 } | 409 } |
416 } | 410 } |
417 } | 411 } |
418 | 412 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 | 465 |
472 std::string channel_id = process_->GetHost()->CreateChannel(); | 466 std::string channel_id = process_->GetHost()->CreateChannel(); |
473 if (channel_id.empty()) | 467 if (channel_id.empty()) |
474 return false; | 468 return false; |
475 | 469 |
476 if (in_process_) { | 470 if (in_process_) { |
477 CommandLine::ForCurrentProcess()->AppendSwitch( | 471 CommandLine::ForCurrentProcess()->AppendSwitch( |
478 switches::kDisableGpuWatchdog); | 472 switches::kDisableGpuWatchdog); |
479 | 473 |
480 in_process_gpu_thread_.reset(new GpuMainThread(channel_id)); | 474 in_process_gpu_thread_.reset(new GpuMainThread(channel_id)); |
481 | 475 in_process_gpu_thread_->Start(); |
482 base::Thread::Options options; | |
483 #if defined(OS_WIN) | |
484 // On Windows the GPU thread needs to pump the compositor child window's | |
485 // message loop. TODO(apatrick): make this an IO thread if / when we get rid | |
486 // of this child window. Unfortunately it might always be necessary for | |
487 // Windows XP because we cannot share the backing store textures between | |
488 // processes. | |
489 options.message_loop_type = MessageLoop::TYPE_UI; | |
490 #else | |
491 options.message_loop_type = MessageLoop::TYPE_IO; | |
492 #endif | |
493 in_process_gpu_thread_->StartWithOptions(options); | |
494 | 476 |
495 OnProcessLaunched(); // Fake a callback that the process is ready. | 477 OnProcessLaunched(); // Fake a callback that the process is ready. |
496 } else if (!LaunchGpuProcess(channel_id)) { | 478 } else if (!LaunchGpuProcess(channel_id)) { |
497 return false; | 479 return false; |
498 } | 480 } |
499 | 481 |
500 if (!Send(new GpuMsg_Initialize())) | 482 if (!Send(new GpuMsg_Initialize())) |
501 return false; | 483 return false; |
502 | 484 |
503 return Send(new GpuMsg_SetVideoMemoryWindowCount( | 485 return Send(new GpuMsg_SetVideoMemoryWindowCount( |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 | 557 |
576 void GpuProcessHost::EstablishGpuChannel( | 558 void GpuProcessHost::EstablishGpuChannel( |
577 int client_id, | 559 int client_id, |
578 bool share_context, | 560 bool share_context, |
579 const EstablishChannelCallback& callback) { | 561 const EstablishChannelCallback& callback) { |
580 DCHECK(CalledOnValidThread()); | 562 DCHECK(CalledOnValidThread()); |
581 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel"); | 563 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel"); |
582 | 564 |
583 // If GPU features are already blacklisted, no need to establish the channel. | 565 // If GPU features are already blacklisted, no need to establish the channel. |
584 if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) { | 566 if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) { |
585 EstablishChannelError( | 567 callback.Run(IPC::ChannelHandle(), GPUInfo()); |
586 callback, IPC::ChannelHandle(), base::kNullProcessHandle, GPUInfo()); | |
587 return; | 568 return; |
588 } | 569 } |
589 | 570 |
590 if (Send(new GpuMsg_EstablishChannel(client_id, share_context))) { | 571 if (Send(new GpuMsg_EstablishChannel(client_id, share_context))) { |
591 channel_requests_.push(callback); | 572 channel_requests_.push(callback); |
592 } else { | 573 } else { |
593 EstablishChannelError( | 574 callback.Run(IPC::ChannelHandle(), GPUInfo()); |
594 callback, IPC::ChannelHandle(), | |
595 base::kNullProcessHandle, GPUInfo()); | |
596 } | 575 } |
597 } | 576 } |
598 | 577 |
599 void GpuProcessHost::CreateViewCommandBuffer( | 578 void GpuProcessHost::CreateViewCommandBuffer( |
600 const gfx::GLSurfaceHandle& compositing_surface, | 579 const gfx::GLSurfaceHandle& compositing_surface, |
601 int surface_id, | 580 int surface_id, |
602 int client_id, | 581 int client_id, |
603 const GPUCreateCommandBufferConfig& init_params, | 582 const GPUCreateCommandBufferConfig& init_params, |
604 const CreateCommandBufferCallback& callback) { | 583 const CreateCommandBufferCallback& callback) { |
605 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::CreateViewCommandBuffer"); | 584 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::CreateViewCommandBuffer"); |
(...skipping 14 matching lines...) Expand all Loading... |
620 #endif // defined(TOOLKIT_GTK) | 599 #endif // defined(TOOLKIT_GTK) |
621 | 600 |
622 if (!compositing_surface.is_null() && | 601 if (!compositing_surface.is_null() && |
623 Send(new GpuMsg_CreateViewCommandBuffer( | 602 Send(new GpuMsg_CreateViewCommandBuffer( |
624 compositing_surface, surface_id, client_id, init_params))) { | 603 compositing_surface, surface_id, client_id, init_params))) { |
625 create_command_buffer_requests_.push(callback); | 604 create_command_buffer_requests_.push(callback); |
626 #if defined(TOOLKIT_GTK) | 605 #if defined(TOOLKIT_GTK) |
627 surface_refs_.insert(std::make_pair(surface_id, surface_ref)); | 606 surface_refs_.insert(std::make_pair(surface_id, surface_ref)); |
628 #endif | 607 #endif |
629 } else { | 608 } else { |
630 CreateCommandBufferError(callback, MSG_ROUTING_NONE); | 609 callback.Run(MSG_ROUTING_NONE); |
631 } | 610 } |
632 } | 611 } |
633 | 612 |
634 void GpuProcessHost::CreateImage( | 613 void GpuProcessHost::CreateImage(gfx::PluginWindowHandle window, |
635 gfx::PluginWindowHandle window, | 614 int client_id, |
636 int client_id, | 615 int image_id, |
637 int image_id, | 616 const CreateImageCallback& callback) { |
638 const CreateImageCallback& callback) { | |
639 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::CreateImage"); | 617 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::CreateImage"); |
640 | 618 |
641 DCHECK(CalledOnValidThread()); | 619 DCHECK(CalledOnValidThread()); |
642 | 620 |
643 if (Send(new GpuMsg_CreateImage(window, client_id, image_id))) { | 621 if (Send(new GpuMsg_CreateImage(window, client_id, image_id))) { |
644 create_image_requests_.push(callback); | 622 create_image_requests_.push(callback); |
645 } else { | 623 } else { |
646 CreateImageError(callback, gfx::Size()); | 624 callback.Run(gfx::Size()); |
647 } | 625 } |
648 } | 626 } |
649 | 627 |
650 void GpuProcessHost::DeleteImage( | 628 void GpuProcessHost::DeleteImage(int client_id, |
651 int client_id, | 629 int image_id, |
652 int image_id, | 630 int sync_point) { |
653 int sync_point) { | |
654 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::DeleteImage"); | 631 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::DeleteImage"); |
655 | 632 |
656 DCHECK(CalledOnValidThread()); | 633 DCHECK(CalledOnValidThread()); |
657 | 634 |
658 Send(new GpuMsg_DeleteImage(client_id, image_id, sync_point)); | 635 Send(new GpuMsg_DeleteImage(client_id, image_id, sync_point)); |
659 } | 636 } |
660 | 637 |
661 void GpuProcessHost::OnInitialized(bool result) { | 638 void GpuProcessHost::OnInitialized(bool result) { |
662 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", result); | 639 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", result); |
663 } | 640 } |
664 | 641 |
665 void GpuProcessHost::OnChannelEstablished( | 642 void GpuProcessHost::OnChannelEstablished( |
666 const IPC::ChannelHandle& channel_handle) { | 643 const IPC::ChannelHandle& channel_handle) { |
667 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnChannelEstablished"); | 644 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnChannelEstablished"); |
668 | 645 |
669 EstablishChannelCallback callback = channel_requests_.front(); | 646 EstablishChannelCallback callback = channel_requests_.front(); |
670 channel_requests_.pop(); | 647 channel_requests_.pop(); |
671 | 648 |
672 // Currently if any of the GPU features are blacklisted, we don't establish a | 649 // Currently if any of the GPU features are blacklisted, we don't establish a |
673 // GPU channel. | 650 // GPU channel. |
674 if (!channel_handle.name.empty() && | 651 if (!channel_handle.name.empty() && |
675 !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) { | 652 !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) { |
676 Send(new GpuMsg_CloseChannel(channel_handle)); | 653 Send(new GpuMsg_CloseChannel(channel_handle)); |
677 EstablishChannelError(callback, | 654 callback.Run(IPC::ChannelHandle(), GPUInfo()); |
678 IPC::ChannelHandle(), | |
679 base::kNullProcessHandle, | |
680 GPUInfo()); | |
681 RouteOnUIThread(GpuHostMsg_OnLogMessage( | 655 RouteOnUIThread(GpuHostMsg_OnLogMessage( |
682 logging::LOG_WARNING, | 656 logging::LOG_WARNING, |
683 "WARNING", | 657 "WARNING", |
684 "Hardware acceleration is unavailable.")); | 658 "Hardware acceleration is unavailable.")); |
685 return; | 659 return; |
686 } | 660 } |
687 | 661 |
688 callback.Run(channel_handle, | 662 callback.Run(channel_handle, |
689 GpuDataManagerImpl::GetInstance()->GetGPUInfo()); | 663 GpuDataManagerImpl::GetInstance()->GetGPUInfo()); |
690 } | 664 } |
691 | 665 |
692 void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) { | 666 void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) { |
693 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnCommandBufferCreated"); | 667 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnCommandBufferCreated"); |
694 | 668 |
695 if (!create_command_buffer_requests_.empty()) { | 669 if (create_command_buffer_requests_.empty()) |
696 CreateCommandBufferCallback callback = | 670 return; |
697 create_command_buffer_requests_.front(); | 671 |
698 create_command_buffer_requests_.pop(); | 672 CreateCommandBufferCallback callback = |
699 if (route_id == MSG_ROUTING_NONE) | 673 create_command_buffer_requests_.front(); |
700 CreateCommandBufferError(callback, route_id); | 674 create_command_buffer_requests_.pop(); |
701 else | 675 callback.Run(route_id); |
702 callback.Run(route_id); | |
703 } | |
704 } | 676 } |
705 | 677 |
706 void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) { | 678 void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) { |
707 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnDestroyCommandBuffer"); | 679 TRACE_EVENT0("gpu", "GpuProcessHostUIShim::OnDestroyCommandBuffer"); |
708 | 680 |
709 #if defined(TOOLKIT_GTK) | 681 #if defined(TOOLKIT_GTK) |
710 SurfaceRefMap::iterator it = surface_refs_.find(surface_id); | 682 SurfaceRefMap::iterator it = surface_refs_.find(surface_id); |
711 if (it != surface_refs_.end()) | 683 if (it != surface_refs_.end()) |
712 surface_refs_.erase(it); | 684 surface_refs_.erase(it); |
713 #endif // defined(TOOLKIT_GTK) | 685 #endif // defined(TOOLKIT_GTK) |
714 } | 686 } |
715 | 687 |
716 void GpuProcessHost::OnImageCreated(const gfx::Size size) { | 688 void GpuProcessHost::OnImageCreated(const gfx::Size size) { |
717 TRACE_EVENT0("gpu", "GpuProcessHost::OnImageCreated"); | 689 TRACE_EVENT0("gpu", "GpuProcessHost::OnImageCreated"); |
718 | 690 |
719 if (!create_image_requests_.empty()) { | 691 if (!create_image_requests_.empty()) |
720 CreateImageCallback callback = create_image_requests_.front(); | 692 return; |
721 create_image_requests_.pop(); | 693 |
722 callback.Run(size); | 694 CreateImageCallback callback = create_image_requests_.front(); |
723 } | 695 create_image_requests_.pop(); |
| 696 callback.Run(size); |
724 } | 697 } |
725 | 698 |
726 void GpuProcessHost::OnDidCreateOffscreenContext( | 699 void GpuProcessHost::OnDidCreateOffscreenContext(const GURL& url) { |
727 const GURL& url) { | |
728 urls_with_live_offscreen_contexts_.insert(url); | 700 urls_with_live_offscreen_contexts_.insert(url); |
729 } | 701 } |
730 | 702 |
731 void GpuProcessHost::OnDidLoseContext(bool offscreen, | 703 void GpuProcessHost::OnDidLoseContext(bool offscreen, |
732 gpu::error::ContextLostReason reason, | 704 gpu::error::ContextLostReason reason, |
733 const GURL& url) { | 705 const GURL& url) { |
734 // TODO(kbr): would be nice to see the "offscreen" flag too. | 706 // TODO(kbr): would be nice to see the "offscreen" flag too. |
735 TRACE_EVENT2("gpu", "GpuProcessHost::OnDidLoseContext", | 707 TRACE_EVENT2("gpu", "GpuProcessHost::OnDidLoseContext", |
736 "reason", reason, | 708 "reason", reason, |
737 "url", | 709 "url", |
738 url.possibly_invalid_spec()); | 710 url.possibly_invalid_spec()); |
739 | 711 |
740 if (!offscreen || url.is_empty()) { | 712 if (!offscreen || url.is_empty()) { |
741 // Assume that the loss of the compositor's or accelerated canvas' | 713 // Assume that the loss of the compositor's or accelerated canvas' |
742 // context is a serious event and blame the loss on all live | 714 // context is a serious event and blame the loss on all live |
743 // offscreen contexts. This more robustly handles situations where | 715 // offscreen contexts. This more robustly handles situations where |
744 // the GPU process may not actually detect the context loss in the | 716 // the GPU process may not actually detect the context loss in the |
745 // offscreen context. | 717 // offscreen context. |
746 BlockLiveOffscreenContexts(); | 718 BlockLiveOffscreenContexts(); |
747 return; | 719 return; |
748 } | 720 } |
749 | 721 |
750 // Initialization only needed because compiler is stupid. | 722 GpuDataManagerImpl::DomainGuilt guilt; |
751 GpuDataManagerImpl::DomainGuilt guilt = | |
752 GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN; | |
753 | |
754 switch (reason) { | 723 switch (reason) { |
755 case gpu::error::kGuilty: | 724 case gpu::error::kGuilty: |
756 guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN; | 725 guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN; |
757 break; | 726 break; |
758 case gpu::error::kUnknown: | 727 case gpu::error::kUnknown: |
759 guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN; | 728 guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN; |
760 break; | 729 break; |
761 case gpu::error::kInnocent: | 730 case gpu::error::kInnocent: |
762 return; | 731 return; |
| 732 default: |
| 733 NOTREACHED(); |
| 734 return; |
763 } | 735 } |
764 | 736 |
765 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs( | 737 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(url, guilt); |
766 url, guilt); | |
767 } | 738 } |
768 | 739 |
769 void GpuProcessHost::OnDidDestroyOffscreenContext( | 740 void GpuProcessHost::OnDidDestroyOffscreenContext(const GURL& url) { |
770 const GURL& url) { | |
771 urls_with_live_offscreen_contexts_.erase(url); | 741 urls_with_live_offscreen_contexts_.erase(url); |
772 } | 742 } |
773 | 743 |
774 void GpuProcessHost::OnGpuMemoryUmaStatsReceived( | 744 void GpuProcessHost::OnGpuMemoryUmaStatsReceived( |
775 const GPUMemoryUmaStats& stats) { | 745 const GPUMemoryUmaStats& stats) { |
776 TRACE_EVENT0("gpu", "GpuProcessHost::OnGpuMemoryUmaStatsReceived"); | 746 TRACE_EVENT0("gpu", "GpuProcessHost::OnGpuMemoryUmaStatsReceived"); |
777 uma_memory_stats_ = stats; | 747 uma_memory_stats_ = stats; |
778 } | 748 } |
779 | 749 |
780 #if defined(OS_MACOSX) | 750 #if defined(OS_MACOSX) |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 | 950 |
981 CommandLine* cmd_line = new CommandLine(exe_path); | 951 CommandLine* cmd_line = new CommandLine(exe_path); |
982 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 952 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
983 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 953 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
984 | 954 |
985 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) | 955 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) |
986 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); | 956 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); |
987 | 957 |
988 // Propagate relevant command line switches. | 958 // Propagate relevant command line switches. |
989 static const char* const kSwitchNames[] = { | 959 static const char* const kSwitchNames[] = { |
| 960 switches::kCrashOnGpuHang, |
| 961 switches::kDisableAcceleratedVideoDecode, |
990 switches::kDisableBreakpad, | 962 switches::kDisableBreakpad, |
991 switches::kDisableGLMultisampling, | 963 switches::kDisableGLMultisampling, |
992 switches::kDisableGpuSandbox, | 964 switches::kDisableGpuSandbox, |
993 switches::kReduceGpuSandbox, | |
994 switches::kDisableSeccompFilterSandbox, | |
995 switches::kEnableGpuSandbox, | |
996 switches::kDisableGpuVsync, | 965 switches::kDisableGpuVsync, |
997 switches::kDisableGpuWatchdog, | 966 switches::kDisableGpuWatchdog, |
998 switches::kDisableImageTransportSurface, | 967 switches::kDisableImageTransportSurface, |
999 switches::kDisableAcceleratedVideoDecode, | |
1000 switches::kDisableLogging, | 968 switches::kDisableLogging, |
| 969 switches::kDisableSeccompFilterSandbox, |
| 970 switches::kEnableGpuSandbox, |
1001 switches::kEnableGPUServiceLogging, | 971 switches::kEnableGPUServiceLogging, |
1002 switches::kEnableLogging, | 972 switches::kEnableLogging, |
1003 #if defined(OS_MACOSX) | 973 switches::kEnableUIReleaseFrontSurface, |
1004 switches::kEnableSandboxLogging, | 974 switches::kEnableVirtualGLContexts, |
1005 #endif | |
1006 switches::kGpuNoContextLost, | 975 switches::kGpuNoContextLost, |
1007 switches::kGpuStartupDialog, | 976 switches::kGpuStartupDialog, |
1008 switches::kGpuSwitching, | 977 switches::kGpuSwitching, |
1009 switches::kLoggingLevel, | 978 switches::kLoggingLevel, |
1010 switches::kNoSandbox, | 979 switches::kNoSandbox, |
| 980 switches::kReduceGpuSandbox, |
1011 switches::kTestGLLib, | 981 switches::kTestGLLib, |
1012 switches::kTraceStartup, | 982 switches::kTraceStartup, |
1013 switches::kV, | 983 switches::kV, |
1014 switches::kVModule, | 984 switches::kVModule, |
1015 switches::kEnableUIReleaseFrontSurface, | 985 #if defined(OS_MACOSX) |
| 986 switches::kEnableSandboxLogging, |
| 987 #endif |
1016 #if defined(USE_AURA) | 988 #if defined(USE_AURA) |
1017 switches::kUIPrioritizeInGpuProcess, | 989 switches::kUIPrioritizeInGpuProcess, |
1018 #endif | 990 #endif |
1019 switches::kCrashOnGpuHang, | |
1020 switches::kEnableVirtualGLContexts, | |
1021 }; | 991 }; |
1022 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, | 992 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, |
1023 arraysize(kSwitchNames)); | 993 arraysize(kSwitchNames)); |
1024 cmd_line->CopySwitchesFrom( | 994 cmd_line->CopySwitchesFrom( |
1025 browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches); | 995 browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches); |
1026 | 996 |
1027 GetContentClient()->browser()->AppendExtraCommandLineSwitches( | 997 GetContentClient()->browser()->AppendExtraCommandLineSwitches( |
1028 cmd_line, process_->GetData().id); | 998 cmd_line, process_->GetData().id); |
1029 | 999 |
1030 GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line); | 1000 GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line); |
1031 | 1001 |
1032 if (cmd_line->HasSwitch(switches::kUseGL)) | 1002 if (cmd_line->HasSwitch(switches::kUseGL)) { |
1033 software_rendering_ = | 1003 software_rendering_ = |
1034 (cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); | 1004 (cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); |
| 1005 } |
1035 | 1006 |
1036 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessSoftwareRendering", software_rendering_); | 1007 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessSoftwareRendering", software_rendering_); |
1037 | 1008 |
1038 #if defined(OS_WIN) | 1009 #if defined(OS_WIN) |
1039 // Make GoogleDesktopNetwork3.dll think that this is a renderer process so | 1010 // Make GoogleDesktopNetwork3.dll think that the GPU process is a renderer |
1040 // it unloads itself. http://crbug/129884 | 1011 // process so the DLL unloads itself. http://crbug/129884 |
1041 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); | 1012 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); |
1042 #endif | 1013 #endif |
1043 | 1014 |
1044 // If specified, prepend a launcher program to the command line. | 1015 // If specified, prepend a launcher program to the command line. |
1045 if (!gpu_launcher.empty()) | 1016 if (!gpu_launcher.empty()) |
1046 cmd_line->PrependWrapper(gpu_launcher); | 1017 cmd_line->PrependWrapper(gpu_launcher); |
1047 | 1018 |
1048 process_->Launch( | 1019 process_->Launch( |
1049 #if defined(OS_WIN) | 1020 #if defined(OS_WIN) |
1050 FilePath(), | 1021 FilePath(), |
1051 #elif defined(OS_POSIX) | 1022 #elif defined(OS_POSIX) |
1052 false, // Never use the zygote (GPU plugin can't be sandboxed). | 1023 false, |
1053 base::EnvironmentVector(), | 1024 base::EnvironmentVector(), |
1054 #endif | 1025 #endif |
1055 cmd_line); | 1026 cmd_line); |
1056 process_launched_ = true; | 1027 process_launched_ = true; |
1057 | 1028 |
1058 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", | 1029 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", |
1059 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX); | 1030 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX); |
1060 return true; | 1031 return true; |
1061 } | 1032 } |
1062 | 1033 |
1063 void GpuProcessHost::SendOutstandingReplies() { | 1034 void GpuProcessHost::SendOutstandingReplies() { |
1064 // First send empty channel handles for all EstablishChannel requests. | 1035 // First send empty channel handles for all EstablishChannel requests. |
1065 while (!channel_requests_.empty()) { | 1036 while (!channel_requests_.empty()) { |
1066 EstablishChannelCallback callback = channel_requests_.front(); | 1037 EstablishChannelCallback callback = channel_requests_.front(); |
1067 channel_requests_.pop(); | 1038 channel_requests_.pop(); |
1068 EstablishChannelError(callback, | 1039 callback.Run(IPC::ChannelHandle(), GPUInfo()); |
1069 IPC::ChannelHandle(), | |
1070 base::kNullProcessHandle, | |
1071 GPUInfo()); | |
1072 } | 1040 } |
1073 } | 1041 } |
1074 | 1042 |
1075 void GpuProcessHost::EstablishChannelError( | |
1076 const EstablishChannelCallback& callback, | |
1077 const IPC::ChannelHandle& channel_handle, | |
1078 base::ProcessHandle renderer_process_for_gpu, | |
1079 const GPUInfo& gpu_info) { | |
1080 callback.Run(channel_handle, gpu_info); | |
1081 } | |
1082 | |
1083 void GpuProcessHost::CreateCommandBufferError( | |
1084 const CreateCommandBufferCallback& callback, int32 route_id) { | |
1085 callback.Run(route_id); | |
1086 } | |
1087 | |
1088 void GpuProcessHost::CreateImageError( | |
1089 const CreateImageCallback& callback, const gfx::Size size) { | |
1090 callback.Run(size); | |
1091 } | |
1092 | |
1093 void GpuProcessHost::BlockLiveOffscreenContexts() { | 1043 void GpuProcessHost::BlockLiveOffscreenContexts() { |
1094 for (std::multiset<GURL>::iterator iter = | 1044 for (std::multiset<GURL>::iterator iter = |
1095 urls_with_live_offscreen_contexts_.begin(); | 1045 urls_with_live_offscreen_contexts_.begin(); |
1096 iter != urls_with_live_offscreen_contexts_.end(); ++iter) { | 1046 iter != urls_with_live_offscreen_contexts_.end(); ++iter) { |
1097 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs( | 1047 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs( |
1098 *iter, GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN); | 1048 *iter, GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN); |
1099 } | 1049 } |
1100 } | 1050 } |
1101 | 1051 |
1102 } // namespace content | 1052 } // namespace content |
OLD | NEW |