dmabuf: Don't use a downloader for builtin downloads

When we use the builtin downloads via mmap(), it's a special case where
we don't need to initialize subsystems and query them for support. We
know what we can and can't do.

Also, we want to use these formats with the lowest priority but pick the
downloader first for supported formats, and queueing it in the
downloaders list doesn't reflect that. So don't do it.
This commit is contained in:
Benjamin Otte 2023-12-13 07:27:43 +01:00
parent f0eceb4aa3
commit 888b9ee352
4 changed files with 79 additions and 97 deletions

View File

@ -1925,12 +1925,13 @@ gdk_display_init_dmabuf (GdkDisplay *self)
{ {
gdk_display_prepare_gl (self, NULL); gdk_display_prepare_gl (self, NULL);
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
#ifdef HAVE_EGL #ifdef HAVE_EGL
if (gdk_display_prepare_gl (self, NULL)) if (gdk_display_prepare_gl (self, NULL))
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder); gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
#endif #endif
gdk_dmabuf_formats_builder_add_formats (builder,
gdk_dmabuf_get_mmap_formats ());
} }
#endif #endif

View File

@ -649,65 +649,42 @@ gdk_dmabuf_get_fourcc (GdkMemoryFormat format,
} }
} }
static gboolean GdkDmabufFormats *
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, gdk_dmabuf_get_mmap_formats (void)
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{ {
gsize i; static GdkDmabufFormats *formats = NULL;
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++) if (formats == NULL)
{ {
GDK_DISPLAY_DEBUG (display, DMABUF, GdkDmabufFormatsBuilder *builder;
"%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x", gsize i;
downloader->name,
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder, builder = gdk_dmabuf_formats_builder_new ();
supported_formats[i].fourcc,
DRM_FORMAT_MOD_LINEAR); 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; return formats;
}
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;
} }
static void static void
gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader, gdk_dmabuf_do_download_mmap (GdkTexture *texture,
GdkTexture *texture, guchar *data,
guchar *data, gsize stride)
gsize stride)
{ {
const GdkDrmFormatInfo *info; const GdkDrmFormatInfo *info;
const GdkDmabuf *dmabuf; const GdkDmabuf *dmabuf;
@ -722,8 +699,9 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
g_return_if_fail (info && info->download); g_return_if_fail (info && info->download);
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF, 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)", "Using mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier); gdk_texture_get_width (texture), gdk_texture_get_height (texture),
(char *)&dmabuf->fourcc, dmabuf->modifier);
for (i = 0; i < dmabuf->n_planes; i++) for (i = 0; i < dmabuf->n_planes; i++)
{ {
@ -782,17 +760,16 @@ out:
} }
} }
static void void
gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader, gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkTexture *texture, GdkMemoryFormat format,
GdkMemoryFormat format, guchar *data,
guchar *data, gsize stride)
gsize stride)
{ {
GdkMemoryFormat src_format = gdk_texture_get_format (texture); GdkMemoryFormat src_format = gdk_texture_get_format (texture);
if (format == src_format) if (format == src_format)
gdk_dmabuf_direct_downloader_do_download (downloader, texture, data, stride); gdk_dmabuf_do_download_mmap (texture, data, stride);
else else
{ {
unsigned int width, height; 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_stride = width * gdk_memory_format_bytes_per_pixel (src_format);
src_data = g_new (guchar, src_stride * height); 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, gdk_memory_convert (data, stride, format,
src_data, src_stride, src_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 int
gdk_dmabuf_ioctl (int fd, gdk_dmabuf_ioctl (int fd,
unsigned long request, unsigned long request,

View File

@ -39,9 +39,15 @@ struct _GdkDmabufDownloader
#ifdef HAVE_DMABUF #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; 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, int gdk_dmabuf_ioctl (int fd,
unsigned long request, unsigned long request,
void *arg); void *arg);

View File

@ -88,11 +88,10 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
{ {
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture); GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
self->downloader->download (self->downloader, if (self->downloader)
texture, self->downloader->download (self->downloader, texture, format, data, stride);
format, else
data, gdk_dmabuf_download_mmap (texture, format, data, stride);
stride);
} }
static void static void
@ -126,6 +125,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
{ {
#ifdef HAVE_DMABUF #ifdef HAVE_DMABUF
GdkDmabufTexture *self; GdkDmabufTexture *self;
const GdkDmabufDownloader *downloader;
GdkTexture *update_texture; GdkTexture *update_texture;
GdkDisplay *display; GdkDisplay *display;
GdkDmabuf dmabuf; GdkDmabuf dmabuf;
@ -149,23 +149,34 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
gdk_display_init_dmabuf (display); 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)) downloader = NULL;
g_clear_error (&local_error);
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
display,
&dmabuf,
premultiplied,
local_error ? NULL : &local_error))
break;
} }
else
if (display->dmabuf_downloaders[i] == NULL)
{ {
g_propagate_error (error, local_error); downloader = NULL;
return 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)) 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, " : "", gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
dmabuf.n_planes, dmabuf.n_planes,
format, format,
display->dmabuf_downloaders[i]->name); downloader ? downloader->name : "none");
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE, self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", width, "width", width,
@ -192,7 +203,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDK_TEXTURE (self)->format = format; GDK_TEXTURE (self)->format = format;
g_set_object (&self->display, display); g_set_object (&self->display, display);
self->downloader = display->dmabuf_downloaders[i]; self->downloader = downloader;
self->dmabuf = dmabuf; self->dmabuf = dmabuf;
self->destroy = destroy; self->destroy = destroy;
self->data = data; self->data = data;