Index: ui/ozone/platform/dri/native_display_delegate_proxy.cc |
diff --git a/ui/ozone/platform/dri/native_display_delegate_proxy.cc b/ui/ozone/platform/dri/native_display_delegate_proxy.cc |
index 8ad2c40a46aa54222e93193ae09460c9290a125d..b05b820a90f5ea6c98a41f2e43af0b222392161d 100644 |
--- a/ui/ozone/platform/dri/native_display_delegate_proxy.cc |
+++ b/ui/ozone/platform/dri/native_display_delegate_proxy.cc |
@@ -7,7 +7,9 @@ |
#include <stdio.h> |
#include "base/logging.h" |
+#include "base/thread_task_runner_handle.h" |
#include "base/threading/thread_restrictions.h" |
+#include "base/threading/worker_pool.h" |
#include "ui/display/types/display_snapshot.h" |
#include "ui/display/types/native_display_observer.h" |
#include "ui/events/ozone/device/device_event.h" |
@@ -22,6 +24,24 @@ namespace ui { |
namespace { |
+const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; |
+ |
+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) { |
+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
+ base::File::FLAG_WRITE); |
+ |
jln (very slow on Chromium)
2015/02/19 01:28:58
Could you please CHECK that the file is not a dire
dnicoara
2015/02/19 02:42:53
Done. I've added another check to verify the path
|
+ if (file.IsValid()) { |
+ reply_runner->PostTask( |
+ FROM_HERE, base::Bind(callback, path, base::Passed(file.Pass()))); |
+ } |
+} |
+ |
class DriDisplaySnapshotProxy : public DisplaySnapshotProxy { |
public: |
DriDisplaySnapshotProxy(const DisplaySnapshot_Params& params, |
@@ -49,7 +69,8 @@ NativeDisplayDelegateProxy::NativeDisplayDelegateProxy( |
: proxy_(proxy), |
device_manager_(device_manager), |
display_manager_(display_manager), |
- has_dummy_display_(false) { |
+ has_dummy_display_(false), |
+ weak_ptr_factory_(this) { |
proxy_->RegisterHandler(this); |
} |
@@ -195,13 +216,31 @@ void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) { |
switch (event.action_type()) { |
case DeviceEvent::ADD: |
VLOG(1) << "Got display added event for " << event.path().value(); |
- proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(event.path())); |
- break; |
+ // 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 EGL_DEFAULT_DISPLAY is the only native |
+ // display we return in GbmSurfaceFactory. |
+ if (event.path().value() == kDefaultGraphicsCardPath) |
+ return; |
+ |
+ base::WorkerPool::PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &OpenDeviceOnWorkerThread, event.path(), |
+ base::ThreadTaskRunnerHandle::Get(), |
+ base::Bind(&NativeDisplayDelegateProxy::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_NE(kDefaultGraphicsCardPath, event.path().value()); |
proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event.path())); |
break; |
} |
@@ -210,10 +249,21 @@ void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) { |
OnConfigurationChanged()); |
} |
+void NativeDisplayDelegateProxy::OnNewGraphicsDevice(const base::FilePath& path, |
+ base::File file) { |
+ DCHECK(file.IsValid()); |
+ proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( |
+ path, base::FileDescriptor(file.Pass()))); |
+ |
+ FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, |
+ OnConfigurationChanged()); |
+} |
+ |
void NativeDisplayDelegateProxy::OnChannelEstablished( |
int host_id, |
scoped_refptr<base::SingleThreadTaskRunner> send_runner, |
const base::Callback<void(IPC::Message*)>& send_callback) { |
+ device_manager_->ScanDevices(this); |
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, |
OnConfigurationChanged()); |
} |