linux-dmabuf: Move the attributes part of linux_dmabuf_buffer into its own struct

This allows renderers to use that struct to create their own dmabufs,
in case they can’t import the one provided by the client directly but
know how to convert it into a format they can render.

Signed-off-by: Emmanuel Gil Peyrot <emmanuel.peyrot@collabora.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Daniel Stone <daniels@collabora.com>

Differential Revision: https://phabricator.freedesktop.org/D332
Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
Reviewed-by: Derek Foreman <derekf@osg.samsung.com>
dev
Emmanuel Gil Peyrot 9 years ago committed by Derek Foreman
parent 6207b6af09
commit c399692b8e
  1. 12
      src/compositor-drm.c
  2. 50
      src/gl-renderer.c
  3. 56
      src/linux-dmabuf.c
  4. 14
      src/linux-dmabuf.h

@ -983,14 +983,14 @@ drm_output_prepare_overlay_view(struct drm_output *output,
* support a mix of gbm_bos and drmfbs. * support a mix of gbm_bos and drmfbs.
*/ */
struct gbm_import_fd_data gbm_dmabuf = { struct gbm_import_fd_data gbm_dmabuf = {
.fd = dmabuf->dmabuf_fd[0], .fd = dmabuf->attributes.fd[0],
.width = dmabuf->width, .width = dmabuf->attributes.width,
.height = dmabuf->height, .height = dmabuf->attributes.height,
.stride = dmabuf->stride[0], .stride = dmabuf->attributes.stride[0],
.format = dmabuf->format .format = dmabuf->attributes.format
}; };
if (dmabuf->n_planes != 1 || dmabuf->offset[0] != 0) if (dmabuf->attributes.n_planes != 1 || dmabuf->attributes.offset[0] != 0)
return NULL; return NULL;
bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_FD, &gbm_dmabuf, bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_FD, &gbm_dmabuf,

@ -1446,38 +1446,38 @@ import_dmabuf(struct gl_renderer *gr,
*/ */
attribs[atti++] = EGL_WIDTH; attribs[atti++] = EGL_WIDTH;
attribs[atti++] = dmabuf->width; attribs[atti++] = dmabuf->attributes.width;
attribs[atti++] = EGL_HEIGHT; attribs[atti++] = EGL_HEIGHT;
attribs[atti++] = dmabuf->height; attribs[atti++] = dmabuf->attributes.height;
attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[atti++] = dmabuf->format; attribs[atti++] = dmabuf->attributes.format;
/* XXX: Add modifier here when supported */ /* XXX: Add modifier here when supported */
if (dmabuf->n_planes > 0) { if (dmabuf->attributes.n_planes > 0) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
attribs[atti++] = dmabuf->dmabuf_fd[0]; attribs[atti++] = dmabuf->attributes.fd[0];
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
attribs[atti++] = dmabuf->offset[0]; attribs[atti++] = dmabuf->attributes.offset[0];
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[atti++] = dmabuf->stride[0]; attribs[atti++] = dmabuf->attributes.stride[0];
} }
if (dmabuf->n_planes > 1) { if (dmabuf->attributes.n_planes > 1) {
attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
attribs[atti++] = dmabuf->dmabuf_fd[1]; attribs[atti++] = dmabuf->attributes.fd[1];
attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
attribs[atti++] = dmabuf->offset[1]; attribs[atti++] = dmabuf->attributes.offset[1];
attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
attribs[atti++] = dmabuf->stride[1]; attribs[atti++] = dmabuf->attributes.stride[1];
} }
if (dmabuf->n_planes > 2) { if (dmabuf->attributes.n_planes > 2) {
attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
attribs[atti++] = dmabuf->dmabuf_fd[2]; attribs[atti++] = dmabuf->attributes.fd[2];
attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
attribs[atti++] = dmabuf->offset[2]; attribs[atti++] = dmabuf->attributes.offset[2];
attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
attribs[atti++] = dmabuf->stride[2]; attribs[atti++] = dmabuf->attributes.stride[2];
} }
attribs[atti++] = EGL_NONE; attribs[atti++] = EGL_NONE;
@ -1507,14 +1507,14 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
assert(gr->has_dmabuf_import); assert(gr->has_dmabuf_import);
for (i = 0; i < dmabuf->n_planes; i++) { for (i = 0; i < dmabuf->attributes.n_planes; i++) {
/* EGL import does not have modifiers */ /* EGL import does not have modifiers */
if (dmabuf->modifier[i] != 0) if (dmabuf->attributes.modifier[i] != 0)
return false; return false;
} }
/* reject all flags we do not recognize or handle */ /* reject all flags we do not recognize or handle */
if (dmabuf->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT) if (dmabuf->attributes.flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
return false; return false;
image = import_dmabuf(gr, dmabuf); image = import_dmabuf(gr, dmabuf);
@ -1528,12 +1528,12 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
} }
static GLenum static GLenum
choose_texture_target(struct linux_dmabuf_buffer *dmabuf) choose_texture_target(struct dmabuf_attributes *attributes)
{ {
if (dmabuf->n_planes > 1) if (attributes->n_planes > 1)
return GL_TEXTURE_EXTERNAL_OES; return GL_TEXTURE_EXTERNAL_OES;
switch (dmabuf->format & ~DRM_FORMAT_BIG_ENDIAN) { switch (attributes->format & ~DRM_FORMAT_BIG_ENDIAN) {
case DRM_FORMAT_YUYV: case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU: case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY: case DRM_FORMAT_UYVY:
@ -1560,16 +1560,16 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
return; return;
} }
buffer->width = dmabuf->width; buffer->width = dmabuf->attributes.width;
buffer->height = dmabuf->height; buffer->height = dmabuf->attributes.height;
buffer->y_inverted = buffer->y_inverted =
!!(dmabuf->flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT); !!(dmabuf->attributes.flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT);
for (i = 0; i < gs->num_images; i++) for (i = 0; i < gs->num_images; i++)
egl_image_unref(gs->images[i]); egl_image_unref(gs->images[i]);
gs->num_images = 0; gs->num_images = 0;
gs->target = choose_texture_target(dmabuf); gs->target = choose_texture_target(&dmabuf->attributes);
switch (gs->target) { switch (gs->target) {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
gs->shader = &gr->texture_shader_rgba; gs->shader = &gr->texture_shader_rgba;

@ -35,12 +35,12 @@ linux_dmabuf_buffer_destroy(struct linux_dmabuf_buffer *buffer)
{ {
int i; int i;
for (i = 0; i < buffer->n_planes; i++) { for (i = 0; i < buffer->attributes.n_planes; i++) {
close(buffer->dmabuf_fd[i]); close(buffer->attributes.fd[i]);
buffer->dmabuf_fd[i] = -1; buffer->attributes.fd[i] = -1;
} }
buffer->n_planes = 0; buffer->attributes.n_planes = 0;
free(buffer); free(buffer);
} }
@ -95,7 +95,7 @@ params_add(struct wl_client *client,
return; return;
} }
if (buffer->dmabuf_fd[plane_idx] != -1) { if (buffer->attributes.fd[plane_idx] != -1) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
"a dmabuf has already been added for plane %u", "a dmabuf has already been added for plane %u",
@ -104,12 +104,12 @@ params_add(struct wl_client *client,
return; return;
} }
buffer->dmabuf_fd[plane_idx] = name_fd; buffer->attributes.fd[plane_idx] = name_fd;
buffer->offset[plane_idx] = offset; buffer->attributes.offset[plane_idx] = offset;
buffer->stride[plane_idx] = stride; buffer->attributes.stride[plane_idx] = stride;
buffer->modifier[plane_idx] = ((uint64_t)modifier_hi << 32) | buffer->attributes.modifier[plane_idx] = ((uint64_t)modifier_hi << 32) |
modifier_lo; modifier_lo;
buffer->n_planes++; buffer->attributes.n_planes++;
} }
static void static void
@ -167,7 +167,7 @@ params_create(struct wl_client *client,
wl_resource_set_user_data(buffer->params_resource, NULL); wl_resource_set_user_data(buffer->params_resource, NULL);
buffer->params_resource = NULL; buffer->params_resource = NULL;
if (!buffer->n_planes) { if (!buffer->attributes.n_planes) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
"no dmabuf has been added to the params"); "no dmabuf has been added to the params");
@ -175,8 +175,8 @@ params_create(struct wl_client *client,
} }
/* Check for holes in the dmabufs set (e.g. [0, 1, 3]) */ /* Check for holes in the dmabufs set (e.g. [0, 1, 3]) */
for (i = 0; i < buffer->n_planes; i++) { for (i = 0; i < buffer->attributes.n_planes; i++) {
if (buffer->dmabuf_fd[i] == -1) { if (buffer->attributes.fd[i] == -1) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
"no dmabuf has been added for plane %i", i); "no dmabuf has been added for plane %i", i);
@ -184,10 +184,10 @@ params_create(struct wl_client *client,
} }
} }
buffer->width = width; buffer->attributes.width = width;
buffer->height = height; buffer->attributes.height = height;
buffer->format = format; buffer->attributes.format = format;
buffer->flags = flags; buffer->attributes.flags = flags;
if (width < 1 || height < 1) { if (width < 1 || height < 1) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
@ -196,10 +196,10 @@ params_create(struct wl_client *client,
goto err_out; goto err_out;
} }
for (i = 0; i < buffer->n_planes; i++) { for (i = 0; i < buffer->attributes.n_planes; i++) {
off_t size; off_t size;
if ((uint64_t) buffer->offset[i] + buffer->stride[i] > UINT32_MAX) { if ((uint64_t) buffer->attributes.offset[i] + buffer->attributes.stride[i] > UINT32_MAX) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
"size overflow for plane %i", i); "size overflow for plane %i", i);
@ -207,8 +207,8 @@ params_create(struct wl_client *client,
} }
if (i == 0 && if (i == 0 &&
(uint64_t) buffer->offset[i] + (uint64_t) buffer->attributes.offset[i] +
(uint64_t) buffer->stride[i] * height > UINT32_MAX) { (uint64_t) buffer->attributes.stride[i] * height > UINT32_MAX) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
"size overflow for plane %i", i); "size overflow for plane %i", i);
@ -217,30 +217,30 @@ params_create(struct wl_client *client,
/* Don't report an error as it might be caused /* Don't report an error as it might be caused
* by the kernel not supporting seeking on dmabuf */ * by the kernel not supporting seeking on dmabuf */
size = lseek(buffer->dmabuf_fd[i], 0, SEEK_END); size = lseek(buffer->attributes.fd[i], 0, SEEK_END);
if (size == -1) if (size == -1)
break; break;
if (buffer->offset[i] >= size) { if (buffer->attributes.offset[i] >= size) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
"invalid offset %i for plane %i", "invalid offset %i for plane %i",
buffer->offset[i], i); buffer->attributes.offset[i], i);
goto err_out; goto err_out;
} }
if (buffer->offset[i] + buffer->stride[i] > size) { if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
"invalid stride %i for plane %i", "invalid stride %i for plane %i",
buffer->stride[i], i); buffer->attributes.stride[i], i);
goto err_out; goto err_out;
} }
/* Only valid for first plane as other planes might be /* Only valid for first plane as other planes might be
* sub-sampled according to fourcc format */ * sub-sampled according to fourcc format */
if (i == 0 && if (i == 0 &&
buffer->offset[i] + buffer->stride[i] * height > size) { buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) {
wl_resource_post_error(params_resource, wl_resource_post_error(params_resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
"invalid buffer stride or height for plane %i", i); "invalid buffer stride or height for plane %i", i);
@ -316,7 +316,7 @@ linux_dmabuf_create_params(struct wl_client *client,
goto err_out; goto err_out;
for (i = 0; i < MAX_DMABUF_PLANES; i++) for (i = 0; i < MAX_DMABUF_PLANES; i++)
buffer->dmabuf_fd[i] = -1; buffer->attributes.fd[i] = -1;
buffer->compositor = compositor; buffer->compositor = compositor;
buffer->params_resource = buffer->params_resource =

@ -31,19 +31,23 @@ struct linux_dmabuf_buffer;
typedef void (*dmabuf_user_data_destroy_func)( typedef void (*dmabuf_user_data_destroy_func)(
struct linux_dmabuf_buffer *buffer); struct linux_dmabuf_buffer *buffer);
struct linux_dmabuf_buffer { struct dmabuf_attributes {
struct wl_resource *buffer_resource;
struct wl_resource *params_resource;
struct weston_compositor *compositor;
int32_t width; int32_t width;
int32_t height; int32_t height;
uint32_t format; uint32_t format;
uint32_t flags; /* enum zlinux_buffer_params_flags */ uint32_t flags; /* enum zlinux_buffer_params_flags */
int n_planes; int n_planes;
int dmabuf_fd[MAX_DMABUF_PLANES]; int fd[MAX_DMABUF_PLANES];
uint32_t offset[MAX_DMABUF_PLANES]; uint32_t offset[MAX_DMABUF_PLANES];
uint32_t stride[MAX_DMABUF_PLANES]; uint32_t stride[MAX_DMABUF_PLANES];
uint64_t modifier[MAX_DMABUF_PLANES]; uint64_t modifier[MAX_DMABUF_PLANES];
};
struct linux_dmabuf_buffer {
struct wl_resource *buffer_resource;
struct wl_resource *params_resource;
struct weston_compositor *compositor;
struct dmabuf_attributes attributes;
void *user_data; void *user_data;
dmabuf_user_data_destroy_func user_data_destroy_func; dmabuf_user_data_destroy_func user_data_destroy_func;

Loading…
Cancel
Save