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

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: Update due to change in ScopedPtrHashMap definition 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_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 "base/threading/worker_pool.h" 12 #include "base/threading/worker_pool.h"
14 #include "ui/display/types/display_snapshot.h" 13 #include "ui/display/types/display_snapshot.h"
15 #include "ui/display/types/native_display_observer.h" 14 #include "ui/display/types/native_display_observer.h"
16 #include "ui/events/ozone/device/device_event.h" 15 #include "ui/events/ozone/device/device_event.h"
17 #include "ui/events/ozone/device/device_manager.h" 16 #include "ui/events/ozone/device/device_manager.h"
18 #include "ui/ozone/common/display_snapshot_proxy.h" 17 #include "ui/ozone/common/display_snapshot_proxy.h"
19 #include "ui/ozone/common/display_util.h" 18 #include "ui/ozone/common/display_util.h"
20 #include "ui/ozone/common/gpu/ozone_gpu_messages.h" 19 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
21 #include "ui/ozone/platform/drm/host/display_manager.h" 20 #include "ui/ozone/platform/drm/host/display_manager.h"
21 #include "ui/ozone/platform/drm/host/drm_device_handle.h"
22 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" 22 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
23 23
24 namespace ui { 24 namespace ui {
25 25
26 namespace { 26 namespace {
27 27
28 typedef base::Callback<void(const base::FilePath&, base::File)> 28 typedef base::Callback<void(const base::FilePath&, scoped_ptr<DrmDeviceHandle>)>
29 OnOpenDeviceReplyCallback; 29 OnOpenDeviceReplyCallback;
30 30
31 const char* kDisplayActionString[] = { 31 const char* kDisplayActionString[] = {
32 "ADD", 32 "ADD",
33 "REMOVE", 33 "REMOVE",
34 "CHANGE", 34 "CHANGE",
35 }; 35 };
36 36
37 bool Authenticate(int fd) {
38 drm_magic_t magic = 0;
39 // We need to make sure the DRM device has enough privilege. Use the DRM
40 // authentication logic to figure out if the device has enough permissions.
41 return !drmGetMagic(fd, &magic) && !drmAuthMagic(fd, magic);
42 }
43
44 base::File OpenDrmDevice(const base::FilePath& path) {
45 base::File file;
46 bool print_warning = true;
47 while (true) {
48 file = base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
49 base::File::FLAG_WRITE);
50
51 base::File::Info info;
52 file.GetInfo(&info);
53
54 CHECK(!info.is_directory);
55 CHECK(path.DirName() == base::FilePath("/dev/dri"));
56
57 if (!file.IsValid()) {
58 LOG(ERROR) << "Failed to open " << path.value() << ": "
59 << base::File::ErrorToString(file.error_details());
60 return file.Pass();
61 }
62
63 if (Authenticate(file.GetPlatformFile()))
64 break;
65
66 LOG_IF(WARNING, print_warning) << "Failed to authenticate " << path.value();
67
68 print_warning = false;
69 usleep(100000);
70 }
71
72 VLOG(1) << "Succeeded authenticating " << path.value();
73 return file.Pass();
74 }
75
76 void OpenDeviceOnWorkerThread( 37 void OpenDeviceOnWorkerThread(
77 const base::FilePath& path, 38 const base::FilePath& path,
78 const scoped_refptr<base::TaskRunner>& reply_runner, 39 const scoped_refptr<base::TaskRunner>& reply_runner,
79 const OnOpenDeviceReplyCallback& callback) { 40 const OnOpenDeviceReplyCallback& callback) {
80 base::File file = OpenDrmDevice(path); 41 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
81 reply_runner->PostTask(FROM_HERE, 42 handle->Initialize(path);
82 base::Bind(callback, path, base::Passed(file.Pass()))); 43 reply_runner->PostTask(
44 FROM_HERE, base::Bind(callback, path, base::Passed(handle.Pass())));
45 }
46
47 void CloseDeviceOnWorkerThread(
48 scoped_ptr<DrmDeviceHandle> handle,
49 const scoped_refptr<base::TaskRunner>& reply_runner,
50 const base::Closure& callback) {
51 handle.reset();
52 reply_runner->PostTask(FROM_HERE, callback);
83 } 53 }
84 54
85 class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy { 55 class DrmDisplaySnapshotProxy : public DisplaySnapshotProxy {
86 public: 56 public:
87 DrmDisplaySnapshotProxy(const DisplaySnapshot_Params& params, 57 DrmDisplaySnapshotProxy(const DisplaySnapshot_Params& params,
88 DisplayManager* display_manager) 58 DisplayManager* display_manager)
89 : DisplaySnapshotProxy(params), display_manager_(display_manager) { 59 : DisplaySnapshotProxy(params), display_manager_(display_manager) {
90 display_manager_->RegisterDisplay(this); 60 display_manager_->RegisterDisplay(this);
91 } 61 }
92 62
(...skipping 15 matching lines...) Expand all
108 DisplayManager* display_manager, 78 DisplayManager* display_manager,
109 const base::FilePath& primary_graphics_card_path) 79 const base::FilePath& primary_graphics_card_path)
110 : proxy_(proxy), 80 : proxy_(proxy),
111 device_manager_(device_manager), 81 device_manager_(device_manager),
112 display_manager_(display_manager), 82 display_manager_(display_manager),
113 primary_graphics_card_path_(primary_graphics_card_path), 83 primary_graphics_card_path_(primary_graphics_card_path),
114 has_dummy_display_(false), 84 has_dummy_display_(false),
115 task_pending_(false), 85 task_pending_(false),
116 weak_ptr_factory_(this) { 86 weak_ptr_factory_(this) {
117 proxy_->RegisterHandler(this); 87 proxy_->RegisterHandler(this);
118 drm_devices_.insert(primary_graphics_card_path);
119 } 88 }
120 89
121 DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() { 90 DrmNativeDisplayDelegate::~DrmNativeDisplayDelegate() {
122 device_manager_->RemoveObserver(this); 91 device_manager_->RemoveObserver(this);
123 proxy_->UnregisterHandler(this); 92 proxy_->UnregisterHandler(this);
93
94 for (auto it = drm_devices_.begin(); it != drm_devices_.end(); ++it) {
95 base::WorkerPool::PostTask(FROM_HERE,
96 base::Bind(&CloseDeviceOnWorkerThread,
97 base::Passed(drm_devices_.take(it)),
98 base::ThreadTaskRunnerHandle::Get(),
99 base::Bind(&base::DoNothing)),
100 false /* task_is_slow */);
101 }
124 } 102 }
125 103
126 void DrmNativeDisplayDelegate::Initialize() { 104 void DrmNativeDisplayDelegate::Initialize() {
105 {
106 // First device needs to be treated specially. We need to open this
107 // synchronously since the GPU process will need it to initialize the
108 // graphics state.
109 base::ThreadRestrictions::ScopedAllowIO allow_io;
110 scoped_ptr<DrmDeviceHandle> handle(new DrmDeviceHandle());
111 if (!handle->Initialize(primary_graphics_card_path_)) {
112 LOG(FATAL) << "Failed to open primary graphics card";
113 return;
114 }
115 drm_devices_.add(primary_graphics_card_path_, handle.Pass());
116 }
117
127 device_manager_->AddObserver(this); 118 device_manager_->AddObserver(this);
128 device_manager_->ScanDevices(this); 119 device_manager_->ScanDevices(this);
129 120
130 if (!displays_.empty()) 121 if (!displays_.empty())
131 return; 122 return;
132 DisplaySnapshot_Params params; 123 DisplaySnapshot_Params params;
133 bool success = false; 124 bool success = false;
134 { 125 {
135 // The file generated by frecon that contains EDID for the 1st display. 126 // The file generated by frecon that contains EDID for the 1st display.
136 const base::FilePath kEDIDFile("/tmp/display_info.bin"); 127 const base::FilePath kEDIDFile("/tmp/display_info.bin");
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 261
271 void DrmNativeDisplayDelegate::ProcessEvent() { 262 void DrmNativeDisplayDelegate::ProcessEvent() {
272 while (!event_queue_.empty() && !task_pending_) { 263 while (!event_queue_.empty() && !task_pending_) {
273 DisplayEvent event = event_queue_.front(); 264 DisplayEvent event = event_queue_.front();
274 event_queue_.pop(); 265 event_queue_.pop();
275 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type] 266 VLOG(1) << "Got display event " << kDisplayActionString[event.action_type]
276 << " for " << event.path.value(); 267 << " for " << event.path.value();
277 switch (event.action_type) { 268 switch (event.action_type) {
278 case DeviceEvent::ADD: 269 case DeviceEvent::ADD:
279 if (drm_devices_.find(event.path) == drm_devices_.end()) { 270 if (drm_devices_.find(event.path) == drm_devices_.end()) {
280 drm_devices_.insert(event.path);
281 task_pending_ = base::WorkerPool::PostTask( 271 task_pending_ = base::WorkerPool::PostTask(
282 FROM_HERE, 272 FROM_HERE,
283 base::Bind( 273 base::Bind(
284 &OpenDeviceOnWorkerThread, event.path, 274 &OpenDeviceOnWorkerThread, event.path,
285 base::ThreadTaskRunnerHandle::Get(), 275 base::ThreadTaskRunnerHandle::Get(),
286 base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice, 276 base::Bind(&DrmNativeDisplayDelegate::OnAddGraphicsDevice,
287 weak_ptr_factory_.GetWeakPtr())), 277 weak_ptr_factory_.GetWeakPtr())),
288 false /* task_is_slow */); 278 false /* task_is_slow */);
289 } 279 }
290 break; 280 break;
291 case DeviceEvent::CHANGE: 281 case DeviceEvent::CHANGE:
292 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask( 282 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
293 FROM_HERE, 283 FROM_HERE,
294 base::Bind(&DrmNativeDisplayDelegate::OnUpdateGraphicsDevice, 284 base::Bind(&DrmNativeDisplayDelegate::OnUpdateGraphicsDevice,
295 weak_ptr_factory_.GetWeakPtr())); 285 weak_ptr_factory_.GetWeakPtr()));
296 break; 286 break;
297 case DeviceEvent::REMOVE: 287 case DeviceEvent::REMOVE:
298 DCHECK(event.path != primary_graphics_card_path_) 288 DCHECK(event.path != primary_graphics_card_path_)
299 << "Removing primary graphics card"; 289 << "Removing primary graphics card";
300 auto it = drm_devices_.find(event.path); 290 auto it = drm_devices_.find(event.path);
301 if (it != drm_devices_.end()) { 291 if (it != drm_devices_.end()) {
302 drm_devices_.erase(it); 292 task_pending_ = base::WorkerPool::PostTask(
303 task_pending_ = base::ThreadTaskRunnerHandle::Get()->PostTask(
304 FROM_HERE, 293 FROM_HERE,
305 base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice, 294 base::Bind(
306 weak_ptr_factory_.GetWeakPtr(), event.path)); 295 &CloseDeviceOnWorkerThread,
296 base::Passed(drm_devices_.take_and_erase(it)),
297 base::ThreadTaskRunnerHandle::Get(),
298 base::Bind(&DrmNativeDisplayDelegate::OnRemoveGraphicsDevice,
299 weak_ptr_factory_.GetWeakPtr(), event.path)),
300 false /* task_is_slow */);
301 return;
307 } 302 }
308 break; 303 break;
309 } 304 }
310 } 305 }
311 } 306 }
312 307
313 void DrmNativeDisplayDelegate::OnAddGraphicsDevice(const base::FilePath& path, 308 void DrmNativeDisplayDelegate::OnAddGraphicsDevice(
314 base::File file) { 309 const base::FilePath& path,
315 if (file.IsValid()) { 310 scoped_ptr<DrmDeviceHandle> handle) {
311 if (handle->IsValid()) {
312 base::ScopedFD file = handle->Duplicate();
313 drm_devices_.add(path, handle.Pass());
316 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice( 314 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
317 path, base::FileDescriptor(file.Pass()))); 315 path, base::FileDescriptor(file.Pass())));
318 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 316 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
319 OnConfigurationChanged()); 317 OnConfigurationChanged());
320 } 318 }
321 319
322 task_pending_ = false; 320 task_pending_ = false;
323 ProcessEvent(); 321 ProcessEvent();
324 } 322 }
325 323
(...skipping 10 matching lines...) Expand all
336 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 334 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
337 OnConfigurationChanged()); 335 OnConfigurationChanged());
338 task_pending_ = false; 336 task_pending_ = false;
339 ProcessEvent(); 337 ProcessEvent();
340 } 338 }
341 339
342 void DrmNativeDisplayDelegate::OnChannelEstablished( 340 void DrmNativeDisplayDelegate::OnChannelEstablished(
343 int host_id, 341 int host_id,
344 scoped_refptr<base::SingleThreadTaskRunner> send_runner, 342 scoped_refptr<base::SingleThreadTaskRunner> send_runner,
345 const base::Callback<void(IPC::Message*)>& send_callback) { 343 const base::Callback<void(IPC::Message*)>& send_callback) {
346 drm_devices_.clear(); 344 auto it = drm_devices_.find(primary_graphics_card_path_);
347 drm_devices_.insert(primary_graphics_card_path_); 345 DCHECK(it != drm_devices_.end());
348 { 346 // Send the primary device first since this is used to initialize graphics
349 // First device needs to be treated specially. We need to open this 347 // state.
350 // synchronously since the GPU process will need it to initialize the 348 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
351 // graphics state. 349 it->first, base::FileDescriptor(it->second->Duplicate())));
352 base::ThreadRestrictions::ScopedAllowIO allow_io; 350
353 base::File file = OpenDrmDevice(primary_graphics_card_path_); 351 for (auto pair : drm_devices_) {
354 if (!file.IsValid()) { 352 if (pair.second->IsValid() && pair.first != primary_graphics_card_path_) {
355 LOG(FATAL) << "Failed to open primary graphics card"; 353 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
356 return; 354 pair.first, base::FileDescriptor(pair.second->Duplicate())));
357 } 355 }
358 proxy_->Send(new OzoneGpuMsg_AddGraphicsDevice(
359 primary_graphics_card_path_, base::FileDescriptor(file.Pass())));
360 } 356 }
361 357
362 device_manager_->ScanDevices(this); 358 device_manager_->ScanDevices(this);
363 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, 359 FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
364 OnConfigurationChanged()); 360 OnConfigurationChanged());
365 } 361 }
366 362
367 void DrmNativeDisplayDelegate::OnChannelDestroyed(int host_id) { 363 void DrmNativeDisplayDelegate::OnChannelDestroyed(int host_id) {
368 // If the channel got destroyed in the middle of a configuration then just 364 // If the channel got destroyed in the middle of a configuration then just
369 // respond with failure. 365 // respond with failure.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 set_hdcp_state_callback_map_.erase(it); 439 set_hdcp_state_callback_map_.erase(it);
444 } 440 }
445 } 441 }
446 442
447 void DrmNativeDisplayDelegate::RunUpdateDisplaysCallback( 443 void DrmNativeDisplayDelegate::RunUpdateDisplaysCallback(
448 const GetDisplaysCallback& callback) const { 444 const GetDisplaysCallback& callback) const {
449 callback.Run(displays_.get()); 445 callback.Run(displays_.get());
450 } 446 }
451 447
452 } // namespace ui 448 } // 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