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 |