From 58a0e4ffaaf0ee281dbb5b316b72d41046da50fe Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 21 Oct 2023 16:40:09 +0200 Subject: [PATCH] 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. --- tests/testdmabuf.c | 129 +++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 45 deletions(-) diff --git a/tests/testdmabuf.c b/tests/testdmabuf.c index 73b575ff6a..e2ab28e863 100644 --- a/tests/testdmabuf.c +++ b/tests/testdmabuf.c @@ -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));