backend/drm: fix disappeared output indices

This commit changes `scan_drm_connectors` to add new outputs to the end of the
list. That way, it's easier to understand what's going on with indices.

When we need to destroy outputs, we now walk the list in reverse order. This
ensures indices remain correct while iterating and removing items from the
list.

We now also make outputs without a CRTC disappear (those are in
WLR_DRM_CONN_NEEDS_MODESET state).
This commit is contained in:
emersion 2018-12-09 10:05:03 +01:00
parent 3699496256
commit f8056a0350
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
1 changed files with 7 additions and 4 deletions

View File

@ -1050,7 +1050,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
drmModeEncoder *curr_enc = drmModeGetEncoder(drm->fd, drmModeEncoder *curr_enc = drmModeGetEncoder(drm->fd,
drm_conn->encoder_id); drm_conn->encoder_id);
int index = -1; ssize_t index = -1;
struct wlr_drm_connector *c, *wlr_conn = NULL; struct wlr_drm_connector *c, *wlr_conn = NULL;
wl_list_for_each(c, &drm->outputs, link) { wl_list_for_each(c, &drm->outputs, link) {
index++; index++;
@ -1086,7 +1086,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
wlr_conn->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id); wlr_conn->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id);
} }
wl_list_insert(&drm->outputs, &wlr_conn->link); wl_list_insert(drm->outputs.prev, &wlr_conn->link);
wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->output.name); wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->output.name);
} else { } else {
seen[index] = true; seen[index] = true;
@ -1178,7 +1178,8 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET;
new_outputs[new_outputs_len++] = wlr_conn; new_outputs[new_outputs_len++] = wlr_conn;
} else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED && } else if ((wlr_conn->state == WLR_DRM_CONN_CONNECTED ||
wlr_conn->state == WLR_DRM_CONN_NEEDS_MODESET) &&
drm_conn->connection != DRM_MODE_CONNECTED) { drm_conn->connection != DRM_MODE_CONNECTED) {
wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->output.name); wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->output.name);
@ -1191,9 +1192,11 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
drmModeFreeResources(res); drmModeFreeResources(res);
// Iterate in reverse order because we'll remove items from the list and
// still want indices to remain correct.
struct wlr_drm_connector *conn, *tmp_conn; struct wlr_drm_connector *conn, *tmp_conn;
size_t index = wl_list_length(&drm->outputs); size_t index = wl_list_length(&drm->outputs);
wl_list_for_each_safe(conn, tmp_conn, &drm->outputs, link) { wl_list_for_each_reverse_safe(conn, tmp_conn, &drm->outputs, link) {
index--; index--;
if (index >= seen_len || seen[index]) { if (index >= seen_len || seen[index]) {
continue; continue;