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 <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 #endif | 47 #endif |
48 | 48 |
49 #if defined(OS_LINUX) | 49 #if defined(OS_LINUX) |
50 #include "content/public/common/sandbox_init.h" | 50 #include "content/public/common/sandbox_init.h" |
51 #endif | 51 #endif |
52 | 52 |
53 const int kGpuTimeout = 10000; | 53 const int kGpuTimeout = 10000; |
54 | 54 |
55 namespace content { | 55 namespace content { |
56 namespace { | 56 namespace { |
57 void WarmUpSandbox(const GPUInfo&, bool); | 57 void WarmUpSandboxInitial(); |
58 void WarmUpSandboxComplete(const GPUInfo&, bool); | |
sheu
2013/04/16 21:47:39
WarmUpSandboxComplete() is only used (and only def
| |
59 #if defined(OS_LINUX) | |
60 bool StartSandboxLinux(GpuWatchdogThread*); | |
61 #elif defined(OS_WIN) | |
62 bool StartSandboxWindows(); | |
63 #endif | |
58 } | 64 } |
59 | 65 |
60 // Main function for starting the Gpu process. | 66 // Main function for starting the Gpu process. |
61 int GpuMain(const MainFunctionParams& parameters) { | 67 int GpuMain(const MainFunctionParams& parameters) { |
62 TRACE_EVENT0("gpu", "GpuMain"); | 68 TRACE_EVENT0("gpu", "GpuMain"); |
63 | 69 |
64 base::Time start_time = base::Time::Now(); | 70 base::Time start_time = base::Time::Now(); |
65 | 71 |
66 const CommandLine& command_line = parameters.command_line; | 72 const CommandLine& command_line = parameters.command_line; |
67 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { | 73 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 success = base::HexStringToInt( | 169 success = base::HexStringToInt( |
164 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), | 170 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), |
165 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); | 171 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); |
166 DCHECK(success); | 172 DCHECK(success); |
167 gpu_info.driver_vendor = | 173 gpu_info.driver_vendor = |
168 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); | 174 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); |
169 gpu_info.driver_version = | 175 gpu_info.driver_version = |
170 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); | 176 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); |
171 GetContentClient()->SetGpuInfo(gpu_info); | 177 GetContentClient()->SetGpuInfo(gpu_info); |
172 | 178 |
173 // We need to track that information for the WarmUpSandbox function. | 179 // Warm up resources that don't need access to GPUInfo. |
180 WarmUpSandboxInitial(); | |
181 | |
182 bool initialized_sandbox = false; | |
183 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | |
jln (very slow on Chromium)
2013/04/16 21:32:22
Maybe owners can suggest something better to do he
| |
184 // On Chrome OS ARM, GPU driver userspace creates threads when initializing | |
185 // a GL context, so start the sandbox early. | |
186 gpu_info.sandboxed = StartSandboxLinux(watchdog_thread.get()); | |
187 initialized_sandbox = true; | |
188 #endif | |
189 | |
190 // We need to track this information for the WarmUpSandboxComplete function. | |
174 bool initialized_gl_context = false; | 191 bool initialized_gl_context = false; |
175 // Load and initialize the GL implementation and locate the GL entry points. | 192 // Load and initialize the GL implementation and locate the GL entry points. |
176 if (gfx::GLSurface::InitializeOneOff()) { | 193 if (gfx::GLSurface::InitializeOneOff()) { |
177 // We need to collect GL strings (VENDOR, RENDERER) for blacklisting | 194 // We need to collect GL strings (VENDOR, RENDERER) for blacklisting |
178 // purpose. However, on Mac we don't actually use them. As documented in | 195 // purposes. However, on Mac we don't actually use them. As documented in |
179 // crbug.com/222934, due to some driver issues, glGetString could take | 196 // crbug.com/222934, due to some driver issues, glGetString could take |
180 // multiple seconds to finish, which in turn cause the GPU process to crash. | 197 // multiple seconds to finish, which in turn cause the GPU process to crash. |
181 // By skipping the following code on Mac, we don't really lose anything, | 198 // By skipping the following code on Mac, we don't really lose anything, |
182 // because the basic GPU information is passed down from browser process | 199 // because the basic GPU information is passed down from browser process |
183 // and we already registered them through SetGpuInfo() above. | 200 // and we already registered them through SetGpuInfo() above. |
184 #if !defined(OS_MACOSX) | 201 #if !defined(OS_MACOSX) |
185 if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info)) | 202 if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info)) |
186 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; | 203 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; |
187 GetContentClient()->SetGpuInfo(gpu_info); | 204 GetContentClient()->SetGpuInfo(gpu_info); |
188 | 205 |
(...skipping 26 matching lines...) Expand all Loading... | |
215 | 232 |
216 // OSMesa is expected to run very slowly, so disable the watchdog in that | 233 // OSMesa is expected to run very slowly, so disable the watchdog in that |
217 // case. | 234 // case. |
218 if (enable_watchdog && | 235 if (enable_watchdog && |
219 gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) { | 236 gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) { |
220 watchdog_thread->Stop(); | 237 watchdog_thread->Stop(); |
221 | 238 |
222 watchdog_thread = NULL; | 239 watchdog_thread = NULL; |
223 } | 240 } |
224 | 241 |
225 { | 242 #if defined(OS_LINUX) |
226 const bool should_initialize_gl_context = !initialized_gl_context && | 243 const bool should_initialize_gl_context = !initialized_gl_context && |
227 !dead_on_arrival; | 244 !dead_on_arrival; |
228 // Warm up the current process before enabling the sandbox. | 245 |
229 WarmUpSandbox(gpu_info, should_initialize_gl_context); | 246 if (!initialized_sandbox) { |
247 // Finish warming up the current process. | |
248 WarmUpSandboxComplete(gpu_info, should_initialize_gl_context); | |
249 gpu_info.sandboxed = StartSandboxLinux(watchdog_thread); | |
230 } | 250 } |
231 | 251 #elif defined(OS_WIN) |
232 #if defined(OS_LINUX) | 252 gpu_info.sandboxed = StartSandboxWindows(); |
233 { | |
234 TRACE_EVENT0("gpu", "Initialize sandbox"); | |
235 bool do_init_sandbox = true; | |
236 | |
237 #if defined(OS_CHROMEOS) && defined(NDEBUG) | |
238 // On Chrome OS and when not on a debug build, initialize | |
239 // the GPU process' sandbox only for Intel GPUs. | |
240 do_init_sandbox = gpu_info.gpu.vendor_id == 0x8086; // Intel GPU. | |
241 #endif | |
242 | |
243 if (do_init_sandbox) { | |
244 if (watchdog_thread.get()) | |
245 watchdog_thread->Stop(); | |
246 gpu_info.sandboxed = LinuxSandbox::InitializeSandbox(); | |
247 if (watchdog_thread.get()) | |
248 watchdog_thread->Start(); | |
249 } | |
250 } | |
251 #endif | |
252 | |
253 #if defined(OS_WIN) | |
254 { | |
255 TRACE_EVENT0("gpu", "Lower token"); | |
256 // For windows, if the target_services interface is not zero, the process | |
257 // is sandboxed and we must call LowerToken() before rendering untrusted | |
258 // content. | |
259 sandbox::TargetServices* target_services = | |
260 parameters.sandbox_info->target_services; | |
261 if (target_services) { | |
262 target_services->LowerToken(); | |
263 gpu_info.sandboxed = true; | |
264 } | |
265 } | |
266 #endif | 253 #endif |
267 | 254 |
268 GpuProcess gpu_process; | 255 GpuProcess gpu_process; |
269 | 256 |
270 GpuChildThread* child_thread = new GpuChildThread(watchdog_thread.get(), | 257 GpuChildThread* child_thread = new GpuChildThread(watchdog_thread.get(), |
271 dead_on_arrival, gpu_info); | 258 dead_on_arrival, gpu_info); |
272 | 259 |
273 child_thread->Init(start_time); | 260 child_thread->Init(start_time); |
274 | 261 |
275 gpu_process.set_main_thread(child_thread); | 262 gpu_process.set_main_thread(child_thread); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 | 295 |
309 // Similarly, this is needed for /dev/nvidia0. | 296 // Similarly, this is needed for /dev/nvidia0. |
310 if (context->MakeCurrent(surface)) { | 297 if (context->MakeCurrent(surface)) { |
311 context->ReleaseCurrent(surface.get()); | 298 context->ReleaseCurrent(surface.get()); |
312 } else { | 299 } else { |
313 VLOG(1) << "gfx::GLContext::MakeCurrent failed"; | 300 VLOG(1) << "gfx::GLContext::MakeCurrent failed"; |
314 } | 301 } |
315 } | 302 } |
316 #endif | 303 #endif |
317 | 304 |
318 void WarmUpSandbox(const GPUInfo& gpu_info, | 305 void WarmUpSandboxInitial() { |
319 bool should_initialize_gl_context) { | |
320 { | 306 { |
321 TRACE_EVENT0("gpu", "Warm up rand"); | 307 TRACE_EVENT0("gpu", "Warm up rand"); |
322 // Warm up the random subsystem, which needs to be done pre-sandbox on all | 308 // Warm up the random subsystem, which needs to be done pre-sandbox on all |
323 // platforms. | 309 // platforms. |
324 (void) base::RandUint64(); | 310 (void) base::RandUint64(); |
325 } | 311 } |
326 { | 312 { |
327 TRACE_EVENT0("gpu", "Warm up HMAC"); | 313 TRACE_EVENT0("gpu", "Warm up HMAC"); |
328 // Warm up the crypto subsystem, which needs to done pre-sandbox on all | 314 // Warm up the crypto subsystem, which needs to done pre-sandbox on all |
329 // platforms. | 315 // platforms. |
330 crypto::HMAC hmac(crypto::HMAC::SHA256); | 316 crypto::HMAC hmac(crypto::HMAC::SHA256); |
331 unsigned char key = '\0'; | 317 unsigned char key = '\0'; |
332 bool ret = hmac.Init(&key, sizeof(key)); | 318 bool ret = hmac.Init(&key, sizeof(key)); |
333 (void) ret; | 319 (void) ret; |
334 } | 320 } |
335 | 321 |
336 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) | 322 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) |
337 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda)) | 323 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda)) |
338 ExynosVideoDecodeAccelerator::PreSandboxInitialization(); | 324 ExynosVideoDecodeAccelerator::PreSandboxInitialization(); |
339 else | 325 else |
340 OmxVideoDecodeAccelerator::PreSandboxInitialization(); | 326 OmxVideoDecodeAccelerator::PreSandboxInitialization(); |
341 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 327 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
342 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); | 328 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); |
343 #endif | 329 #endif |
344 | 330 |
331 #if defined(OS_WIN) | |
332 { | |
333 TRACE_EVENT0("gpu", "Preload setupapi.dll"); | |
334 // Preload this DLL because the sandbox prevents it from loading. | |
335 LoadLibrary(L"setupapi.dll"); | |
336 } | |
337 | |
338 { | |
339 TRACE_EVENT0("gpu", "Initialize DXVA"); | |
340 // Initialize H/W video decoding stuff which fails in the sandbox. | |
341 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | |
342 } | |
343 #endif | |
344 } | |
345 | |
345 #if defined(OS_LINUX) | 346 #if defined(OS_LINUX) |
347 void WarmUpSandboxComplete(const GPUInfo& gpu_info, | |
348 bool should_initialize_gl_context) { | |
sheu
2013/04/16 21:47:39
WarmUpSandboxComplete() seems to be NVIDIA-specifi
Jorge Lucangeli Obes
2013/04/16 22:39:57
Before making it Linux-only due to its code, the p
| |
346 // We special case Optimus since the vendor_id we see may not be Nvidia. | 349 // We special case Optimus since the vendor_id we see may not be Nvidia. |
347 bool uses_nvidia_driver = (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA. | 350 bool uses_nvidia_driver = (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA. |
348 gpu_info.driver_vendor == "NVIDIA") || | 351 gpu_info.driver_vendor == "NVIDIA") || |
349 gpu_info.optimus; | 352 gpu_info.optimus; |
350 if (uses_nvidia_driver && should_initialize_gl_context) { | 353 if (uses_nvidia_driver && should_initialize_gl_context) { |
351 // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0. | 354 // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0. |
352 CreateDummyGlContext(); | 355 CreateDummyGlContext(); |
353 } | 356 } |
357 } | |
358 | |
359 bool StartSandboxLinux(GpuWatchdogThread* watchdog_thread) { | |
360 TRACE_EVENT0("gpu", "Initialize sandbox"); | |
361 | |
362 bool res = false; | |
363 | |
364 if (watchdog_thread) | |
365 watchdog_thread->Stop(); | |
366 // LinuxSandbox::InitializeSandbox() must always be called | |
367 // with only one thread. | |
368 res = LinuxSandbox::InitializeSandbox(); | |
369 if (watchdog_thread) | |
370 watchdog_thread->Start(); | |
371 | |
372 return res; | |
373 } | |
354 #endif | 374 #endif |
jln (very slow on Chromium)
2013/04/16 21:32:22
style: add // defined(OS_LINUX)
Jorge Lucangeli Obes
2013/04/16 21:40:31
Done.
| |
355 | 375 |
356 #if defined(OS_WIN) | 376 #if defined(OS_WIN) |
357 { | 377 bool StartSandboxWindows() { |
358 TRACE_EVENT0("gpu", "Preload setupapi.dll"); | 378 TRACE_EVENT0("gpu", "Lower token"); |
359 // Preload this DLL because the sandbox prevents it from loading. | 379 |
360 LoadLibrary(L"setupapi.dll"); | 380 // For Windows, if the target_services interface is not zero, the process |
381 // is sandboxed and we must call LowerToken() before rendering untrusted | |
382 // content. | |
383 sandbox::TargetServices* target_services = | |
384 parameters.sandbox_info->target_services; | |
jln (very slow on Chromium)
2013/04/16 21:33:52
Looks like you'll need to take this as a parameter
Jorge Lucangeli Obes
2013/04/16 21:40:31
Done.
| |
385 if (target_services) { | |
386 target_services->LowerToken(); | |
387 return true: | |
361 } | 388 } |
362 | 389 |
363 { | 390 return false; |
364 TRACE_EVENT0("gpu", "Initialize DXVA"); | 391 } |
365 // Initialize H/W video decoding stuff which fails in the sandbox. | |
366 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | |
367 } | |
368 #endif | 392 #endif |
jln (very slow on Chromium)
2013/04/16 21:32:22
style: add // defined(OS_WIN)
Jorge Lucangeli Obes
2013/04/16 21:40:31
Done.
| |
369 } | |
370 | 393 |
371 } // namespace. | 394 } // namespace. |
372 | 395 |
373 } // namespace content | 396 } // namespace content |
OLD | NEW |