From 7ed7134f96597f046ff777a589108d0fb29e6e25 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 10 Oct 2023 11:51:48 -0400 Subject: [PATCH] Add GdkDmabufFormats This is an immutable struct containing information about supported dma-buf formats and their properties. --- gdk/gdk.h | 1 + gdk/gdkdmabufformats.c | 203 ++++++++++++++++++++++++++++++++++ gdk/gdkdmabufformats.h | 54 +++++++++ gdk/gdkdmabufformatsprivate.h | 13 +++ gdk/gdktypes.h | 2 + gdk/meson.build | 2 + 6 files changed, 275 insertions(+) create mode 100644 gdk/gdkdmabufformats.c create mode 100644 gdk/gdkdmabufformats.h create mode 100644 gdk/gdkdmabufformatsprivate.h diff --git a/gdk/gdk.h b/gdk/gdk.h index 6b69c4dd89..462682be48 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/gdk/gdkdmabufformats.c b/gdk/gdkdmabufformats.c new file mode 100644 index 0000000000..61227310a8 --- /dev/null +++ b/gdk/gdkdmabufformats.c @@ -0,0 +1,203 @@ +/* gdkdmabufformats.c + * + * 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 . + */ + +#include + +#include +#include "gdkdmabufformatsprivate.h" + + +/** + * GdkDmabufFormats: + * + * The `GdkDmabufFormats struct provides information about + * supported DMA buffer formats. + * + * You can query whether a given format is supported with + * [method@Gdk.DmabufFormats.contains] and you can iterate + * over the list of all supported formats with + * [method@Gdk.DmabufFormats.get_n_formats] and + * [method@Gdk.DmabufFormats.get_format]. + * + * The list of supported formats is sorted by preference, + * with the best formats coming first. + * + * See [class@Gdk.DmabufTextureBuilder] for more information + * about DMA buffers. + * + * 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) + +/** + * gdk_dmabuf_formats_ref: + * @formats: a `GdkDmabufFormats` + * + * Increases the reference count of @formats. + * + * Returns: the passed-in object + * + * Since: 4.14 + */ +GdkDmabufFormats * +gdk_dmabuf_formats_ref (GdkDmabufFormats *formats) +{ + formats->ref_count++; + + return formats; +} + +/** + * gdk_dmabuf_formats_unref: + * @formats: a `GdkDmabufFormats` + * + * Decreases the reference count of @formats. + * + * When the reference count reaches zero, + * the object is freed. + * + * Since: 4.14 + */ +void +gdk_dmabuf_formats_unref (GdkDmabufFormats *formats) +{ + formats->ref_count--; + + if (formats->ref_count > 0) + return; + + g_free (formats->formats); + g_free (formats); +} + +/** + * gdk_dmabuf_formats_get_n_formats: + * @formats: a `GdkDmabufFormats` + * + * Returns the number of formats that the + * @formats object contains. + * + * Returns: the number of formats + * + * Since: 4.14 + */ +gsize +gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats) +{ + return formats->n_formats; +} + +/** + * gdk_dmabuf_formats_get_format: + * @formats: a `GdkDmabufFormats` + * @idx: the index of the format to return + * @fourcc: (out): return location for the format code + * @modifier: (out): return location for the format modifier + * + * Gets the fourcc code and modifier for a format + * that is contained in @formats. + * + * Since: 4.14 + */ +void +gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats, + gsize idx, + guint32 *fourcc, + guint64 *modifier) +{ + GdkDmabufFormat *format; + + g_return_if_fail (idx < formats->n_formats); + g_return_if_fail (fourcc != NULL); + g_return_if_fail (modifier != NULL); + + format = &formats->formats[idx]; + + *fourcc = format->fourcc; + *modifier = format->modifier; +} + +/** + * gdk_dmabuf_format_contains: + * @formats: a `GdkDmabufFormats` + * @fourcc: a format code + * @modfier: a format modifier + * + * Returns whether a given format is contained in @formats. + * + * Returns: `TRUE` if the format specified by the arguments + * is part of @formats + * + * Since: 4.14 + */ +gboolean +gdk_dmabuf_formats_contains (GdkDmabufFormats *formats, + guint32 fourcc, + guint64 modifier) +{ + for (gsize i = 0; i < formats->n_formats; i++) + { + GdkDmabufFormat *format = &formats->formats[i]; + + if (format->fourcc == fourcc && format->modifier == modifier) + return TRUE; + } + + return FALSE; +} + +/*< private > + * gdk_dmabuf_formats_new: + * @formats: the formats + * @n_formats: the length of @formats + * + * Creates a new `GdkDmabufFormats struct for + * the given formats. + * + * The @formats array is expected to be sorted + * by preference. + * + * Returns: (transfer full): the new `GdkDmabufFormats` + * + * Since: 4.14 + */ +GdkDmabufFormats * +gdk_dmabuf_formats_new (GdkDmabufFormat *formats, + gsize n_formats) +{ + GdkDmabufFormats *self; + + self = g_new0 (GdkDmabufFormats, 1); + + self->ref_count = 1; + self->n_formats = n_formats; + self->formats = g_new (GdkDmabufFormat, n_formats); + + memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat)); + + return self; +} diff --git a/gdk/gdkdmabufformats.h b/gdk/gdkdmabufformats.h new file mode 100644 index 0000000000..d9388d5ef0 --- /dev/null +++ b/gdk/gdkdmabufformats.h @@ -0,0 +1,54 @@ +/* gdkdmabufformats.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 . + */ + +#pragma once + +#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_DMABUF_FORMATS (gdk_dmabuf_formats_get_type ()) + +GDK_AVAILABLE_IN_4_14 +GType gdk_dmabuf_formats_get_type (void) G_GNUC_CONST; + +GDK_AVAILABLE_IN_4_14 +GdkDmabufFormats * gdk_dmabuf_formats_ref (GdkDmabufFormats *formats); + +GDK_AVAILABLE_IN_4_14 +void gdk_dmabuf_formats_unref (GdkDmabufFormats *formats); + +GDK_AVAILABLE_IN_4_14 +gsize gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats); + +GDK_AVAILABLE_IN_4_14 +void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats, + gsize idx, + guint32 *fourcc, + guint64 *modifier); + +GDK_AVAILABLE_IN_4_14 +gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats, + guint32 fourcc, + guint64 modifier); + +G_END_DECLS diff --git a/gdk/gdkdmabufformatsprivate.h b/gdk/gdkdmabufformatsprivate.h new file mode 100644 index 0000000000..c204a75d2e --- /dev/null +++ b/gdk/gdkdmabufformatsprivate.h @@ -0,0 +1,13 @@ +#pragma once + +#include "gdkdmabufformats.h" + +typedef struct _GdkDmabufFormat GdkDmabufFormat; +struct _GdkDmabufFormat +{ + guint32 fourcc; + guint64 modifier; +}; + +GdkDmabufFormats *gdk_dmabuf_formats_new (GdkDmabufFormat *formats, + gsize n_formats); diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 489ca9cbcc..a014c8c3af 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -96,6 +96,8 @@ typedef struct _GdkCairoContext GdkCairoContext; typedef struct _GdkGLContext GdkGLContext; typedef struct _GdkVulkanContext GdkVulkanContext; +typedef struct _GdkDmabufFormats GdkDmabufFormats; + /* * GDK_DECLARE_INTERNAL_TYPE: * @ModuleObjName: The name of the new type, in camel case (like GtkWidget) diff --git a/gdk/meson.build b/gdk/meson.build index 6b2f50950d..3d0d0cc77d 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -17,6 +17,7 @@ gdk_public_sources = files([ 'gdkdevicetool.c', 'gdkdisplay.c', 'gdkdisplaymanager.c', + 'gdkdmabufformats.c', 'gdkdrag.c', 'gdkdragsurface.c', 'gdkdragsurfacesize.c', @@ -79,6 +80,7 @@ gdk_public_headers = files([ 'gdkdisplay.h', 'gdkdisplaymanager.h', 'gdkdrag.h', + 'gdkdmabufformats.h', 'gdkdragsurfacesize.h', 'gdkdrawcontext.h', 'gdkdrop.h',