#include "config.h"
#include "gdkdmabuf-wayland-private.h"
#include "gdkdebugprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#include <fcntl.h>
#include <sys/mman.h>
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#include "linux-dmabuf-unstable-v1-client-protocol.h"
static DmabufTranche *
dmabuf_tranche_new (void )
{
return g_new0 (DmabufTranche, 1 );
}
static void
dmabuf_tranche_free (DmabufTranche *tranche)
{
gdk_dmabuf_formats_unref (tranche->formats);
g_free (tranche);
}
static DmabufFormats *
dmabuf_formats_new (void )
{
DmabufFormats *formats;
formats = g_new0 (DmabufFormats, 1 );
formats->tranches = g_ptr_array_new_with_free_func ((GDestroyNotify) dmabuf_tranche_free);
return formats;
}
static void
dmabuf_formats_free (DmabufFormats *formats)
{
g_ptr_array_unref (formats->tranches);
g_free (formats);
}
static void
update_dmabuf_formats (DmabufFormatsInfo *info)
{
DmabufFormats *formats = info->dmabuf_formats;
GDK_DISPLAY_DEBUG_FULL (info->display, GDK_DEBUG_DMABUF | GDK_DEBUG_MISC,
"dmabuf format table (%" G_GSIZE_FORMAT " entries)" ,
info->n_dmabuf_formats);
#ifdef HAVE_SYS_SYSMACROS_H
GDK_DISPLAY_DEBUG_FULL (info->display, GDK_DEBUG_DMABUF | GDK_DEBUG_MISC,
"dmabuf main device: %u %u" ,
major (formats->main_device),
minor (formats->main_device));
#endif
for (gsize i = 0 ; i < formats->tranches->len; i++)
{
DmabufTranche *tranche = g_ptr_array_index (formats->tranches, i);
gsize n_formats = gdk_dmabuf_formats_get_n_formats (tranche->formats);
#ifdef HAVE_SYS_SYSMACROS_H
GDK_DISPLAY_DEBUG_FULL (info->display, GDK_DEBUG_DMABUF | GDK_DEBUG_MISC,
"dmabuf tranche target device: %u %u" ,
major (tranche->target_device),
minor (tranche->target_device));
#endif
GDK_DISPLAY_DEBUG_FULL (info->display, GDK_DEBUG_DMABUF | GDK_DEBUG_MISC,
"dmabuf%s tranche (%" G_GSIZE_FORMAT " entries):" ,
tranche->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ?
" scanout" : "" ,
n_formats);
for (gsize j = 0 ; j < n_formats; j++)
{
guint32 fourcc;
guint64 modifier;
gdk_dmabuf_formats_get_format (tranche->formats, j, &fourcc, &modifier);
GDK_DISPLAY_DEBUG_FULL (info->display, GDK_DEBUG_DMABUF | GDK_DEBUG_MISC,
" %.4s:%#" G_GINT64_MODIFIER "x" ,
(char *) &fourcc, modifier);
}
}
}
static void
linux_dmabuf_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback)
{
DmabufFormatsInfo *info = data;
g_clear_pointer (&info->dmabuf_formats, dmabuf_formats_free);
info->dmabuf_formats = info->pending_dmabuf_formats;
info->pending_dmabuf_formats = NULL;
update_dmabuf_formats (info);
}
static void
linux_dmabuf_format_table (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback,
int32_t fd,
uint32_t size)
{
DmabufFormatsInfo *info = data;
if (info->dmabuf_formats)
munmap (info->dmabuf_formats, sizeof (DmabufFormat) * info->n_dmabuf_formats);
info->n_dmabuf_formats = size / 16 ;
info->dmabuf_format_table = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0 );
close (fd);
}
static void
linux_dmabuf_main_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback,
struct wl_array *device)
{
DmabufFormatsInfo *info = data;
dev_t dev;
memcpy (&dev, device->data, sizeof (dev_t));
g_assert (info->pending_dmabuf_formats == NULL);
info->pending_dmabuf_formats = dmabuf_formats_new ();
info->pending_dmabuf_formats->main_device = dev;
}
static void
linux_dmabuf_tranche_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback)
{
DmabufFormatsInfo *info = data;
g_ptr_array_add (info->pending_dmabuf_formats->tranches,
info->pending_tranche);
info->pending_tranche = NULL;
}
static void
linux_dmabuf_tranche_target_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback,
struct wl_array *device)
{
DmabufFormatsInfo *info = data;
dev_t dev;
DmabufTranche *tranche;
memcpy (&dev, device->data, sizeof (dev_t));
g_assert (info->pending_tranche == NULL);
tranche = dmabuf_tranche_new ();
tranche->target_device = dev;
info->pending_tranche = tranche;
}
static void
linux_dmabuf_tranche_formats (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback,
struct wl_array *indices)
{
DmabufFormatsInfo *info = data;
DmabufTranche *tranche;
GdkDmabufFormatsBuilder *formats_builder;
uint16_t *pos;
g_assert (info->pending_tranche != NULL);
tranche = info->pending_tranche;
formats_builder = gdk_dmabuf_formats_builder_new ();
wl_array_for_each (pos, indices)
{
DmabufFormat *format = &info->dmabuf_format_table[*pos];
gdk_dmabuf_formats_builder_add_format (formats_builder,
format->fourcc,
format->modifier);
}
tranche->formats =
gdk_dmabuf_formats_builder_free_to_formats (g_steal_pointer (&formats_builder));
}
static void
linux_dmabuf_tranche_flags (void *data,
struct zwp_linux_dmabuf_feedback_v1 *feedback,
uint32_t flags)
{
DmabufFormatsInfo *info = data;
DmabufTranche *tranche;
g_assert (info->pending_tranche != NULL);
tranche = info->pending_tranche;
tranche->flags = flags;
}
static const struct zwp_linux_dmabuf_feedback_v1_listener feedback_listener = {
linux_dmabuf_done,
linux_dmabuf_format_table,
linux_dmabuf_main_device,
linux_dmabuf_tranche_done,
linux_dmabuf_tranche_target_device,
linux_dmabuf_tranche_formats,
linux_dmabuf_tranche_flags,
};
DmabufFormatsInfo *
dmabuf_formats_info_new (GdkDisplay *display,
const char *name,
struct zwp_linux_dmabuf_feedback_v1 *feedback)
{
DmabufFormatsInfo *info;
info = g_new0 (DmabufFormatsInfo, 1 );
info->display = display;
info->name = g_strdup (name);
info->feedback = feedback;
if (info->feedback)
zwp_linux_dmabuf_feedback_v1_add_listener (info->feedback,
&feedback_listener, info);
return info;
}
void
dmabuf_formats_info_free (DmabufFormatsInfo *info)
{
g_free (info->name);
g_clear_pointer (&info->feedback, zwp_linux_dmabuf_feedback_v1_destroy);
if (info->dmabuf_format_table)
{
munmap (info->dmabuf_format_table, info->n_dmabuf_formats * 16 );
info->dmabuf_format_table = NULL;
}
g_clear_pointer (&info->dmabuf_formats, dmabuf_formats_free);
g_clear_pointer (&info->pending_dmabuf_formats, dmabuf_formats_free);
g_clear_pointer (&info->pending_tranche, dmabuf_tranche_free);
g_free (info);
}
Messung V0.5 in Prozent C=98 H=96 G=96
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-07-02)
¤
*© Formatika GbR, Deutschland