dmabuf: Add Wayland information
Add device and scanout information for dmabuf formats. While this is not a great API, there is no good alternative to making this information available to applications that want to negotiate dmabuf formats suitable for graphics offload. The getters for Wayland-specific information are kept as Wayland backend apis. Tests included.
This commit is contained in:
@@ -205,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.
|
||||
@@ -218,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;
|
||||
|
||||
@@ -227,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));
|
||||
|
||||
@@ -261,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;
|
||||
|
||||
@@ -271,7 +278,9 @@ gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
|
||||
if (f1->fourcc != f2->fourcc ||
|
||||
f1->modifier != f2->modifier ||
|
||||
f1->next_priority != f2->next_priority)
|
||||
f1->next_priority != f2->next_priority ||
|
||||
f1->flags != f2->flags ||
|
||||
f1->device != f2->device)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,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
|
||||
@@ -82,7 +84,8 @@ gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
|
||||
}
|
||||
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
||||
gdk_dmabuf_formats_builder_free_to_formats_for_device (GdkDmabufFormatsBuilder *self,
|
||||
guint64 device)
|
||||
{
|
||||
GdkDmabufFormats *formats;
|
||||
|
||||
@@ -90,19 +93,28 @@ gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
||||
gdk_dmabuf_formats_builder_sort (self);
|
||||
|
||||
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
|
||||
gdk_dmabuf_formats_builder_get_size (self));
|
||||
gdk_dmabuf_formats_builder_get_size (self),
|
||||
device);
|
||||
gdk_dmabuf_formats_builder_clear (self);
|
||||
g_free (self);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
||||
{
|
||||
GdkDmabufFormat format = { fourcc, modifier, G_MAXSIZE };
|
||||
return gdk_dmabuf_formats_builder_free_to_formats_for_device (self, 0);
|
||||
}
|
||||
|
||||
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 };
|
||||
|
||||
for (gsize i = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
||||
{
|
||||
@@ -113,6 +125,14 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
gdk_dmabuf_formats_builder_append (self, &format);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
{
|
||||
gdk_dmabuf_formats_builder_add_format_for_device (self, fourcc, 0, modifier, 0);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_formats_builder_next_priority (GdkDmabufFormatsBuilder *self)
|
||||
{
|
||||
|
||||
@@ -4,13 +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_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier);
|
||||
|
||||
void gdk_dmabuf_formats_builder_next_priority (GdkDmabufFormatsBuilder *self);
|
||||
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||
GdkDmabufFormats *formats);
|
||||
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,7 +6,9 @@ typedef struct _GdkDmabufFormat GdkDmabufFormat;
|
||||
struct _GdkDmabufFormat
|
||||
{
|
||||
guint32 fourcc;
|
||||
guint32 flags;
|
||||
guint64 modifier;
|
||||
guint64 device;
|
||||
gsize next_priority;
|
||||
};
|
||||
|
||||
@@ -16,9 +18,11 @@ struct _GdkDmabufFormats
|
||||
|
||||
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);
|
||||
|
||||
85
gdk/wayland/gdkdmabuf-wayland.c
Normal file
85
gdk/wayland/gdkdmabuf-wayland.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkwaylanddmabufformats.h"
|
||||
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
/**
|
||||
* 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 form the compositor), then 0 is returned.
|
||||
*
|
||||
* Returns: the main DRM device that the compositor prefers
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
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 form the compositor), then 0 is returned.
|
||||
*
|
||||
* Returns: the target DRM device for this format
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
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 intents to use buffers with this
|
||||
* format for scanout.
|
||||
*
|
||||
* If this information isn't available (e.g. because @formats wasn't
|
||||
* obtained form the compositor), then 0 is returned.
|
||||
*
|
||||
* Returns: whether the format will be used for scanout
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_wayland_dmabuf_formats_is_scanout (GdkDmabufFormats *formats,
|
||||
gsize idx)
|
||||
{
|
||||
GdkDmabufFormat *format;
|
||||
|
||||
g_return_val_if_fail (idx < formats->n_formats, 0);
|
||||
|
||||
format = &formats->formats[idx];
|
||||
|
||||
return format->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT;
|
||||
}
|
||||
@@ -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_14
|
||||
dev_t gdk_wayland_dmabuf_formats_get_main_device (GdkDmabufFormats *formats);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
dev_t gdk_wayland_dmabuf_formats_get_target_device (GdkDmabufFormats *formats,
|
||||
gsize idx);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_wayland_dmabuf_formats_is_scanout (GdkDmabufFormats *formats,
|
||||
gsize idx);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -8,6 +8,7 @@ gdk_wayland_sources = files([
|
||||
'gdkdevice-wayland.c',
|
||||
'gdkdevicepad-wayland.c',
|
||||
'gdkdisplay-wayland.c',
|
||||
'gdkdmabuf-wayland.c',
|
||||
'gdkdrag-wayland.c',
|
||||
'gdkdragsurface-wayland.c',
|
||||
'gdkdrop-wayland.c',
|
||||
@@ -28,6 +29,7 @@ gdk_wayland_sources = files([
|
||||
gdk_wayland_public_headers = files([
|
||||
'gdkwaylanddevice.h',
|
||||
'gdkwaylanddisplay.h',
|
||||
'gdkwaylanddmabufformats.h',
|
||||
'gdkwaylandglcontext.h',
|
||||
'gdkwaylandmonitor.h',
|
||||
'gdkwaylandpopup.h',
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_dmabuf_formats_basic (void)
|
||||
{
|
||||
@@ -137,6 +141,52 @@ test_priorities (void)
|
||||
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[])
|
||||
{
|
||||
@@ -145,6 +195,7 @@ 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