OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h" | 5 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <xf86drm.h> | 9 #include <xf86drm.h> |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 void OpenDeviceOnWorkerThread( | 41 void OpenDeviceOnWorkerThread( |
42 const base::FilePath& path, | 42 const base::FilePath& path, |
43 const scoped_refptr<base::TaskRunner>& reply_runner, | 43 const scoped_refptr<base::TaskRunner>& reply_runner, |
44 const OnOpenDeviceReplyCallback& callback) { | 44 const OnOpenDeviceReplyCallback& callback) { |
45 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); | 45 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); |
46 handle->Initialize(path); | 46 handle->Initialize(path); |
47 reply_runner->PostTask( | 47 reply_runner->PostTask( |
48 FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass()))); | 48 FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass()))); |
49 } | 49 } |
50 | 50 |
51 void CloseDeviceOnWorkerThread( | |
52 scoped_ptr<DrmDeviceHandle> handle, | |
53 const scoped_refptr<base::TaskRunner>& reply_runner, | |
54 const base::Closure& callback) { | |
55 handle.reset(); | |
56 reply_runner->PostTask(FROM_HERE, callback); | |
57 } | |
58 | |
59 base::FilePath GetPrimaryDisplayCardPath() { | 51 base::FilePath GetPrimaryDisplayCardPath() { |
60 struct drm_mode_card_res res; | 52 struct drm_mode_card_res res; |
61 for (int i = 0; /* end on first card# that does not exist */; i++) { | 53 for (int i = 0; /* end on first card# that does not exist */; i++) { |
62 std::string card_path = base::StringPrintf(kDefaultGraphicsCardPattern, i); | 54 std::string card_path = base::StringPrintf(kDefaultGraphicsCardPattern, i); |
63 | 55 |
64 if (access(card_path.c_str(), F_OK) != 0) | 56 if (access(card_path.c_str(), F_OK) != 0) |
65 break; | 57 break; |
66 | 58 |
67 int fd = open(card_path.c_str(), O_RDWR | O_CLOEXEC); | 59 int fd = open(card_path.c_str(), O_RDWR | O_CLOEXEC); |
68 if (fd < 0) { | 60 if (fd < 0) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 delegate_(nullptr), | 96 delegate_(nullptr), |
105 primary_graphics_card_path_(GetPrimaryDisplayCardPath()), | 97 primary_graphics_card_path_(GetPrimaryDisplayCardPath()), |
106 has_dummy_display_(false), | 98 has_dummy_display_(false), |
107 task_pending_(false), | 99 task_pending_(false), |
108 weak_ptr_factory_(this) { | 100 weak_ptr_factory_(this) { |
109 { | 101 { |
110 // First device needs to be treated specially. We need to open this | 102 // First device needs to be treated specially. We need to open this |
111 // synchronously since the GPU process will need it to initialize the | 103 // synchronously since the GPU process will need it to initialize the |
112 // graphics state. | 104 // graphics state. |
113 base::ThreadRestrictions::ScopedAllowIO allow_io; | 105 base::ThreadRestrictions::ScopedAllowIO allow_io; |
114 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); | 106 primary_drm_device_handle_.reset(new DrmDeviceHandle()); |
115 if (!handle->Initialize(primary_graphics_card_path_)) { | 107 if (!primary_drm_device_handle_->Initialize(primary_graphics_card_path_)) { |
116 LOG(FATAL) << "Failed to open primary graphics card"; | 108 LOG(FATAL) << "Failed to open primary graphics card"; |
117 return; | 109 return; |
118 } | 110 } |
119 drm_devices_.add(primary_graphics_card_path_, handle.Pass()); | 111 drm_devices_.insert(primary_graphics_card_path_); |
120 } | 112 } |
121 | 113 |
122 device_manager_->AddObserver(this); | 114 device_manager_->AddObserver(this); |
123 proxy_->RegisterHandler(this); | 115 proxy_->RegisterHandler(this); |
124 | 116 |
125 DrmDeviceHandle* handle = drm_devices_.get(primary_graphics_card_path_); | |
126 ScopedVector<HardwareDisplayControllerInfo> display_infos = | 117 ScopedVector<HardwareDisplayControllerInfo> display_infos = |
127 GetAvailableDisplayControllerInfos(handle->fd()); | 118 GetAvailableDisplayControllerInfos(primary_drm_device_handle_->fd()); |
128 has_dummy_display_ = !display_infos.empty(); | 119 has_dummy_display_ = !display_infos.empty(); |
129 for (size_t i = 0; i < display_infos.size(); ++i) { | 120 for (size_t i = 0; i < display_infos.size(); ++i) { |
130 displays_.push_back(new DisplaySnapshotProxy(CreateDisplaySnapshotParams( | 121 displays_.push_back(new DisplaySnapshotProxy(CreateDisplaySnapshotParams( |
131 display_infos[i], handle->fd(), i, gfx::Point()))); | 122 display_infos[i], primary_drm_device_handle_->fd(), i, gfx::Point()))); |
132 } | 123 } |
133 } | 124 } |
134 | 125 |
135 DrmDisplayHostManager::~DrmDisplayHostManager() { | 126 DrmDisplayHostManager::~DrmDisplayHostManager() { |
136 device_manager_->RemoveObserver(this); | 127 device_manager_->RemoveObserver(this); |
137 proxy_->UnregisterHandler(this); | 128 proxy_->UnregisterHandler(this); |
138 | |
139 for (auto it = drm_devices_.begin(); it != drm_devices_.end(); ++it) { | |
140 base::WorkerPool::PostTask(FROM_HERE, | |
141 base::Bind(&CloseDeviceOnWorkerThread, | |
142 base::Passed(drm_devices_.take(it)), | |
143 base::ThreadTaskRunnerHandle::Get(), | |
144 base::Bind(&base::DoNothing)), | |
145 false /* task_is_slow */); | |
146 } | |
147 } | 129 } |
148 | 130 |
149 DisplaySnapshot* DrmDisplayHostManager::GetDisplay(int64_t display_id) { | 131 DisplaySnapshot* DrmDisplayHostManager::GetDisplay(int64_t display_id) { |
150 auto it = std::find_if(displays_.begin(), displays_.end(), | 132 auto it = std::find_if(displays_.begin(), displays_.end(), |
151 FindDisplaySnapshotById(display_id)); | 133 FindDisplaySnapshotById(display_id)); |
152 if (it == displays_.end()) | 134 if (it == displays_.end()) |
153 return nullptr; | 135 return nullptr; |
154 | 136 |
155 return *it; | 137 return *it; |
156 } | 138 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( | 243 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( |
262 FROM_HERE, | 244 FROM_HERE, |
263 base::Bind(&DrmDisplayHostManager::OnUpdateGraphicsDevice, | 245 base::Bind(&DrmDisplayHostManager::OnUpdateGraphicsDevice, |
264 weak_ptr_factory_.GetWeakPtr())); | 246 weak_ptr_factory_.GetWeakPtr())); |
265 break; | 247 break; |
266 case DeviceEvent::REMOVE: | 248 case DeviceEvent::REMOVE: |
267 DCHECK(event.path != primary_graphics_card_path_) | 249 DCHECK(event.path != primary_graphics_card_path_) |
268 << "Removing primary graphics card"; | 250 << "Removing primary graphics card"; |
269 auto it = drm_devices_.find(event.path); | 251 auto it = drm_devices_.find(event.path); |
270 if (it != drm_devices_.end()) { | 252 if (it != drm_devices_.end()) { |
271 task_pending_ = base::WorkerPool::PostTask( | 253 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( |
272 FROM_HERE, | 254 FROM_HERE, |
273 base::Bind( | 255 base::Bind(&DrmDisplayHostManager::OnRemoveGraphicsDevice, |
274 &CloseDeviceOnWorkerThread, | 256 weak_ptr_factory_.GetWeakPtr(), event.path)); |
275 base::Passed(drm_devices_.take_and_erase(it)), | 257 drm_devices_.erase(it); |
276 base::ThreadTaskRunnerHandle::Get(), | |
277 base::Bind(&DrmDisplayHostManager::OnRemoveGraphicsDevice, | |
278 weak_ptr_factory_.GetWeakPtr(), event.path)), | |
279 false /* task_is_slow */); | |
280 return; | |
281 } | 258 } |
282 break; | 259 break; |
283 } | 260 } |
284 } | 261 } |
285 } | 262 } |
286 | 263 |
287 void DrmDisplayHostManager::OnAddGraphicsDevice( | 264 void DrmDisplayHostManager::OnAddGraphicsDevice( |
288 const base::FilePath& path, | 265 const base::FilePath& path, |
289 scoped_ptr<DrmDeviceHandle> handle) { | 266 scoped_ptr<DrmDeviceHandle> handle) { |
290 if (handle->IsValid()) { | 267 if (handle->IsValid()) { |
291 base::ScopedFD file = handle->Duplicate(); | 268 drm_devices_.insert(path); |
292 drm_devices_.add(path, handle.Pass()); | |
293 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( | 269 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( |
294 path, base::FileDescriptor(file.Pass()))); | 270 path, base::FileDescriptor(handle->PassFD()))); |
295 NotifyDisplayDelegate(); | 271 NotifyDisplayDelegate(); |
296 } | 272 } |
297 | 273 |
298 task_pending_ = false; | 274 task_pending_ = false; |
299 ProcessEvent(); | 275 ProcessEvent(); |
300 } | 276 } |
301 | 277 |
302 void DrmDisplayHostManager::OnUpdateGraphicsDevice() { | 278 void DrmDisplayHostManager::OnUpdateGraphicsDevice() { |
303 NotifyDisplayDelegate(); | 279 NotifyDisplayDelegate(); |
304 task_pending_ = false; | 280 task_pending_ = false; |
305 ProcessEvent(); | 281 ProcessEvent(); |
306 } | 282 } |
307 | 283 |
308 void DrmDisplayHostManager::OnRemoveGraphicsDevice(const base::FilePath& path) { | 284 void DrmDisplayHostManager::OnRemoveGraphicsDevice(const base::FilePath& path) { |
309 proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(path)); | 285 proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(path)); |
310 NotifyDisplayDelegate(); | 286 NotifyDisplayDelegate(); |
311 task_pending_ = false; | 287 task_pending_ = false; |
312 ProcessEvent(); | 288 ProcessEvent(); |
313 } | 289 } |
314 | 290 |
315 void DrmDisplayHostManager::OnChannelEstablished( | 291 void DrmDisplayHostManager::OnChannelEstablished( |
316 int host_id, | 292 int host_id, |
317 scoped_refptr<base::SingleThreadTaskRunner> send_runner, | 293 scoped_refptr<base::SingleThreadTaskRunner> send_runner, |
318 const base::Callback<void(IPC::Message*)>& send_callback) { | 294 const base::Callback<void(IPC::Message*)>& send_callback) { |
319 auto it = drm_devices_.find(primary_graphics_card_path_); | 295 drm_devices_.clear(); |
320 DCHECK(it != drm_devices_.end()); | 296 drm_devices_.insert(primary_graphics_card_path_); |
| 297 scoped_ptr<DrmDeviceHandle> handle = primary_drm_device_handle_.Pass(); |
| 298 if (!handle) { |
| 299 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 300 handle.reset(new DrmDeviceHandle()); |
| 301 if (!handle->Initialize(primary_graphics_card_path_)) |
| 302 LOG(FATAL) << "Failed to open primary graphics card"; |
| 303 } |
| 304 |
321 // Send the primary device first since this is used to initialize graphics | 305 // Send the primary device first since this is used to initialize graphics |
322 // state. | 306 // state. |
323 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( | 307 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( |
324 it->first, base::FileDescriptor(it->second->Duplicate()))); | 308 primary_graphics_card_path_, base::FileDescriptor(handle->PassFD()))); |
325 | |
326 for (auto pair : drm_devices_) { | |
327 if (pair.second->IsValid() && pair.first != primary_graphics_card_path_) { | |
328 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( | |
329 pair.first, base::FileDescriptor(pair.second->Duplicate()))); | |
330 } | |
331 } | |
332 | 309 |
333 device_manager_->ScanDevices(this); | 310 device_manager_->ScanDevices(this); |
334 NotifyDisplayDelegate(); | 311 NotifyDisplayDelegate(); |
335 } | 312 } |
336 | 313 |
337 void DrmDisplayHostManager::OnChannelDestroyed(int host_id) { | 314 void DrmDisplayHostManager::OnChannelDestroyed(int host_id) { |
338 // If the channel got destroyed in the middle of a configuration then just | 315 // If the channel got destroyed in the middle of a configuration then just |
339 // respond with failure. | 316 // respond with failure. |
340 if (!get_displays_callback_.is_null()) { | 317 if (!get_displays_callback_.is_null()) { |
341 base::ThreadTaskRunnerHandle::Get()->PostTask( | 318 base::ThreadTaskRunnerHandle::Get()->PostTask( |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 const GetDisplaysCallback& callback) const { | 394 const GetDisplaysCallback& callback) const { |
418 callback.Run(displays_.get()); | 395 callback.Run(displays_.get()); |
419 } | 396 } |
420 | 397 |
421 void DrmDisplayHostManager::NotifyDisplayDelegate() const { | 398 void DrmDisplayHostManager::NotifyDisplayDelegate() const { |
422 if (delegate_) | 399 if (delegate_) |
423 delegate_->OnConfigurationChanged(); | 400 delegate_->OnConfigurationChanged(); |
424 } | 401 } |
425 | 402 |
426 } // namespace ui | 403 } // namespace ui |
OLD | NEW |