dmabuf: Reshuffle APIs a bit

Give the builder an n-planes property, and
add private api to the texture to access
the per-plane properties as arrays.
This commit is contained in:
Matthias Clasen
2023-10-09 08:22:14 -04:00
parent e2162c13ee
commit a9fb224b8d
4 changed files with 162 additions and 65 deletions

View File

@@ -65,10 +65,12 @@ struct _GdkDmabufTexture
unsigned int fourcc;
guint64 modifier;
unsigned int n_planes;
/* Per-plane properties */
int fd[4];
unsigned int stride[4];
unsigned int offset[4];
int fds[4];
unsigned int strides[4];
unsigned int offsets[4];
GDestroyNotify destroy;
gpointer data;
@@ -194,13 +196,13 @@ do_direct_download (GdkDmabufTexture *self,
height = gdk_texture_get_height (GDK_TEXTURE (self));
bpp = gdk_memory_format_bytes_per_pixel (gdk_texture_get_format (GDK_TEXTURE (self)));
src_stride = self->stride[0];
size = self->stride[0] * height;
src_stride = self->strides[0];
size = self->strides[0] * height;
if (ioctl (self->fd[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
if (ioctl (self->fds[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
src_data = mmap (NULL, size, PROT_READ, MAP_SHARED, self->fd[0], self->offset[0]);
src_data = mmap (NULL, size, PROT_READ, MAP_SHARED, self->fds[0], self->offsets[0]);
if (stride == src_stride)
memcpy (data, src_data, size);
@@ -210,7 +212,7 @@ do_direct_download (GdkDmabufTexture *self,
memcpy (data + i * stride, src_data + i * src_stride, height * bpp);
}
if (ioctl (self->fd[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
if (ioctl (self->fds[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
munmap (src_data, size);
@@ -228,7 +230,7 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
info = get_drm_format_info (self->fourcc);
if (info->requires_gl)
if (info->requires_gl || self->n_planes > 1)
do_indirect_download (self, format, data, stride);
else if (format == src_format)
do_direct_download (self, data, stride);
@@ -241,7 +243,7 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
src_stride = self->stride[0];
src_stride = self->strides[0];
src_data = g_new (guchar, src_stride * height);
do_direct_download (self, src_data, src_stride);
@@ -268,7 +270,7 @@ gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass)
static void
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
{
self->fd[0] = self->fd[1] = self->fd[2] = self->fd[3] = -1;
self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1;
}
static gboolean
@@ -303,13 +305,14 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GdkTexture *update_texture;
GdkDisplay *display = gdk_dmabuf_texture_builder_get_display (builder);
uint32_t fourcc = gdk_dmabuf_texture_builder_get_fourcc (builder);
uint64_t modifier = gdk_dmabuf_texture_builder_get_modifier(builder);
uint64_t modifier = gdk_dmabuf_texture_builder_get_modifier (builder);
unsigned int n_planes = gdk_dmabuf_texture_builder_get_n_planes (builder);
GdkDrmFormatInfo *info;
info = get_drm_format_info (fourcc);
if (!info ||
(info->requires_gl && !display_supports_format (display, fourcc, modifier)))
((info->requires_gl || n_planes > 1) && !display_supports_format (display, fourcc, modifier)))
{
g_warning ("Unsupported dmabuf format %c%c%c%c:%#lx",
fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier);
@@ -330,16 +333,11 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
self->fourcc = fourcc;
self->modifier = modifier;
self->n_planes = n_planes;
for (int i = 0; i < 4; i++)
{
self->fd[i] = gdk_dmabuf_texture_builder_get_fd (builder, i);
self->stride[i] = gdk_dmabuf_texture_builder_get_stride (builder, i);
if (self->stride[i] == 0)
self->stride[i] = gdk_dmabuf_texture_builder_get_width (builder) *
gdk_memory_format_bytes_per_pixel (info->memory_format);
self->offset[i] = gdk_dmabuf_texture_builder_get_offset (builder, i);
}
memcpy (self->fds, gdk_dmabuf_texture_builder_get_fds (builder), sizeof (int) * 4);
memcpy (self->strides, gdk_dmabuf_texture_builder_get_strides (builder), sizeof (unsigned int) * 4);
memcpy (self->offsets, gdk_dmabuf_texture_builder_get_offsets (builder), sizeof (unsigned int) * 4);
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
if (update_texture)
@@ -373,24 +371,27 @@ gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture)
}
unsigned int
gdk_dmabuf_texture_get_offset (GdkDmabufTexture *texture,
int plane)
gdk_dmabuf_texture_get_n_planes (GdkDmabufTexture *texture)
{
return texture->offset[plane];
return texture->n_planes;
}
unsigned int
gdk_dmabuf_texture_get_stride (GdkDmabufTexture *texture,
int plane)
int *
gdk_dmabuf_texture_get_fds (GdkDmabufTexture *texture)
{
return texture->stride[plane];
return texture->fds;
}
int
gdk_dmabuf_texture_get_fd (GdkDmabufTexture *texture,
int plane)
unsigned int *
gdk_dmabuf_texture_get_strides (GdkDmabufTexture *texture)
{
return texture->fd[plane];
return texture->strides;
}
unsigned int *
gdk_dmabuf_texture_get_offsets (GdkDmabufTexture *texture)
{
return texture->offsets;
}
#endif /* __linux__ */

View File

@@ -38,10 +38,12 @@ struct _GdkDmabufTextureBuilder
unsigned int fourcc;
guint64 modifier;
unsigned int n_planes;
/* per-plane properties */
int fd[4];
unsigned int stride[4];
unsigned int offset[4];
int fds[4];
unsigned int strides[4];
unsigned int offsets[4];
GdkTexture *update_texture;
cairo_region_t *update_region;
@@ -83,6 +85,7 @@ enum
PROP_HEIGHT,
PROP_FOURCC,
PROP_MODIFIER,
PROP_N_PLANES,
PROP_FD0,
PROP_FD1,
PROP_FD2,
@@ -146,52 +149,56 @@ gdk_dmabuf_texture_builder_get_property (GObject *object,
g_value_set_uint64 (value, self->modifier);
break;
case PROP_N_PLANES:
g_value_set_uint (value, self->n_planes);
break;
case PROP_FD0:
g_value_set_int (value, self->fd[0]);
g_value_set_int (value, self->fds[0]);
break;
case PROP_FD1:
g_value_set_int (value, self->fd[1]);
g_value_set_int (value, self->fds[1]);
break;
case PROP_FD2:
g_value_set_int (value, self->fd[2]);
g_value_set_int (value, self->fds[2]);
break;
case PROP_FD3:
g_value_set_int (value, self->fd[3]);
g_value_set_int (value, self->fds[3]);
break;
case PROP_STRIDE0:
g_value_set_uint (value, self->stride[0]);
g_value_set_uint (value, self->strides[0]);
break;
case PROP_STRIDE1:
g_value_set_uint (value, self->stride[1]);
g_value_set_uint (value, self->strides[1]);
break;
case PROP_STRIDE2:
g_value_set_uint (value, self->stride[2]);
g_value_set_uint (value, self->strides[2]);
break;
case PROP_STRIDE3:
g_value_set_uint (value, self->stride[3]);
g_value_set_uint (value, self->strides[3]);
break;
case PROP_OFFSET0:
g_value_set_uint (value, self->offset[0]);
g_value_set_uint (value, self->offsets[0]);
break;
case PROP_OFFSET1:
g_value_set_uint (value, self->offset[1]);
g_value_set_uint (value, self->offsets[1]);
break;
case PROP_OFFSET2:
g_value_set_uint (value, self->offset[2]);
g_value_set_uint (value, self->offsets[2]);
break;
case PROP_OFFSET3:
g_value_set_uint (value, self->offset[3]);
g_value_set_uint (value, self->offsets[3]);
break;
case PROP_UPDATE_REGION:
@@ -238,6 +245,10 @@ gdk_dmabuf_texture_builder_set_property (GObject *object,
gdk_dmabuf_texture_builder_set_modifier (self, g_value_get_uint64 (value));
break;
case PROP_N_PLANES:
gdk_dmabuf_texture_builder_set_n_planes (self, g_value_get_uint (value));
break;
case PROP_FD0:
gdk_dmabuf_texture_builder_set_fd (self, 0, g_value_get_int (value));
break;
@@ -369,6 +380,21 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:n-planes: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_n_planes org.gdk.Property.set=gdk_dmabuf_texture_builder_set_n_planes)
*
* The number of planes of the texture.
*
* Note that you can set properties for other planes,
* but they will be ignored when constructing the texture.
*
* Since: 4.14
*/
properties[PROP_N_PLANES] =
g_param_spec_uint ("n-planes", NULL, NULL,
0, 4, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fd0:
*
@@ -543,7 +569,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
static void
gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self)
{
self->fd[0] = self->fd[1] = self->fd[2] = self->fd[3] = -1;
self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1;
}
/**
@@ -780,6 +806,47 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODIFIER]);
}
/**
* gdk_dmabuf_texture_builder_get_n_planes: (attributes org.gdk.Method.get_property=n-planes)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the number of planes.
*
* Returns: The number of planes
*
* Since: 4.14
*/
unsigned int
gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->n_planes;
}
/**
* gdk_dmabuf_texture_builder_set_n_planes: (attributes org.gdk.Method.set_property=n-planes)
* @self: a `GdkDmabufTextureBuilder`
* @n_planes: the number of planes
*
* Sets the number of planes of the texture.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->n_planes == n_planes)
return;
self->n_planes = n_planes;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_PLANES]);
}
/**
* gdk_dmabuf_texture_builder_get_fd:
* @self: a `GdkDmabufTextureBuilder`
@@ -798,7 +865,7 @@ gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->fd[plane];
return self->fds[plane];
}
/**
@@ -819,10 +886,10 @@ gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < 4);
if (self->fd[plane] == fd)
if (self->fds[plane] == fd)
return;
self->fd[plane] = fd;
self->fds[plane] = fd;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FD0 + plane]);
}
@@ -845,7 +912,7 @@ gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->stride[plane];
return self->strides[plane];
}
/**
@@ -868,10 +935,10 @@ gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < 4);
if (self->stride[plane] == stride)
if (self->strides[plane] == stride)
return;
self->stride[plane] = stride;
self->strides[plane] = stride;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STRIDE0 + plane]);
}
@@ -894,7 +961,7 @@ gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->offset[plane];
return self->offsets[plane];
}
/**
@@ -915,10 +982,10 @@ gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < 4);
if (self->offset[plane] == offset)
if (self->offsets[plane] == offset)
return;
self->offset[plane] = offset;
self->offsets[plane] = offset;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OFFSET0 + plane]);
}
@@ -1053,7 +1120,10 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
g_return_val_if_fail (self->fourcc != 0, NULL);
g_return_val_if_fail (self->fd[0] != -1, NULL);
g_return_val_if_fail (self->n_planes > 0, NULL);
for (int i = 0; i < self->n_planes; i++)
g_return_val_if_fail (self->fds[i] != -1 || self->offsets[i] != 0, NULL);
#ifdef __linux__
return gdk_dmabuf_texture_new_from_builder (self, destroy, data);
@@ -1061,3 +1131,21 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
return NULL;
#endif
}
int *
gdk_dmabuf_texture_builder_get_fds (GdkDmabufTextureBuilder *self)
{
return self->fds;
}
unsigned int *
gdk_dmabuf_texture_builder_get_strides (GdkDmabufTextureBuilder *self)
{
return self->strides;
}
unsigned int *
gdk_dmabuf_texture_builder_get_offsets (GdkDmabufTextureBuilder *self)
{
return self->offsets;
}

View File

@@ -64,6 +64,12 @@ GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes);
GDK_AVAILABLE_IN_4_14
int gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
int plane) G_GNUC_PURE;

View File

@@ -7,18 +7,20 @@
G_BEGIN_DECLS
int * gdk_dmabuf_texture_builder_get_fds (GdkDmabufTextureBuilder *builder);
unsigned int * gdk_dmabuf_texture_builder_get_offsets (GdkDmabufTextureBuilder *builder);
unsigned int * gdk_dmabuf_texture_builder_get_strides (GdkDmabufTextureBuilder *builder);
GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data);
unsigned int gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture);
guint64 gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture);
int gdk_dmabuf_texture_get_fd (GdkDmabufTexture *texture,
int plane);
unsigned int gdk_dmabuf_texture_get_offset (GdkDmabufTexture *texture,
int plane);
unsigned int gdk_dmabuf_texture_get_stride (GdkDmabufTexture *texture,
int plane);
unsigned int gdk_dmabuf_texture_get_n_planes (GdkDmabufTexture *texture);
int * gdk_dmabuf_texture_get_fds (GdkDmabufTexture *texture);
unsigned int * gdk_dmabuf_texture_get_offsets (GdkDmabufTexture *texture);
unsigned int * gdk_dmabuf_texture_get_strides (GdkDmabufTexture *texture);
gboolean gdk_dmabuf_texture_may_support (unsigned int fourcc);