diff options
author | Simon Ser <contact@emersion.fr> | 2023-06-12 12:13:21 +0200 |
---|---|---|
committer | Kenny Levinsen <kl@kl.wtf> | 2023-06-12 20:38:03 +0000 |
commit | 4339c37f99aa311e300205a7d27c43e470ae93da (patch) | |
tree | 98cfb853d890683927cba03e0f591d7f8a101686 /backend | |
parent | a09bb1314de6296545aae5146658ac1259ae6c40 (diff) |
backend/drm: clip FB damage
The kernel complains when the damage exceeds the FB bounds:
[73850.448326] i915 0000:00:02.0: [drm:drm_atomic_check_only] [PLANE:31:plane 1A] invalid damage clip 0 0 2147483647 2147483647
Make the DRM backend behave like the Wayland one and allow compositors
to damage (0, 0, INT32_MAX, INT32_MAX) to repaint everything without
needing to know the exact buffer size.
Closes: https://github.com/swaywm/sway/issues/7632
Diffstat (limited to 'backend')
-rw-r--r-- | backend/drm/atomic.c | 36 | ||||
-rw-r--r-- | backend/drm/libliftoff.c | 9 |
2 files changed, 30 insertions, 15 deletions
diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index c8ffaff6..4c95a3bb 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -143,6 +143,32 @@ bool create_gamma_lut_blob(struct wlr_drm_backend *drm, return true; } +bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm, + struct wlr_drm_fb *fb, const pixman_region32_t *damage, uint32_t *blob_id) { + if (!pixman_region32_not_empty(damage)) { + *blob_id = 0; + return true; + } + + int width = fb->wlr_buf->width; + int height = fb->wlr_buf->height; + + pixman_region32_t clipped; + pixman_region32_init(&clipped); + pixman_region32_intersect_rect(&clipped, damage, 0, 0, width, height); + + int rects_len; + const pixman_box32_t *rects = pixman_region32_rectangles(&clipped, &rects_len); + int ret = drmModeCreatePropertyBlob(drm->fd, rects, sizeof(*rects) * rects_len, blob_id); + pixman_region32_fini(&clipped); + if (ret != 0) { + wlr_log_errno(WLR_ERROR, "Failed to create FB_DAMAGE_CLIPS property blob"); + return false; + } + + return true; +} + static uint64_t max_bpc_for_format(uint32_t format) { switch (format) { case DRM_FORMAT_XRGB2101010: @@ -271,15 +297,9 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, uint32_t fb_damage_clips = 0; if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) && - pixman_region32_not_empty(&state->base->damage) && crtc->primary->props.fb_damage_clips != 0) { - int rects_len; - const pixman_box32_t *rects = - pixman_region32_rectangles(&state->base->damage, &rects_len); - if (drmModeCreatePropertyBlob(drm->fd, rects, - sizeof(*rects) * rects_len, &fb_damage_clips) != 0) { - wlr_log_errno(WLR_ERROR, "Failed to create FB_DAMAGE_CLIPS property blob"); - } + create_fb_damage_clips_blob(drm, state->primary_fb, + &state->base->damage, &fb_damage_clips); } bool prev_vrr_enabled = diff --git a/backend/drm/libliftoff.c b/backend/drm/libliftoff.c index a6afb1f9..80410f43 100644 --- a/backend/drm/libliftoff.c +++ b/backend/drm/libliftoff.c @@ -324,14 +324,9 @@ static bool crtc_commit(struct wlr_drm_connector *conn, uint32_t fb_damage_clips = 0; if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) && - pixman_region32_not_empty(&state->base->damage) && crtc->primary->props.fb_damage_clips != 0) { - int rects_len; - const pixman_box32_t *rects = pixman_region32_rectangles(&state->base->damage, &rects_len); - if (drmModeCreatePropertyBlob(drm->fd, rects, - sizeof(*rects) * rects_len, &fb_damage_clips) != 0) { - wlr_log_errno(WLR_ERROR, "Failed to create FB_DAMAGE_CLIPS property blob"); - } + create_fb_damage_clips_blob(drm, state->primary_fb, + &state->base->damage, &fb_damage_clips); } bool prev_vrr_enabled = |