| 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/common/drm_util.h" | 5 #include "ui/ozone/platform/drm/common/drm_util.h" |
| 6 | 6 |
| 7 #include <drm_fourcc.h> | 7 #include <drm_fourcc.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
| 11 #include <xf86drmMode.h> | 11 #include <xf86drmMode.h> |
| 12 | 12 |
| 13 #include "ui/display/util/edid_parser.h" | 13 #include "ui/display/util/edid_parser.h" |
| 14 | 14 |
| 15 #if !defined(DRM_MODE_CONNECTOR_DSI) | 15 #if !defined(DRM_MODE_CONNECTOR_DSI) |
| 16 #define DRM_MODE_CONNECTOR_DSI 16 | 16 #define DRM_MODE_CONNECTOR_DSI 16 |
| 17 #endif | 17 #endif |
| 18 | 18 |
| 19 namespace ui { | 19 namespace ui { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 bool IsCrtcInUse(uint32_t crtc, | 23 bool IsCrtcInUse(uint32_t crtc, |
| 24 const ScopedVector<HardwareDisplayControllerInfo>& displays) { | 24 const std::vector<HardwareDisplayControllerInfo>& displays) { |
| 25 for (size_t i = 0; i < displays.size(); ++i) { | 25 for (const auto& display : displays) { |
| 26 if (crtc == displays[i]->crtc()->crtc_id) | 26 if (crtc == display.crtc()->crtc_id) |
| 27 return true; | 27 return true; |
| 28 } | 28 } |
| 29 | 29 |
| 30 return false; | 30 return false; |
| 31 } | 31 } |
| 32 | 32 |
| 33 uint32_t GetCrtc(int fd, | 33 uint32_t GetCrtc(int fd, |
| 34 drmModeConnector* connector, | 34 drmModeConnector* connector, |
| 35 drmModeRes* resources, | 35 drmModeRes* resources, |
| 36 const ScopedVector<HardwareDisplayControllerInfo>& displays) { | 36 const std::vector<HardwareDisplayControllerInfo>& displays) { |
| 37 // If the connector already has an encoder try to re-use. | 37 // If the connector already has an encoder try to re-use. |
| 38 if (connector->encoder_id) { | 38 if (connector->encoder_id) { |
| 39 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoder_id)); | 39 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoder_id)); |
| 40 if (encoder && encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) | 40 if (encoder && encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) |
| 41 return encoder->crtc_id; | 41 return encoder->crtc_id; |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Try to find an encoder for the connector. | 44 // Try to find an encoder for the connector. |
| 45 for (int i = 0; i < connector->count_encoders; ++i) { | 45 for (int i = 0; i < connector->count_encoders; ++i) { |
| 46 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoders[i])); | 46 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoders[i])); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 } | 157 } |
| 158 | 158 |
| 159 } // namespace | 159 } // namespace |
| 160 | 160 |
| 161 HardwareDisplayControllerInfo::HardwareDisplayControllerInfo( | 161 HardwareDisplayControllerInfo::HardwareDisplayControllerInfo( |
| 162 ScopedDrmConnectorPtr connector, | 162 ScopedDrmConnectorPtr connector, |
| 163 ScopedDrmCrtcPtr crtc, | 163 ScopedDrmCrtcPtr crtc, |
| 164 size_t index) | 164 size_t index) |
| 165 : connector_(connector.Pass()), crtc_(crtc.Pass()), index_(index) {} | 165 : connector_(connector.Pass()), crtc_(crtc.Pass()), index_(index) {} |
| 166 | 166 |
| 167 HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() { | 167 std::vector<HardwareDisplayControllerInfo> GetAvailableDisplayControllerInfos( |
| 168 } | |
| 169 | |
| 170 ScopedVector<HardwareDisplayControllerInfo> GetAvailableDisplayControllerInfos( | |
| 171 int fd) { | 168 int fd) { |
| 172 ScopedDrmResourcesPtr resources(drmModeGetResources(fd)); | 169 ScopedDrmResourcesPtr resources(drmModeGetResources(fd)); |
| 173 DCHECK(resources) << "Failed to get DRM resources"; | 170 DCHECK(resources) << "Failed to get DRM resources"; |
| 174 ScopedVector<HardwareDisplayControllerInfo> displays; | 171 std::vector<HardwareDisplayControllerInfo> displays; |
| 175 | 172 |
| 176 for (int i = 0; i < resources->count_connectors; ++i) { | 173 for (int i = 0; i < resources->count_connectors; ++i) { |
| 177 ScopedDrmConnectorPtr connector( | 174 ScopedDrmConnectorPtr connector( |
| 178 drmModeGetConnector(fd, resources->connectors[i])); | 175 drmModeGetConnector(fd, resources->connectors[i])); |
| 179 | 176 |
| 180 if (!connector || connector->connection != DRM_MODE_CONNECTED || | 177 if (!connector || connector->connection != DRM_MODE_CONNECTED || |
| 181 connector->count_modes == 0) | 178 connector->count_modes == 0) |
| 182 continue; | 179 continue; |
| 183 | 180 |
| 184 uint32_t crtc_id = GetCrtc(fd, connector.get(), resources.get(), displays); | 181 uint32_t crtc_id = GetCrtc(fd, connector.get(), resources.get(), displays); |
| 185 if (!crtc_id) | 182 if (!crtc_id) |
| 186 continue; | 183 continue; |
| 187 | 184 |
| 188 ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id)); | 185 ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id)); |
| 189 displays.push_back( | 186 displays.push_back( |
| 190 new HardwareDisplayControllerInfo(connector.Pass(), crtc.Pass(), i)); | 187 HardwareDisplayControllerInfo(connector.Pass(), crtc.Pass(), i)); |
| 191 } | 188 } |
| 192 | 189 |
| 193 return displays.Pass(); | 190 return displays; |
| 194 } | 191 } |
| 195 | 192 |
| 196 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) { | 193 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) { |
| 197 return lhs.clock == rhs.clock && lhs.hdisplay == rhs.hdisplay && | 194 return lhs.clock == rhs.clock && lhs.hdisplay == rhs.hdisplay && |
| 198 lhs.vdisplay == rhs.vdisplay && lhs.vrefresh == rhs.vrefresh && | 195 lhs.vdisplay == rhs.vdisplay && lhs.vrefresh == rhs.vrefresh && |
| 199 lhs.hsync_start == rhs.hsync_start && lhs.hsync_end == rhs.hsync_end && | 196 lhs.hsync_start == rhs.hsync_start && lhs.hsync_end == rhs.hsync_end && |
| 200 lhs.htotal == rhs.htotal && lhs.hskew == rhs.hskew && | 197 lhs.htotal == rhs.htotal && lhs.hskew == rhs.hskew && |
| 201 lhs.vsync_start == rhs.vsync_start && lhs.vsync_end == rhs.vsync_end && | 198 lhs.vsync_start == rhs.vsync_start && lhs.vsync_end == rhs.vsync_end && |
| 202 lhs.vtotal == rhs.vtotal && lhs.vscan == rhs.vscan && | 199 lhs.vtotal == rhs.vtotal && lhs.vscan == rhs.vscan && |
| 203 lhs.flags == rhs.flags && strcmp(lhs.name, rhs.name) == 0; | 200 lhs.flags == rhs.flags && strcmp(lhs.name, rhs.name) == 0; |
| 204 } | 201 } |
| 205 | 202 |
| 206 DisplayMode_Params CreateDisplayModeParams(const drmModeModeInfo& mode) { | 203 DisplayMode_Params CreateDisplayModeParams(const drmModeModeInfo& mode) { |
| 207 DisplayMode_Params params; | 204 DisplayMode_Params params; |
| 208 params.size = gfx::Size(mode.hdisplay, mode.vdisplay); | 205 params.size = gfx::Size(mode.hdisplay, mode.vdisplay); |
| 209 params.is_interlaced = mode.flags & DRM_MODE_FLAG_INTERLACE; | 206 params.is_interlaced = mode.flags & DRM_MODE_FLAG_INTERLACE; |
| 210 params.refresh_rate = GetRefreshRate(mode); | 207 params.refresh_rate = GetRefreshRate(mode); |
| 211 | 208 |
| 212 return params; | 209 return params; |
| 213 } | 210 } |
| 214 | 211 |
| 215 DisplaySnapshot_Params CreateDisplaySnapshotParams( | 212 DisplaySnapshot_Params CreateDisplaySnapshotParams( |
| 216 HardwareDisplayControllerInfo* info, | 213 const HardwareDisplayControllerInfo& info, |
| 217 int fd, | 214 int fd, |
| 218 size_t device_index, | 215 size_t device_index, |
| 219 const gfx::Point& origin) { | 216 const gfx::Point& origin) { |
| 220 DisplaySnapshot_Params params; | 217 DisplaySnapshot_Params params; |
| 221 int64 connector_index = ConnectorIndex(device_index, info->index()); | 218 int64 connector_index = ConnectorIndex(device_index, info.index()); |
| 222 params.display_id = connector_index; | 219 params.display_id = connector_index; |
| 223 params.origin = origin; | 220 params.origin = origin; |
| 224 params.physical_size = | 221 params.physical_size = |
| 225 gfx::Size(info->connector()->mmWidth, info->connector()->mmHeight); | 222 gfx::Size(info.connector()->mmWidth, info.connector()->mmHeight); |
| 226 params.type = GetDisplayType(info->connector()); | 223 params.type = GetDisplayType(info.connector()); |
| 227 params.is_aspect_preserving_scaling = | 224 params.is_aspect_preserving_scaling = |
| 228 IsAspectPreserving(fd, info->connector()); | 225 IsAspectPreserving(fd, info.connector()); |
| 229 | 226 |
| 230 ScopedDrmPropertyBlobPtr edid_blob( | 227 ScopedDrmPropertyBlobPtr edid_blob( |
| 231 GetDrmPropertyBlob(fd, info->connector(), "EDID")); | 228 GetDrmPropertyBlob(fd, info.connector(), "EDID")); |
| 232 | 229 |
| 233 if (edid_blob) { | 230 if (edid_blob) { |
| 234 std::vector<uint8_t> edid( | 231 std::vector<uint8_t> edid( |
| 235 static_cast<uint8_t*>(edid_blob->data), | 232 static_cast<uint8_t*>(edid_blob->data), |
| 236 static_cast<uint8_t*>(edid_blob->data) + edid_blob->length); | 233 static_cast<uint8_t*>(edid_blob->data) + edid_blob->length); |
| 237 | 234 |
| 238 GetDisplayIdFromEDID(edid, connector_index, ¶ms.display_id, | 235 GetDisplayIdFromEDID(edid, connector_index, ¶ms.display_id, |
| 239 ¶ms.product_id); | 236 ¶ms.product_id); |
| 240 | 237 |
| 241 ParseOutputDeviceData(edid, nullptr, nullptr, ¶ms.display_name, nullptr, | 238 ParseOutputDeviceData(edid, nullptr, nullptr, ¶ms.display_name, nullptr, |
| 242 nullptr); | 239 nullptr); |
| 243 ParseOutputOverscanFlag(edid, ¶ms.has_overscan); | 240 ParseOutputOverscanFlag(edid, ¶ms.has_overscan); |
| 244 } else { | 241 } else { |
| 245 VLOG(1) << "Failed to get EDID blob for connector " | 242 VLOG(1) << "Failed to get EDID blob for connector " |
| 246 << info->connector()->connector_id; | 243 << info.connector()->connector_id; |
| 247 } | 244 } |
| 248 | 245 |
| 249 for (int i = 0; i < info->connector()->count_modes; ++i) { | 246 for (int i = 0; i < info.connector()->count_modes; ++i) { |
| 250 const drmModeModeInfo& mode = info->connector()->modes[i]; | 247 const drmModeModeInfo& mode = info.connector()->modes[i]; |
| 251 params.modes.push_back(CreateDisplayModeParams(mode)); | 248 params.modes.push_back(CreateDisplayModeParams(mode)); |
| 252 | 249 |
| 253 if (info->crtc()->mode_valid && SameMode(info->crtc()->mode, mode)) { | 250 if (info.crtc()->mode_valid && SameMode(info.crtc()->mode, mode)) { |
| 254 params.has_current_mode = true; | 251 params.has_current_mode = true; |
| 255 params.current_mode = params.modes.back(); | 252 params.current_mode = params.modes.back(); |
| 256 } | 253 } |
| 257 | 254 |
| 258 if (mode.type & DRM_MODE_TYPE_PREFERRED) { | 255 if (mode.type & DRM_MODE_TYPE_PREFERRED) { |
| 259 params.has_native_mode = true; | 256 params.has_native_mode = true; |
| 260 params.native_mode = params.modes.back(); | 257 params.native_mode = params.modes.back(); |
| 261 } | 258 } |
| 262 } | 259 } |
| 263 | 260 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 292 case DRM_FORMAT_XRGB8888: | 289 case DRM_FORMAT_XRGB8888: |
| 293 return gfx::BufferFormat::BGRX_8888; | 290 return gfx::BufferFormat::BGRX_8888; |
| 294 case DRM_FORMAT_UYVY: | 291 case DRM_FORMAT_UYVY: |
| 295 return gfx::BufferFormat::UYVY_422; | 292 return gfx::BufferFormat::UYVY_422; |
| 296 default: | 293 default: |
| 297 NOTREACHED(); | 294 NOTREACHED(); |
| 298 return gfx::BufferFormat::LAST; | 295 return gfx::BufferFormat::LAST; |
| 299 } | 296 } |
| 300 } | 297 } |
| 301 } // namespace ui | 298 } // namespace ui |
| OLD | NEW |