| Index: content/gpu/gpu_main.cc
|
| diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
|
| index 53e035c2f06007a17d0134a16915c30099179719..d566d0817ecfedaf6420acd0abcad80316f82c1f 100644
|
| --- a/content/gpu/gpu_main.cc
|
| +++ b/content/gpu/gpu_main.cc
|
| @@ -8,10 +8,7 @@
|
| #include <memory>
|
| #include <utility>
|
|
|
| -#include "base/lazy_instance.h"
|
| #include "base/message_loop/message_loop.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/metrics/statistics_recorder.h"
|
| #include "base/rand_util.h"
|
| #include "base/run_loop.h"
|
| #include "base/strings/string_number_conversions.h"
|
| @@ -22,7 +19,6 @@
|
| #include "build/build_config.h"
|
| #include "content/child/child_process.h"
|
| #include "content/common/content_constants_internal.h"
|
| -#include "content/common/gpu_host_messages.h"
|
| #include "content/common/sandbox_linux/sandbox_linux.h"
|
| #include "content/gpu/gpu_child_thread.h"
|
| #include "content/gpu/gpu_process.h"
|
| @@ -31,19 +27,11 @@
|
| #include "content/public/common/main_function_params.h"
|
| #include "gpu/command_buffer/service/gpu_switches.h"
|
| #include "gpu/config/gpu_info_collector.h"
|
| -#include "gpu/config/gpu_switches.h"
|
| -#include "gpu/config/gpu_util.h"
|
| -#include "gpu/ipc/common/gpu_memory_buffer_support.h"
|
| #include "gpu/ipc/service/gpu_config.h"
|
| -#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
|
| +#include "gpu/ipc/service/gpu_init.h"
|
| +#include "gpu/ipc/service/gpu_init_delegate.h"
|
| #include "gpu/ipc/service/gpu_watchdog_thread.h"
|
| #include "ui/events/platform/platform_event_source.h"
|
| -#include "ui/gl/gl_context.h"
|
| -#include "ui/gl/gl_implementation.h"
|
| -#include "ui/gl/gl_surface.h"
|
| -#include "ui/gl/gl_switches.h"
|
| -#include "ui/gl/gpu_switching_manager.h"
|
| -#include "ui/gl/init/gl_factory.h"
|
|
|
| #if defined(OS_WIN)
|
| #include <windows.h>
|
| @@ -64,7 +52,6 @@
|
| #endif
|
|
|
| #if defined(USE_X11)
|
| -#include "ui/base/x/x11_util.h" // nogncheck
|
| #include "ui/gfx/x/x11_switches.h" // nogncheck
|
| #endif
|
|
|
| @@ -90,415 +77,189 @@ namespace content {
|
|
|
| namespace {
|
|
|
| -void GetGpuInfoFromCommandLine(gpu::GPUInfo& gpu_info,
|
| - const base::CommandLine& command_line);
|
| -void WarmUpSandbox();
|
| -
|
| -#if !defined(OS_MACOSX)
|
| -bool CollectGraphicsInfo(gpu::GPUInfo& gpu_info);
|
| -#endif
|
| -
|
| #if defined(OS_LINUX)
|
| -#if !defined(OS_CHROMEOS)
|
| -bool CanAccessNvidiaDeviceFile();
|
| -#endif
|
| bool StartSandboxLinux(const gpu::GPUInfo&, gpu::GpuWatchdogThread*);
|
| #elif defined(OS_WIN)
|
| bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
|
| #endif
|
|
|
| -base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages =
|
| - LAZY_INSTANCE_INITIALIZER;
|
| -
|
| -bool GpuProcessLogMessageHandler(int severity,
|
| - const char* file, int line,
|
| - size_t message_start,
|
| - const std::string& str) {
|
| - std::string header = str.substr(0, message_start);
|
| - std::string message = str.substr(message_start);
|
| - deferred_messages.Get().push(
|
| - new GpuHostMsg_OnLogMessage(severity, header, message));
|
| - return false;
|
| -}
|
| -
|
| -} // namespace anonymous
|
| +class ContentGpuInitDelegate : public gpu::GpuInitDelegate {
|
| + public:
|
| + explicit ContentGpuInitDelegate(const base::CommandLine* command_line)
|
| + : command_line_(command_line), watchdog_thread_(nullptr) {
|
| + DCHECK(command_line_);
|
| + }
|
| + ~ContentGpuInitDelegate() override {}
|
|
|
| -// Main function for starting the Gpu process.
|
| -int GpuMain(const MainFunctionParams& parameters) {
|
| - TRACE_EVENT0("gpu", "GpuMain");
|
| - base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process");
|
| - base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
|
| - kTraceEventGpuProcessSortIndex);
|
| +#if defined(OS_WIN)
|
| + void set_sandbox_info(sandbox::SandboxInterfaceInfo* sandbox_info) {
|
| + sandbox_info_ = sandbox_info;
|
| + }
|
| +#endif
|
|
|
| - const base::CommandLine& command_line = parameters.command_line;
|
| - if (command_line.HasSwitch(switches::kGpuStartupDialog)) {
|
| - ChildProcess::WaitForDebugger("Gpu");
|
| + private:
|
| + // gpu::GpuInit::Delegate:
|
| + void OnGpuInfoUpdate(const gpu::GPUInfo& gpu_info) override {
|
| + gpu_info_ = gpu_info;
|
| + GetContentClient()->SetGpuInfo(gpu_info_);
|
| }
|
|
|
| - base::Time start_time = base::Time::Now();
|
| + void OnGpuWatchdogThreadCreated(gpu::GpuWatchdogThread* thread) override {
|
| + watchdog_thread_ = thread;
|
| + }
|
|
|
| -#if defined(OS_WIN)
|
| - // Prevent Windows from displaying a modal dialog on failures like not being
|
| - // able to load a DLL.
|
| - SetErrorMode(
|
| - SEM_FAILCRITICALERRORS |
|
| - SEM_NOGPFAULTERRORBOX |
|
| - SEM_NOOPENFILEERRORBOX);
|
| -#elif defined(USE_X11)
|
| - ui::SetDefaultX11ErrorHandlers();
|
| -
|
| -#if !defined(OS_CHROMEOS)
|
| - DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kWindowDepth));
|
| - DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kX11VisualID));
|
| -#endif
|
| + void OnGpuWatchdogThreadDestroyed() override { watchdog_thread_ = nullptr; }
|
|
|
| + bool ShouldInitializeGL() override {
|
| +#if defined(OS_MACOSX)
|
| + // On Mac, if the sandbox is enabled, then gl::init::InitializeGLOneOff()
|
| + // is called from the sandbox warmup code before getting here.
|
| + if (!command_line_->HasSwitch(switches::kNoSandbox))
|
| + return false;
|
| #endif
|
| -
|
| - logging::SetLogMessageHandler(GpuProcessLogMessageHandler);
|
| -
|
| - if (command_line.HasSwitch(switches::kSupportsDualGpus)) {
|
| - std::string types = command_line.GetSwitchValueASCII(
|
| - switches::kGpuDriverBugWorkarounds);
|
| - std::set<int> workarounds;
|
| - gpu::StringToFeatureSet(types, &workarounds);
|
| - if (workarounds.count(gpu::FORCE_DISCRETE_GPU) == 1)
|
| - ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
|
| - else if (workarounds.count(gpu::FORCE_INTEGRATED_GPU) == 1)
|
| - ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
|
| + if (command_line_->HasSwitch(switches::kInProcessGPU)) {
|
| + // With in-process GPU, gl::init::InitializeGLOneOff() is called from
|
| + // GpuChildThread before getting here.
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| - // Initialization of the OpenGL bindings may fail, in which case we
|
| - // will need to tear down this process. However, we can not do so
|
| - // safely until the IPC channel is set up, because the detection of
|
| - // early return of a child process is implemented using an IPC
|
| - // channel error. If the IPC channel is not fully set up between the
|
| - // browser and GPU process, and the GPU process crashes or exits
|
| - // early, the browser process will never detect it. For this reason
|
| - // we defer tearing down the GPU process until receiving the
|
| - // GpuMsg_Initialize message from the browser.
|
| - bool dead_on_arrival = false;
|
| + void WaitForDebugger() override { ChildProcess::WaitForDebugger("Gpu"); }
|
|
|
| + void InitializeMessageLoop() override {
|
| #if defined(OS_WIN)
|
| - // Use a UI message loop because ANGLE and the desktop GL platform can
|
| - // create child windows to render to.
|
| - base::MessagePumpForGpu::InitFactory();
|
| - base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
|
| + // Use a UI message loop because ANGLE and the desktop GL platform can
|
| + // create child windows to render to.
|
| + base::MessagePumpForGpu::InitFactory();
|
| + message_loop_ =
|
| + base::MakeUnique<base::MessageLoop>(base::MessageLoop::TYPE_UI);
|
| #elif defined(OS_LINUX) && defined(USE_X11)
|
| - // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX
|
| - // and https://crbug.com/326995.
|
| - base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
|
| - std::unique_ptr<ui::PlatformEventSource> event_source =
|
| - ui::PlatformEventSource::CreateDefault();
|
| + // We need a UI loop so that we can grab the Expose events. See GLSurfaceGLX
|
| + // and https://crbug.com/326995.
|
| + message_loop_ =
|
| + base::MakeUnique<base::MessageLoop>(base::MessageLoop::TYPE_UI);
|
| + std::unique_ptr<ui::PlatformEventSource> event_source =
|
| + ui::PlatformEventSource::CreateDefault();
|
| #elif defined(OS_LINUX)
|
| - base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT);
|
| + message_loop_ =
|
| + base::MakeUnique<base::MessageLoop>(base::MessageLoop::TYPE_DEFAULT);
|
| #elif defined(OS_MACOSX)
|
| - // This is necessary for CoreAnimation layers hosted in the GPU process to be
|
| - // drawn. See http://crbug.com/312462.
|
| - std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop());
|
| - base::MessageLoop main_message_loop(std::move(pump));
|
| + // This is necessary for CoreAnimation layers hosted in the GPU process to
|
| + // be
|
| + // drawn. See http://crbug.com/312462.
|
| + std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop());
|
| + message_loop_ = base::MakeUnique<base::MessageLoop>(std::move(pump));
|
| #else
|
| - base::MessageLoop main_message_loop(base::MessageLoop::TYPE_IO);
|
| + message_loop_ =
|
| + base::MakeUnique<base::MessageLoop>(base::MessageLoop::TYPE_IO);
|
| #endif
|
| + }
|
|
|
| - base::PlatformThread::SetName("CrGpuMain");
|
| -
|
| - // In addition to disabling the watchdog if the command line switch is
|
| - // present, disable the watchdog on valgrind because the code is expected
|
| - // to run slowly in that case.
|
| - bool enable_watchdog =
|
| - !command_line.HasSwitch(switches::kDisableGpuWatchdog) &&
|
| - !RunningOnValgrind();
|
| -
|
| - // Disable the watchdog in debug builds because they tend to only be run by
|
| - // developers who will not appreciate the watchdog killing the GPU process.
|
| -#ifndef NDEBUG
|
| - enable_watchdog = false;
|
| -#endif
|
| -
|
| - bool delayed_watchdog_enable = false;
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - // Don't start watchdog immediately, to allow developers to switch to VT2 on
|
| - // startup.
|
| - delayed_watchdog_enable = true;
|
| -#endif
|
| -
|
| - scoped_refptr<gpu::GpuWatchdogThread> watchdog_thread;
|
| -
|
| - // Start the GPU watchdog only after anything that is expected to be time
|
| - // consuming has completed, otherwise the process is liable to be aborted.
|
| - if (enable_watchdog && !delayed_watchdog_enable)
|
| - watchdog_thread = gpu::GpuWatchdogThread::Create();
|
| -
|
| - // Initializes StatisticsRecorder which tracks UMA histograms.
|
| - base::StatisticsRecorder::Initialize();
|
| -
|
| - gpu::GPUInfo gpu_info;
|
| - // Get vendor_id, device_id, driver_version from browser process through
|
| - // commandline switches.
|
| - GetGpuInfoFromCommandLine(gpu_info, command_line);
|
| - gpu_info.in_process_gpu = false;
|
| -
|
| + void PreSandboxInitialization() override {
|
| #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
|
| - media::VaapiWrapper::PreSandboxInitialization();
|
| -#endif
|
| -
|
| -#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
|
| - // Set thread priority before sandbox initialization.
|
| - base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
|
| + media::VaapiWrapper::PreSandboxInitialization();
|
| #endif
|
| -
|
| - // Warm up resources that don't need access to GPUInfo.
|
| - WarmUpSandbox();
|
| -
|
| -#if defined(OS_LINUX)
|
| - bool initialized_sandbox = false;
|
| - // On Chrome OS ARM Mali, GPU driver userspace creates threads when
|
| - // initializing a GL context, so start the sandbox early.
|
| - if (command_line.HasSwitch(switches::kGpuSandboxStartEarly)) {
|
| - gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get());
|
| - initialized_sandbox = true;
|
| }
|
| -#endif // defined(OS_LINUX)
|
| -
|
| - base::TimeTicks before_initialize_one_off = base::TimeTicks::Now();
|
|
|
| - // Determine if we need to initialize GL here or it has already been done.
|
| - bool gl_already_initialized = false;
|
| -#if defined(OS_MACOSX)
|
| - if (!command_line.HasSwitch(switches::kNoSandbox)) {
|
| - // On Mac, if the sandbox is enabled, then gl::init::InitializeGLOneOff()
|
| - // is called from the sandbox warmup code before getting here.
|
| - gl_already_initialized = true;
|
| - }
|
| + bool ShouldStartSandboxEarly() override {
|
| +#if defined(OS_LINUX)
|
| + // On Chrome OS ARM Mali, GPU driver userspace creates threads when
|
| + // initializing a GL context, so start the sandbox early.
|
| + return command_line_->HasSwitch(switches::kGpuSandboxStartEarly);
|
| +#else
|
| + return false;
|
| #endif
|
| - if (command_line.HasSwitch(switches::kInProcessGPU)) {
|
| - // With in-process GPU, gl::init::InitializeGLOneOff() is called from
|
| - // GpuChildThread before getting here.
|
| - gl_already_initialized = true;
|
| }
|
|
|
| - // Load and initialize the GL implementation and locate the GL entry points.
|
| - bool gl_initialized =
|
| - gl_already_initialized
|
| - ? gl::GetGLImplementation() != gl::kGLImplementationNone
|
| - : gl::init::InitializeGLOneOff();
|
| - if (gl_initialized) {
|
| - // We need to collect GL strings (VENDOR, RENDERER) for blacklisting
|
| - // purposes. However, on Mac we don't actually use them. As documented in
|
| - // crbug.com/222934, due to some driver issues, glGetString could take
|
| - // multiple seconds to finish, which in turn cause the GPU process to
|
| - // crash.
|
| - // By skipping the following code on Mac, we don't really lose anything,
|
| - // because the basic GPU information is passed down from browser process
|
| - // and we already registered them through SetGpuInfo() above.
|
| - base::TimeTicks before_collect_context_graphics_info =
|
| - base::TimeTicks::Now();
|
| -#if !defined(OS_MACOSX)
|
| - if (!CollectGraphicsInfo(gpu_info))
|
| - dead_on_arrival = true;
|
| -
|
| - // Recompute gpu driver bug workarounds.
|
| - // This is necessary on systems where vendor_id/device_id aren't available
|
| - // (Chrome OS, Android) or where workarounds may be dependent on GL_VENDOR
|
| - // and GL_RENDERER strings which are lazily computed (Linux).
|
| - if (!command_line.HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
|
| - // TODO: this can not affect disabled extensions, since they're already
|
| - // initialized in the bindings. This should be moved before bindings
|
| - // initialization. However, populating GPUInfo fully works only on
|
| - // Android. Other platforms would need the bindings to query GL strings.
|
| - gpu::ApplyGpuDriverBugWorkarounds(
|
| - gpu_info, const_cast<base::CommandLine*>(&command_line));
|
| - }
|
| -#endif // !defined(OS_MACOSX)
|
| -
|
| -#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
| - if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA
|
| - gpu_info.driver_vendor == "NVIDIA" && !CanAccessNvidiaDeviceFile())
|
| - dead_on_arrival = true;
|
| -#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
| -
|
| - base::TimeDelta collect_context_time =
|
| - base::TimeTicks::Now() - before_collect_context_graphics_info;
|
| - UMA_HISTOGRAM_TIMES("GPU.CollectContextGraphicsInfo", collect_context_time);
|
| - } else { // gl_initialized
|
| - VLOG(1) << "gl::init::InitializeGLOneOff failed";
|
| - dead_on_arrival = true;
|
| - }
|
| -
|
| - base::TimeDelta initialize_one_off_time =
|
| - base::TimeTicks::Now() - before_initialize_one_off;
|
| - UMA_HISTOGRAM_MEDIUM_TIMES("GPU.InitializeOneOffMediumTime",
|
| - initialize_one_off_time);
|
| - if (enable_watchdog && delayed_watchdog_enable)
|
| - watchdog_thread = gpu::GpuWatchdogThread::Create();
|
| -
|
| - // OSMesa is expected to run very slowly, so disable the watchdog in that
|
| - // case.
|
| - if (enable_watchdog &&
|
| - gl::GetGLImplementation() == gl::kGLImplementationOSMesaGL) {
|
| - watchdog_thread->Stop();
|
| - watchdog_thread = NULL;
|
| + void WarmUpSandbox() override {
|
| +#if defined(OS_WIN)
|
| + media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
|
| + media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
|
| +#endif
|
| }
|
|
|
| + bool StartSandbox() override {
|
| #if defined(OS_LINUX)
|
| - if (!initialized_sandbox)
|
| - gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get());
|
| + return StartSandboxLinux(gpu_info_, watchdog_thread_);
|
| #elif defined(OS_WIN)
|
| - gpu_info.sandboxed = StartSandboxWindows(parameters.sandbox_info);
|
| + return StartSandboxWindows(sandbox_info_);
|
| #elif defined(OS_MACOSX)
|
| - gpu_info.sandboxed = Sandbox::SandboxIsCurrentlyActive();
|
| + return Sandbox::SandboxIsCurrentlyActive();
|
| +#else
|
| + return false;
|
| #endif
|
| + }
|
|
|
| - logging::SetLogMessageHandler(NULL);
|
| -
|
| - std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory;
|
| - if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER)
|
| - gpu_memory_buffer_factory = gpu::GpuMemoryBufferFactory::CreateNativeType();
|
| -
|
| - base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
|
| + void Initialize(base::Time start_time,
|
| + bool dead_on_arrival,
|
| + std::vector<gpu::GpuInitLogMessage> init_log_messages,
|
| + gpu::GpuMemoryBufferFactory* gpu_buffer_factory) override {
|
| + base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
|
| #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
|
| - io_thread_priority = base::ThreadPriority::DISPLAY;
|
| + io_thread_priority = base::ThreadPriority::DISPLAY;
|
| #endif
|
| + gpu_process_.reset(new GpuProcess(io_thread_priority));
|
|
|
| - GpuProcess gpu_process(io_thread_priority);
|
| -
|
| - GpuChildThread* child_thread = new GpuChildThread(
|
| - watchdog_thread.get(), dead_on_arrival, gpu_info, deferred_messages.Get(),
|
| - gpu_memory_buffer_factory.get());
|
| - while (!deferred_messages.Get().empty())
|
| - deferred_messages.Get().pop();
|
| + GpuChildThread* child_thread =
|
| + new GpuChildThread(watchdog_thread_, dead_on_arrival, gpu_info_,
|
| + std::move(init_log_messages), gpu_buffer_factory);
|
| + child_thread->Init(start_time);
|
|
|
| - child_thread->Init(start_time);
|
| -
|
| - gpu_process.set_main_thread(child_thread);
|
| -
|
| - if (watchdog_thread.get())
|
| - watchdog_thread->AddPowerObserver();
|
| + gpu_process_->set_main_thread(child_thread);
|
|
|
| #if defined(OS_ANDROID)
|
| - base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
|
| - tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
|
| - nullptr);
|
| + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
|
| + tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
|
| + nullptr);
|
| #endif
|
| -
|
| - {
|
| - TRACE_EVENT0("gpu", "Run Message Loop");
|
| - base::RunLoop().Run();
|
| }
|
|
|
| - child_thread->StopWatchdog();
|
| + const base::CommandLine* command_line_;
|
| + gpu::GpuWatchdogThread* watchdog_thread_ = nullptr;
|
| + gpu::GPUInfo gpu_info_;
|
| + std::unique_ptr<base::MessageLoop> message_loop_;
|
| + std::unique_ptr<GpuProcess> gpu_process_;
|
| +#if defined(OS_WIN)
|
| + sandbox::SandboxInterfaceInfo* sandbox_info_ = nullptr;
|
| +#endif
|
|
|
| - return dead_on_arrival ? 2 : 0;
|
| -}
|
| + DISALLOW_COPY_AND_ASSIGN(ContentGpuInitDelegate);
|
| +};
|
|
|
| -namespace {
|
| +} // namespace anonymous
|
|
|
| -void GetGpuInfoFromCommandLine(gpu::GPUInfo& gpu_info,
|
| - const base::CommandLine& command_line) {
|
| - DCHECK(command_line.HasSwitch(switches::kGpuVendorID) &&
|
| - command_line.HasSwitch(switches::kGpuDeviceID) &&
|
| - command_line.HasSwitch(switches::kGpuDriverVersion));
|
| - bool success = base::HexStringToUInt(
|
| - command_line.GetSwitchValueASCII(switches::kGpuVendorID),
|
| - &gpu_info.gpu.vendor_id);
|
| - DCHECK(success);
|
| - success = base::HexStringToUInt(
|
| - command_line.GetSwitchValueASCII(switches::kGpuDeviceID),
|
| - &gpu_info.gpu.device_id);
|
| - DCHECK(success);
|
| - gpu_info.driver_vendor =
|
| - command_line.GetSwitchValueASCII(switches::kGpuDriverVendor);
|
| - gpu_info.driver_version =
|
| - command_line.GetSwitchValueASCII(switches::kGpuDriverVersion);
|
| - gpu_info.driver_date =
|
| - command_line.GetSwitchValueASCII(switches::kGpuDriverDate);
|
| - gpu::ParseSecondaryGpuDevicesFromCommandLine(command_line, &gpu_info);
|
| -
|
| - // Set active gpu device.
|
| - if (command_line.HasSwitch(switches::kGpuActiveVendorID) &&
|
| - command_line.HasSwitch(switches::kGpuActiveDeviceID)) {
|
| - uint32_t active_vendor_id = 0;
|
| - uint32_t active_device_id = 0;
|
| - success = base::HexStringToUInt(
|
| - command_line.GetSwitchValueASCII(switches::kGpuActiveVendorID),
|
| - &active_vendor_id);
|
| - DCHECK(success);
|
| - success = base::HexStringToUInt(
|
| - command_line.GetSwitchValueASCII(switches::kGpuActiveDeviceID),
|
| - &active_device_id);
|
| - DCHECK(success);
|
| - if (gpu_info.gpu.vendor_id == active_vendor_id &&
|
| - gpu_info.gpu.device_id == active_device_id) {
|
| - gpu_info.gpu.active = true;
|
| - } else {
|
| - for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
|
| - if (gpu_info.secondary_gpus[i].vendor_id == active_vendor_id &&
|
| - gpu_info.secondary_gpus[i].device_id == active_device_id) {
|
| - gpu_info.secondary_gpus[i].active = true;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| +// Main function for starting the Gpu process.
|
| +int GpuMain(const MainFunctionParams& parameters) {
|
| + TRACE_EVENT0("gpu", "GpuMain");
|
| + base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process");
|
| + base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
|
| + kTraceEventGpuProcessSortIndex);
|
|
|
| - GetContentClient()->SetGpuInfo(gpu_info);
|
| -}
|
| + DCHECK(parameters.command_line.HasSwitch(switches::kGpuVendorID) &&
|
| + parameters.command_line.HasSwitch(switches::kGpuDeviceID) &&
|
| + parameters.command_line.HasSwitch(switches::kGpuDriverVersion));
|
| +#if defined(USE_X11) && !defined(OS_CHROMEOS)
|
| + DCHECK(parameters.command_line.HasSwitch(switches::kWindowDepth));
|
| + DCHECK(parameters.command_line.HasSwitch(switches::kX11VisualID));
|
| +#endif // defined(USE_X11) && !defined(OS_CHROMEOS)
|
|
|
| -void WarmUpSandbox() {
|
| + ContentGpuInitDelegate init_delegate(¶meters.command_line);
|
| +#if defined(OS_WIN)
|
| + init_delegate.set_sandbox_info(parameters.sandbox_info);
|
| +#endif
|
| + gpu::GpuInit gpu_init(&init_delegate, parameters.command_line);
|
| {
|
| - TRACE_EVENT0("gpu", "Warm up rand");
|
| - // Warm up the random subsystem, which needs to be done pre-sandbox on all
|
| - // platforms.
|
| - (void) base::RandUint64();
|
| + TRACE_EVENT0("gpu", "Run Message Loop");
|
| + base::RunLoop().Run();
|
| }
|
|
|
| -#if defined(OS_WIN)
|
| - media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
|
| - media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
|
| -#endif
|
| + return 0;
|
| }
|
|
|
| -#if !defined(OS_MACOSX)
|
| -bool CollectGraphicsInfo(gpu::GPUInfo& gpu_info) {
|
| - TRACE_EVENT0("gpu,startup", "Collect Graphics Info");
|
| -
|
| - bool res = true;
|
| - gpu::CollectInfoResult result = gpu::CollectContextGraphicsInfo(&gpu_info);
|
| - switch (result) {
|
| - case gpu::kCollectInfoFatalFailure:
|
| - LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal).";
|
| - res = false;
|
| - break;
|
| - case gpu::kCollectInfoNonFatalFailure:
|
| - DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal).";
|
| - break;
|
| - case gpu::kCollectInfoNone:
|
| - NOTREACHED();
|
| - break;
|
| - case gpu::kCollectInfoSuccess:
|
| - break;
|
| - }
|
| - GetContentClient()->SetGpuInfo(gpu_info);
|
| - return res;
|
| -}
|
| -#endif
|
| +namespace {
|
|
|
| #if defined(OS_LINUX)
|
| -#if !defined(OS_CHROMEOS)
|
| -bool CanAccessNvidiaDeviceFile() {
|
| - bool res = true;
|
| - base::ThreadRestrictions::AssertIOAllowed();
|
| - if (access("/dev/nvidiactl", R_OK) != 0) {
|
| - DVLOG(1) << "NVIDIA device file /dev/nvidiactl access denied";
|
| - res = false;
|
| - }
|
| - return res;
|
| -}
|
| -#endif
|
| -
|
| bool StartSandboxLinux(const gpu::GPUInfo& gpu_info,
|
| gpu::GpuWatchdogThread* watchdog_thread) {
|
| TRACE_EVENT0("gpu,startup", "Initialize sandbox");
|
|
|