Compare commits
9 Commits
main
...
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
|
||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (self, builder));
|
||||
gdk_dmabuf_formats_builder_next_priority (builder);
|
||||
#endif
|
||||
|
||||
gdk_dmabuf_formats_builder_add_formats (builder,
|
||||
@@ -2016,6 +2017,29 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Initialized support for %zu 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)
|
||||
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);
|
||||
|
@@ -93,24 +93,17 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
|
||||
for (int j = 0; j < num_modifiers; j++)
|
||||
{
|
||||
/* All linear formats we support are already added my the mmap downloader.
|
||||
* 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)))
|
||||
if (!external_only[j])
|
||||
{
|
||||
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]);
|
||||
all_external = FALSE;
|
||||
}
|
||||
if (external_only[j])
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
||||
else
|
||||
all_external = FALSE;
|
||||
{
|
||||
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.
|
||||
@@ -120,9 +113,9 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
* As an extra wrinkle, treat the implicit modifier as '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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -149,6 +142,7 @@ GdkDmabufDownloader *
|
||||
gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder)
|
||||
{
|
||||
GdkGLContext *context;
|
||||
GdkDmabufFormatsBuilder *formats;
|
||||
GdkDmabufFormatsBuilder *external;
|
||||
gboolean retval = FALSE;
|
||||
@@ -163,6 +157,8 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
|
||||
return NULL;
|
||||
|
||||
previous = gdk_gl_context_get_current ();
|
||||
context = gdk_display_get_gl_context (display);
|
||||
|
||||
formats = 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);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@@ -49,14 +49,6 @@
|
||||
* 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)
|
||||
|
||||
/**
|
||||
@@ -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`
|
||||
* @fourcc: a format code
|
||||
* @modifier: a format modifier
|
||||
@@ -184,6 +205,8 @@ gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||
* gdk_dmabuf_formats_new:
|
||||
* @formats: the 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
|
||||
* the given formats.
|
||||
@@ -197,7 +220,8 @@ gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||
*/
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||
gsize n_formats)
|
||||
gsize n_formats,
|
||||
guint64 device)
|
||||
{
|
||||
GdkDmabufFormats *self;
|
||||
|
||||
@@ -206,6 +230,7 @@ gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||
self->ref_count = 1;
|
||||
self->n_formats = n_formats;
|
||||
self->formats = g_new (GdkDmabufFormat, n_formats);
|
||||
self->device = device;
|
||||
|
||||
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
|
||||
|
||||
@@ -240,6 +265,9 @@ gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
if (formats1 == NULL || formats2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (formats1->device != formats2->device)
|
||||
return FALSE;
|
||||
|
||||
if (formats1->n_formats != formats2->n_formats)
|
||||
return FALSE;
|
||||
|
||||
@@ -249,7 +277,10 @@ gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
GdkDmabufFormat *f2 = &formats2->formats[i];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,10 @@ void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats
|
||||
guint32 *fourcc,
|
||||
guint64 *modifier);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
gsize gdk_dmabuf_formats_next_priority (GdkDmabufFormats *formats,
|
||||
gsize idx);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||
guint32 fourcc,
|
||||
|
@@ -52,7 +52,9 @@ gdk_dmabuf_format_compare (gconstpointer data_a,
|
||||
const GdkDmabufFormat *a = data_a;
|
||||
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));
|
||||
else
|
||||
return a->fourcc - b->fourcc;
|
||||
@@ -67,7 +69,9 @@ gdk_dmabuf_format_equal (gconstpointer data_a,
|
||||
const GdkDmabufFormat *b = data_b;
|
||||
|
||||
return a->fourcc == b->fourcc &&
|
||||
a->modifier == b->modifier;
|
||||
a->flags == b->flags &&
|
||||
a->modifier == b->modifier &&
|
||||
a->device == b->device;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -79,38 +83,46 @@ gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
|
||||
gdk_dmabuf_format_compare);
|
||||
}
|
||||
|
||||
/* list must be sorted */
|
||||
static void
|
||||
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_builder_free_to_formats_for_device (GdkDmabufFormatsBuilder *self,
|
||||
guint64 device)
|
||||
{
|
||||
gsize i, j;
|
||||
GdkDmabufFormats *formats;
|
||||
|
||||
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
||||
{
|
||||
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
|
||||
gdk_dmabuf_formats_builder_get (self, j)))
|
||||
continue;
|
||||
gdk_dmabuf_formats_builder_next_priority (self);
|
||||
gdk_dmabuf_formats_builder_sort (self);
|
||||
|
||||
j++;
|
||||
if (i != j)
|
||||
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
|
||||
}
|
||||
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
|
||||
gdk_dmabuf_formats_builder_get_size (self),
|
||||
device);
|
||||
gdk_dmabuf_formats_builder_clear (self);
|
||||
g_free (self);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
GdkDmabufFormats *
|
||||
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);
|
||||
gdk_dmabuf_formats_builder_remove_duplicates (self);
|
||||
void
|
||||
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),
|
||||
gdk_dmabuf_formats_builder_get_size (self));
|
||||
gdk_dmabuf_formats_builder_clear (self);
|
||||
g_free (self);
|
||||
for (gsize i = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
||||
{
|
||||
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i), &format))
|
||||
return;
|
||||
}
|
||||
|
||||
return formats;
|
||||
gdk_dmabuf_formats_builder_append (self, &format);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -118,17 +130,33 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
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
|
||||
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||
GdkDmabufFormats *formats)
|
||||
{
|
||||
gdk_dmabuf_formats_builder_splice (self,
|
||||
gdk_dmabuf_formats_builder_get_size (self),
|
||||
0,
|
||||
FALSE,
|
||||
gdk_dmabuf_formats_peek_formats (formats),
|
||||
gdk_dmabuf_formats_get_n_formats (formats));
|
||||
for (gsize i = 0; i < gdk_dmabuf_formats_get_n_formats (formats); i++)
|
||||
{
|
||||
guint32 fourcc;
|
||||
guint64 modifier;
|
||||
|
||||
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;
|
||||
|
||||
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
|
||||
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
|
||||
GdkDmabufFormatsBuilder *gdk_dmabuf_formats_builder_new (void);
|
||||
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
|
||||
|
||||
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier);
|
||||
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||
GdkDmabufFormats *formats);
|
||||
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
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,
|
||||
GdkDmabufFormats *formats);
|
||||
|
@@ -6,10 +6,23 @@ typedef struct _GdkDmabufFormat GdkDmabufFormat;
|
||||
struct _GdkDmabufFormat
|
||||
{
|
||||
guint32 fourcc;
|
||||
guint32 flags;
|
||||
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,
|
||||
gsize n_formats);
|
||||
gsize n_formats,
|
||||
guint64 device);
|
||||
|
||||
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktexture.h"
|
||||
#include "gsk/gskrectprivate.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
|
||||
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_clear_object (&subsurface->parent);
|
||||
g_clear_pointer (&subsurface->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
|
||||
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 >
|
||||
* gdk_subsurface_attach:
|
||||
* @subsurface: the `GdkSubsurface`
|
||||
@@ -150,7 +174,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
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_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 || sibling->parent == subsurface->parent, FALSE);
|
||||
|
||||
was_topmost = is_topmost_subsurface (subsurface);
|
||||
|
||||
result = GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface,
|
||||
texture,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -212,10 +261,25 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
void
|
||||
gdk_subsurface_detach (GdkSubsurface *subsurface)
|
||||
{
|
||||
gboolean was_topmost;
|
||||
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
|
||||
was_topmost = is_topmost_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);
|
||||
}
|
||||
|
||||
@@ -370,3 +434,17 @@ gdk_subsurface_get_bounds (GdkSubsurface *subsurface,
|
||||
if (gdk_subsurface_get_background_rect (subsurface, &background))
|
||||
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 "gdksurface.h"
|
||||
#include "gdkdmabufformats.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -45,6 +46,8 @@ struct _GdkSubsurface
|
||||
gboolean above_parent;
|
||||
GdkSubsurface *sibling_above;
|
||||
GdkSubsurface *sibling_below;
|
||||
|
||||
GdkDmabufFormats *dmabuf_formats;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -109,6 +112,8 @@ gboolean gdk_subsurface_get_background_rect (GdkSubsurface *subsu
|
||||
graphene_rect_t *rect);
|
||||
void gdk_subsurface_get_bounds (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *bounds);
|
||||
void gdk_subsurface_set_dmabuf_formats (GdkSubsurface *subsurface,
|
||||
GdkDmabufFormats *formats);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -91,6 +91,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_CURSOR,
|
||||
PROP_DISPLAY,
|
||||
PROP_DMABUF_FORMATS,
|
||||
PROP_FRAME_CLOCK,
|
||||
PROP_MAPPED,
|
||||
PROP_WIDTH,
|
||||
@@ -548,6 +549,18 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
GDK_TYPE_DISPLAY,
|
||||
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)
|
||||
*
|
||||
@@ -773,6 +786,9 @@ gdk_surface_finalize (GObject *object)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -827,6 +843,10 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_object (value, surface->display);
|
||||
break;
|
||||
|
||||
case PROP_DMABUF_FORMATS:
|
||||
g_value_set_boxed (value, surface->effective_dmabuf_formats);
|
||||
break;
|
||||
|
||||
case PROP_FRAME_CLOCK:
|
||||
g_value_set_object (value, surface->frame_clock);
|
||||
break;
|
||||
@@ -3076,3 +3096,70 @@ gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
{
|
||||
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,
|
||||
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_END_DECLS
|
||||
|
@@ -105,6 +105,9 @@ struct _GdkSurface
|
||||
*/
|
||||
GdkSubsurface *subsurfaces_above;
|
||||
GdkSubsurface *subsurfaces_below;
|
||||
|
||||
GdkDmabufFormats *dmabuf_formats;
|
||||
GdkDmabufFormats *effective_dmabuf_formats;
|
||||
};
|
||||
|
||||
struct _GdkSurfaceClass
|
||||
@@ -355,4 +358,10 @@ gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
|
||||
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
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
|
||||
|
@@ -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_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
|
||||
gdk_registry_handle_global (void *data,
|
||||
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);
|
||||
display_wayland->dmabuf_formats_info = dmabuf_formats_info_new (GDK_DISPLAY (display_wayland),
|
||||
"default",
|
||||
feedback);
|
||||
NULL,
|
||||
feedback,
|
||||
dmabuf_formats_callback,
|
||||
display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
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->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
||||
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->wl_registry, wl_registry_destroy);
|
||||
|
@@ -100,6 +100,7 @@ struct _GdkWaylandDisplay
|
||||
struct wl_shm *shm;
|
||||
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
|
||||
DmabufFormatsInfo *dmabuf_formats_info;
|
||||
GdkDmabufFormats *wayland_dmabuf_formats;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||
struct gtk_shell1 *gtk_shell;
|
||||
|
@@ -54,24 +54,40 @@ typedef struct
|
||||
|
||||
typedef struct DmabufFormatsInfo DmabufFormatsInfo;
|
||||
|
||||
typedef void (* DmabufFormatsUpdateCallback) (gpointer data,
|
||||
DmabufFormatsInfo *formats);
|
||||
|
||||
struct DmabufFormatsInfo
|
||||
{
|
||||
GdkDisplay *display;
|
||||
char *name;
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
||||
|
||||
DmabufFormatsUpdateCallback callback;
|
||||
gpointer data;
|
||||
|
||||
gsize n_dmabuf_formats;
|
||||
DmabufFormat *dmabuf_format_table;
|
||||
|
||||
DmabufFormats *dmabuf_formats;
|
||||
DmabufFormats *pending_dmabuf_formats;
|
||||
DmabufTranche *pending_tranche;
|
||||
|
||||
GdkDmabufFormats *egl_formats;
|
||||
GdkDmabufFormats *formats;
|
||||
};
|
||||
|
||||
DmabufFormatsInfo * dmabuf_formats_info_new (GdkDisplay *display,
|
||||
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_set_egl_formats
|
||||
(DmabufFormatsInfo *info,
|
||||
GdkDmabufFormats *egl_formats);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdmabuf-wayland-private.h"
|
||||
#include "gdkwaylanddmabufformats.h"
|
||||
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
@@ -45,44 +46,116 @@ dmabuf_formats_free (DmabufFormats *formats)
|
||||
g_free (formats);
|
||||
}
|
||||
|
||||
static void
|
||||
update_dmabuf_formats (DmabufFormatsInfo *info)
|
||||
static gboolean
|
||||
is_in_tranche (GdkDmabufFormats *formats,
|
||||
gsize idx,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
{
|
||||
DmabufFormats *formats = info->dmabuf_formats;
|
||||
gsize end;
|
||||
guint32 f;
|
||||
guint64 m;
|
||||
|
||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
||||
"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++)
|
||||
end = gdk_dmabuf_formats_next_priority (formats, idx);
|
||||
for (gsize i = idx; i < end; i++)
|
||||
{
|
||||
DmabufTranche *tranche = g_ptr_array_index (formats->tranches, i);
|
||||
gdk_dmabuf_formats_get_format (formats, i, &f, &m);
|
||||
if (f == fourcc && m == modifier)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
||||
"dmabuf tranche target device: %u %u",
|
||||
major (tranche->target_device),
|
||||
minor (tranche->target_device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
for (gsize j = 0; j < tranche->n_formats; j++)
|
||||
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++)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (info->display, MISC,
|
||||
" %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
(char *) &(tranche->formats[j].fourcc),
|
||||
tranche->formats[j].modifier);
|
||||
format = &formats->formats[i];
|
||||
gdk_debug_message (" %.4s:%#" G_GINT64_MODIFIER "x", (char *) &format->fourcc, format->modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_done (void *data,
|
||||
update_dmabuf_formats (DmabufFormatsInfo *info)
|
||||
{
|
||||
GdkDmabufFormatsBuilder *builder;
|
||||
GdkDmabufFormats *egl_formats = info->egl_formats;
|
||||
DmabufFormats *formats = info->dmabuf_formats;
|
||||
|
||||
builder = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
for (gsize i = 0; i < formats->tranches->len; i++)
|
||||
{
|
||||
DmabufTranche *tranche = g_ptr_array_index (formats->tranches, i);
|
||||
|
||||
if (egl_formats)
|
||||
{
|
||||
for (gsize k = 0; k < gdk_dmabuf_formats_get_n_formats (egl_formats); k = gdk_dmabuf_formats_next_priority (egl_formats, k))
|
||||
{
|
||||
for (gsize j = 0; j < tranche->n_formats; j++)
|
||||
{
|
||||
if (is_in_tranche (egl_formats, k,
|
||||
tranche->formats[j].fourcc,
|
||||
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
|
||||
linux_dmabuf_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
@@ -96,10 +169,10 @@ linux_dmabuf_done (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_format_table (void *data,
|
||||
linux_dmabuf_format_table (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
int32_t fd,
|
||||
uint32_t size)
|
||||
int32_t fd,
|
||||
uint32_t size)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
|
||||
@@ -111,9 +184,9 @@ linux_dmabuf_format_table (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_main_device (void *data,
|
||||
linux_dmabuf_main_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *device)
|
||||
struct wl_array *device)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
dev_t dev;
|
||||
@@ -127,7 +200,7 @@ linux_dmabuf_main_device (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_done (void *data,
|
||||
linux_dmabuf_tranche_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
@@ -139,9 +212,9 @@ linux_dmabuf_tranche_done (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_target_device (void *data,
|
||||
linux_dmabuf_tranche_target_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *device)
|
||||
struct wl_array *device)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
dev_t dev;
|
||||
@@ -158,9 +231,9 @@ linux_dmabuf_tranche_target_device (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_formats (void *data,
|
||||
linux_dmabuf_tranche_formats (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *indices)
|
||||
struct wl_array *indices)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
DmabufTranche *tranche;
|
||||
@@ -181,9 +254,9 @@ linux_dmabuf_tranche_formats (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_flags (void *data,
|
||||
linux_dmabuf_tranche_flags (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
uint32_t flags)
|
||||
uint32_t flags)
|
||||
{
|
||||
DmabufFormatsInfo *info = data;
|
||||
DmabufTranche *tranche;
|
||||
@@ -206,7 +279,10 @@ static const struct zwp_linux_dmabuf_feedback_v1_listener feedback_listener = {
|
||||
DmabufFormatsInfo *
|
||||
dmabuf_formats_info_new (GdkDisplay *display,
|
||||
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;
|
||||
|
||||
@@ -214,11 +290,21 @@ dmabuf_formats_info_new (GdkDisplay *display,
|
||||
|
||||
info->display = display;
|
||||
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->callback = callback;
|
||||
info->data = data;
|
||||
|
||||
if (info->feedback)
|
||||
zwp_linux_dmabuf_feedback_v1_add_listener (info->feedback,
|
||||
&feedback_listener, info);
|
||||
else
|
||||
info->callback (info->data, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -227,6 +313,8 @@ void
|
||||
dmabuf_formats_info_free (DmabufFormatsInfo *info)
|
||||
{
|
||||
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);
|
||||
if (info->dmabuf_format_table)
|
||||
{
|
||||
@@ -239,3 +327,91 @@ dmabuf_formats_info_free (DmabufFormatsInfo *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
|
||||
|
||||
#include "gdk/gdkdmabufformats.h"
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
#include "gdkdmabuf-wayland-private.h"
|
||||
|
||||
#include "wayland-client-protocol.h"
|
||||
|
||||
@@ -35,6 +37,8 @@ struct _GdkWaylandSubsurface
|
||||
struct wp_viewport *bg_viewport;
|
||||
cairo_rectangle_int_t bg_rect;
|
||||
gboolean bg_attached;
|
||||
|
||||
DmabufFormatsInfo *formats;
|
||||
};
|
||||
|
||||
struct _GdkWaylandSubsurfaceClass
|
||||
@@ -48,4 +52,3 @@ void gdk_wayland_subsurface_request_frame (GdkSubsurface *subsurface);
|
||||
void gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *subsurface);
|
||||
|
||||
GdkSubsurface * gdk_wayland_surface_create_subsurface (GdkSurface *surface);
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gsk/gskrectprivate.h"
|
||||
#include "gdkprivate.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_subsurface, wl_subsurface_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);
|
||||
}
|
||||
@@ -790,6 +792,15 @@ gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *sub)
|
||||
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 *
|
||||
gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
@@ -798,6 +809,8 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
||||
GdkWaylandDisplay *disp = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandSubsurface *sub;
|
||||
struct wl_region *region;
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback;
|
||||
char *name;
|
||||
|
||||
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_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);
|
||||
|
||||
return GDK_SUBSURFACE (sub);
|
||||
}
|
||||
|
||||
|
@@ -89,6 +89,8 @@ struct _GdkWaylandSurface
|
||||
uint32_t last_configure_serial;
|
||||
|
||||
int state_freeze_count;
|
||||
|
||||
DmabufFormatsInfo *formats;
|
||||
};
|
||||
|
||||
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
|
||||
|
@@ -936,6 +936,15 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *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
|
||||
gdk_wayland_surface_constructed (GObject *object)
|
||||
{
|
||||
@@ -944,6 +953,8 @@ gdk_wayland_surface_constructed (GObject *object)
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
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);
|
||||
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_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, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <gdk/wayland/gdkwaylanddevice.h>
|
||||
#include <gdk/wayland/gdkwaylanddisplay.h>
|
||||
#include <gdk/wayland/gdkwaylanddmabufformats.h>
|
||||
#include <gdk/wayland/gdkwaylandglcontext.h>
|
||||
#include <gdk/wayland/gdkwaylandmonitor.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([
|
||||
'gdkwaylanddevice.h',
|
||||
'gdkwaylanddisplay.h',
|
||||
'gdkwaylanddmabufformats.h',
|
||||
'gdkwaylandglcontext.h',
|
||||
'gdkwaylandmonitor.h',
|
||||
'gdkwaylandpopup.h',
|
||||
|
@@ -483,6 +483,12 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
if (priv->surface == NULL)
|
||||
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);
|
||||
|
||||
clip = cairo_region_copy (region);
|
||||
@@ -528,6 +534,8 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
cairo_region_destroy (clip);
|
||||
g_clear_pointer (&offload, gsk_offload_free);
|
||||
priv->prev_node = gsk_render_node_ref (root);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (priv->surface));
|
||||
}
|
||||
|
||||
/*< private >
|
||||
|
@@ -132,12 +132,15 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
|
||||
GstPlayer *player)
|
||||
{
|
||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
|
||||
GdkDmabufFormats *dmabuf_formats;
|
||||
GstElement *sink;
|
||||
GdkGLContext *ctx;
|
||||
|
||||
dmabuf_formats = gdk_display_get_dmabuf_formats (gdk_display_get_default ());
|
||||
sink = g_object_new (GTK_TYPE_GST_SINK,
|
||||
"paintable", self,
|
||||
"gl-context", self->context,
|
||||
"dmabuf-formats", dmabuf_formats,
|
||||
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));
|
||||
#ifdef HAVE_GSTREAMER_DRM
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self->gdk_context);
|
||||
GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
tmp = gst_caps_make_writable (tmp);
|
||||
add_drm_formats_and_modifiers (tmp, formats);
|
||||
}
|
||||
tmp = gst_caps_make_writable (tmp);
|
||||
|
||||
surface = gdk_gl_context_get_surface (self->gdk_context);
|
||||
add_drm_formats_and_modifiers (tmp, gdk_surface_get_dmabuf_formats (surface));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@@ -5,6 +5,12 @@
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkdmabuffourccprivate.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
|
||||
test_dmabuf_formats_basic (void)
|
||||
@@ -82,6 +88,102 @@ test_dmabuf_formats_builder (void)
|
||||
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
|
||||
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/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 ();
|
||||
}
|
||||
|
Reference in New Issue
Block a user