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_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

View File

@ -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,

View File

@ -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);

View File

@ -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;