| 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 |