| 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());
|
|
|