Merge branch 'dmabuf-separate-alpha-formats' into 'main'

dmabuf: Add support for separate alpha formats

See merge request GNOME/gtk!6571
This commit is contained in:
Matthias Clasen
2023-11-18 07:41:44 +00:00
2 changed files with 86 additions and 1 deletions

View File

@@ -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)

View File

@@ -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