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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "content/public/common/content_client.h" | 29 #include "content/public/common/content_client.h" |
30 #include "content/public/common/content_switches.h" | 30 #include "content/public/common/content_switches.h" |
31 #include "content/public/common/main_function_params.h" | 31 #include "content/public/common/main_function_params.h" |
32 #include "gpu/command_buffer/service/gpu_switches.h" | 32 #include "gpu/command_buffer/service/gpu_switches.h" |
33 #include "gpu/config/gpu_driver_bug_list.h" | 33 #include "gpu/config/gpu_driver_bug_list.h" |
34 #include "gpu/config/gpu_info_collector.h" | 34 #include "gpu/config/gpu_info_collector.h" |
35 #include "gpu/config/gpu_switches.h" | 35 #include "gpu/config/gpu_switches.h" |
36 #include "gpu/config/gpu_util.h" | 36 #include "gpu/config/gpu_util.h" |
37 #include "gpu/ipc/common/gpu_memory_buffer_support.h" | 37 #include "gpu/ipc/common/gpu_memory_buffer_support.h" |
38 #include "gpu/ipc/service/gpu_config.h" | 38 #include "gpu/ipc/service/gpu_config.h" |
39 #include "gpu/ipc/service/gpu_init.h" | |
39 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" | 40 #include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
40 #include "gpu/ipc/service/gpu_watchdog_thread.h" | 41 #include "gpu/ipc/service/gpu_watchdog_thread.h" |
41 #include "ui/events/platform/platform_event_source.h" | 42 #include "ui/events/platform/platform_event_source.h" |
42 #include "ui/gl/gl_context.h" | 43 #include "ui/gl/gl_context.h" |
43 #include "ui/gl/gl_implementation.h" | 44 #include "ui/gl/gl_implementation.h" |
44 #include "ui/gl/gl_surface.h" | 45 #include "ui/gl/gl_surface.h" |
45 #include "ui/gl/gl_switches.h" | 46 #include "ui/gl/gl_switches.h" |
46 #include "ui/gl/gpu_switching_manager.h" | 47 #include "ui/gl/gpu_switching_manager.h" |
47 #include "ui/gl/init/gl_factory.h" | 48 #include "ui/gl/init/gl_factory.h" |
48 | 49 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 | 85 |
85 #if defined(SANITIZER_COVERAGE) | 86 #if defined(SANITIZER_COVERAGE) |
86 #include <sanitizer/common_interface_defs.h> | 87 #include <sanitizer/common_interface_defs.h> |
87 #include <sanitizer/coverage_interface.h> | 88 #include <sanitizer/coverage_interface.h> |
88 #endif | 89 #endif |
89 | 90 |
90 namespace content { | 91 namespace content { |
91 | 92 |
92 namespace { | 93 namespace { |
93 | 94 |
94 void GetGpuInfoFromCommandLine(gpu::GPUInfo& gpu_info, | |
95 const base::CommandLine& command_line); | |
96 void WarmUpSandbox(); | 95 void WarmUpSandbox(); |
97 | 96 |
98 #if !defined(OS_MACOSX) | |
99 bool CollectGraphicsInfo(gpu::GPUInfo& gpu_info); | |
100 #endif | |
101 | |
102 #if defined(OS_LINUX) | 97 #if defined(OS_LINUX) |
103 #if !defined(OS_CHROMEOS) | 98 bool StartSandboxLinux(gpu::GpuWatchdogThread*); |
104 bool CanAccessNvidiaDeviceFile(); | |
105 #endif | |
106 bool StartSandboxLinux(const gpu::GPUInfo&, gpu::GpuWatchdogThread*); | |
107 #elif defined(OS_WIN) | 99 #elif defined(OS_WIN) |
108 bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*); | 100 bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*); |
109 #endif | 101 #endif |
110 | 102 |
111 base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages = | 103 base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages = |
112 LAZY_INSTANCE_INITIALIZER; | 104 LAZY_INSTANCE_INITIALIZER; |
113 | 105 |
114 bool GpuProcessLogMessageHandler(int severity, | 106 bool GpuProcessLogMessageHandler(int severity, |
115 const char* file, int line, | 107 const char* file, int line, |
116 size_t message_start, | 108 size_t message_start, |
117 const std::string& str) { | 109 const std::string& str) { |
118 std::string header = str.substr(0, message_start); | 110 std::string header = str.substr(0, message_start); |
119 std::string message = str.substr(message_start); | 111 std::string message = str.substr(message_start); |
120 deferred_messages.Get().push( | 112 deferred_messages.Get().push( |
121 new GpuHostMsg_OnLogMessage(severity, header, message)); | 113 new GpuHostMsg_OnLogMessage(severity, header, message)); |
122 return false; | 114 return false; |
123 } | 115 } |
124 | 116 |
117 class ContentSandboxHelper : public gpu::GpuSandboxHelper { | |
118 public: | |
119 ContentSandboxHelper() {} | |
120 ~ContentSandboxHelper() override {} | |
121 | |
122 #if defined(OS_WIN) | |
123 void set_sandbox_info(const sandbox::SandboxInterfaceInfo* info) { | |
124 sandbox_info_ = info; | |
125 } | |
126 #endif | |
127 | |
128 #if defined(OS_LINUX) | |
129 void set_gpu_init(gpu::GpuInit* gpu_init) { gpu_init_ = gpu_init; } | |
130 #endif | |
131 | |
132 private: | |
133 // SandboxHelper: | |
134 void PreSandboxStartup() override { | |
135 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | |
136 media::VaapiWrapper::PreSandboxInitialization(); | |
137 #endif | |
138 | |
139 // Warm up resources that don't need access to GPUInfo. | |
140 WarmUpSandbox(); | |
piman
2016/09/09 03:32:41
nit: maybe just inline WarmupSandbox here?
sadrul
2016/09/09 15:38:04
Done.
| |
141 } | |
142 | |
143 bool EnsureSandboxInitialized() override { | |
144 #if defined(OS_LINUX) | |
145 return StartSandboxLinux(gpu_init_->watchdog_thread()); | |
146 #elif defined(OS_WIN) | |
147 return StartSandboxWindows(sandbox_info_); | |
148 #elif defined(OS_MACOSX) | |
149 return Sandbox::SandboxIsCurrentlyActive(); | |
150 #else | |
151 return false; | |
152 #endif | |
153 } | |
154 | |
155 #if defined(OS_WIN) | |
156 const sandbox::SandboxInterfaceInfo* sandbox_info_ = nullptr; | |
157 #elif defined(OS_LINUX) | |
158 gpu::GpuInit* gpu_init_ = nullptr; | |
159 #endif | |
160 | |
161 DISALLOW_COPY_AND_ASSIGN(ContentSandboxHelper); | |
162 }; | |
163 | |
125 } // namespace anonymous | 164 } // namespace anonymous |
126 | 165 |
127 // Main function for starting the Gpu process. | 166 // Main function for starting the Gpu process. |
128 int GpuMain(const MainFunctionParams& parameters) { | 167 int GpuMain(const MainFunctionParams& parameters) { |
129 TRACE_EVENT0("gpu", "GpuMain"); | 168 TRACE_EVENT0("gpu", "GpuMain"); |
130 base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process"); | 169 base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process"); |
131 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( | 170 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( |
132 kTraceEventGpuProcessSortIndex); | 171 kTraceEventGpuProcessSortIndex); |
133 | 172 |
134 const base::CommandLine& command_line = parameters.command_line; | 173 const base::CommandLine& command_line = parameters.command_line; |
(...skipping 17 matching lines...) Expand all Loading... | |
152 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 191 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
153 switches::kWindowDepth)); | 192 switches::kWindowDepth)); |
154 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 193 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
155 switches::kX11VisualID)); | 194 switches::kX11VisualID)); |
156 #endif | 195 #endif |
157 | 196 |
158 #endif | 197 #endif |
159 | 198 |
160 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); | 199 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); |
161 | 200 |
162 if (command_line.HasSwitch(switches::kSupportsDualGpus)) { | |
163 std::set<int> workarounds; | |
164 gpu::GpuDriverBugList::AppendWorkaroundsFromCommandLine(&workarounds, | |
165 command_line); | |
166 gpu::InitializeDualGpusIfSupported(workarounds); | |
167 } | |
168 | |
169 // Initialization of the OpenGL bindings may fail, in which case we | |
170 // will need to tear down this process. However, we can not do so | |
171 // safely until the IPC channel is set up, because the detection of | |
172 // early return of a child process is implemented using an IPC | |
173 // channel error. If the IPC channel is not fully set up between the | |
174 // browser and GPU process, and the GPU process crashes or exits | |
175 // early, the browser process will never detect it. For this reason | |
176 // we defer tearing down the GPU process until receiving the | |
177 // GpuMsg_Initialize message from the browser. | |
178 bool dead_on_arrival = false; | |
179 | |
180 #if defined(OS_WIN) | 201 #if defined(OS_WIN) |
181 // Use a UI message loop because ANGLE and the desktop GL platform can | 202 // Use a UI message loop because ANGLE and the desktop GL platform can |
182 // create child windows to render to. | 203 // create child windows to render to. |
183 base::MessagePumpForGpu::InitFactory(); | 204 base::MessagePumpForGpu::InitFactory(); |
184 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); | 205 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); |
185 #elif defined(OS_LINUX) && defined(USE_X11) | 206 #elif defined(OS_LINUX) && defined(USE_X11) |
186 // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX | 207 // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX |
187 // and https://crbug.com/326995. | 208 // and https://crbug.com/326995. |
188 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); | 209 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); |
189 std::unique_ptr<ui::PlatformEventSource> event_source = | 210 std::unique_ptr<ui::PlatformEventSource> event_source = |
190 ui::PlatformEventSource::CreateDefault(); | 211 ui::PlatformEventSource::CreateDefault(); |
191 #elif defined(OS_LINUX) | 212 #elif defined(OS_LINUX) |
192 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT); | 213 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT); |
193 #elif defined(OS_MACOSX) | 214 #elif defined(OS_MACOSX) |
194 // This is necessary for CoreAnimation layers hosted in the GPU process to be | 215 // This is necessary for CoreAnimation layers hosted in the GPU process to be |
195 // drawn. See http://crbug.com/312462. | 216 // drawn. See http://crbug.com/312462. |
196 std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop()); | 217 std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop()); |
197 base::MessageLoop main_message_loop(std::move(pump)); | 218 base::MessageLoop main_message_loop(std::move(pump)); |
198 #else | 219 #else |
199 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_IO); | 220 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_IO); |
200 #endif | 221 #endif |
201 | 222 |
202 base::PlatformThread::SetName("CrGpuMain"); | 223 base::PlatformThread::SetName("CrGpuMain"); |
203 | 224 |
204 // In addition to disabling the watchdog if the command line switch is | |
205 // present, disable the watchdog on valgrind because the code is expected | |
206 // to run slowly in that case. | |
207 bool enable_watchdog = | |
208 !command_line.HasSwitch(switches::kDisableGpuWatchdog) && | |
209 !RunningOnValgrind(); | |
210 | |
211 // Disable the watchdog in debug builds because they tend to only be run by | |
212 // developers who will not appreciate the watchdog killing the GPU process. | |
213 #ifndef NDEBUG | |
214 enable_watchdog = false; | |
215 #endif | |
216 | |
217 bool delayed_watchdog_enable = false; | |
218 | |
219 #if defined(OS_CHROMEOS) | |
220 // Don't start watchdog immediately, to allow developers to switch to VT2 on | |
221 // startup. | |
222 delayed_watchdog_enable = true; | |
223 #endif | |
224 | |
225 scoped_refptr<gpu::GpuWatchdogThread> watchdog_thread; | |
226 | |
227 // Start the GPU watchdog only after anything that is expected to be time | |
228 // consuming has completed, otherwise the process is liable to be aborted. | |
229 if (enable_watchdog && !delayed_watchdog_enable) | |
230 watchdog_thread = gpu::GpuWatchdogThread::Create(); | |
231 | |
232 // Initializes StatisticsRecorder which tracks UMA histograms. | 225 // Initializes StatisticsRecorder which tracks UMA histograms. |
233 base::StatisticsRecorder::Initialize(); | 226 base::StatisticsRecorder::Initialize(); |
234 | 227 |
235 gpu::GPUInfo gpu_info; | |
236 // Get vendor_id, device_id, driver_version from browser process through | |
237 // commandline switches. | |
238 GetGpuInfoFromCommandLine(gpu_info, command_line); | |
239 gpu_info.in_process_gpu = false; | |
240 | |
241 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | |
242 media::VaapiWrapper::PreSandboxInitialization(); | |
243 #endif | |
244 | |
245 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 228 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
246 // Set thread priority before sandbox initialization. | 229 // Set thread priority before sandbox initialization. |
247 base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY); | 230 base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY); |
248 #endif | 231 #endif |
249 | 232 |
250 // Warm up resources that don't need access to GPUInfo. | 233 gpu::GpuInit gpu_init; |
251 WarmUpSandbox(); | 234 ContentSandboxHelper sandbox_helper; |
252 | 235 #if defined(OS_WIN) |
253 #if defined(OS_LINUX) | 236 sandbox_helper.set_sandbox_info(parameters.sandbox_info); |
254 bool initialized_sandbox = false; | 237 #elif defined(OS_LINUX) |
255 // On Chrome OS ARM Mali, GPU driver userspace creates threads when | 238 sandbox_helper.set_gpu_init(&gpu_init); |
256 // initializing a GL context, so start the sandbox early. | |
257 if (command_line.HasSwitch(switches::kGpuSandboxStartEarly)) { | |
258 gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get()); | |
259 initialized_sandbox = true; | |
260 } | |
261 #endif // defined(OS_LINUX) | |
262 | |
263 base::TimeTicks before_initialize_one_off = base::TimeTicks::Now(); | |
264 | |
265 // Determine if we need to initialize GL here or it has already been done. | |
266 bool gl_already_initialized = false; | |
267 #if defined(OS_MACOSX) | |
268 if (!command_line.HasSwitch(switches::kNoSandbox)) { | |
269 // On Mac, if the sandbox is enabled, then gl::init::InitializeGLOneOff() | |
270 // is called from the sandbox warmup code before getting here. | |
271 gl_already_initialized = true; | |
272 } | |
273 #endif | |
274 if (command_line.HasSwitch(switches::kInProcessGPU)) { | |
275 // With in-process GPU, gl::init::InitializeGLOneOff() is called from | |
276 // GpuChildThread before getting here. | |
277 gl_already_initialized = true; | |
278 } | |
279 | |
280 // Load and initialize the GL implementation and locate the GL entry points. | |
281 bool gl_initialized = | |
282 gl_already_initialized | |
283 ? gl::GetGLImplementation() != gl::kGLImplementationNone | |
284 : gl::init::InitializeGLOneOff(); | |
285 if (gl_initialized) { | |
286 // We need to collect GL strings (VENDOR, RENDERER) for blacklisting | |
287 // purposes. However, on Mac we don't actually use them. As documented in | |
288 // crbug.com/222934, due to some driver issues, glGetString could take | |
289 // multiple seconds to finish, which in turn cause the GPU process to | |
290 // crash. | |
291 // By skipping the following code on Mac, we don't really lose anything, | |
292 // because the basic GPU information is passed down from browser process | |
293 // and we already registered them through SetGpuInfo() above. | |
294 base::TimeTicks before_collect_context_graphics_info = | |
295 base::TimeTicks::Now(); | |
296 #if !defined(OS_MACOSX) | |
297 if (!CollectGraphicsInfo(gpu_info)) | |
298 dead_on_arrival = true; | |
299 | |
300 // Recompute gpu driver bug workarounds. | |
301 // This is necessary on systems where vendor_id/device_id aren't available | |
302 // (Chrome OS, Android) or where workarounds may be dependent on GL_VENDOR | |
303 // and GL_RENDERER strings which are lazily computed (Linux). | |
304 if (!command_line.HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) { | |
305 // TODO: this can not affect disabled extensions, since they're already | |
306 // initialized in the bindings. This should be moved before bindings | |
307 // initialization. However, populating GPUInfo fully works only on | |
308 // Android. Other platforms would need the bindings to query GL strings. | |
309 gpu::ApplyGpuDriverBugWorkarounds( | |
310 gpu_info, const_cast<base::CommandLine*>(&command_line)); | |
311 } | |
312 #endif // !defined(OS_MACOSX) | |
313 | |
314 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
315 if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA | |
316 gpu_info.driver_vendor == "NVIDIA" && !CanAccessNvidiaDeviceFile()) | |
317 dead_on_arrival = true; | |
318 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | |
319 | |
320 base::TimeDelta collect_context_time = | |
321 base::TimeTicks::Now() - before_collect_context_graphics_info; | |
322 UMA_HISTOGRAM_TIMES("GPU.CollectContextGraphicsInfo", collect_context_time); | |
323 } else { // gl_initialized | |
324 VLOG(1) << "gl::init::InitializeGLOneOff failed"; | |
325 dead_on_arrival = true; | |
326 } | |
327 | |
328 base::TimeDelta initialize_one_off_time = | |
329 base::TimeTicks::Now() - before_initialize_one_off; | |
330 UMA_HISTOGRAM_MEDIUM_TIMES("GPU.InitializeOneOffMediumTime", | |
331 initialize_one_off_time); | |
332 if (enable_watchdog && delayed_watchdog_enable) | |
333 watchdog_thread = gpu::GpuWatchdogThread::Create(); | |
334 | |
335 // OSMesa is expected to run very slowly, so disable the watchdog in that | |
336 // case. | |
337 if (enable_watchdog && | |
338 gl::GetGLImplementation() == gl::kGLImplementationOSMesaGL) { | |
339 watchdog_thread->Stop(); | |
340 watchdog_thread = NULL; | |
341 } | |
342 | |
343 #if defined(OS_LINUX) | |
344 if (!initialized_sandbox) | |
345 gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get()); | |
346 #elif defined(OS_WIN) | |
347 gpu_info.sandboxed = StartSandboxWindows(parameters.sandbox_info); | |
348 #elif defined(OS_MACOSX) | |
349 gpu_info.sandboxed = Sandbox::SandboxIsCurrentlyActive(); | |
350 #endif | 239 #endif |
351 | 240 |
241 gpu_init.set_sandbox_helper(&sandbox_helper); | |
242 gpu_init.InitializeAndStartSandbox(command_line); | |
243 | |
352 logging::SetLogMessageHandler(NULL); | 244 logging::SetLogMessageHandler(NULL); |
245 GetContentClient()->SetGpuInfo(gpu_init.gpu_info()); | |
353 | 246 |
354 std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory; | 247 std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory; |
355 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) | 248 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) |
356 gpu_memory_buffer_factory = gpu::GpuMemoryBufferFactory::CreateNativeType(); | 249 gpu_memory_buffer_factory = gpu::GpuMemoryBufferFactory::CreateNativeType(); |
357 | 250 |
358 base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL; | 251 base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL; |
359 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 252 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
360 io_thread_priority = base::ThreadPriority::DISPLAY; | 253 io_thread_priority = base::ThreadPriority::DISPLAY; |
361 #endif | 254 #endif |
362 | 255 |
363 GpuProcess gpu_process(io_thread_priority); | 256 GpuProcess gpu_process(io_thread_priority); |
364 | 257 |
258 bool dead_on_arrival = gpu_init.dead_on_arrival(); | |
365 GpuChildThread* child_thread = new GpuChildThread( | 259 GpuChildThread* child_thread = new GpuChildThread( |
366 watchdog_thread.get(), dead_on_arrival, gpu_info, deferred_messages.Get(), | 260 gpu_init.watchdog_thread(), dead_on_arrival, gpu_init.gpu_info(), |
367 gpu_memory_buffer_factory.get()); | 261 deferred_messages.Get(), gpu_memory_buffer_factory.get()); |
368 while (!deferred_messages.Get().empty()) | 262 while (!deferred_messages.Get().empty()) |
369 deferred_messages.Get().pop(); | 263 deferred_messages.Get().pop(); |
370 | 264 |
371 child_thread->Init(start_time); | 265 child_thread->Init(start_time); |
372 | 266 |
373 gpu_process.set_main_thread(child_thread); | 267 gpu_process.set_main_thread(child_thread); |
374 | 268 |
375 if (watchdog_thread.get()) | 269 if (gpu_init.watchdog_thread()) |
376 watchdog_thread->AddPowerObserver(); | 270 gpu_init.watchdog_thread()->AddPowerObserver(); |
377 | 271 |
378 #if defined(OS_ANDROID) | 272 #if defined(OS_ANDROID) |
379 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 273 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
380 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics", | 274 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics", |
381 nullptr); | 275 nullptr); |
382 #endif | 276 #endif |
383 | 277 |
384 { | 278 { |
385 TRACE_EVENT0("gpu", "Run Message Loop"); | 279 TRACE_EVENT0("gpu", "Run Message Loop"); |
386 base::RunLoop().Run(); | 280 base::RunLoop().Run(); |
387 } | 281 } |
388 | 282 |
389 child_thread->StopWatchdog(); | 283 child_thread->StopWatchdog(); |
390 | 284 |
391 return dead_on_arrival ? 2 : 0; | 285 return dead_on_arrival ? 2 : 0; |
392 } | 286 } |
393 | 287 |
394 namespace { | 288 namespace { |
395 | 289 |
396 void GetGpuInfoFromCommandLine(gpu::GPUInfo& gpu_info, | |
397 const base::CommandLine& command_line) { | |
398 DCHECK(command_line.HasSwitch(switches::kGpuVendorID) && | |
399 command_line.HasSwitch(switches::kGpuDeviceID) && | |
400 command_line.HasSwitch(switches::kGpuDriverVersion)); | |
401 bool success = base::HexStringToUInt( | |
402 command_line.GetSwitchValueASCII(switches::kGpuVendorID), | |
403 &gpu_info.gpu.vendor_id); | |
404 DCHECK(success); | |
405 success = base::HexStringToUInt( | |
406 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), | |
407 &gpu_info.gpu.device_id); | |
408 DCHECK(success); | |
409 gpu_info.driver_vendor = | |
410 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); | |
411 gpu_info.driver_version = | |
412 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); | |
413 gpu_info.driver_date = | |
414 command_line.GetSwitchValueASCII(switches::kGpuDriverDate); | |
415 gpu::ParseSecondaryGpuDevicesFromCommandLine(command_line, &gpu_info); | |
416 | |
417 // Set active gpu device. | |
418 if (command_line.HasSwitch(switches::kGpuActiveVendorID) && | |
419 command_line.HasSwitch(switches::kGpuActiveDeviceID)) { | |
420 uint32_t active_vendor_id = 0; | |
421 uint32_t active_device_id = 0; | |
422 success = base::HexStringToUInt( | |
423 command_line.GetSwitchValueASCII(switches::kGpuActiveVendorID), | |
424 &active_vendor_id); | |
425 DCHECK(success); | |
426 success = base::HexStringToUInt( | |
427 command_line.GetSwitchValueASCII(switches::kGpuActiveDeviceID), | |
428 &active_device_id); | |
429 DCHECK(success); | |
430 if (gpu_info.gpu.vendor_id == active_vendor_id && | |
431 gpu_info.gpu.device_id == active_device_id) { | |
432 gpu_info.gpu.active = true; | |
433 } else { | |
434 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { | |
435 if (gpu_info.secondary_gpus[i].vendor_id == active_vendor_id && | |
436 gpu_info.secondary_gpus[i].device_id == active_device_id) { | |
437 gpu_info.secondary_gpus[i].active = true; | |
438 break; | |
439 } | |
440 } | |
441 } | |
442 } | |
443 | |
444 GetContentClient()->SetGpuInfo(gpu_info); | |
445 } | |
446 | |
447 void WarmUpSandbox() { | 290 void WarmUpSandbox() { |
448 { | 291 { |
449 TRACE_EVENT0("gpu", "Warm up rand"); | 292 TRACE_EVENT0("gpu", "Warm up rand"); |
450 // Warm up the random subsystem, which needs to be done pre-sandbox on all | 293 // Warm up the random subsystem, which needs to be done pre-sandbox on all |
451 // platforms. | 294 // platforms. |
452 (void) base::RandUint64(); | 295 (void) base::RandUint64(); |
453 } | 296 } |
454 | 297 |
455 #if defined(OS_WIN) | 298 #if defined(OS_WIN) |
456 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | 299 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); |
457 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); | 300 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); |
458 #endif | 301 #endif |
459 } | 302 } |
460 | 303 |
461 #if !defined(OS_MACOSX) | |
462 bool CollectGraphicsInfo(gpu::GPUInfo& gpu_info) { | |
463 TRACE_EVENT0("gpu,startup", "Collect Graphics Info"); | |
464 | |
465 bool res = true; | |
466 gpu::CollectInfoResult result = gpu::CollectContextGraphicsInfo(&gpu_info); | |
467 switch (result) { | |
468 case gpu::kCollectInfoFatalFailure: | |
469 LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal)."; | |
470 res = false; | |
471 break; | |
472 case gpu::kCollectInfoNonFatalFailure: | |
473 DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal)."; | |
474 break; | |
475 case gpu::kCollectInfoNone: | |
476 NOTREACHED(); | |
477 break; | |
478 case gpu::kCollectInfoSuccess: | |
479 break; | |
480 } | |
481 GetContentClient()->SetGpuInfo(gpu_info); | |
482 return res; | |
483 } | |
484 #endif | |
485 | |
486 #if defined(OS_LINUX) | 304 #if defined(OS_LINUX) |
487 #if !defined(OS_CHROMEOS) | 305 bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread) { |
488 bool CanAccessNvidiaDeviceFile() { | |
489 bool res = true; | |
490 base::ThreadRestrictions::AssertIOAllowed(); | |
491 if (access("/dev/nvidiactl", R_OK) != 0) { | |
492 DVLOG(1) << "NVIDIA device file /dev/nvidiactl access denied"; | |
493 res = false; | |
494 } | |
495 return res; | |
496 } | |
497 #endif | |
498 | |
499 bool StartSandboxLinux(const gpu::GPUInfo& gpu_info, | |
500 gpu::GpuWatchdogThread* watchdog_thread) { | |
501 TRACE_EVENT0("gpu,startup", "Initialize sandbox"); | 306 TRACE_EVENT0("gpu,startup", "Initialize sandbox"); |
502 | 307 |
503 bool res = false; | 308 bool res = false; |
504 | 309 |
505 if (watchdog_thread) { | 310 if (watchdog_thread) { |
506 // LinuxSandbox needs to be able to ensure that the thread | 311 // LinuxSandbox needs to be able to ensure that the thread |
507 // has really been stopped. | 312 // has really been stopped. |
508 LinuxSandbox::StopThread(watchdog_thread); | 313 LinuxSandbox::StopThread(watchdog_thread); |
509 } | 314 } |
510 | 315 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 return true; | 349 return true; |
545 } | 350 } |
546 | 351 |
547 return false; | 352 return false; |
548 } | 353 } |
549 #endif // defined(OS_WIN) | 354 #endif // defined(OS_WIN) |
550 | 355 |
551 } // namespace. | 356 } // namespace. |
552 | 357 |
553 } // namespace content | 358 } // namespace content |
OLD | NEW |