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 26 matching lines...) Expand all Loading... | |
37 #endif | 37 #endif |
38 | 38 |
39 #if defined(USE_X11) | 39 #if defined(USE_X11) |
40 #include "ui/base/x/x11_util.h" | 40 #include "ui/base/x/x11_util.h" |
41 #endif | 41 #endif |
42 | 42 |
43 #if defined(OS_LINUX) | 43 #if defined(OS_LINUX) |
44 #include "content/public/common/sandbox_init.h" | 44 #include "content/public/common/sandbox_init.h" |
45 #endif | 45 #endif |
46 | 46 |
47 namespace { | |
48 void WarmUpSandbox(const content::GPUInfo&, bool); | |
49 void CollectGraphicsInfo(content::GPUInfo*); | |
50 } | |
51 | |
47 // Main function for starting the Gpu process. | 52 // Main function for starting the Gpu process. |
48 int GpuMain(const content::MainFunctionParams& parameters) { | 53 int GpuMain(const content::MainFunctionParams& parameters) { |
49 TRACE_EVENT0("gpu", "GpuMain"); | 54 TRACE_EVENT0("gpu", "GpuMain"); |
50 | 55 |
51 base::Time start_time = base::Time::Now(); | 56 base::Time start_time = base::Time::Now(); |
52 | 57 |
53 const CommandLine& command_line = parameters.command_line; | 58 const CommandLine& command_line = parameters.command_line; |
54 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { | 59 if (command_line.HasSwitch(switches::kGpuStartupDialog)) { |
55 ChildProcess::WaitForDebugger("Gpu"); | 60 ChildProcess::WaitForDebugger("Gpu"); |
56 } | 61 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 success = base::HexStringToInt( | 97 success = base::HexStringToInt( |
93 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), | 98 command_line.GetSwitchValueASCII(switches::kGpuDeviceID), |
94 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); | 99 reinterpret_cast<int*>(&(gpu_info.gpu.device_id))); |
95 DCHECK(success); | 100 DCHECK(success); |
96 gpu_info.driver_vendor = | 101 gpu_info.driver_vendor = |
97 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); | 102 command_line.GetSwitchValueASCII(switches::kGpuDriverVendor); |
98 gpu_info.driver_version = | 103 gpu_info.driver_version = |
99 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); | 104 command_line.GetSwitchValueASCII(switches::kGpuDriverVersion); |
100 content::GetContentClient()->SetGpuInfo(gpu_info); | 105 content::GetContentClient()->SetGpuInfo(gpu_info); |
101 | 106 |
107 // We need to track that information for the WarmUpSandbox function. | |
108 bool initialized_gl_context = false; | |
102 // Load and initialize the GL implementation and locate the GL entry points. | 109 // Load and initialize the GL implementation and locate the GL entry points. |
103 if (gfx::GLSurface::InitializeOneOff()) { | 110 if (gfx::GLSurface::InitializeOneOff()) { |
104 #if defined(OS_LINUX) | 111 #if defined(OS_LINUX) |
105 // We collect full GPU info on demand in Win/Mac, i.e., when about:gpu | 112 // We collect full GPU info on demand in Win/Mac, i.e., when about:gpu |
106 // page opens. This is because we can make blacklist decisions based on | 113 // page opens. This is because we can make blacklist decisions based on |
107 // preliminary GPU info. | 114 // preliminary GPU info. |
108 // However, on Linux, we may not have enough info for blacklisting. | 115 // However, on Linux, we may not have enough info for blacklisting. |
109 if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id || | 116 if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id || |
110 gpu_info.driver_vendor.empty() || gpu_info.driver_version.empty()) { | 117 gpu_info.driver_vendor.empty() || gpu_info.driver_version.empty()) { |
111 if (!gpu_info_collector::CollectGraphicsInfo(&gpu_info)) | 118 CollectGraphicsInfo(&gpu_info); |
112 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; | 119 // We know that CollectGraphicsInfo will initialize a GLContext. |
113 content::GetContentClient()->SetGpuInfo(gpu_info); | 120 initialized_gl_context = true; |
114 } | 121 } |
115 | 122 |
116 #if !defined(OS_CHROMEOS) | 123 #if !defined(OS_CHROMEOS) |
117 if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA | 124 if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA |
118 gpu_info.driver_vendor == "NVIDIA") { | 125 gpu_info.driver_vendor == "NVIDIA") { |
119 base::ThreadRestrictions::AssertIOAllowed(); | 126 base::ThreadRestrictions::AssertIOAllowed(); |
120 if (access("/dev/nvidiactl", R_OK) != 0) { | 127 if (access("/dev/nvidiactl", R_OK) != 0) { |
121 VLOG(1) << "NVIDIA device file /dev/nvidiactl access denied"; | 128 VLOG(1) << "NVIDIA device file /dev/nvidiactl access denied"; |
122 gpu_info.gpu_accessible = false; | 129 gpu_info.gpu_accessible = false; |
123 dead_on_arrival = true; | 130 dead_on_arrival = true; |
124 } | 131 } |
125 } | 132 } |
126 #endif // OS_CHROMEOS | 133 #endif // OS_CHROMEOS |
127 #endif // OS_LINUX | 134 #endif // OS_LINUX |
128 } else { | 135 } else { |
129 VLOG(1) << "gfx::GLSurface::InitializeOneOff failed"; | 136 VLOG(1) << "gfx::GLSurface::InitializeOneOff failed"; |
130 gpu_info.gpu_accessible = false; | 137 gpu_info.gpu_accessible = false; |
131 gpu_info.finalized = true; | 138 gpu_info.finalized = true; |
132 dead_on_arrival = true; | 139 dead_on_arrival = true; |
133 } | 140 } |
134 | 141 |
135 { | 142 { |
136 TRACE_EVENT0("gpu", "Warm up rand"); | 143 const bool should_initialize_gl_context = !initialized_gl_context && |
137 // Warm up the random subsystem, which needs to be done pre-sandbox on all | 144 !dead_on_arrival; |
138 // platforms. | 145 // Warm up the current process before enabling the sandbox. |
139 (void) base::RandUint64(); | 146 WarmUpSandbox(gpu_info, should_initialize_gl_context); |
140 } | |
141 { | |
142 TRACE_EVENT0("gpu", "Warm up HMAC"); | |
143 // Warm up the crypto subsystem, which needs to done pre-sandbox on all | |
144 // platforms. | |
145 crypto::HMAC hmac(crypto::HMAC::SHA256); | |
146 unsigned char key = '\0'; | |
147 bool ret = hmac.Init(&key, sizeof(key)); | |
148 (void) ret; | |
149 } | 147 } |
150 | 148 |
151 #if defined(OS_LINUX) | 149 #if defined(OS_LINUX) |
152 { | 150 { |
153 TRACE_EVENT0("gpu", "Initialize sandbox"); | 151 TRACE_EVENT0("gpu", "Initialize sandbox"); |
154 bool do_init_sandbox = true; | 152 bool do_init_sandbox = true; |
155 | 153 |
156 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | |
157 OmxVideoDecodeAccelerator::PreSandboxInitialization(); | |
158 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | |
159 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); | |
160 #endif | |
161 | |
162 #if defined(OS_CHROMEOS) && defined(NDEBUG) | 154 #if defined(OS_CHROMEOS) && defined(NDEBUG) |
163 // On Chrome OS and when not on a debug build, initialize | 155 // On Chrome OS and when not on a debug build, initialize |
164 // the GPU process' sandbox only for Intel GPUs. | 156 // the GPU process' sandbox only for Intel GPUs. |
165 do_init_sandbox = gpu_info.gpu.vendor_id == 0x8086; // Intel GPU. | 157 do_init_sandbox = gpu_info.gpu.vendor_id == 0x8086; // Intel GPU. |
166 #endif | 158 #endif |
167 | 159 |
168 if (do_init_sandbox) { | 160 if (do_init_sandbox) { |
169 content::InitializeSandbox(); | 161 content::InitializeSandbox(); |
170 } | 162 } |
171 } | 163 } |
172 #endif | 164 #endif |
173 | 165 |
174 { | |
175 TRACE_EVENT0("gpu", "Initialize COM"); | |
176 base::win::ScopedCOMInitializer com_initializer; | |
177 } | |
178 | |
179 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
180 { | 167 { |
181 TRACE_EVENT0("gpu", "Preload setupapi.dll"); | |
182 // Preload this DLL because the sandbox prevents it from loading. | |
183 LoadLibrary(L"setupapi.dll"); | |
184 } | |
185 | |
186 { | |
187 TRACE_EVENT0("gpu", "Initialize DXVA"); | |
188 // Initialize H/W video decoding stuff which fails in the sandbox. | |
189 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | |
190 } | |
191 | |
192 { | |
193 TRACE_EVENT0("gpu", "Lower token"); | 168 TRACE_EVENT0("gpu", "Lower token"); |
194 // For windows, if the target_services interface is not zero, the process | 169 // For windows, if the target_services interface is not zero, the process |
195 // is sandboxed and we must call LowerToken() before rendering untrusted | 170 // is sandboxed and we must call LowerToken() before rendering untrusted |
196 // content. | 171 // content. |
197 sandbox::TargetServices* target_services = | 172 sandbox::TargetServices* target_services = |
198 parameters.sandbox_info->target_services; | 173 parameters.sandbox_info->target_services; |
199 if (target_services) | 174 if (target_services) |
200 target_services->LowerToken(); | 175 target_services->LowerToken(); |
201 } | 176 } |
202 #endif | 177 #endif |
(...skipping 25 matching lines...) Expand all Loading... | |
228 | 203 |
229 { | 204 { |
230 TRACE_EVENT0("gpu", "Run Message Loop"); | 205 TRACE_EVENT0("gpu", "Run Message Loop"); |
231 main_message_loop.Run(); | 206 main_message_loop.Run(); |
232 } | 207 } |
233 | 208 |
234 child_thread->StopWatchdog(); | 209 child_thread->StopWatchdog(); |
235 | 210 |
236 return 0; | 211 return 0; |
237 } | 212 } |
213 | |
214 namespace { | |
215 | |
216 void WarmUpSandbox(const content::GPUInfo& gpu_info, | |
217 bool should_initialize_gl_context) { | |
218 { | |
219 TRACE_EVENT0("gpu", "Warm up rand"); | |
220 // Warm up the random subsystem, which needs to be done pre-sandbox on all | |
221 // platforms. | |
222 (void) base::RandUint64(); | |
223 } | |
224 { | |
225 TRACE_EVENT0("gpu", "Warm up HMAC"); | |
226 // Warm up the crypto subsystem, which needs to done pre-sandbox on all | |
227 // platforms. | |
228 crypto::HMAC hmac(crypto::HMAC::SHA256); | |
229 unsigned char key = '\0'; | |
230 bool ret = hmac.Init(&key, sizeof(key)); | |
231 (void) ret; | |
232 } | |
233 | |
234 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | |
235 OmxVideoDecodeAccelerator::PreSandboxInitialization(); | |
236 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | |
237 VaapiVideoDecodeAccelerator::PreSandboxInitialization(); | |
238 #endif | |
239 | |
240 #if defined(OS_LINUX) | |
241 if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA | |
242 gpu_info.driver_vendor == "NVIDIA" && | |
243 should_initialize_gl_context) { | |
244 scoped_refptr<gfx::GLSurface> surface( | |
245 gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1))); | |
246 if (surface.get()) { | |
247 // On Linux, this is needed to make sure /dev/nvidiactl has | |
248 // been opened and its descriptor cached. | |
249 scoped_refptr<gfx::GLContext> context( | |
250 gfx::GLContext::CreateGLContext(NULL, | |
251 surface, | |
252 gfx::PreferDiscreteGpu)); | |
253 if (context.get()) { | |
254 // Similarly, this is needed for /dev/nvidia0. | |
255 if (context->MakeCurrent(surface)) { | |
256 context->ReleaseCurrent(surface.get()); | |
piman
2012/08/16 18:38:33
nit:indent
| |
257 } else { | |
258 VLOG(1) << "gfx::GLContext::MakeCurrent failed"; | |
259 } | |
260 } else { | |
261 VLOG(1) << "gfx::GLContext::CreateGLContext failed"; | |
262 } | |
263 } else { | |
264 VLOG(1) << "gfx::GLSurface::CreateOffscreenGLSurface failed"; | |
265 } | |
piman
2012/08/16 18:38:33
Is there any way we could avoid all these levels o
| |
266 | |
267 } | |
268 #endif | |
269 | |
270 { | |
271 TRACE_EVENT0("gpu", "Initialize COM"); | |
272 base::win::ScopedCOMInitializer com_initializer; | |
273 } | |
274 | |
275 #if defined(OS_WIN) | |
276 { | |
277 TRACE_EVENT0("gpu", "Preload setupapi.dll"); | |
278 // Preload this DLL because the sandbox prevents it from loading. | |
279 LoadLibrary(L"setupapi.dll"); | |
280 } | |
281 | |
282 { | |
283 TRACE_EVENT0("gpu", "Initialize DXVA"); | |
284 // Initialize H/W video decoding stuff which fails in the sandbox. | |
285 DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | |
286 } | |
287 #endif | |
288 } | |
289 | |
290 void CollectGraphicsInfo(content::GPUInfo* gpu_info) { | |
291 if (!gpu_info_collector::CollectGraphicsInfo(gpu_info)) | |
292 VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; | |
293 content::GetContentClient()->SetGpuInfo(*gpu_info); | |
294 } | |
295 | |
296 } // namespace. | |
297 | |
OLD | NEW |