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

Side by Side Diff: ui/ozone/platform/drm/host/drm_display_host_manager.cc

Issue 1124063003: drm: GPU process manages VGEM fd. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase to ToT Created 5 years, 7 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 unified diff | Download patch
« no previous file with comments | « ui/ozone/platform/drm/host/drm_display_host_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #include "base/files/file_enumerator.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
13 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/thread_restrictions.h" 15 #include "base/threading/thread_restrictions.h"
15 #include "base/threading/worker_pool.h" 16 #include "base/threading/worker_pool.h"
16 #include "ui/events/ozone/device/device_event.h" 17 #include "ui/events/ozone/device/device_event.h"
17 #include "ui/events/ozone/device/device_manager.h" 18 #include "ui/events/ozone/device/device_manager.h"
18 #include "ui/ozone/common/display_snapshot_proxy.h" 19 #include "ui/ozone/common/display_snapshot_proxy.h"
19 #include "ui/ozone/common/display_util.h" 20 #include "ui/ozone/common/display_util.h"
20 #include "ui/ozone/common/gpu/ozone_gpu_messages.h" 21 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
21 #include "ui/ozone/platform/drm/common/drm_util.h" 22 #include "ui/ozone/platform/drm/common/drm_util.h"
22 #include "ui/ozone/platform/drm/host/drm_device_handle.h" 23 #include "ui/ozone/platform/drm/host/drm_device_handle.h"
23 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" 24 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
24 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h" 25 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
25 26
26 namespace ui { 27 namespace ui {
27 28
28 namespace { 29 namespace {
29 30
30 typedef base::Callback<void(const base::FilePath&, scoped_ptr<DrmDeviceHandle>)> 31 typedef base::Callback<void(const base::FilePath&, scoped_ptr<DrmDeviceHandle>)>
31 OnOpenDeviceReplyCallback; 32 OnOpenDeviceReplyCallback;
32 33
33 const char kDefaultGraphicsCardPattern[] = "/dev/dri/card%d"; 34 const char kDefaultGraphicsCardPattern[] = "/dev/dri/card%d";
35 const char kVgemDevDriCardPath[] = "/dev/dri/";
36 const char kVgemSysCardPath[] = "/sys/bus/platform/devices/vgem/drm/";
34 37
35 const char* kDisplayActionString[] = { 38 const char* kDisplayActionString[] = {
36 "ADD", 39 "ADD",
37 "REMOVE", 40 "REMOVE",
38 "CHANGE", 41 "CHANGE",
39 }; 42 };
40 43
41 void OpenDeviceOnWorkerThread( 44 void OpenDeviceOnWorkerThread(
42 const base::FilePath& path, 45 const base::FilePath& path,
46 bool is_vgem,
43 const scoped_refptr<base::TaskRunner>& reply_runner, 47 const scoped_refptr<base::TaskRunner>& reply_runner,
44 const OnOpenDeviceReplyCallback& callback) { 48 const OnOpenDeviceReplyCallback& callback) {
45 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle()); 49 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
46 handle->Initialize(path); 50 handle->Initialize(path, is_vgem);
47 reply_runner->PostTask( 51 reply_runner->PostTask(
48 FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass()))); 52 FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass())));
49 } 53 }
50 54
51 base::FilePath GetPrimaryDisplayCardPath() { 55 base::FilePath GetPrimaryDisplayCardPath() {
52 struct drm_mode_card_res res; 56 struct drm_mode_card_res res;
53 for (int i = 0; /* end on first card# that does not exist */; i++) { 57 for (int i = 0; /* end on first card# that does not exist */; i++) {
54 std::string card_path = base::StringPrintf(kDefaultGraphicsCardPattern, i); 58 std::string card_path = base::StringPrintf(kDefaultGraphicsCardPattern, i);
55 59
56 if (access(card_path.c_str(), F_OK) != 0) 60 if (access(card_path.c_str(), F_OK) != 0)
(...skipping 11 matching lines...) Expand all
68 if (ret == 0 && res.count_crtcs > 0) { 72 if (ret == 0 && res.count_crtcs > 0) {
69 return base::FilePath(card_path); 73 return base::FilePath(card_path);
70 } 74 }
71 75
72 VPLOG_IF(1, ret) << "Failed to get DRM resources for '" << card_path << "'"; 76 VPLOG_IF(1, ret) << "Failed to get DRM resources for '" << card_path << "'";
73 } 77 }
74 78
75 return base::FilePath(); 79 return base::FilePath();
76 } 80 }
77 81
82 base::FilePath GetVgemCardPath() {
83 base::FileEnumerator file_iter(
84 base::FilePath::FromUTF8Unsafe(kVgemSysCardPath), false,
85 base::FileEnumerator::DIRECTORIES, FILE_PATH_LITERAL("card*"));
86
87 while (!file_iter.Next().empty()) {
88 // Inspect the card%d directories in the directory and extract the filename.
89 std::string vgem_card_path =
90 kVgemDevDriCardPath +
91 file_iter.GetInfo().GetName().BaseName().MaybeAsASCII();
92 DVLOG(1) << "VGEM card path is " << vgem_card_path;
93 return base::FilePath(vgem_card_path);
94 }
95 DVLOG(1) << "Don't support VGEM";
96 return base::FilePath();
97 }
98
78 class FindDisplaySnapshotById { 99 class FindDisplaySnapshotById {
79 public: 100 public:
80 FindDisplaySnapshotById(int64_t display_id) : display_id_(display_id) {} 101 FindDisplaySnapshotById(int64_t display_id) : display_id_(display_id) {}
81 102
82 bool operator()(const DisplaySnapshot* display) { 103 bool operator()(const DisplaySnapshot* display) {
83 return display->display_id() == display_id_; 104 return display->display_id() == display_id_;
84 } 105 }
85 106
86 private: 107 private:
87 int64_t display_id_; 108 int64_t display_id_;
88 }; 109 };
89 110
90 } // namespace 111 } // namespace
91 112
92 DrmDisplayHostManager::DrmDisplayHostManager(DrmGpuPlatformSupportHost* proxy, 113 DrmDisplayHostManager::DrmDisplayHostManager(DrmGpuPlatformSupportHost* proxy,
93 DeviceManager* device_manager) 114 DeviceManager* device_manager)
94 : proxy_(proxy), 115 : proxy_(proxy),
95 device_manager_(device_manager), 116 device_manager_(device_manager),
96 delegate_(nullptr), 117 delegate_(nullptr),
97 primary_graphics_card_path_(GetPrimaryDisplayCardPath()), 118 primary_graphics_card_path_(GetPrimaryDisplayCardPath()),
98 has_dummy_display_(false), 119 has_dummy_display_(false),
99 task_pending_(false), 120 task_pending_(false),
100 weak_ptr_factory_(this) { 121 weak_ptr_factory_(this) {
101 { 122 {
102 // First device needs to be treated specially. We need to open this 123 // First device needs to be treated specially. We need to open this
103 // synchronously since the GPU process will need it to initialize the 124 // synchronously since the GPU process will need it to initialize the
104 // graphics state. 125 // graphics state.
105 base::ThreadRestrictions::ScopedAllowIO allow_io; 126 base::ThreadRestrictions::ScopedAllowIO allow_io;
106 primary_drm_device_handle_.reset(new DrmDeviceHandle()); 127 primary_drm_device_handle_.reset(new DrmDeviceHandle());
107 if (!primary_drm_device_handle_->Initialize(primary_graphics_card_path_)) { 128 if (!primary_drm_device_handle_->Initialize(primary_graphics_card_path_,
129 false)) {
108 LOG(FATAL) << "Failed to open primary graphics card"; 130 LOG(FATAL) << "Failed to open primary graphics card";
109 return; 131 return;
110 } 132 }
111 drm_devices_.insert(primary_graphics_card_path_); 133 drm_devices_.insert(primary_graphics_card_path_);
134
135 vgem_card_path_ = GetVgemCardPath();
112 } 136 }
113 137
114 device_manager_->AddObserver(this); 138 device_manager_->AddObserver(this);
115 proxy_->RegisterHandler(this); 139 proxy_->RegisterHandler(this);
116 140
117 ScopedVector<HardwareDisplayControllerInfo> display_infos = 141 ScopedVector<HardwareDisplayControllerInfo> display_infos =
118 GetAvailableDisplayControllerInfos(primary_drm_device_handle_->fd()); 142 GetAvailableDisplayControllerInfos(primary_drm_device_handle_->fd());
119 has_dummy_display_ = !display_infos.empty(); 143 has_dummy_display_ = !display_infos.empty();
120 for (size_t i = 0; i < display_infos.size(); ++i) { 144 for (size_t i = 0; i < display_infos.size(); ++i) {
121 displays_.push_back(new DisplaySnapshotProxy(CreateDisplaySnapshotParams( 145 displays_.push_back(new DisplaySnapshotProxy(CreateDisplaySnapshotParams(
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 DisplayEvent event = event_queue_.front(); 250 DisplayEvent event = event_queue_.front();
227 event_queue_.pop(); 251 event_queue_.pop();
228 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type] 252 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type]
229 << " for " << event.path.value(); 253 << " for " << event.path.value();
230 switch (event.action_type) { 254 switch (event.action_type) {
231 case DeviceEvent::ADD: 255 case DeviceEvent::ADD:
232 if (drm_devices_.find(event.path) == drm_devices_.end()) { 256 if (drm_devices_.find(event.path) == drm_devices_.end()) {
233 task_pending_ = base::WorkerPool::PostTask( 257 task_pending_ = base::WorkerPool::PostTask(
234 FROM_HERE, 258 FROM_HERE,
235 base::Bind(&OpenDeviceOnWorkerThread, event.path, 259 base::Bind(&OpenDeviceOnWorkerThread, event.path,
260 event.path == vgem_card_path_,
236 base::ThreadTaskRunnerHandle::Get(), 261 base::ThreadTaskRunnerHandle::Get(),
237 base::Bind(&DrmDisplayHostManager::OnAddGraphicsDevice, 262 base::Bind(&DrmDisplayHostManager::OnAddGraphicsDevice,
238 weak_ptr_factory_.GetWeakPtr())), 263 weak_ptr_factory_.GetWeakPtr())),
239 false /* task_is_slow */); 264 false /* task_is_slow */);
240 } 265 }
241 break; 266 break;
242 case DeviceEvent::CHANGE: 267 case DeviceEvent::CHANGE:
243 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( 268 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
244 FROM_HERE, 269 FROM_HERE,
245 base::Bind(&DrmDisplayHostManager::OnUpdateGraphicsDevice, 270 base::Bind(&DrmDisplayHostManager::OnUpdateGraphicsDevice,
246 weak_ptr_factory_.GetWeakPtr())); 271 weak_ptr_factory_.GetWeakPtr()));
247 break; 272 break;
248 case DeviceEvent::REMOVE: 273 case DeviceEvent::REMOVE:
249 DCHECK(event.path != primary_graphics_card_path_) 274 DCHECK(event.path != primary_graphics_card_path_)
250 << "Removing primary graphics card"; 275 << "Removing primary graphics card";
276 DCHECK(event.path != vgem_card_path_) << "Removing VGEM device";
251 auto it = drm_devices_.find(event.path); 277 auto it = drm_devices_.find(event.path);
252 if (it != drm_devices_.end()) { 278 if (it != drm_devices_.end()) {
253 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( 279 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
254 FROM_HERE, 280 FROM_HERE,
255 base::Bind(&DrmDisplayHostManager::OnRemoveGraphicsDevice, 281 base::Bind(&DrmDisplayHostManager::OnRemoveGraphicsDevice,
256 weak_ptr_factory_.GetWeakPtr(), event.path)); 282 weak_ptr_factory_.GetWeakPtr(), event.path));
257 drm_devices_.erase(it); 283 drm_devices_.erase(it);
258 } 284 }
259 break; 285 break;
260 } 286 }
261 } 287 }
262 } 288 }
263 289
264 void DrmDisplayHostManager::OnAddGraphicsDevice( 290 void DrmDisplayHostManager::OnAddGraphicsDevice(
265 const base::FilePath& path, 291 const base::FilePath& path,
266 scoped_ptr<DrmDeviceHandle> handle) { 292 scoped_ptr<DrmDeviceHandle> handle) {
267 if (handle->IsValid()) { 293 if (handle->IsValid()) {
268 drm_devices_.insert(path); 294 drm_devices_.insert(path);
269 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( 295 if (handle->IsVgem()) {
270 path, base::FileDescriptor(handle->PassFD()))); 296 proxy_->Send(new OzoneGpuMsg_AddVgemDevice(
297 path, base::FileDescriptor(handle->PassFD())));
298 } else {
299 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
300 path, base::FileDescriptor(handle->PassFD())));
301 }
271 NotifyDisplayDelegate(); 302 NotifyDisplayDelegate();
272 } 303 }
273 304
274 task_pending_ = false; 305 task_pending_ = false;
275 ProcessEvent(); 306 ProcessEvent();
276 } 307 }
277 308
278 void DrmDisplayHostManager::OnUpdateGraphicsDevice() { 309 void DrmDisplayHostManager::OnUpdateGraphicsDevice() {
279 NotifyDisplayDelegate(); 310 NotifyDisplayDelegate();
280 task_pending_ = false; 311 task_pending_ = false;
(...skipping 10 matching lines...) Expand all
291 void DrmDisplayHostManager::OnChannelEstablished( 322 void DrmDisplayHostManager::OnChannelEstablished(
292 int host_id, 323 int host_id,
293 scoped_refptr<base::SingleThreadTaskRunner> send_runner, 324 scoped_refptr<base::SingleThreadTaskRunner> send_runner,
294 const base::Callback<void(IPC::Message*)>& send_callback) { 325 const base::Callback<void(IPC::Message*)>& send_callback) {
295 drm_devices_.clear(); 326 drm_devices_.clear();
296 drm_devices_.insert(primary_graphics_card_path_); 327 drm_devices_.insert(primary_graphics_card_path_);
297 scoped_ptr<DrmDeviceHandle> handle = primary_drm_device_handle_.Pass(); 328 scoped_ptr<DrmDeviceHandle> handle = primary_drm_device_handle_.Pass();
298 if (!handle) { 329 if (!handle) {
299 base::ThreadRestrictions::ScopedAllowIO allow_io; 330 base::ThreadRestrictions::ScopedAllowIO allow_io;
300 handle.reset(new DrmDeviceHandle()); 331 handle.reset(new DrmDeviceHandle());
301 if (!handle->Initialize(primary_graphics_card_path_)) 332 if (!handle->Initialize(primary_graphics_card_path_, false))
302 LOG(FATAL) << "Failed to open primary graphics card"; 333 LOG(FATAL) << "Failed to open primary graphics card";
303 } 334 }
304 335
305 // Send the primary device first since this is used to initialize graphics 336 // Send the primary device first since this is used to initialize graphics
306 // state. 337 // state.
307 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( 338 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
308 primary_graphics_card_path_, base::FileDescriptor(handle->PassFD()))); 339 primary_graphics_card_path_, base::FileDescriptor(handle->PassFD())));
309 340
310 device_manager_->ScanDevices(this); 341 device_manager_->ScanDevices(this);
311 NotifyDisplayDelegate(); 342 NotifyDisplayDelegate();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 const GetDisplaysCallback& callback) const { 425 const GetDisplaysCallback& callback) const {
395 callback.Run(displays_.get()); 426 callback.Run(displays_.get());
396 } 427 }
397 428
398 void DrmDisplayHostManager::NotifyDisplayDelegate() const { 429 void DrmDisplayHostManager::NotifyDisplayDelegate() const {
399 if (delegate_) 430 if (delegate_)
400 delegate_->OnConfigurationChanged(); 431 delegate_->OnConfigurationChanged();
401 } 432 }
402 433
403 } // namespace ui 434 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/drm/host/drm_display_host_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698