testdmabuf: Add --disjoint and --undecorated

The code now by default puts all planes into the same fd - like
v4l does, too.

The old behavior of one fd per plane can be enabled via --disjoint.

Also, am --undecorated option has been added so that the window
isn't decorated and all that the renderer has to do is display the
dmabuf.
This is useful when debugging just the dmabuf rendering.
This commit is contained in:
Benjamin Otte 2023-10-21 16:40:09 +02:00
parent 7ab9056c11
commit 58a0e4ffaa

View File

@ -36,9 +36,9 @@ allocate_dma_buf (gsize size)
}
static void
populate_dma_buf (int fd,
guchar *data,
gsize size)
populate_dma_buf (int fd,
const guchar *data,
gsize size)
{
guchar *buf;
@ -235,9 +235,54 @@ nv12_create_buffer (uint32_t drm_format,
return buf;
}
static void
texture_builder_set_planes (GdkDmabufTextureBuilder *builder,
gboolean disjoint,
const guchar *buf,
unsigned size,
unsigned n_planes,
unsigned strides[4],
unsigned sizes[4])
{
gdk_dmabuf_texture_builder_set_n_planes (builder, n_planes);
if (disjoint)
{
unsigned offset = 0;
unsigned i;
for (i = 0; i < n_planes; i++)
{
int fd = allocate_dma_buf (sizes[i]);
populate_dma_buf (fd, buf + offset, sizes[i]);
gdk_dmabuf_texture_builder_set_fd (builder, i, fd);
gdk_dmabuf_texture_builder_set_stride (builder, i, strides[i]);
gdk_dmabuf_texture_builder_set_offset (builder, i, 0);
offset += sizes[i];
}
}
else
{
unsigned offset = 0;
unsigned i;
int fd = allocate_dma_buf (size);
populate_dma_buf (fd, buf, size);
for (i = 0; i < n_planes; i++)
{
gdk_dmabuf_texture_builder_set_fd (builder, i, fd);
gdk_dmabuf_texture_builder_set_stride (builder, i, strides[i]);
gdk_dmabuf_texture_builder_set_offset (builder, i, offset);
offset += sizes[i];
}
}
}
static GdkTexture *
make_dmabuf_texture (const char *filename,
guint32 format)
guint32 format,
gboolean disjoint)
{
GdkTexture *texture;
int width, height;
@ -284,30 +329,15 @@ make_dmabuf_texture (const char *filename,
guchar *buf;
int size, u_offset, v_offset;
gdk_dmabuf_texture_builder_set_n_planes (builder, 3);
buf = y_u_v_create_buffer (format, rgb_data, width, height, &size, &u_offset, &v_offset);
fd = allocate_dma_buf (width * height);
populate_dma_buf (fd, buf, width * height);
gdk_dmabuf_texture_builder_set_fd (builder, 0, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 0, width);
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
fd = allocate_dma_buf ((width / 2) * (height / 2));
populate_dma_buf (fd, buf + u_offset, (width / 2) * (height / 2));
gdk_dmabuf_texture_builder_set_fd (builder, 1, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 1, width / 2);
gdk_dmabuf_texture_builder_set_offset (builder, 1, 0);
fd = allocate_dma_buf ((width / 2) * (height / 2));
populate_dma_buf (fd, buf + v_offset, (width / 2) * (height / 2));
gdk_dmabuf_texture_builder_set_fd (builder, 2, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 2, width / 2);
gdk_dmabuf_texture_builder_set_offset (builder, 2, 0);
texture_builder_set_planes (builder,
disjoint,
buf,
size,
3,
(unsigned[4]) { width, width / 2, width / 2 },
(unsigned[4]) { width * height, width * height / 4, width * height / 4 });
g_free (buf);
}
@ -316,23 +346,15 @@ make_dmabuf_texture (const char *filename,
guchar *buf;
int size, uv_offset;
gdk_dmabuf_texture_builder_set_n_planes (builder, 2);
buf = nv12_create_buffer (format, rgb_data, width, height, &size, &uv_offset);
fd = allocate_dma_buf (width * height);
populate_dma_buf (fd, buf, width * height);
gdk_dmabuf_texture_builder_set_fd (builder, 0, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 0, width);
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
fd = allocate_dma_buf ((width / 2) * (height / 2) * sizeof (uint16_t));
populate_dma_buf (fd, buf + uv_offset, (width / 2) * (height / 2) * sizeof (uint16_t));
gdk_dmabuf_texture_builder_set_fd (builder, 1, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 1, width);
gdk_dmabuf_texture_builder_set_offset (builder, 1, 0);
texture_builder_set_planes (builder,
disjoint,
buf,
size,
2,
(unsigned[4]) { width, width, },
(unsigned[4]) { width * height, width * height / 2 });
g_free (buf);
}
@ -388,7 +410,7 @@ static void
usage (void)
{
char *formats = supported_formats_to_string ();
g_print ("Usage: testdmabuf FORMAT FILE\n"
g_print ("Usage: testdmabuf [--bare] [--disjoint] FORMAT FILE\n"
"Supported formats: %s\n", formats);
g_free (formats);
exit (1);
@ -415,9 +437,25 @@ main (int argc, char *argv[])
GtkWidget *window, *picture;
char *filename;
guint32 format;
gboolean disjoint = FALSE;
gboolean decorated = TRUE;
unsigned i;
if (argc != 3)
usage ();
for (i = 1; i < argc; i++)
{
if (g_str_equal (argv[i], "--disjoint"))
disjoint = TRUE;
if (g_str_equal (argv[i], "--undecorated"))
decorated = FALSE;
else
break;
}
if (argc - i != 2)
{
usage ();
return 1;
}
format = parse_format (argv[1]);
filename = argv[2];
@ -427,11 +465,12 @@ main (int argc, char *argv[])
/* Get the list of supported formats with GDK_DEBUG=opengl */
gdk_display_get_dmabuf_formats (gdk_display_get_default ());
texture = make_dmabuf_texture (filename, format);
texture = make_dmabuf_texture (filename, format, disjoint);
gdk_texture_save_to_png (texture, "testdmabuf.out.png");
window = gtk_window_new ();
gtk_window_set_decorated (GTK_WINDOW (window), decorated);
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));