| 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/gpu/drm_device.h" | 5 #include "ui/ozone/platform/drm/gpu/drm_device.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <sys/mman.h> | 8 #include <sys/mman.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 #include <xf86drm.h> | 10 #include <xf86drm.h> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool CanQueryForResources(int fd) { | 95 bool CanQueryForResources(int fd) { |
| 96 drm_mode_card_res resources; | 96 drm_mode_card_res resources; |
| 97 memset(&resources, 0, sizeof(resources)); | 97 memset(&resources, 0, sizeof(resources)); |
| 98 // If there is no error getting DRM resources then assume this is a | 98 // If there is no error getting DRM resources then assume this is a |
| 99 // modesetting device. | 99 // modesetting device. |
| 100 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); | 100 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); |
| 101 } | 101 } |
| 102 | 102 |
| 103 bool Authenticate(int fd) { | |
| 104 drm_magic_t magic; | |
| 105 memset(&magic, 0, sizeof(magic)); | |
| 106 // We need to make sure the DRM device has enough privilege. Use the DRM | |
| 107 // authentication logic to figure out if the device has enough permissions. | |
| 108 return !drmGetMagic(fd, &magic) && !drmAuthMagic(fd, magic); | |
| 109 } | |
| 110 | |
| 111 } // namespace | 103 } // namespace |
| 112 | 104 |
| 113 class DrmDevice::IOWatcher | 105 class DrmDevice::IOWatcher |
| 114 : public base::RefCountedThreadSafe<DrmDevice::IOWatcher>, | 106 : public base::RefCountedThreadSafe<DrmDevice::IOWatcher>, |
| 115 public base::MessagePumpLibevent::Watcher { | 107 public base::MessagePumpLibevent::Watcher { |
| 116 public: | 108 public: |
| 117 IOWatcher(int fd, | 109 IOWatcher(int fd, |
| 118 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) | 110 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) |
| 119 : io_task_runner_(io_task_runner), paused_(true), fd_(fd) {} | 111 : io_task_runner_(io_task_runner), paused_(true), fd_(fd) {} |
| 120 | 112 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 } | 197 } |
| 206 | 198 |
| 207 bool DrmDevice::Initialize() { | 199 bool DrmDevice::Initialize() { |
| 208 // Ignore devices that cannot perform modesetting. | 200 // Ignore devices that cannot perform modesetting. |
| 209 if (!CanQueryForResources(file_.GetPlatformFile())) { | 201 if (!CanQueryForResources(file_.GetPlatformFile())) { |
| 210 VLOG(2) << "Cannot query for resources for '" << device_path_.value() | 202 VLOG(2) << "Cannot query for resources for '" << device_path_.value() |
| 211 << "'"; | 203 << "'"; |
| 212 return false; | 204 return false; |
| 213 } | 205 } |
| 214 | 206 |
| 215 bool print_warning = true; | |
| 216 // TODO(dnicoara) Ugly hack to block until getting master. This is needed | |
| 217 // since DRM devices from an old GPU process may be getting deallocated while | |
| 218 // the new GPU process tries to take them. | |
| 219 // Move ownership of devices in the Browser process and just have the GPU | |
| 220 // processes authenticate. | |
| 221 while (!Authenticate(file_.GetPlatformFile())) { | |
| 222 PLOG_IF(WARNING, print_warning) << "Failed to take master on " | |
| 223 << device_path_.value(); | |
| 224 print_warning = false; | |
| 225 | |
| 226 usleep(100000); | |
| 227 file_ = | |
| 228 base::File(device_path_, base::File::FLAG_OPEN | base::File::FLAG_READ | | |
| 229 base::File::FLAG_WRITE); | |
| 230 LOG_IF(FATAL, !file_.IsValid()) | |
| 231 << "Failed to open '" << device_path_.value() | |
| 232 << "': " << base::File::ErrorToString(file_.error_details()); | |
| 233 } | |
| 234 | |
| 235 VLOG(1) << "Succeeded in taking master on " << device_path_.value(); | |
| 236 | |
| 237 #if defined(USE_DRM_ATOMIC) | 207 #if defined(USE_DRM_ATOMIC) |
| 238 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic()); | 208 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic()); |
| 239 #else | 209 #else |
| 240 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); | 210 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); |
| 241 #endif // defined(USE_DRM_ATOMIC) | 211 #endif // defined(USE_DRM_ATOMIC) |
| 242 if (!plane_manager_->Initialize(this)) { | 212 if (!plane_manager_->Initialize(this)) { |
| 243 LOG(ERROR) << "Failed to initialize the plane manager for " | 213 LOG(ERROR) << "Failed to initialize the plane manager for " |
| 244 << device_path_.value(); | 214 << device_path_.value(); |
| 245 plane_manager_.reset(); | 215 plane_manager_.reset(); |
| 246 return false; | 216 return false; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 DCHECK(file_.IsValid()); | 470 DCHECK(file_.IsValid()); |
| 501 return (drmSetMaster(file_.GetPlatformFile()) == 0); | 471 return (drmSetMaster(file_.GetPlatformFile()) == 0); |
| 502 } | 472 } |
| 503 | 473 |
| 504 bool DrmDevice::DropMaster() { | 474 bool DrmDevice::DropMaster() { |
| 505 DCHECK(file_.IsValid()); | 475 DCHECK(file_.IsValid()); |
| 506 return (drmDropMaster(file_.GetPlatformFile()) == 0); | 476 return (drmDropMaster(file_.GetPlatformFile()) == 0); |
| 507 } | 477 } |
| 508 | 478 |
| 509 } // namespace ui | 479 } // namespace ui |
| OLD | NEW |