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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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)), |
145 dead_on_arrival_(dead_on_arrival), | 159 dead_on_arrival_(dead_on_arrival), |
146 sync_point_manager_(sync_point_manager), | 160 sync_point_manager_(sync_point_manager), |
147 gpu_info_(gpu_info), | 161 gpu_info_(gpu_info), |
148 deferred_messages_(deferred_messages), | 162 deferred_messages_(deferred_messages), |
149 in_browser_process_(false), | 163 in_browser_process_(false), |
150 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { | 164 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { |
| 165 InitGpuPreferences(); |
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( |
159 const InProcessChildThreadParams& params, | 174 const InProcessChildThreadParams& params, |
160 GpuMemoryBufferFactory* gpu_memory_buffer_factory, | 175 GpuMemoryBufferFactory* gpu_memory_buffer_factory, |
161 gpu::SyncPointManager* sync_point_manager) | 176 gpu::SyncPointManager* sync_point_manager) |
162 : ChildThreadImpl(ChildThreadImpl::Options::Builder() | 177 : ChildThreadImpl(ChildThreadImpl::Options::Builder() |
163 .InBrowserProcess(params) | 178 .InBrowserProcess(params) |
164 .AddStartupFilter(new GpuMemoryBufferMessageFilter( | 179 .AddStartupFilter(new GpuMemoryBufferMessageFilter( |
165 gpu_memory_buffer_factory)) | 180 gpu_memory_buffer_factory)) |
166 .Build()), | 181 .Build()), |
167 dead_on_arrival_(false), | 182 dead_on_arrival_(false), |
168 sync_point_manager_(sync_point_manager), | 183 sync_point_manager_(sync_point_manager), |
169 in_browser_process_(true), | 184 in_browser_process_(true), |
170 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { | 185 gpu_memory_buffer_factory_(gpu_memory_buffer_factory) { |
| 186 InitGpuPreferences(); |
171 #if defined(OS_WIN) | 187 #if defined(OS_WIN) |
172 target_services_ = NULL; | 188 target_services_ = NULL; |
173 #endif | 189 #endif |
174 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 190 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
175 switches::kSingleProcess) || | 191 switches::kSingleProcess) || |
176 base::CommandLine::ForCurrentProcess()->HasSwitch( | 192 base::CommandLine::ForCurrentProcess()->HasSwitch( |
177 switches::kInProcessGPU)); | 193 switches::kInProcessGPU)); |
178 | 194 |
179 // Populate accelerator capabilities (normally done during GpuMain, which is | 195 // Populate accelerator capabilities (normally done during GpuMain, which is |
180 // not called for single process or in process gpu). | 196 // not called for single process or in process gpu). |
(...skipping 24 matching lines...) Expand all Loading... |
205 process_control_.reset(new GpuProcessControlImpl()); | 221 process_control_.reset(new GpuProcessControlImpl()); |
206 // Use of base::Unretained(this) is safe here because |service_registry()| | 222 // Use of base::Unretained(this) is safe here because |service_registry()| |
207 // will be destroyed before GpuChildThread is destructed. | 223 // will be destroyed before GpuChildThread is destructed. |
208 service_registry()->AddService(base::Bind( | 224 service_registry()->AddService(base::Bind( |
209 &GpuChildThread::BindProcessControlRequest, base::Unretained(this))); | 225 &GpuChildThread::BindProcessControlRequest, base::Unretained(this))); |
210 | 226 |
211 if (GetContentClient()->gpu()) // NULL in tests. | 227 if (GetContentClient()->gpu()) // NULL in tests. |
212 GetContentClient()->gpu()->RegisterMojoServices(service_registry()); | 228 GetContentClient()->gpu()->RegisterMojoServices(service_registry()); |
213 } | 229 } |
214 | 230 |
| 231 void GpuChildThread::InitGpuPreferences() { |
| 232 DCHECK(base::CommandLine::InitializedForCurrentProcess()); |
| 233 const base::CommandLine* command_line = |
| 234 base::CommandLine::ForCurrentProcess(); |
| 235 gpu_preferences_.single_process = |
| 236 command_line->HasSwitch(switches::kSingleProcess); |
| 237 gpu_preferences_.in_process_gpu = |
| 238 command_line->HasSwitch(switches::kInProcessGPU); |
| 239 gpu_preferences_.compile_shader_always_succeeds = |
| 240 command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds); |
| 241 gpu_preferences_.disable_gl_error_limit = |
| 242 command_line->HasSwitch(switches::kDisableGLErrorLimit); |
| 243 gpu_preferences_.disable_glsl_translator = |
| 244 command_line->HasSwitch(switches::kDisableGLSLTranslator); |
| 245 gpu_preferences_.disable_gpu_driver_bug_workarounds = |
| 246 command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds); |
| 247 gpu_preferences_.disable_shader_name_hashing = |
| 248 command_line->HasSwitch(switches::kDisableShaderNameHashing); |
| 249 gpu_preferences_.enable_gpu_command_logging = |
| 250 command_line->HasSwitch(switches::kEnableGPUCommandLogging); |
| 251 gpu_preferences_.enable_gpu_debugging = |
| 252 command_line->HasSwitch(switches::kEnableGPUDebugging); |
| 253 gpu_preferences_.enable_gpu_service_logging_gpu = |
| 254 command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU); |
| 255 gpu_preferences_.disable_gpu_program_cache = |
| 256 command_line->HasSwitch(switches::kDisableGpuProgramCache); |
| 257 gpu_preferences_.enforce_gl_minimums = |
| 258 command_line->HasSwitch(switches::kEnforceGLMinimums); |
| 259 if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb, |
| 260 &gpu_preferences_.force_gpu_mem_available)) { |
| 261 gpu_preferences_.force_gpu_mem_available *= 1024 * 1024; |
| 262 } |
| 263 if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb, |
| 264 &gpu_preferences_.gpu_program_cache_size)) { |
| 265 gpu_preferences_.gpu_program_cache_size *= 1024; |
| 266 } |
| 267 gpu_preferences_.enable_share_group_async_texture_upload = |
| 268 command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload); |
| 269 gpu_preferences_.enable_subscribe_uniform_extension = |
| 270 command_line->HasSwitch(switches::kEnableSubscribeUniformExtension); |
| 271 gpu_preferences_.enable_threaded_texture_mailboxes = |
| 272 command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes); |
| 273 gpu_preferences_.gl_shader_interm_output = |
| 274 command_line->HasSwitch(switches::kGLShaderIntermOutput); |
| 275 gpu_preferences_.emulate_shader_precision = |
| 276 command_line->HasSwitch(switches::kEmulateShaderPrecision); |
| 277 gpu_preferences_.enable_gl_path_rendering = |
| 278 command_line->HasSwitch(switches::kEnableGLPathRendering); |
| 279 gpu_preferences_.enable_gpu_service_logging = |
| 280 command_line->HasSwitch(switches::kEnableGPUServiceLogging); |
| 281 gpu_preferences_.enable_gpu_service_tracing = |
| 282 command_line->HasSwitch(switches::kEnableGPUServiceTracing); |
| 283 gpu_preferences_.enable_unsafe_es3_apis = |
| 284 command_line->HasSwitch(switches::kEnableUnsafeES3APIs); |
| 285 } |
| 286 |
215 bool GpuChildThread::Send(IPC::Message* msg) { | 287 bool GpuChildThread::Send(IPC::Message* msg) { |
216 // The GPU process must never send a synchronous IPC message to the browser | 288 // The GPU process must never send a synchronous IPC message to the browser |
217 // process. This could result in deadlock. | 289 // process. This could result in deadlock. |
218 DCHECK(!msg->is_sync()); | 290 DCHECK(!msg->is_sync()); |
219 | 291 |
220 return ChildThreadImpl::Send(msg); | 292 return ChildThreadImpl::Send(msg); |
221 } | 293 } |
222 | 294 |
223 bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) { | 295 bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) { |
224 bool handled = true; | 296 bool handled = true; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } | 422 } |
351 | 423 |
352 // We don't need to pipe log messages if we are running the GPU thread in | 424 // We don't need to pipe log messages if we are running the GPU thread in |
353 // the browser process. | 425 // the browser process. |
354 if (!in_browser_process_) | 426 if (!in_browser_process_) |
355 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); | 427 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); |
356 | 428 |
357 // Defer creation of the render thread. This is to prevent it from handling | 429 // 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 | 430 // IPC messages before the sandbox has been enabled and all other necessary |
359 // initialization has succeeded. | 431 // initialization has succeeded. |
360 gpu_channel_manager_.reset(new GpuChannelManager( | 432 gpu_channel_manager_.reset( |
361 this, watchdog_thread_.get(), base::ThreadTaskRunnerHandle::Get().get(), | 433 new GpuChannelManager(gpu_preferences_, this, watchdog_thread_.get(), |
362 ChildProcess::current()->io_task_runner(), | 434 base::ThreadTaskRunnerHandle::Get().get(), |
363 ChildProcess::current()->GetShutDownEvent(), sync_point_manager_, | 435 ChildProcess::current()->io_task_runner(), |
364 gpu_memory_buffer_factory_)); | 436 ChildProcess::current()->GetShutDownEvent(), |
| 437 sync_point_manager_, gpu_memory_buffer_factory_)); |
365 | 438 |
366 #if defined(USE_OZONE) | 439 #if defined(USE_OZONE) |
367 ui::OzonePlatform::GetInstance() | 440 ui::OzonePlatform::GetInstance() |
368 ->GetGpuPlatformSupport() | 441 ->GetGpuPlatformSupport() |
369 ->OnChannelEstablished(this); | 442 ->OnChannelEstablished(this); |
370 #endif | 443 #endif |
371 } | 444 } |
372 | 445 |
373 void GpuChildThread::OnFinalize() { | 446 void GpuChildThread::OnFinalize() { |
374 // Quit the GPU process | 447 // Quit the GPU process |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 | 598 |
526 void GpuChildThread::BindProcessControlRequest( | 599 void GpuChildThread::BindProcessControlRequest( |
527 mojo::InterfaceRequest<ProcessControl> request) { | 600 mojo::InterfaceRequest<ProcessControl> request) { |
528 DVLOG(1) << "GPU: Binding ProcessControl request"; | 601 DVLOG(1) << "GPU: Binding ProcessControl request"; |
529 DCHECK(process_control_); | 602 DCHECK(process_control_); |
530 process_control_bindings_.AddBinding(process_control_.get(), | 603 process_control_bindings_.AddBinding(process_control_.get(), |
531 std::move(request)); | 604 std::move(request)); |
532 } | 605 } |
533 | 606 |
534 } // namespace content | 607 } // namespace content |
OLD | NEW |