Chromium Code Reviews| 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 std::vector<scoped_refptr<DrmDevice>> devices = |
|
alexst (slow to review)
2015/04/22 18:27:56
This is not thread safe. You return a vector here,
dnicoara
2015/04/22 18:41:30
This is fine. All the devices are added on the GPU
| |
| 175 drm_device_manager_->GetDrmDevices(); | |
| 176 for (const auto& drm : devices) { | |
| 204 if (!drm->SetMaster()) { | 177 if (!drm->SetMaster()) { |
| 205 LOG(ERROR) << "Failed to take control of the display"; | 178 LOG(ERROR) << "Failed to take control of the display"; |
| 206 return false; | 179 return false; |
| 207 } | 180 } |
| 208 } | 181 } |
| 209 return true; | 182 return true; |
| 210 } | 183 } |
| 211 | 184 |
| 212 bool DrmGpuDisplayManager::RelinquishDisplayControl() { | 185 bool DrmGpuDisplayManager::RelinquishDisplayControl() { |
| 213 for (const auto& drm : devices_) { | 186 std::vector<scoped_refptr<DrmDevice>> devices = |
| 187 drm_device_manager_->GetDrmDevices(); | |
|
alexst (slow to review)
2015/04/22 18:27:56
ditto here.
| |
| 188 for (const auto& drm : devices) { | |
| 214 if (!drm->DropMaster()) { | 189 if (!drm->DropMaster()) { |
| 215 LOG(ERROR) << "Failed to relinquish control of the display"; | 190 LOG(ERROR) << "Failed to relinquish control of the display"; |
| 216 return false; | 191 return false; |
| 217 } | 192 } |
| 218 } | 193 } |
| 219 return true; | 194 return true; |
| 220 } | 195 } |
| 221 | 196 |
| 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) { | 197 DrmDisplaySnapshot* DrmGpuDisplayManager::FindDisplaySnapshot(int64_t id) { |
| 257 for (size_t i = 0; i < cached_displays_.size(); ++i) | 198 for (size_t i = 0; i < cached_displays_.size(); ++i) |
| 258 if (cached_displays_[i]->display_id() == id) | 199 if (cached_displays_[i]->display_id() == id) |
| 259 return cached_displays_[i]; | 200 return cached_displays_[i]; |
| 260 | 201 |
| 261 return NULL; | 202 return NULL; |
| 262 } | 203 } |
| 263 | 204 |
| 264 const DrmDisplayMode* DrmGpuDisplayManager::FindDisplayMode( | 205 const DrmDisplayMode* DrmGpuDisplayManager::FindDisplayMode( |
| 265 const gfx::Size& size, | 206 const gfx::Size& size, |
| 266 bool is_interlaced, | 207 bool is_interlaced, |
| 267 float refresh_rate) { | 208 float refresh_rate) { |
| 268 for (size_t i = 0; i < cached_modes_.size(); ++i) | 209 for (size_t i = 0; i < cached_modes_.size(); ++i) |
| 269 if (cached_modes_[i]->size() == size && | 210 if (cached_modes_[i]->size() == size && |
| 270 cached_modes_[i]->is_interlaced() == is_interlaced && | 211 cached_modes_[i]->is_interlaced() == is_interlaced && |
| 271 cached_modes_[i]->refresh_rate() == refresh_rate) | 212 cached_modes_[i]->refresh_rate() == refresh_rate) |
| 272 return static_cast<const DrmDisplayMode*>(cached_modes_[i]); | 213 return static_cast<const DrmDisplayMode*>(cached_modes_[i]); |
| 273 | 214 |
| 274 return NULL; | 215 return NULL; |
| 275 } | 216 } |
| 276 | 217 |
| 277 void DrmGpuDisplayManager::RefreshDisplayList() { | 218 void DrmGpuDisplayManager::RefreshDisplayList() { |
| 278 ScopedVector<DrmDisplaySnapshot> old_displays(cached_displays_.Pass()); | 219 ScopedVector<DrmDisplaySnapshot> old_displays(cached_displays_.Pass()); |
| 279 ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass()); | 220 ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass()); |
| 280 | 221 |
| 281 for (const auto& drm : devices_) { | 222 std::vector<scoped_refptr<DrmDevice>> devices = |
| 223 drm_device_manager_->GetDrmDevices(); | |
| 224 for (const auto& drm : devices) { | |
| 282 ScopedVector<HardwareDisplayControllerInfo> displays = | 225 ScopedVector<HardwareDisplayControllerInfo> displays = |
| 283 GetAvailableDisplayControllerInfos(drm->get_fd()); | 226 GetAvailableDisplayControllerInfos(drm->get_fd()); |
| 284 for (size_t i = 0; i < displays.size(); ++i) { | 227 for (size_t i = 0; i < displays.size(); ++i) { |
| 285 DrmDisplaySnapshot* display = new DrmDisplaySnapshot( | 228 DrmDisplaySnapshot* display = new DrmDisplaySnapshot( |
| 286 drm, displays[i]->connector(), displays[i]->crtc(), i); | 229 drm, displays[i]->connector(), displays[i]->crtc(), i); |
| 287 | 230 |
| 288 // If the display exists make sure to sync up the new snapshot with the | 231 // If the display exists make sure to sync up the new snapshot with the |
| 289 // old one to keep the user configured details. | 232 // old one to keep the user configured details. |
| 290 auto it = std::find_if( | 233 auto it = std::find_if( |
| 291 old_displays.begin(), old_displays.end(), | 234 old_displays.begin(), old_displays.end(), |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 | 351 |
| 409 if (it == old_displays.end()) { | 352 if (it == old_displays.end()) { |
| 410 screen_manager_->AddDisplayController(new_displays[i]->drm(), | 353 screen_manager_->AddDisplayController(new_displays[i]->drm(), |
| 411 new_displays[i]->crtc(), | 354 new_displays[i]->crtc(), |
| 412 new_displays[i]->connector()); | 355 new_displays[i]->connector()); |
| 413 } | 356 } |
| 414 } | 357 } |
| 415 } | 358 } |
| 416 | 359 |
| 417 } // namespace ui | 360 } // namespace ui |
| OLD | NEW |