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.
5 #include "ui/ozone/platform/dri/dri_util.h"
12 #include <xf86drmMode.h>
18 bool IsCrtcInUse(uint32_t crtc
,
19 const ScopedVector
<HardwareDisplayControllerInfo
>& displays
) {
20 for (size_t i
= 0; i
< displays
.size(); ++i
) {
21 if (crtc
== displays
[i
]->crtc()->crtc_id
)
28 uint32_t GetCrtc(int fd
,
29 drmModeConnector
* connector
,
30 drmModeRes
* resources
,
31 const ScopedVector
<HardwareDisplayControllerInfo
>& displays
) {
32 // If the connector already has an encoder try to re-use.
33 if (connector
->encoder_id
) {
34 ScopedDrmEncoderPtr
encoder(drmModeGetEncoder(fd
, connector
->encoder_id
));
35 if (encoder
&& encoder
->crtc_id
&& !IsCrtcInUse(encoder
->crtc_id
, displays
))
36 return encoder
->crtc_id
;
39 // Try to find an encoder for the connector.
40 for (int i
= 0; i
< connector
->count_encoders
; ++i
) {
41 ScopedDrmEncoderPtr
encoder(drmModeGetEncoder(fd
, connector
->encoders
[i
]));
45 for (int j
= 0; j
< resources
->count_crtcs
; ++j
) {
46 // Check if the encoder is compatible with this CRTC
47 if (!(encoder
->possible_crtcs
& (1 << j
)) ||
48 IsCrtcInUse(resources
->crtcs
[j
], displays
))
51 return resources
->crtcs
[j
];
60 HardwareDisplayControllerInfo::HardwareDisplayControllerInfo(
61 ScopedDrmConnectorPtr connector
,
62 ScopedDrmCrtcPtr crtc
)
63 : connector_(connector
.Pass()),
66 HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() {}
68 ScopedVector
<HardwareDisplayControllerInfo
>
69 GetAvailableDisplayControllerInfos(int fd
) {
70 ScopedDrmResourcesPtr
resources(drmModeGetResources(fd
));
71 DCHECK(resources
) << "Failed to get DRM resources";
72 ScopedVector
<HardwareDisplayControllerInfo
> displays
;
74 for (int i
= 0; i
< resources
->count_connectors
; ++i
) {
75 ScopedDrmConnectorPtr
connector(drmModeGetConnector(
76 fd
, resources
->connectors
[i
]));
78 if (!connector
|| connector
->connection
!= DRM_MODE_CONNECTED
||
79 connector
->count_modes
== 0)
82 uint32_t crtc_id
= GetCrtc(fd
, connector
.get(), resources
.get(), displays
);
86 ScopedDrmCrtcPtr
crtc(drmModeGetCrtc(fd
, crtc_id
));
87 displays
.push_back(new HardwareDisplayControllerInfo(connector
.Pass(),
91 return displays
.Pass();
94 bool SameMode(const drmModeModeInfo
& lhs
, const drmModeModeInfo
& rhs
) {
95 return lhs
.clock
== rhs
.clock
&&
96 lhs
.hdisplay
== rhs
.hdisplay
&&
97 lhs
.vdisplay
== rhs
.vdisplay
&&
98 lhs
.vrefresh
== rhs
.vrefresh
&&
99 lhs
.hsync_start
== rhs
.hsync_start
&&
100 lhs
.hsync_end
== rhs
.hsync_end
&&
101 lhs
.htotal
== rhs
.htotal
&&
102 lhs
.hskew
== rhs
.hskew
&&
103 lhs
.vsync_start
== rhs
.vsync_start
&&
104 lhs
.vsync_end
== rhs
.vsync_end
&&
105 lhs
.vtotal
== rhs
.vtotal
&&
106 lhs
.vscan
== rhs
.vscan
&&
107 lhs
.flags
== rhs
.flags
&&
108 strcmp(lhs
.name
, rhs
.name
) == 0;
111 bool MapDumbBuffer(int fd
,
115 struct drm_mode_map_dumb map_request
;
116 memset(&map_request
, 0, sizeof(map_request
));
117 map_request
.handle
= handle
;
118 if (drmIoctl(fd
, DRM_IOCTL_MODE_MAP_DUMB
, &map_request
)) {
119 VLOG(2) << "Cannot prepare dumb buffer for mapping (" << errno
<< ") "
126 PROT_READ
| PROT_WRITE
,
130 if (*pixels
== MAP_FAILED
) {
131 VLOG(2) << "Cannot mmap dumb buffer (" << errno
<< ") " << strerror(errno
);