diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 1bfc2d2a8a..3db0dc206a 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1839,7 +1839,7 @@ gdk_display_get_egl_display (GdkDisplay *self) #endif } -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF static void gdk_display_add_dmabuf_downloader (GdkDisplay *display, const GdkDmabufDownloader *downloader, @@ -1847,7 +1847,8 @@ gdk_display_add_dmabuf_downloader (GdkDisplay *display, { gsize i; - downloader->add_formats (downloader, display, builder); + if (!downloader->add_formats (downloader, display, builder)) + return; /* dmabuf_downloaders is NULL-terminated */ for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++) @@ -1876,7 +1877,7 @@ gdk_display_init_dmabuf (GdkDisplay *self) builder = gdk_dmabuf_formats_builder_new (); -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF if (!GDK_DEBUG_CHECK (DMABUF_DISABLE)) { gdk_display_prepare_gl (self, NULL); diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index be723e4914..4b17fe563f 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -24,7 +24,7 @@ #include "gdkdmabuftextureprivate.h" #include "gdkmemoryformatprivate.h" -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF #include #include #include @@ -264,7 +264,7 @@ get_drm_format_info (guint32 fourcc) return NULL; } -static void +static gboolean gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, GdkDisplay *display, GdkDmabufFormatsBuilder *builder) @@ -277,6 +277,8 @@ gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, supported_formats[i].fourcc, DRM_FORMAT_MOD_LINEAR); } + + return TRUE; } static gboolean @@ -482,6 +484,14 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, return FALSE; } + if (src->modifier == DRM_FORMAT_MOD_INVALID) + { + g_set_error (error, + GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, + "GTK does not support the INVALID modifier."); + return FALSE; + } + info = get_drm_format_info (src->fourcc); if (info == NULL) @@ -495,7 +505,7 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, *dest = *src; - if (src->modifier && src->modifier != DRM_FORMAT_MOD_INVALID) + if (src->modifier) return TRUE; switch (dest->fourcc) @@ -517,4 +527,27 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, return TRUE; } -#endif /* HAVE_LINUX_DMA_BUF_H */ +/* + * gdk_dmabuf_is_disjoint: + * @dmabuf: a sanitized GdkDmabuf + * + * A dmabuf is considered disjoint if it uses more than + * 1 file descriptor. + * + * Returns: %TRUE if the dmabuf is disjoint + **/ +gboolean +gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf) +{ + unsigned i; + + for (i = 1; i < dmabuf->n_planes; i++) + { + if (dmabuf->planes[0].fd != dmabuf->planes[i].fd) + return TRUE; + } + + return FALSE; +} + +#endif /* HAVE_DMABUF */ diff --git a/gdk/gdkdmabufformatsbuilder.c b/gdk/gdkdmabufformatsbuilder.c index 249abd39c1..223eada0a7 100644 --- a/gdk/gdkdmabufformatsbuilder.c +++ b/gdk/gdkdmabufformatsbuilder.c @@ -22,6 +22,10 @@ #include "gdkdmabufformatsprivate.h" +#ifdef HAVE_DMABUF +#include +#endif + #define GDK_ARRAY_NAME gdk_dmabuf_formats_builder #define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder #define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat @@ -117,6 +121,12 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self, guint32 fourcc, guint64 modifier) { +#ifdef HAVE_DMABUF + g_return_if_fail (modifier != DRM_FORMAT_MOD_INVALID); +#else + g_return_if_reached (); +#endif + gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier }); } diff --git a/gdk/gdkdmabufprivate.h b/gdk/gdkdmabufprivate.h index 5bca5e16b1..33ff1398c5 100644 --- a/gdk/gdkdmabufprivate.h +++ b/gdk/gdkdmabufprivate.h @@ -22,7 +22,7 @@ struct _GdkDmabuf struct _GdkDmabufDownloader { const char *name; - void (* add_formats) (const GdkDmabufDownloader *downloader, + gboolean (* add_formats) (const GdkDmabufDownloader *downloader, GdkDisplay *display, GdkDmabufFormatsBuilder *builder); @@ -39,7 +39,7 @@ struct _GdkDmabufDownloader gsize stride); }; -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST; @@ -48,4 +48,6 @@ gboolean gdk_dmabuf_sanitize (GdkDmabuf gsize height, const GdkDmabuf *src, GError **error); +gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf); + #endif diff --git a/gdk/gdkdmabuftexture.c b/gdk/gdkdmabuftexture.c index 5841f42dad..97bb473bd9 100644 --- a/gdk/gdkdmabuftexture.c +++ b/gdk/gdkdmabuftexture.c @@ -28,7 +28,7 @@ #include #include -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF #include #include #include @@ -129,7 +129,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, gpointer data, GError **error) { -#ifdef HAVE_LINUX_DMA_BUF_H +#ifdef HAVE_DMABUF GdkDmabufTexture *self; GdkTexture *update_texture; GdkDisplay *display; @@ -210,7 +210,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, return GDK_TEXTURE (self); -#else /* !HAVE_LINUX_DMA_BUF_H */ +#else /* !HAVE_DMABUF */ g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE, "dmabuf support disabled at compile-time."); return NULL; diff --git a/gdk/gdkdmabuftexturebuilder.c b/gdk/gdkdmabuftexturebuilder.c index 25979287e6..8301f37308 100644 --- a/gdk/gdkdmabuftexturebuilder.c +++ b/gdk/gdkdmabuftexturebuilder.c @@ -27,6 +27,11 @@ #include "gdkdmabuftextureprivate.h" #include +#ifdef HAVE_DMABUF +#include +#else +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif struct _GdkDmabufTextureBuilder @@ -598,6 +603,13 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self, guint64 modifier) { g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); + if (modifier == DRM_FORMAT_MOD_INVALID) + { + g_critical ("GTK does not support the INVALID modifier. " + "If you use code that produces it, it should include " + "instructions how to transform it into a regular modifier."); + return; + } if (self->dmabuf.modifier == modifier) return; diff --git a/meson.build b/meson.build index 60cfb3974a..666332e1a6 100644 --- a/meson.build +++ b/meson.build @@ -162,7 +162,6 @@ check_headers = [ 'inttypes.h', 'linux/input.h', 'linux/memfd.h', - 'linux/dma-buf.h', 'locale.h', 'memory.h', 'stdint.h', @@ -186,8 +185,12 @@ foreach h : check_headers endif endforeach -if os_linux and not cc.has_header('linux/dma-buf.h') - error('OS is Linux, but linux/dma-buf.h not found.') +if cc.has_header('linux/dma-buf.h') and cc.has_header('drm/drm_fourcc.h') + cdata.set('HAVE_DMABUF', 1) +else + if os_linux + error('OS is Linux, but linux/dma-buf.h and drm/drm-fourcc.h not found.') + endif endif # Maths functions might be implemented in libm