From 1ca067a4782d5c8738249547af394aefa447f912 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 14 Oct 2023 21:57:15 +0200 Subject: [PATCH] dmabuf: Add a GError to gdk_dmabuf_texture_builder_build() --- gdk/gdkdmabuftexture.c | 21 +++++++++++++++++---- gdk/gdkdmabuftexture.h | 5 +++++ gdk/gdkdmabuftexturebuilder.c | 17 +++++++++++------ gdk/gdkdmabuftexturebuilder.h | 3 ++- gdk/gdkdmabuftextureprivate.h | 3 ++- gdk/gdkenums.h | 16 ++++++++++++++++ 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/gdk/gdkdmabuftexture.c b/gdk/gdkdmabuftexture.c index 52adf8cabb..3bd74272d4 100644 --- a/gdk/gdkdmabuftexture.c +++ b/gdk/gdkdmabuftexture.c @@ -72,6 +72,8 @@ struct _GdkDmabufTextureClass GdkTextureClass parent_class; }; +G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error) + G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE) static void @@ -267,7 +269,8 @@ gdk_dmabuf_texture_download (GdkTexture *texture, GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, GDestroyNotify destroy, - gpointer data) + gpointer data, + GError **error) { #ifdef HAVE_LINUX_DMA_BUF_H GdkDmabufTexture *self; @@ -281,10 +284,18 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, info = get_drm_format_info (fourcc); - if (!info || modifier != DRM_FORMAT_MOD_LINEAR || n_planes > 1) + if (!info || modifier != DRM_FORMAT_MOD_LINEAR) { - g_warning ("Unsupported dmabuf format %c%c%c%c:%#lx", - fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier); + g_set_error (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, + "Unsupported dmabuf format %c%c%c%c:%#lx", + fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, 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 %c%c%c%c:%#lx", + fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier); return NULL; } @@ -331,6 +342,8 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, return GDK_TEXTURE (self); #else /* !HAVE_LINUX_DMA_BUF_H */ + g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE, + "dmabuf support disabled at compile-time."); return NULL; #endif } diff --git a/gdk/gdkdmabuftexture.h b/gdk/gdkdmabuftexture.h index a9ec4cf8b3..ae5c23d2b4 100644 --- a/gdk/gdkdmabuftexture.h +++ b/gdk/gdkdmabuftexture.h @@ -32,12 +32,17 @@ G_BEGIN_DECLS #define GDK_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DMABUF_TEXTURE, GdkDmabufTexture)) #define GDK_IS_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DMABUF_TEXTURE)) +#define GDK_DMABUF_ERROR (gdk_dmabuf_error_quark ()) + typedef struct _GdkDmabufTexture GdkDmabufTexture; typedef struct _GdkDmabufTextureClass GdkDmabufTextureClass; GDK_AVAILABLE_IN_4_14 GType gdk_dmabuf_texture_get_type (void) G_GNUC_CONST; +GDK_AVAILABLE_IN_4_14 +GQuark gdk_dmabuf_error_quark (void) G_GNUC_CONST; + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDmabufTexture, g_object_unref) G_END_DECLS diff --git a/gdk/gdkdmabuftexturebuilder.c b/gdk/gdkdmabuftexturebuilder.c index 0e61855813..6b72f7ccc4 100644 --- a/gdk/gdkdmabuftexturebuilder.c +++ b/gdk/gdkdmabuftexturebuilder.c @@ -932,14 +932,17 @@ gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self, * @destroy: (nullable): destroy function to be called when the texture is * released * @data: user data to pass to the destroy function + * @error: Return location for an error * * Builds a new `GdkTexture` with the values set up in the builder. * - * The `destroy` function gets called when the returned texture gets released. - * - * Note that it is a programming error to call this function if any mandatory + * It is a programming error to call this function if any mandatory * property has not been set. * + * If the dmabuf is not supported by GTK, %NULL will be returned and @error will be set. + * + * The `destroy` function gets called when the returned texture gets released. + * * It is possible to call this function multiple times to create multiple textures, * possibly with changing properties in between. * @@ -957,11 +960,13 @@ gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self, */ GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, - GDestroyNotify destroy, - gpointer data) + GDestroyNotify destroy, + gpointer data, + GError **error) { g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL); g_return_val_if_fail (destroy == NULL || data != NULL, NULL); + 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); @@ -970,7 +975,7 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, for (int i = 0; i < self->n_planes; i++) g_return_val_if_fail (self->fds[i] != -1 || self->offsets[i] != 0, NULL); - return gdk_dmabuf_texture_new_from_builder (self, destroy, data); + return gdk_dmabuf_texture_new_from_builder (self, destroy, data, error); } int * diff --git a/gdk/gdkdmabuftexturebuilder.h b/gdk/gdkdmabuftexturebuilder.h index 0570aa8d73..88ecfea5cf 100644 --- a/gdk/gdkdmabuftexturebuilder.h +++ b/gdk/gdkdmabuftexturebuilder.h @@ -115,7 +115,8 @@ void gdk_dmabuf_texture_builder_set_update_region (GdkDmabuf GDK_AVAILABLE_IN_4_14 GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, GDestroyNotify destroy, - gpointer data); + gpointer data, + GError **error); G_END_DECLS diff --git a/gdk/gdkdmabuftextureprivate.h b/gdk/gdkdmabuftextureprivate.h index 973705a4dd..d8667dc39a 100644 --- a/gdk/gdkdmabuftextureprivate.h +++ b/gdk/gdkdmabuftextureprivate.h @@ -18,7 +18,8 @@ unsigned int * gdk_dmabuf_texture_builder_get_strides (GdkDmabufTextur GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, GDestroyNotify destroy, - gpointer data); + gpointer data, + GError **error); guint32 gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture); guint64 gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture); diff --git a/gdk/gdkenums.h b/gdk/gdkenums.h index c03cf9f7c7..9ccb651742 100644 --- a/gdk/gdkenums.h +++ b/gdk/gdkenums.h @@ -142,6 +142,22 @@ typedef enum GDK_BUTTON4_MASK|GDK_BUTTON5_MASK) +/** + * GdkDmabufError: + * @GDK_DMABUF_ERROR_NOT_AVAILABLE: Dmabuf support is not available, because the OS + * is not Linux, or it was explicitly disabled at compile- or runtime + * @GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT: The requested format is not supported + * @GDK_DMABUF_ERROR_CREATION_FAILED: GTK failed to create the resource for other + * reasons + * + * Error enumeration for `GdkDmabufTexture`. + */ +typedef enum { + GDK_DMABUF_ERROR_NOT_AVAILABLE, + GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, + GDK_DMABUF_ERROR_CREATION_FAILED, +} GdkDmabufError; + /** * GdkGLError: * @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available