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

Unified Diff: ui/ozone/platform/drm/host/drm_native_display_delegate.cc

Issue 1072193008: [1/4][Ozone-Drm] Process display hotplug events sequentially (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add task_pending_ Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/platform/drm/host/drm_native_display_delegate.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 709ade8b59bb1107dbb92c2ec80363b8fdfe5e22..dc57045af3ea8f6974963f34e81dc9dbe8f81d68 100644
--- a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
+++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
@@ -27,10 +27,13 @@ namespace {
typedef base::Callback<void(const base::FilePath&, base::File)>
OnOpenDeviceReplyCallback;
-void OpenDeviceOnWorkerThread(
- const base::FilePath& path,
- const scoped_refptr<base::TaskRunner>& reply_runner,
- const OnOpenDeviceReplyCallback& callback) {
+const char* kDisplayActionString[] = {
+ "ADD",
+ "REMOVE",
+ "CHANGE",
+};
+
+base::File OpenDrmDevice(const base::FilePath& path) {
base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_WRITE);
@@ -40,10 +43,21 @@ void OpenDeviceOnWorkerThread(
CHECK(!info.is_directory);
CHECK(path.DirName() == base::FilePath("/dev/dri"));
- if (file.IsValid()) {
- reply_runner->PostTask(
- FROM_HERE, base::Bind(callback, path, base::Passed(file.Pass())));
+ if (!file.IsValid()) {
+ LOG(ERROR) << "Failed to open " << path.value() << ": "
+ << base::File::ErrorToString(file.error_details());
}
+
+ 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())));
}
class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy {
@@ -76,8 +90,10 @@ DrmNativeDisplayDelegate::DrmNativeDisplayDelegate(
display_manager_(display_manager),
primary_graphics_card_path_(primary_graphics_card_path),
has_dummy_display_(false),
+ task_pending_(false),
weak_ptr_factory_(this) {
proxy_->RegisterHandler(this);
+ drm_devices_.insert(primary_graphics_card_path);
}
DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() {
@@ -226,57 +242,87 @@ void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) {
if (event.device_type() != DeviceEvent::DISPLAY)
return;
- switch (event.action_type()) {
- case DeviceEvent::ADD:
- VLOG(1) << "Got display added event for " << event.path().value();
- // The default card is a special case since it needs to be opened early on
- // the GPU process in order to initialize EGL. If it is opened here as
- // well, it will cause a race with opening it in the GPU process and the
- // GPU process may fail initialization.
- // TODO(dnicoara) Remove this when the media stack does not require super
- // early initialization.
- if (event.path() == primary_graphics_card_path_)
- return;
-
- base::WorkerPool::PostTask(
- FROM_HERE,
- base::Bind(&OpenDeviceOnWorkerThread, event.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&DrmNativeDisplayDelegate::OnNewGraphicsDevice,
- weak_ptr_factory_.GetWeakPtr())),
- false /* task_is_slow */);
- return;
- case DeviceEvent::CHANGE:
- VLOG(1) << "Got display changed event for " << event.path().value();
- break;
- case DeviceEvent::REMOVE:
- VLOG(1) << "Got display removed event for " << event.path().value();
- // It shouldn't be possible to remove this device.
- DCHECK(primary_graphics_card_path_ != event.path())
- << "Got event to remove primary graphics card "
- << event.path().value();
- proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event.path()));
- break;
+ event_queue_.push(DisplayEvent(event.action_type(), event.path()));
+ ProcessEvent();
+}
+
+void DrmNativeDisplayDelegate::ProcessEvent() {
+ while (!event_queue_.empty() && !task_pending_) {
+ DisplayEvent event = event_queue_.front();
+ event_queue_.pop();
+ VLOG(1) << "Got display event " << kDisplayActionString[event.action_type]
+ << " for " << event.path.value();
+ switch (event.action_type) {
+ case DeviceEvent::ADD:
+ if (drm_devices_.find(event.path) == drm_devices_.end()) {
+ drm_devices_.insert(event.path);
+ task_pending_ = base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(
+ &OpenDeviceOnWorkerThread, event.path,
+ base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice,
+ weak_ptr_factory_.GetWeakPtr())),
+ false /* task_is_slow */);
+ }
+ break;
+ case DeviceEvent::CHANGE:
+ task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&DrmNativeDisplayDelegate::OnUpdateGraphicsDevice,
+ weak_ptr_factory_.GetWeakPtr()));
+ break;
+ case DeviceEvent::REMOVE:
+ DCHECK(event.path != primary_graphics_card_path_)
+ << "Removing primary graphics card";
+ auto it = drm_devices_.find(event.path);
+ if (it != drm_devices_.end()) {
+ drm_devices_.erase(it);
+ task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice,
+ weak_ptr_factory_.GetWeakPtr(), event.path));
+ }
+ break;
+ }
+ }
+}
+
+void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path,
+ base::File file) {
+ if (file.IsValid()) {
+ proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
+ path, base::FileDescriptor(file.Pass())));
+ FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
+ OnConfigurationChanged());
}
+ task_pending_ = false;
+ ProcessEvent();
+}
+
+void DrmNativeDisplayDelegate::OnUpdateGraphicsDevice() {
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
+ task_pending_ = false;
+ ProcessEvent();
}
-void DrmNativeDisplayDelegate::OnNewGraphicsDevice(const base::FilePath& path,
- base::File file) {
- DCHECK(file.IsValid());
- proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
- path, base::FileDescriptor(file.Pass())));
-
+void DrmNativeDisplayDelegate::OnRemoveGraphicsDevice(
+ const base::FilePath& path) {
+ proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(path));
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
+ task_pending_ = false;
+ ProcessEvent();
}
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_);
device_manager_->ScanDevices(this);
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
« no previous file with comments | « ui/ozone/platform/drm/host/drm_native_display_delegate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698