OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/gpu_process_host.h" | 5 #include "chrome/browser/gpu_process_host.h" |
6 | 6 |
7 #include "app/app_switches.h" | 7 #include "app/app_switches.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/string_piece.h" | 11 #include "base/string_piece.h" |
12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
13 #include "chrome/browser/browser_thread.h" | 13 #include "chrome/browser/browser_thread.h" |
14 #include "chrome/browser/gpu_blacklist.h" | 14 #include "chrome/browser/gpu_blacklist.h" |
15 #include "chrome/browser/gpu_process_host_ui_shim.h" | 15 #include "chrome/browser/gpu_process_host_ui_shim.h" |
16 #include "chrome/browser/renderer_host/render_message_filter.h" | 16 #include "chrome/browser/renderer_host/render_message_filter.h" |
17 #include "chrome/browser/renderer_host/render_view_host.h" | 17 #include "chrome/browser/renderer_host/render_view_host.h" |
18 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 18 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
19 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" | 19 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" |
20 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/gpu_feature_flags.h" | 21 #include "chrome/common/gpu_feature_flags.h" |
22 #include "chrome/common/gpu_info.h" | 22 #include "chrome/common/gpu_info.h" |
23 #include "chrome/common/gpu_messages.h" | 23 #include "chrome/common/gpu_messages.h" |
24 #include "chrome/common/render_messages.h" | 24 #include "chrome/common/render_messages.h" |
| 25 #include "chrome/gpu/gpu_thread.h" |
25 #include "grit/browser_resources.h" | 26 #include "grit/browser_resources.h" |
26 #include "ipc/ipc_channel_handle.h" | 27 #include "ipc/ipc_channel_handle.h" |
27 #include "ipc/ipc_switches.h" | 28 #include "ipc/ipc_switches.h" |
28 #include "media/base/media_switches.h" | 29 #include "media/base/media_switches.h" |
29 | 30 |
30 #if defined(OS_LINUX) | 31 #if defined(OS_LINUX) |
31 // These two #includes need to come after render_messages.h. | 32 // These two #includes need to come after render_messages.h. |
32 #include <gdk/gdkwindow.h> // NOLINT | 33 #include <gdk/gdkwindow.h> // NOLINT |
33 #include <gdk/gdkx.h> // NOLINT | 34 #include <gdk/gdkx.h> // NOLINT |
34 #include "app/x11_util.h" | 35 #include "app/x11_util.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 // Once this limit is reached, any request to launch the gpu process will fail. | 77 // Once this limit is reached, any request to launch the gpu process will fail. |
77 static const int kGpuMaxCrashCount = 3; | 78 static const int kGpuMaxCrashCount = 3; |
78 | 79 |
79 void RouteOnUIThread(const IPC::Message& message) { | 80 void RouteOnUIThread(const IPC::Message& message) { |
80 BrowserThread::PostTask(BrowserThread::UI, | 81 BrowserThread::PostTask(BrowserThread::UI, |
81 FROM_HERE, | 82 FROM_HERE, |
82 new RouteOnUIThreadTask(message)); | 83 new RouteOnUIThreadTask(message)); |
83 } | 84 } |
84 } // anonymous namespace | 85 } // anonymous namespace |
85 | 86 |
| 87 class GpuMainThread : public base::Thread { |
| 88 public: |
| 89 explicit GpuMainThread(const std::string& channel_id) |
| 90 : base::Thread("CrGpuMain"), |
| 91 channel_id_(channel_id) { |
| 92 } |
| 93 |
| 94 ~GpuMainThread() { |
| 95 Stop(); |
| 96 } |
| 97 |
| 98 protected: |
| 99 virtual void Init() { |
| 100 // Must be created on GPU thread. |
| 101 gpu_thread_.reset(new GpuThread(channel_id_)); |
| 102 gpu_thread_->Init(base::Time::Now()); |
| 103 } |
| 104 |
| 105 virtual void CleanUp() { |
| 106 // Must be destroyed on GPU thread. |
| 107 gpu_thread_.reset(); |
| 108 } |
| 109 |
| 110 private: |
| 111 scoped_ptr<GpuThread> gpu_thread_; |
| 112 std::string channel_id_; |
| 113 DISALLOW_COPY_AND_ASSIGN(GpuMainThread); |
| 114 }; |
| 115 |
86 GpuProcessHost::GpuProcessHost() | 116 GpuProcessHost::GpuProcessHost() |
87 : BrowserChildProcessHost(GPU_PROCESS, NULL), | 117 : BrowserChildProcessHost(GPU_PROCESS, NULL), |
88 initialized_(false), | 118 initialized_(false), |
89 initialized_successfully_(false), | 119 initialized_successfully_(false), |
90 blacklist_result_recorded_(false) { | 120 blacklist_result_recorded_(false) { |
91 DCHECK_EQ(sole_instance_, static_cast<GpuProcessHost*>(NULL)); | 121 DCHECK_EQ(sole_instance_, static_cast<GpuProcessHost*>(NULL)); |
92 } | 122 } |
93 | 123 |
94 GpuProcessHost::~GpuProcessHost() { | 124 GpuProcessHost::~GpuProcessHost() { |
95 while (!queued_synchronization_replies_.empty()) { | 125 while (!queued_synchronization_replies_.empty()) { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 566 } |
537 BrowserChildProcessHost::OnProcessCrashed(exit_code); | 567 BrowserChildProcessHost::OnProcessCrashed(exit_code); |
538 } | 568 } |
539 | 569 |
540 bool GpuProcessHost::CanLaunchGpuProcess() const { | 570 bool GpuProcessHost::CanLaunchGpuProcess() const { |
541 return RenderViewHostDelegateHelper::gpu_enabled(); | 571 return RenderViewHostDelegateHelper::gpu_enabled(); |
542 } | 572 } |
543 | 573 |
544 bool GpuProcessHost::LaunchGpuProcess() { | 574 bool GpuProcessHost::LaunchGpuProcess() { |
545 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 575 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
546 CommandLine::StringType gpu_launcher = | |
547 browser_command_line.GetSwitchValueNative(switches::kGpuLauncher); | |
548 | 576 |
549 FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty()); | 577 // If the single-process switch is present, just launch the GPU service in a |
550 if (exe_path.empty()) | 578 // new thread in the browser process. |
551 return false; | 579 if (browser_command_line.HasSwitch(switches::kSingleProcess)) { |
| 580 GpuMainThread* thread = new GpuMainThread(channel_id()); |
552 | 581 |
553 CommandLine* cmd_line = new CommandLine(exe_path); | 582 base::Thread::Options options; |
554 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 583 options.message_loop_type = MessageLoop::TYPE_UI; |
555 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); | |
556 | 584 |
557 // Propagate relevant command line switches. | 585 if (!thread->StartWithOptions(options)) |
558 static const char* const kSwitchNames[] = { | 586 return false; |
559 switches::kUseGL, | 587 } else { |
560 switches::kDisableGpuVsync, | 588 CommandLine::StringType gpu_launcher = |
561 switches::kDisableGpuWatchdog, | 589 browser_command_line.GetSwitchValueNative(switches::kGpuLauncher); |
562 switches::kDisableLogging, | 590 |
563 switches::kEnableAcceleratedDecoding, | 591 FilePath exe_path = ChildProcessHost::GetChildPath(gpu_launcher.empty()); |
564 switches::kEnableLogging, | 592 if (exe_path.empty()) |
565 #if defined(OS_MACOSX) | 593 return false; |
566 switches::kEnableSandboxLogging, | 594 |
| 595 CommandLine* cmd_line = new CommandLine(exe_path); |
| 596 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
| 597 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); |
| 598 |
| 599 // Propagate relevant command line switches. |
| 600 static const char* const kSwitchNames[] = { |
| 601 switches::kUseGL, |
| 602 switches::kDisableGpuVsync, |
| 603 switches::kDisableGpuWatchdog, |
| 604 switches::kDisableLogging, |
| 605 switches::kEnableAcceleratedDecoding, |
| 606 switches::kEnableLogging, |
| 607 #if defined(OS_MACOSX) |
| 608 switches::kEnableSandboxLogging, |
| 609 #endif |
| 610 switches::kGpuStartupDialog, |
| 611 switches::kLoggingLevel, |
| 612 switches::kNoGpuSandbox, |
| 613 switches::kNoSandbox, |
| 614 }; |
| 615 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, |
| 616 arraysize(kSwitchNames)); |
| 617 |
| 618 // If specified, prepend a launcher program to the command line. |
| 619 if (!gpu_launcher.empty()) |
| 620 cmd_line->PrependWrapper(gpu_launcher); |
| 621 |
| 622 Launch( |
| 623 #if defined(OS_WIN) |
| 624 FilePath(), |
| 625 #elif defined(OS_POSIX) |
| 626 false, // Never use the zygote (GPU plugin can't be sandboxed). |
| 627 base::environment_vector(), |
567 #endif | 628 #endif |
568 switches::kGpuStartupDialog, | 629 cmd_line); |
569 switches::kLoggingLevel, | 630 } |
570 switches::kNoGpuSandbox, | |
571 switches::kNoSandbox, | |
572 }; | |
573 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, | |
574 arraysize(kSwitchNames)); | |
575 | |
576 // If specified, prepend a launcher program to the command line. | |
577 if (!gpu_launcher.empty()) | |
578 cmd_line->PrependWrapper(gpu_launcher); | |
579 | |
580 Launch( | |
581 #if defined(OS_WIN) | |
582 FilePath(), | |
583 #elif defined(OS_POSIX) | |
584 false, // Never use the zygote (GPU plugin can't be sandboxed). | |
585 base::environment_vector(), | |
586 #endif | |
587 cmd_line); | |
588 | 631 |
589 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", | 632 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", |
590 LAUNCED, GPU_PROCESS_LIFETIME_EVENT_MAX); | 633 LAUNCED, GPU_PROCESS_LIFETIME_EVENT_MAX); |
591 return true; | 634 return true; |
592 } | 635 } |
593 | 636 |
594 bool GpuProcessHost::LoadGpuBlacklist() { | 637 bool GpuProcessHost::LoadGpuBlacklist() { |
595 if (gpu_blacklist_.get() != NULL) | 638 if (gpu_blacklist_.get() != NULL) |
596 return true; | 639 return true; |
597 static const base::StringPiece gpu_blacklist_json( | 640 static const base::StringPiece gpu_blacklist_json( |
598 ResourceBundle::GetSharedInstance().GetRawDataResource( | 641 ResourceBundle::GetSharedInstance().GetRawDataResource( |
599 IDR_GPU_BLACKLIST)); | 642 IDR_GPU_BLACKLIST)); |
600 GpuBlacklist* blacklist = new GpuBlacklist(); | 643 GpuBlacklist* blacklist = new GpuBlacklist(); |
601 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 644 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
602 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || | 645 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || |
603 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { | 646 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { |
604 gpu_blacklist_.reset(blacklist); | 647 gpu_blacklist_.reset(blacklist); |
605 return true; | 648 return true; |
606 } | 649 } |
607 delete blacklist; | 650 delete blacklist; |
608 return false; | 651 return false; |
609 } | 652 } |
610 | 653 |
OLD | NEW |