From a9fb224b8d7bddbccc12c57fd75bfd6a0dcb193f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 9 Oct 2023 08:22:14 -0400 Subject: [PATCH] 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. --- gdk/gdkdmabuftexture.c | 67 ++++++++-------- gdk/gdkdmabuftexturebuilder.c | 140 +++++++++++++++++++++++++++------- gdk/gdkdmabuftexturebuilder.h | 6 ++ gdk/gdkdmabuftextureprivate.h | 14 ++-- 4 files changed, 162 insertions(+), 65 deletions(-) diff --git a/gdk/gdkdmabuftexture.c b/gdk/gdkdmabuftexture.c index 50d7ed54ff..033adb1089 100644 --- a/gdk/gdkdmabuftexture.c +++ b/gdk/gdkdmabuftexture.c @@ -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__ */ diff --git a/gdk/gdkdmabuftexturebuilder.c b/gdk/gdkdmabuftexturebuilder.c index f13e54bc39..182054b283 100644 --- a/gdk/gdkdmabuftexturebuilder.c +++ b/gdk/gdkdmabuftexturebuilder.c @@ -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; +} diff --git a/gdk/gdkdmabuftexturebuilder.h b/gdk/gdkdmabuftexturebuilder.h index 59f0903fc7..dc8f2e35ec 100644 --- a/gdk/gdkdmabuftexturebuilder.h +++ b/gdk/gdkdmabuftexturebuilder.h @@ -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; diff --git a/gdk/gdkdmabuftextureprivate.h b/gdk/gdkdmabuftextureprivate.h index ab23afea6f..565a405764 100644 --- a/gdk/gdkdmabuftextureprivate.h +++ b/gdk/gdkdmabuftextureprivate.h @@ -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);