Compare commits
9 Commits
css-variab
...
dmabuf-way
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0c9c66c38 | ||
|
|
349a29bb49 | ||
|
|
dbb890240a | ||
|
|
ad636b2afb | ||
|
|
66bc0c968f | ||
|
|
3674497163 | ||
|
|
1217cc91d7 | ||
|
|
4a8ecd4114 | ||
|
|
8182fb5704 |
@@ -2004,6 +2004,7 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
|||||||
|
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (self, builder));
|
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (self, builder));
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gdk_dmabuf_formats_builder_add_formats (builder,
|
gdk_dmabuf_formats_builder_add_formats (builder,
|
||||||
@@ -2016,6 +2017,29 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
|||||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||||
"Initialized support for %zu dmabuf formats",
|
"Initialized support for %zu dmabuf formats",
|
||||||
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
if (GDK_DISPLAY_DEBUG_CHECK (self, DMABUF))
|
||||||
|
{
|
||||||
|
for (gsize i = 0; i < gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats); i++)
|
||||||
|
{
|
||||||
|
guint32 fourcc;
|
||||||
|
guint64 modifier;
|
||||||
|
|
||||||
|
gdk_dmabuf_formats_get_format (self->dmabuf_formats, i, &fourcc, &modifier);
|
||||||
|
|
||||||
|
gdk_debug_message (" %.4s:%#" G_GINT64_MODIFIER "x%s",
|
||||||
|
(char *) &fourcc,
|
||||||
|
modifier,
|
||||||
|
gdk_dmabuf_formats_contains (self->egl_external_formats, fourcc, modifier) ? " (external)" : "");
|
||||||
|
|
||||||
|
if (i + 1 < gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats) &&
|
||||||
|
gdk_dmabuf_formats_next_priority (self->dmabuf_formats, i) == i + 1)
|
||||||
|
gdk_debug_message ("------");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1965,10 +1965,6 @@ gdk_dmabuf_get_mmap_formats (void)
|
|||||||
if (!supported_formats[i].download)
|
if (!supported_formats[i].download)
|
||||||
continue;
|
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,
|
gdk_dmabuf_formats_builder_add_format (builder,
|
||||||
supported_formats[i].fourcc,
|
supported_formats[i].fourcc,
|
||||||
DRM_FORMAT_MOD_LINEAR);
|
DRM_FORMAT_MOD_LINEAR);
|
||||||
|
|||||||
@@ -93,25 +93,18 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
|||||||
|
|
||||||
for (int j = 0; j < num_modifiers; j++)
|
for (int j = 0; j < num_modifiers; j++)
|
||||||
{
|
{
|
||||||
/* All linear formats we support are already added my the mmap downloader.
|
if (!external_only[j])
|
||||||
* We don't add external formats, unless we can use them (via GLES)
|
|
||||||
*/
|
|
||||||
if (modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
|
|
||||||
(!external_only[j] || gdk_gl_context_get_use_es (context)))
|
|
||||||
{
|
{
|
||||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
|
||||||
"%s EGL dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
|
|
||||||
external_only[j] ? "external " : "",
|
|
||||||
(char *) &fourccs[i],
|
|
||||||
modifiers[j]);
|
|
||||||
|
|
||||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
||||||
}
|
|
||||||
if (external_only[j])
|
|
||||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
|
||||||
else
|
|
||||||
all_external = FALSE;
|
all_external = FALSE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gdk_gl_context_get_use_es (context))
|
||||||
|
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Accept implicit modifiers as long as we accept the format at all.
|
/* Accept implicit modifiers as long as we accept the format at all.
|
||||||
* This is a bit of a crapshot, but unfortunately needed for a bunch
|
* This is a bit of a crapshot, but unfortunately needed for a bunch
|
||||||
@@ -120,9 +113,9 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
|||||||
* As an extra wrinkle, treat the implicit modifier as 'external only'
|
* As an extra wrinkle, treat the implicit modifier as 'external only'
|
||||||
* if all formats with the same fourcc are 'external only'.
|
* if all formats with the same fourcc are 'external only'.
|
||||||
*/
|
*/
|
||||||
if (!all_external || gdk_gl_context_get_use_es (context))
|
if (!all_external)
|
||||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||||
if (all_external)
|
else if (gdk_gl_context_get_use_es (context))
|
||||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +142,7 @@ GdkDmabufDownloader *
|
|||||||
gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
||||||
GdkDmabufFormatsBuilder *builder)
|
GdkDmabufFormatsBuilder *builder)
|
||||||
{
|
{
|
||||||
|
GdkGLContext *context;
|
||||||
GdkDmabufFormatsBuilder *formats;
|
GdkDmabufFormatsBuilder *formats;
|
||||||
GdkDmabufFormatsBuilder *external;
|
GdkDmabufFormatsBuilder *external;
|
||||||
gboolean retval = FALSE;
|
gboolean retval = FALSE;
|
||||||
@@ -163,6 +157,8 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
previous = gdk_gl_context_get_current ();
|
previous = gdk_gl_context_get_current ();
|
||||||
|
context = gdk_display_get_gl_context (display);
|
||||||
|
|
||||||
formats = gdk_dmabuf_formats_builder_new ();
|
formats = gdk_dmabuf_formats_builder_new ();
|
||||||
external = gdk_dmabuf_formats_builder_new ();
|
external = gdk_dmabuf_formats_builder_new ();
|
||||||
|
|
||||||
@@ -172,6 +168,11 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
|||||||
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
|
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
|
||||||
|
|
||||||
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
|
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
|
||||||
|
if (gdk_gl_context_get_use_es (context))
|
||||||
|
{
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||||
|
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_external_formats);
|
||||||
|
}
|
||||||
|
|
||||||
if (!retval)
|
if (!retval)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,14 +49,6 @@
|
|||||||
* Since: 4.14
|
* Since: 4.14
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct _GdkDmabufFormats
|
|
||||||
{
|
|
||||||
int ref_count;
|
|
||||||
|
|
||||||
gsize n_formats;
|
|
||||||
GdkDmabufFormat *formats;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
|
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +144,36 @@ gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_dmabuf_formats_contains:
|
* gdk_dmabuf_formats_next_priority:
|
||||||
|
* @formats: a `GdkDmabufFormats`
|
||||||
|
* @idx: the index of the format to query
|
||||||
|
*
|
||||||
|
* Returns the index of the next-lower-priority format.
|
||||||
|
*
|
||||||
|
* The formats in a `GdkDmabufFormats` are sorted by decreasing
|
||||||
|
* priority. This function lets you identify formats with the
|
||||||
|
* same priority: all the formats between @idx and the return
|
||||||
|
* value of this function have the same priority.
|
||||||
|
*
|
||||||
|
* Returns: the index of the next lower priority format
|
||||||
|
*
|
||||||
|
* Since: 4.16
|
||||||
|
*/
|
||||||
|
gsize
|
||||||
|
gdk_dmabuf_formats_next_priority (GdkDmabufFormats *formats,
|
||||||
|
gsize idx)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat *format;
|
||||||
|
|
||||||
|
g_return_val_if_fail (idx < formats->n_formats, G_MAXSIZE);
|
||||||
|
|
||||||
|
format = &formats->formats[idx];
|
||||||
|
|
||||||
|
return format->next_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_dmabuf_format_contains:
|
||||||
* @formats: a `GdkDmabufFormats`
|
* @formats: a `GdkDmabufFormats`
|
||||||
* @fourcc: a format code
|
* @fourcc: a format code
|
||||||
* @modifier: a format modifier
|
* @modifier: a format modifier
|
||||||
@@ -184,6 +205,8 @@ gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
|||||||
* gdk_dmabuf_formats_new:
|
* gdk_dmabuf_formats_new:
|
||||||
* @formats: the formats
|
* @formats: the formats
|
||||||
* @n_formats: the length of @formats
|
* @n_formats: the length of @formats
|
||||||
|
* @device: the DRM device that the compositor uses, or
|
||||||
|
* 0 if this object doesn't describe compositor formats
|
||||||
*
|
*
|
||||||
* Creates a new `GdkDmabufFormats struct for
|
* Creates a new `GdkDmabufFormats struct for
|
||||||
* the given formats.
|
* the given formats.
|
||||||
@@ -197,7 +220,8 @@ gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
|||||||
*/
|
*/
|
||||||
GdkDmabufFormats *
|
GdkDmabufFormats *
|
||||||
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||||
gsize n_formats)
|
gsize n_formats,
|
||||||
|
guint64 device)
|
||||||
{
|
{
|
||||||
GdkDmabufFormats *self;
|
GdkDmabufFormats *self;
|
||||||
|
|
||||||
@@ -206,6 +230,7 @@ gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
|||||||
self->ref_count = 1;
|
self->ref_count = 1;
|
||||||
self->n_formats = n_formats;
|
self->n_formats = n_formats;
|
||||||
self->formats = g_new (GdkDmabufFormat, n_formats);
|
self->formats = g_new (GdkDmabufFormat, n_formats);
|
||||||
|
self->device = device;
|
||||||
|
|
||||||
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
|
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
|
||||||
|
|
||||||
@@ -240,6 +265,9 @@ gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
|||||||
if (formats1 == NULL || formats2 == NULL)
|
if (formats1 == NULL || formats2 == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (formats1->device != formats2->device)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (formats1->n_formats != formats2->n_formats)
|
if (formats1->n_formats != formats2->n_formats)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -249,7 +277,10 @@ gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
|||||||
GdkDmabufFormat *f2 = &formats2->formats[i];
|
GdkDmabufFormat *f2 = &formats2->formats[i];
|
||||||
|
|
||||||
if (f1->fourcc != f2->fourcc ||
|
if (f1->fourcc != f2->fourcc ||
|
||||||
f1->modifier != f2->modifier)
|
f1->modifier != f2->modifier ||
|
||||||
|
f1->next_priority != f2->next_priority ||
|
||||||
|
f1->flags != f2->flags ||
|
||||||
|
f1->device != f2->device)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats
|
|||||||
guint32 *fourcc,
|
guint32 *fourcc,
|
||||||
guint64 *modifier);
|
guint64 *modifier);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_16
|
||||||
|
gsize gdk_dmabuf_formats_next_priority (GdkDmabufFormats *formats,
|
||||||
|
gsize idx);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_4_14
|
GDK_AVAILABLE_IN_4_14
|
||||||
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||||
guint32 fourcc,
|
guint32 fourcc,
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ gdk_dmabuf_format_compare (gconstpointer data_a,
|
|||||||
const GdkDmabufFormat *a = data_a;
|
const GdkDmabufFormat *a = data_a;
|
||||||
const GdkDmabufFormat *b = data_b;
|
const GdkDmabufFormat *b = data_b;
|
||||||
|
|
||||||
if (a->fourcc == b->fourcc)
|
if (a->next_priority != b->next_priority)
|
||||||
|
return (a->next_priority < b->next_priority) ? -1 : 1;
|
||||||
|
else if (a->fourcc == b->fourcc)
|
||||||
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
|
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
|
||||||
else
|
else
|
||||||
return a->fourcc - b->fourcc;
|
return a->fourcc - b->fourcc;
|
||||||
@@ -67,7 +69,9 @@ gdk_dmabuf_format_equal (gconstpointer data_a,
|
|||||||
const GdkDmabufFormat *b = data_b;
|
const GdkDmabufFormat *b = data_b;
|
||||||
|
|
||||||
return a->fourcc == b->fourcc &&
|
return a->fourcc == b->fourcc &&
|
||||||
a->modifier == b->modifier;
|
a->flags == b->flags &&
|
||||||
|
a->modifier == b->modifier &&
|
||||||
|
a->device == b->device;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -79,38 +83,46 @@ gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
|
|||||||
gdk_dmabuf_format_compare);
|
gdk_dmabuf_format_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list must be sorted */
|
GdkDmabufFormats *
|
||||||
static void
|
gdk_dmabuf_formats_builder_free_to_formats_for_device (GdkDmabufFormatsBuilder *self,
|
||||||
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
|
guint64 device)
|
||||||
{
|
{
|
||||||
gsize i, j;
|
GdkDmabufFormats *formats;
|
||||||
|
|
||||||
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
gdk_dmabuf_formats_builder_next_priority (self);
|
||||||
{
|
gdk_dmabuf_formats_builder_sort (self);
|
||||||
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
|
|
||||||
gdk_dmabuf_formats_builder_get (self, j)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
j++;
|
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
|
||||||
if (i != j)
|
gdk_dmabuf_formats_builder_get_size (self),
|
||||||
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
|
device);
|
||||||
}
|
gdk_dmabuf_formats_builder_clear (self);
|
||||||
|
g_free (self);
|
||||||
|
|
||||||
|
return formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkDmabufFormats *
|
GdkDmabufFormats *
|
||||||
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
||||||
{
|
{
|
||||||
GdkDmabufFormats *formats;
|
return gdk_dmabuf_formats_builder_free_to_formats_for_device (self, 0);
|
||||||
|
}
|
||||||
|
|
||||||
gdk_dmabuf_formats_builder_sort (self);
|
void
|
||||||
gdk_dmabuf_formats_builder_remove_duplicates (self);
|
gdk_dmabuf_formats_builder_add_format_for_device (GdkDmabufFormatsBuilder *self,
|
||||||
|
guint32 fourcc,
|
||||||
|
guint32 flags,
|
||||||
|
guint64 modifier,
|
||||||
|
guint64 device)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat format = { fourcc, flags, modifier, device, G_MAXSIZE };
|
||||||
|
|
||||||
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
|
for (gsize i = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
||||||
gdk_dmabuf_formats_builder_get_size (self));
|
{
|
||||||
gdk_dmabuf_formats_builder_clear (self);
|
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i), &format))
|
||||||
g_free (self);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return formats;
|
gdk_dmabuf_formats_builder_append (self, &format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -118,17 +130,33 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
|||||||
guint32 fourcc,
|
guint32 fourcc,
|
||||||
guint64 modifier)
|
guint64 modifier)
|
||||||
{
|
{
|
||||||
gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
|
gdk_dmabuf_formats_builder_add_format_for_device (self, fourcc, 0, modifier, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (GdkDmabufFormatsBuilder *self)
|
||||||
|
{
|
||||||
|
for (gsize i = gdk_dmabuf_formats_builder_get_size (self); i > 0; i--)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat *format = gdk_dmabuf_formats_builder_get (self, i - 1);
|
||||||
|
|
||||||
|
if (format->next_priority != G_MAXSIZE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
format->next_priority = gdk_dmabuf_formats_builder_get_size (self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||||
GdkDmabufFormats *formats)
|
GdkDmabufFormats *formats)
|
||||||
{
|
{
|
||||||
gdk_dmabuf_formats_builder_splice (self,
|
for (gsize i = 0; i < gdk_dmabuf_formats_get_n_formats (formats); i++)
|
||||||
gdk_dmabuf_formats_builder_get_size (self),
|
{
|
||||||
0,
|
guint32 fourcc;
|
||||||
FALSE,
|
guint64 modifier;
|
||||||
gdk_dmabuf_formats_peek_formats (formats),
|
|
||||||
gdk_dmabuf_formats_get_n_formats (formats));
|
gdk_dmabuf_formats_get_format (formats, i, &fourcc, &modifier);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (self, fourcc, modifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,21 @@
|
|||||||
|
|
||||||
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
|
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
|
||||||
|
|
||||||
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
|
GdkDmabufFormatsBuilder *gdk_dmabuf_formats_builder_new (void);
|
||||||
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
|
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
|
||||||
|
|
||||||
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||||
guint32 fourcc,
|
guint32 fourcc,
|
||||||
guint64 modifier);
|
guint64 modifier);
|
||||||
|
|
||||||
|
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats_for_device (GdkDmabufFormatsBuilder *self,
|
||||||
|
guint64 device);
|
||||||
|
void gdk_dmabuf_formats_builder_add_format_for_device (GdkDmabufFormatsBuilder *self,
|
||||||
|
guint32 fourcc,
|
||||||
|
guint32 flags,
|
||||||
|
guint64 modifier,
|
||||||
|
guint64 device);
|
||||||
|
|
||||||
|
void gdk_dmabuf_formats_builder_next_priority (GdkDmabufFormatsBuilder *self);
|
||||||
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||||
GdkDmabufFormats *formats);
|
GdkDmabufFormats *formats);
|
||||||
|
|||||||
@@ -6,10 +6,23 @@ typedef struct _GdkDmabufFormat GdkDmabufFormat;
|
|||||||
struct _GdkDmabufFormat
|
struct _GdkDmabufFormat
|
||||||
{
|
{
|
||||||
guint32 fourcc;
|
guint32 fourcc;
|
||||||
|
guint32 flags;
|
||||||
guint64 modifier;
|
guint64 modifier;
|
||||||
|
guint64 device;
|
||||||
|
gsize next_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkDmabufFormats
|
||||||
|
{
|
||||||
|
int ref_count;
|
||||||
|
|
||||||
|
gsize n_formats;
|
||||||
|
GdkDmabufFormat *formats;
|
||||||
|
guint64 device;
|
||||||
};
|
};
|
||||||
|
|
||||||
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||||
gsize n_formats);
|
gsize n_formats,
|
||||||
|
guint64 device);
|
||||||
|
|
||||||
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
|
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "gdksurfaceprivate.h"
|
#include "gdksurfaceprivate.h"
|
||||||
#include "gdktexture.h"
|
#include "gdktexture.h"
|
||||||
#include "gsk/gskrectprivate.h"
|
#include "gsk/gskrectprivate.h"
|
||||||
|
#include "gdkdebugprivate.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ gdk_subsurface_finalize (GObject *object)
|
|||||||
|
|
||||||
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
|
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
|
||||||
g_clear_object (&subsurface->parent);
|
g_clear_object (&subsurface->parent);
|
||||||
|
g_clear_pointer (&subsurface->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_subsurface_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gdk_subsurface_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -116,6 +118,28 @@ insert_subsurface (GdkSubsurface *subsurface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
is_topmost_subsurface (GdkSubsurface *subsurface)
|
||||||
|
{
|
||||||
|
GdkSurface *parent = subsurface->parent;
|
||||||
|
|
||||||
|
return !subsurface->sibling_above && parent->subsurfaces_below != subsurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GdkSubsurface *
|
||||||
|
find_topmost_subsurface (GdkSurface *surface)
|
||||||
|
{
|
||||||
|
GdkSubsurface *top = surface->subsurfaces_above;
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
while (top->sibling_above)
|
||||||
|
top = top->sibling_above;
|
||||||
|
}
|
||||||
|
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* gdk_subsurface_attach:
|
* gdk_subsurface_attach:
|
||||||
* @subsurface: the `GdkSubsurface`
|
* @subsurface: the `GdkSubsurface`
|
||||||
@@ -150,7 +174,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
|||||||
GdkSubsurface *sibling)
|
GdkSubsurface *sibling)
|
||||||
{
|
{
|
||||||
GdkSurface *parent = subsurface->parent;
|
GdkSurface *parent = subsurface->parent;
|
||||||
gboolean result;
|
gboolean was_topmost, is_topmost, result;
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
|
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
|
||||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||||
@@ -164,6 +188,8 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
|||||||
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
|
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
|
||||||
g_return_val_if_fail (sibling == NULL || sibling->parent == subsurface->parent, FALSE);
|
g_return_val_if_fail (sibling == NULL || sibling->parent == subsurface->parent, FALSE);
|
||||||
|
|
||||||
|
was_topmost = is_topmost_subsurface (subsurface);
|
||||||
|
|
||||||
result = GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface,
|
result = GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface,
|
||||||
texture,
|
texture,
|
||||||
source,
|
source,
|
||||||
@@ -198,6 +224,29 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_topmost = is_topmost_subsurface (subsurface);
|
||||||
|
|
||||||
|
if (!was_topmost && is_topmost)
|
||||||
|
{
|
||||||
|
GDK_DISPLAY_DEBUG (parent->display, DMABUF, "Using formats of topmost subsurface %p", subsurface);
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (parent, subsurface->dmabuf_formats);
|
||||||
|
}
|
||||||
|
else if (was_topmost && !is_topmost)
|
||||||
|
{
|
||||||
|
GdkSubsurface *top = find_topmost_subsurface (parent);
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
GDK_DISPLAY_DEBUG (parent->display, DMABUF, "Using formats of topmost subsurface %p", top);
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (parent, top->dmabuf_formats);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GDK_DISPLAY_DEBUG (parent->display, DMABUF, "Using formats of main surface");
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (parent, parent->dmabuf_formats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,10 +261,25 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
|||||||
void
|
void
|
||||||
gdk_subsurface_detach (GdkSubsurface *subsurface)
|
gdk_subsurface_detach (GdkSubsurface *subsurface)
|
||||||
{
|
{
|
||||||
|
gboolean was_topmost;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||||
|
|
||||||
|
was_topmost = is_topmost_subsurface (subsurface);
|
||||||
|
|
||||||
remove_subsurface (subsurface);
|
remove_subsurface (subsurface);
|
||||||
|
|
||||||
|
if (was_topmost)
|
||||||
|
{
|
||||||
|
GdkSurface *parent = subsurface->parent;
|
||||||
|
GdkSubsurface *top = find_topmost_subsurface (parent);
|
||||||
|
|
||||||
|
if (top)
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (parent, top->dmabuf_formats);
|
||||||
|
else
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (parent, parent->dmabuf_formats);
|
||||||
|
}
|
||||||
|
|
||||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
|
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,3 +434,17 @@ gdk_subsurface_get_bounds (GdkSubsurface *subsurface,
|
|||||||
if (gdk_subsurface_get_background_rect (subsurface, &background))
|
if (gdk_subsurface_get_background_rect (subsurface, &background))
|
||||||
graphene_rect_union (bounds, &background, bounds);
|
graphene_rect_union (bounds, &background, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_subsurface_set_dmabuf_formats (GdkSubsurface *subsurface,
|
||||||
|
GdkDmabufFormats *formats)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||||
|
g_return_if_fail (formats != NULL);
|
||||||
|
|
||||||
|
g_clear_pointer (&subsurface->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
subsurface->dmabuf_formats = gdk_dmabuf_formats_ref (formats);
|
||||||
|
|
||||||
|
if (subsurface->parent && is_topmost_subsurface (subsurface))
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (subsurface->parent, formats);
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "gdkenumtypes.h"
|
#include "gdkenumtypes.h"
|
||||||
#include "gdksurface.h"
|
#include "gdksurface.h"
|
||||||
|
#include "gdkdmabufformats.h"
|
||||||
#include <graphene.h>
|
#include <graphene.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@@ -45,6 +46,8 @@ struct _GdkSubsurface
|
|||||||
gboolean above_parent;
|
gboolean above_parent;
|
||||||
GdkSubsurface *sibling_above;
|
GdkSubsurface *sibling_above;
|
||||||
GdkSubsurface *sibling_below;
|
GdkSubsurface *sibling_below;
|
||||||
|
|
||||||
|
GdkDmabufFormats *dmabuf_formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -109,6 +112,8 @@ gboolean gdk_subsurface_get_background_rect (GdkSubsurface *subsu
|
|||||||
graphene_rect_t *rect);
|
graphene_rect_t *rect);
|
||||||
void gdk_subsurface_get_bounds (GdkSubsurface *subsurface,
|
void gdk_subsurface_get_bounds (GdkSubsurface *subsurface,
|
||||||
graphene_rect_t *bounds);
|
graphene_rect_t *bounds);
|
||||||
|
void gdk_subsurface_set_dmabuf_formats (GdkSubsurface *subsurface,
|
||||||
|
GdkDmabufFormats *formats);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CURSOR,
|
PROP_CURSOR,
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
|
PROP_DMABUF_FORMATS,
|
||||||
PROP_FRAME_CLOCK,
|
PROP_FRAME_CLOCK,
|
||||||
PROP_MAPPED,
|
PROP_MAPPED,
|
||||||
PROP_WIDTH,
|
PROP_WIDTH,
|
||||||
@@ -548,6 +549,18 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
|||||||
GDK_TYPE_DISPLAY,
|
GDK_TYPE_DISPLAY,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GdkSurface:dmabuf-formats: (attributes org.gtk.Property.get=gdk_surface_get_dmabuf_formats)
|
||||||
|
*
|
||||||
|
* The dmabuf formats that can be used with this surface.
|
||||||
|
*
|
||||||
|
* Since: 4.14
|
||||||
|
*/
|
||||||
|
properties[PROP_DMABUF_FORMATS] =
|
||||||
|
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
|
||||||
|
GDK_TYPE_DMABUF_FORMATS,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GdkSurface:frame-clock: (attributes org.gtk.Property.get=gdk_surface_get_frame_clock)
|
* GdkSurface:frame-clock: (attributes org.gtk.Property.get=gdk_surface_get_frame_clock)
|
||||||
*
|
*
|
||||||
@@ -773,6 +786,9 @@ gdk_surface_finalize (GObject *object)
|
|||||||
|
|
||||||
g_ptr_array_unref (surface->subsurfaces);
|
g_ptr_array_unref (surface->subsurfaces);
|
||||||
|
|
||||||
|
g_clear_pointer (&surface->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
g_clear_pointer (&surface->effective_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,6 +843,10 @@ gdk_surface_get_property (GObject *object,
|
|||||||
g_value_set_object (value, surface->display);
|
g_value_set_object (value, surface->display);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_DMABUF_FORMATS:
|
||||||
|
g_value_set_boxed (value, surface->effective_dmabuf_formats);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_FRAME_CLOCK:
|
case PROP_FRAME_CLOCK:
|
||||||
g_value_set_object (value, surface->frame_clock);
|
g_value_set_object (value, surface->frame_clock);
|
||||||
break;
|
break;
|
||||||
@@ -3076,3 +3096,70 @@ gdk_surface_get_subsurface (GdkSurface *surface,
|
|||||||
{
|
{
|
||||||
return g_ptr_array_index (surface->subsurfaces, idx);
|
return g_ptr_array_index (surface->subsurfaces, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_surface_set_dmabuf_formats (GdkSurface *surface,
|
||||||
|
GdkDmabufFormats *formats)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||||
|
g_return_if_fail (formats != NULL);
|
||||||
|
|
||||||
|
g_clear_pointer (&surface->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
surface->dmabuf_formats = gdk_dmabuf_formats_ref (formats);
|
||||||
|
|
||||||
|
if (surface->subsurfaces_above == NULL)
|
||||||
|
{
|
||||||
|
GDK_DISPLAY_DEBUG (surface->display, DMABUF, "Using main surface formats");
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (surface, formats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_surface_set_effective_dmabuf_formats (GdkSurface *surface,
|
||||||
|
GdkDmabufFormats *formats)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||||
|
|
||||||
|
if (!formats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gdk_dmabuf_formats_equal (surface->effective_dmabuf_formats, formats))
|
||||||
|
{
|
||||||
|
GDK_DISPLAY_DEBUG (surface->display, DMABUF, "Formats unchanged");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&surface->effective_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
surface->effective_dmabuf_formats = gdk_dmabuf_formats_ref (formats);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_DMABUF_FORMATS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_surface_get_dmabuf_formats:
|
||||||
|
* @surface: a `GdkSurface`
|
||||||
|
*
|
||||||
|
* Returns the dma-buf formats that are supported on this surface.
|
||||||
|
*
|
||||||
|
* What formats can be used may depend on the geometry and stacking
|
||||||
|
* order of the surface and its subsurfaces, and can change over time.
|
||||||
|
*
|
||||||
|
* The formats returned by this function can be used for negotiating
|
||||||
|
* buffer formats with producers such as v4l, pipewire or GStreamer.
|
||||||
|
*
|
||||||
|
* To learn more about dma-bufs, see [class@Gdk.DmabufTextureBuilder].
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): a `GdkDmabufFormats` object
|
||||||
|
*
|
||||||
|
* Since: 4.16
|
||||||
|
*/
|
||||||
|
GdkDmabufFormats *
|
||||||
|
gdk_surface_get_dmabuf_formats (GdkSurface *surface)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||||
|
|
||||||
|
if (surface->effective_dmabuf_formats)
|
||||||
|
return surface->effective_dmabuf_formats;
|
||||||
|
else
|
||||||
|
return gdk_display_get_dmabuf_formats (surface->display);
|
||||||
|
}
|
||||||
|
|||||||
@@ -139,6 +139,10 @@ GdkVulkanContext *
|
|||||||
gdk_surface_create_vulkan_context(GdkSurface *surface,
|
gdk_surface_create_vulkan_context(GdkSurface *surface,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_16
|
||||||
|
GdkDmabufFormats *
|
||||||
|
gdk_surface_get_dmabuf_formats (GdkSurface *surface);
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkSurface, g_object_unref)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkSurface, g_object_unref)
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ struct _GdkSurface
|
|||||||
*/
|
*/
|
||||||
GdkSubsurface *subsurfaces_above;
|
GdkSubsurface *subsurfaces_above;
|
||||||
GdkSubsurface *subsurfaces_below;
|
GdkSubsurface *subsurfaces_below;
|
||||||
|
|
||||||
|
GdkDmabufFormats *dmabuf_formats;
|
||||||
|
GdkDmabufFormats *effective_dmabuf_formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkSurfaceClass
|
struct _GdkSurfaceClass
|
||||||
@@ -355,4 +358,10 @@ gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
|
|||||||
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
||||||
gsize idx);
|
gsize idx);
|
||||||
|
|
||||||
|
void gdk_surface_set_dmabuf_formats (GdkSurface *surface,
|
||||||
|
GdkDmabufFormats *formats);
|
||||||
|
|
||||||
|
void gdk_surface_set_effective_dmabuf_formats (GdkSurface *surface,
|
||||||
|
GdkDmabufFormats *formats);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -337,6 +337,16 @@ static void gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wa
|
|||||||
static void gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland);
|
static void gdk_wayland_display_init_xdg_output (GdkWaylandDisplay *display_wayland);
|
||||||
static void gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor);
|
static void gdk_wayland_display_get_xdg_output (GdkWaylandMonitor *monitor);
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmabuf_formats_callback (gpointer data,
|
||||||
|
DmabufFormatsInfo *info)
|
||||||
|
{
|
||||||
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (data);
|
||||||
|
|
||||||
|
g_clear_pointer (&display_wayland->wayland_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
display_wayland->wayland_dmabuf_formats = gdk_dmabuf_formats_ref (info->formats);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_registry_handle_global (void *data,
|
gdk_registry_handle_global (void *data,
|
||||||
struct wl_registry *registry,
|
struct wl_registry *registry,
|
||||||
@@ -370,7 +380,10 @@ gdk_registry_handle_global (void *data,
|
|||||||
feedback = zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
|
feedback = zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
|
||||||
display_wayland->dmabuf_formats_info = dmabuf_formats_info_new (GDK_DISPLAY (display_wayland),
|
display_wayland->dmabuf_formats_info = dmabuf_formats_info_new (GDK_DISPLAY (display_wayland),
|
||||||
"default",
|
"default",
|
||||||
feedback);
|
NULL,
|
||||||
|
feedback,
|
||||||
|
dmabuf_formats_callback,
|
||||||
|
display_wayland);
|
||||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||||
}
|
}
|
||||||
else if (strcmp (interface, "xdg_wm_base") == 0)
|
else if (strcmp (interface, "xdg_wm_base") == 0)
|
||||||
@@ -744,6 +757,7 @@ gdk_wayland_display_dispose (GObject *object)
|
|||||||
g_clear_pointer (&display_wayland->single_pixel_buffer, wp_single_pixel_buffer_manager_v1_destroy);
|
g_clear_pointer (&display_wayland->single_pixel_buffer, wp_single_pixel_buffer_manager_v1_destroy);
|
||||||
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
||||||
g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free);
|
g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free);
|
||||||
|
g_clear_pointer (&display_wayland->wayland_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||||
|
|
||||||
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
|
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
|
||||||
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
|
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ struct _GdkWaylandDisplay
|
|||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
|
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
|
||||||
DmabufFormatsInfo *dmabuf_formats_info;
|
DmabufFormatsInfo *dmabuf_formats_info;
|
||||||
|
GdkDmabufFormats *wayland_dmabuf_formats;
|
||||||
struct xdg_wm_base *xdg_wm_base;
|
struct xdg_wm_base *xdg_wm_base;
|
||||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||||
struct gtk_shell1 *gtk_shell;
|
struct gtk_shell1 *gtk_shell;
|
||||||
|
|||||||
@@ -54,24 +54,40 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct DmabufFormatsInfo DmabufFormatsInfo;
|
typedef struct DmabufFormatsInfo DmabufFormatsInfo;
|
||||||
|
|
||||||
|
typedef void (* DmabufFormatsUpdateCallback) (gpointer data,
|
||||||
|
DmabufFormatsInfo *formats);
|
||||||
|
|
||||||
struct DmabufFormatsInfo
|
struct DmabufFormatsInfo
|
||||||
{
|
{
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
char *name;
|
char *name;
|
||||||
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
||||||
|
|
||||||
|
DmabufFormatsUpdateCallback callback;
|
||||||
|
gpointer data;
|
||||||
|
|
||||||
gsize n_dmabuf_formats;
|
gsize n_dmabuf_formats;
|
||||||
DmabufFormat *dmabuf_format_table;
|
DmabufFormat *dmabuf_format_table;
|
||||||
|
|
||||||
DmabufFormats *dmabuf_formats;
|
DmabufFormats *dmabuf_formats;
|
||||||
DmabufFormats *pending_dmabuf_formats;
|
DmabufFormats *pending_dmabuf_formats;
|
||||||
DmabufTranche *pending_tranche;
|
DmabufTranche *pending_tranche;
|
||||||
|
|
||||||
|
GdkDmabufFormats *egl_formats;
|
||||||
|
GdkDmabufFormats *formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
DmabufFormatsInfo * dmabuf_formats_info_new (GdkDisplay *display,
|
DmabufFormatsInfo * dmabuf_formats_info_new (GdkDisplay *display,
|
||||||
const char *name,
|
const char *name,
|
||||||
struct zwp_linux_dmabuf_feedback_v1 *feedback);
|
GdkDmabufFormats *egl_formats,
|
||||||
|
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||||
|
DmabufFormatsUpdateCallback callback,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
void dmabuf_formats_info_free (DmabufFormatsInfo *info);
|
void dmabuf_formats_info_free (DmabufFormatsInfo *info);
|
||||||
|
|
||||||
|
void dmabuf_formats_info_set_egl_formats
|
||||||
|
(DmabufFormatsInfo *info,
|
||||||
|
GdkDmabufFormats *egl_formats);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gdkdmabuf-wayland-private.h"
|
#include "gdkdmabuf-wayland-private.h"
|
||||||
|
#include "gdkwaylanddmabufformats.h"
|
||||||
|
|
||||||
#include "gdkdebugprivate.h"
|
#include "gdkdebugprivate.h"
|
||||||
#include "gdkdmabufformatsprivate.h"
|
#include "gdkdmabufformatsprivate.h"
|
||||||
@@ -45,40 +46,112 @@ dmabuf_formats_free (DmabufFormats *formats)
|
|||||||
g_free (formats);
|
g_free (formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_in_tranche (GdkDmabufFormats *formats,
|
||||||
|
gsize idx,
|
||||||
|
guint32 fourcc,
|
||||||
|
guint64 modifier)
|
||||||
|
{
|
||||||
|
gsize end;
|
||||||
|
guint32 f;
|
||||||
|
guint64 m;
|
||||||
|
|
||||||
|
end = gdk_dmabuf_formats_next_priority (formats, idx);
|
||||||
|
for (gsize i = idx; i < end; i++)
|
||||||
|
{
|
||||||
|
gdk_dmabuf_formats_get_format (formats, i, &f, &m);
|
||||||
|
if (f == fourcc && m == modifier)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_wayland_dmabuf_formats_dump (GdkDmabufFormats *formats,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
gdk_debug_message ("Wayland %s dmabuf formats: (%lu entries)", name, formats->n_formats);
|
||||||
|
gdk_debug_message ("Main device: %u %u",
|
||||||
|
major (formats->device),
|
||||||
|
minor (formats->device));
|
||||||
|
|
||||||
|
gsize i = 0;
|
||||||
|
while (i < formats->n_formats)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat *format = &formats->formats[i];
|
||||||
|
gsize next_priority = format->next_priority;
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
gdk_debug_message ("------");
|
||||||
|
|
||||||
|
gdk_debug_message ("Tranche target device: %u %u",
|
||||||
|
major (format->device),
|
||||||
|
minor (format->device));
|
||||||
|
if (format->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT)
|
||||||
|
gdk_debug_message ("Tranche is scanout");
|
||||||
|
gdk_debug_message ("Tranche formats (%lu entries)", next_priority - i);
|
||||||
|
|
||||||
|
for (; i < next_priority; i++)
|
||||||
|
{
|
||||||
|
format = &formats->formats[i];
|
||||||
|
gdk_debug_message (" %.4s:%#" G_GINT64_MODIFIER "x", (char *) &format->fourcc, format->modifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_dmabuf_formats (DmabufFormatsInfo *info)
|
update_dmabuf_formats (DmabufFormatsInfo *info)
|
||||||
{
|
{
|
||||||
|
GdkDmabufFormatsBuilder *builder;
|
||||||
|
GdkDmabufFormats *egl_formats = info->egl_formats;
|
||||||
DmabufFormats *formats = info->dmabuf_formats;
|
DmabufFormats *formats = info->dmabuf_formats;
|
||||||
|
|
||||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
builder = gdk_dmabuf_formats_builder_new ();
|
||||||
"dmabuf format table (%lu entries)", info->n_dmabuf_formats);
|
|
||||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
|
||||||
"dmabuf main device: %u %u",
|
|
||||||
major (formats->main_device),
|
|
||||||
minor (formats->main_device));
|
|
||||||
|
|
||||||
for (gsize i = 0; i < formats->tranches->len; i++)
|
for (gsize i = 0; i < formats->tranches->len; i++)
|
||||||
{
|
{
|
||||||
DmabufTranche *tranche = g_ptr_array_index (formats->tranches, i);
|
DmabufTranche *tranche = g_ptr_array_index (formats->tranches, i);
|
||||||
|
|
||||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
if (egl_formats)
|
||||||
"dmabuf tranche target device: %u %u",
|
{
|
||||||
major (tranche->target_device),
|
for (gsize k = 0; k < gdk_dmabuf_formats_get_n_formats (egl_formats); k = gdk_dmabuf_formats_next_priority (egl_formats, k))
|
||||||
minor (tranche->target_device));
|
{
|
||||||
|
|
||||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
|
||||||
"dmabuf%s tranche (%lu entries):",
|
|
||||||
tranche->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ? " scanout" : "",
|
|
||||||
tranche->n_formats);
|
|
||||||
|
|
||||||
for (gsize j = 0; j < tranche->n_formats; j++)
|
for (gsize j = 0; j < tranche->n_formats; j++)
|
||||||
{
|
{
|
||||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
if (is_in_tranche (egl_formats, k,
|
||||||
" %.4s:%#" G_GINT64_MODIFIER "x",
|
tranche->formats[j].fourcc,
|
||||||
(char *) &(tranche->formats[j].fourcc),
|
tranche->formats[j].modifier))
|
||||||
tranche->formats[j].modifier);
|
gdk_dmabuf_formats_builder_add_format_for_device (builder,
|
||||||
|
tranche->formats[j].fourcc,
|
||||||
|
tranche->flags,
|
||||||
|
tranche->formats[j].modifier,
|
||||||
|
tranche->target_device);
|
||||||
|
}
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (gsize j = 0; j < tranche->n_formats; j++)
|
||||||
|
{
|
||||||
|
gdk_dmabuf_formats_builder_add_format_for_device (builder,
|
||||||
|
tranche->formats[j].fourcc,
|
||||||
|
tranche->flags,
|
||||||
|
tranche->formats[j].modifier,
|
||||||
|
tranche->target_device);
|
||||||
|
}
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&info->formats, gdk_dmabuf_formats_unref);
|
||||||
|
info->formats = gdk_dmabuf_formats_builder_free_to_formats_for_device (builder, formats->main_device);
|
||||||
|
|
||||||
|
if (GDK_DISPLAY_DEBUG_CHECK (info->display, DMABUF))
|
||||||
|
gdk_wayland_dmabuf_formats_dump (info->formats, info->name);
|
||||||
|
|
||||||
|
info->callback (info->data, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -206,7 +279,10 @@ static const struct zwp_linux_dmabuf_feedback_v1_listener feedback_listener = {
|
|||||||
DmabufFormatsInfo *
|
DmabufFormatsInfo *
|
||||||
dmabuf_formats_info_new (GdkDisplay *display,
|
dmabuf_formats_info_new (GdkDisplay *display,
|
||||||
const char *name,
|
const char *name,
|
||||||
struct zwp_linux_dmabuf_feedback_v1 *feedback)
|
GdkDmabufFormats *egl_formats,
|
||||||
|
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||||
|
DmabufFormatsUpdateCallback callback,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
DmabufFormatsInfo *info;
|
DmabufFormatsInfo *info;
|
||||||
|
|
||||||
@@ -214,11 +290,21 @@ dmabuf_formats_info_new (GdkDisplay *display,
|
|||||||
|
|
||||||
info->display = display;
|
info->display = display;
|
||||||
info->name = g_strdup (name);
|
info->name = g_strdup (name);
|
||||||
|
if (egl_formats)
|
||||||
|
{
|
||||||
|
info->egl_formats = gdk_dmabuf_formats_ref (egl_formats);
|
||||||
|
info->formats = gdk_dmabuf_formats_ref (egl_formats);
|
||||||
|
}
|
||||||
info->feedback = feedback;
|
info->feedback = feedback;
|
||||||
|
|
||||||
|
info->callback = callback;
|
||||||
|
info->data = data;
|
||||||
|
|
||||||
if (info->feedback)
|
if (info->feedback)
|
||||||
zwp_linux_dmabuf_feedback_v1_add_listener (info->feedback,
|
zwp_linux_dmabuf_feedback_v1_add_listener (info->feedback,
|
||||||
&feedback_listener, info);
|
&feedback_listener, info);
|
||||||
|
else
|
||||||
|
info->callback (info->data, info);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -227,6 +313,8 @@ void
|
|||||||
dmabuf_formats_info_free (DmabufFormatsInfo *info)
|
dmabuf_formats_info_free (DmabufFormatsInfo *info)
|
||||||
{
|
{
|
||||||
g_free (info->name);
|
g_free (info->name);
|
||||||
|
g_clear_pointer (&info->formats, gdk_dmabuf_formats_unref);
|
||||||
|
g_clear_pointer (&info->egl_formats, gdk_dmabuf_formats_unref);
|
||||||
g_clear_pointer (&info->feedback, zwp_linux_dmabuf_feedback_v1_destroy);
|
g_clear_pointer (&info->feedback, zwp_linux_dmabuf_feedback_v1_destroy);
|
||||||
if (info->dmabuf_format_table)
|
if (info->dmabuf_format_table)
|
||||||
{
|
{
|
||||||
@@ -239,3 +327,91 @@ dmabuf_formats_info_free (DmabufFormatsInfo *info)
|
|||||||
|
|
||||||
g_free (info);
|
g_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dmabuf_formats_info_set_egl_formats (DmabufFormatsInfo *info,
|
||||||
|
GdkDmabufFormats *egl_formats)
|
||||||
|
{
|
||||||
|
if (info->egl_formats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info->egl_formats = gdk_dmabuf_formats_ref (egl_formats);
|
||||||
|
|
||||||
|
if (info->dmabuf_formats)
|
||||||
|
update_dmabuf_formats (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_wayland_dmabuf_formats_get_main_device:
|
||||||
|
* @formats: a `GdkDmabufFormats`
|
||||||
|
*
|
||||||
|
* Returns the DRM device that the compositor uses for compositing.
|
||||||
|
*
|
||||||
|
* If this information isn't available (e.g. because @formats wasn't
|
||||||
|
* obtained from the compositor), then 0 is returned.
|
||||||
|
*
|
||||||
|
* Returns: the main DRM device that the compositor prefers
|
||||||
|
*
|
||||||
|
* Since: 4.16
|
||||||
|
*/
|
||||||
|
dev_t
|
||||||
|
gdk_wayland_dmabuf_formats_get_main_device (GdkDmabufFormats *formats)
|
||||||
|
{
|
||||||
|
return formats->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_wayland_dmabuf_formats_get_target_device:
|
||||||
|
* @formats: a `GdkDmabufFormats`
|
||||||
|
* @idx: the index of the format to return
|
||||||
|
*
|
||||||
|
* Returns the target DRM device that should be used for creating buffers
|
||||||
|
* with this format.
|
||||||
|
*
|
||||||
|
* If this information isn't available (e.g. because @formats wasn't
|
||||||
|
* obtained from the compositor), then 0 is returned.
|
||||||
|
*
|
||||||
|
* Returns: the target DRM device for this format
|
||||||
|
*
|
||||||
|
* Since: 4.16
|
||||||
|
*/
|
||||||
|
dev_t
|
||||||
|
gdk_wayland_dmabuf_formats_get_target_device (GdkDmabufFormats *formats,
|
||||||
|
gsize idx)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat *format;
|
||||||
|
|
||||||
|
g_return_val_if_fail (idx < formats->n_formats, 0);
|
||||||
|
|
||||||
|
format = &formats->formats[idx];
|
||||||
|
|
||||||
|
return format->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_wayland_dmabuf_formats_is_scanout:
|
||||||
|
* @formats: a `GdkDmabufFormats`
|
||||||
|
* @idx: the index of the format to return
|
||||||
|
*
|
||||||
|
* Returns whether the compositor may use buffers with this
|
||||||
|
* format for scanout.
|
||||||
|
*
|
||||||
|
* If this information isn't available (e.g. because @formats wasn't
|
||||||
|
* obtained from the compositor), then `FALSE` is returned.
|
||||||
|
*
|
||||||
|
* Returns: whether the format will be used for scanout
|
||||||
|
*
|
||||||
|
* Since: 4.16
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gdk_wayland_dmabuf_formats_is_scanout (GdkDmabufFormats *formats,
|
||||||
|
gsize idx)
|
||||||
|
{
|
||||||
|
GdkDmabufFormat *format;
|
||||||
|
|
||||||
|
g_return_val_if_fail (idx < formats->n_formats, FALSE);
|
||||||
|
|
||||||
|
format = &formats->formats[idx];
|
||||||
|
|
||||||
|
return (format->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT) != 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gdk/gdkdmabufformats.h"
|
||||||
#include "gdksubsurfaceprivate.h"
|
#include "gdksubsurfaceprivate.h"
|
||||||
|
#include "gdkdmabuf-wayland-private.h"
|
||||||
|
|
||||||
#include "wayland-client-protocol.h"
|
#include "wayland-client-protocol.h"
|
||||||
|
|
||||||
@@ -35,6 +37,8 @@ struct _GdkWaylandSubsurface
|
|||||||
struct wp_viewport *bg_viewport;
|
struct wp_viewport *bg_viewport;
|
||||||
cairo_rectangle_int_t bg_rect;
|
cairo_rectangle_int_t bg_rect;
|
||||||
gboolean bg_attached;
|
gboolean bg_attached;
|
||||||
|
|
||||||
|
DmabufFormatsInfo *formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWaylandSubsurfaceClass
|
struct _GdkWaylandSubsurfaceClass
|
||||||
@@ -48,4 +52,3 @@ void gdk_wayland_subsurface_request_frame (GdkSubsurface *subsurface);
|
|||||||
void gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *subsurface);
|
void gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *subsurface);
|
||||||
|
|
||||||
GdkSubsurface * gdk_wayland_surface_create_subsurface (GdkSurface *surface);
|
GdkSubsurface * gdk_wayland_surface_create_subsurface (GdkSurface *surface);
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "gdksubsurfaceprivate.h"
|
#include "gdksubsurfaceprivate.h"
|
||||||
#include "gdkdebugprivate.h"
|
#include "gdkdebugprivate.h"
|
||||||
#include "gsk/gskrectprivate.h"
|
#include "gsk/gskrectprivate.h"
|
||||||
|
#include "gdkprivate.h"
|
||||||
|
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ gdk_wayland_subsurface_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->bg_viewport, wp_viewport_destroy);
|
g_clear_pointer (&self->bg_viewport, wp_viewport_destroy);
|
||||||
g_clear_pointer (&self->bg_subsurface, wl_subsurface_destroy);
|
g_clear_pointer (&self->bg_subsurface, wl_subsurface_destroy);
|
||||||
g_clear_pointer (&self->bg_surface, wl_surface_destroy);
|
g_clear_pointer (&self->bg_surface, wl_surface_destroy);
|
||||||
|
g_clear_pointer (&self->formats, dmabuf_formats_info_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_wayland_subsurface_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gdk_wayland_subsurface_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -790,6 +792,15 @@ gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *sub)
|
|||||||
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmabuf_formats_callback (gpointer data,
|
||||||
|
DmabufFormatsInfo *info)
|
||||||
|
{
|
||||||
|
GdkSubsurface *sub = data;
|
||||||
|
|
||||||
|
gdk_subsurface_set_dmabuf_formats (sub, info->formats);
|
||||||
|
}
|
||||||
|
|
||||||
GdkSubsurface *
|
GdkSubsurface *
|
||||||
gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
||||||
{
|
{
|
||||||
@@ -798,6 +809,8 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
|||||||
GdkWaylandDisplay *disp = GDK_WAYLAND_DISPLAY (display);
|
GdkWaylandDisplay *disp = GDK_WAYLAND_DISPLAY (display);
|
||||||
GdkWaylandSubsurface *sub;
|
GdkWaylandSubsurface *sub;
|
||||||
struct wl_region *region;
|
struct wl_region *region;
|
||||||
|
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
||||||
|
char *name;
|
||||||
|
|
||||||
if (disp->subcompositor == NULL || disp->viewporter == NULL)
|
if (disp->subcompositor == NULL || disp->viewporter == NULL)
|
||||||
{
|
{
|
||||||
@@ -825,8 +838,28 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
|||||||
wl_region_add (sub->opaque_region, 0, 0, G_MAXINT, G_MAXINT);
|
wl_region_add (sub->opaque_region, 0, 0, G_MAXINT, G_MAXINT);
|
||||||
wl_surface_set_opaque_region (sub->surface, sub->opaque_region);
|
wl_surface_set_opaque_region (sub->surface, sub->opaque_region);
|
||||||
|
|
||||||
|
gdk_display_init_dmabuf (display);
|
||||||
|
|
||||||
|
if (disp->linux_dmabuf)
|
||||||
|
{
|
||||||
|
dmabuf_formats_info_set_egl_formats (disp->dmabuf_formats_info, display->dmabuf_formats);
|
||||||
|
feedback = zwp_linux_dmabuf_v1_get_surface_feedback (disp->linux_dmabuf, sub->surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
feedback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = g_strdup_printf ("subsurface %p", sub);
|
||||||
|
sub->formats = dmabuf_formats_info_new (display,
|
||||||
|
name,
|
||||||
|
display->dmabuf_formats,
|
||||||
|
feedback,
|
||||||
|
dmabuf_formats_callback,
|
||||||
|
sub);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
|
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
|
||||||
|
|
||||||
return GDK_SUBSURFACE (sub);
|
return GDK_SUBSURFACE (sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ struct _GdkWaylandSurface
|
|||||||
uint32_t last_configure_serial;
|
uint32_t last_configure_serial;
|
||||||
|
|
||||||
int state_freeze_count;
|
int state_freeze_count;
|
||||||
|
|
||||||
|
DmabufFormatsInfo *formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
|
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
|
||||||
|
|||||||
@@ -936,6 +936,15 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
|
|||||||
self->display_server.wl_surface = wl_surface;
|
self->display_server.wl_surface = wl_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmabuf_formats_callback (gpointer data,
|
||||||
|
DmabufFormatsInfo *info)
|
||||||
|
{
|
||||||
|
GdkSurface *surface = data;
|
||||||
|
|
||||||
|
gdk_surface_set_dmabuf_formats (surface, info->formats);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_wayland_surface_constructed (GObject *object)
|
gdk_wayland_surface_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@@ -944,6 +953,8 @@ gdk_wayland_surface_constructed (GObject *object)
|
|||||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||||
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
|
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
|
||||||
|
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
||||||
|
char *name;
|
||||||
|
|
||||||
self->event_queue = wl_display_create_queue (display_wayland->wl_display);
|
self->event_queue = wl_display_create_queue (display_wayland->wl_display);
|
||||||
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
|
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
|
||||||
@@ -969,6 +980,29 @@ gdk_wayland_surface_constructed (GObject *object)
|
|||||||
|
|
||||||
gdk_wayland_surface_create_wl_surface (surface);
|
gdk_wayland_surface_create_wl_surface (surface);
|
||||||
|
|
||||||
|
gdk_display_init_dmabuf (display);
|
||||||
|
|
||||||
|
if (display_wayland->linux_dmabuf)
|
||||||
|
{
|
||||||
|
dmabuf_formats_info_set_egl_formats (display_wayland->dmabuf_formats_info,
|
||||||
|
display->dmabuf_formats);
|
||||||
|
feedback = zwp_linux_dmabuf_v1_get_surface_feedback (display_wayland->linux_dmabuf,
|
||||||
|
self->display_server.wl_surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
feedback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = g_strdup_printf ("surface %p", surface);
|
||||||
|
self->formats = dmabuf_formats_info_new (display,
|
||||||
|
name,
|
||||||
|
display->dmabuf_formats,
|
||||||
|
feedback,
|
||||||
|
dmabuf_formats_callback,
|
||||||
|
surface);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
|
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
|
||||||
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
|
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <gdk/wayland/gdkwaylanddevice.h>
|
#include <gdk/wayland/gdkwaylanddevice.h>
|
||||||
#include <gdk/wayland/gdkwaylanddisplay.h>
|
#include <gdk/wayland/gdkwaylanddisplay.h>
|
||||||
|
#include <gdk/wayland/gdkwaylanddmabufformats.h>
|
||||||
#include <gdk/wayland/gdkwaylandglcontext.h>
|
#include <gdk/wayland/gdkwaylandglcontext.h>
|
||||||
#include <gdk/wayland/gdkwaylandmonitor.h>
|
#include <gdk/wayland/gdkwaylandmonitor.h>
|
||||||
#include <gdk/wayland/gdkwaylandpopup.h>
|
#include <gdk/wayland/gdkwaylandpopup.h>
|
||||||
|
|||||||
40
gdk/wayland/gdkwaylanddmabufformats.h
Normal file
40
gdk/wayland/gdkwaylanddmabufformats.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/* gdkwaylanddmabufformats.h
|
||||||
|
*
|
||||||
|
* Copyright 2023 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||||
|
#error "Only <gdk/wayland/gdkwayland.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gdk/gdkdmabufformats.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_16
|
||||||
|
dev_t gdk_wayland_dmabuf_formats_get_main_device (GdkDmabufFormats *formats);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_16
|
||||||
|
dev_t gdk_wayland_dmabuf_formats_get_target_device (GdkDmabufFormats *formats,
|
||||||
|
gsize idx);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_16
|
||||||
|
gboolean gdk_wayland_dmabuf_formats_is_scanout (GdkDmabufFormats *formats,
|
||||||
|
gsize idx);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
@@ -30,6 +30,7 @@ gdk_wayland_sources = files([
|
|||||||
gdk_wayland_public_headers = files([
|
gdk_wayland_public_headers = files([
|
||||||
'gdkwaylanddevice.h',
|
'gdkwaylanddevice.h',
|
||||||
'gdkwaylanddisplay.h',
|
'gdkwaylanddisplay.h',
|
||||||
|
'gdkwaylanddmabufformats.h',
|
||||||
'gdkwaylandglcontext.h',
|
'gdkwaylandglcontext.h',
|
||||||
'gdkwaylandmonitor.h',
|
'gdkwaylandmonitor.h',
|
||||||
'gdkwaylandpopup.h',
|
'gdkwaylandpopup.h',
|
||||||
|
|||||||
@@ -483,6 +483,12 @@ gsk_renderer_render (GskRenderer *renderer,
|
|||||||
if (priv->surface == NULL)
|
if (priv->surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Offloading can change subsurface stacking, which may trigger
|
||||||
|
* surface property changes. We don't want them to take effect
|
||||||
|
* during frame processing.
|
||||||
|
*/
|
||||||
|
g_object_freeze_notify (G_OBJECT (priv->surface));
|
||||||
|
|
||||||
renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
||||||
|
|
||||||
clip = cairo_region_copy (region);
|
clip = cairo_region_copy (region);
|
||||||
@@ -528,6 +534,8 @@ gsk_renderer_render (GskRenderer *renderer,
|
|||||||
cairo_region_destroy (clip);
|
cairo_region_destroy (clip);
|
||||||
g_clear_pointer (&offload, gsk_offload_free);
|
g_clear_pointer (&offload, gsk_offload_free);
|
||||||
priv->prev_node = gsk_render_node_ref (root);
|
priv->prev_node = gsk_render_node_ref (root);
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (priv->surface));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
|
|||||||
@@ -132,12 +132,15 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
|
|||||||
GstPlayer *player)
|
GstPlayer *player)
|
||||||
{
|
{
|
||||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
|
GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
|
||||||
|
GdkDmabufFormats *dmabuf_formats;
|
||||||
GstElement *sink;
|
GstElement *sink;
|
||||||
GdkGLContext *ctx;
|
GdkGLContext *ctx;
|
||||||
|
|
||||||
|
dmabuf_formats = gdk_display_get_dmabuf_formats (gdk_display_get_default ());
|
||||||
sink = g_object_new (GTK_TYPE_GST_SINK,
|
sink = g_object_new (GTK_TYPE_GST_SINK,
|
||||||
"paintable", self,
|
"paintable", self,
|
||||||
"gl-context", self->context,
|
"gl-context", self->context,
|
||||||
|
"dmabuf-formats", dmabuf_formats,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (self->context != NULL)
|
if (self->context != NULL)
|
||||||
|
|||||||
@@ -178,13 +178,12 @@ gtk_gst_sink_get_caps (GstBaseSink *bsink,
|
|||||||
{
|
{
|
||||||
tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
|
tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
|
||||||
#ifdef HAVE_GSTREAMER_DRM
|
#ifdef HAVE_GSTREAMER_DRM
|
||||||
{
|
GdkSurface *surface;
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (self->gdk_context);
|
|
||||||
GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (display);
|
|
||||||
|
|
||||||
tmp = gst_caps_make_writable (tmp);
|
tmp = gst_caps_make_writable (tmp);
|
||||||
add_drm_formats_and_modifiers (tmp, formats);
|
|
||||||
}
|
surface = gdk_gl_context_get_surface (self->gdk_context);
|
||||||
|
add_drm_formats_and_modifiers (tmp, gdk_surface_get_dmabuf_formats (surface));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
#include <gdk/gdkglcontextprivate.h>
|
#include <gdk/gdkglcontextprivate.h>
|
||||||
#include <gdk/gdkdmabuffourccprivate.h>
|
#include <gdk/gdkdmabuffourccprivate.h>
|
||||||
#include <gdk/gdkdmabuftextureprivate.h>
|
#include <gdk/gdkdmabuftextureprivate.h>
|
||||||
|
#include <gdk/gdkdmabufformatsprivate.h>
|
||||||
|
#include <gdk/gdkdmabufformatsbuilderprivate.h>
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
#include <gdk/wayland/gdkwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dmabuf_formats_basic (void)
|
test_dmabuf_formats_basic (void)
|
||||||
@@ -82,6 +88,102 @@ test_dmabuf_formats_builder (void)
|
|||||||
gdk_dmabuf_formats_unref (formats1);
|
gdk_dmabuf_formats_unref (formats1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AAAA fourcc_code ('A', 'A', 'A', 'A')
|
||||||
|
#define BBBB fourcc_code ('B', 'B', 'B', 'B')
|
||||||
|
#define CCCC fourcc_code ('C', 'C', 'C', 'C')
|
||||||
|
#define DDDD fourcc_code ('D', 'D', 'D', 'D')
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dmabuf_format_matches (const GdkDmabufFormat *f1, guint32 fourcc, guint64 modifier, gsize next_priority)
|
||||||
|
{
|
||||||
|
return f1->fourcc == fourcc &&
|
||||||
|
f1->modifier == modifier &&
|
||||||
|
f1->next_priority == next_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that sorting respects priorities, and the highest priority instance
|
||||||
|
* of duplicates is kept.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
test_priorities (void)
|
||||||
|
{
|
||||||
|
GdkDmabufFormatsBuilder *builder;
|
||||||
|
GdkDmabufFormats *formats;
|
||||||
|
const GdkDmabufFormat *f;
|
||||||
|
|
||||||
|
builder = gdk_dmabuf_formats_builder_new ();
|
||||||
|
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, AAAA, DRM_FORMAT_MOD_LINEAR);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, BBBB, DRM_FORMAT_MOD_LINEAR);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, AAAA, I915_FORMAT_MOD_X_TILED);
|
||||||
|
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, DDDD, I915_FORMAT_MOD_X_TILED);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, BBBB, I915_FORMAT_MOD_X_TILED);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, CCCC, DRM_FORMAT_MOD_LINEAR);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, BBBB, DRM_FORMAT_MOD_LINEAR); // a duplicate
|
||||||
|
|
||||||
|
formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||||
|
|
||||||
|
g_assert_true (gdk_dmabuf_formats_get_n_formats (formats) == 6);
|
||||||
|
|
||||||
|
f = gdk_dmabuf_formats_peek_formats (formats);
|
||||||
|
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[0], AAAA, DRM_FORMAT_MOD_LINEAR, 3));
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[1], AAAA, I915_FORMAT_MOD_X_TILED, 3));
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[2], BBBB, DRM_FORMAT_MOD_LINEAR, 3));
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[3], BBBB, I915_FORMAT_MOD_X_TILED, 6));
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[4], CCCC, DRM_FORMAT_MOD_LINEAR, 6));
|
||||||
|
g_assert_true (dmabuf_format_matches (&f[5], DDDD, I915_FORMAT_MOD_X_TILED, 6));
|
||||||
|
|
||||||
|
gdk_dmabuf_formats_unref (formats);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_wayland (void)
|
||||||
|
{
|
||||||
|
GdkDmabufFormatsBuilder *builder;
|
||||||
|
GdkDmabufFormats *formats1, *formats2;
|
||||||
|
|
||||||
|
builder = gdk_dmabuf_formats_builder_new ();
|
||||||
|
gdk_dmabuf_formats_builder_add_format_for_device (builder,
|
||||||
|
DRM_FORMAT_RGBA8888,
|
||||||
|
0,
|
||||||
|
DRM_FORMAT_MOD_LINEAR,
|
||||||
|
0);
|
||||||
|
gdk_dmabuf_formats_builder_add_format_for_device (builder,
|
||||||
|
DRM_FORMAT_ARGB8888,
|
||||||
|
0,
|
||||||
|
DRM_FORMAT_MOD_LINEAR,
|
||||||
|
1);
|
||||||
|
formats1 = gdk_dmabuf_formats_builder_free_to_formats_for_device (builder, 2);
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_main_device (formats1) == 2);
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_target_device (formats1, 0) == 0);
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_target_device (formats1, 1) == 1);
|
||||||
|
g_assert_false (gdk_wayland_dmabuf_formats_is_scanout (formats1, 0));
|
||||||
|
g_assert_false (gdk_wayland_dmabuf_formats_is_scanout (formats1, 1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
builder = gdk_dmabuf_formats_builder_new ();
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR);
|
||||||
|
gdk_dmabuf_formats_builder_add_format (builder, DRM_FORMAT_RGBA8888, DRM_FORMAT_MOD_LINEAR);
|
||||||
|
formats2 = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_main_device (formats2) == 0);
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_target_device (formats2, 0) == 0);
|
||||||
|
g_assert_true (gdk_wayland_dmabuf_formats_get_target_device (formats2, 1) == 0);
|
||||||
|
g_assert_false (gdk_wayland_dmabuf_formats_is_scanout (formats2, 0));
|
||||||
|
g_assert_false (gdk_wayland_dmabuf_formats_is_scanout (formats2, 1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_assert_false (gdk_dmabuf_formats_equal (formats1, formats2));
|
||||||
|
|
||||||
|
gdk_dmabuf_formats_unref (formats1);
|
||||||
|
gdk_dmabuf_formats_unref (formats2);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -89,6 +191,8 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
g_test_add_func ("/dmabuf/formats/basic", test_dmabuf_formats_basic);
|
g_test_add_func ("/dmabuf/formats/basic", test_dmabuf_formats_basic);
|
||||||
g_test_add_func ("/dmabuf/formats/builder", test_dmabuf_formats_builder);
|
g_test_add_func ("/dmabuf/formats/builder", test_dmabuf_formats_builder);
|
||||||
|
g_test_add_func ("/dmabuf/formats/priorities", test_priorities);
|
||||||
|
g_test_add_func ("/dmabuf/formats/wayland", test_wayland);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user