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/lazy_instance.h" |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 | 162 |
163 private: | 163 private: |
164 std::string channel_id_; | 164 std::string channel_id_; |
165 // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. | 165 // Deleted in CleanUp() on the gpu thread, so don't use smart pointers. |
166 GpuProcess* gpu_process_; | 166 GpuProcess* gpu_process_; |
167 GpuChildThread* child_thread_; | 167 GpuChildThread* child_thread_; |
168 | 168 |
169 DISALLOW_COPY_AND_ASSIGN(GpuMainThread); | 169 DISALLOW_COPY_AND_ASSIGN(GpuMainThread); |
170 }; | 170 }; |
171 | 171 |
172 static bool HostIsValid(int host_id, GpuProcessHost* host) { | |
173 if (!host) | |
174 return false; | |
175 | |
176 // The Gpu process is invalid if it's not using software, the card is | |
177 // blacklisted, and we can kill it and start over. | |
178 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | |
179 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU) || | |
180 host->IsSoftwareRendering() || | |
181 !GpuDataManager::GetInstance()->IsSoftwareRendering()) { | |
182 return true; | |
183 } | |
184 | |
185 host->Send(new GpuMsg_Crash()); | |
186 g_hosts_by_id.Pointer()->Remove(host_id); | |
187 return false; | |
188 } | |
189 | |
172 // static | 190 // static |
173 GpuProcessHost* GpuProcessHost::GetForRenderer( | 191 GpuProcessHost* GpuProcessHost::GetForRenderer( |
174 int renderer_id, content::CauseForGpuLaunch cause) { | 192 int renderer_id, content::CauseForGpuLaunch cause) { |
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
176 | 194 |
177 // Don't grant further access to GPU if it is not allowed. | 195 // Don't grant further access to GPU if it is not allowed. |
178 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance(); | 196 GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance(); |
179 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) | 197 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) |
180 return NULL; | 198 return NULL; |
181 | 199 |
182 // The current policy is to ignore the renderer ID and use a single GPU | 200 // The current policy is to ignore the renderer ID and use a single GPU |
183 // process for all renderers. Later this will be extended to allow the | 201 // process for all renderers. Later this will be extended to allow the |
184 // use of multiple GPU processes. | 202 // use of multiple GPU processes. |
185 if (!g_hosts_by_id.Pointer()->IsEmpty()) { | 203 if (!g_hosts_by_id.Pointer()->IsEmpty()) { |
186 IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); | 204 IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); |
187 return it.GetCurrentValue(); | 205 GpuProcessHost *host = it.GetCurrentValue(); |
206 | |
207 if (HostIsValid(it.GetCurrentKey(), host)) | |
208 return host; | |
188 } | 209 } |
189 | 210 |
190 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) | 211 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
191 return NULL; | 212 return NULL; |
192 | 213 |
193 int host_id; | 214 int host_id; |
194 host_id = ++g_last_host_id; | 215 host_id = ++g_last_host_id; |
195 | 216 |
196 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", | 217 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
197 cause, | 218 cause, |
(...skipping 17 matching lines...) Expand all Loading... | |
215 &SendGpuProcessMessage, renderer_id, cause, message)); | 236 &SendGpuProcessMessage, renderer_id, cause, message)); |
216 } | 237 } |
217 | 238 |
218 // static | 239 // static |
219 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 240 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
221 | 242 |
222 if (host_id == 0) | 243 if (host_id == 0) |
223 return NULL; | 244 return NULL; |
224 | 245 |
225 return g_hosts_by_id.Pointer()->Lookup(host_id); | 246 GpuProcessHost *host = g_hosts_by_id.Pointer()->Lookup(host_id); |
247 if (HostIsValid(host_id, host)) | |
248 return host; | |
249 | |
250 return NULL; | |
226 } | 251 } |
227 | 252 |
228 GpuProcessHost::GpuProcessHost(int host_id) | 253 GpuProcessHost::GpuProcessHost(int host_id) |
229 : BrowserChildProcessHost(GPU_PROCESS), | 254 : BrowserChildProcessHost(GPU_PROCESS), |
230 host_id_(host_id), | 255 host_id_(host_id), |
231 gpu_process_(base::kNullProcessHandle), | 256 gpu_process_(base::kNullProcessHandle), |
232 in_process_(false) { | 257 in_process_(false), |
258 software_rendering_(false) { | |
233 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 259 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
234 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) | 260 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) |
235 in_process_ = true; | 261 in_process_ = true; |
236 | 262 |
237 // If the 'single GPU process' policy ever changes, we still want to maintain | 263 // If the 'single GPU process' policy ever changes, we still want to maintain |
238 // it for 'gpu thread' mode and only create one instance of host and thread. | 264 // it for 'gpu thread' mode and only create one instance of host and thread. |
239 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); | 265 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); |
240 | 266 |
241 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); | 267 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); |
242 | 268 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 | 535 |
510 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 536 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
511 SendOutstandingReplies(); | 537 SendOutstandingReplies(); |
512 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { | 538 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { |
513 // The gpu process is too unstable to use. Disable it for current session. | 539 // The gpu process is too unstable to use. Disable it for current session. |
514 gpu_enabled_ = false; | 540 gpu_enabled_ = false; |
515 } | 541 } |
516 BrowserChildProcessHost::OnProcessCrashed(exit_code); | 542 BrowserChildProcessHost::OnProcessCrashed(exit_code); |
517 } | 543 } |
518 | 544 |
545 bool GpuProcessHost::IsSoftwareRendering() { | |
546 return software_rendering_; | |
547 } | |
548 | |
519 bool GpuProcessHost::LaunchGpuProcess() { | 549 bool GpuProcessHost::LaunchGpuProcess() { |
520 if (!gpu_enabled_ || g_gpu_crash_count >= kGpuMaxCrashCount) { | 550 if (!gpu_enabled_ || g_gpu_crash_count >= kGpuMaxCrashCount) { |
521 SendOutstandingReplies(); | 551 SendOutstandingReplies(); |
522 gpu_enabled_ = false; | 552 gpu_enabled_ = false; |
523 return false; | 553 return false; |
524 } | 554 } |
525 | 555 |
526 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 556 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
527 | 557 |
528 CommandLine::StringType gpu_launcher = | 558 CommandLine::StringType gpu_launcher = |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 arraysize(kSwitchNames)); | 596 arraysize(kSwitchNames)); |
567 | 597 |
568 // If --ignore-gpu-blacklist is passed in, don't send in crash reports | 598 // If --ignore-gpu-blacklist is passed in, don't send in crash reports |
569 // because GPU is expected to be unreliable. | 599 // because GPU is expected to be unreliable. |
570 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) && | 600 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) && |
571 !cmd_line->HasSwitch(switches::kDisableBreakpad)) | 601 !cmd_line->HasSwitch(switches::kDisableBreakpad)) |
572 cmd_line->AppendSwitch(switches::kDisableBreakpad); | 602 cmd_line->AppendSwitch(switches::kDisableBreakpad); |
573 | 603 |
574 GpuDataManager::GetInstance()->AppendGpuCommandLine(cmd_line); | 604 GpuDataManager::GetInstance()->AppendGpuCommandLine(cmd_line); |
575 | 605 |
606 if (cmd_line->HasSwitch(switches::kUseGL)) | |
607 software_rendering_ = | |
Zhenyao Mo
2011/11/05 00:39:19
I feel like this logic should be in GpuDataManager
jbauman
2011/11/05 00:49:34
This is per-host, so we can check whether the gpu
Zhenyao Mo
2011/11/05 01:03:58
understood. then you also need to make the access
| |
608 (cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); | |
609 | |
576 // If specified, prepend a launcher program to the command line. | 610 // If specified, prepend a launcher program to the command line. |
577 if (!gpu_launcher.empty()) | 611 if (!gpu_launcher.empty()) |
578 cmd_line->PrependWrapper(gpu_launcher); | 612 cmd_line->PrependWrapper(gpu_launcher); |
579 | 613 |
580 Launch( | 614 Launch( |
581 #if defined(OS_WIN) | 615 #if defined(OS_WIN) |
582 FilePath(), | 616 FilePath(), |
583 #elif defined(OS_POSIX) | 617 #elif defined(OS_POSIX) |
584 false, // Never use the zygote (GPU plugin can't be sandboxed). | 618 false, // Never use the zygote (GPU plugin can't be sandboxed). |
585 base::environment_vector(), | 619 base::environment_vector(), |
(...skipping 25 matching lines...) Expand all Loading... | |
611 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); | 645 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); |
612 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); | 646 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); |
613 } | 647 } |
614 | 648 |
615 void GpuProcessHost::CreateCommandBufferError( | 649 void GpuProcessHost::CreateCommandBufferError( |
616 CreateCommandBufferCallback* callback, int32 route_id) { | 650 CreateCommandBufferCallback* callback, int32 route_id) { |
617 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> | 651 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> |
618 wrapped_callback(callback); | 652 wrapped_callback(callback); |
619 callback->Run(route_id); | 653 callback->Run(route_id); |
620 } | 654 } |
OLD | NEW |