diff --git a/backend/x11/output.c b/backend/x11/output.c index 181c2de14..51a9c1441 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -19,6 +19,7 @@ #include #include "backend/x11.h" +#include "render/pixel_format.h" #include "util/time.h" #include "types/wlr_buffer.h" #include "types/wlr_output.h" @@ -167,11 +168,20 @@ static bool output_test(struct wlr_output *wlr_output, if (state->committed & WLR_OUTPUT_STATE_BUFFER) { struct wlr_buffer *buffer = state->buffer; - - if (buffer_get_drm_format(buffer) != x11->x11_format->drm) { + uint32_t format = buffer_get_drm_format(buffer); + if (format != x11->x11_format->drm) { wlr_log(WLR_DEBUG, "Unsupported buffer format"); return false; } + struct wlr_shm_attributes shm; + if (wlr_buffer_get_shm(buffer, &shm)) { + const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(format); + if (shm.stride != pixel_format_info_min_stride(info, shm.width)) { + // xcb_shm_create_pixmap() does not allow arbitrary strides. + wlr_log(WLR_DEBUG, "Unsupported shm buffer stride"); + return false; + } + } } if (state->committed & WLR_OUTPUT_STATE_MODE) { @@ -261,6 +271,12 @@ static xcb_pixmap_t import_shm(struct wlr_x11_output *output, return XCB_PIXMAP_NONE; } + const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(shm->format); + if (shm->stride != pixel_format_info_min_stride(info, shm->width)) { + // xcb_shm_create_pixmap() does not allow arbitrary strides. + return XCB_PIXMAP_NONE; + } + // xcb closes the FD after sending it int fd = fcntl(shm->fd, F_DUPFD_CLOEXEC, 0); if (fd < 0) {