diff --git a/gdk/gdkdmabuftexturebuilder.c b/gdk/gdkdmabuftexturebuilder.c index 98699d5bb7..25979287e6 100644 --- a/gdk/gdkdmabuftexturebuilder.c +++ b/gdk/gdkdmabuftexturebuilder.c @@ -964,6 +964,8 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, gpointer data, GError **error) { + unsigned i; + g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL); g_return_val_if_fail (destroy == NULL || data != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); @@ -971,8 +973,8 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self, g_return_val_if_fail (self->height > 0, NULL); g_return_val_if_fail (self->dmabuf.fourcc != 0, NULL); - for (int i = 0; i < self->dmabuf.n_planes; i++) - g_return_val_if_fail (self->dmabuf.planes[i].fd != -1 || self->dmabuf.planes[i].offset != 0, NULL); + for (i = 0; i < self->dmabuf.n_planes; i++) + g_return_val_if_fail (self->dmabuf.planes[i].fd != -1, NULL); if (GDK_DEBUG_CHECK (DMABUF_DISABLE)) { diff --git a/tests/testdmabuf.c b/tests/testdmabuf.c index 075906bcd5..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; @@ -145,7 +145,7 @@ y_u_v_create_buffer (uint32_t drm_format, * sub-sampling does not require proper * filtering/averaging/siting. */ - argb = *(rgb_row + x / 2 * 2); + argb = rgb_row[x]; /* * A stupid way of "sub-sampling" chroma. This does not @@ -180,7 +180,7 @@ nv12_create_buffer (uint32_t drm_format, int x, y; uint32_t *rgb_row; uint8_t *y_base; - uint16_t *uv_base; + uint8_t *uv_base; uint8_t *y_row; uint16_t *uv_row; uint32_t argb; @@ -190,21 +190,22 @@ nv12_create_buffer (uint32_t drm_format, g_assert (drm_format == DRM_FORMAT_NV12); - /* Full size Y, quarter UV */ + /* Full size Y plane, half size UV plane */ bytes = rgb_width * rgb_height + - (rgb_width / 2) * (rgb_height / 2) * sizeof (uint16_t); + rgb_width * (rgb_height / 2); + *size = bytes; buf = g_new0 (guchar, bytes); *uv_offset = rgb_width * rgb_height; y_base = buf; - uv_base = (uint16_t *)(y_base + rgb_width * rgb_height); + uv_base = y_base + rgb_width * rgb_height; for (y = 0; y < rgb_height; y++) { rgb_row = (uint32_t *) (rgb_data + y * 4 * rgb_width); y_row = y_base + y * rgb_width; - uv_row = (uint16_t *) (uv_base + (y / 2) * (rgb_width / 2)); + uv_row = (uint16_t *) (uv_base + (y / 2) * rgb_width); for (x = 0; x < rgb_width; x++) { @@ -213,7 +214,7 @@ nv12_create_buffer (uint32_t drm_format, * sub-sampling does not require proper * filtering/averaging/siting. */ - argb = *(rgb_row + x / 2 * 2); + argb = rgb_row[x]; /* * A stupid way of "sub-sampling" chroma. This does not @@ -234,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; @@ -283,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); } @@ -315,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); } @@ -387,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); @@ -414,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]; @@ -426,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));