| Index: ui/ozone/platform/drm/host/drm_native_display_delegate.cc
|
| diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
|
| index ffbb923da830fb520d93ac7ba2ebb66540a40b0a..36ba4f7db15d68b4b83ec59bd7538a6ee28cf844 100644
|
| --- a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
|
| +++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
|
| @@ -5,7 +5,6 @@
|
| #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
|
|
|
| #include <stdio.h>
|
| -#include <xf86drm.h>
|
|
|
| #include "base/logging.h"
|
| #include "base/thread_task_runner_handle.h"
|
| @@ -19,13 +18,14 @@
|
| #include "ui/ozone/common/display_util.h"
|
| #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
|
| #include "ui/ozone/platform/drm/host/display_manager.h"
|
| +#include "ui/ozone/platform/drm/host/drm_device_handle.h"
|
| #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
|
|
|
| namespace ui {
|
|
|
| namespace {
|
|
|
| -typedef base::Callback<void(const base::FilePath&, base::File)>
|
| +typedef base::Callback<void(const base::FilePath&, scoped_ptr<DrmDeviceHandle>)>
|
| OnOpenDeviceReplyCallback;
|
|
|
| const char* kDisplayActionString[] = {
|
| @@ -34,52 +34,22 @@ const char* kDisplayActionString[] = {
|
| "CHANGE",
|
| };
|
|
|
| -bool Authenticate(int fd) {
|
| - drm_magic_t magic = 0;
|
| - // We need to make sure the DRM device has enough privilege. Use the DRM
|
| - // authentication logic to figure out if the device has enough permissions.
|
| - return !drmGetMagic(fd, &magic) && !drmAuthMagic(fd, magic);
|
| -}
|
| -
|
| -base::File OpenDrmDevice(const base::FilePath& path) {
|
| - base::File file;
|
| - bool print_warning = true;
|
| - while (true) {
|
| - file = base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE);
|
| -
|
| - base::File::Info info;
|
| - file.GetInfo(&info);
|
| -
|
| - CHECK(!info.is_directory);
|
| - CHECK(path.DirName() == base::FilePath("/dev/dri"));
|
| -
|
| - if (!file.IsValid()) {
|
| - LOG(ERROR) << "Failed to open " << path.value() << ": "
|
| - << base::File::ErrorToString(file.error_details());
|
| - return file.Pass();
|
| - }
|
| -
|
| - if (Authenticate(file.GetPlatformFile()))
|
| - break;
|
| -
|
| - LOG_IF(WARNING, print_warning) << "Failed to authenticate " << path.value();
|
| -
|
| - print_warning = false;
|
| - usleep(100000);
|
| - }
|
| -
|
| - VLOG(1) << "Succeeded authenticating " << path.value();
|
| - return file.Pass();
|
| -}
|
| -
|
| void OpenDeviceOnWorkerThread(
|
| const base::FilePath& path,
|
| const scoped_refptr<base::TaskRunner>& reply_runner,
|
| const OnOpenDeviceReplyCallback& callback) {
|
| - base::File file = OpenDrmDevice(path);
|
| - reply_runner->PostTask(FROM_HERE,
|
| - base::Bind(callback, path, base::Passed(file.Pass())));
|
| + scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
|
| + handle->Initialize(path);
|
| + reply_runner->PostTask(
|
| + FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass())));
|
| +}
|
| +
|
| +void CloseDeviceOnWorkerThread(
|
| + scoped_ptr<DrmDeviceHandle> handle,
|
| + const scoped_refptr<base::TaskRunner>& reply_runner,
|
| + const base::Closure& callback) {
|
| + handle->Shutdown();
|
| + reply_runner->PostTask(FROM_HERE, callback);
|
| }
|
|
|
| class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy {
|
| @@ -114,7 +84,6 @@ DrmNativeDisplayDelegate::DrmNativeDisplayDelegate(
|
| has_dummy_display_(false),
|
| weak_ptr_factory_(this) {
|
| proxy_->RegisterHandler(this);
|
| - drm_devices_.insert(primary_graphics_card_path);
|
| }
|
|
|
| DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() {
|
| @@ -123,6 +92,19 @@ DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() {
|
| }
|
|
|
| void DrmNativeDisplayDelegate::Initialize() {
|
| + {
|
| + // First device needs to be treated specially. We need to open this
|
| + // synchronously since the GPU process will need it to initialize the
|
| + // graphics state.
|
| + base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| + scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
|
| + if (!handle->Initialize(primary_graphics_card_path_)) {
|
| + LOG(FATAL) << "Failed to open primary graphics card";
|
| + return;
|
| + }
|
| + drm_devices_.add(primary_graphics_card_path_, handle.Pass());
|
| + }
|
| +
|
| device_manager_->AddObserver(this);
|
| device_manager_->ScanDevices(this);
|
|
|
| @@ -276,7 +258,6 @@ void DrmNativeDisplayDelegate::ProcessEvent() {
|
| switch (event.action_type) {
|
| case DeviceEvent::ADD:
|
| if (drm_devices_.find(event.path) == drm_devices_.end()) {
|
| - drm_devices_.insert(event.path);
|
| base::WorkerPool::PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| @@ -300,11 +281,15 @@ void DrmNativeDisplayDelegate::ProcessEvent() {
|
| << "Removing primary graphics card";
|
| auto it = drm_devices_.find(event.path);
|
| if (it != drm_devices_.end()) {
|
| - drm_devices_.erase(it);
|
| - base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + base::WorkerPool::PostTask(
|
| FROM_HERE,
|
| - base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice,
|
| - weak_ptr_factory_.GetWeakPtr(), event.path));
|
| + base::Bind(
|
| + &CloseDeviceOnWorkerThread,
|
| + base::Passed(drm_devices_.take_and_erase(it)),
|
| + base::ThreadTaskRunnerHandle::Get(),
|
| + base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice,
|
| + weak_ptr_factory_.GetWeakPtr(), event.path)),
|
| + false /* task_is_slow */);
|
| return;
|
| }
|
| break;
|
| @@ -315,9 +300,12 @@ void DrmNativeDisplayDelegate::ProcessEvent() {
|
| }
|
| }
|
|
|
| -void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path,
|
| - base::File file) {
|
| - if (file.IsValid()) {
|
| +void DrmNativeDisplayDelegate::OnAddGraphicsDevice(
|
| + const base::FilePath& path,
|
| + scoped_ptr<DrmDeviceHandle> handle) {
|
| + if (handle->IsValid()) {
|
| + base::File file = handle->DuplicateFile();
|
| + drm_devices_.add(path, handle.Pass());
|
| proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
|
| path, base::FileDescriptor(file.Pass())));
|
| FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
|
| @@ -348,19 +336,11 @@ void DrmNativeDisplayDelegate::OnChannelEstablished(
|
| int host_id,
|
| scoped_refptr<base::SingleThreadTaskRunner> send_runner,
|
| const base::Callback<void(IPC::Message*)>& send_callback) {
|
| - drm_devices_.clear();
|
| - drm_devices_.insert(primary_graphics_card_path_);
|
| - {
|
| - // First device needs to be treated specially. We need to open this
|
| - // synchronously since the GPU process will need it to initialize the
|
| - // graphics state.
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| - base::File file = OpenDrmDevice(primary_graphics_card_path_);
|
| - if (!file.IsValid()) {
|
| - LOG(FATAL) << "Failed to open primary graphics card";
|
| - return;
|
| + for (auto pair : drm_devices_) {
|
| + if (pair.second->IsValid()) {
|
| + proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
|
| + pair.first, base::FileDescriptor(pair.second->DuplicateFile())));
|
| }
|
| - OnAddGraphicsDevice(primary_graphics_card_path_, file.Pass());
|
| }
|
|
|
| device_manager_->ScanDevices(this);
|
|
|