xwayland: properly get FDs from multiplanar GBM BOs
Multiplanar GBM buffers can point to different objects from each plane. Use the _for_plane API when possible to retrieve the correct prime FD for each plane. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Simon Ser <contact@emersion.fr> Tested-by: Guido Günther <agx@sigxcpu.org>
This commit is contained in:
parent
951502e497
commit
7d5ad2d372
|
@ -354,12 +354,15 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||||
unsigned short width = pixmap->drawable.width;
|
unsigned short width = pixmap->drawable.width;
|
||||||
unsigned short height = pixmap->drawable.height;
|
unsigned short height = pixmap->drawable.height;
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
int prime_fd;
|
|
||||||
int num_planes;
|
int num_planes;
|
||||||
|
int prime_fds[4];
|
||||||
uint32_t strides[4];
|
uint32_t strides[4];
|
||||||
uint32_t offsets[4];
|
uint32_t offsets[4];
|
||||||
uint64_t modifier;
|
uint64_t modifier;
|
||||||
int i;
|
int i;
|
||||||
|
#ifndef GBM_BO_FD_FOR_PLANE
|
||||||
|
int32_t first_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (xwl_pixmap == NULL)
|
if (xwl_pixmap == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -374,20 +377,43 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||||
|
|
||||||
format = wl_drm_format_for_depth(pixmap->drawable.depth);
|
format = wl_drm_format_for_depth(pixmap->drawable.depth);
|
||||||
|
|
||||||
prime_fd = gbm_bo_get_fd(xwl_pixmap->bo);
|
|
||||||
if (prime_fd == -1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#ifdef GBM_BO_WITH_MODIFIERS
|
#ifdef GBM_BO_WITH_MODIFIERS
|
||||||
num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
|
num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
|
||||||
modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
||||||
for (i = 0; i < num_planes; i++) {
|
for (i = 0; i < num_planes; i++) {
|
||||||
|
#ifdef GBM_BO_FD_FOR_PLANE
|
||||||
|
prime_fds[i] = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, i);
|
||||||
|
#else
|
||||||
|
union gbm_bo_handle plane_handle;
|
||||||
|
|
||||||
|
plane_handle = gbm_bo_get_handle_for_plane(xwl_pixmap->bo, i);
|
||||||
|
if (i == 0)
|
||||||
|
first_handle = plane_handle.s32;
|
||||||
|
|
||||||
|
/* If all planes point to the same object as the first plane, i.e. they
|
||||||
|
* all have the same handle, we can fall back to the non-planar
|
||||||
|
* gbm_bo_get_fd without losing information. If they point to different
|
||||||
|
* objects we are out of luck and need to give up.
|
||||||
|
*/
|
||||||
|
if (first_handle == plane_handle.s32)
|
||||||
|
prime_fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||||
|
else
|
||||||
|
prime_fds[i] = -1;
|
||||||
|
#endif
|
||||||
|
if (prime_fds[i] == -1) {
|
||||||
|
while (--i >= 0)
|
||||||
|
close(prime_fds[i]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
|
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
|
||||||
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
|
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
num_planes = 1;
|
num_planes = 1;
|
||||||
modifier = DRM_FORMAT_MOD_INVALID;
|
modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
|
prime_fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||||
|
if (prime_fds[0] == -1)
|
||||||
|
return NULL;
|
||||||
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
|
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
|
||||||
offsets[0] = 0;
|
offsets[0] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -398,7 +424,7 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||||
|
|
||||||
params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
|
params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
|
||||||
for (i = 0; i < num_planes; i++) {
|
for (i = 0; i < num_planes; i++) {
|
||||||
zwp_linux_buffer_params_v1_add(params, prime_fd, i,
|
zwp_linux_buffer_params_v1_add(params, prime_fds[i], i,
|
||||||
offsets[i], strides[i],
|
offsets[i], strides[i],
|
||||||
modifier >> 32, modifier & 0xffffffff);
|
modifier >> 32, modifier & 0xffffffff);
|
||||||
}
|
}
|
||||||
|
@ -409,14 +435,15 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||||
zwp_linux_buffer_params_v1_destroy(params);
|
zwp_linux_buffer_params_v1_destroy(params);
|
||||||
} else if (num_planes == 1) {
|
} else if (num_planes == 1) {
|
||||||
xwl_pixmap->buffer =
|
xwl_pixmap->buffer =
|
||||||
wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fd, width, height,
|
wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fds[0], width, height,
|
||||||
format,
|
format,
|
||||||
0, gbm_bo_get_stride(xwl_pixmap->bo),
|
0, gbm_bo_get_stride(xwl_pixmap->bo),
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0);
|
0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(prime_fd);
|
for (i = 0; i < num_planes; i++)
|
||||||
|
close(prime_fds[i]);
|
||||||
|
|
||||||
/* Add our listener now */
|
/* Add our listener now */
|
||||||
wl_buffer_add_listener(xwl_pixmap->buffer,
|
wl_buffer_add_listener(xwl_pixmap->buffer,
|
||||||
|
@ -610,6 +637,9 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
|
||||||
{
|
{
|
||||||
struct xwl_pixmap *xwl_pixmap;
|
struct xwl_pixmap *xwl_pixmap;
|
||||||
#ifdef GBM_BO_WITH_MODIFIERS
|
#ifdef GBM_BO_WITH_MODIFIERS
|
||||||
|
#ifndef GBM_BO_FD_FOR_PLANE
|
||||||
|
int32_t first_handle;
|
||||||
|
#endif
|
||||||
uint32_t num_fds;
|
uint32_t num_fds;
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
@ -627,7 +657,25 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
|
||||||
*modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
*modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
|
||||||
|
|
||||||
for (i = 0; i < num_fds; i++) {
|
for (i = 0; i < num_fds; i++) {
|
||||||
fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
|
#ifdef GBM_BO_FD_FOR_PLANE
|
||||||
|
fds[i] = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, i);
|
||||||
|
#else
|
||||||
|
union gbm_bo_handle plane_handle;
|
||||||
|
|
||||||
|
plane_handle = gbm_bo_get_handle_for_plane(xwl_pixmap->bo, i);
|
||||||
|
if (i == 0)
|
||||||
|
first_handle = plane_handle.s32;
|
||||||
|
|
||||||
|
/* If all planes point to the same object as the first plane, i.e. they
|
||||||
|
* all have the same handle, we can fall back to the non-planar
|
||||||
|
* gbm_bo_get_fd without losing information. If they point to different
|
||||||
|
* objects we are out of luck and need to give up.
|
||||||
|
*/
|
||||||
|
if (first_handle == plane_handle.s32)
|
||||||
|
fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
|
||||||
|
else
|
||||||
|
fds[i] = -1;
|
||||||
|
#endif
|
||||||
if (fds[i] == -1) {
|
if (fds[i] == -1) {
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
close(fds[i]);
|
close(fds[i]);
|
||||||
|
|
Loading…
Reference in New Issue