diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index bdda9eaee5..b2103dacd6 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1925,12 +1925,13 @@ gdk_display_init_dmabuf (GdkDisplay *self) { gdk_display_prepare_gl (self, NULL); - gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder); - #ifdef HAVE_EGL if (gdk_display_prepare_gl (self, NULL)) gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder); #endif + + gdk_dmabuf_formats_builder_add_formats (builder, + gdk_dmabuf_get_mmap_formats ()); } #endif diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index 4ad05dc1ff..32af8d0146 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -649,65 +649,42 @@ gdk_dmabuf_get_fourcc (GdkMemoryFormat format, } } -static gboolean -gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, - GdkDisplay *display, - GdkDmabufFormatsBuilder *builder) +GdkDmabufFormats * +gdk_dmabuf_get_mmap_formats (void) { - gsize i; + static GdkDmabufFormats *formats = NULL; - for (i = 0; i < G_N_ELEMENTS (supported_formats); i++) + if (formats == NULL) { - GDK_DISPLAY_DEBUG (display, DMABUF, - "%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x", - downloader->name, - (char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR); + GdkDmabufFormatsBuilder *builder; + gsize i; - gdk_dmabuf_formats_builder_add_format (builder, - supported_formats[i].fourcc, - DRM_FORMAT_MOD_LINEAR); + builder = gdk_dmabuf_formats_builder_new (); + + for (i = 0; i < G_N_ELEMENTS (supported_formats); i++) + { + if (!supported_formats[i].download) + continue; + + GDK_DEBUG (DMABUF, + "mmap dmabuf format %.4s:%#0" G_GINT64_MODIFIER "x", + (char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR); + + gdk_dmabuf_formats_builder_add_format (builder, + supported_formats[i].fourcc, + DRM_FORMAT_MOD_LINEAR); + } + + formats = gdk_dmabuf_formats_builder_free_to_formats (builder); } - return TRUE; -} - -static gboolean -gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader, - GdkDisplay *display, - const GdkDmabuf *dmabuf, - gboolean premultiplied, - GError **error) -{ - const GdkDrmFormatInfo *info; - - info = get_drm_format_info (dmabuf->fourcc); - - if (!info || !info->download) - { - g_set_error (error, - GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, - "Unsupported dmabuf format %.4s", - (char *) &dmabuf->fourcc); - return FALSE; - } - - if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR) - { - g_set_error (error, - GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT, - "Unsupported dmabuf modifier %#lx (only linear buffers are supported)", - dmabuf->modifier); - return FALSE; - } - - return TRUE; + return formats; } static void -gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader, - GdkTexture *texture, - guchar *data, - gsize stride) +gdk_dmabuf_do_download_mmap (GdkTexture *texture, + guchar *data, + gsize stride) { const GdkDrmFormatInfo *info; const GdkDmabuf *dmabuf; @@ -722,8 +699,9 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader, g_return_if_fail (info && info->download); GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF, - "Using %s for downloading a dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)", - downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier); + "Using mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)", + gdk_texture_get_width (texture), gdk_texture_get_height (texture), + (char *)&dmabuf->fourcc, dmabuf->modifier); for (i = 0; i < dmabuf->n_planes; i++) { @@ -782,17 +760,16 @@ out: } } -static void -gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader, - GdkTexture *texture, - GdkMemoryFormat format, - guchar *data, - gsize stride) +void +gdk_dmabuf_download_mmap (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 (downloader, texture, data, stride); + gdk_dmabuf_do_download_mmap (texture, data, stride); else { unsigned int width, height; @@ -805,7 +782,7 @@ gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader, src_stride = width * gdk_memory_format_bytes_per_pixel (src_format); src_data = g_new (guchar, src_stride * height); - gdk_dmabuf_direct_downloader_do_download (downloader, texture, src_data, src_stride); + gdk_dmabuf_do_download_mmap (texture, src_data, src_stride); gdk_memory_convert (data, stride, format, src_data, src_stride, src_format, @@ -815,19 +792,6 @@ gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader, } } -const GdkDmabufDownloader * -gdk_dmabuf_get_direct_downloader (void) -{ - static const GdkDmabufDownloader downloader = { - "mmap", - gdk_dmabuf_direct_downloader_add_formats, - gdk_dmabuf_direct_downloader_supports, - gdk_dmabuf_direct_downloader_download, - }; - - return &downloader; -} - int gdk_dmabuf_ioctl (int fd, unsigned long request, diff --git a/gdk/gdkdmabufprivate.h b/gdk/gdkdmabufprivate.h index 031729bfd1..d46d5cd771 100644 --- a/gdk/gdkdmabufprivate.h +++ b/gdk/gdkdmabufprivate.h @@ -39,9 +39,15 @@ struct _GdkDmabufDownloader #ifdef HAVE_DMABUF -const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST; const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (void) G_GNUC_CONST; +GdkDmabufFormats * gdk_dmabuf_get_mmap_formats (void) G_GNUC_CONST; +void gdk_dmabuf_download_mmap (GdkTexture *texture, + GdkMemoryFormat format, + guchar *data, + gsize stride); + + int gdk_dmabuf_ioctl (int fd, unsigned long request, void *arg); diff --git a/gdk/gdkdmabuftexture.c b/gdk/gdkdmabuftexture.c index 3b222ef00d..f0dafe1d37 100644 --- a/gdk/gdkdmabuftexture.c +++ b/gdk/gdkdmabuftexture.c @@ -88,11 +88,10 @@ gdk_dmabuf_texture_download (GdkTexture *texture, { GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture); - self->downloader->download (self->downloader, - texture, - format, - data, - stride); + if (self->downloader) + self->downloader->download (self->downloader, texture, format, data, stride); + else + gdk_dmabuf_download_mmap (texture, format, data, stride); } static void @@ -126,6 +125,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, { #ifdef HAVE_DMABUF GdkDmabufTexture *self; + const GdkDmabufDownloader *downloader; GdkTexture *update_texture; GdkDisplay *display; GdkDmabuf dmabuf; @@ -149,23 +149,34 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, gdk_display_init_dmabuf (display); - for (i = 0; display->dmabuf_downloaders[i] != NULL; i++) + if (gdk_dmabuf_formats_contains (gdk_dmabuf_get_mmap_formats (), dmabuf.fourcc, dmabuf.modifier)) { - 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, - premultiplied, - local_error ? NULL : &local_error)) - break; + downloader = NULL; } - - if (display->dmabuf_downloaders[i] == NULL) + else { - g_propagate_error (error, local_error); - return NULL; + downloader = NULL; + for (i = 0; display->dmabuf_downloaders[i] != NULL; i++) + { + 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, + premultiplied, + local_error ? NULL : &local_error)) + { + downloader = display->dmabuf_downloaders[i]; + break; + } + } + + if (downloader == NULL) + { + g_propagate_error (error, local_error); + return NULL; + } } if (!gdk_dmabuf_get_memory_format (dmabuf.fourcc, premultiplied, &format)) @@ -183,7 +194,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "", dmabuf.n_planes, format, - display->dmabuf_downloaders[i]->name); + downloader ? downloader->name : "none"); self = g_object_new (GDK_TYPE_DMABUF_TEXTURE, "width", width, @@ -192,7 +203,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder, GDK_TEXTURE (self)->format = format; g_set_object (&self->display, display); - self->downloader = display->dmabuf_downloaders[i]; + self->downloader = downloader; self->dmabuf = dmabuf; self->destroy = destroy; self->data = data;