backend/drm: fix EINVAL atomic commits after VT switch

The drm_connector_commit_state() call in handle_session_active()
was not resulting in any atomic commit, because it didn't match any
of the if branches: active = true, no new buffer was committed,
and adaptive sync/gamma LUT were unchanged. Thus the commit was a
no-op.

Later on, when the compositor performs regular page-flips, the
kernel would return EINVAL indicating that a modeset was needed.

Rework the logic to use a non-blocking page-flip commit if a buffer
was committed, and use a blocking commit if the connector is on or
is being disabled. The only case where we should skip the atomic
commit is when disabling (active = false) an already-disabled
connector (conn->crtc == NULL).

Note, 6936e163b5 ("backend/drm: short-circuit no-op commits")
has introduced early returns for other situations where we don't
need to perform an atomic commit (e.g. updating scale or transform
of an output).

Fixes: f216e97983 ("backend/drm: drop drm_connector_set_mode()")
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3432
This commit is contained in:
Simon Ser 2022-10-17 12:29:38 +02:00 committed by Simon Zeni
parent ca432ea539
commit 98a83ce14c

View file

@ -592,18 +592,11 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
}
}
if (!pending.active) {
if (conn->crtc != NULL && !drm_crtc_commit(conn, &pending, 0, false)) {
return false;
}
} else if (pending.base->committed & WLR_OUTPUT_STATE_BUFFER) {
if (pending.base->committed & WLR_OUTPUT_STATE_BUFFER) {
if (!drm_crtc_page_flip(conn, &pending)) {
return false;
}
} else if (pending.base->committed & (WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED |
WLR_OUTPUT_STATE_GAMMA_LUT)) {
assert(conn->crtc != NULL);
// TODO: maybe request a page-flip event here?
} else if (pending.active || conn->crtc != NULL) {
if (!drm_crtc_commit(conn, &pending, 0, false)) {
return false;
}