dmabuf: Query supported formats using new method

This makes the old table unnecessary and we can finally remove it.
This commit is contained in:
Benjamin Otte
2024-11-12 04:36:00 +01:00
parent b92797da1f
commit d96334b75f

View File

@@ -32,609 +32,6 @@
#include <linux/dma-buf.h>
#include <epoxy/egl.h>
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
struct _GdkDrmFormatInfo
{
guint32 fourcc;
void (* download) (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]);
};
static void
download_memcpy (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])
{
const guchar *src_data;
gsize src_stride;
guint bpp;
bpp = gdk_memory_format_bytes_per_pixel (dst_format);
src_stride = dmabuf->planes[0].stride;
src_data = src_datas[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + gdk_memory_format_min_buffer_size (dst_format, src_stride, width, height));
if (dst_stride == src_stride)
memcpy (dst_data, src_data, (height - 1) * dst_stride + width * bpp);
else
{
gsize i;
for (i = 0; i < height; i++)
memcpy (dst_data + i * dst_stride, src_data + i * src_stride, width * bpp);
}
}
static const GdkDrmFormatInfo *
get_drm_format_info (guint32 fourcc);
static void
download_data_format (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
GdkDataBuffer buffer = {
.width = width,
.height = height,
.planes = {
{ src_data[0] + dmabuf->planes[0].offset, dmabuf->planes[0].stride },
{ src_data[1] + dmabuf->planes[1].offset, dmabuf->planes[1].stride },
{ src_data[2] + dmabuf->planes[2].offset, dmabuf->planes[2].stride },
{ src_data[3] + dmabuf->planes[3].offset, dmabuf->planes[3].stride }
},
};
if (!gdk_data_format_find_by_dmabuf_fourcc (dmabuf->fourcc, &buffer.format))
{
g_assert_not_reached ();
}
gdk_data_convert (&buffer,
dst_data,
dst_stride);
}
static const GdkDrmFormatInfo supported_formats[] = {
#if 0
/* palette formats?! */
{
.fourcc = DRM_FORMAT_C1,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_C2,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_C4,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_C8,
.download = NULL,
},
#endif
/* darkness */
{
.fourcc = DRM_FORMAT_D1,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_D2,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_D4,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_D8,
.download = NULL,
},
/* red only - we treat this as gray */
{
.fourcc = DRM_FORMAT_R1,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R2,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R4,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R8,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R10,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R12,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_R16,
.download = NULL,
},
/* 2 channels - FIXME: Should this be gray + alpha? */
{
.fourcc = DRM_FORMAT_RG88,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_GR88,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RG1616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_GR1616,
.download = NULL,
},
/* <8bit per channel RGB(A) */
{
.fourcc = DRM_FORMAT_RGB332,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGR233,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XRGB4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XBGR4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBX4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRX4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ARGB4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ABGR4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBA4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRA4444,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XRGB1555,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XBGR1555,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBX5551,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRX5551,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ARGB1555,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ABGR1555,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBA5551,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRA5551,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGB565,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGR565,
.download = NULL,
},
/* 8bit RGB */
{
.fourcc = DRM_FORMAT_RGB888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_BGR888,
.download = download_memcpy,
},
/* 8bit RGBA */
{
.fourcc = DRM_FORMAT_BGRA8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_ABGR8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_ARGB8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_RGBA8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_BGRX8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_XBGR8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_XRGB8888,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_RGBX8888,
.download = download_memcpy,
},
/* 10bit RGB(A) */
{
.fourcc = DRM_FORMAT_XRGB2101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XBGR2101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBX1010102,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRX1010102,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ARGB2101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ABGR2101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGBA1010102,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGRA1010102,
.download = NULL,
},
/* 16bit RGB(A) */
{
.fourcc = DRM_FORMAT_XRGB16161616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XBGR16161616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ARGB16161616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ABGR16161616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XRGB16161616F,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XBGR16161616F,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ARGB16161616F,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_ABGR16161616F,
.download = download_memcpy,
},
{
.fourcc = DRM_FORMAT_AXBXGXRX106106106106,
.download = NULL,
},
/* 1-plane YUV formats */
{
.fourcc = DRM_FORMAT_YUYV,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVYU,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_VYUY,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_UYVY,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_AYUV,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_AVUY8888,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XYUV8888,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XVUY8888,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_VUY888,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_VUY101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y210,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y212,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y216,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y410,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y412,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y416,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XVYU2101010,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XVYU12_16161616,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_XVYU16161616,
.download = NULL,
},
/* tiled YUV */
{
.fourcc = DRM_FORMAT_Y0L0,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_X0L0,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Y0L2,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_X0L2,
.download = NULL,
},
/* non-linear YUV */
{
.fourcc = DRM_FORMAT_YUV420_8BIT,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_YUV420_10BIT,
.download = NULL,
},
/* 2 plane RGB + A */
{
.fourcc = DRM_FORMAT_BGRX8888_A8,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_RGBX8888_A8,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_XBGR8888_A8,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_XRGB8888_A8,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_RGB888_A8,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGR888_A8,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_RGB565_A8,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_BGR565_A8,
.download = NULL,
},
/* 2-plane YUV formats */
{
.fourcc = DRM_FORMAT_NV12,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV21,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV16,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV61,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV24,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV42,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_NV15,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_P210,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_P010,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_P012,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_P016,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_P030,
.download = NULL,
},
/* 3-plane YUV */
{
.fourcc = DRM_FORMAT_Q410,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_Q401,
.download = NULL,
},
{
.fourcc = DRM_FORMAT_YUV410,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVU410,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YUV411,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVU411,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YUV420,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVU420,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YUV422,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVU422,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YUV444,
.download = download_data_format,
},
{
.fourcc = DRM_FORMAT_YVU444,
.download = download_data_format,
},
};
static const GdkDrmFormatInfo *
get_drm_format_info (guint32 fourcc)
{
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (supported_formats[i].fourcc == fourcc)
return &supported_formats[i];
}
return NULL;
}
GdkDmabufFormats *
gdk_dmabuf_get_mmap_formats (void)
{
@@ -643,22 +40,34 @@ gdk_dmabuf_get_mmap_formats (void)
if (formats == NULL)
{
GdkDmabufFormatsBuilder *builder;
guint32 fourcc;
gsize i;
builder = gdk_dmabuf_formats_builder_new ();
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
for (i = 0; i < GDK_MEMORY_N_FORMATS; i++)
{
if (!supported_formats[i].download)
fourcc = gdk_memory_format_get_dmabuf_fourcc (i);
if (fourcc == 0)
continue;
GDK_DEBUG (DMABUF,
"mmap advertises dmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
(char *) &fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder,
supported_formats[i].fourcc,
DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder, fourcc, DRM_FORMAT_MOD_LINEAR);
}
for (i = 0; i < GDK_DATA_N_FORMATS; i++)
{
fourcc = gdk_data_format_get_dmabuf_fourcc (i);
if (fourcc == 0)
continue;
GDK_DEBUG (DMABUF,
"mmap advertises dmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
(char *) &fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder, fourcc, DRM_FORMAT_MOD_LINEAR);
}
formats = gdk_dmabuf_formats_builder_free_to_formats (builder);