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" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 | 72 |
73 #if defined(TOOLKIT_USES_GTK) | 73 #if defined(TOOLKIT_USES_GTK) |
74 | 74 |
75 void ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface) { | 75 void ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface) { |
76 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); | 76 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); |
77 manager->ReleasePermanentXID(surface); | 77 manager->ReleasePermanentXID(surface); |
78 } | 78 } |
79 | 79 |
80 #endif | 80 #endif |
81 | 81 |
82 void SendGpuProcessMessage(int client_id, | 82 void SendGpuProcessMessage(GpuProcessHost::GpuProcessKind kind, |
83 content::CauseForGpuLaunch cause, | 83 content::CauseForGpuLaunch cause, |
84 IPC::Message* message) { | 84 IPC::Message* message) { |
85 GpuProcessHost* host = GpuProcessHost::GetForClient(client_id, cause); | 85 GpuProcessHost* host = GpuProcessHost::Get(kind, cause); |
86 if (host) { | 86 if (host) { |
87 host->Send(message); | 87 host->Send(message); |
88 } else { | 88 } else { |
89 delete message; | 89 delete message; |
90 } | 90 } |
91 } | 91 } |
92 | 92 |
93 } // anonymous namespace | 93 } // anonymous namespace |
94 | 94 |
95 #if defined(TOOLKIT_USES_GTK) | 95 #if defined(TOOLKIT_USES_GTK) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 host->software_rendering() || | 180 host->software_rendering() || |
181 !GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) { | 181 !GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) { |
182 return true; | 182 return true; |
183 } | 183 } |
184 | 184 |
185 host->ForceShutdown(); | 185 host->ForceShutdown(); |
186 return false; | 186 return false; |
187 } | 187 } |
188 | 188 |
189 // static | 189 // static |
190 GpuProcessHost* GpuProcessHost::GetForClient( | 190 GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, |
191 int client_id, content::CauseForGpuLaunch cause) { | 191 content::CauseForGpuLaunch cause) { |
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
193 | 193 |
194 // Don't grant further access to GPU if it is not allowed. | 194 // Don't grant further access to GPU if it is not allowed. |
195 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); | 195 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); |
196 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) | 196 if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed()) |
197 return NULL; | 197 return NULL; |
198 | 198 |
199 // The current policy is to ignore the renderer ID and use a single GPU | |
200 // process (the first valid host in the host-id map) for all renderers. Later | |
201 // this will be extended to allow the use of multiple GPU processes. | |
202 for (IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); | 199 for (IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); |
Ami GONE FROM CHROMIUM
2012/03/01 03:21:03
Add a TODO to clean this up? (with a flame-thrower
| |
203 !it.IsAtEnd(); it.Advance()) { | 200 !it.IsAtEnd(); it.Advance()) { |
204 GpuProcessHost* host = it.GetCurrentValue(); | 201 GpuProcessHost* host = it.GetCurrentValue(); |
205 | 202 |
206 if (host->sandboxed() != (client_id != 0)) | 203 if (host->kind() != kind) |
207 continue; | 204 continue; |
208 | 205 |
209 if (HostIsValid(host)) | 206 if (HostIsValid(host)) |
210 return host; | 207 return host; |
211 } | 208 } |
212 | 209 |
213 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) | 210 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
214 return NULL; | 211 return NULL; |
215 | 212 |
216 int host_id; | 213 int host_id; |
217 host_id = ++g_last_host_id; | 214 host_id = ++g_last_host_id; |
218 | 215 |
219 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", | 216 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
220 cause, | 217 cause, |
221 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); | 218 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); |
222 | 219 |
223 GpuProcessHost* host = new GpuProcessHost(host_id, client_id != 0); | 220 GpuProcessHost* host = new GpuProcessHost(host_id, kind); |
224 if (host->Init()) | 221 if (host->Init()) |
225 return host; | 222 return host; |
226 | 223 |
227 delete host; | 224 delete host; |
228 return NULL; | 225 return NULL; |
229 } | 226 } |
230 | 227 |
231 // static | 228 // static |
232 void GpuProcessHost::SendOnIO(int client_id, | 229 void GpuProcessHost::SendOnIO(GpuProcessKind kind, |
233 content::CauseForGpuLaunch cause, | 230 content::CauseForGpuLaunch cause, |
234 IPC::Message* message) { | 231 IPC::Message* message) { |
235 BrowserThread::PostTask( | 232 BrowserThread::PostTask( |
236 BrowserThread::IO, FROM_HERE, | 233 BrowserThread::IO, FROM_HERE, |
237 base::Bind( | 234 base::Bind( |
238 &SendGpuProcessMessage, client_id, cause, message)); | 235 &SendGpuProcessMessage, kind, cause, message)); |
239 } | 236 } |
240 | 237 |
241 // static | 238 // static |
242 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 239 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
244 | 241 |
245 if (host_id == 0) | 242 if (host_id == 0) |
246 return NULL; | 243 return NULL; |
247 | 244 |
248 GpuProcessHost* host = g_hosts_by_id.Pointer()->Lookup(host_id); | 245 GpuProcessHost* host = g_hosts_by_id.Pointer()->Lookup(host_id); |
249 if (HostIsValid(host)) | 246 if (HostIsValid(host)) |
250 return host; | 247 return host; |
251 | 248 |
252 return NULL; | 249 return NULL; |
253 } | 250 } |
254 | 251 |
255 GpuProcessHost::GpuProcessHost(int host_id, bool sandboxed) | 252 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) |
256 : host_id_(host_id), | 253 : host_id_(host_id), |
257 gpu_process_(base::kNullProcessHandle), | 254 gpu_process_(base::kNullProcessHandle), |
258 in_process_(false), | 255 in_process_(false), |
259 software_rendering_(false), | 256 software_rendering_(false), |
260 sandboxed_(sandboxed), | 257 kind_(kind), |
261 process_launched_(false) { | 258 process_launched_(false) { |
262 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 259 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
263 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) | 260 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) |
264 in_process_ = true; | 261 in_process_ = true; |
265 | 262 |
266 // 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 |
267 // 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. |
268 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); | 265 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); |
269 | 266 |
270 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); | 267 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); |
(...skipping 12 matching lines...) Expand all Loading... | |
283 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_GPU, this)); | 280 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_GPU, this)); |
284 } | 281 } |
285 | 282 |
286 GpuProcessHost::~GpuProcessHost() { | 283 GpuProcessHost::~GpuProcessHost() { |
287 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
288 | 285 |
289 SendOutstandingReplies(); | 286 SendOutstandingReplies(); |
290 // Ending only acts as a failure if the GPU process was actually started and | 287 // Ending only acts as a failure if the GPU process was actually started and |
291 // was intended for actual rendering (and not just checking caps or other | 288 // was intended for actual rendering (and not just checking caps or other |
292 // options). | 289 // options). |
293 if (process_launched_ && sandboxed_) { | 290 if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) { |
294 if (software_rendering_) { | 291 if (software_rendering_) { |
295 if (++g_gpu_software_crash_count >= kGpuMaxCrashCount) { | 292 if (++g_gpu_software_crash_count >= kGpuMaxCrashCount) { |
296 // The software renderer is too unstable to use. Disable it for current | 293 // The software renderer is too unstable to use. Disable it for current |
297 // session. | 294 // session. |
298 gpu_enabled_ = false; | 295 gpu_enabled_ = false; |
299 } | 296 } |
300 } else { | 297 } else { |
301 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { | 298 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { |
302 // The gpu process is too unstable to use. Disable it for current | 299 // The gpu process is too unstable to use. Disable it for current |
303 // session. | 300 // session. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( | 523 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( |
527 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { | 524 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { |
528 TRACE_EVENT0("renderer", | 525 TRACE_EVENT0("renderer", |
529 "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped"); | 526 "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped"); |
530 | 527 |
531 GpuSurfaceTracker::Get()->AsyncPresentAndAcknowledge( | 528 GpuSurfaceTracker::Get()->AsyncPresentAndAcknowledge( |
532 params.surface_id, | 529 params.surface_id, |
533 params.size, | 530 params.size, |
534 params.surface_handle, | 531 params.surface_handle, |
535 base::Bind(SendOnIO, | 532 base::Bind(SendOnIO, |
536 host_id_, | 533 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, |
537 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, | 534 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, |
538 new AcceleratedSurfaceMsg_BuffersSwappedACK( | 535 new AcceleratedSurfaceMsg_BuffersSwappedACK( |
539 params.route_id))); | 536 params.route_id))); |
540 } | 537 } |
541 | 538 |
542 void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer( | 539 void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer( |
543 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) { | 540 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) { |
544 TRACE_EVENT0("renderer", | 541 TRACE_EVENT0("renderer", |
545 "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer"); | 542 "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer"); |
546 | 543 |
(...skipping 24 matching lines...) Expand all Loading... | |
571 } | 568 } |
572 | 569 |
573 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 570 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
574 SendOutstandingReplies(); | 571 SendOutstandingReplies(); |
575 } | 572 } |
576 | 573 |
577 bool GpuProcessHost::software_rendering() { | 574 bool GpuProcessHost::software_rendering() { |
578 return software_rendering_; | 575 return software_rendering_; |
579 } | 576 } |
580 | 577 |
581 bool GpuProcessHost::sandboxed() { | 578 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { |
582 return sandboxed_; | 579 return kind_; |
583 } | 580 } |
584 | 581 |
585 void GpuProcessHost::ForceShutdown() { | 582 void GpuProcessHost::ForceShutdown() { |
586 g_hosts_by_id.Pointer()->Remove(host_id_); | 583 g_hosts_by_id.Pointer()->Remove(host_id_); |
587 process_->ForceShutdown(); | 584 process_->ForceShutdown(); |
588 } | 585 } |
589 | 586 |
590 bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { | 587 bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { |
591 if (!(gpu_enabled_ && | 588 if (!(gpu_enabled_ && |
592 GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) && | 589 GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) && |
(...skipping 15 matching lines...) Expand all Loading... | |
608 #endif | 605 #endif |
609 | 606 |
610 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); | 607 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
611 if (exe_path.empty()) | 608 if (exe_path.empty()) |
612 return false; | 609 return false; |
613 | 610 |
614 CommandLine* cmd_line = new CommandLine(exe_path); | 611 CommandLine* cmd_line = new CommandLine(exe_path); |
615 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 612 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
616 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 613 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
617 | 614 |
618 if (!sandboxed_) | 615 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) |
619 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); | 616 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); |
620 | 617 |
621 // Propagate relevant command line switches. | 618 // Propagate relevant command line switches. |
622 static const char* const kSwitchNames[] = { | 619 static const char* const kSwitchNames[] = { |
623 switches::kDisableBreakpad, | 620 switches::kDisableBreakpad, |
624 switches::kDisableGLMultisampling, | 621 switches::kDisableGLMultisampling, |
625 switches::kDisableGpuDriverBugWorkarounds, | 622 switches::kDisableGpuDriverBugWorkarounds, |
626 switches::kDisableGpuSandbox, | 623 switches::kDisableGpuSandbox, |
627 switches::kReduceGpuSandbox, | 624 switches::kReduceGpuSandbox, |
628 switches::kDisableGpuVsync, | 625 switches::kDisableGpuVsync, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 const IPC::ChannelHandle& channel_handle, | 688 const IPC::ChannelHandle& channel_handle, |
692 base::ProcessHandle renderer_process_for_gpu, | 689 base::ProcessHandle renderer_process_for_gpu, |
693 const content::GPUInfo& gpu_info) { | 690 const content::GPUInfo& gpu_info) { |
694 callback.Run(channel_handle, renderer_process_for_gpu, gpu_info); | 691 callback.Run(channel_handle, renderer_process_for_gpu, gpu_info); |
695 } | 692 } |
696 | 693 |
697 void GpuProcessHost::CreateCommandBufferError( | 694 void GpuProcessHost::CreateCommandBufferError( |
698 const CreateCommandBufferCallback& callback, int32 route_id) { | 695 const CreateCommandBufferCallback& callback, int32 route_id) { |
699 callback.Run(route_id); | 696 callback.Run(route_id); |
700 } | 697 } |
OLD | NEW |