| 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_gpu_display_manager.h" | 5 #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/file_descriptor_posix.h" | 9 #include "base/file_descriptor_posix.h" |
| 10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "ui/display/types/native_display_observer.h" | 12 #include "ui/display/types/native_display_observer.h" |
| 13 #include "ui/events/ozone/device/device_event.h" | 13 #include "ui/events/ozone/device/device_event.h" |
| 14 #include "ui/ozone/common/display_util.h" | 14 #include "ui/ozone/common/display_util.h" |
| 15 #include "ui/ozone/platform/drm/gpu/drm_device.h" | 15 #include "ui/ozone/platform/drm/gpu/drm_device.h" |
| 16 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h" | 16 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" |
| 17 #include "ui/ozone/platform/drm/gpu/drm_display_mode.h" | 17 #include "ui/ozone/platform/drm/gpu/drm_display_mode.h" |
| 18 #include "ui/ozone/platform/drm/gpu/drm_display_snapshot.h" | 18 #include "ui/ozone/platform/drm/gpu/drm_display_snapshot.h" |
| 19 #include "ui/ozone/platform/drm/gpu/drm_util.h" | 19 #include "ui/ozone/platform/drm/gpu/drm_util.h" |
| 20 #include "ui/ozone/platform/drm/gpu/screen_manager.h" | 20 #include "ui/ozone/platform/drm/gpu/screen_manager.h" |
| 21 #include "ui/ozone/public/ozone_switches.h" | 21 #include "ui/ozone/public/ozone_switches.h" |
| 22 | 22 |
| 23 namespace ui { | 23 namespace ui { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 return drm_ == other->drm() && connector_ == other->connector() && | 70 return drm_ == other->drm() && connector_ == other->connector() && |
| 71 crtc_ == other->crtc(); | 71 crtc_ == other->crtc(); |
| 72 } | 72 } |
| 73 | 73 |
| 74 private: | 74 private: |
| 75 scoped_refptr<DrmDevice> drm_; | 75 scoped_refptr<DrmDevice> drm_; |
| 76 uint32_t crtc_; | 76 uint32_t crtc_; |
| 77 uint32_t connector_; | 77 uint32_t connector_; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 class FindByDevicePath { | |
| 81 public: | |
| 82 explicit FindByDevicePath(const base::FilePath& path) : path_(path) {} | |
| 83 | |
| 84 bool operator()(const scoped_refptr<DrmDevice>& device) { | |
| 85 return device->device_path() == path_; | |
| 86 } | |
| 87 | |
| 88 private: | |
| 89 base::FilePath path_; | |
| 90 }; | |
| 91 | |
| 92 std::string GetEnumNameForProperty(drmModeConnector* connector, | 80 std::string GetEnumNameForProperty(drmModeConnector* connector, |
| 93 drmModePropertyRes* property) { | 81 drmModePropertyRes* property) { |
| 94 for (int prop_idx = 0; prop_idx < connector->count_props; ++prop_idx) { | 82 for (int prop_idx = 0; prop_idx < connector->count_props; ++prop_idx) { |
| 95 if (connector->props[prop_idx] != property->prop_id) | 83 if (connector->props[prop_idx] != property->prop_id) |
| 96 continue; | 84 continue; |
| 97 | 85 |
| 98 for (int enum_idx = 0; enum_idx < property->count_enums; ++enum_idx) { | 86 for (int enum_idx = 0; enum_idx < property->count_enums; ++enum_idx) { |
| 99 const drm_mode_property_enum& property_enum = property->enums[enum_idx]; | 87 const drm_mode_property_enum& property_enum = property->enums[enum_idx]; |
| 100 if (property_enum.value == connector->prop_values[prop_idx]) | 88 if (property_enum.value == connector->prop_values[prop_idx]) |
| 101 return property_enum.name; | 89 return property_enum.name; |
| 102 } | 90 } |
| 103 } | 91 } |
| 104 | 92 |
| 105 NOTREACHED(); | 93 NOTREACHED(); |
| 106 return std::string(); | 94 return std::string(); |
| 107 } | 95 } |
| 108 | 96 |
| 109 } // namespace | 97 } // namespace |
| 110 | 98 |
| 111 DrmGpuDisplayManager::DrmGpuDisplayManager( | 99 DrmGpuDisplayManager::DrmGpuDisplayManager(ScreenManager* screen_manager, |
| 112 ScreenManager* screen_manager, | 100 DrmDeviceManager* drm_device_manager) |
| 113 const scoped_refptr<DrmDevice>& primary_device, | 101 : screen_manager_(screen_manager), drm_device_manager_(drm_device_manager) { |
| 114 scoped_ptr<DrmDeviceGenerator> drm_device_generator) | |
| 115 : screen_manager_(screen_manager), | |
| 116 drm_device_generator_(drm_device_generator.Pass()) { | |
| 117 devices_.push_back(primary_device); | |
| 118 } | 102 } |
| 119 | 103 |
| 120 DrmGpuDisplayManager::~DrmGpuDisplayManager() { | 104 DrmGpuDisplayManager::~DrmGpuDisplayManager() { |
| 121 } | 105 } |
| 122 | 106 |
| 123 void DrmGpuDisplayManager::InitializeIOTaskRunner( | |
| 124 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { | |
| 125 DCHECK(!io_task_runner_); | |
| 126 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); | |
| 127 // If not surfaceless, there isn't support for async page flips. | |
| 128 if (!cmd->HasSwitch(switches::kOzoneUseSurfaceless)) | |
| 129 return; | |
| 130 | |
| 131 io_task_runner_ = task_runner; | |
| 132 for (const auto& device : devices_) | |
| 133 device->InitializeTaskRunner(io_task_runner_); | |
| 134 } | |
| 135 | |
| 136 std::vector<DisplaySnapshot_Params> DrmGpuDisplayManager::GetDisplays() { | 107 std::vector<DisplaySnapshot_Params> DrmGpuDisplayManager::GetDisplays() { |
| 137 RefreshDisplayList(); | 108 RefreshDisplayList(); |
| 138 | 109 |
| 139 std::vector<DisplaySnapshot_Params> displays; | 110 std::vector<DisplaySnapshot_Params> displays; |
| 140 for (size_t i = 0; i < cached_displays_.size(); ++i) | 111 for (size_t i = 0; i < cached_displays_.size(); ++i) |
| 141 displays.push_back(GetDisplaySnapshotParams(*cached_displays_[i])); | 112 displays.push_back(GetDisplaySnapshotParams(*cached_displays_[i])); |
| 142 | 113 |
| 143 return displays; | 114 return displays; |
| 144 } | 115 } |
| 145 | 116 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 bool success = false; | 164 bool success = false; |
| 194 if (display) | 165 if (display) |
| 195 success = Configure(*display, NULL, gfx::Point()); | 166 success = Configure(*display, NULL, gfx::Point()); |
| 196 else | 167 else |
| 197 LOG(ERROR) << "There is no display with ID " << id; | 168 LOG(ERROR) << "There is no display with ID " << id; |
| 198 | 169 |
| 199 return success; | 170 return success; |
| 200 } | 171 } |
| 201 | 172 |
| 202 bool DrmGpuDisplayManager::TakeDisplayControl() { | 173 bool DrmGpuDisplayManager::TakeDisplayControl() { |
| 203 for (const auto& drm : devices_) { | 174 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 175 for (const auto& drm : devices) { |
| 204 if (!drm->SetMaster()) { | 176 if (!drm->SetMaster()) { |
| 205 LOG(ERROR) << "Failed to take control of the display"; | 177 LOG(ERROR) << "Failed to take control of the display"; |
| 206 return false; | 178 return false; |
| 207 } | 179 } |
| 208 } | 180 } |
| 209 return true; | 181 return true; |
| 210 } | 182 } |
| 211 | 183 |
| 212 bool DrmGpuDisplayManager::RelinquishDisplayControl() { | 184 bool DrmGpuDisplayManager::RelinquishDisplayControl() { |
| 213 for (const auto& drm : devices_) { | 185 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 186 for (const auto& drm : devices) { |
| 214 if (!drm->DropMaster()) { | 187 if (!drm->DropMaster()) { |
| 215 LOG(ERROR) << "Failed to relinquish control of the display"; | 188 LOG(ERROR) << "Failed to relinquish control of the display"; |
| 216 return false; | 189 return false; |
| 217 } | 190 } |
| 218 } | 191 } |
| 219 return true; | 192 return true; |
| 220 } | 193 } |
| 221 | 194 |
| 222 void DrmGpuDisplayManager::AddGraphicsDevice(const base::FilePath& path, | |
| 223 const base::FileDescriptor& fd) { | |
| 224 base::File file(fd.fd); | |
| 225 auto it = | |
| 226 std::find_if(devices_.begin(), devices_.end(), FindByDevicePath(path)); | |
| 227 if (it != devices_.end()) { | |
| 228 VLOG(2) << "Got request to add existing device '" << path.value() << "'"; | |
| 229 return; | |
| 230 } | |
| 231 | |
| 232 scoped_refptr<DrmDevice> device = | |
| 233 drm_device_generator_->CreateDevice(path, file.Pass()); | |
| 234 if (!device) { | |
| 235 VLOG(2) << "Could not initialize DRM device for '" << path.value() << "'"; | |
| 236 return; | |
| 237 } | |
| 238 | |
| 239 devices_.push_back(device); | |
| 240 if (io_task_runner_) | |
| 241 device->InitializeTaskRunner(io_task_runner_); | |
| 242 } | |
| 243 | |
| 244 void DrmGpuDisplayManager::RemoveGraphicsDevice(const base::FilePath& path) { | |
| 245 auto it = | |
| 246 std::find_if(devices_.begin(), devices_.end(), FindByDevicePath(path)); | |
| 247 if (it == devices_.end()) { | |
| 248 VLOG(2) << "Got request to remove non-existent device '" << path.value() | |
| 249 << "'"; | |
| 250 return; | |
| 251 } | |
| 252 | |
| 253 devices_.erase(it); | |
| 254 } | |
| 255 | |
| 256 DrmDisplaySnapshot* DrmGpuDisplayManager::FindDisplaySnapshot(int64_t id) { | 195 DrmDisplaySnapshot* DrmGpuDisplayManager::FindDisplaySnapshot(int64_t id) { |
| 257 for (size_t i = 0; i < cached_displays_.size(); ++i) | 196 for (size_t i = 0; i < cached_displays_.size(); ++i) |
| 258 if (cached_displays_[i]->display_id() == id) | 197 if (cached_displays_[i]->display_id() == id) |
| 259 return cached_displays_[i]; | 198 return cached_displays_[i]; |
| 260 | 199 |
| 261 return NULL; | 200 return NULL; |
| 262 } | 201 } |
| 263 | 202 |
| 264 const DrmDisplayMode* DrmGpuDisplayManager::FindDisplayMode( | 203 const DrmDisplayMode* DrmGpuDisplayManager::FindDisplayMode( |
| 265 const gfx::Size& size, | 204 const gfx::Size& size, |
| 266 bool is_interlaced, | 205 bool is_interlaced, |
| 267 float refresh_rate) { | 206 float refresh_rate) { |
| 268 for (size_t i = 0; i < cached_modes_.size(); ++i) | 207 for (size_t i = 0; i < cached_modes_.size(); ++i) |
| 269 if (cached_modes_[i]->size() == size && | 208 if (cached_modes_[i]->size() == size && |
| 270 cached_modes_[i]->is_interlaced() == is_interlaced && | 209 cached_modes_[i]->is_interlaced() == is_interlaced && |
| 271 cached_modes_[i]->refresh_rate() == refresh_rate) | 210 cached_modes_[i]->refresh_rate() == refresh_rate) |
| 272 return static_cast<const DrmDisplayMode*>(cached_modes_[i]); | 211 return static_cast<const DrmDisplayMode*>(cached_modes_[i]); |
| 273 | 212 |
| 274 return NULL; | 213 return NULL; |
| 275 } | 214 } |
| 276 | 215 |
| 277 void DrmGpuDisplayManager::RefreshDisplayList() { | 216 void DrmGpuDisplayManager::RefreshDisplayList() { |
| 278 ScopedVector<DrmDisplaySnapshot> old_displays(cached_displays_.Pass()); | 217 ScopedVector<DrmDisplaySnapshot> old_displays(cached_displays_.Pass()); |
| 279 ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass()); | 218 ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass()); |
| 280 | 219 |
| 281 for (const auto& drm : devices_) { | 220 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 221 for (const auto& drm : devices) { |
| 282 ScopedVector<HardwareDisplayControllerInfo> displays = | 222 ScopedVector<HardwareDisplayControllerInfo> displays = |
| 283 GetAvailableDisplayControllerInfos(drm->get_fd()); | 223 GetAvailableDisplayControllerInfos(drm->get_fd()); |
| 284 for (size_t i = 0; i < displays.size(); ++i) { | 224 for (size_t i = 0; i < displays.size(); ++i) { |
| 285 DrmDisplaySnapshot* display = new DrmDisplaySnapshot( | 225 DrmDisplaySnapshot* display = new DrmDisplaySnapshot( |
| 286 drm, displays[i]->connector(), displays[i]->crtc(), i); | 226 drm, displays[i]->connector(), displays[i]->crtc(), i); |
| 287 | 227 |
| 288 // If the display exists make sure to sync up the new snapshot with the | 228 // If the display exists make sure to sync up the new snapshot with the |
| 289 // old one to keep the user configured details. | 229 // old one to keep the user configured details. |
| 290 auto it = std::find_if( | 230 auto it = std::find_if( |
| 291 old_displays.begin(), old_displays.end(), | 231 old_displays.begin(), old_displays.end(), |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 | 358 |
| 419 if (it == old_displays.end()) { | 359 if (it == old_displays.end()) { |
| 420 screen_manager_->AddDisplayController(new_displays[i]->drm(), | 360 screen_manager_->AddDisplayController(new_displays[i]->drm(), |
| 421 new_displays[i]->crtc(), | 361 new_displays[i]->crtc(), |
| 422 new_displays[i]->connector()); | 362 new_displays[i]->connector()); |
| 423 } | 363 } |
| 424 } | 364 } |
| 425 } | 365 } |
| 426 | 366 |
| 427 } // namespace ui | 367 } // namespace ui |
| OLD | NEW |