| 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/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/base_switches.h" | 8 #include "base/base_switches.h" |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/sha1.h" | 16 #include "base/sha1.h" |
| 17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
| 18 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
| 19 #include "components/tracing/tracing_switches.h" | 19 #include "components/tracing/tracing_switches.h" |
| 20 #include "content/browser/browser_child_process_host_impl.h" | 20 #include "content/browser/browser_child_process_host_impl.h" |
| 21 #include "content/browser/gpu/compositor_util.h" | 21 #include "content/browser/gpu/compositor_util.h" |
| 22 #include "content/browser/gpu/gpu_data_manager_impl.h" | 22 #include "content/browser/gpu/gpu_data_manager_impl.h" |
| 23 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 23 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
| 24 #include "content/browser/gpu/gpu_surface_tracker.h" | 24 #include "content/browser/gpu/gpu_surface_tracker.h" |
| 25 #include "content/browser/gpu/shader_disk_cache.h" | 25 #include "content/browser/gpu/shader_disk_cache.h" |
| 26 #include "content/browser/mojo/mojo_application_host.h" |
| 26 #include "content/browser/renderer_host/render_widget_host_impl.h" | 27 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 27 #include "content/common/child_process_host_impl.h" | 28 #include "content/common/child_process_host_impl.h" |
| 28 #include "content/common/gpu/gpu_messages.h" | 29 #include "content/common/gpu/gpu_messages.h" |
| 29 #include "content/common/in_process_child_thread_params.h" | 30 #include "content/common/in_process_child_thread_params.h" |
| 30 #include "content/common/view_messages.h" | 31 #include "content/common/view_messages.h" |
| 31 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
| 33 #include "content/public/browser/render_process_host.h" | 34 #include "content/public/browser/render_process_host.h" |
| 34 #include "content/public/browser/render_widget_host_view.h" | 35 #include "content/public/browser/render_widget_host_view.h" |
| 35 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 36 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 message = "The GPU process crashed!"; | 521 message = "The GPU process crashed!"; |
| 521 break; | 522 break; |
| 522 case base::TERMINATION_STATUS_LAUNCH_FAILED: | 523 case base::TERMINATION_STATUS_LAUNCH_FAILED: |
| 523 message = "The GPU process failed to start!"; | 524 message = "The GPU process failed to start!"; |
| 524 break; | 525 break; |
| 525 default: | 526 default: |
| 526 break; | 527 break; |
| 527 } | 528 } |
| 528 } | 529 } |
| 529 | 530 |
| 531 // We could be destroyed as a result of Chrome shutdown. When that happens, |
| 532 // the Mojo channel doesn't get the opportunity to shut down cleanly because |
| 533 // it posts to the IO thread (the current thread) which is being destroyed. |
| 534 // To guarantee proper shutdown of the Mojo channel, do it explicitly here. |
| 535 if (mojo_application_host_) |
| 536 mojo_application_host_->ShutdownOnIOThread(); |
| 537 |
| 530 BrowserThread::PostTask(BrowserThread::UI, | 538 BrowserThread::PostTask(BrowserThread::UI, |
| 531 FROM_HERE, | 539 FROM_HERE, |
| 532 base::Bind(&GpuProcessHostUIShim::Destroy, | 540 base::Bind(&GpuProcessHostUIShim::Destroy, |
| 533 host_id_, | 541 host_id_, |
| 534 message)); | 542 message)); |
| 535 } | 543 } |
| 536 | 544 |
| 537 bool GpuProcessHost::Init() { | 545 bool GpuProcessHost::Init() { |
| 538 init_start_time_ = base::TimeTicks::Now(); | 546 init_start_time_ = base::TimeTicks::Now(); |
| 539 | 547 |
| 540 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); | 548 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); |
| 541 | 549 |
| 542 std::string channel_id = process_->GetHost()->CreateChannel(); | 550 std::string channel_id = process_->GetHost()->CreateChannel(); |
| 543 if (channel_id.empty()) | 551 if (channel_id.empty()) |
| 544 return false; | 552 return false; |
| 545 | 553 |
| 554 if (!SetupMojo()) |
| 555 return false; |
| 556 |
| 546 if (in_process_) { | 557 if (in_process_) { |
| 547 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 558 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 548 DCHECK(g_gpu_main_thread_factory); | 559 DCHECK(g_gpu_main_thread_factory); |
| 549 in_process_gpu_thread_.reset( | 560 in_process_gpu_thread_.reset( |
| 550 g_gpu_main_thread_factory(InProcessChildThreadParams( | 561 g_gpu_main_thread_factory(InProcessChildThreadParams( |
| 551 channel_id, base::MessageLoop::current()->task_runner()))); | 562 channel_id, base::MessageLoop::current()->task_runner()))); |
| 552 base::Thread::Options options; | 563 base::Thread::Options options; |
| 553 #if defined(OS_WIN) | 564 #if defined(OS_WIN) |
| 554 // WGL needs to create its own window and pump messages on it. | 565 // WGL needs to create its own window and pump messages on it. |
| 555 options.message_loop_type = base::MessageLoop::TYPE_UI; | 566 options.message_loop_type = base::MessageLoop::TYPE_UI; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 568 io_surface_manager_token_ = | 579 io_surface_manager_token_ = |
| 569 BrowserIOSurfaceManager::GetInstance()->GenerateGpuProcessToken(); | 580 BrowserIOSurfaceManager::GetInstance()->GenerateGpuProcessToken(); |
| 570 // Note: A valid IOSurface manager token needs to be sent to the Gpu process | 581 // Note: A valid IOSurface manager token needs to be sent to the Gpu process |
| 571 // before any GpuMemoryBuffer allocation requests can be sent. | 582 // before any GpuMemoryBuffer allocation requests can be sent. |
| 572 Send(new ChildProcessMsg_SetIOSurfaceManagerToken(io_surface_manager_token_)); | 583 Send(new ChildProcessMsg_SetIOSurfaceManagerToken(io_surface_manager_token_)); |
| 573 #endif | 584 #endif |
| 574 | 585 |
| 575 return true; | 586 return true; |
| 576 } | 587 } |
| 577 | 588 |
| 589 bool GpuProcessHost::SetupMojo() { |
| 590 CHECK(!mojo_application_host_); |
| 591 mojo_application_host_.reset(new MojoApplicationHost); |
| 592 return mojo_application_host_->Init(); |
| 593 } |
| 594 |
| 578 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { | 595 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { |
| 579 BrowserThread::PostTask( | 596 BrowserThread::PostTask( |
| 580 BrowserThread::UI, | 597 BrowserThread::UI, |
| 581 FROM_HERE, | 598 FROM_HERE, |
| 582 base::Bind(&RouteToGpuProcessHostUIShimTask, host_id_, message)); | 599 base::Bind(&RouteToGpuProcessHostUIShimTask, host_id_, message)); |
| 583 } | 600 } |
| 584 | 601 |
| 585 bool GpuProcessHost::Send(IPC::Message* msg) { | 602 bool GpuProcessHost::Send(IPC::Message* msg) { |
| 586 DCHECK(CalledOnValidThread()); | 603 DCHECK(CalledOnValidThread()); |
| 587 if (process_->GetHost()->IsChannelOpening()) { | 604 if (process_->GetHost()->IsChannelOpening()) { |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 #if defined(OS_MACOSX) | 878 #if defined(OS_MACOSX) |
| 862 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( | 879 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( |
| 863 const IPC::Message& message) { | 880 const IPC::Message& message) { |
| 864 RenderWidgetResizeHelper::PostGpuProcessMsg(host_id_, message); | 881 RenderWidgetResizeHelper::PostGpuProcessMsg(host_id_, message); |
| 865 } | 882 } |
| 866 #endif | 883 #endif |
| 867 | 884 |
| 868 void GpuProcessHost::OnProcessLaunched() { | 885 void GpuProcessHost::OnProcessLaunched() { |
| 869 UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime", | 886 UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime", |
| 870 base::TimeTicks::Now() - init_start_time_); | 887 base::TimeTicks::Now() - init_start_time_); |
| 888 if (mojo_application_host_) { |
| 889 base::ProcessHandle handle; |
| 890 if (in_process_) |
| 891 handle = base::GetCurrentProcessHandle(); |
| 892 else |
| 893 handle = process_->GetData().handle; |
| 894 |
| 895 mojo_application_host_->Activate(this, handle); |
| 896 } |
| 871 } | 897 } |
| 872 | 898 |
| 873 void GpuProcessHost::OnProcessLaunchFailed() { | 899 void GpuProcessHost::OnProcessLaunchFailed() { |
| 874 RecordProcessCrash(); | 900 RecordProcessCrash(); |
| 875 } | 901 } |
| 876 | 902 |
| 877 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 903 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
| 878 SendOutstandingReplies(); | 904 SendOutstandingReplies(); |
| 879 RecordProcessCrash(); | 905 RecordProcessCrash(); |
| 880 GpuDataManagerImpl::GetInstance()->ProcessCrashed( | 906 GpuDataManagerImpl::GetInstance()->ProcessCrashed( |
| 881 process_->GetTerminationStatus(true /* known_dead */, NULL)); | 907 process_->GetTerminationStatus(true /* known_dead */, NULL)); |
| 882 } | 908 } |
| 883 | 909 |
| 910 ServiceRegistry* GpuProcessHost::GetServiceRegistry() { |
| 911 if (mojo_application_host_) |
| 912 return mojo_application_host_->service_registry(); |
| 913 return nullptr; |
| 914 } |
| 915 |
| 884 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { | 916 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { |
| 885 return kind_; | 917 return kind_; |
| 886 } | 918 } |
| 887 | 919 |
| 888 void GpuProcessHost::ForceShutdown() { | 920 void GpuProcessHost::ForceShutdown() { |
| 889 // This is only called on the IO thread so no race against the constructor | 921 // This is only called on the IO thread so no race against the constructor |
| 890 // for another GpuProcessHost. | 922 // for another GpuProcessHost. |
| 891 if (g_gpu_process_hosts[kind_] == this) | 923 if (g_gpu_process_hosts[kind_] == this) |
| 892 g_gpu_process_hosts[kind_] = NULL; | 924 g_gpu_process_hosts[kind_] = NULL; |
| 893 | 925 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); | 1158 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); |
| 1127 ClientIdToShaderCacheMap::iterator iter = | 1159 ClientIdToShaderCacheMap::iterator iter = |
| 1128 client_id_to_shader_cache_.find(client_id); | 1160 client_id_to_shader_cache_.find(client_id); |
| 1129 // If the cache doesn't exist then this is an off the record profile. | 1161 // If the cache doesn't exist then this is an off the record profile. |
| 1130 if (iter == client_id_to_shader_cache_.end()) | 1162 if (iter == client_id_to_shader_cache_.end()) |
| 1131 return; | 1163 return; |
| 1132 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); | 1164 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); |
| 1133 } | 1165 } |
| 1134 | 1166 |
| 1135 } // namespace content | 1167 } // namespace content |
| OLD | NEW |