Chromium Code Reviews| 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 ca3ae94ff304ca36352c66fa38f3b95d212a9d2a..6178a39948ac9b1ab15dbbda87d1b8c1d5d660c7 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" |
| @@ -18,14 +17,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)> |
| - OnOpenDeviceReplyCallback; |
| +typedef base::Callback<void(const base::FilePath&)> OnOpenDeviceReplyCallback; |
| const char* kDisplayActionString[] = { |
| "ADD", |
| @@ -33,52 +32,13 @@ 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, |
| + DrmDeviceHandle* handle, |
| 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()))); |
| + if (handle->Initialize(path)) |
| + reply_runner->PostTask(FROM_HERE, base::Bind(callback, path)); |
| } |
| void UpdateDeviceOnWorkerThread( |
| @@ -88,6 +48,14 @@ void UpdateDeviceOnWorkerThread( |
| reply_runner->PostTask(FROM_HERE, callback); |
| } |
| +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 { |
| public: |
| DrmDisplaySnapshotProxy(const DisplaySnapshot_Params& params, |
| @@ -120,7 +88,6 @@ DrmNativeDisplayDelegate::DrmNativeDisplayDelegate( |
| has_dummy_display_(false), |
| weak_ptr_factory_(this) { |
| proxy_->RegisterHandler(this); |
| - drm_devices_.insert(primary_graphics_card_path); |
| } |
| DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() { |
| @@ -269,14 +236,15 @@ void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) { |
| switch (event.action_type()) { |
| case DeviceEvent::ADD: |
| if (drm_devices_.find(event.path()) == drm_devices_.end()) { |
| - drm_devices_.insert(event.path()); |
| + scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); |
| scheduler_.PostNamedSequencedWorkerTask( |
| event.path().value(), FROM_HERE, |
| base::Bind( |
| - &OpenDeviceOnWorkerThread, event.path(), |
| + &OpenDeviceOnWorkerThread, event.path(), handle.get(), |
| base::ThreadTaskRunnerHandle::Get(), |
| base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice, |
| weak_ptr_factory_.GetWeakPtr()))); |
| + drm_devices_.add(event.path(), handle.Pass()); |
|
dnicoara
2015/04/27 16:46:55
Hmm, this will be problematic since the handle may
|
| } |
| return; |
| case DeviceEvent::CHANGE: |
| @@ -292,11 +260,11 @@ void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) { |
| << "Removing primary graphics card"; |
| auto it = drm_devices_.find(event.path()); |
| if (it != drm_devices_.end()) { |
| - drm_devices_.erase(it); |
| scheduler_.PostNamedSequencedWorkerTask( |
| event.path().value(), FROM_HERE, |
| base::Bind( |
| - &UpdateDeviceOnWorkerThread, |
| + &CloseDeviceOnWorkerThread, |
| + base::Passed(drm_devices_.take_and_erase(it)), |
| base::ThreadTaskRunnerHandle::Get(), |
| base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice, |
| weak_ptr_factory_.GetWeakPtr(), event.path()))); |
| @@ -305,13 +273,13 @@ void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) { |
| } |
| } |
| -void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path, |
| - base::File file) { |
| - if (!file.IsValid()) |
| +void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path) { |
| + auto it = drm_devices_.find(path); |
| + if (it == drm_devices_.end()) |
| return; |
| proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( |
| - path, base::FileDescriptor(file.Pass()))); |
| + path, base::FileDescriptor(it->second->DuplicateFile()))); |
| FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, |
| OnConfigurationChanged()); |
| } |
| @@ -332,21 +300,23 @@ 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_); |
| - { |
| + if (drm_devices_.find(primary_graphics_card_path_) == drm_devices_.end()) { |
| // 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()) { |
| + scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); |
| + if (!handle->Initialize(primary_graphics_card_path_)) { |
| LOG(FATAL) << "Failed to open primary graphics card"; |
| return; |
| } |
| - OnAddGraphicsDevice(primary_graphics_card_path_, file.Pass()); |
| + drm_devices_.add(primary_graphics_card_path_, handle.Pass()); |
| + OnAddGraphicsDevice(primary_graphics_card_path_); |
| } |
| + for (auto pair : drm_devices_) |
| + OnAddGraphicsDevice(pair.first); |
| + |
| device_manager_->ScanDevices(this); |
| FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, |
| OnConfigurationChanged()); |