OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/lazy_instance.h" |
10 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
12 #include "base/process_util.h" | 13 #include "base/process_util.h" |
13 #include "base/string_piece.h" | 14 #include "base/string_piece.h" |
14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
15 #include "content/browser/browser_thread.h" | 16 #include "content/browser/browser_thread.h" |
16 #include "content/browser/gpu/gpu_data_manager.h" | 17 #include "content/browser/gpu/gpu_data_manager.h" |
17 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 18 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
18 #include "content/browser/renderer_host/render_widget_host.h" | 19 #include "content/browser/renderer_host/render_widget_host.h" |
19 #include "content/browser/renderer_host/render_widget_host_view.h" | 20 #include "content/browser/renderer_host/render_widget_host_view.h" |
(...skipping 19 matching lines...) Expand all Loading... |
39 enum GPUProcessLifetimeEvent { | 40 enum GPUProcessLifetimeEvent { |
40 LAUNCHED, | 41 LAUNCHED, |
41 DIED_FIRST_TIME, | 42 DIED_FIRST_TIME, |
42 DIED_SECOND_TIME, | 43 DIED_SECOND_TIME, |
43 DIED_THIRD_TIME, | 44 DIED_THIRD_TIME, |
44 DIED_FOURTH_TIME, | 45 DIED_FOURTH_TIME, |
45 GPU_PROCESS_LIFETIME_EVENT_MAX | 46 GPU_PROCESS_LIFETIME_EVENT_MAX |
46 }; | 47 }; |
47 | 48 |
48 // A global map from GPU process host ID to GpuProcessHost. | 49 // A global map from GPU process host ID to GpuProcessHost. |
49 static IDMap<GpuProcessHost> g_hosts_by_id; | 50 static base::LazyInstance<IDMap<GpuProcessHost> > g_hosts_by_id( |
| 51 base::LINKER_INITIALIZED); |
50 | 52 |
51 // Number of times the gpu process has crashed in the current browser session. | 53 // Number of times the gpu process has crashed in the current browser session. |
52 static int g_gpu_crash_count = 0; | 54 static int g_gpu_crash_count = 0; |
53 | 55 |
54 // Maximum number of times the gpu process is allowed to crash in a session. | 56 // Maximum number of times the gpu process is allowed to crash in a session. |
55 // Once this limit is reached, any request to launch the gpu process will fail. | 57 // Once this limit is reached, any request to launch the gpu process will fail. |
56 static const int kGpuMaxCrashCount = 3; | 58 static const int kGpuMaxCrashCount = 3; |
57 | 59 |
58 int g_last_host_id = 0; | 60 int g_last_host_id = 0; |
59 | 61 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
172 | 174 |
173 // Don't grant further access to GPU if it is not allowed. | 175 // Don't grant further access to GPU if it is not allowed. |
174 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance(); | 176 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance(); |
175 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) | 177 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) |
176 return NULL; | 178 return NULL; |
177 | 179 |
178 // The current policy is to ignore the renderer ID and use a single GPU | 180 // The current policy is to ignore the renderer ID and use a single GPU |
179 // process for all renderers. Later this will be extended to allow the | 181 // process for all renderers. Later this will be extended to allow the |
180 // use of multiple GPU processes. | 182 // use of multiple GPU processes. |
181 if (!g_hosts_by_id.IsEmpty()) { | 183 if (!g_hosts_by_id.Pointer()->IsEmpty()) { |
182 IDMap<GpuProcessHost>::iterator it(&g_hosts_by_id); | 184 IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); |
183 return it.GetCurrentValue(); | 185 return it.GetCurrentValue(); |
184 } | 186 } |
185 | 187 |
186 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) | 188 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
187 return NULL; | 189 return NULL; |
188 | 190 |
189 int host_id; | 191 int host_id; |
190 host_id = ++g_last_host_id; | 192 host_id = ++g_last_host_id; |
191 | 193 |
192 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", | 194 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
(...skipping 18 matching lines...) Expand all Loading... |
211 &SendGpuProcessMessage, renderer_id, cause, message)); | 213 &SendGpuProcessMessage, renderer_id, cause, message)); |
212 } | 214 } |
213 | 215 |
214 // static | 216 // static |
215 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 217 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
217 | 219 |
218 if (host_id == 0) | 220 if (host_id == 0) |
219 return NULL; | 221 return NULL; |
220 | 222 |
221 return g_hosts_by_id.Lookup(host_id); | 223 return g_hosts_by_id.Pointer()->Lookup(host_id); |
222 } | 224 } |
223 | 225 |
224 GpuProcessHost::GpuProcessHost(int host_id) | 226 GpuProcessHost::GpuProcessHost(int host_id) |
225 : BrowserChildProcessHost(GPU_PROCESS), | 227 : BrowserChildProcessHost(GPU_PROCESS), |
226 host_id_(host_id), | 228 host_id_(host_id), |
227 gpu_process_(base::kNullProcessHandle), | 229 gpu_process_(base::kNullProcessHandle), |
228 in_process_(false) { | 230 in_process_(false) { |
229 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 231 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
230 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) | 232 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) |
231 in_process_ = true; | 233 in_process_ = true; |
232 | 234 |
233 // If the 'single GPU process' policy ever changes, we still want to maintain | 235 // If the 'single GPU process' policy ever changes, we still want to maintain |
234 // it for 'gpu thread' mode and only create one instance of host and thread. | 236 // it for 'gpu thread' mode and only create one instance of host and thread. |
235 DCHECK(!in_process_ || g_hosts_by_id.IsEmpty()); | 237 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); |
236 | 238 |
237 g_hosts_by_id.AddWithID(this, host_id_); | 239 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); |
238 | 240 |
239 // Post a task to create the corresponding GpuProcessHostUIShim. The | 241 // Post a task to create the corresponding GpuProcessHostUIShim. The |
240 // GpuProcessHostUIShim will be destroyed if either the browser exits, | 242 // GpuProcessHostUIShim will be destroyed if either the browser exits, |
241 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the | 243 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the |
242 // GpuProcessHost is destroyed, which happens when the corresponding GPU | 244 // GpuProcessHost is destroyed, which happens when the corresponding GPU |
243 // process terminates or fails to launch. | 245 // process terminates or fails to launch. |
244 BrowserThread::PostTask( | 246 BrowserThread::PostTask( |
245 BrowserThread::UI, | 247 BrowserThread::UI, |
246 FROM_HERE, | 248 FROM_HERE, |
247 NewRunnableFunction(&GpuProcessHostUIShim::Create, host_id)); | 249 NewRunnableFunction(&GpuProcessHostUIShim::Create, host_id)); |
248 } | 250 } |
249 | 251 |
250 GpuProcessHost::~GpuProcessHost() { | 252 GpuProcessHost::~GpuProcessHost() { |
251 DCHECK(CalledOnValidThread()); | 253 DCHECK(CalledOnValidThread()); |
252 #if defined(OS_WIN) | 254 #if defined(OS_WIN) |
253 if (gpu_process_) | 255 if (gpu_process_) |
254 CloseHandle(gpu_process_); | 256 CloseHandle(gpu_process_); |
255 #endif | 257 #endif |
256 | 258 |
257 // In case we never started, clean up. | 259 // In case we never started, clean up. |
258 while (!queued_messages_.empty()) { | 260 while (!queued_messages_.empty()) { |
259 delete queued_messages_.front(); | 261 delete queued_messages_.front(); |
260 queued_messages_.pop(); | 262 queued_messages_.pop(); |
261 } | 263 } |
262 | 264 |
263 g_hosts_by_id.Remove(host_id_); | 265 g_hosts_by_id.Pointer()->Remove(host_id_); |
264 | 266 |
265 BrowserThread::PostTask(BrowserThread::UI, | 267 BrowserThread::PostTask(BrowserThread::UI, |
266 FROM_HERE, | 268 FROM_HERE, |
267 NewRunnableFunction(GpuProcessHostUIShim::Destroy, | 269 NewRunnableFunction(GpuProcessHostUIShim::Destroy, |
268 host_id_)); | 270 host_id_)); |
269 } | 271 } |
270 | 272 |
271 bool GpuProcessHost::Init() { | 273 bool GpuProcessHost::Init() { |
272 if (!CreateChannel()) | 274 if (!CreateChannel()) |
273 return false; | 275 return false; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); | 606 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); |
605 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); | 607 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); |
606 } | 608 } |
607 | 609 |
608 void GpuProcessHost::CreateCommandBufferError( | 610 void GpuProcessHost::CreateCommandBufferError( |
609 CreateCommandBufferCallback* callback, int32 route_id) { | 611 CreateCommandBufferCallback* callback, int32 route_id) { |
610 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> | 612 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> |
611 wrapped_callback(callback); | 613 wrapped_callback(callback); |
612 callback->Run(route_id); | 614 callback->Run(route_id); |
613 } | 615 } |
OLD | NEW |