kms: Try to preserve existing output routing as weston would do

This is basically a backport from weston:
75487c2560

It states that:

 - preserving the existing CRTC -> encoder -> connector routing will
   make the startup faster
 - the existing routing may be set according to some device limitations

Since the QtWayland implementation appears to be based off an old
version of weston (maybe pre-2.0), this patch might look different from
the latest weston implementation. But the idea stays the same.

FWIW, this works around the issue I've seen on Renesas R-Car E3 (aka
Ebisu) board. Without this patch, VGA1+HDMI1 setup would fail because
the device reported possible_crtcs=1 (meaning {crtcs[0]}) for the second
screen "HDMI1", but the crtcs[0] was already taken by the first screen
"VGA1".

  No usable crtc/encoder pair for connector "HDMI1"

With this patch, the crtcs[1] is paired with "VGA1" (as it is the
existing routing), so the crtcs[0] can be allocated for "HDMI1".

Change-Id: Ibd304a8b5efbe4a8aa94b2c5697fe2b399386280
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Yuya Nishihara 2019-07-01 12:38:46 +09:00
parent ac885a34ec
commit 7cf9f4e3d3

View File

@ -66,6 +66,8 @@ enum OutputConfiguration {
int QKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector)
{
int candidate = -1;
for (int i = 0; i < connector->count_encoders; i++) {
drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]);
if (!encoder) {
@ -73,19 +75,30 @@ int QKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr co
continue;
}
quint32 encoderId = encoder->encoder_id;
quint32 crtcId = encoder->crtc_id;
quint32 possibleCrtcs = encoder->possible_crtcs;
drmModeFreeEncoder(encoder);
for (int j = 0; j < resources->count_crtcs; j++) {
bool isPossible = possibleCrtcs & (1 << j);
bool isAvailable = !(m_crtc_allocator & (1 << j));
// Preserve the existing CRTC -> encoder -> connector routing if
// any. It makes the initialization faster, and may be better
// since we have a very dumb picking algorithm.
bool isBestChoice = (!connector->encoder_id ||
(connector->encoder_id == encoderId &&
resources->crtcs[j] == crtcId));
if (isPossible && isAvailable)
if (isPossible && isAvailable && isBestChoice) {
return j;
} else if (isPossible && isAvailable) {
candidate = j;
}
}
}
return -1;
return candidate;
}
static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_*