OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" |
| 6 |
| 7 #include "ui/display/types/gamma_ramp_rgb_entry.h" |
| 8 #include "ui/ozone/common/display_util.h" |
| 9 #include "ui/ozone/platform/drm/common/drm_util.h" |
| 10 #include "ui/ozone/platform/drm/gpu/drm_device.h" |
| 11 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h" |
| 12 #include "ui/ozone/platform/drm/gpu/drm_display.h" |
| 13 #include "ui/ozone/platform/drm/gpu/screen_manager.h" |
| 14 |
| 15 namespace ui { |
| 16 |
| 17 namespace { |
| 18 |
| 19 class DisplayComparator { |
| 20 public: |
| 21 explicit DisplayComparator(const DrmDisplay* display) |
| 22 : drm_(display->drm()), |
| 23 crtc_(display->crtc()), |
| 24 connector_(display->connector()) {} |
| 25 |
| 26 DisplayComparator(const scoped_refptr<DrmDevice>& drm, |
| 27 uint32_t crtc, |
| 28 uint32_t connector) |
| 29 : drm_(drm), crtc_(crtc), connector_(connector) {} |
| 30 |
| 31 bool operator()(const DrmDisplay* other) const { |
| 32 return drm_ == other->drm() && connector_ == other->connector() && |
| 33 crtc_ == other->crtc(); |
| 34 } |
| 35 |
| 36 private: |
| 37 scoped_refptr<DrmDevice> drm_; |
| 38 uint32_t crtc_; |
| 39 uint32_t connector_; |
| 40 }; |
| 41 |
| 42 bool FindMatchingMode(const std::vector<drmModeModeInfo> modes, |
| 43 const DisplayMode_Params& mode_params, |
| 44 drmModeModeInfo* mode) { |
| 45 for (const drmModeModeInfo& m : modes) { |
| 46 DisplayMode_Params params = CreateDisplayModeParams(m); |
| 47 if (mode_params.size == params.size && |
| 48 mode_params.refresh_rate == params.refresh_rate && |
| 49 mode_params.is_interlaced == params.is_interlaced) { |
| 50 *mode = m; |
| 51 return true; |
| 52 } |
| 53 } |
| 54 |
| 55 return false; |
| 56 } |
| 57 |
| 58 } // namespace |
| 59 |
| 60 DrmGpuDisplayManager::DrmGpuDisplayManager(ScreenManager* screen_manager, |
| 61 DrmDeviceManager* drm_device_manager) |
| 62 : screen_manager_(screen_manager), drm_device_manager_(drm_device_manager) { |
| 63 } |
| 64 |
| 65 DrmGpuDisplayManager::~DrmGpuDisplayManager() { |
| 66 } |
| 67 |
| 68 std::vector<DisplaySnapshot_Params> DrmGpuDisplayManager::GetDisplays() { |
| 69 ScopedVector<DrmDisplay> old_displays(displays_.Pass()); |
| 70 std::vector<DisplaySnapshot_Params> params_list; |
| 71 |
| 72 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 73 // Unique identifier used to create the display id. |
| 74 size_t index = 0; |
| 75 for (const auto& drm : devices) { |
| 76 ScopedVector<HardwareDisplayControllerInfo> display_infos = |
| 77 GetAvailableDisplayControllerInfos(drm->get_fd()); |
| 78 for (auto* display_info : display_infos) { |
| 79 auto it = std::find_if( |
| 80 old_displays.begin(), old_displays.end(), |
| 81 DisplayComparator(drm, display_info->crtc()->crtc_id, |
| 82 display_info->connector()->connector_id)); |
| 83 if (it != old_displays.end()) { |
| 84 displays_.push_back(*it); |
| 85 old_displays.weak_erase(it); |
| 86 } else { |
| 87 displays_.push_back(new DrmDisplay(screen_manager_, drm)); |
| 88 } |
| 89 |
| 90 params_list.push_back(displays_.back()->Update(display_info, index++)); |
| 91 } |
| 92 } |
| 93 |
| 94 NotifyScreenManager(displays_.get(), old_displays.get()); |
| 95 return params_list; |
| 96 } |
| 97 |
| 98 bool DrmGpuDisplayManager::TakeDisplayControl() { |
| 99 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 100 bool status = true; |
| 101 for (const auto& drm : devices) |
| 102 status &= drm->SetMaster(); |
| 103 |
| 104 // Roll-back any successful operation. |
| 105 if (!status) { |
| 106 LOG(ERROR) << "Failed to take control of the display"; |
| 107 RelinquishDisplayControl(); |
| 108 } |
| 109 |
| 110 return status; |
| 111 } |
| 112 |
| 113 void DrmGpuDisplayManager::RelinquishDisplayControl() { |
| 114 const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices(); |
| 115 for (const auto& drm : devices) |
| 116 drm->DropMaster(); |
| 117 } |
| 118 |
| 119 bool DrmGpuDisplayManager::ConfigureDisplay( |
| 120 int64_t display_id, |
| 121 const DisplayMode_Params& mode_param, |
| 122 const gfx::Point& origin) { |
| 123 DrmDisplay* display = FindDisplay(display_id); |
| 124 if (!display) { |
| 125 LOG(ERROR) << "There is no display with ID " << display_id; |
| 126 return false; |
| 127 } |
| 128 |
| 129 drmModeModeInfo mode; |
| 130 bool mode_found = FindMatchingMode(display->modes(), mode_param, &mode); |
| 131 if (!mode_found) { |
| 132 // If the display doesn't have the mode natively, then lookup the mode from |
| 133 // other displays and try using it on the current display (some displays |
| 134 // support panel fitting and they can use different modes even if the mode |
| 135 // isn't explicitly declared). |
| 136 for (DrmDisplay* other : displays_) { |
| 137 mode_found = FindMatchingMode(other->modes(), mode_param, &mode); |
| 138 if (mode_found) |
| 139 break; |
| 140 } |
| 141 } |
| 142 |
| 143 if (!mode_found) { |
| 144 LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString() |
| 145 << " is_interlaced=" << mode_param.is_interlaced |
| 146 << " refresh_rate=" << mode_param.refresh_rate; |
| 147 return false; |
| 148 } |
| 149 |
| 150 return display->Configure(&mode, origin); |
| 151 } |
| 152 |
| 153 bool DrmGpuDisplayManager::DisableDisplay(int64_t display_id) { |
| 154 DrmDisplay* display = FindDisplay(display_id); |
| 155 if (!display) { |
| 156 LOG(ERROR) << "There is no display with ID " << display_id; |
| 157 return false; |
| 158 } |
| 159 |
| 160 return display->Configure(nullptr, gfx::Point()); |
| 161 } |
| 162 |
| 163 bool DrmGpuDisplayManager::GetHDCPState(int64_t display_id, HDCPState* state) { |
| 164 DrmDisplay* display = FindDisplay(display_id); |
| 165 if (!display) { |
| 166 LOG(ERROR) << "There is no display with ID " << display_id; |
| 167 return false; |
| 168 } |
| 169 |
| 170 return display->GetHDCPState(state); |
| 171 } |
| 172 |
| 173 bool DrmGpuDisplayManager::SetHDCPState(int64_t display_id, HDCPState state) { |
| 174 DrmDisplay* display = FindDisplay(display_id); |
| 175 if (!display) { |
| 176 LOG(ERROR) << "There is no display with ID " << display_id; |
| 177 return false; |
| 178 } |
| 179 |
| 180 return display->SetHDCPState(state); |
| 181 } |
| 182 |
| 183 void DrmGpuDisplayManager::SetGammaRamp( |
| 184 int64_t display_id, |
| 185 const std::vector<GammaRampRGBEntry>& lut) { |
| 186 DrmDisplay* display = FindDisplay(display_id); |
| 187 if (!display) { |
| 188 LOG(ERROR) << "There is no display with ID " << display_id; |
| 189 return; |
| 190 } |
| 191 |
| 192 display->SetGammaRamp(lut); |
| 193 } |
| 194 |
| 195 DrmDisplay* DrmGpuDisplayManager::FindDisplay(int64_t display_id) { |
| 196 for (DrmDisplay* display : displays_) |
| 197 if (display->display_id() == display_id) |
| 198 return display; |
| 199 |
| 200 return nullptr; |
| 201 } |
| 202 |
| 203 void DrmGpuDisplayManager::NotifyScreenManager( |
| 204 const std::vector<DrmDisplay*>& new_displays, |
| 205 const std::vector<DrmDisplay*>& old_displays) const { |
| 206 for (size_t i = 0; i < old_displays.size(); ++i) { |
| 207 const std::vector<DrmDisplay*>::const_iterator it = |
| 208 std::find_if(new_displays.begin(), new_displays.end(), |
| 209 DisplayComparator(old_displays[i])); |
| 210 |
| 211 if (it == new_displays.end()) { |
| 212 screen_manager_->RemoveDisplayController(old_displays[i]->drm(), |
| 213 old_displays[i]->crtc()); |
| 214 } |
| 215 } |
| 216 |
| 217 for (size_t i = 0; i < new_displays.size(); ++i) { |
| 218 const std::vector<DrmDisplay*>::const_iterator it = |
| 219 std::find_if(old_displays.begin(), old_displays.end(), |
| 220 DisplayComparator(new_displays[i])); |
| 221 |
| 222 if (it == old_displays.end()) { |
| 223 screen_manager_->AddDisplayController(new_displays[i]->drm(), |
| 224 new_displays[i]->crtc(), |
| 225 new_displays[i]->connector()); |
| 226 } |
| 227 } |
| 228 } |
| 229 |
| 230 } // namespace ui |
OLD | NEW |