| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 GpuProcessHost::EstablishChannelRequest::EstablishChannelRequest( | 385 GpuProcessHost::EstablishChannelRequest::EstablishChannelRequest( |
| 386 const EstablishChannelRequest& other) = default; | 386 const EstablishChannelRequest& other) = default; |
| 387 | 387 |
| 388 GpuProcessHost::EstablishChannelRequest::~EstablishChannelRequest() {} | 388 GpuProcessHost::EstablishChannelRequest::~EstablishChannelRequest() {} |
| 389 | 389 |
| 390 void GpuProcessHost::RegisterGpuMainThreadFactory( | 390 void GpuProcessHost::RegisterGpuMainThreadFactory( |
| 391 GpuMainThreadFactoryFunction create) { | 391 GpuMainThreadFactoryFunction create) { |
| 392 g_gpu_main_thread_factory = create; | 392 g_gpu_main_thread_factory = create; |
| 393 } | 393 } |
| 394 | 394 |
| 395 shell::InterfaceProvider* GpuProcessHost::GetRemoteInterfaces() { | |
| 396 return process_->child_connection()->GetRemoteInterfaces(); | |
| 397 } | |
| 398 | |
| 399 // static | 395 // static |
| 400 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 396 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
| 401 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 397 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 402 | 398 |
| 403 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { | 399 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { |
| 404 GpuProcessHost* host = g_gpu_process_hosts[i]; | 400 GpuProcessHost* host = g_gpu_process_hosts[i]; |
| 405 if (host && host->host_id_ == host_id && ValidateHost(host)) | 401 if (host && host->host_id_ == host_id && ValidateHost(host)) |
| 406 return host; | 402 return host; |
| 407 } | 403 } |
| 408 | 404 |
| 409 return NULL; | 405 return NULL; |
| 410 } | 406 } |
| 411 | 407 |
| 412 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) | 408 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) |
| 413 : host_id_(host_id), | 409 : host_id_(host_id), |
| 414 valid_(true), | 410 valid_(true), |
| 415 in_process_(false), | 411 in_process_(false), |
| 416 swiftshader_rendering_(false), | 412 swiftshader_rendering_(false), |
| 417 kind_(kind), | 413 kind_(kind), |
| 418 process_launched_(false), | 414 process_launched_(false), |
| 419 initialized_(false), | 415 initialized_(false), |
| 420 uma_memory_stats_received_(false) { | 416 uma_memory_stats_received_(false), |
| 417 child_token_(mojo::edk::GenerateRandomToken()) { |
| 421 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 418 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 422 switches::kSingleProcess) || | 419 switches::kSingleProcess) || |
| 423 base::CommandLine::ForCurrentProcess()->HasSwitch( | 420 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 424 switches::kInProcessGPU)) { | 421 switches::kInProcessGPU)) { |
| 425 in_process_ = true; | 422 in_process_ = true; |
| 426 } | 423 } |
| 427 | 424 |
| 428 // If the 'single GPU process' policy ever changes, we still want to maintain | 425 // If the 'single GPU process' policy ever changes, we still want to maintain |
| 429 // it for 'gpu thread' mode and only create one instance of host and thread. | 426 // it for 'gpu thread' mode and only create one instance of host and thread. |
| 430 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); | 427 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); |
| 431 | 428 |
| 432 g_gpu_process_hosts[kind] = this; | 429 g_gpu_process_hosts[kind] = this; |
| 433 | 430 |
| 434 // Post a task to create the corresponding GpuProcessHostUIShim. The | 431 // Post a task to create the corresponding GpuProcessHostUIShim. The |
| 435 // GpuProcessHostUIShim will be destroyed if either the browser exits, | 432 // GpuProcessHostUIShim will be destroyed if either the browser exits, |
| 436 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the | 433 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the |
| 437 // GpuProcessHost is destroyed, which happens when the corresponding GPU | 434 // GpuProcessHost is destroyed, which happens when the corresponding GPU |
| 438 // process terminates or fails to launch. | 435 // process terminates or fails to launch. |
| 439 BrowserThread::PostTask( | 436 BrowserThread::PostTask( |
| 440 BrowserThread::UI, | 437 BrowserThread::UI, |
| 441 FROM_HERE, | 438 FROM_HERE, |
| 442 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); | 439 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); |
| 443 | 440 |
| 444 process_.reset(new BrowserChildProcessHostImpl( | 441 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this, |
| 445 PROCESS_TYPE_GPU, this, kGpuMojoApplicationName)); | 442 child_token_)); |
| 446 } | 443 } |
| 447 | 444 |
| 448 GpuProcessHost::~GpuProcessHost() { | 445 GpuProcessHost::~GpuProcessHost() { |
| 449 DCHECK(CalledOnValidThread()); | 446 DCHECK(CalledOnValidThread()); |
| 450 | 447 |
| 451 SendOutstandingReplies(); | 448 SendOutstandingReplies(); |
| 452 | 449 |
| 453 // In case we never started, clean up. | 450 // In case we never started, clean up. |
| 454 while (!queued_messages_.empty()) { | 451 while (!queued_messages_.empty()) { |
| 455 delete queued_messages_.front(); | 452 delete queued_messages_.front(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 base::Bind(&GpuProcessHostUIShim::Destroy, | 540 base::Bind(&GpuProcessHostUIShim::Destroy, |
| 544 host_id_, | 541 host_id_, |
| 545 message)); | 542 message)); |
| 546 } | 543 } |
| 547 | 544 |
| 548 bool GpuProcessHost::Init() { | 545 bool GpuProcessHost::Init() { |
| 549 init_start_time_ = base::TimeTicks::Now(); | 546 init_start_time_ = base::TimeTicks::Now(); |
| 550 | 547 |
| 551 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); | 548 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); |
| 552 | 549 |
| 553 process_->GetHost()->CreateChannelMojo(); | 550 const std::string mojo_channel_token = |
| 551 process_->GetHost()->CreateChannelMojo(child_token_); |
| 552 if (mojo_channel_token.empty()) |
| 553 return false; |
| 554 |
| 555 DCHECK(!mojo_child_connection_); |
| 556 mojo_child_connection_.reset(new MojoChildConnection( |
| 557 kGpuMojoApplicationName, "", child_token_, |
| 558 MojoShellContext::GetConnectorForIOThread(), |
| 559 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); |
| 554 | 560 |
| 555 gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine(); | 561 gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine(); |
| 556 if (in_process_) { | 562 if (in_process_) { |
| 557 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 563 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 558 DCHECK(g_gpu_main_thread_factory); | 564 DCHECK(g_gpu_main_thread_factory); |
| 559 in_process_gpu_thread_.reset(g_gpu_main_thread_factory( | 565 in_process_gpu_thread_.reset(g_gpu_main_thread_factory( |
| 560 InProcessChildThreadParams( | 566 InProcessChildThreadParams( |
| 561 std::string(), base::ThreadTaskRunnerHandle::Get(), | 567 std::string(), base::ThreadTaskRunnerHandle::Get(), |
| 562 std::string(), | 568 mojo_channel_token, mojo_child_connection_->service_token()), |
| 563 process_->child_connection()->service_token()), | |
| 564 gpu_preferences)); | 569 gpu_preferences)); |
| 565 base::Thread::Options options; | 570 base::Thread::Options options; |
| 566 #if defined(OS_WIN) | 571 #if defined(OS_WIN) |
| 567 // WGL needs to create its own window and pump messages on it. | 572 // WGL needs to create its own window and pump messages on it. |
| 568 options.message_loop_type = base::MessageLoop::TYPE_UI; | 573 options.message_loop_type = base::MessageLoop::TYPE_UI; |
| 569 #endif | 574 #endif |
| 570 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 575 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| 571 options.priority = base::ThreadPriority::DISPLAY; | 576 options.priority = base::ThreadPriority::DISPLAY; |
| 572 #endif | 577 #endif |
| 573 in_process_gpu_thread_->StartWithOptions(options); | 578 in_process_gpu_thread_->StartWithOptions(options); |
| 574 | 579 |
| 575 OnProcessLaunched(); // Fake a callback that the process is ready. | 580 OnProcessLaunched(); // Fake a callback that the process is ready. |
| 576 } else if (!LaunchGpuProcess(&gpu_preferences)) { | 581 } else if (!LaunchGpuProcess(mojo_channel_token, &gpu_preferences)) { |
| 577 return false; | 582 return false; |
| 578 } | 583 } |
| 579 | 584 |
| 580 if (!Send(new GpuMsg_Initialize(gpu_preferences))) | 585 if (!Send(new GpuMsg_Initialize(gpu_preferences))) |
| 581 return false; | 586 return false; |
| 582 | 587 |
| 583 return true; | 588 return true; |
| 584 } | 589 } |
| 585 | 590 |
| 586 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { | 591 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 RecordProcessCrash(); | 919 RecordProcessCrash(); |
| 915 } | 920 } |
| 916 | 921 |
| 917 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 922 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
| 918 SendOutstandingReplies(); | 923 SendOutstandingReplies(); |
| 919 RecordProcessCrash(); | 924 RecordProcessCrash(); |
| 920 GpuDataManagerImpl::GetInstance()->ProcessCrashed( | 925 GpuDataManagerImpl::GetInstance()->ProcessCrashed( |
| 921 process_->GetTerminationStatus(true /* known_dead */, NULL)); | 926 process_->GetTerminationStatus(true /* known_dead */, NULL)); |
| 922 } | 927 } |
| 923 | 928 |
| 929 shell::InterfaceProvider* GpuProcessHost::GetRemoteInterfaces() { |
| 930 return mojo_child_connection_->GetRemoteInterfaces(); |
| 931 } |
| 932 |
| 924 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { | 933 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { |
| 925 return kind_; | 934 return kind_; |
| 926 } | 935 } |
| 927 | 936 |
| 928 void GpuProcessHost::ForceShutdown() { | 937 void GpuProcessHost::ForceShutdown() { |
| 929 // This is only called on the IO thread so no race against the constructor | 938 // This is only called on the IO thread so no race against the constructor |
| 930 // for another GpuProcessHost. | 939 // for another GpuProcessHost. |
| 931 if (g_gpu_process_hosts[kind_] == this) | 940 if (g_gpu_process_hosts[kind_] == this) |
| 932 g_gpu_process_hosts[kind_] = NULL; | 941 g_gpu_process_hosts[kind_] = NULL; |
| 933 | 942 |
| 934 process_->ForceShutdown(); | 943 process_->ForceShutdown(); |
| 935 } | 944 } |
| 936 | 945 |
| 937 void GpuProcessHost::StopGpuProcess() { | 946 void GpuProcessHost::StopGpuProcess() { |
| 938 Send(new GpuMsg_Finalize()); | 947 Send(new GpuMsg_Finalize()); |
| 939 } | 948 } |
| 940 | 949 |
| 941 bool GpuProcessHost::LaunchGpuProcess(gpu::GpuPreferences* gpu_preferences) { | 950 bool GpuProcessHost::LaunchGpuProcess(const std::string& mojo_channel_token, |
| 951 gpu::GpuPreferences* gpu_preferences) { |
| 942 if (!(gpu_enabled_ && | 952 if (!(gpu_enabled_ && |
| 943 GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) && | 953 GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) && |
| 944 !hardware_gpu_enabled_) { | 954 !hardware_gpu_enabled_) { |
| 945 SendOutstandingReplies(); | 955 SendOutstandingReplies(); |
| 946 return false; | 956 return false; |
| 947 } | 957 } |
| 948 | 958 |
| 949 const base::CommandLine& browser_command_line = | 959 const base::CommandLine& browser_command_line = |
| 950 *base::CommandLine::ForCurrentProcess(); | 960 *base::CommandLine::ForCurrentProcess(); |
| 951 | 961 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 966 int child_flags = ChildProcessHost::CHILD_NORMAL; | 976 int child_flags = ChildProcessHost::CHILD_NORMAL; |
| 967 #endif | 977 #endif |
| 968 | 978 |
| 969 base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); | 979 base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
| 970 if (exe_path.empty()) | 980 if (exe_path.empty()) |
| 971 return false; | 981 return false; |
| 972 | 982 |
| 973 base::CommandLine* cmd_line = new base::CommandLine(exe_path); | 983 base::CommandLine* cmd_line = new base::CommandLine(exe_path); |
| 974 #endif | 984 #endif |
| 975 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 985 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
| 986 cmd_line->AppendSwitchASCII(switches::kMojoChannelToken, mojo_channel_token); |
| 987 cmd_line->AppendSwitchASCII(switches::kMojoApplicationChannelToken, |
| 988 mojo_child_connection_->service_token()); |
| 976 BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); | 989 BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); |
| 977 | 990 |
| 978 #if defined(OS_WIN) | 991 #if defined(OS_WIN) |
| 979 cmd_line->AppendArg(switches::kPrefetchArgumentGpu); | 992 cmd_line->AppendArg(switches::kPrefetchArgumentGpu); |
| 980 #endif // defined(OS_WIN) | 993 #endif // defined(OS_WIN) |
| 981 | 994 |
| 982 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) | 995 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) |
| 983 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); | 996 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); |
| 984 | 997 |
| 985 // TODO(penghuang): Replace all GPU related switches with GpuPreferences. | 998 // TODO(penghuang): Replace all GPU related switches with GpuPreferences. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); | 1172 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); |
| 1160 ClientIdToShaderCacheMap::iterator iter = | 1173 ClientIdToShaderCacheMap::iterator iter = |
| 1161 client_id_to_shader_cache_.find(client_id); | 1174 client_id_to_shader_cache_.find(client_id); |
| 1162 // If the cache doesn't exist then this is an off the record profile. | 1175 // If the cache doesn't exist then this is an off the record profile. |
| 1163 if (iter == client_id_to_shader_cache_.end()) | 1176 if (iter == client_id_to_shader_cache_.end()) |
| 1164 return; | 1177 return; |
| 1165 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); | 1178 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); |
| 1166 } | 1179 } |
| 1167 | 1180 |
| 1168 } // namespace content | 1181 } // namespace content |
| OLD | NEW |