Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: content/gpu/gpu_main.cc

Issue 2322123002: gpu: Introduce GpuInit. (Closed)
Patch Set: . Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/gpu/gpu_child_thread.h ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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();
97
98 #if !defined(OS_MACOSX)
99 bool CollectGraphicsInfo(gpu::GPUInfo& gpu_info);
100 #endif
101
102 #if defined(OS_LINUX) 95 #if defined(OS_LINUX)
103 #if !defined(OS_CHROMEOS) 96 bool StartSandboxLinux(gpu::GpuWatchdogThread*);
104 bool CanAccessNvidiaDeviceFile();
105 #endif
106 bool StartSandboxLinux(const gpu::GPUInfo&, gpu::GpuWatchdogThread*);
107 #elif defined(OS_WIN) 97 #elif defined(OS_WIN)
108 bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*); 98 bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
109 #endif 99 #endif
110 100
111 base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages = 101 base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages =
112 LAZY_INSTANCE_INITIALIZER; 102 LAZY_INSTANCE_INITIALIZER;
113 103
114 bool GpuProcessLogMessageHandler(int severity, 104 bool GpuProcessLogMessageHandler(int severity,
115 const char* file, int line, 105 const char* file, int line,
116 size_t message_start, 106 size_t message_start,
117 const std::string& str) { 107 const std::string& str) {
118 std::string header = str.substr(0, message_start); 108 std::string header = str.substr(0, message_start);
119 std::string message = str.substr(message_start); 109 std::string message = str.substr(message_start);
120 deferred_messages.Get().push( 110 deferred_messages.Get().push(
121 new GpuHostMsg_OnLogMessage(severity, header, message)); 111 new GpuHostMsg_OnLogMessage(severity, header, message));
122 return false; 112 return false;
123 } 113 }
124 114
115 class ContentSandboxHelper : public gpu::GpuSandboxHelper {
116 public:
117 ContentSandboxHelper() {}
118 ~ContentSandboxHelper() override {}
119
120 #if defined(OS_WIN)
121 void set_sandbox_info(const sandbox::SandboxInterfaceInfo* info) {
122 sandbox_info_ = info;
123 }
124 #endif
125
126 #if defined(OS_LINUX)
127 void set_gpu_init(gpu::GpuInit* gpu_init) { gpu_init_ = gpu_init; }
128 #endif
129
130 private:
131 // SandboxHelper:
132 void PreSandboxStartup() override {
133 // Warm up resources that don't need access to GPUInfo.
134 {
135 TRACE_EVENT0("gpu", "Warm up rand");
136 // Warm up the random subsystem, which needs to be done pre-sandbox on all
137 // platforms.
138 (void)base::RandUint64();
139 }
140
141 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
142 media::VaapiWrapper::PreSandboxInitialization();
143 #endif
144 #if defined(OS_WIN)
145 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
146 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
147 #endif
148 }
149
150 bool EnsureSandboxInitialized() override {
151 #if defined(OS_LINUX)
152 return StartSandboxLinux(gpu_init_->watchdog_thread());
153 #elif defined(OS_WIN)
154 return StartSandboxWindows(sandbox_info_);
155 #elif defined(OS_MACOSX)
156 return Sandbox::SandboxIsCurrentlyActive();
157 #else
158 return false;
159 #endif
160 }
161
162 #if defined(OS_WIN)
163 const sandbox::SandboxInterfaceInfo* sandbox_info_ = nullptr;
164 #elif defined(OS_LINUX)
165 gpu::GpuInit* gpu_init_ = nullptr;
166 #endif
167
168 DISALLOW_COPY_AND_ASSIGN(ContentSandboxHelper);
169 };
170
125 } // namespace anonymous 171 } // namespace anonymous
126 172
127 // Main function for starting the Gpu process. 173 // Main function for starting the Gpu process.
128 int GpuMain(const MainFunctionParams& parameters) { 174 int GpuMain(const MainFunctionParams& parameters) {
129 TRACE_EVENT0("gpu", "GpuMain"); 175 TRACE_EVENT0("gpu", "GpuMain");
130 base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process"); 176 base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process");
131 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( 177 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
132 kTraceEventGpuProcessSortIndex); 178 kTraceEventGpuProcessSortIndex);
133 179
134 const base::CommandLine& command_line = parameters.command_line; 180 const base::CommandLine& command_line = parameters.command_line;
(...skipping 17 matching lines...) Expand all
152 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 198 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
153 switches::kWindowDepth)); 199 switches::kWindowDepth));
154 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 200 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
155 switches::kX11VisualID)); 201 switches::kX11VisualID));
156 #endif 202 #endif
157 203
158 #endif 204 #endif
159 205
160 logging::SetLogMessageHandler(GpuProcessLogMessageHandler); 206 logging::SetLogMessageHandler(GpuProcessLogMessageHandler);
161 207
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) 208 #if defined(OS_WIN)
181 // Use a UI message loop because ANGLE and the desktop GL platform can 209 // Use a UI message loop because ANGLE and the desktop GL platform can
182 // create child windows to render to. 210 // create child windows to render to.
183 base::MessagePumpForGpu::InitFactory(); 211 base::MessagePumpForGpu::InitFactory();
184 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); 212 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
185 #elif defined(OS_LINUX) && defined(USE_X11) 213 #elif defined(OS_LINUX) && defined(USE_X11)
186 // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX 214 // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX
187 // and https://crbug.com/326995. 215 // and https://crbug.com/326995.
188 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI); 216 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
189 std::unique_ptr<ui::PlatformEventSource> event_source = 217 std::unique_ptr<ui::PlatformEventSource> event_source =
190 ui::PlatformEventSource::CreateDefault(); 218 ui::PlatformEventSource::CreateDefault();
191 #elif defined(OS_LINUX) 219 #elif defined(OS_LINUX)
192 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT); 220 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT);
193 #elif defined(OS_MACOSX) 221 #elif defined(OS_MACOSX)
194 // This is necessary for CoreAnimation layers hosted in the GPU process to be 222 // This is necessary for CoreAnimation layers hosted in the GPU process to be
195 // drawn. See http://crbug.com/312462. 223 // drawn. See http://crbug.com/312462.
196 std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop()); 224 std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop());
197 base::MessageLoop main_message_loop(std::move(pump)); 225 base::MessageLoop main_message_loop(std::move(pump));
198 #else 226 #else
199 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_IO); 227 base::MessageLoop main_message_loop(base::MessageLoop::TYPE_IO);
200 #endif 228 #endif
201 229
202 base::PlatformThread::SetName("CrGpuMain"); 230 base::PlatformThread::SetName("CrGpuMain");
203 231
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. 232 // Initializes StatisticsRecorder which tracks UMA histograms.
233 base::StatisticsRecorder::Initialize(); 233 base::StatisticsRecorder::Initialize();
234 234
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) 235 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
246 // Set thread priority before sandbox initialization. 236 // Set thread priority before sandbox initialization.
247 base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY); 237 base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
248 #endif 238 #endif
249 239
250 // Warm up resources that don't need access to GPUInfo. 240 gpu::GpuInit gpu_init;
251 WarmUpSandbox(); 241 ContentSandboxHelper sandbox_helper;
252 242 #if defined(OS_WIN)
253 #if defined(OS_LINUX) 243 sandbox_helper.set_sandbox_info(parameters.sandbox_info);
254 bool initialized_sandbox = false; 244 #elif defined(OS_LINUX)
255 // On Chrome OS ARM Mali, GPU driver userspace creates threads when 245 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 246 #endif
351 247
248 gpu_init.set_sandbox_helper(&sandbox_helper);
249
250 // Gpu initialization may fail for various reasons, in which case we will need
251 // to tear down this process. However, we can not do so safely until the IPC
252 // channel is set up, because the detection of early return of a child process
253 // is implemented using an IPC channel error. If the IPC channel is not fully
254 // set up between the browser and GPU process, and the GPU process crashes or
255 // exits early, the browser process will never detect it. For this reason we
256 // defer tearing down the GPU process until receiving the GpuMsg_Initialize
257 // message from the browser.
258 const bool init_success = gpu_init.InitializeAndStartSandbox(command_line);
259 const bool dead_on_arrival = !init_success;
260
352 logging::SetLogMessageHandler(NULL); 261 logging::SetLogMessageHandler(NULL);
262 GetContentClient()->SetGpuInfo(gpu_init.gpu_info());
353 263
354 std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory; 264 std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory;
355 if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) 265 if (init_success &&
266 gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER)
356 gpu_memory_buffer_factory = gpu::GpuMemoryBufferFactory::CreateNativeType(); 267 gpu_memory_buffer_factory = gpu::GpuMemoryBufferFactory::CreateNativeType();
357 268
358 base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL; 269 base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
359 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) 270 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
360 io_thread_priority = base::ThreadPriority::DISPLAY; 271 io_thread_priority = base::ThreadPriority::DISPLAY;
361 #endif 272 #endif
362 273
363 GpuProcess gpu_process(io_thread_priority); 274 GpuProcess gpu_process(io_thread_priority);
364
365 GpuChildThread* child_thread = new GpuChildThread( 275 GpuChildThread* child_thread = new GpuChildThread(
366 watchdog_thread.get(), dead_on_arrival, gpu_info, deferred_messages.Get(), 276 gpu_init.watchdog_thread(), dead_on_arrival, gpu_init.gpu_info(),
367 gpu_memory_buffer_factory.get()); 277 deferred_messages.Get(), gpu_memory_buffer_factory.get());
368 while (!deferred_messages.Get().empty()) 278 while (!deferred_messages.Get().empty())
369 deferred_messages.Get().pop(); 279 deferred_messages.Get().pop();
370 280
371 child_thread->Init(start_time); 281 child_thread->Init(start_time);
372 282
373 gpu_process.set_main_thread(child_thread); 283 gpu_process.set_main_thread(child_thread);
374 284
375 if (watchdog_thread.get()) 285 if (gpu_init.watchdog_thread())
376 watchdog_thread->AddPowerObserver(); 286 gpu_init.watchdog_thread()->AddPowerObserver();
377 287
378 #if defined(OS_ANDROID) 288 #if defined(OS_ANDROID)
379 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 289 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
380 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics", 290 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
381 nullptr); 291 nullptr);
382 #endif 292 #endif
383 293
384 { 294 {
385 TRACE_EVENT0("gpu", "Run Message Loop"); 295 TRACE_EVENT0("gpu", "Run Message Loop");
386 base::RunLoop().Run(); 296 base::RunLoop().Run();
387 } 297 }
388 298
389 child_thread->StopWatchdog(); 299 child_thread->StopWatchdog();
390 300
391 return dead_on_arrival ? 2 : 0; 301 return dead_on_arrival ? 2 : 0;
392 } 302 }
393 303
394 namespace { 304 namespace {
395 305
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() {
448 {
449 TRACE_EVENT0("gpu", "Warm up rand");
450 // Warm up the random subsystem, which needs to be done pre-sandbox on all
451 // platforms.
452 (void) base::RandUint64();
453 }
454
455 #if defined(OS_WIN)
456 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
457 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
458 #endif
459 }
460
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) 306 #if defined(OS_LINUX)
487 #if !defined(OS_CHROMEOS) 307 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"); 308 TRACE_EVENT0("gpu,startup", "Initialize sandbox");
502 309
503 bool res = false; 310 bool res = false;
504 311
505 if (watchdog_thread) { 312 if (watchdog_thread) {
506 // LinuxSandbox needs to be able to ensure that the thread 313 // LinuxSandbox needs to be able to ensure that the thread
507 // has really been stopped. 314 // has really been stopped.
508 LinuxSandbox::StopThread(watchdog_thread); 315 LinuxSandbox::StopThread(watchdog_thread);
509 } 316 }
510 317
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 return true; 351 return true;
545 } 352 }
546 353
547 return false; 354 return false;
548 } 355 }
549 #endif // defined(OS_WIN) 356 #endif // defined(OS_WIN)
550 357
551 } // namespace. 358 } // namespace.
552 359
553 } // namespace content 360 } // namespace content
OLDNEW
« no previous file with comments | « content/gpu/gpu_child_thread.h ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698