summaryrefslogtreecommitdiff
path: root/chromium/content/gpu
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-29 16:35:13 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-01 15:33:35 +0000
commitc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch)
tree9157c3d9815e5870799e070b113813bec53e0535 /chromium/content/gpu
parentabefd5095b41dac94ca451d784ab6e27372e981a (diff)
downloadqtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/content/gpu')
-rw-r--r--chromium/content/gpu/BUILD.gn14
-rw-r--r--chromium/content/gpu/DEPS4
-rw-r--r--chromium/content/gpu/gpu_child_thread.cc47
-rw-r--r--chromium/content/gpu/gpu_child_thread.h15
-rw-r--r--chromium/content/gpu/gpu_main.cc83
-rw-r--r--chromium/content/gpu/gpu_sandbox_hook_linux.cc351
-rw-r--r--chromium/content/gpu/gpu_sandbox_hook_linux.h17
-rw-r--r--chromium/content/gpu/gpu_service_factory.cc8
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.cc14
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.h9
10 files changed, 496 insertions, 66 deletions
diff --git a/chromium/content/gpu/BUILD.gn b/chromium/content/gpu/BUILD.gn
index a5424bb7c11..b1277cbfae2 100644
--- a/chromium/content/gpu/BUILD.gn
+++ b/chromium/content/gpu/BUILD.gn
@@ -27,6 +27,7 @@ if (is_component_build) {
} else {
link_target_type = "static_library"
}
+
target(link_target_type, "gpu_sources") {
# This is an internal content API. Code outside of the content "component"
# (like content/test and content/shell) should depend on ":gpu" above.
@@ -38,6 +39,8 @@ target(link_target_type, "gpu_sources") {
"gpu_main.cc",
"gpu_process.cc",
"gpu_process.h",
+ "gpu_sandbox_hook_linux.cc",
+ "gpu_sandbox_hook_linux.h",
"gpu_service_factory.cc",
"gpu_service_factory.h",
"in_process_gpu_thread.cc",
@@ -59,6 +62,7 @@ target(link_target_type, "gpu_sources") {
"//content/public/common:common_sources",
"//gpu:gpu",
"//gpu/ipc/common:command_buffer_traits",
+ "//gpu/ipc/common:gpu_preferences_util",
"//gpu/ipc/service",
"//ipc",
"//media/gpu",
@@ -67,15 +71,16 @@ target(link_target_type, "gpu_sources") {
# TODO(jrummell): As //media/gpu/ipc/service is a source_set in a
# component build, determine if it should not be included here.
# http://crbug.com/702833.
+ "//components/viz/service/main",
"//media/gpu/ipc/service",
"//media/mojo/clients:clients",
"//services/service_manager/public/cpp",
"//services/service_manager/public/interfaces",
"//services/shape_detection:lib",
"//services/shape_detection/public/interfaces",
- "//services/ui/gpu",
- "//services/ui/gpu/interfaces",
+ "//services/viz/privileged/interfaces",
"//skia",
+ "//third_party/angle:angle_gpu_info_util",
"//ui/gfx/ipc",
"//ui/gl",
"//ui/gl/init",
@@ -114,4 +119,9 @@ target(link_target_type, "gpu_sources") {
if (enable_vulkan) {
deps += [ "//gpu/vulkan" ]
}
+
+ # Use DRI on desktop Linux builds.
+ if (is_desktop_linux && (!is_chromecast || is_cast_desktop_build)) {
+ configs += [ "//build/config/linux/dri" ]
+ }
}
diff --git a/chromium/content/gpu/DEPS b/chromium/content/gpu/DEPS
index 11a913643f5..084a0645313 100644
--- a/chromium/content/gpu/DEPS
+++ b/chromium/content/gpu/DEPS
@@ -8,8 +8,8 @@ include_rules = [
"+services/service_manager",
"+services/shape_detection",
"+services/ui/common",
- "+services/ui/gpu",
- "+services/viz/privileged/interfaces/gl",
+ "+services/viz/privileged/interfaces",
+ "+services/viz/service",
"+sandbox",
"+skia",
]
diff --git a/chromium/content/gpu/gpu_child_thread.cc b/chromium/content/gpu/gpu_child_thread.cc
index 1048a37c9aa..6752f55e381 100644
--- a/chromium/content/gpu/gpu_child_thread.cc
+++ b/chromium/content/gpu/gpu_child_thread.cc
@@ -9,12 +9,14 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
+#include "components/viz/common/switches.h"
#include "content/child/child_process.h"
#include "content/gpu/gpu_service_factory.h"
#include "content/public/common/connection_filter.h"
@@ -44,11 +46,6 @@
namespace content {
namespace {
-bool IsVizEnabled() {
- // TODO(crbug.com/770833): Look at the --enable-viz flag instead.
- return false;
-}
-
ChildThreadImpl::Options GetOptions() {
ChildThreadImpl::Options::Builder builder;
@@ -106,7 +103,7 @@ class QueueingConnectionFilter : public ConnectionFilter {
registry_->BindInterface(interface_name, std::move(*interface_pipe));
} else {
std::unique_ptr<PendingRequest> request =
- base::MakeUnique<PendingRequest>();
+ std::make_unique<PendingRequest>();
request->interface_name = interface_name;
request->interface_pipe = std::move(*interface_pipe);
pending_requests_.push_back(std::move(request));
@@ -134,23 +131,26 @@ class QueueingConnectionFilter : public ConnectionFilter {
DISALLOW_COPY_AND_ASSIGN(QueueingConnectionFilter);
};
-ui::GpuMain::ExternalDependencies CreateGpuMainDependencies() {
- ui::GpuMain::ExternalDependencies deps;
- deps.create_display_compositor = IsVizEnabled();
+viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies(
+ service_manager::Connector* connector) {
+ viz::VizMainImpl::ExternalDependencies deps;
+ deps.create_display_compositor =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViz);
if (GetContentClient()->gpu())
deps.sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
auto* process = ChildProcess::current();
deps.shutdown_event = process->GetShutDownEvent();
deps.io_thread_task_runner = process->io_task_runner();
+ deps.connector = connector;
return deps;
}
} // namespace
GpuChildThread::GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
- ui::GpuMain::LogMessages log_messages)
+ viz::VizMainImpl::LogMessages log_messages)
: GpuChildThread(GetOptions(), std::move(gpu_init)) {
- gpu_main_.SetLogMessagesForHost(std::move(log_messages));
+ viz_main_.SetLogMessagesForHost(std::move(log_messages));
}
GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
@@ -165,7 +165,9 @@ GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init)
: ChildThreadImpl(options),
- gpu_main_(this, CreateGpuMainDependencies(), std::move(gpu_init)),
+ viz_main_(this,
+ CreateVizMainDependencies(GetConnector()),
+ std::move(gpu_init)),
weak_factory_(this) {
if (in_process_gpu()) {
DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -178,7 +180,7 @@ GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
GpuChildThread::~GpuChildThread() {}
void GpuChildThread::Init(const base::Time& process_start_time) {
- gpu_main_.gpu_service()->set_start_time(process_start_time);
+ viz_main_.gpu_service()->set_start_time(process_start_time);
// When running in in-process mode, this has been set in the browser at
// ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
@@ -189,11 +191,12 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
}
#endif
- AssociatedInterfaceRegistry* associated_registry = &associated_interfaces_;
+ blink::AssociatedInterfaceRegistry* associated_registry =
+ &associated_interfaces_;
associated_registry->AddInterface(base::Bind(
- &GpuChildThread::CreateGpuMainService, base::Unretained(this)));
+ &GpuChildThread::CreateVizMainService, base::Unretained(this)));
- auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
registry->AddInterface(base::Bind(&GpuChildThread::BindServiceFactoryRequest,
weak_factory_.GetWeakPtr()),
base::ThreadTaskRunnerHandle::Get());
@@ -201,7 +204,7 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
GetContentClient()->gpu()->InitializeRegistry(registry.get());
std::unique_ptr<QueueingConnectionFilter> filter =
- base::MakeUnique<QueueingConnectionFilter>(GetIOTaskRunner(),
+ std::make_unique<QueueingConnectionFilter>(GetIOTaskRunner(),
std::move(registry));
release_pending_requests_closure_ = filter->GetReleaseCallback();
GetServiceManagerConnection()->AddConnectionFilter(std::move(filter));
@@ -209,13 +212,13 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
StartServiceManagerConnection();
}
-void GpuChildThread::CreateGpuMainService(
- ui::mojom::GpuMainAssociatedRequest request) {
- gpu_main_.BindAssociated(std::move(request));
+void GpuChildThread::CreateVizMainService(
+ viz::mojom::VizMainAssociatedRequest request) {
+ viz_main_.BindAssociated(std::move(request));
}
bool GpuChildThread::in_process_gpu() const {
- return gpu_main_.gpu_service()->gpu_info().in_process_gpu;
+ return viz_main_.gpu_service()->gpu_info().in_process_gpu;
}
bool GpuChildThread::Send(IPC::Message* msg) {
@@ -296,7 +299,7 @@ std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
FROM_HERE, base::BindOnce(bind_connector_request, std::move(request)));
}
- return base::MakeUnique<media::MojoAndroidOverlay>(
+ return std::make_unique<media::MojoAndroidOverlay>(
std::move(overlay_provider), std::move(config), routing_token,
std::move(context_ref));
}
diff --git a/chromium/content/gpu/gpu_child_thread.h b/chromium/content/gpu/gpu_child_thread.h
index a1990df78a5..6bb47df8146 100644
--- a/chromium/content/gpu/gpu_child_thread.h
+++ b/chromium/content/gpu/gpu_child_thread.h
@@ -19,6 +19,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/service/gl/gpu_service_impl.h"
+#include "components/viz/service/main/viz_main_impl.h"
#include "content/child/child_thread_impl.h"
#include "content/common/associated_interface_registry_impl.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
@@ -34,8 +35,7 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "services/service_manager/public/interfaces/service_factory.mojom.h"
-#include "services/ui/gpu/gpu_main.h"
-#include "services/ui/gpu/interfaces/gpu_main.mojom.h"
+#include "services/viz/privileged/interfaces/viz_main.mojom.h"
#include "ui/gfx/native_widget_types.h"
namespace content {
@@ -45,10 +45,11 @@ class GpuServiceFactory;
// these per process. It does process initialization and shutdown. It forwards
// IPC messages to gpu::GpuChannelManager, which is responsible for issuing
// rendering commands to the GPU.
-class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
+class GpuChildThread : public ChildThreadImpl,
+ public viz::VizMainImpl::Delegate {
public:
GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
- ui::GpuMain::LogMessages deferred_messages);
+ viz::VizMainImpl::LogMessages deferred_messages);
GpuChildThread(const InProcessChildThreadParams& params,
std::unique_ptr<gpu::GpuInit> gpu_init);
@@ -61,7 +62,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
GpuChildThread(const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init);
- void CreateGpuMainService(ui::mojom::GpuMainAssociatedRequest request);
+ void CreateVizMainService(viz::mojom::VizMainAssociatedRequest request);
bool in_process_gpu() const;
@@ -73,7 +74,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) override;
- // ui::GpuMain::Delegate:
+ // viz::VizMainImpl::Delegate:
void OnInitializationFailed() override;
void OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) override;
@@ -88,7 +89,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
media::AndroidOverlayConfig);
#endif
- ui::GpuMain gpu_main_;
+ viz::VizMainImpl viz_main_;
// ServiceFactory for service_manager::Service hosting.
std::unique_ptr<GpuServiceFactory> service_factory_;
diff --git a/chromium/content/gpu/gpu_main.cc b/chromium/content/gpu/gpu_main.cc
index 556cf00e8ac..c170ebdf874 100644
--- a/chromium/content/gpu/gpu_main.cc
+++ b/chromium/content/gpu/gpu_main.cc
@@ -22,6 +22,7 @@
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/viz/service/main/viz_main_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
#include "content/gpu/gpu_child_thread.h"
@@ -36,11 +37,12 @@
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
+#include "gpu/ipc/common/gpu_preferences_util.h"
#include "gpu/ipc/service/gpu_config.h"
#include "gpu/ipc/service/gpu_init.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
#include "media/gpu/features.h"
-#include "services/ui/gpu/gpu_main.h"
+#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/switches.h"
@@ -76,8 +78,10 @@
#if defined(OS_LINUX)
#include "content/common/font_config_ipc_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/gpu/gpu_sandbox_hook_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/sandbox_init.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#endif
@@ -99,19 +103,21 @@ namespace content {
namespace {
#if defined(OS_LINUX)
-bool StartSandboxLinux(gpu::GpuWatchdogThread*, const gpu::GPUInfo*);
+bool StartSandboxLinux(gpu::GpuWatchdogThread*,
+ const gpu::GPUInfo*,
+ const gpu::GpuPreferences&);
#elif defined(OS_WIN)
bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
#endif
-base::LazyInstance<ui::GpuMain::LogMessages>::DestructorAtExit
+base::LazyInstance<viz::VizMainImpl::LogMessages>::DestructorAtExit
deferred_messages = LAZY_INSTANCE_INITIALIZER;
bool GpuProcessLogMessageHandler(int severity,
const char* file, int line,
size_t message_start,
const std::string& str) {
- ui::GpuMain::LogMessage log;
+ viz::VizMainImpl::LogMessage log;
log.severity = severity;
log.header = str.substr(0, message_start);
log.message = str.substr(message_start);
@@ -155,13 +161,14 @@ class ContentSandboxHelper : public gpu::GpuSandboxHelper {
}
bool EnsureSandboxInitialized(gpu::GpuWatchdogThread* watchdog_thread,
- const gpu::GPUInfo* gpu_info) override {
+ const gpu::GPUInfo* gpu_info,
+ const gpu::GpuPreferences& gpu_prefs) override {
#if defined(OS_LINUX)
- return StartSandboxLinux(watchdog_thread, gpu_info);
+ return StartSandboxLinux(watchdog_thread, gpu_info, gpu_prefs);
#elif defined(OS_WIN)
return StartSandboxWindows(sandbox_info_);
#elif defined(OS_MACOSX)
- return service_manager::Sandbox::SandboxIsCurrentlyActive();
+ return service_manager::SandboxMac::IsCurrentlyActive();
#else
return false;
#endif
@@ -179,12 +186,21 @@ class ContentSandboxHelper : public gpu::GpuSandboxHelper {
// 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()->set_process_name("GPU Process");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventGpuProcessSortIndex);
const base::CommandLine& command_line = parameters.command_line;
- if (command_line.HasSwitch(switches::kGpuStartupDialog))
+
+ gpu::GpuPreferences gpu_preferences;
+ if (command_line.HasSwitch(switches::kGpuPreferences)) {
+ std::string value =
+ command_line.GetSwitchValueASCII(switches::kGpuPreferences);
+ bool success = gpu::SwitchValueToGpuPreferences(value, &gpu_preferences);
+ CHECK(success);
+ }
+
+ if (gpu_preferences.gpu_startup_dialog)
WaitForDebugger("Gpu");
base::Time start_time = base::Time::Now();
@@ -239,9 +255,10 @@ int GpuMain(const MainFunctionParams& parameters) {
#elif defined(OS_LINUX)
#error "Unsupported Linux platform."
#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());
+ // Cross-process CoreAnimation requires a CFRunLoop to function at all, and
+ // requires a NSRunLoop to not starve under heavy load. See:
+ // https://crbug.com/312462#c51 and https://crbug.com/783298
+ std::unique_ptr<base::MessagePump> pump(new base::MessagePumpNSRunLoop());
main_message_loop.reset(new base::MessageLoop(std::move(pump)));
#else
main_message_loop.reset(
@@ -274,12 +291,12 @@ int GpuMain(const MainFunctionParams& parameters) {
// 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 initialization
- // message from the browser (through mojom::GpuMain::CreateGpuService()).
+ // message from the browser (through mojom::VizMain::CreateGpuService()).
const bool init_success = gpu_init->InitializeAndStartSandbox(
- const_cast<base::CommandLine*>(&command_line));
+ const_cast<base::CommandLine*>(&command_line), gpu_preferences);
const bool dead_on_arrival = !init_success;
- logging::SetLogMessageHandler(NULL);
+ logging::SetLogMessageHandler(nullptr);
GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
@@ -325,24 +342,38 @@ namespace {
#if defined(OS_LINUX)
bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
- const gpu::GPUInfo* gpu_info) {
+ const gpu::GPUInfo* gpu_info,
+ const gpu::GpuPreferences& gpu_prefs) {
TRACE_EVENT0("gpu,startup", "Initialize sandbox");
- bool res = false;
-
if (watchdog_thread) {
- // LinuxSandbox needs to be able to ensure that the thread
+ // SandboxLinux needs to be able to ensure that the thread
// has really been stopped.
- LinuxSandbox::StopThread(watchdog_thread);
+ service_manager::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
}
- // LinuxSandbox::InitializeSandbox() must always be called
+ // SandboxLinux::InitializeSandbox() must always be called
// with only one thread.
- res = LinuxSandbox::InitializeSandbox(gpu_info);
+ service_manager::SandboxLinux::Options sandbox_options;
+ sandbox_options.use_amd_specific_policies =
+ gpu_info && angle::IsAMD(gpu_info->active_gpu().vendor_id);
+ sandbox_options.accelerated_video_decode_enabled =
+ !gpu_prefs.disable_accelerated_video_decode;
+
+#if defined(OS_CHROMEOS)
+ sandbox_options.vaapi_accelerated_video_encode_enabled =
+ !gpu_prefs.disable_vaapi_accelerated_video_encode;
+#endif
+
+ bool res = service_manager::SandboxLinux::GetInstance()->InitializeSandbox(
+ service_manager::SandboxTypeFromCommandLine(
+ *base::CommandLine::ForCurrentProcess()),
+ base::BindOnce(GpuProcessPreSandboxHook), sandbox_options);
+
if (watchdog_thread) {
- base::Thread::Options options;
- options.timer_slack = base::TIMER_SLACK_MAXIMUM;
- watchdog_thread->StartWithOptions(options);
+ base::Thread::Options thread_options;
+ thread_options.timer_slack = base::TIMER_SLACK_MAXIMUM;
+ watchdog_thread->StartWithOptions(thread_options);
}
return res;
diff --git a/chromium/content/gpu/gpu_sandbox_hook_linux.cc b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
new file mode 100644
index 00000000000..c0ea3627ea5
--- /dev/null
+++ b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
@@ -0,0 +1,351 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/gpu/gpu_sandbox_hook_linux.h"
+
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/scoped_file.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+#include "content/public/common/content_switches.h"
+#include "media/gpu/features.h"
+#include "sandbox/linux/bpf_dsl/policy.h"
+#include "sandbox/linux/syscall_broker/broker_file_permission.h"
+#include "sandbox/linux/syscall_broker/broker_process.h"
+#include "services/service_manager/embedder/set_process_title.h"
+#include "services/service_manager/sandbox/linux/bpf_cros_amd_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/bpf_cros_arm_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/bpf_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+#if BUILDFLAG(USE_VAAPI)
+#include <va/va_version.h>
+#endif
+
+using sandbox::bpf_dsl::Policy;
+using sandbox::syscall_broker::BrokerFilePermission;
+using sandbox::syscall_broker::BrokerProcess;
+
+namespace content {
+namespace {
+
+inline bool IsChromeOS() {
+#if defined(OS_CHROMEOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureX86_64() {
+#if defined(__x86_64__)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureI386() {
+#if defined(__i386__)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureArm() {
+#if defined(ARCH_CPU_ARM_FAMILY)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool UseV4L2Codec() {
+#if BUILDFLAG(USE_V4L2_CODEC)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool UseLibV4L2() {
+#if BUILDFLAG(USE_LIBV4L2)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsLibVAVersion2() {
+#if BUILDFLAG(USE_VAAPI) && VA_MAJOR_VERSION == 1
+ return true;
+#else
+ return false;
+#endif
+}
+
+constexpr int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
+
+void AddV4L2GpuWhitelist(
+ std::vector<BrokerFilePermission>* permissions,
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (options.accelerated_video_decode_enabled) {
+ // Device nodes for V4L2 video decode accelerator drivers.
+ static const base::FilePath::CharType kDevicePath[] =
+ FILE_PATH_LITERAL("/dev/");
+ static const base::FilePath::CharType kVideoDecPattern[] = "video-dec[0-9]";
+ base::FileEnumerator enumerator(base::FilePath(kDevicePath), false,
+ base::FileEnumerator::FILES,
+ base::FilePath(kVideoDecPattern).value());
+ for (base::FilePath name = enumerator.Next(); !name.empty();
+ name = enumerator.Next())
+ permissions->push_back(BrokerFilePermission::ReadWrite(name.value()));
+ }
+
+ // Device node for V4L2 video encode accelerator drivers.
+ static const char kDevVideoEncPath[] = "/dev/video-enc";
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevVideoEncPath));
+
+ // Device node for V4L2 JPEG decode accelerator drivers.
+ static const char kDevJpegDecPath[] = "/dev/jpeg-dec";
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevJpegDecPath));
+}
+
+void AddArmMaliGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ // Device file needed by the ARM GPU userspace.
+ static const char kMali0Path[] = "/dev/mali0";
+
+ // Image processor used on ARM platforms.
+ static const char kDevImageProc0Path[] = "/dev/image-proc0";
+
+ permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path));
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path));
+}
+
+void AddAmdGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ static const char* const kReadOnlyList[] = {"/etc/ld.so.cache",
+ "/usr/lib64/libEGL.so.1",
+ "/usr/lib64/libGLESv2.so.2"};
+ for (const char* item : kReadOnlyList)
+ permissions->push_back(BrokerFilePermission::ReadOnly(item));
+
+ static const char* const kReadWriteList[] = {
+ "/dev/dri",
+ "/dev/dri/card0",
+ "/dev/dri/controlD64",
+ "/dev/dri/renderD128",
+ "/sys/class/drm/card0/device/config",
+ "/sys/class/drm/controlD64/device/config",
+ "/sys/class/drm/renderD128/device/config",
+ "/usr/share/libdrm/amdgpu.ids"};
+ for (const char* item : kReadWriteList)
+ permissions->push_back(BrokerFilePermission::ReadWrite(item));
+
+ static const char kCharDevices[] = "/sys/dev/char/";
+ permissions->push_back(BrokerFilePermission::ReadOnlyRecursive(kCharDevices));
+}
+
+void AddArmGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ // On ARM we're enabling the sandbox before the X connection is made,
+ // so we need to allow access to |.Xauthority|.
+ static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
+ static const char kLdSoCache[] = "/etc/ld.so.cache";
+
+ // Files needed by the ARM GPU userspace.
+ static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
+ static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
+
+ permissions->push_back(BrokerFilePermission::ReadOnly(kXAuthorityPath));
+ permissions->push_back(BrokerFilePermission::ReadOnly(kLdSoCache));
+ permissions->push_back(BrokerFilePermission::ReadOnly(kLibGlesPath));
+ permissions->push_back(BrokerFilePermission::ReadOnly(kLibEglPath));
+
+ AddArmMaliGpuWhitelist(permissions);
+}
+
+void AddStandardGpuWhiteList(std::vector<BrokerFilePermission>* permissions) {
+ static const char kDriCardBasePath[] = "/dev/dri/card";
+ static const char kNvidiaCtlPath[] = "/dev/nvidiactl";
+ static const char kNvidiaDeviceBasePath[] = "/dev/nvidia";
+ static const char kNvidiaParamsPath[] = "/proc/driver/nvidia/params";
+ static const char kDevShm[] = "/dev/shm/";
+
+ // For shared memory.
+ permissions->push_back(
+ BrokerFilePermission::ReadWriteCreateTemporaryRecursive(kDevShm));
+
+ // For DRI cards.
+ for (int i = 0; i <= 9; ++i) {
+ permissions->push_back(BrokerFilePermission::ReadWrite(
+ base::StringPrintf("%s%d", kDriCardBasePath, i)));
+ }
+
+ // For Nvidia GLX driver.
+ permissions->push_back(BrokerFilePermission::ReadWrite(kNvidiaCtlPath));
+ for (int i = 0; i < 10; ++i) {
+ permissions->push_back(BrokerFilePermission::ReadWrite(
+ base::StringPrintf("%s%d", kNvidiaDeviceBasePath, i)));
+ }
+ permissions->push_back(BrokerFilePermission::ReadOnly(kNvidiaParamsPath));
+}
+
+std::vector<BrokerFilePermission> FilePermissionsForGpu(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ std::vector<BrokerFilePermission> permissions;
+
+ // All GPU process policies need this file brokered out.
+ static const char kDriRcPath[] = "/etc/drirc";
+ permissions.push_back(BrokerFilePermission::ReadOnly(kDriRcPath));
+
+ if (IsChromeOS()) {
+ if (UseV4L2Codec())
+ AddV4L2GpuWhitelist(&permissions, options);
+ if (IsArchitectureArm()) {
+ AddArmGpuWhitelist(&permissions);
+ return permissions;
+ }
+ if (options.use_amd_specific_policies) {
+ AddAmdGpuWhitelist(&permissions);
+ return permissions;
+ }
+ }
+ AddStandardGpuWhiteList(&permissions);
+ return permissions;
+}
+
+void LoadArmGpuLibraries() {
+ // Preload the Mali library.
+ dlopen("/usr/lib/libmali.so", dlopen_flag);
+
+ // Preload the Tegra V4L2 (video decode acceleration) library.
+ dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
+}
+
+bool LoadAmdGpuLibraries() {
+ // Preload the amdgpu-dependent libraries.
+ if (nullptr == dlopen("libglapi.so", dlopen_flag)) {
+ LOG(ERROR) << "dlopen(libglapi.so) failed with error: " << dlerror();
+ return false;
+ }
+
+ const char* radeonsi_lib = "/usr/lib64/dri/radeonsi_dri.so";
+#if defined(DRI_DRIVER_DIR)
+ radeonsi_lib = DRI_DRIVER_DIR "/radeonsi_dri.so";
+#endif
+ if (nullptr == dlopen(radeonsi_lib, dlopen_flag)) {
+ LOG(ERROR) << "dlopen(radeonsi_dri.so) failed with error: " << dlerror();
+ return false;
+ }
+ return true;
+}
+
+void LoadV4L2Libraries() {
+ if (UseLibV4L2()) {
+ dlopen("/usr/lib/libv4l2.so", dlopen_flag);
+
+ // This is a device-specific encoder plugin.
+ dlopen("/usr/lib/libv4l/plugins/libv4l-encplugin.so", dlopen_flag);
+ }
+}
+
+void LoadStandardLibraries(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (IsArchitectureX86_64() || IsArchitectureI386()) {
+ // Accelerated video dlopen()'s some shared objects
+ // inside the sandbox, so preload them now.
+ if (options.vaapi_accelerated_video_encode_enabled ||
+ options.accelerated_video_decode_enabled) {
+ if (IsLibVAVersion2()) {
+ if (IsArchitectureX86_64()) {
+ dlopen("/usr/lib64/va/drivers/i965_drv_video.so", dlopen_flag);
+ dlopen("/usr/lib64/va/drivers/hybrid_drv_video.so", dlopen_flag);
+ } else if (IsArchitectureI386()) {
+ dlopen("/usr/lib/va/drivers/i965_drv_video.so", dlopen_flag);
+ }
+ dlopen("libva.so.2", dlopen_flag);
+#if defined(USE_OZONE)
+ dlopen("libva-drm.so.2", dlopen_flag);
+#endif
+ } else {
+ // If we are linked against libva 1, we have two cases to handle:
+ // - the sysroot includes both libva 1 and 2, in which case the drivers
+ // are in /usr/lib{64}/va1/
+ // - the sysroot only includes libva 1, in which case the drivers are
+ // are in /usr/lib{64}/va/
+ // This is ugly, but temporary until all builds have switched to libva 2.
+ if (IsArchitectureX86_64()) {
+ if (!dlopen("/usr/lib64/va1/drivers/i965_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib64/va/drivers/i965_drv_video.so", dlopen_flag);
+ if (!dlopen("/usr/lib64/va1/drivers/hybrid_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib64/va/drivers/hybrid_drv_video.so", dlopen_flag);
+ } else if (IsArchitectureI386()) {
+ if (!dlopen("/usr/lib/va1/drivers/i965_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib/va/drivers/i965_drv_video.so", dlopen_flag);
+ }
+ dlopen("libva.so.1", dlopen_flag);
+#if defined(USE_OZONE)
+ dlopen("libva-drm.so.1", dlopen_flag);
+#elif defined(USE_X11)
+ dlopen("libva-x11.so.1", dlopen_flag);
+#endif
+ }
+ }
+ }
+}
+
+bool LoadLibrariesForGpu(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (IsChromeOS()) {
+ if (UseV4L2Codec())
+ LoadV4L2Libraries();
+ if (IsArchitectureArm()) {
+ LoadArmGpuLibraries();
+ return true;
+ }
+ if (options.use_amd_specific_policies)
+ return LoadAmdGpuLibraries();
+ }
+ LoadStandardLibraries(options);
+ return true;
+}
+
+bool BrokerProcessPreSandboxHook(
+ service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options) {
+ // Oddly enough, we call back into gpu to invoke this service manager
+ // method, since it is part of the embedder component, and the service
+ // mananger's sandbox component is a lower layer that can't depend on it.
+ service_manager::SetProcessTitleFromCommandLine(nullptr);
+ return true;
+}
+
+} // namespace
+
+bool GpuProcessPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options) {
+ auto* instance = service_manager::SandboxLinux::GetInstance();
+ instance->StartBrokerProcess(policy, FilePermissionsForGpu(options),
+ base::BindOnce(BrokerProcessPreSandboxHook),
+ options);
+
+ if (!LoadLibrariesForGpu(options))
+ return false;
+
+ // TODO(tsepez): enable namspace sandbox here once crashes are understood.
+
+ errno = 0;
+ return true;
+}
+
+} // namespace content
diff --git a/chromium/content/gpu/gpu_sandbox_hook_linux.h b/chromium/content/gpu/gpu_sandbox_hook_linux.h
new file mode 100644
index 00000000000..581f61f7a5b
--- /dev/null
+++ b/chromium/content/gpu/gpu_sandbox_hook_linux.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
+#define CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
+
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+namespace content {
+
+bool GpuProcessPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options);
+
+} // namespace content
+
+#endif // CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
diff --git a/chromium/content/gpu/gpu_service_factory.cc b/chromium/content/gpu/gpu_service_factory.cc
index c8d60024e39..9daced1ca4d 100644
--- a/chromium/content/gpu/gpu_service_factory.cc
+++ b/chromium/content/gpu/gpu_service_factory.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/shape_detection/public/interfaces/constants.mojom.h"
#include "services/shape_detection/shape_detection_service.h"
@@ -37,7 +38,12 @@ void GpuServiceFactory::RegisterServices(ServiceMap* services) {
info.factory =
base::Bind(&media::CreateGpuMediaService, gpu_preferences_, task_runner_,
media_gpu_channel_manager_, android_overlay_factory_cb_);
- info.use_own_thread = true;
+ // This service will host audio/video decoders, and if these decoding
+ // operations are blocked, user may hear audio glitch or see video freezing,
+ // hence "user blocking".
+ // TODO(crbug.com/786169): Check whether this needs to be single threaded.
+ info.task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
+ {base::TaskPriority::USER_BLOCKING});
services->insert(std::make_pair("media", info));
#endif
diff --git a/chromium/content/gpu/in_process_gpu_thread.cc b/chromium/content/gpu/in_process_gpu_thread.cc
index 185ddee629a..39145978648 100644
--- a/chromium/content/gpu/in_process_gpu_thread.cc
+++ b/chromium/content/gpu/in_process_gpu_thread.cc
@@ -12,6 +12,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/gpu/content_gpu_client.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/service/gpu_init.h"
@@ -27,10 +28,13 @@
namespace content {
-InProcessGpuThread::InProcessGpuThread(const InProcessChildThreadParams& params)
+InProcessGpuThread::InProcessGpuThread(
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences)
: base::Thread("Chrome_InProcGpuThread"),
params_(params),
- gpu_process_(NULL) {}
+ gpu_process_(nullptr),
+ gpu_preferences_(gpu_preferences) {}
InProcessGpuThread::~InProcessGpuThread() {
Stop();
@@ -54,6 +58,7 @@ void InProcessGpuThread::Init() {
auto gpu_init = std::make_unique<gpu::GpuInit>();
auto* client = GetContentClient()->gpu();
gpu_init->InitializeInProcess(base::CommandLine::ForCurrentProcess(),
+ gpu_preferences_,
client ? client->GetGPUInfo() : nullptr,
client ? client->GetGpuFeatureInfo() : nullptr);
@@ -77,8 +82,9 @@ void InProcessGpuThread::CleanUp() {
}
base::Thread* CreateInProcessGpuThread(
- const InProcessChildThreadParams& params) {
- return new InProcessGpuThread(params);
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences) {
+ return new InProcessGpuThread(params, gpu_preferences);
}
} // namespace content
diff --git a/chromium/content/gpu/in_process_gpu_thread.h b/chromium/content/gpu/in_process_gpu_thread.h
index 66af2058bdc..c8e96e88d47 100644
--- a/chromium/content/gpu/in_process_gpu_thread.h
+++ b/chromium/content/gpu/in_process_gpu_thread.h
@@ -11,6 +11,7 @@
#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "content/common/in_process_child_thread_params.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
namespace content {
@@ -20,7 +21,8 @@ class GpuProcess;
// with --in-process-gpu or --single-process.
class InProcessGpuThread : public base::Thread {
public:
- explicit InProcessGpuThread(const InProcessChildThreadParams& params);
+ explicit InProcessGpuThread(const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences);
~InProcessGpuThread() override;
protected:
@@ -33,11 +35,14 @@ class InProcessGpuThread : public base::Thread {
// Deleted in CleanUp() on the gpu thread, so don't use smart pointers.
GpuProcess* gpu_process_;
+ gpu::GpuPreferences gpu_preferences_;
+
DISALLOW_COPY_AND_ASSIGN(InProcessGpuThread);
};
CONTENT_EXPORT base::Thread* CreateInProcessGpuThread(
- const InProcessChildThreadParams& params);
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences);
} // namespace content