backend/drm: make commits without a buffer blocking

The wlr_output API requires compositors to wait for wlr_output.frame
before submitting a new buffer. However, compositors can perform a
commit which doesn't involve a buffer anytime.

If the commit is a modeset, we set DRM_MODE_ATOMIC_ALLOW_MODESET and
block until the commit is done. If it isn't, we currently always
perform a non-blocking commit. This is an issue because a previous
page-flip might still be in flight kernel-side, returning EBUSY.

Fix this by using blocking commits when a buffer isn't submitted by
the compositor.

Closes: https://github.com/swaywm/sway/issues/6962
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/2239
This commit is contained in:
Simon Ser 2022-05-27 13:21:55 +02:00
parent e383c1f1db
commit acc6d94db0

View file

@ -264,7 +264,12 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
} }
if (modeset) { if (modeset) {
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
} else if (!test_only) { } else if (!test_only && (state->base->committed & WLR_OUTPUT_STATE_BUFFER)) {
// The wlr_output API requires non-modeset commits with a new buffer to
// wait for the frame event. However compositors often perform
// non-modesets commits without a new buffer without waiting for the
// frame event. In that case we need to make the KMS commit blocking,
// otherwise the kernel will error out with EBUSY.
flags |= DRM_MODE_ATOMIC_NONBLOCK; flags |= DRM_MODE_ATOMIC_NONBLOCK;
} }