From 85d7ad2eef99b5ddc9da514231306c3678179f10 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 8 Jul 2021 16:52:59 +0200 Subject: [PATCH] backend/drm: allow legacy scan-out if FB props match Historically we haven't allowed direct scan-out for legacy KMS, because legacy misses the functionality to make sure a buffer can be scanned out. However with renderer v6 the backend can't figure out anymore whether the buffer comes from its internal swap-chain, because the backend doesn't have an internal swap-chain. The legacy KMS API guarantees that the driver won't reject a buffer as long as it's been allocated with the same parameters as the previous one. Let's check this in legacy_crtc_test. --- backend/drm/legacy.c | 45 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index dd9845ff..4750c1ce 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -8,13 +8,50 @@ #include "backend/drm/iface.h" #include "backend/drm/util.h" +static bool legacy_fb_props_match(struct wlr_drm_fb *fb1, + struct wlr_drm_fb *fb2) { + if (fb1->wlr_buf->width != fb2->wlr_buf->width || + fb1->wlr_buf->height != fb2->wlr_buf->height || + gbm_bo_get_format(fb1->bo) != gbm_bo_get_format(fb2->bo) || + gbm_bo_get_modifier(fb1->bo) != gbm_bo_get_modifier(fb2->bo) || + gbm_bo_get_plane_count(fb1->bo) != gbm_bo_get_plane_count(fb2->bo)) { + return false; + } + + for (int i = 0; i < gbm_bo_get_plane_count(fb1->bo); i++) { + if (gbm_bo_get_stride_for_plane(fb1->bo, i) != + gbm_bo_get_stride_for_plane(fb2->bo, i)) { + return false; + } + if (gbm_bo_get_offset(fb1->bo, i) != gbm_bo_get_offset(fb2->bo, i)) { + return false; + } + } + + return true; +} + static bool legacy_crtc_test(struct wlr_drm_connector *conn, const struct wlr_output_state *state) { + struct wlr_drm_crtc *crtc = conn->crtc; + if ((state->committed & WLR_OUTPUT_STATE_BUFFER) && - state->buffer_type == WLR_OUTPUT_STATE_BUFFER_SCANOUT) { - wlr_drm_conn_log(conn, WLR_DEBUG, - "Cannot use direct scan-out with legacy KMS API"); - return false; + state->buffer_type == WLR_OUTPUT_STATE_BUFFER_SCANOUT && + !drm_connector_state_is_modeset(state)) { + struct wlr_drm_fb *pending_fb = crtc->primary->pending_fb; + + struct wlr_drm_fb *prev_fb = crtc->primary->queued_fb; + if (!prev_fb) { + prev_fb = crtc->primary->current_fb; + } + + /* Legacy is only guaranteed to be able to display a FB if it's been + * allocated the same way as the previous one. */ + if (prev_fb != NULL && !legacy_fb_props_match(prev_fb, pending_fb)) { + wlr_drm_conn_log(conn, WLR_DEBUG, + "Cannot change scan-out buffer parameters with legacy KMS API"); + return false; + } } return true;