Chromium Code Reviews| 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 |