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

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

Issue 1064453003: [4/4][Ozone-Drm] Keep track of DRM devices in browser process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@change-page-flip-tracking
Patch Set: . 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 unified diff | 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 »
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_native_display_delegate.h" 5 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <xf86drm.h>
9 8
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "base/thread_task_runner_handle.h" 10 #include "base/thread_task_runner_handle.h"
12 #include "base/threading/thread_restrictions.h" 11 #include "base/threading/thread_restrictions.h"
13 #include "ui/display/types/display_snapshot.h" 12 #include "ui/display/types/display_snapshot.h"
14 #include "ui/display/types/native_display_observer.h" 13 #include "ui/display/types/native_display_observer.h"
15 #include "ui/events/ozone/device/device_event.h" 14 #include "ui/events/ozone/device/device_event.h"
16 #include "ui/events/ozone/device/device_manager.h" 15 #include "ui/events/ozone/device/device_manager.h"
17 #include "ui/ozone/common/display_snapshot_proxy.h" 16 #include "ui/ozone/common/display_snapshot_proxy.h"
18 #include "ui/ozone/common/display_util.h" 17 #include "ui/ozone/common/display_util.h"
19 #include "ui/ozone/common/gpu/ozone_gpu_messages.h" 18 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
20 #include "ui/ozone/platform/drm/host/display_manager.h" 19 #include "ui/ozone/platform/drm/host/display_manager.h"
20 #include "ui/ozone/platform/drm/host/drm_device_handle.h"
21 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" 21 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
22 22
23 namespace ui { 23 namespace ui {
24 24
25 namespace { 25 namespace {
26 26
27 typedef base::Callback<void(const base::FilePath&, base::File)> 27 typedef base::Callback<void(const base::FilePath&)> OnOpenDeviceReplyCallback;
28 OnOpenDeviceReplyCallback;
29 28
30 const char* kDisplayActionString[] = { 29 const char* kDisplayActionString[] = {
31 "ADD", 30 "ADD",
32 "REMOVE", 31 "REMOVE",
33 "CHANGE", 32 "CHANGE",
34 }; 33 };
35 34
36 bool Authenticate(int fd) {
37 drm_magic_t magic = 0;
38 // We need to make sure the DRM device has enough privilege. Use the DRM
39 // authentication logic to figure out if the device has enough permissions.
40 return !drmGetMagic(fd, &magic) && !drmAuthMagic(fd, magic);
41 }
42
43 base::File OpenDrmDevice(const base::FilePath& path) {
44 base::File file;
45 bool print_warning = true;
46 while (true) {
47 file = base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
48 base::File::FLAG_WRITE);
49
50 base::File::Info info;
51 file.GetInfo(&info);
52
53 CHECK(!info.is_directory);
54 CHECK(path.DirName() == base::FilePath("/dev/dri"));
55
56 if (!file.IsValid()) {
57 LOG(ERROR) << "Failed to open " << path.value() << ": "
58 << base::File::ErrorToString(file.error_details());
59 return file.Pass();
60 }
61
62 if (Authenticate(file.GetPlatformFile()))
63 break;
64
65 LOG_IF(WARNING, print_warning) << "Failed to authenticate " << path.value();
66
67 print_warning = false;
68 usleep(100000);
69 }
70
71 VLOG(1) << "Succeeded authenticating " << path.value();
72 return file.Pass();
73 }
74
75 void OpenDeviceOnWorkerThread( 35 void OpenDeviceOnWorkerThread(
76 const base::FilePath& path, 36 const base::FilePath& path,
37 DrmDeviceHandle* handle,
77 const scoped_refptr<base::TaskRunner>& reply_runner, 38 const scoped_refptr<base::TaskRunner>& reply_runner,
78 const OnOpenDeviceReplyCallback& callback) { 39 const OnOpenDeviceReplyCallback& callback) {
79 base::File file = OpenDrmDevice(path); 40 if (handle->Initialize(path))
80 reply_runner->PostTask(FROM_HERE, 41 reply_runner->PostTask(FROM_HERE, base::Bind(callback, path));
81 base::Bind(callback, path, base::Passed(file.Pass())));
82 } 42 }
83 43
84 void UpdateDeviceOnWorkerThread( 44 void UpdateDeviceOnWorkerThread(
85 const scoped_refptr<base::TaskRunner>& reply_runner, 45 const scoped_refptr<base::TaskRunner>& reply_runner,
86 const base::Closure& callback) { 46 const base::Closure& callback) {
87 // Just reply since there isn't a need for extra operations. 47 // Just reply since there isn't a need for extra operations.
88 reply_runner->PostTask(FROM_HERE, callback); 48 reply_runner->PostTask(FROM_HERE, callback);
89 } 49 }
90 50
51 void CloseDeviceOnWorkerThread(
52 scoped_ptr<DrmDeviceHandle> handle,
53 const scoped_refptr<base::TaskRunner>& reply_runner,
54 const base::Closure& callback) {
55 handle->Shutdown();
56 reply_runner->PostTask(FROM_HERE, callback);
57 }
58
91 class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy { 59 class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy {
92 public: 60 public:
93 DrmDisplaySnapshotProxy(const DisplaySnapshot_Params& params, 61 DrmDisplaySnapshotProxy(const DisplaySnapshot_Params& params,
94 DisplayManager* display_manager) 62 DisplayManager* display_manager)
95 : DisplaySnapshotProxy(params), display_manager_(display_manager) { 63 : DisplaySnapshotProxy(params), display_manager_(display_manager) {
96 display_manager_->RegisterDisplay(this); 64 display_manager_->RegisterDisplay(this);
97 } 65 }
98 66
99 ~DrmDisplaySnapshotProxy() override { 67 ~DrmDisplaySnapshotProxy() override {
100 display_manager_->UnregisterDisplay(this); 68 display_manager_->UnregisterDisplay(this);
(...skipping 12 matching lines...) Expand all
113 DeviceManager* device_manager, 81 DeviceManager* device_manager,
114 DisplayManager* display_manager, 82 DisplayManager* display_manager,
115 const base::FilePath& primary_graphics_card_path) 83 const base::FilePath& primary_graphics_card_path)
116 : proxy_(proxy), 84 : proxy_(proxy),
117 device_manager_(device_manager), 85 device_manager_(device_manager),
118 display_manager_(display_manager), 86 display_manager_(display_manager),
119 primary_graphics_card_path_(primary_graphics_card_path), 87 primary_graphics_card_path_(primary_graphics_card_path),
120 has_dummy_display_(false), 88 has_dummy_display_(false),
121 weak_ptr_factory_(this) { 89 weak_ptr_factory_(this) {
122 proxy_->RegisterHandler(this); 90 proxy_->RegisterHandler(this);
123 drm_devices_.insert(primary_graphics_card_path);
124 } 91 }
125 92
126 DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() { 93 DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() {
127 device_manager_->RemoveObserver(this); 94 device_manager_->RemoveObserver(this);
128 proxy_->UnregisterHandler(this); 95 proxy_->UnregisterHandler(this);
129 } 96 }
130 97
131 void DrmNativeDisplayDelegate::Initialize() { 98 void DrmNativeDisplayDelegate::Initialize() {
132 device_manager_->AddObserver(this); 99 device_manager_->AddObserver(this);
133 device_manager_->ScanDevices(this); 100 device_manager_->ScanDevices(this);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 229
263 void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) { 230 void DrmNativeDisplayDelegate::OnDeviceEvent(const DeviceEvent& event) {
264 if (event.device_type() != DeviceEvent::DISPLAY) 231 if (event.device_type() != DeviceEvent::DISPLAY)
265 return; 232 return;
266 233
267 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type()] 234 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type()]
268 << " for " << event.path().value(); 235 << " for " << event.path().value();
269 switch (event.action_type()) { 236 switch (event.action_type()) {
270 case DeviceEvent::ADD: 237 case DeviceEvent::ADD:
271 if (drm_devices_.find(event.path()) == drm_devices_.end()) { 238 if (drm_devices_.find(event.path()) == drm_devices_.end()) {
272 drm_devices_.insert(event.path()); 239 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
273 scheduler_.PostNamedSequencedWorkerTask( 240 scheduler_.PostNamedSequencedWorkerTask(
274 event.path().value(), FROM_HERE, 241 event.path().value(), FROM_HERE,
275 base::Bind( 242 base::Bind(
276 &OpenDeviceOnWorkerThread, event.path(), 243 &OpenDeviceOnWorkerThread, event.path(), handle.get(),
277 base::ThreadTaskRunnerHandle::Get(), 244 base::ThreadTaskRunnerHandle::Get(),
278 base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice, 245 base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice,
279 weak_ptr_factory_.GetWeakPtr()))); 246 weak_ptr_factory_.GetWeakPtr())));
247 drm_devices_.add(event.path(), handle.Pass());
dnicoara 2015/04/27 16:46:55 Hmm, this will be problematic since the handle may
280 } 248 }
281 return; 249 return;
282 case DeviceEvent::CHANGE: 250 case DeviceEvent::CHANGE:
283 scheduler_.PostNamedSequencedWorkerTask( 251 scheduler_.PostNamedSequencedWorkerTask(
284 event.path().value(), FROM_HERE, 252 event.path().value(), FROM_HERE,
285 base::Bind( 253 base::Bind(
286 &UpdateDeviceOnWorkerThread, base::ThreadTaskRunnerHandle::Get(), 254 &UpdateDeviceOnWorkerThread, base::ThreadTaskRunnerHandle::Get(),
287 base::Bind(&DrmNativeDisplayDelegate::OnUpdateGraphicsDevice, 255 base::Bind(&DrmNativeDisplayDelegate::OnUpdateGraphicsDevice,
288 weak_ptr_factory_.GetWeakPtr()))); 256 weak_ptr_factory_.GetWeakPtr())));
289 return; 257 return;
290 case DeviceEvent::REMOVE: 258 case DeviceEvent::REMOVE:
291 DCHECK(event.path() != primary_graphics_card_path_) 259 DCHECK(event.path() != primary_graphics_card_path_)
292 << "Removing primary graphics card"; 260 << "Removing primary graphics card";
293 auto it = drm_devices_.find(event.path()); 261 auto it = drm_devices_.find(event.path());
294 if (it != drm_devices_.end()) { 262 if (it != drm_devices_.end()) {
295 drm_devices_.erase(it);
296 scheduler_.PostNamedSequencedWorkerTask( 263 scheduler_.PostNamedSequencedWorkerTask(
297 event.path().value(), FROM_HERE, 264 event.path().value(), FROM_HERE,
298 base::Bind( 265 base::Bind(
299 &UpdateDeviceOnWorkerThread, 266 &CloseDeviceOnWorkerThread,
267 base::Passed(drm_devices_.take_and_erase(it)),
300 base::ThreadTaskRunnerHandle::Get(), 268 base::ThreadTaskRunnerHandle::Get(),
301 base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice, 269 base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice,
302 weak_ptr_factory_.GetWeakPtr(), event.path()))); 270 weak_ptr_factory_.GetWeakPtr(), event.path())));
303 } 271 }
304 return; 272 return;
305 } 273 }
306 } 274 }
307 275
308 void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path, 276 void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path) {
309 base::File file) { 277 auto it = drm_devices_.find(path);
310 if (!file.IsValid()) 278 if (it == drm_devices_.end())
311 return; 279 return;
312 280
313 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( 281 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
314 path, base::FileDescriptor(file.Pass()))); 282 path, base::FileDescriptor(it->second->DuplicateFile())));
315 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 283 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
316 OnConfigurationChanged()); 284 OnConfigurationChanged());
317 } 285 }
318 286
319 void DrmNativeDisplayDelegate::OnUpdateGraphicsDevice() { 287 void DrmNativeDisplayDelegate::OnUpdateGraphicsDevice() {
320 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 288 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
321 OnConfigurationChanged()); 289 OnConfigurationChanged());
322 } 290 }
323 291
324 void DrmNativeDisplayDelegate::OnRemoveGraphicsDevice( 292 void DrmNativeDisplayDelegate::OnRemoveGraphicsDevice(
325 const base::FilePath& path) { 293 const base::FilePath& path) {
326 proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(path)); 294 proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(path));
327 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 295 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
328 OnConfigurationChanged()); 296 OnConfigurationChanged());
329 } 297 }
330 298
331 void DrmNativeDisplayDelegate::OnChannelEstablished( 299 void DrmNativeDisplayDelegate::OnChannelEstablished(
332 int host_id, 300 int host_id,
333 scoped_refptr<base::SingleThreadTaskRunner> send_runner, 301 scoped_refptr<base::SingleThreadTaskRunner> send_runner,
334 const base::Callback<void(IPC::Message*)>& send_callback) { 302 const base::Callback<void(IPC::Message*)>& send_callback) {
335 drm_devices_.clear(); 303 if (drm_devices_.find(primary_graphics_card_path_) == drm_devices_.end()) {
336 drm_devices_.insert(primary_graphics_card_path_);
337 {
338 // First device needs to be treated specially. We need to open this 304 // First device needs to be treated specially. We need to open this
339 // synchronously since the GPU process will need it to initialize the 305 // synchronously since the GPU process will need it to initialize the
340 // graphics state. 306 // graphics state.
341 base::ThreadRestrictions::ScopedAllowIO allow_io; 307 base::ThreadRestrictions::ScopedAllowIO allow_io;
342 base::File file = OpenDrmDevice(primary_graphics_card_path_); 308 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
343 if (!file.IsValid()) { 309 if (!handle->Initialize(primary_graphics_card_path_)) {
344 LOG(FATAL) << "Failed to open primary graphics card"; 310 LOG(FATAL) << "Failed to open primary graphics card";
345 return; 311 return;
346 } 312 }
347 OnAddGraphicsDevice(primary_graphics_card_path_, file.Pass()); 313 drm_devices_.add(primary_graphics_card_path_, handle.Pass());
314 OnAddGraphicsDevice(primary_graphics_card_path_);
348 } 315 }
349 316
317 for (auto pair : drm_devices_)
318 OnAddGraphicsDevice(pair.first);
319
350 device_manager_->ScanDevices(this); 320 device_manager_->ScanDevices(this);
351 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 321 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
352 OnConfigurationChanged()); 322 OnConfigurationChanged());
353 } 323 }
354 324
355 void DrmNativeDisplayDelegate::OnChannelDestroyed(int host_id) { 325 void DrmNativeDisplayDelegate::OnChannelDestroyed(int host_id) {
356 // If the channel got destroyed in the middle of a configuration then just 326 // If the channel got destroyed in the middle of a configuration then just
357 // respond with failure. 327 // respond with failure.
358 if (!get_displays_callback_.is_null()) { 328 if (!get_displays_callback_.is_null()) {
359 base::ThreadTaskRunnerHandle::Get()->PostTask( 329 base::ThreadTaskRunnerHandle::Get()->PostTask(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 configure_callback_map_.erase(it); 378 configure_callback_map_.erase(it);
409 } 379 }
410 } 380 }
411 381
412 void DrmNativeDisplayDelegate::RunUpdateDisplaysCallback( 382 void DrmNativeDisplayDelegate::RunUpdateDisplaysCallback(
413 const GetDisplaysCallback& callback) const { 383 const GetDisplaysCallback& callback) const {
414 callback.Run(displays_.get()); 384 callback.Run(displays_.get());
415 } 385 }
416 386
417 } // namespace ui 387 } // namespace ui
OLDNEW
« 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