diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index 742c9ea815..72279d9643 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -78,6 +78,55 @@ download_memcpy (guchar *dst_data, } } +static void +download_memcpy_3_1 (guchar *dst_data, + gsize dst_stride, + GdkMemoryFormat dst_format, + gsize width, + gsize height, + const GdkDmabuf *dmabuf, + const guchar *src_datas[GDK_DMABUF_MAX_PLANES], + gsize sizes[GDK_DMABUF_MAX_PLANES]) +{ + guint a; + guchar *dst_row; + const guchar *src_data, *src_row; + gsize src_stride; + + g_assert (dmabuf->n_planes == 2); + + download_memcpy (dst_data, dst_stride, dst_format, width, height, dmabuf, src_datas, sizes); + + switch ((int)dst_format) + { + case GDK_MEMORY_A8R8G8B8: + case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: + case GDK_MEMORY_A8B8G8R8: + case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED: + a = 0; + break; + case GDK_MEMORY_R8G8B8A8: + case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: + case GDK_MEMORY_B8G8R8A8: + case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: + a = 3; + break; + default: + g_assert_not_reached (); + } + + src_stride = dmabuf->planes[1].stride; + src_data = src_datas[1]; + + for (gsize y = 0; y < height; y++) + { + dst_row = dst_data + y * dst_stride; + src_row = src_data + y * src_stride; + for (gsize x = 0; x < width; x++) + dst_row[4 * x + a] = src_row[x]; + } +} + typedef struct _YUVCoefficients YUVCoefficients; struct _YUVCoefficients @@ -332,6 +381,11 @@ static const GdkDrmFormatInfo supported_formats[] = { { DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT, download_memcpy }, { DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_memcpy }, { DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8, download_memcpy }, + /* 2 plane RGB + A */ + { DRM_FORMAT_BGRX8888_A8, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8, download_memcpy_3_1 }, + { DRM_FORMAT_RGBX8888_A8, GDK_MEMORY_A8B8G8R8_PREMULTIPLIED, GDK_MEMORY_A8B8G8R8, download_memcpy_3_1 }, + { DRM_FORMAT_XBGR8888_A8, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8, download_memcpy_3_1 }, + { DRM_FORMAT_XRGB8888_A8, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8, download_memcpy_3_1 }, /* YUV formats */ { DRM_FORMAT_NV12, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, { DRM_FORMAT_NV21, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 }, @@ -483,7 +537,7 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader, g_warning ("Failed to seek dmabuf: %s", g_strerror (errno)); goto out; } - /* be a good citizen and seek back to the start, as the dos recommend */ + /* be a good citizen and seek back to the start, as the docs recommend */ lseek (dmabuf->planes[i].fd, 0, SEEK_SET); if (ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0) diff --git a/tests/testdmabuf.c b/tests/testdmabuf.c index 981ba79cf9..b272f11c80 100644 --- a/tests/testdmabuf.c +++ b/tests/testdmabuf.c @@ -482,6 +482,36 @@ make_dmabuf_texture (const char *filename, gdk_dmabuf_texture_builder_set_fd (builder, 0, fd); gdk_dmabuf_texture_builder_set_stride (builder, 0, rgb_stride); } + else if (format == DRM_FORMAT_XRGB8888_A8) + { + guchar *alpha_data; + gsize alpha_stride; + gsize alpha_size; + + gdk_dmabuf_texture_builder_set_n_planes (builder, 2); + + fd = allocate_buffer (rgb_size); + populate_buffer (fd, rgb_data, rgb_size); + + gdk_dmabuf_texture_builder_set_fd (builder, 0, fd); + gdk_dmabuf_texture_builder_set_stride (builder, 0, rgb_stride); + + alpha_stride = width; + alpha_size = alpha_stride * height; + alpha_data = g_new0 (guchar, alpha_size); + + for (gsize i = 0; i < height; i++) + for (gsize j = 0; j < width; j++) + alpha_data[i * alpha_stride + j] = rgb_data[i * rgb_stride + j * 4 + 3]; + + fd = allocate_buffer (alpha_size); + populate_buffer (fd, alpha_data, alpha_size); + + gdk_dmabuf_texture_builder_set_fd (builder, 1, fd); + gdk_dmabuf_texture_builder_set_stride (builder, 1, alpha_stride); + + g_free (alpha_data); + } else if (format == DRM_FORMAT_YUV420) { guchar *buf; @@ -533,6 +563,7 @@ static guint32 supported_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_YUV420, DRM_FORMAT_NV12, + DRM_FORMAT_XRGB8888_A8, }; static gboolean