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); | |
59 void DoInitializeSandbox(scoped_refptr<GpuWatchdogThread>, GPUInfo&); | |
60 void DoLowerToken(GPUInfo&); | |
58 } | 61 } |
59 | 62 |
60 // Main function for starting the Gpu process. | 63 // Main function for starting the Gpu process. |
61 int GpuMain(const MainFunctionParams& parameters) { | 64 int GpuMain(const MainFunctionParams& parameters) { |
62 TRACE_EVENT0("gpu", "GpuMain"); | 65 TRACE_EVENT0("gpu", "GpuMain"); |
63 | 66 |
64 base::Time start_time = base::Time::Now(); | 67 base::Time start_time = base::Time::Now(); |
65 | 68 |
66 const CommandLine& command_line = parameters.command_line; | 69 const CommandLine& command_line = parameters.command_line; |
67 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { | 70 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 success = base::HexStringToInt( | 166 success = base::HexStringToInt( |
164 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), | 167 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), |
165 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); | 168 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); |
166 DCHECK(success); | 169 DCHECK(success); |
167 gpu_info.driver_vendor = | 170 gpu_info.driver_vendor = |
168 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); | 171 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); |
169 gpu_info.driver_version = | 172 gpu_info.driver_version = |
170 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); | 173 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); |
171 GetContentClient()->SetGpuInfo(gpu_info); | 174 GetContentClient()->SetGpuInfo(gpu_info); |
172 | 175 |
173 // We need to track that information for the WarmUpSandbox function. | 176 WarmUpSandboxInitial(); |
177 | |
178 bool initialized_sandbox = false; | |
179 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | |
jln (very slow on Chromium)
2013/04/16 19:45:54
Are these ifdef really the best way ? Can we have
Jorge Lucangeli Obes
2013/04/16 21:26:29
The only way I see to have driver information at t
| |
180 DoInitializeSandbox(watchdog_thread, gpu_info); | |
181 initialized_sandbox = true; | |
182 #endif | |
183 | |
184 // We need to track this information for the WarmUpSandbox function. | |
174 bool initialized_gl_context = false; | 185 bool initialized_gl_context = false; |
175 // Load and initialize the GL implementation and locate the GL entry points. | 186 // Load and initialize the GL implementation and locate the GL entry points. |
176 if (gfx::GLSurface::InitializeOneOff()) { | 187 if (gfx::GLSurface::InitializeOneOff()) { |
177 // We need to collect GL strings (VENDOR, RENDERER) for blacklisting | 188 // We need to collect GL strings (VENDOR, RENDERER) for blacklisting |
178 // purpose. However, on Mac we don't actually use them. As documented in | 189 // 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 | 190 // 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. | 191 // 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, | 192 // 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 | 193 // because the basic GPU information is passed down from browser process |
183 // and we already registered them through SetGpuInfo() above. | 194 // and we already registered them through SetGpuInfo() above. |
184 #if !defined(OS_MACOSX) | 195 #if !defined(OS_MACOSX) |
185 if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info)) | 196 if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info)) |
186 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; | 197 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; |
187 GetContentClient()->SetGpuInfo(gpu_info); | 198 GetContentClient()->SetGpuInfo(gpu_info); |
188 | 199 |
(...skipping 26 matching lines...) Expand all Loading... | |
215 | 226 |
216 // OSMesa is expected to run very slowly, so disable the watchdog in that | 227 // OSMesa is expected to run very slowly, so disable the watchdog in that |
217 // case. | 228 // case. |
218 if (enable_watchdog && | 229 if (enable_watchdog && |
219 gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) { | 230 gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) { |
220 watchdog_thread->Stop(); | 231 watchdog_thread->Stop(); |
221 | 232 |
222 watchdog_thread = NULL; | 233 watchdog_thread = NULL; |
223 } | 234 } |
224 | 235 |
225 { | 236 const bool should_initialize_gl_context = !initialized_gl_context && |
226 const bool should_initialize_gl_context = !initialized_gl_context && | 237 !dead_on_arrival; |
227 !dead_on_arrival; | 238 // Finish warming up the current process. |
228 // Warm up the current process before enabling the sandbox. | 239 WarmUpSandboxComplete(gpu_info, should_initialize_gl_context); |
229 WarmUpSandbox(gpu_info, should_initialize_gl_context); | |
230 } | |
231 | 240 |
232 #if defined(OS_LINUX) | 241 #if defined(OS_LINUX) |
233 { | 242 if (!initialized_sandbox) |
jln (very slow on Chromium)
2013/04/16 19:45:54
Wouldn't it make sense to also move "WarmUpSandbox
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
234 TRACE_EVENT0("gpu", "Initialize sandbox"); | 243 DoInitializeSandbox(watchdog_thread, gpu_info); |
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 | 244 #endif |
252 | 245 |
253 #if defined(OS_WIN) | 246 #if defined(OS_WIN) |
254 { | 247 DoLowerToken(gpu_info); |
jln (very slow on Chromium)
2013/04/16 19:45:54
Maybe rename to StartWindowsSandbox() ? It's quite
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
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 | 248 #endif |
267 | 249 |
268 GpuProcess gpu_process; | 250 GpuProcess gpu_process; |
269 | 251 |
270 GpuChildThread* child_thread = new GpuChildThread(watchdog_thread.get(), | 252 GpuChildThread* child_thread = new GpuChildThread(watchdog_thread.get(), |
271 dead_on_arrival, gpu_info); | 253 dead_on_arrival, gpu_info); |
272 | 254 |
273 child_thread->Init(start_time); | 255 child_thread->Init(start_time); |
274 | 256 |
275 gpu_process.set_main_thread(child_thread); | 257 gpu_process.set_main_thread(child_thread); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 | 290 |
309 // Similarly, this is needed for /dev/nvidia0. | 291 // Similarly, this is needed for /dev/nvidia0. |
310 if (context->MakeCurrent(surface)) { | 292 if (context->MakeCurrent(surface)) { |
311 context->ReleaseCurrent(surface.get()); | 293 context->ReleaseCurrent(surface.get()); |
312 } else { | 294 } else { |
313 VLOG(1) << "gfx::GLContext::MakeCurrent failed"; | 295 VLOG(1) << "gfx::GLContext::MakeCurrent failed"; |
314 } | 296 } |
315 } | 297 } |
316 #endif | 298 #endif |
317 | 299 |
318 void WarmUpSandbox(const GPUInfo& gpu_info, | 300 void WarmUpSandboxInitial() { |
319 bool should_initialize_gl_context) { | |
320 { | 301 { |
321 TRACE_EVENT0("gpu", "Warm up rand"); | 302 TRACE_EVENT0("gpu", "Warm up rand"); |
322 // Warm up the random subsystem, which needs to be done pre-sandbox on all | 303 // Warm up the random subsystem, which needs to be done pre-sandbox on all |
323 // platforms. | 304 // platforms. |
324 (void) base::RandUint64(); | 305 (void) base::RandUint64(); |
325 } | 306 } |
326 { | 307 { |
327 TRACE_EVENT0("gpu", "Warm up HMAC"); | 308 TRACE_EVENT0("gpu", "Warm up HMAC"); |
328 // Warm up the crypto subsystem, which needs to done pre-sandbox on all | 309 // Warm up the crypto subsystem, which needs to done pre-sandbox on all |
329 // platforms. | 310 // platforms. |
330 crypto::HMAC hmac(crypto::HMAC::SHA256); | 311 crypto::HMAC hmac(crypto::HMAC::SHA256); |
331 unsigned char key = '\0'; | 312 unsigned char key = '\0'; |
332 bool ret = hmac.Init(&key, sizeof(key)); | 313 bool ret = hmac.Init(&key, sizeof(key)); |
333 (void) ret; | 314 (void) ret; |
334 } | 315 } |
335 | 316 |
336 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) | 317 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) |
337 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda)) | 318 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda)) |
338 ExynosVideoDecodeAccelerator::PreSandboxInitialization(); | 319 ExynosVideoDecodeAccelerator::PreSandboxInitialization(); |
339 else | 320 else |
340 OmxVideoDecodeAccelerator::PreSandboxInitialization(); | 321 OmxVideoDecodeAccelerator::PreSandboxInitialization(); |
341 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 322 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
342 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); | 323 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); |
343 #endif | 324 #endif |
344 | 325 |
345 #if defined(OS_LINUX) | |
346 // 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. | |
348 gpu_info.driver_vendor == "NVIDIA") || | |
349 gpu_info.optimus; | |
350 if (uses_nvidia_driver && should_initialize_gl_context) { | |
351 // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0. | |
352 CreateDummyGlContext(); | |
353 } | |
354 #endif | |
355 | |
356 #if defined(OS_WIN) | 326 #if defined(OS_WIN) |
357 { | 327 { |
358 TRACE_EVENT0("gpu", "Preload setupapi.dll"); | 328 TRACE_EVENT0("gpu", "Preload setupapi.dll"); |
359 // Preload this DLL because the sandbox prevents it from loading. | 329 // Preload this DLL because the sandbox prevents it from loading. |
360 LoadLibrary(L"setupapi.dll"); | 330 LoadLibrary(L"setupapi.dll"); |
361 } | 331 } |
362 | 332 |
363 { | 333 { |
364 TRACE_EVENT0("gpu", "Initialize DXVA"); | 334 TRACE_EVENT0("gpu", "Initialize DXVA"); |
365 // Initialize H/W video decoding stuff which fails in the sandbox. | 335 // Initialize H/W video decoding stuff which fails in the sandbox. |
366 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | 336 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); |
367 } | 337 } |
368 #endif | 338 #endif |
369 } | 339 } |
370 | 340 |
341 void WarmUpSandboxComplete(const GPUInfo& gpu_info, | |
jln (very slow on Chromium)
2013/04/16 19:45:54
Nit: for some reason I have the impression that Wa
| |
342 bool should_initialize_gl_context) { | |
343 #if defined(OS_LINUX) | |
344 // We special case Optimus since the vendor_id we see may not be Nvidia. | |
345 bool uses_nvidia_driver = (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA. | |
346 gpu_info.driver_vendor == "NVIDIA") || | |
347 gpu_info.optimus; | |
348 if (uses_nvidia_driver && should_initialize_gl_context) { | |
349 // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0. | |
350 CreateDummyGlContext(); | |
351 } | |
352 #endif | |
353 } | |
354 | |
355 #if defined(OS_LINUX) | |
356 void DoInitializeSandbox(scoped_refptr<GpuWatchdogThread> watchdog_thread, | |
jln (very slow on Chromium)
2013/04/16 19:45:54
I think a raw pointer to the watchdog_thread is be
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
357 GPUInfo& gpu_info) { | |
jln (very slow on Chromium)
2013/04/16 19:45:54
Non const references are evil (and forbidden). Jus
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
358 TRACE_EVENT0("gpu", "Initialize sandbox"); | |
359 | |
360 if (watchdog_thread.get()) | |
361 watchdog_thread->Stop(); | |
jln (very slow on Chromium)
2013/04/16 19:45:54
Do you want to take this opportunity to add a comm
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
362 gpu_info.sandboxed = LinuxSandbox::InitializeSandbox(); | |
363 if (watchdog_thread.get()) | |
364 watchdog_thread->Start(); | |
365 } | |
366 #endif | |
367 | |
368 #if defined(OS_WIN) | |
369 bool DoLowerToken(GPUInfo& gpu_info) { | |
jln (very slow on Chromium)
2013/04/16 19:45:54
Same remark regarding non const references.
Jorge Lucangeli Obes
2013/04/16 21:26:29
Done.
| |
370 TRACE_EVENT0("gpu", "Lower token"); | |
371 // For Windows, if the target_services interface is not zero, the process | |
372 // is sandboxed and we must call LowerToken() before rendering untrusted | |
373 // content. | |
374 sandbox::TargetServices* target_services = | |
375 parameters.sandbox_info->target_services; | |
376 if (target_services) { | |
377 target_services->LowerToken(); | |
378 gpu_info.sandboxed = true; | |
379 } | |
380 } | |
381 #endif | |
382 | |
371 } // namespace. | 383 } // namespace. |
372 | 384 |
373 } // namespace content | 385 } // namespace content |
OLD | NEW |