| 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/gpu/gpu_child_thread.h" | 5 #include "content/gpu/gpu_child_thread.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/threading/worker_pool.h" | 13 #include "base/threading/worker_pool.h" |
| 13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 14 #include "content/child/child_process.h" | 15 #include "content/child/child_process.h" |
| 15 #include "content/child/thread_safe_sender.h" | 16 #include "content/child/thread_safe_sender.h" |
| 16 #include "content/common/gpu/establish_channel_params.h" | 17 #include "content/common/gpu/establish_channel_params.h" |
| 17 #include "content/common/gpu/gpu_host_messages.h" | 18 #include "content/common/gpu/gpu_host_messages.h" |
| 18 #include "content/common/gpu/gpu_memory_buffer_factory.h" | 19 #include "content/common/gpu/gpu_memory_buffer_factory.h" |
| 19 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" | 20 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" |
| 20 #include "content/gpu/gpu_process_control_impl.h" | 21 #include "content/gpu/gpu_process_control_impl.h" |
| 21 #include "content/gpu/gpu_watchdog_thread.h" | 22 #include "content/gpu/gpu_watchdog_thread.h" |
| 22 #include "content/public/common/content_client.h" | 23 #include "content/public/common/content_client.h" |
| 23 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
| 24 #include "content/public/gpu/content_gpu_client.h" | 25 #include "content/public/gpu/content_gpu_client.h" |
| 26 #include "gpu/command_buffer/service/gpu_switches.h" |
| 25 #include "gpu/config/gpu_info_collector.h" | 27 #include "gpu/config/gpu_info_collector.h" |
| 28 #include "gpu/config/gpu_switches.h" |
| 29 #include "gpu/config/gpu_util.h" |
| 26 #include "ipc/ipc_channel_handle.h" | 30 #include "ipc/ipc_channel_handle.h" |
| 27 #include "ipc/ipc_sync_message_filter.h" | 31 #include "ipc/ipc_sync_message_filter.h" |
| 28 #include "ui/gl/gl_implementation.h" | 32 #include "ui/gl/gl_implementation.h" |
| 33 #include "ui/gl/gl_switches.h" |
| 29 #include "ui/gl/gpu_switching_manager.h" | 34 #include "ui/gl/gpu_switching_manager.h" |
| 30 | 35 |
| 31 #if defined(USE_OZONE) | 36 #if defined(USE_OZONE) |
| 32 #include "ui/ozone/public/gpu_platform_support.h" | 37 #include "ui/ozone/public/gpu_platform_support.h" |
| 33 #include "ui/ozone/public/ozone_platform.h" | 38 #include "ui/ozone/public/ozone_platform.h" |
| 34 #endif | 39 #endif |
| 35 | 40 |
| 36 namespace content { | 41 namespace content { |
| 37 namespace { | 42 namespace { |
| 38 | 43 |
| 39 static base::LazyInstance<scoped_refptr<ThreadSafeSender> > | 44 static base::LazyInstance<scoped_refptr<ThreadSafeSender> > |
| 40 g_thread_safe_sender = LAZY_INSTANCE_INITIALIZER; | 45 g_thread_safe_sender = LAZY_INSTANCE_INITIALIZER; |
| 41 | 46 |
| 47 bool GetSizeTFromSwitch(const base::CommandLine* command_line, |
| 48 const base::StringPiece& switch_string, |
| 49 size_t* value) { |
| 50 if (!command_line->HasSwitch(switch_string)) |
| 51 return false; |
| 52 std::string switch_value(command_line->GetSwitchValueASCII(switch_string)); |
| 53 return base::StringToSizeT(switch_value, value); |
| 54 } |
| 55 |
| 42 bool GpuProcessLogMessageHandler(int severity, | 56 bool GpuProcessLogMessageHandler(int severity, |
| 43 const char* file, int line, | 57 const char* file, int line, |
| 44 size_t message_start, | 58 size_t message_start, |
| 45 const std::string& str) { | 59 const std::string& str) { |
| 46 std::string header = str.substr(0, message_start); | 60 std::string header = str.substr(0, message_start); |
| 47 std::string message = str.substr(message_start); | 61 std::string message = str.substr(message_start); |
| 48 | 62 |
| 49 g_thread_safe_sender.Get()->Send( | 63 g_thread_safe_sender.Get()->Send( |
| 50 new GpuHostMsg_OnLogMessage(severity, header, message)); | 64 new GpuHostMsg_OnLogMessage(severity, header, message)); |
| 51 | 65 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 } // namespace | 149 } // namespace |
| 136 | 150 |
| 137 GpuChildThread::GpuChildThread( | 151 GpuChildThread::GpuChildThread( |
| 138 GpuWatchdogThread* watchdog_thread, | 152 GpuWatchdogThread* watchdog_thread, |
| 139 bool dead_on_arrival, | 153 bool dead_on_arrival, |
| 140 const gpu::GPUInfo& gpu_info, | 154 const gpu::GPUInfo& gpu_info, |
| 141 const DeferredMessages& deferred_messages, | 155 const DeferredMessages& deferred_messages, |
| 142 GpuMemoryBufferFactory* gpu_memory_buffer_factory, | 156 GpuMemoryBufferFactory* gpu_memory_buffer_factory, |
| 143 gpu::SyncPointManager* sync_point_manager) | 157 gpu::SyncPointManager* sync_point_manager) |
| 144 : ChildThreadImpl(GetOptions(gpu_memory_buffer_factory)), | 158 : ChildThreadImpl(GetOptions(gpu_memory_buffer_factory)), |
| 159 gpu_preferences_(GetGpuPreferencesFromCommandLine()), |
| 145 dead_on_arrival_(dead_on_arrival), | 160 dead_on_arrival_(dead_on_arrival), |
| 146 sync_point_manager_(sync_point_manager), | 161 sync_point_manager_(sync_point_manager), |
| 147 gpu_info_(gpu_info), | 162 gpu_info_(gpu_info), |
| 148 deferred_messages_(deferred_messages), | 163 deferred_messages_(deferred_messages), |
| 149 in_browser_process_(false), | 164 in_browser_process_(false), |
| 150 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { | 165 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { |
| 151 watchdog_thread_ = watchdog_thread; | 166 watchdog_thread_ = watchdog_thread; |
| 152 #if defined(OS_WIN) | 167 #if defined(OS_WIN) |
| 153 target_services_ = NULL; | 168 target_services_ = NULL; |
| 154 #endif | 169 #endif |
| 155 g_thread_safe_sender.Get() = thread_safe_sender(); | 170 g_thread_safe_sender.Get() = thread_safe_sender(); |
| 156 } | 171 } |
| 157 | 172 |
| 158 GpuChildThread::GpuChildThread( | 173 GpuChildThread::GpuChildThread( |
| 174 const gpu::GpuPreferences& gpu_preferences, |
| 159 const InProcessChildThreadParams& params, | 175 const InProcessChildThreadParams& params, |
| 160 GpuMemoryBufferFactory* gpu_memory_buffer_factory, | 176 GpuMemoryBufferFactory* gpu_memory_buffer_factory, |
| 161 gpu::SyncPointManager* sync_point_manager) | 177 gpu::SyncPointManager* sync_point_manager) |
| 162 : ChildThreadImpl(ChildThreadImpl::Options::Builder() | 178 : ChildThreadImpl(ChildThreadImpl::Options::Builder() |
| 163 .InBrowserProcess(params) | 179 .InBrowserProcess(params) |
| 164 .AddStartupFilter(new GpuMemoryBufferMessageFilter( | 180 .AddStartupFilter(new GpuMemoryBufferMessageFilter( |
| 165 gpu_memory_buffer_factory)) | 181 gpu_memory_buffer_factory)) |
| 166 .Build()), | 182 .Build()), |
| 183 gpu_preferences_(gpu_preferences), |
| 167 dead_on_arrival_(false), | 184 dead_on_arrival_(false), |
| 168 sync_point_manager_(sync_point_manager), | 185 sync_point_manager_(sync_point_manager), |
| 169 in_browser_process_(true), | 186 in_browser_process_(true), |
| 170 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { | 187 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { |
| 171 #if defined(OS_WIN) | 188 #if defined(OS_WIN) |
| 172 target_services_ = NULL; | 189 target_services_ = NULL; |
| 173 #endif | 190 #endif |
| 174 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 191 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 175 switches::kSingleProcess) || | 192 switches::kSingleProcess) || |
| 176 base::CommandLine::ForCurrentProcess()->HasSwitch( | 193 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 } | 367 } |
| 351 | 368 |
| 352 // We don't need to pipe log messages if we are running the GPU thread in | 369 // We don't need to pipe log messages if we are running the GPU thread in |
| 353 // the browser process. | 370 // the browser process. |
| 354 if (!in_browser_process_) | 371 if (!in_browser_process_) |
| 355 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); | 372 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); |
| 356 | 373 |
| 357 // Defer creation of the render thread. This is to prevent it from handling | 374 // Defer creation of the render thread. This is to prevent it from handling |
| 358 // IPC messages before the sandbox has been enabled and all other necessary | 375 // IPC messages before the sandbox has been enabled and all other necessary |
| 359 // initialization has succeeded. | 376 // initialization has succeeded. |
| 360 gpu_channel_manager_.reset(new GpuChannelManager( | 377 gpu_channel_manager_.reset( |
| 361 this, watchdog_thread_.get(), base::ThreadTaskRunnerHandle::Get().get(), | 378 new GpuChannelManager(gpu_preferences_, this, watchdog_thread_.get(), |
| 362 ChildProcess::current()->io_task_runner(), | 379 base::ThreadTaskRunnerHandle::Get().get(), |
| 363 ChildProcess::current()->GetShutDownEvent(), sync_point_manager_, | 380 ChildProcess::current()->io_task_runner(), |
| 364 gpu_memory_buffer_factory_)); | 381 ChildProcess::current()->GetShutDownEvent(), |
| 382 sync_point_manager_, gpu_memory_buffer_factory_)); |
| 365 | 383 |
| 366 #if defined(USE_OZONE) | 384 #if defined(USE_OZONE) |
| 367 ui::OzonePlatform::GetInstance() | 385 ui::OzonePlatform::GetInstance() |
| 368 ->GetGpuPlatformSupport() | 386 ->GetGpuPlatformSupport() |
| 369 ->OnChannelEstablished(this); | 387 ->OnChannelEstablished(this); |
| 370 #endif | 388 #endif |
| 371 } | 389 } |
| 372 | 390 |
| 373 void GpuChildThread::OnFinalize() { | 391 void GpuChildThread::OnFinalize() { |
| 374 // Quit the GPU process | 392 // Quit the GPU process |
| 375 base::MessageLoop::current()->QuitWhenIdle(); | 393 base::MessageLoop::current()->QuitWhenIdle(); |
| 376 } | 394 } |
| 377 | 395 |
| 378 void GpuChildThread::StopWatchdog() { | 396 void GpuChildThread::StopWatchdog() { |
| 379 if (watchdog_thread_.get()) { | 397 if (watchdog_thread_.get()) { |
| 380 watchdog_thread_->Stop(); | 398 watchdog_thread_->Stop(); |
| 381 } | 399 } |
| 382 } | 400 } |
| 383 | 401 |
| 402 // static |
| 403 gpu::GpuPreferences GpuChildThread::GetGpuPreferencesFromCommandLine() { |
| 404 // TODO(penghuang): share below code with |
| 405 // android_webview/browser/deferred_gpu_command_service.cc |
| 406 // http://crbug.com/590825 |
| 407 // For any modification of below code, deferred_gpu_command_service.cc should |
| 408 // be updated as well. |
| 409 DCHECK(base::CommandLine::InitializedForCurrentProcess()); |
| 410 const base::CommandLine* command_line = |
| 411 base::CommandLine::ForCurrentProcess(); |
| 412 gpu::GpuPreferences gpu_preferences; |
| 413 gpu_preferences.single_process = |
| 414 command_line->HasSwitch(switches::kSingleProcess); |
| 415 gpu_preferences.in_process_gpu = |
| 416 command_line->HasSwitch(switches::kInProcessGPU); |
| 417 gpu_preferences.ui_prioritize_in_gpu_process = |
| 418 command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess); |
| 419 gpu_preferences.compile_shader_always_succeeds = |
| 420 command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds); |
| 421 gpu_preferences.disable_gl_error_limit = |
| 422 command_line->HasSwitch(switches::kDisableGLErrorLimit); |
| 423 gpu_preferences.disable_glsl_translator = |
| 424 command_line->HasSwitch(switches::kDisableGLSLTranslator); |
| 425 gpu_preferences.disable_gpu_driver_bug_workarounds = |
| 426 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds); |
| 427 gpu_preferences.disable_shader_name_hashing = |
| 428 command_line->HasSwitch(switches::kDisableShaderNameHashing); |
| 429 gpu_preferences.enable_gpu_command_logging = |
| 430 command_line->HasSwitch(switches::kEnableGPUCommandLogging); |
| 431 gpu_preferences.enable_gpu_debugging = |
| 432 command_line->HasSwitch(switches::kEnableGPUDebugging); |
| 433 gpu_preferences.enable_gpu_service_logging_gpu = |
| 434 command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU); |
| 435 gpu_preferences.disable_gpu_program_cache = |
| 436 command_line->HasSwitch(switches::kDisableGpuProgramCache); |
| 437 gpu_preferences.enforce_gl_minimums = |
| 438 command_line->HasSwitch(switches::kEnforceGLMinimums); |
| 439 if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb, |
| 440 &gpu_preferences.force_gpu_mem_available)) { |
| 441 gpu_preferences.force_gpu_mem_available *= 1024 * 1024; |
| 442 } |
| 443 if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb, |
| 444 &gpu_preferences.gpu_program_cache_size)) { |
| 445 gpu_preferences.gpu_program_cache_size *= 1024; |
| 446 } |
| 447 gpu_preferences.enable_share_group_async_texture_upload = |
| 448 command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload); |
| 449 gpu_preferences.enable_subscribe_uniform_extension = |
| 450 command_line->HasSwitch(switches::kEnableSubscribeUniformExtension); |
| 451 gpu_preferences.enable_threaded_texture_mailboxes = |
| 452 command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes); |
| 453 gpu_preferences.gl_shader_interm_output = |
| 454 command_line->HasSwitch(switches::kGLShaderIntermOutput); |
| 455 gpu_preferences.emulate_shader_precision = |
| 456 command_line->HasSwitch(switches::kEmulateShaderPrecision); |
| 457 gpu_preferences.enable_gpu_service_logging = |
| 458 command_line->HasSwitch(switches::kEnableGPUServiceLogging); |
| 459 gpu_preferences.enable_gpu_service_tracing = |
| 460 command_line->HasSwitch(switches::kEnableGPUServiceTracing); |
| 461 gpu_preferences.enable_unsafe_es3_apis = |
| 462 command_line->HasSwitch(switches::kEnableUnsafeES3APIs); |
| 463 return gpu_preferences; |
| 464 } |
| 465 |
| 384 void GpuChildThread::OnCollectGraphicsInfo() { | 466 void GpuChildThread::OnCollectGraphicsInfo() { |
| 385 #if defined(OS_WIN) | 467 #if defined(OS_WIN) |
| 386 // GPU full info collection should only happen on un-sandboxed GPU process | 468 // GPU full info collection should only happen on un-sandboxed GPU process |
| 387 // or single process/in-process gpu mode on Windows. | 469 // or single process/in-process gpu mode on Windows. |
| 388 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 470 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 389 DCHECK(command_line->HasSwitch(switches::kDisableGpuSandbox) || | 471 DCHECK(command_line->HasSwitch(switches::kDisableGpuSandbox) || |
| 390 in_browser_process_); | 472 in_browser_process_); |
| 391 #endif // OS_WIN | 473 #endif // OS_WIN |
| 392 | 474 |
| 393 gpu::CollectInfoResult result = | 475 gpu::CollectInfoResult result = |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 | 607 |
| 526 void GpuChildThread::BindProcessControlRequest( | 608 void GpuChildThread::BindProcessControlRequest( |
| 527 mojo::InterfaceRequest<ProcessControl> request) { | 609 mojo::InterfaceRequest<ProcessControl> request) { |
| 528 DVLOG(1) << "GPU: Binding ProcessControl request"; | 610 DVLOG(1) << "GPU: Binding ProcessControl request"; |
| 529 DCHECK(process_control_); | 611 DCHECK(process_control_); |
| 530 process_control_bindings_.AddBinding(process_control_.get(), | 612 process_control_bindings_.AddBinding(process_control_.get(), |
| 531 std::move(request)); | 613 std::move(request)); |
| 532 } | 614 } |
| 533 | 615 |
| 534 } // namespace content | 616 } // namespace content |
| OLD | NEW |