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

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
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(); 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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698