aboutsummaryrefslogtreecommitdiff
path: root/backend/drm
diff options
context:
space:
mode:
authorvanfanel <redwindwanderer@gmail.com>2022-09-11 18:38:53 +0200
committerSimon Ser <contact@emersion.fr>2022-09-16 14:15:58 +0000
commit8795dde94eebb642e180de2a39ca19e4eee88ac1 (patch)
treef4cd98fb8fcfe26a44ebacf1722bf8e688309e29 /backend/drm
parent1facdeabe5a8712b43fd157adadd79a027e29c07 (diff)
Initialize connectors current mode to the mode used by KMS on startup.
Diffstat (limited to 'backend/drm')
-rw-r--r--backend/drm/drm.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 06548ed0..6d5d0de3 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -1341,6 +1341,24 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
free(subconnector);
+ // Before iterating on the conn's modes, get the current KMS mode
+ // in use from the connector's CRTC.
+ drmModeModeInfo *current_modeinfo = NULL;
+ if (wlr_conn->crtc != NULL) {
+ if (wlr_conn->crtc->props.mode_id == 0) {
+ // Use the legacy drm interface.
+ if (wlr_conn->crtc->legacy_crtc->mode_valid) {
+ current_modeinfo = &wlr_conn->crtc->legacy_crtc->mode;
+ }
+ } else {
+ // Use the modern atomic drm interface.
+ size_t modeinfo_size = 0;
+ current_modeinfo = get_drm_prop_blob(drm->fd, wlr_conn->crtc->id,
+ wlr_conn->crtc->props.mode_id, &modeinfo_size);
+ assert(modeinfo_size == sizeof(drmModeModeInfo));
+ }
+ }
+
wlr_log(WLR_INFO, "Detected modes:");
for (int i = 0; i < drm_conn->count_modes; ++i) {
@@ -1363,6 +1381,21 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
mode->wlr_mode.preferred = true;
}
+ // If this is the current mode set on the conn's crtc,
+ // then set it as the conn's output current mode.
+ if (current_modeinfo != NULL && memcmp(&mode->drm_mode,
+ current_modeinfo, sizeof(*current_modeinfo)) == 0) {
+ // Update width, height, refresh, transform_matrix and current_mode
+ // of this connector's output.
+ wlr_output_update_mode(&wlr_conn->output, &mode->wlr_mode);
+
+ uint64_t mode_id = 0;
+ get_drm_prop(drm->fd, wlr_conn->crtc->id,
+ wlr_conn->crtc->props.mode_id, &mode_id);
+
+ wlr_conn->crtc->mode_id = mode_id;
+ }
+
wlr_log(WLR_INFO, " %"PRId32"x%"PRId32"@%"PRId32" %s",
mode->wlr_mode.width, mode->wlr_mode.height,
mode->wlr_mode.refresh,
@@ -1371,6 +1404,12 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
wl_list_insert(wlr_conn->output.modes.prev, &mode->wlr_mode.link);
}
+ if (wlr_conn->crtc != NULL && wlr_conn->crtc->props.mode_id != 0) {
+ // free() the modeinfo pointer, but only
+ // if not using the legacy API.
+ free(current_modeinfo);
+ }
+
wlr_conn->possible_crtcs =
drmModeConnectorGetPossibleCrtcs(drm->fd, drm_conn);
if (wlr_conn->possible_crtcs == 0) {