| 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 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 GpuProcessHost::EstablishChannelRequest::EstablishChannelRequest( | 409 GpuProcessHost::EstablishChannelRequest::EstablishChannelRequest( |
| 410 const EstablishChannelRequest& other) = default; | 410 const EstablishChannelRequest& other) = default; |
| 411 | 411 |
| 412 GpuProcessHost::EstablishChannelRequest::~EstablishChannelRequest() {} | 412 GpuProcessHost::EstablishChannelRequest::~EstablishChannelRequest() {} |
| 413 | 413 |
| 414 void GpuProcessHost::RegisterGpuMainThreadFactory( | 414 void GpuProcessHost::RegisterGpuMainThreadFactory( |
| 415 GpuMainThreadFactoryFunction create) { | 415 GpuMainThreadFactoryFunction create) { |
| 416 g_gpu_main_thread_factory = create; | 416 g_gpu_main_thread_factory = create; |
| 417 } | 417 } |
| 418 | 418 |
| 419 shell::InterfaceProvider* GpuProcessHost::GetRemoteInterfaces() { |
| 420 return process_->child_connection()->GetRemoteInterfaces(); |
| 421 } |
| 422 |
| 419 // static | 423 // static |
| 420 GpuProcessHost* GpuProcessHost::FromID(int host_id) { | 424 GpuProcessHost* GpuProcessHost::FromID(int host_id) { |
| 421 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 425 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 422 | 426 |
| 423 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { | 427 for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) { |
| 424 GpuProcessHost* host = g_gpu_process_hosts[i]; | 428 GpuProcessHost* host = g_gpu_process_hosts[i]; |
| 425 if (host && host->host_id_ == host_id && ValidateHost(host)) | 429 if (host && host->host_id_ == host_id && ValidateHost(host)) |
| 426 return host; | 430 return host; |
| 427 } | 431 } |
| 428 | 432 |
| 429 return NULL; | 433 return NULL; |
| 430 } | 434 } |
| 431 | 435 |
| 432 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) | 436 GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) |
| 433 : host_id_(host_id), | 437 : host_id_(host_id), |
| 434 valid_(true), | 438 valid_(true), |
| 435 in_process_(false), | 439 in_process_(false), |
| 436 swiftshader_rendering_(false), | 440 swiftshader_rendering_(false), |
| 437 kind_(kind), | 441 kind_(kind), |
| 438 process_launched_(false), | 442 process_launched_(false), |
| 439 initialized_(false), | 443 initialized_(false), |
| 440 uma_memory_stats_received_(false), | 444 uma_memory_stats_received_(false) { |
| 441 child_token_(mojo::edk::GenerateRandomToken()) { | |
| 442 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 445 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 443 switches::kSingleProcess) || | 446 switches::kSingleProcess) || |
| 444 base::CommandLine::ForCurrentProcess()->HasSwitch( | 447 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 445 switches::kInProcessGPU)) { | 448 switches::kInProcessGPU)) { |
| 446 in_process_ = true; | 449 in_process_ = true; |
| 447 } | 450 } |
| 448 | 451 |
| 449 // If the 'single GPU process' policy ever changes, we still want to maintain | 452 // If the 'single GPU process' policy ever changes, we still want to maintain |
| 450 // it for 'gpu thread' mode and only create one instance of host and thread. | 453 // it for 'gpu thread' mode and only create one instance of host and thread. |
| 451 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); | 454 DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL); |
| 452 | 455 |
| 453 g_gpu_process_hosts[kind] = this; | 456 g_gpu_process_hosts[kind] = this; |
| 454 | 457 |
| 455 // Post a task to create the corresponding GpuProcessHostUIShim. The | 458 // Post a task to create the corresponding GpuProcessHostUIShim. The |
| 456 // GpuProcessHostUIShim will be destroyed if either the browser exits, | 459 // GpuProcessHostUIShim will be destroyed if either the browser exits, |
| 457 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the | 460 // in which case it calls GpuProcessHostUIShim::DestroyAll, or the |
| 458 // GpuProcessHost is destroyed, which happens when the corresponding GPU | 461 // GpuProcessHost is destroyed, which happens when the corresponding GPU |
| 459 // process terminates or fails to launch. | 462 // process terminates or fails to launch. |
| 460 BrowserThread::PostTask( | 463 BrowserThread::PostTask( |
| 461 BrowserThread::UI, | 464 BrowserThread::UI, |
| 462 FROM_HERE, | 465 FROM_HERE, |
| 463 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); | 466 base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); |
| 464 | 467 |
| 465 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_GPU, this, | 468 process_.reset(new BrowserChildProcessHostImpl( |
| 466 child_token_)); | 469 PROCESS_TYPE_GPU, this, kGpuMojoApplicationName)); |
| 467 } | 470 } |
| 468 | 471 |
| 469 GpuProcessHost::~GpuProcessHost() { | 472 GpuProcessHost::~GpuProcessHost() { |
| 470 DCHECK(CalledOnValidThread()); | 473 DCHECK(CalledOnValidThread()); |
| 471 | 474 |
| 472 SendOutstandingReplies(); | 475 SendOutstandingReplies(); |
| 473 | 476 |
| 474 // In case we never started, clean up. | 477 // In case we never started, clean up. |
| 475 while (!queued_messages_.empty()) { | 478 while (!queued_messages_.empty()) { |
| 476 delete queued_messages_.front(); | 479 delete queued_messages_.front(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 init_start_time_ = base::TimeTicks::Now(); | 573 init_start_time_ = base::TimeTicks::Now(); |
| 571 | 574 |
| 572 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); | 575 TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD); |
| 573 | 576 |
| 574 // May be null during test execution. | 577 // May be null during test execution. |
| 575 if (MojoShellConnection::GetForProcess()) { | 578 if (MojoShellConnection::GetForProcess()) { |
| 576 MojoShellConnection::GetForProcess()->AddConnectionFilter( | 579 MojoShellConnection::GetForProcess()->AddConnectionFilter( |
| 577 base::MakeUnique<ConnectionFilterImpl>(this)); | 580 base::MakeUnique<ConnectionFilterImpl>(this)); |
| 578 } | 581 } |
| 579 | 582 |
| 580 const std::string mojo_channel_token = | 583 process_->GetHost()->CreateChannelMojo(); |
| 581 process_->GetHost()->CreateChannelMojo(child_token_); | |
| 582 if (mojo_channel_token.empty()) | |
| 583 return false; | |
| 584 | |
| 585 DCHECK(!mojo_child_connection_); | |
| 586 mojo_child_connection_.reset(new MojoChildConnection( | |
| 587 kGpuMojoApplicationName, "", child_token_, | |
| 588 MojoShellContext::GetConnectorForIOThread(), | |
| 589 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); | |
| 590 | 584 |
| 591 gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine(); | 585 gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine(); |
| 592 if (in_process_) { | 586 if (in_process_) { |
| 593 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 587 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 594 DCHECK(g_gpu_main_thread_factory); | 588 DCHECK(g_gpu_main_thread_factory); |
| 595 in_process_gpu_thread_.reset(g_gpu_main_thread_factory( | 589 in_process_gpu_thread_.reset(g_gpu_main_thread_factory( |
| 596 InProcessChildThreadParams( | 590 InProcessChildThreadParams( |
| 597 std::string(), base::ThreadTaskRunnerHandle::Get(), | 591 std::string(), base::ThreadTaskRunnerHandle::Get(), |
| 598 mojo_channel_token, mojo_child_connection_->service_token()), | 592 std::string(), |
| 593 process_->child_connection()->service_token()), |
| 599 gpu_preferences)); | 594 gpu_preferences)); |
| 600 base::Thread::Options options; | 595 base::Thread::Options options; |
| 601 #if defined(OS_WIN) | 596 #if defined(OS_WIN) |
| 602 // WGL needs to create its own window and pump messages on it. | 597 // WGL needs to create its own window and pump messages on it. |
| 603 options.message_loop_type = base::MessageLoop::TYPE_UI; | 598 options.message_loop_type = base::MessageLoop::TYPE_UI; |
| 604 #endif | 599 #endif |
| 605 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 600 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| 606 options.priority = base::ThreadPriority::DISPLAY; | 601 options.priority = base::ThreadPriority::DISPLAY; |
| 607 #endif | 602 #endif |
| 608 in_process_gpu_thread_->StartWithOptions(options); | 603 in_process_gpu_thread_->StartWithOptions(options); |
| 609 | 604 |
| 610 OnProcessLaunched(); // Fake a callback that the process is ready. | 605 OnProcessLaunched(); // Fake a callback that the process is ready. |
| 611 } else if (!LaunchGpuProcess(mojo_channel_token, &gpu_preferences)) { | 606 } else if (!LaunchGpuProcess(&gpu_preferences)) { |
| 612 return false; | 607 return false; |
| 613 } | 608 } |
| 614 | 609 |
| 615 if (!Send(new GpuMsg_Initialize(gpu_preferences))) | 610 if (!Send(new GpuMsg_Initialize(gpu_preferences))) |
| 616 return false; | 611 return false; |
| 617 | 612 |
| 618 return true; | 613 return true; |
| 619 } | 614 } |
| 620 | 615 |
| 621 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { | 616 void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 RecordProcessCrash(); | 944 RecordProcessCrash(); |
| 950 } | 945 } |
| 951 | 946 |
| 952 void GpuProcessHost::OnProcessCrashed(int exit_code) { | 947 void GpuProcessHost::OnProcessCrashed(int exit_code) { |
| 953 SendOutstandingReplies(); | 948 SendOutstandingReplies(); |
| 954 RecordProcessCrash(); | 949 RecordProcessCrash(); |
| 955 GpuDataManagerImpl::GetInstance()->ProcessCrashed( | 950 GpuDataManagerImpl::GetInstance()->ProcessCrashed( |
| 956 process_->GetTerminationStatus(true /* known_dead */, NULL)); | 951 process_->GetTerminationStatus(true /* known_dead */, NULL)); |
| 957 } | 952 } |
| 958 | 953 |
| 959 shell::InterfaceProvider* GpuProcessHost::GetRemoteInterfaces() { | |
| 960 return mojo_child_connection_->GetRemoteInterfaces(); | |
| 961 } | |
| 962 | |
| 963 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { | 954 GpuProcessHost::GpuProcessKind GpuProcessHost::kind() { |
| 964 return kind_; | 955 return kind_; |
| 965 } | 956 } |
| 966 | 957 |
| 967 void GpuProcessHost::ForceShutdown() { | 958 void GpuProcessHost::ForceShutdown() { |
| 968 // This is only called on the IO thread so no race against the constructor | 959 // This is only called on the IO thread so no race against the constructor |
| 969 // for another GpuProcessHost. | 960 // for another GpuProcessHost. |
| 970 if (g_gpu_process_hosts[kind_] == this) | 961 if (g_gpu_process_hosts[kind_] == this) |
| 971 g_gpu_process_hosts[kind_] = NULL; | 962 g_gpu_process_hosts[kind_] = NULL; |
| 972 | 963 |
| 973 process_->ForceShutdown(); | 964 process_->ForceShutdown(); |
| 974 } | 965 } |
| 975 | 966 |
| 976 void GpuProcessHost::StopGpuProcess() { | 967 void GpuProcessHost::StopGpuProcess() { |
| 977 Send(new GpuMsg_Finalize()); | 968 Send(new GpuMsg_Finalize()); |
| 978 } | 969 } |
| 979 | 970 |
| 980 bool GpuProcessHost::LaunchGpuProcess(const std::string& mojo_channel_token, | 971 bool GpuProcessHost::LaunchGpuProcess(gpu::GpuPreferences* gpu_preferences) { |
| 981 gpu::GpuPreferences* gpu_preferences) { | |
| 982 if (!(gpu_enabled_ && | 972 if (!(gpu_enabled_ && |
| 983 GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) && | 973 GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) && |
| 984 !hardware_gpu_enabled_) { | 974 !hardware_gpu_enabled_) { |
| 985 SendOutstandingReplies(); | 975 SendOutstandingReplies(); |
| 986 return false; | 976 return false; |
| 987 } | 977 } |
| 988 | 978 |
| 989 const base::CommandLine& browser_command_line = | 979 const base::CommandLine& browser_command_line = |
| 990 *base::CommandLine::ForCurrentProcess(); | 980 *base::CommandLine::ForCurrentProcess(); |
| 991 | 981 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1006 int child_flags = ChildProcessHost::CHILD_NORMAL; | 996 int child_flags = ChildProcessHost::CHILD_NORMAL; |
| 1007 #endif | 997 #endif |
| 1008 | 998 |
| 1009 base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); | 999 base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
| 1010 if (exe_path.empty()) | 1000 if (exe_path.empty()) |
| 1011 return false; | 1001 return false; |
| 1012 | 1002 |
| 1013 base::CommandLine* cmd_line = new base::CommandLine(exe_path); | 1003 base::CommandLine* cmd_line = new base::CommandLine(exe_path); |
| 1014 #endif | 1004 #endif |
| 1015 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); | 1005 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); |
| 1016 cmd_line->AppendSwitchASCII(switches::kMojoChannelToken, mojo_channel_token); | |
| 1017 cmd_line->AppendSwitchASCII(switches::kMojoApplicationChannelToken, | |
| 1018 mojo_child_connection_->service_token()); | |
| 1019 BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); | 1006 BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); |
| 1020 | 1007 |
| 1021 #if defined(OS_WIN) | 1008 #if defined(OS_WIN) |
| 1022 cmd_line->AppendArg(switches::kPrefetchArgumentGpu); | 1009 cmd_line->AppendArg(switches::kPrefetchArgumentGpu); |
| 1023 #endif // defined(OS_WIN) | 1010 #endif // defined(OS_WIN) |
| 1024 | 1011 |
| 1025 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) | 1012 if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED) |
| 1026 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); | 1013 cmd_line->AppendSwitch(switches::kDisableGpuSandbox); |
| 1027 | 1014 |
| 1028 // TODO(penghuang): Replace all GPU related switches with GpuPreferences. | 1015 // TODO(penghuang): Replace all GPU related switches with GpuPreferences. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); | 1189 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); |
| 1203 ClientIdToShaderCacheMap::iterator iter = | 1190 ClientIdToShaderCacheMap::iterator iter = |
| 1204 client_id_to_shader_cache_.find(client_id); | 1191 client_id_to_shader_cache_.find(client_id); |
| 1205 // If the cache doesn't exist then this is an off the record profile. | 1192 // If the cache doesn't exist then this is an off the record profile. |
| 1206 if (iter == client_id_to_shader_cache_.end()) | 1193 if (iter == client_id_to_shader_cache_.end()) |
| 1207 return; | 1194 return; |
| 1208 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); | 1195 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); |
| 1209 } | 1196 } |
| 1210 | 1197 |
| 1211 } // namespace content | 1198 } // namespace content |
| OLD | NEW |