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::Kind 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(Kind 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 | 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 | 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. | 201 // this will be extended to allow the use of multiple GPU processes. |
Ami GONE FROM CHROMIUM
2012/03/01 02:33:04
The CL description made me think this comment was
apatrick_chromium
2012/03/01 02:57:39
Yeah missed this comment. Thanks. The idea is, if
| |
202 for (IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); | 202 for (IDMap<GpuProcessHost>::iterator it(g_hosts_by_id.Pointer()); |
Ami GONE FROM CHROMIUM
2012/03/01 02:33:04
If the map is kept, why is this iterating through
apatrick_chromium
2012/03/01 02:57:39
Because the lookup is not by host ID I guess. I ag
| |
203 !it.IsAtEnd(); it.Advance()) { | 203 !it.IsAtEnd(); it.Advance()) { |
204 GpuProcessHost* host = it.GetCurrentValue(); | 204 GpuProcessHost* host = it.GetCurrentValue(); |
205 | 205 |
206 if (host->sandboxed() != (client_id != 0)) | 206 if (host->kind() != kind) |
207 continue; | 207 continue; |
208 | 208 |
209 if (HostIsValid(host)) | 209 if (HostIsValid(host)) |
210 return host; | 210 return host; |
211 } | 211 } |
212 | 212 |
213 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) | 213 if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
214 return NULL; | 214 return NULL; |
215 | 215 |
216 int host_id; | 216 int host_id; |
217 host_id = ++g_last_host_id; | 217 host_id = ++g_last_host_id; |
218 | 218 |
219 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", | 219 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
220 cause, | 220 cause, |
221 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); | 221 content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM); |
222 | 222 |
223 GpuProcessHost* host = new GpuProcessHost(host_id, client_id != 0); | 223 GpuProcessHost* host = new GpuProcessHost(host_id, kind); |
224 if (host->Init()) | 224 if (host->Init()) |
225 return host; | 225 return host; |
226 | 226 |
227 delete host; | 227 delete host; |
228 return NULL; | 228 return NULL; |
229 } | 229 } |
230 | 230 |
231 // static | 231 // static |
232 void GpuProcessHost::SendOnIO(int client_id, | 232 void GpuProcessHost::SendOnIO(Kind kind, |
233 content::CauseForGpuLaunch cause, | 233 content::CauseForGpuLaunch cause, |
234 IPC::Message* message) { | 234 IPC::Message* message) { |
235 BrowserThread::PostTask( | 235 BrowserThread::PostTask( |
236 BrowserThread::IO, FROM_HERE, | 236 BrowserThread::IO, FROM_HERE, |
237 base::Bind( | 237 base::Bind( |
238 &SendGpuProcessMessage, client_id, cause, message)); | 238 &SendGpuProcessMessage, kind, cause, message)); |
239 } | 239 } |
240 | 240 |
241 // static | 241 // static |
242 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 242 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
244 | 244 |
245 if (host_id == 0) | 245 if (host_id == 0) |
246 return NULL; | 246 return NULL; |
247 | 247 |
248 GpuProcessHost* host = g_hosts_by_id.Pointer()->Lookup(host_id); | 248 GpuProcessHost* host = g_hosts_by_id.Pointer()->Lookup(host_id); |
249 if (HostIsValid(host)) | 249 if (HostIsValid(host)) |
250 return host; | 250 return host; |
251 | 251 |
252 return NULL; | 252 return NULL; |
253 } | 253 } |
254 | 254 |
255 GpuProcessHost::GpuProcessHost(int host_id, bool sandboxed) | 255 GpuProcessHost::GpuProcessHost(int host_id, Kind kind) |
256 : host_id_(host_id), | 256 : host_id_(host_id), |
257 gpu_process_(base::kNullProcessHandle), | 257 gpu_process_(base::kNullProcessHandle), |
258 in_process_(false), | 258 in_process_(false), |
259 software_rendering_(false), | 259 software_rendering_(false), |
260 sandboxed_(sandboxed), | 260 kind_(kind), |
261 process_launched_(false) { | 261 process_launched_(false) { |
262 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || | 262 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
263 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) | 263 CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) |
264 in_process_ = true; | 264 in_process_ = true; |
265 | 265 |
266 // If the 'single GPU process' policy ever changes, we still want to maintain | 266 // 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. | 267 // it for 'gpu thread' mode and only create one instance of host and thread. |
268 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); | 268 DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); |
269 | 269 |
270 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); | 270 g_hosts_by_id.Pointer()->AddWithID(this, host_id_); |
(...skipping 12 matching lines...) Expand all Loading... | |
283 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_GPU, this)); | 283 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_GPU, this)); |
284 } | 284 } |
285 | 285 |
286 GpuProcessHost::~GpuProcessHost() { | 286 GpuProcessHost::~GpuProcessHost() { |
287 DCHECK(CalledOnValidThread()); | 287 DCHECK(CalledOnValidThread()); |
288 | 288 |
289 SendOutstandingReplies(); | 289 SendOutstandingReplies(); |
290 // Ending only acts as a failure if the GPU process was actually started and | 290 // 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 | 291 // was intended for actual rendering (and not just checking caps or other |
292 // options). | 292 // options). |
293 if (process_launched_ && sandboxed_) { | 293 if (process_launched_ && kind_ == kSandboxed) { |
294 if (software_rendering_) { | 294 if (software_rendering_) { |
295 if (++g_gpu_software_crash_count >= kGpuMaxCrashCount) { | 295 if (++g_gpu_software_crash_count >= kGpuMaxCrashCount) { |
296 // The software renderer is too unstable to use. Disable it for current | 296 // The software renderer is too unstable to use. Disable it for current |
297 // session. | 297 // session. |
298 gpu_enabled_ = false; | 298 gpu_enabled_ = false; |
299 } | 299 } |
300 } else { | 300 } else { |
301 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { | 301 if (++g_gpu_crash_count >= kGpuMaxCrashCount) { |
302 // The gpu process is too unstable to use. Disable it for current | 302 // The gpu process is too unstable to use. Disable it for current |
303 // session. | 303 // session. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( | 526 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( |
527 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { | 527 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { |
528 TRACE_EVENT0("renderer", | 528 TRACE_EVENT0("renderer", |
529 "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped"); | 529 "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped"); |
530 | 530 |
531 GpuSurfaceTracker::Get()->AsyncPresentAndAcknowledge( | 531 GpuSurfaceTracker::Get()->AsyncPresentAndAcknowledge( |
532 params.surface_id, | 532 params.surface_id, |
533 params.size, | 533 params.size, |
534 params.surface_handle, | 534 params.surface_handle, |
535 base::Bind(SendOnIO, | 535 base::Bind(SendOnIO, |
536 host_id_, | 536 GpuProcessHost::kSandboxed, |
537 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, | 537 content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, |
538 new AcceleratedSurfaceMsg_BuffersSwappedACK( | 538 new AcceleratedSurfaceMsg_BuffersSwappedACK( |
539 params.route_id))); | 539 params.route_id))); |
540 } | 540 } |
541 | 541 |
542 void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer( | 542 void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer( |
543 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) { | 543 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) { |
544 TRACE_EVENT0("renderer", | 544 TRACE_EVENT0("renderer", |
545 "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer"); | 545 "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer"); |
546 | 546 |
(...skipping 24 matching lines...) Expand all Loading... | |
571 } | 571 } |
572 | 572 |
573 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 573 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
574 SendOutstandingReplies(); | 574 SendOutstandingReplies(); |
575 } | 575 } |
576 | 576 |
577 bool GpuProcessHost::software_rendering() { | 577 bool GpuProcessHost::software_rendering() { |
578 return software_rendering_; | 578 return software_rendering_; |
579 } | 579 } |
580 | 580 |
581 bool GpuProcessHost::sandboxed() { | 581 GpuProcessHost::Kind GpuProcessHost::kind() { |
582 return sandboxed_; | 582 return kind_; |
583 } | 583 } |
584 | 584 |
585 void GpuProcessHost::ForceShutdown() { | 585 void GpuProcessHost::ForceShutdown() { |
586 g_hosts_by_id.Pointer()->Remove(host_id_); | 586 g_hosts_by_id.Pointer()->Remove(host_id_); |
587 process_->ForceShutdown(); | 587 process_->ForceShutdown(); |
588 } | 588 } |
589 | 589 |
590 bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { | 590 bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { |
591 if (!(gpu_enabled_ && | 591 if (!(gpu_enabled_ && |
592 GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) && | 592 GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) && |
(...skipping 15 matching lines...) Expand all Loading... | |
608 #endif | 608 #endif |
609 | 609 |
610 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); | 610 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
611 if (exe_path.empty()) | 611 if (exe_path.empty()) |
612 return false; | 612 return false; |
613 | 613 |
614 CommandLine* cmd_line = new CommandLine(exe_path); | 614 CommandLine* cmd_line = new CommandLine(exe_path); |
615 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 615 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
616 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 616 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
617 | 617 |
618 if (!sandboxed_) | 618 if (kind_ == kUnsandboxed) |
619 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); | 619 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); |
620 | 620 |
621 // Propagate relevant command line switches. | 621 // Propagate relevant command line switches. |
622 static const char* const kSwitchNames[] = { | 622 static const char* const kSwitchNames[] = { |
623 switches::kDisableBreakpad, | 623 switches::kDisableBreakpad, |
624 switches::kDisableGLMultisampling, | 624 switches::kDisableGLMultisampling, |
625 switches::kDisableGpuDriverBugWorkarounds, | 625 switches::kDisableGpuDriverBugWorkarounds, |
626 switches::kDisableGpuSandbox, | 626 switches::kDisableGpuSandbox, |
627 switches::kReduceGpuSandbox, | 627 switches::kReduceGpuSandbox, |
628 switches::kDisableGpuVsync, | 628 switches::kDisableGpuVsync, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 const IPC::ChannelHandle& channel_handle, | 691 const IPC::ChannelHandle& channel_handle, |
692 base::ProcessHandle renderer_process_for_gpu, | 692 base::ProcessHandle renderer_process_for_gpu, |
693 const content::GPUInfo& gpu_info) { | 693 const content::GPUInfo& gpu_info) { |
694 callback.Run(channel_handle, renderer_process_for_gpu, gpu_info); | 694 callback.Run(channel_handle, renderer_process_for_gpu, gpu_info); |
695 } | 695 } |
696 | 696 |
697 void GpuProcessHost::CreateCommandBufferError( | 697 void GpuProcessHost::CreateCommandBufferError( |
698 const CreateCommandBufferCallback& callback, int32 route_id) { | 698 const CreateCommandBufferCallback& callback, int32 route_id) { |
699 callback.Run(route_id); | 699 callback.Run(route_id); |
700 } | 700 } |
OLD | NEW |