| 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" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/process_util.h" | 13 #include "base/process_util.h" |
| 14 #include "base/string_piece.h" | 14 #include "base/string_piece.h" |
| 15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 16 #include "content/browser/gpu/gpu_data_manager.h" | 16 #include "content/browser/gpu/gpu_data_manager.h" |
| 17 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 17 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
| 18 #include "content/browser/renderer_host/render_widget_host.h" | 18 #include "content/browser/renderer_host/render_widget_host.h" |
| 19 #include "content/browser/renderer_host/render_widget_host_view.h" | 19 #include "content/browser/renderer_host/render_widget_host_view.h" |
| 20 #include "content/common/child_process_host.h" | 20 #include "content/common/child_process_host_impl.h" |
| 21 #include "content/common/gpu/gpu_messages.h" | 21 #include "content/common/gpu/gpu_messages.h" |
| 22 #include "content/gpu/gpu_child_thread.h" | 22 #include "content/gpu/gpu_child_thread.h" |
| 23 #include "content/gpu/gpu_process.h" | 23 #include "content/gpu/gpu_process.h" |
| 24 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
| 26 #include "content/public/common/result_codes.h" | 26 #include "content/public/common/result_codes.h" |
| 27 #include "ipc/ipc_channel_handle.h" | 27 #include "ipc/ipc_channel_handle.h" |
| 28 #include "ipc/ipc_switches.h" | 28 #include "ipc/ipc_switches.h" |
| 29 #include "ui/gfx/gl/gl_context.h" | 29 #include "ui/gfx/gl/gl_context.h" |
| 30 #include "ui/gfx/gl/gl_implementation.h" | 30 #include "ui/gfx/gl/gl_implementation.h" |
| 31 #include "ui/gfx/gl/gl_switches.h" | 31 #include "ui/gfx/gl/gl_switches.h" |
| 32 | 32 |
| 33 #if defined(TOOLKIT_USES_GTK) | 33 #if defined(TOOLKIT_USES_GTK) |
| 34 #include "ui/gfx/gtk_native_view_id_manager.h" | 34 #include "ui/gfx/gtk_native_view_id_manager.h" |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 using content::BrowserThread; | 37 using content::BrowserThread; |
| 38 using content::ChildProcessHost; |
| 38 | 39 |
| 39 bool GpuProcessHost::gpu_enabled_ = true; | 40 bool GpuProcessHost::gpu_enabled_ = true; |
| 40 | 41 |
| 41 namespace { | 42 namespace { |
| 42 | 43 |
| 43 enum GPUProcessLifetimeEvent { | 44 enum GPUProcessLifetimeEvent { |
| 44 LAUNCHED, | 45 LAUNCHED, |
| 45 DIED_FIRST_TIME, | 46 DIED_FIRST_TIME, |
| 46 DIED_SECOND_TIME, | 47 DIED_SECOND_TIME, |
| 47 DIED_THIRD_TIME, | 48 DIED_THIRD_TIME, |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 | 313 |
| 313 g_hosts_by_id.Pointer()->Remove(host_id_); | 314 g_hosts_by_id.Pointer()->Remove(host_id_); |
| 314 | 315 |
| 315 BrowserThread::PostTask(BrowserThread::UI, | 316 BrowserThread::PostTask(BrowserThread::UI, |
| 316 FROM_HERE, | 317 FROM_HERE, |
| 317 NewRunnableFunction(GpuProcessHostUIShim::Destroy, | 318 NewRunnableFunction(GpuProcessHostUIShim::Destroy, |
| 318 host_id_)); | 319 host_id_)); |
| 319 } | 320 } |
| 320 | 321 |
| 321 bool GpuProcessHost::Init() { | 322 bool GpuProcessHost::Init() { |
| 322 if (!child_process_host()->CreateChannel()) | 323 std::string channel_id = child_process_host()->CreateChannel(); |
| 324 if (channel_id.empty()) |
| 323 return false; | 325 return false; |
| 324 | 326 |
| 325 if (in_process_) { | 327 if (in_process_) { |
| 326 CommandLine::ForCurrentProcess()->AppendSwitch( | 328 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 327 switches::kDisableGpuWatchdog); | 329 switches::kDisableGpuWatchdog); |
| 328 | 330 |
| 329 in_process_gpu_thread_.reset(new GpuMainThread( | 331 in_process_gpu_thread_.reset(new GpuMainThread(channel_id)); |
| 330 child_process_host()->channel_id())); | |
| 331 | 332 |
| 332 base::Thread::Options options; | 333 base::Thread::Options options; |
| 333 #if defined(OS_WIN) | 334 #if defined(OS_WIN) |
| 334 // On Windows the GPU thread needs to pump the compositor child window's | 335 // On Windows the GPU thread needs to pump the compositor child window's |
| 335 // message loop. TODO(apatrick): make this an IO thread if / when we get rid | 336 // message loop. TODO(apatrick): make this an IO thread if / when we get rid |
| 336 // of this child window. Unfortunately it might always be necessary for | 337 // of this child window. Unfortunately it might always be necessary for |
| 337 // Windows XP because we cannot share the backing store textures between | 338 // Windows XP because we cannot share the backing store textures between |
| 338 // processes. | 339 // processes. |
| 339 options.message_loop_type = MessageLoop::TYPE_UI; | 340 options.message_loop_type = MessageLoop::TYPE_UI; |
| 340 #else | 341 #else |
| 341 options.message_loop_type = MessageLoop::TYPE_IO; | 342 options.message_loop_type = MessageLoop::TYPE_IO; |
| 342 #endif | 343 #endif |
| 343 in_process_gpu_thread_->StartWithOptions(options); | 344 in_process_gpu_thread_->StartWithOptions(options); |
| 344 | 345 |
| 345 OnProcessLaunched(); // Fake a callback that the process is ready. | 346 OnProcessLaunched(); // Fake a callback that the process is ready. |
| 346 } else if (!LaunchGpuProcess()) | 347 } else if (!LaunchGpuProcess(channel_id)) |
| 347 return false; | 348 return false; |
| 348 | 349 |
| 349 return Send(new GpuMsg_Initialize()); | 350 return Send(new GpuMsg_Initialize()); |
| 350 } | 351 } |
| 351 | 352 |
| 352 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { | 353 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { |
| 353 BrowserThread::PostTask( | 354 BrowserThread::PostTask( |
| 354 BrowserThread::UI, | 355 BrowserThread::UI, |
| 355 FROM_HERE, | 356 FROM_HERE, |
| 356 new RouteToGpuProcessHostUIShimTask(host_id_, message)); | 357 new RouteToGpuProcessHostUIShimTask(host_id_, message)); |
| 357 } | 358 } |
| 358 | 359 |
| 359 bool GpuProcessHost::Send(IPC::Message* msg) { | 360 bool GpuProcessHost::Send(IPC::Message* msg) { |
| 360 DCHECK(CalledOnValidThread()); | 361 DCHECK(CalledOnValidThread()); |
| 361 if (child_process_host()->opening_channel()) { | 362 if (child_process_host()->IsChannelOpening()) { |
| 362 queued_messages_.push(msg); | 363 queued_messages_.push(msg); |
| 363 return true; | 364 return true; |
| 364 } | 365 } |
| 365 | 366 |
| 366 return BrowserChildProcessHost::Send(msg); | 367 return BrowserChildProcessHost::Send(msg); |
| 367 } | 368 } |
| 368 | 369 |
| 369 bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { | 370 bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { |
| 370 DCHECK(CalledOnValidThread()); | 371 DCHECK(CalledOnValidThread()); |
| 371 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) | 372 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 // The gpu process is too unstable to use. Disable it for current session. | 537 // The gpu process is too unstable to use. Disable it for current session. |
| 537 gpu_enabled_ = false; | 538 gpu_enabled_ = false; |
| 538 } | 539 } |
| 539 BrowserChildProcessHost::OnProcessCrashed(exit_code); | 540 BrowserChildProcessHost::OnProcessCrashed(exit_code); |
| 540 } | 541 } |
| 541 | 542 |
| 542 bool GpuProcessHost::software_rendering() { | 543 bool GpuProcessHost::software_rendering() { |
| 543 return software_rendering_; | 544 return software_rendering_; |
| 544 } | 545 } |
| 545 | 546 |
| 546 bool GpuProcessHost::LaunchGpuProcess() { | 547 bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { |
| 547 if (!gpu_enabled_ || g_gpu_crash_count >= kGpuMaxCrashCount) { | 548 if (!gpu_enabled_ || g_gpu_crash_count >= kGpuMaxCrashCount) { |
| 548 SendOutstandingReplies(); | 549 SendOutstandingReplies(); |
| 549 gpu_enabled_ = false; | 550 gpu_enabled_ = false; |
| 550 return false; | 551 return false; |
| 551 } | 552 } |
| 552 | 553 |
| 553 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 554 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 554 | 555 |
| 555 CommandLine::StringType gpu_launcher = | 556 CommandLine::StringType gpu_launcher = |
| 556 browser_command_line.GetSwitchValueNative(switches::kGpuLauncher); | 557 browser_command_line.GetSwitchValueNative(switches::kGpuLauncher); |
| 557 | 558 |
| 558 #if defined(OS_LINUX) | 559 #if defined(OS_LINUX) |
| 559 int child_flags = gpu_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF : | 560 int child_flags = gpu_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF : |
| 560 ChildProcessHost::CHILD_NORMAL; | 561 ChildProcessHost::CHILD_NORMAL; |
| 561 #else | 562 #else |
| 562 int child_flags = ChildProcessHost::CHILD_NORMAL; | 563 int child_flags = ChildProcessHost::CHILD_NORMAL; |
| 563 #endif | 564 #endif |
| 564 | 565 |
| 565 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); | 566 FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
| 566 if (exe_path.empty()) | 567 if (exe_path.empty()) |
| 567 return false; | 568 return false; |
| 568 | 569 |
| 569 CommandLine* cmd_line = new CommandLine(exe_path); | 570 CommandLine* cmd_line = new CommandLine(exe_path); |
| 570 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 571 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
| 571 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, | 572 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
| 572 child_process_host()->channel_id()); | |
| 573 | 573 |
| 574 // Propagate relevant command line switches. | 574 // Propagate relevant command line switches. |
| 575 static const char* const kSwitchNames[] = { | 575 static const char* const kSwitchNames[] = { |
| 576 switches::kDisableBreakpad, | 576 switches::kDisableBreakpad, |
| 577 switches::kDisableGLMultisampling, | 577 switches::kDisableGLMultisampling, |
| 578 switches::kDisableGpuDriverBugWorkarounds, | 578 switches::kDisableGpuDriverBugWorkarounds, |
| 579 switches::kDisableGpuSandbox, | 579 switches::kDisableGpuSandbox, |
| 580 switches::kDisableGpuVsync, | 580 switches::kDisableGpuVsync, |
| 581 switches::kDisableGpuWatchdog, | 581 switches::kDisableGpuWatchdog, |
| 582 switches::kDisableLogging, | 582 switches::kDisableLogging, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); | 643 scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); |
| 644 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); | 644 wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); |
| 645 } | 645 } |
| 646 | 646 |
| 647 void GpuProcessHost::CreateCommandBufferError( | 647 void GpuProcessHost::CreateCommandBufferError( |
| 648 CreateCommandBufferCallback* callback, int32 route_id) { | 648 CreateCommandBufferCallback* callback, int32 route_id) { |
| 649 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> | 649 scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> |
| 650 wrapped_callback(callback); | 650 wrapped_callback(callback); |
| 651 callback->Run(route_id); | 651 callback->Run(route_id); |
| 652 } | 652 } |
| OLD | NEW |