Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: ui/ozone/platform/drm/common/drm_util.cc

Issue 2625813005: ozone: Pick CRTCs with majority of planes. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <xf86drm.h> 11 #include <xf86drm.h>
12 #include <xf86drmMode.h> 12 #include <xf86drmMode.h>
13 #include <algorithm>
13 #include <utility> 14 #include <utility>
14 15
16 #include "base/containers/small_map.h"
15 #include "ui/display/util/edid_parser.h" 17 #include "ui/display/util/edid_parser.h"
16 18
17 #if !defined(DRM_MODE_CONNECTOR_DSI) 19 #if !defined(DRM_MODE_CONNECTOR_DSI)
18 #define DRM_MODE_CONNECTOR_DSI 16 20 #define DRM_MODE_CONNECTOR_DSI 16
19 #endif 21 #endif
20 22
21 #if !defined(DRM_CAP_CURSOR_WIDTH) 23 #if !defined(DRM_CAP_CURSOR_WIDTH)
22 #define DRM_CAP_CURSOR_WIDTH 0x8 24 #define DRM_CAP_CURSOR_WIDTH 0x8
23 #endif 25 #endif
24 26
(...skipping 24 matching lines...) Expand all
49 bool IsCrtcInUse(uint32_t crtc, 51 bool IsCrtcInUse(uint32_t crtc,
50 const ScopedVector<HardwareDisplayControllerInfo>& displays) { 52 const ScopedVector<HardwareDisplayControllerInfo>& displays) {
51 for (size_t i = 0; i < displays.size(); ++i) { 53 for (size_t i = 0; i < displays.size(); ++i) {
52 if (crtc == displays[i]->crtc()->crtc_id) 54 if (crtc == displays[i]->crtc()->crtc_id)
53 return true; 55 return true;
54 } 56 }
55 57
56 return false; 58 return false;
57 } 59 }
58 60
61 // Return a CRTC compatible with |connector| and not already used in |displays|.
62 // If there are multiple compatible CRTCs, the one that supports the majority of
63 // planes will be returned.
59 uint32_t GetCrtc(int fd, 64 uint32_t GetCrtc(int fd,
60 drmModeConnector* connector, 65 drmModeConnector* connector,
61 drmModeRes* resources, 66 drmModeRes* resources,
62 const ScopedVector<HardwareDisplayControllerInfo>& displays) { 67 const ScopedVector<HardwareDisplayControllerInfo>& displays) {
63 // If the connector already has an encoder try to re-use. 68 ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(fd));
64 if (connector->encoder_id) { 69 std::vector<ScopedDrmPlanePtr> planes;
65 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoder_id)); 70 for (uint32_t i = 0; i < plane_resources->count_planes; i++)
66 if (encoder && encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) 71 planes.emplace_back(drmModeGetPlane(fd, plane_resources->planes[i]));
67 return encoder->crtc_id; 72
68 } 73 DCHECK_GE(32, resources->count_crtcs);
74 uint32_t best_crtc = 0;
75 int best_crtc_planes = 0;
69 76
70 // Try to find an encoder for the connector. 77 // Try to find an encoder for the connector.
71 for (int i = 0; i < connector->count_encoders; ++i) { 78 for (int i = 0; i < connector->count_encoders; ++i) {
72 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoders[i])); 79 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, connector->encoders[i]));
73 if (!encoder) 80 if (!encoder)
74 continue; 81 continue;
75 82
76 for (int j = 0; j < resources->count_crtcs; ++j) { 83 for (int j = 0; j < resources->count_crtcs; ++j) {
77 // Check if the encoder is compatible with this CRTC 84 // Check if the encoder is compatible with this CRTC
78 if (!(encoder->possible_crtcs & (1 << j)) || 85 int crtc_bit = 1 << j;
86 if (!(encoder->possible_crtcs & crtc_bit) ||
79 IsCrtcInUse(resources->crtcs[j], displays)) 87 IsCrtcInUse(resources->crtcs[j], displays))
80 continue; 88 continue;
81 89
82 return resources->crtcs[j]; 90 int supported_planes = std::count_if(
91 planes.begin(), planes.end(), [crtc_bit](const ScopedDrmPlanePtr& p) {
92 return p->possible_crtcs & crtc_bit;
93 });
94
95 uint32_t assigned_crtc = 0;
96 if (connector->encoder_id == encoder->encoder_id)
97 assigned_crtc = encoder->crtc_id;
98 if (supported_planes > best_crtc_planes ||
99 (supported_planes == best_crtc_planes &&
100 assigned_crtc == resources->crtcs[j])) {
101 best_crtc_planes = supported_planes;
102 best_crtc = resources->crtcs[j];
103 }
83 } 104 }
84 } 105 }
85 106
86 return 0; 107 return best_crtc;
87 } 108 }
88 109
89 // Computes the refresh rate for the specific mode. If we have enough 110 // Computes the refresh rate for the specific mode. If we have enough
90 // information use the mode timings to compute a more exact value otherwise 111 // information use the mode timings to compute a more exact value otherwise
91 // fallback to using the mode's vertical refresh rate (the kernel computes this 112 // fallback to using the mode's vertical refresh rate (the kernel computes this
92 // the same way, however there is a loss in precision since |vrefresh| is sent 113 // the same way, however there is a loss in precision since |vrefresh| is sent
93 // as an integer). 114 // as an integer).
94 float GetRefreshRate(const drmModeModeInfo& mode) { 115 float GetRefreshRate(const drmModeModeInfo& mode) {
95 if (!mode.htotal || !mode.vtotal) 116 if (!mode.htotal || !mode.vtotal)
96 return mode.vrefresh; 117 return mode.vrefresh;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 240
220 HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() { 241 HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() {
221 } 242 }
222 243
223 ScopedVector<HardwareDisplayControllerInfo> GetAvailableDisplayControllerInfos( 244 ScopedVector<HardwareDisplayControllerInfo> GetAvailableDisplayControllerInfos(
224 int fd) { 245 int fd) {
225 ScopedDrmResourcesPtr resources(drmModeGetResources(fd)); 246 ScopedDrmResourcesPtr resources(drmModeGetResources(fd));
226 DCHECK(resources) << "Failed to get DRM resources"; 247 DCHECK(resources) << "Failed to get DRM resources";
227 ScopedVector<HardwareDisplayControllerInfo> displays; 248 ScopedVector<HardwareDisplayControllerInfo> displays;
228 249
250 std::vector<ScopedDrmConnectorPtr> available_connectors;
251 std::vector<ScopedDrmConnectorPtr::element_type*> connectors;
229 for (int i = 0; i < resources->count_connectors; ++i) { 252 for (int i = 0; i < resources->count_connectors; ++i) {
230 ScopedDrmConnectorPtr connector( 253 ScopedDrmConnectorPtr connector(
231 drmModeGetConnector(fd, resources->connectors[i])); 254 drmModeGetConnector(fd, resources->connectors[i]));
255 connectors.push_back(connector.get());
232 256
233 if (!connector || connector->connection != DRM_MODE_CONNECTED || 257 if (connector && connector->connection == DRM_MODE_CONNECTED &&
234 connector->count_modes == 0) 258 connector->count_modes != 0)
235 continue; 259 available_connectors.push_back(std::move(connector));
260 }
236 261
237 uint32_t crtc_id = GetCrtc(fd, connector.get(), resources.get(), displays); 262 base::SmallMap<std::map<ScopedDrmConnectorPtr::element_type*, int>>
263 connector_crtcs;
264 for (auto& c : available_connectors) {
265 uint32_t possible_crtcs = 0;
266 for (int i = 0; i < c->count_encoders; ++i) {
267 ScopedDrmEncoderPtr encoder(drmModeGetEncoder(fd, c->encoders[i]));
268 if (!encoder)
269 continue;
270 possible_crtcs |= encoder->possible_crtcs;
271 }
272 connector_crtcs[c.get()] = possible_crtcs;
273 }
274 // Make sure to start assigning a crtc to the connector that supports the
275 // fewest crtcs first.
276 std::stable_sort(available_connectors.begin(), available_connectors.end(),
277 [&connector_crtcs](const ScopedDrmConnectorPtr& c1,
278 const ScopedDrmConnectorPtr& c2) {
279 // When c1 supports a proper subset of the crtcs of c2, we
280 // should process c1 first (return true).
281 int c1_crtcs = connector_crtcs[c1.get()];
282 int c2_crtcs = connector_crtcs[c2.get()];
283 return (c1_crtcs & c2_crtcs) == c1_crtcs &&
284 c1_crtcs != c2_crtcs;
285 });
286
287 for (auto& c : available_connectors) {
288 uint32_t crtc_id = GetCrtc(fd, c.get(), resources.get(), displays);
238 if (!crtc_id) 289 if (!crtc_id)
239 continue; 290 continue;
240 291
241 ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id)); 292 ScopedDrmCrtcPtr crtc(drmModeGetCrtc(fd, crtc_id));
242 displays.push_back(new HardwareDisplayControllerInfo(std::move(connector), 293 size_t index = std::find(connectors.begin(), connectors.end(), c.get()) -
243 std::move(crtc), i)); 294 connectors.begin();
295 DCHECK_LT(index, connectors.size());
296 displays.push_back(new HardwareDisplayControllerInfo(
297 std::move(c), std::move(crtc), index));
244 } 298 }
245 299
246 return displays; 300 return displays;
247 } 301 }
248 302
249 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) { 303 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) {
250 return lhs.clock == rhs.clock && lhs.hdisplay == rhs.hdisplay && 304 return lhs.clock == rhs.clock && lhs.hdisplay == rhs.hdisplay &&
251 lhs.vdisplay == rhs.vdisplay && lhs.vrefresh == rhs.vrefresh && 305 lhs.vdisplay == rhs.vdisplay && lhs.vrefresh == rhs.vrefresh &&
252 lhs.hsync_start == rhs.hsync_start && lhs.hsync_end == rhs.hsync_end && 306 lhs.hsync_start == rhs.hsync_start && lhs.hsync_end == rhs.hsync_end &&
253 lhs.htotal == rhs.htotal && lhs.hskew == rhs.hskew && 307 lhs.htotal == rhs.htotal && lhs.hskew == rhs.hskew &&
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 case gfx::BufferFormat::BGR_565: 449 case gfx::BufferFormat::BGR_565:
396 return DRM_FORMAT_RGB565; 450 return DRM_FORMAT_RGB565;
397 case gfx::BufferFormat::UYVY_422: 451 case gfx::BufferFormat::UYVY_422:
398 return DRM_FORMAT_UYVY; 452 return DRM_FORMAT_UYVY;
399 default: 453 default:
400 NOTREACHED(); 454 NOTREACHED();
401 return 0; 455 return 0;
402 } 456 }
403 } 457 }
404 } // namespace ui 458 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698