display: Get supported dmabuf formats

These are the dmabuf formats that we can hope to
download by first importing them as an EGLImage and
then downloading them as a GL texture.
This commit is contained in:
Matthias Clasen
2023-10-02 23:16:42 -04:00
parent 0d27813b42
commit 7a11bc9442
3 changed files with 109 additions and 0 deletions

View File

@@ -404,6 +404,8 @@ gdk_display_finalize (GObject *object)
g_list_free_full (display->seats, g_object_unref);
g_free (display->egl_dmabuf_formats);
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
}
@@ -1259,6 +1261,61 @@ gdk_display_create_vulkan_context (GdkDisplay *self,
NULL);
}
static void
init_dmabuf_formats (GdkDisplay *self)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
if (priv->egl_display != EGL_NO_DISPLAY)
{
int num_formats;
int *formats;
GArray *array;
eglQueryDmaBufFormatsEXT (priv->egl_display, 0, NULL, &num_formats);
formats = g_new (int, num_formats);
eglQueryDmaBufFormatsEXT (priv->egl_display, num_formats, formats, &num_formats);
array = g_array_new (FALSE, FALSE, sizeof (GdkDmabufFormat));
for (int i = 0; i < num_formats; i++)
{
int num_modifiers;
uint64_t *modifiers;
unsigned int *external_only;
eglQueryDmaBufModifiersEXT (priv->egl_display, formats[i], 0, NULL, NULL, &num_modifiers);
modifiers = g_new (uint64_t, num_modifiers);
external_only = g_new (unsigned int, num_modifiers);
eglQueryDmaBufModifiersEXT (priv->egl_display, formats[i], num_modifiers, modifiers, external_only, &num_modifiers);
if (num_modifiers == 0)
g_array_append_val (array, ((GdkDmabufFormat){ formats[i], 0 }));
else
{
for (int j = 0; j < num_modifiers; j++)
g_array_append_val (array, ((GdkDmabufFormat){ formats[i], modifiers[j] }));
}
g_free (modifiers);
}
g_free (formats);
self->egl_dmabuf_n_formats = array->len;
self->egl_dmabuf_formats = (GdkDmabufFormat *) g_array_free (array, FALSE);
}
GDK_DEBUG (MISC, "EGL dmabuf formats: (%lu)", self->egl_dmabuf_n_formats);
for (gsize i = 0; i < self->egl_dmabuf_n_formats; i++)
{
uint32_t f = self->egl_dmabuf_formats[i].fourcc;
uint64_t m = self->egl_dmabuf_formats[i].modifier;
GDK_DEBUG (MISC, " %c%c%c%c:%#lx", f & 0xff, (f >> 8) & 0xff, (f >> 16) & 0xff, (f >> 24) & 0xff, m);
}
}
static void
gdk_display_init_gl (GdkDisplay *self)
{
@@ -1300,6 +1357,10 @@ gdk_display_init_gl (GdkDisplay *self)
gdk_gl_backend_use (GDK_GL_CONTEXT_GET_CLASS (context)->backend_type);
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
gdk_gl_context_make_current (context);
init_dmabuf_formats (self);
}
/**
@@ -1824,6 +1885,40 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif
}
/**
* GdkDmabufFormat:
* @fourcc: the format code
* @modifiers: the format modifier
*
* The `GdkDmabufFormat` struct represents a dma-buf format
* as defined in the `drm_fourcc.h` header.
*
* Since: 4.14
*/
/**
* gdk_display_get_dmabuf_formats:
* @display: a `GdkDisplay`
* @n_formats: return location for the number of formats
*
* Returns the dma-buf formats that are supported for
* this display.
*
* Returns: (transfer none): an array of `GdkDmabufFormat` structs.
* The length of the array is returned in @n_formats
*
* Since: 4.14
*/
const GdkDmabufFormat *
gdk_display_get_dmabuf_formats (GdkDisplay *display,
gsize *n_formats)
{
gdk_display_prepare_gl (display, NULL);
*n_formats = display->egl_dmabuf_n_formats;
return display->egl_dmabuf_formats;
}
GdkDebugFlags
gdk_display_get_debug_flags (GdkDisplay *display)
{

View File

@@ -134,6 +134,17 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
const char *name,
GValue *value);
typedef struct
{
uint32_t fourcc;
uint64_t modifier;
} GdkDmabufFormat;
GDK_AVAILABLE_IN_4_14
const GdkDmabufFormat *
gdk_display_get_dmabuf_formats (GdkDisplay *display,
gsize *n_formats);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
G_END_DECLS

View File

@@ -113,6 +113,9 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
GdkDmabufFormat *egl_dmabuf_formats;
gsize egl_dmabuf_n_formats;
};
struct _GdkDisplayClass