diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 2e75be10eb..a601bd4c37 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1839,6 +1839,29 @@ gdk_display_get_egl_display (GdkDisplay *self) #endif } +#ifdef HAVE_LINUX_DMA_BUF_H +static void +gdk_display_add_dmabuf_downloader (GdkDisplay *display, + const GdkDmabufDownloader *downloader, + GdkDmabufFormatsBuilder *builder) +{ + gsize i; + + downloader->add_formats (downloader, display, builder); + + /* dmabuf_downloaders is NULL-terminated */ + for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++) + { + if (display->dmabuf_downloaders[i] == NULL) + break; + } + + g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders)); + + display->dmabuf_downloaders[i] = downloader; +} +#endif + /* To support a drm format, we must be able to import it into GL * using the relevant EGL extensions, and download it into a memory * texture, possibly doing format conversion with shaders (in GSK). @@ -1853,15 +1876,17 @@ init_dmabuf_formats (GdkDisplay *display) builder = gdk_dmabuf_formats_builder_new (); +#ifdef HAVE_LINUX_DMA_BUF_H if (!GDK_DEBUG_CHECK (DMABUF_DISABLE)) { gdk_display_prepare_gl (display, NULL); - gdk_dmabuf_texture_add_supported_formats (builder); + gdk_display_add_dmabuf_downloader (display, gdk_dmabuf_get_direct_downloader (), builder); } +#endif display->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder); -} +} /** * gdk_display_get_dmabuf_formats: diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index e8a1c949f2..d581c58425 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -25,7 +25,7 @@ #include "gdksurfaceprivate.h" #include "gdkkeysprivate.h" #include "gdkdeviceprivate.h" -#include "gdkdmabufformats.h" +#include "gdkdmabufprivate.h" #ifdef GDK_RENDERING_VULKAN #include @@ -116,6 +116,7 @@ struct _GdkDisplay guint have_egl_pixel_format_float : 1; GdkDmabufFormats *dmabuf_formats; + const GdkDmabufDownloader *dmabuf_downloaders[4]; }; struct _GdkDisplayClass diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c new file mode 100644 index 0000000000..de21b08d2b --- /dev/null +++ b/gdk/gdkdmabuf.c @@ -0,0 +1,198 @@ +/* gdkdmabuf.c + * + * Copyright 2023 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gdkdmabufprivate.h" + +#include "gdkdebugprivate.h" +#include "gdkdmabuftextureprivate.h" +#include "gdkmemoryformatprivate.h" + +#ifdef HAVE_LINUX_DMA_BUF_H +#include +#include +#include +#include +#include + +typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo; +struct _GdkDrmFormatInfo +{ + guint32 fourcc; + GdkMemoryFormat premultiplied_memory_format; + GdkMemoryFormat unpremultiplied_memory_format; +}; + +static GdkDrmFormatInfo supported_formats[] = { + { DRM_FORMAT_ARGB8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8 }, + { DRM_FORMAT_RGBA8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8 }, + { DRM_FORMAT_BGRA8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8 }, + { DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT }, + { DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8 }, + { DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8 }, +}; + +static GdkDrmFormatInfo * +get_drm_format_info (guint32 fourcc) +{ + for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++) + { + if (supported_formats[i].fourcc == fourcc) + return &supported_formats[i]; + } + + return NULL; +} + +static void +gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, + GdkDisplay *display, + GdkDmabufFormatsBuilder *builder) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS (supported_formats); i++) + { + gdk_dmabuf_formats_builder_add_format (builder, + supported_formats[i].fourcc, + DRM_FORMAT_MOD_LINEAR); + } +} + +static gboolean +gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader, + GdkDisplay *display, + const GdkDmabuf *dmabuf, + gboolean premultiplied, + GdkMemoryFormat *out_format, + GError **error) +{ + GdkDrmFormatInfo *info; + + info = get_drm_format_info (dmabuf->fourcc); + + if (!info || dmabuf->modifier != DRM_FORMAT_MOD_LINEAR) + { + g_set_error (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, + "Unsupported dmabuf format %.4s:%#lx", + (char *) &dmabuf->fourcc, dmabuf->modifier); + return FALSE; + } + if (dmabuf->n_planes > 1) + { + g_set_error (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_CREATION_FAILED, + "Cannot create multiplanar textures for dmabuf format %.4s:%#lx", + (char *) &dmabuf->fourcc, dmabuf->modifier); + return FALSE; + } + + *out_format = premultiplied ? info->premultiplied_memory_format + : info->unpremultiplied_memory_format; + + return TRUE; +} + +static void +gdk_dmabuf_direct_downloader_do_download (GdkTexture *texture, + guchar *data, + gsize stride) +{ + const GdkDmabuf *dmabuf; + gsize size; + unsigned int height; + gsize src_stride; + guchar *src_data; + int bpp; + + GDK_DEBUG (DMABUF, "Using mmap() and memcpy() for downloading a dmabuf"); + + dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)); + height = gdk_texture_get_height (texture); + bpp = gdk_memory_format_bytes_per_pixel (gdk_texture_get_format (texture)); + + src_stride = dmabuf->planes[0].stride; + size = dmabuf->planes[0].stride * height; + + if (ioctl (dmabuf->planes[0].fd, 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, dmabuf->planes[0].fd, dmabuf->planes[0].offset); + + if (stride == src_stride) + memcpy (data, src_data, size); + else + { + for (unsigned int i = 0; i < height; i++) + memcpy (data + i * stride, src_data + i * src_stride, height * bpp); + } + + munmap (src_data, size); + + if (ioctl (dmabuf->planes[0].fd, 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)); +} + +static void +gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader, + GdkTexture *texture, + GdkMemoryFormat format, + guchar *data, + gsize stride) +{ + GdkMemoryFormat src_format = gdk_texture_get_format (texture); + + if (format == src_format) + gdk_dmabuf_direct_downloader_do_download (texture, data, stride); + else + { + const GdkDmabuf *dmabuf; + unsigned int width, height; + guchar *src_data; + gsize src_stride; + + dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)); + width = gdk_texture_get_width (texture); + height = gdk_texture_get_height (texture); + + src_stride = dmabuf->planes[0].stride; + src_data = g_new (guchar, src_stride * height); + + gdk_dmabuf_direct_downloader_do_download (texture, src_data, src_stride); + + gdk_memory_convert (data, stride, format, + src_data, src_stride, src_format, + width, height); + + g_free (src_data); + } +} + +const GdkDmabufDownloader * +gdk_dmabuf_get_direct_downloader (void) +{ + static const GdkDmabufDownloader downloader = { + gdk_dmabuf_direct_downloader_add_formats, + gdk_dmabuf_direct_downloader_supports, + gdk_dmabuf_direct_downloader_download, + }; + + return &downloader; +} + +#endif /* HAVE_LINUX_DMA_BUF_H */ diff --git a/gdk/gdkdmabufprivate.h b/gdk/gdkdmabufprivate.h new file mode 100644 index 0000000000..b1c90a9c79 --- /dev/null +++ b/gdk/gdkdmabufprivate.h @@ -0,0 +1,44 @@ +#pragma once + +#include "gdkdmabufformatsbuilderprivate.h" + +#define GDK_DMABUF_MAX_PLANES 4 + +typedef struct _GdkDmabuf GdkDmabuf; +typedef struct _GdkDmabufDownloader GdkDmabufDownloader; + +struct _GdkDmabuf +{ + guint32 fourcc; + guint64 modifier; + unsigned int n_planes; + struct { + int fd; + unsigned int stride; + unsigned int offset; + } planes[GDK_DMABUF_MAX_PLANES]; +}; + +struct _GdkDmabufDownloader +{ + void (* add_formats) (const GdkDmabufDownloader *downloader, + GdkDisplay *display, + GdkDmabufFormatsBuilder *builder); + + gboolean (* supports) (const GdkDmabufDownloader *downloader, + GdkDisplay *display, + const GdkDmabuf *dmabuf, + gboolean premultiplied, + GdkMemoryFormat *out_format, + GError **error); + void (* download) (const GdkDmabufDownloader *downloader, + GdkTexture *texture, + GdkMemoryFormat format, + guchar *data, + gsize stride); +}; + +#ifdef HAVE_LINUX_DMA_BUF_H +const GdkDmabufDownloader * + gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST; +#endif diff --git a/gdk/gdkdmabuftexture.c b/gdk/gdkdmabuftexture.c index 777ff53e98..bde7918c35 100644 --- a/gdk/gdkdmabuftexture.c +++ b/gdk/gdkdmabuftexture.c @@ -22,8 +22,7 @@ #include "gdkdisplayprivate.h" #include "gdkdmabufformatsbuilderprivate.h" -#include "gdkmemoryformatprivate.h" -#include "gdkmemorytextureprivate.h" +#include "gdktextureprivate.h" #include #include #include @@ -52,16 +51,9 @@ struct _GdkDmabufTexture GdkTexture parent_instance; GdkDisplay *display; + const GdkDmabufDownloader *downloader; - guint32 fourcc; - guint64 modifier; - - unsigned int n_planes; - - /* Per-plane properties */ - int fds[MAX_DMABUF_PLANES]; - unsigned int strides[MAX_DMABUF_PLANES]; - unsigned int offsets[MAX_DMABUF_PLANES]; + GdkDmabuf dmabuf; GDestroyNotify destroy; gpointer data; @@ -79,7 +71,6 @@ G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE) static void gdk_dmabuf_texture_init (GdkDmabufTexture *self) { - self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1; } static void @@ -93,10 +84,20 @@ gdk_dmabuf_texture_dispose (GObject *object) G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object); } -static void gdk_dmabuf_texture_download (GdkTexture *texture, - GdkMemoryFormat format, - guchar *data, - gsize stride); +static void +gdk_dmabuf_texture_download (GdkTexture *texture, + GdkMemoryFormat format, + guchar *data, + gsize stride) +{ + GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture); + + self->downloader->download (self->downloader, + texture, + format, + data, + stride); +} static void gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass) @@ -109,161 +110,10 @@ gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass) gobject_class->dispose = gdk_dmabuf_texture_dispose; } -guint32 -gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture) +const GdkDmabuf * +gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self) { - return texture->fourcc; -} - -guint64 -gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture) -{ - return texture->modifier; -} - -unsigned int -gdk_dmabuf_texture_get_n_planes (GdkDmabufTexture *texture) -{ - return texture->n_planes; -} - -int * -gdk_dmabuf_texture_get_fds (GdkDmabufTexture *texture) -{ - return texture->fds; -} - -unsigned int * -gdk_dmabuf_texture_get_strides (GdkDmabufTexture *texture) -{ - return texture->strides; -} - -unsigned int * -gdk_dmabuf_texture_get_offsets (GdkDmabufTexture *texture) -{ - return texture->offsets; -} - -#ifdef HAVE_LINUX_DMA_BUF_H - -typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo; -struct _GdkDrmFormatInfo -{ - guint32 fourcc; - GdkMemoryFormat premultiplied_memory_format; - GdkMemoryFormat unpremultiplied_memory_format; -}; - -static GdkDrmFormatInfo supported_formats[] = { - { DRM_FORMAT_ARGB8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8 }, - { DRM_FORMAT_RGBA8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8 }, - { DRM_FORMAT_BGRA8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8 }, - { DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT }, - { DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8 }, - { DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8 }, -}; - -static GdkDrmFormatInfo * -get_drm_format_info (guint32 fourcc) -{ - for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++) - { - if (supported_formats[i].fourcc == fourcc) - return &supported_formats[i]; - } - - return NULL; -} - -static void -do_direct_download (GdkDmabufTexture *self, - guchar *data, - gsize stride) -{ - gsize size; - unsigned int height; - gsize src_stride; - guchar *src_data; - int bpp; - - GDK_DEBUG (DMABUF, "Using mmap() and memcpy() for downloading a dmabuf"); - - 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->strides[0]; - size = self->strides[0] * height; - - 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->fds[0], self->offsets[0]); - - if (stride == src_stride) - memcpy (data, src_data, size); - else - { - for (unsigned int i = 0; i < height; i++) - memcpy (data + i * stride, src_data + i * src_stride, height * bpp); - } - - munmap (src_data, size); - - 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)); -} - -#endif /* HAVE_LINUX_DMA_BUF_H */ - -void -gdk_dmabuf_texture_add_supported_formats (GdkDmabufFormatsBuilder *builder) -{ -#ifdef HAVE_LINUX_DMA_BUF_H - gsize i; - - for (i = 0; i < G_N_ELEMENTS (supported_formats); i++) - { - gdk_dmabuf_formats_builder_add_format (builder, - supported_formats[i].fourcc, - DRM_FORMAT_MOD_LINEAR); - } -#endif -} - -static void -gdk_dmabuf_texture_download (GdkTexture *texture, - GdkMemoryFormat format, - guchar *data, - gsize stride) -{ -#ifdef HAVE_LINUX_DMA_BUF_H - GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture); - GdkMemoryFormat src_format = gdk_texture_get_format (texture); - - if (format == src_format) - do_direct_download (self, data, stride); - else - { - unsigned int width, height; - guchar *src_data; - gsize src_stride; - - width = gdk_texture_get_width (texture); - height = gdk_texture_get_height (texture); - - src_stride = self->strides[0]; - src_data = g_new (guchar, src_stride * height); - - do_direct_download (self, src_data, src_stride); - - gdk_memory_convert (data, stride, format, - src_data, src_stride, src_format, - width, height); - - g_free (src_data); - } -#endif /* HAVE_LINUX_DMA_BUF_H */ + return &self->dmabuf; } GdkTexture * @@ -275,54 +125,47 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, #ifdef HAVE_LINUX_DMA_BUF_H GdkDmabufTexture *self; GdkTexture *update_texture; - GdkDisplay *display = gdk_dmabuf_texture_builder_get_display (builder); - guint32 fourcc = gdk_dmabuf_texture_builder_get_fourcc (builder); - guint64 modifier = gdk_dmabuf_texture_builder_get_modifier (builder); - gboolean premultiplied = gdk_dmabuf_texture_builder_get_premultiplied (builder); - unsigned int n_planes = gdk_dmabuf_texture_builder_get_n_planes (builder); - GdkDrmFormatInfo *info; + GdkDisplay *display; + const GdkDmabuf *dmabuf; + GdkMemoryFormat format; + GError *local_error = NULL; + gsize i; - info = get_drm_format_info (fourcc); + display = gdk_dmabuf_texture_builder_get_display (builder); + dmabuf = gdk_dmabuf_texture_builder_get_dmabuf (builder); - if (!info || modifier != DRM_FORMAT_MOD_LINEAR) + for (i = 0; display->dmabuf_downloaders[i] != NULL; i++) { - g_set_error (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, - "Unsupported dmabuf format: %.4s:%#lx", - (char *) &fourcc, modifier); - return NULL; - } - if (n_planes > 1) - { - g_set_error (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_CREATION_FAILED, - "Cannot create multiplanar textures for dmabuf format: %.4s:%#lx", - (char *) &fourcc, modifier); - return NULL; + if (local_error && g_error_matches (local_error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT)) + g_clear_error (&local_error); + + if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i], + display, + dmabuf, + gdk_dmabuf_texture_builder_get_premultiplied (builder), + &format, + local_error ? NULL : &local_error)) + break; } - GDK_DEBUG (DMABUF, "Create dmabuf texture (format %.4s:%#lx)", - (char *) &fourcc, modifier); + if (display->dmabuf_downloaders[i] == NULL) + { + g_propagate_error (error, local_error); + return NULL; + } self = g_object_new (GDK_TYPE_DMABUF_TEXTURE, "width", gdk_dmabuf_texture_builder_get_width (builder), "height", gdk_dmabuf_texture_builder_get_height (builder), NULL); + GDK_TEXTURE (self)->format = format; + g_set_object (&self->display, display); + self->downloader = display->dmabuf_downloaders[i]; + self->dmabuf = *dmabuf; self->destroy = destroy; self->data = data; - GDK_TEXTURE (self)->format = premultiplied ? info->premultiplied_memory_format - : info->unpremultiplied_memory_format; - - g_set_object (&self->display, display); - - self->fourcc = fourcc; - self->modifier = modifier; - self->n_planes = n_planes; - - memcpy (self->fds, gdk_dmabuf_texture_builder_get_fds (builder), sizeof (int) * MAX_DMABUF_PLANES); - memcpy (self->strides, gdk_dmabuf_texture_builder_get_strides (builder), sizeof (unsigned int) * MAX_DMABUF_PLANES); - memcpy (self->offsets, gdk_dmabuf_texture_builder_get_offsets (builder), sizeof (unsigned int) * MAX_DMABUF_PLANES); - update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder); if (update_texture) { @@ -347,3 +190,4 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, return NULL; #endif } + diff --git a/gdk/gdkdmabuftexturebuilder.c b/gdk/gdkdmabuftexturebuilder.c index 0167ed5173..421adc7741 100644 --- a/gdk/gdkdmabuftexturebuilder.c +++ b/gdk/gdkdmabuftexturebuilder.c @@ -36,16 +36,9 @@ struct _GdkDmabufTextureBuilder GdkDisplay *display; unsigned int width; unsigned int height; - guint32 fourcc; - guint64 modifier; gboolean premultiplied; - unsigned int n_planes; - - /* per-plane properties */ - int fds[MAX_DMABUF_PLANES]; - unsigned int strides[MAX_DMABUF_PLANES]; - unsigned int offsets[MAX_DMABUF_PLANES]; + GdkDmabuf dmabuf; GdkTexture *update_texture; cairo_region_t *update_region; @@ -162,11 +155,11 @@ gdk_dmabuf_texture_builder_get_property (GObject *object, break; case PROP_FOURCC: - g_value_set_uint (value, self->fourcc); + g_value_set_uint (value, self->dmabuf.fourcc); break; case PROP_MODIFIER: - g_value_set_uint64 (value, self->modifier); + g_value_set_uint64 (value, self->dmabuf.modifier); break; case PROP_PREMULTIPLIED: @@ -174,7 +167,7 @@ gdk_dmabuf_texture_builder_get_property (GObject *object, break; case PROP_N_PLANES: - g_value_set_uint (value, self->n_planes); + g_value_set_uint (value, self->dmabuf.n_planes); break; case PROP_UPDATE_REGION: @@ -371,8 +364,9 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass) static void gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self) { - self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1; self->premultiplied = TRUE; + for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++) + self->dmabuf.planes[i].fd = -1; } /** @@ -538,7 +532,7 @@ gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0); - return self->fourcc; + return self->dmabuf.fourcc; } /** @@ -560,10 +554,10 @@ gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self, { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - if (self->fourcc == fourcc) + if (self->dmabuf.fourcc == fourcc) return; - self->fourcc = fourcc; + self->dmabuf.fourcc = fourcc; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOURCC]); } @@ -583,7 +577,7 @@ gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0); - return self->modifier; + return self->dmabuf.modifier; } /** @@ -601,10 +595,10 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self, { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - if (self->modifier == modifier) + if (self->dmabuf.modifier == modifier) return; - self->modifier = modifier; + self->dmabuf.modifier = modifier; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODIFIER]); } @@ -624,7 +618,7 @@ 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; + return self->dmabuf.n_planes; } /** @@ -686,10 +680,10 @@ gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self, { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - if (self->n_planes == n_planes) + if (self->dmabuf.n_planes == n_planes) return; - self->n_planes = n_planes; + self->dmabuf.n_planes = n_planes; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_PLANES]); } @@ -710,9 +704,9 @@ gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self, unsigned int plane) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0); - g_return_val_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES, 0); + g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0); - return self->fds[plane]; + return self->dmabuf.planes[plane].fd; } /** @@ -731,12 +725,12 @@ gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self, int fd) { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - g_return_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES); + g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES); - if (self->fds[plane] == fd) + if (self->dmabuf.planes[plane].fd == fd) return; - self->fds[plane] = fd; + self->dmabuf.planes[plane].fd = fd; } /** @@ -755,9 +749,9 @@ gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self, unsigned int plane) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0); - g_return_val_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES, 0); + g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0); - return self->strides[plane]; + return self->dmabuf.planes[plane].stride; } /** @@ -778,12 +772,12 @@ gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self, unsigned int stride) { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - g_return_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES); + g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES); - if (self->strides[plane] == stride) + if (self->dmabuf.planes[plane].stride == stride) return; - self->strides[plane] = stride; + self->dmabuf.planes[plane].stride = stride; } /** @@ -802,9 +796,9 @@ gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self, unsigned int plane) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0); - g_return_val_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES, 0); + g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0); - return self->offsets[plane]; + return self->dmabuf.planes[plane].offset; } /** @@ -823,12 +817,12 @@ gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self, unsigned int offset) { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); - g_return_if_fail (0 <= plane && plane < MAX_DMABUF_PLANES); + g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES); - if (self->offsets[plane] == offset) + if (self->dmabuf.planes[plane].offset == offset) return; - self->offsets[plane] = offset; + self->dmabuf.planes[plane].offset = offset; } /** @@ -970,11 +964,11 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, g_return_val_if_fail (error == NULL || *error == NULL, NULL); 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->n_planes > 0, NULL); + g_return_val_if_fail (self->dmabuf.fourcc != 0, NULL); + g_return_val_if_fail (self->dmabuf.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); + for (int i = 0; i < self->dmabuf.n_planes; i++) + g_return_val_if_fail (self->dmabuf.planes[i].fd != -1 || self->dmabuf.planes[i].offset != 0, NULL); if (GDK_DEBUG_CHECK (DMABUF_DISABLE)) { @@ -986,20 +980,8 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, return gdk_dmabuf_texture_new_from_builder (self, destroy, data, error); } -int * -gdk_dmabuf_texture_builder_get_fds (GdkDmabufTextureBuilder *self) +const GdkDmabuf * +gdk_dmabuf_texture_builder_get_dmabuf (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; + return &self->dmabuf; } diff --git a/gdk/gdkdmabuftextureprivate.h b/gdk/gdkdmabuftextureprivate.h index d8667dc39a..bec9a21fbc 100644 --- a/gdk/gdkdmabuftextureprivate.h +++ b/gdk/gdkdmabuftextureprivate.h @@ -3,33 +3,18 @@ #include "gdkdmabuftexture.h" #include "gdkdmabuftexturebuilder.h" -#include "gdkdmabufformatsbuilderprivate.h" -#include "gdkdmabufformatsprivate.h" -#include "gdktextureprivate.h" -#include "gdkdisplay.h" +#include "gdkdmabufprivate.h" G_BEGIN_DECLS -#define MAX_DMABUF_PLANES 4 - -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); +const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder); GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, GDestroyNotify destroy, gpointer data, GError **error); -guint32 gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture); -guint64 gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture); -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); - -void gdk_dmabuf_texture_add_supported_formats (GdkDmabufFormatsBuilder *builder); - +const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self); G_END_DECLS diff --git a/gdk/meson.build b/gdk/meson.build index 2c4cc4aef1..30f63d0451 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -17,6 +17,7 @@ gdk_public_sources = files([ 'gdkdevicetool.c', 'gdkdisplay.c', 'gdkdisplaymanager.c', + 'gdkdmabuf.c', 'gdkdmabufformats.c', 'gdkdmabufformatsbuilder.c', 'gdkdmabuftexture.c',