dmabuf: Split out conversion functions

Create a GdkDataFormat enum and give it an API similar to
GdkMemoryFormat.

This makes the code no longer dmabuf-specific and provides a generic
method for all backends to access weird formats.

Technically, we could now add a GdkTexture implementation based on this.
This commit is contained in:
Benjamin Otte
2024-11-10 16:04:39 +01:00
parent 11b28c24c2
commit 8e5a69da9c
5 changed files with 897 additions and 363 deletions

758
gdk/gdkdataformat.c Normal file
View File

@@ -0,0 +1,758 @@
#include "config.h"
#include "gdkdataformatprivate.h"
#include "gdk/gdkdmabuffourccprivate.h"
typedef struct _GdkDataFormatDescription GdkDataFormatDescription;
struct _GdkDataFormatDescription
{
const char *name;
GdkMemoryFormat conversion;
gsize n_planes;
gsize alignment;
gsize block_size[2];
guint32 dmabuf_fourcc;
#ifdef GDK_RENDERING_VULKAN
struct {
VkFormat format;
VkComponentMapping swizzle;
} vk;
#endif
void (* convert) (const GdkDataBuffer *self,
guchar *dst_data,
gsize dst_stride);
};
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static inline void
gdk_convert_nv12_like (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *y_data,
gsize y_stride,
const guchar *uv_data,
gsize uv_stride,
gboolean uv_swapped,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow,
uv_data[x / x_subsample * 2 + (uv_swapped ? 1 : 0)],
uv_data[x / x_subsample * 2 + (uv_swapped ? 0 : 1)],
&r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
uv_data += uv_stride;
}
}
#define CONVERT_NV12_FUNC(name, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_nv12_like (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
self->planes[1].data, \
self->planes[1].stride, \
uv_swapped, x_subsample, y_subsample); \
}
CONVERT_NV12_FUNC (nv12, FALSE, 2, 2)
CONVERT_NV12_FUNC (nv21, TRUE, 2, 2)
CONVERT_NV12_FUNC (nv16, FALSE, 2, 1)
CONVERT_NV12_FUNC (nv61, TRUE, 2, 1)
CONVERT_NV12_FUNC (nv24, FALSE, 1, 1)
CONVERT_NV12_FUNC (nv42, TRUE, 1, 1)
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static inline void
gdk_convert_p010_like (guint16 *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guint16 *y_data,
gsize y_stride,
const guint16 *uv_data,
gsize uv_stride,
gsize bits_used,
gboolean uv_swapped,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
guint16 mask;
mask = 0xFFFF << (16 - bits_used);
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u, v;
u = uv_data[x / x_subsample * 2 + (uv_swapped ? 1 : 0)];
u = (u & mask) | (u >> bits_used);
v = uv_data[x / x_subsample * 2 + (uv_swapped ? 0 : 1)];
v = (v & mask) | (v >> bits_used);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
{
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = (y_ & mask) | (y_ >> bits_used);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
uv_data += uv_stride;
}
}
#define CONVERT_P010_FUNC(name, bits_used, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_p010_like ((guint16 *) dst_data, \
dst_stride, \
self->width, \
self->height, \
(guint16 *) self->planes[0].data, \
self->planes[0].stride, \
(guint16 *) self->planes[1].data, \
self->planes[1].stride, \
bits_used, uv_swapped, x_subsample, y_subsample); \
}
CONVERT_P010_FUNC (p010, 10, FALSE, 2, 2)
CONVERT_P010_FUNC (p012, 12, FALSE, 2, 2)
CONVERT_P010_FUNC (p016, 16, FALSE, 2, 2)
static inline void
gdk_convert_3_plane (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *y_data,
gsize y_stride,
const guchar *u_data,
gsize u_stride,
const guchar *v_data,
gsize v_stride,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow, u_data[x / x_subsample], v_data[x / x_subsample], &r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
u_data += u_stride;
v_data += v_stride;
}
}
#define CONVERT_3_PLANE_FUNC(name, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_3_plane (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
self->planes[uv_swapped ? 2 : 1].data, \
self->planes[uv_swapped ? 2 : 1].stride, \
self->planes[uv_swapped ? 1 : 2].data, \
self->planes[uv_swapped ? 1 : 2].stride, \
x_subsample, y_subsample); \
}
CONVERT_3_PLANE_FUNC (yuv410, FALSE, 4, 4)
CONVERT_3_PLANE_FUNC (yvu410, TRUE, 4, 4)
CONVERT_3_PLANE_FUNC (yuv411, FALSE, 4, 1)
CONVERT_3_PLANE_FUNC (yvu411, TRUE, 4, 1)
CONVERT_3_PLANE_FUNC (yuv420, FALSE, 2, 2)
CONVERT_3_PLANE_FUNC (yvu420, TRUE, 2, 2)
CONVERT_3_PLANE_FUNC (yuv422, FALSE, 2, 1)
CONVERT_3_PLANE_FUNC (yvu422, TRUE, 2, 1)
CONVERT_3_PLANE_FUNC (yuv444, FALSE, 1, 1)
CONVERT_3_PLANE_FUNC (yvu444, TRUE, 1, 1)
static inline void
gdk_convert_yuyv_like (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *src_data,
gsize src_stride,
gsize y_index,
gsize u_index,
gsize v_index)
{
gsize x, y;
for (y = 0; y < height; y ++)
{
for (x = 0; x < width; x += 2)
{
int r, g, b;
get_uv_values (&itu601_narrow, src_data[2 * x + u_index], src_data[2 * x + v_index], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + y_index], r, g, b);
if (x + 1 < width)
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + y_index + 2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
}
}
#define CONVERT_YUYV_FUNC(name, y_index, u_index, v_index) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_yuyv_like (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
y_index, u_index, v_index); \
}
CONVERT_YUYV_FUNC (yuyv, 0, 1, 3)
CONVERT_YUYV_FUNC (yvyu, 0, 3, 1)
CONVERT_YUYV_FUNC (uyvy, 1, 0, 2)
CONVERT_YUYV_FUNC (vyuy, 1, 2, 0)
#define VULKAN_SWIZZLE(_R, _G, _B, _A) { VK_COMPONENT_SWIZZLE_ ## _R, VK_COMPONENT_SWIZZLE_ ## _G, VK_COMPONENT_SWIZZLE_ ## _B, VK_COMPONENT_SWIZZLE_ ## _A }
#define VULKAN_DEFAULT_SWIZZLE VULKAN_SWIZZLE (R, G, B, A)
GdkDataFormatDescription data_formats[] = {
[GDK_DATA_NV12] = {
.name = "NV12",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_NV12,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv12,
},
[GDK_DATA_NV21] = {
.name = "NV21",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_NV21,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv21,
},
[GDK_DATA_NV16] = {
.name = "NV16",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV16,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv16,
},
[GDK_DATA_NV61] = {
.name = "NV61",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV61,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv61,
},
[GDK_DATA_NV24] = {
.name = "NV24",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV24,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv24,
},
[GDK_DATA_NV42] = {
.name = "NV42",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 2,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV42,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv42,
},
[GDK_DATA_P010] = {
.name = "P010",
.conversion = GDK_MEMORY_R16G16B16,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P010,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p010,
},
[GDK_DATA_P012] = {
.name = "P012",
.conversion = GDK_MEMORY_R16G16B16,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P012,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p012,
},
[GDK_DATA_P016] = {
.name = "P016",
.conversion = GDK_MEMORY_R16G16B16,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P016,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p016,
},
[GDK_DATA_YUV410] = {
.name = "YUV410",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 4 },
.dmabuf_fourcc = DRM_FORMAT_YUV410,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv410,
},
[GDK_DATA_YVU410] = {
.name = "YVU410",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 4 },
.dmabuf_fourcc = DRM_FORMAT_YVU410,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yvu410,
},
[GDK_DATA_YUV411] = {
.name = "YUV411",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV411,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv411,
},
[GDK_DATA_YVU411] = {
.name = "YVU411",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU411,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yvu411,
},
[GDK_DATA_YUV420] = {
.name = "YUV420",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_YUV420,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv420,
},
[GDK_DATA_YVU420] = {
.name = "YVU420",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_YVU420,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu420,
},
[GDK_DATA_YUV422] = {
.name = "YUV422",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV422,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv422,
},
[GDK_DATA_YVU422] = {
.name = "YVU422",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU422,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu422,
},
[GDK_DATA_YUV444] = {
.name = "YUV444",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV444,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv444,
},
[GDK_DATA_YVU444] = {
.name = "YVU444",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 3,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU444,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu444,
},
[GDK_DATA_YUYV] = {
.name = "YUYV",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUYV,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuyv,
},
[GDK_DATA_YVYU] = {
.name = "YVYU",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVYU,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvyu,
},
[GDK_DATA_UYVY] = {
.name = "UYVY",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_UYVY,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_uyvy,
},
[GDK_DATA_VYUY] = {
.name = "VYUY",
.conversion = GDK_MEMORY_R8G8B8,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_VYUY,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_vyuy,
},
};
const char *
gdk_data_format_get_name (GdkDataFormat format)
{
return data_formats[format].name;
}
GdkMemoryFormat
gdk_data_format_get_conversion (GdkDataFormat format)
{
return data_formats[format].conversion;
}
gsize
gdk_data_format_n_planes (GdkDataFormat format)
{
return data_formats[format].n_planes;
}
gsize
gdk_data_format_alignment (GdkDataFormat format)
{
return data_formats[format].alignment;
}
gsize
gdk_data_format_block_width (GdkDataFormat format)
{
return data_formats[format].block_size[0];
}
gsize
gdk_data_format_block_height (GdkDataFormat format)
{
return data_formats[format].block_size[1];
}
guint32
gdk_data_format_get_dmabuf_fourcc (GdkDataFormat format)
{
return data_formats[format].dmabuf_fourcc;
}
#ifdef GDK_RENDERING_VULKAN
VkFormat
gdk_data_format_vk_format (GdkDataFormat format,
VkComponentMapping *out_swizzle)
{
if (out_swizzle)
*out_swizzle = data_formats[format].vk.swizzle;
return data_formats[format].vk.format;
}
#endif
void
gdk_data_convert (const GdkDataBuffer *self,
guchar *dest_data,
gsize dest_stride)
{
data_formats[self->format].convert (self,
dest_data,
dest_stride);
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include "gdkenums.h"
#include "gdktypes.h"
#include "gdkmemoryformatprivate.h"
/* epoxy needs this, see https://github.com/anholt/libepoxy/issues/299 */
#ifdef GDK_WINDOWING_WIN32
#include <windows.h>
#endif
#include <epoxy/gl.h>
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
#endif
G_BEGIN_DECLS
typedef enum {
GDK_DATA_NV12,
GDK_DATA_NV21,
GDK_DATA_NV16,
GDK_DATA_NV61,
GDK_DATA_NV24,
GDK_DATA_NV42,
GDK_DATA_P010,
GDK_DATA_P012,
GDK_DATA_P016,
GDK_DATA_YUV410,
GDK_DATA_YVU410,
GDK_DATA_YUV411,
GDK_DATA_YVU411,
GDK_DATA_YUV420,
GDK_DATA_YVU420,
GDK_DATA_YUV422,
GDK_DATA_YVU422,
GDK_DATA_YUV444,
GDK_DATA_YVU444,
GDK_DATA_YUYV,
GDK_DATA_YVYU,
GDK_DATA_UYVY,
GDK_DATA_VYUY,
GDK_DATA_N_FORMATS
} GdkDataFormat;
#define GDK_DATA_FORMAT_MAX_PLANES 4
typedef struct _GdkDataBuffer GdkDataBuffer;
struct _GdkDataBuffer
{
GdkDataFormat format;
gsize width;
gsize height;
struct {
const guchar *data;
gsize stride;
} planes[GDK_DATA_FORMAT_MAX_PLANES];
};
const char * gdk_data_format_get_name (GdkDataFormat format) G_GNUC_CONST;
GdkMemoryFormat gdk_data_format_get_conversion (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_n_planes (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_alignment (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_block_width (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_block_height (GdkDataFormat format) G_GNUC_CONST;
guint32 gdk_data_format_get_dmabuf_fourcc (GdkDataFormat format) G_GNUC_CONST;
#ifdef GDK_RENDERING_VULKAN
VkFormat gdk_data_format_vk_format (GdkDataFormat format,
VkComponentMapping *out_swizzle);
#endif
void gdk_data_convert (const GdkDataBuffer *self,
guchar *dest_data,
gsize dest_stride);
G_END_DECLS

View File

@@ -20,6 +20,7 @@
#include "gdkdmabufprivate.h"
#include "gdkdataformatprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
@@ -37,6 +38,7 @@ struct _GdkDrmFormatInfo
{
guint32 fourcc;
GdkMemoryFormat memory_format;
GdkDataFormat data_format;
gboolean is_yuv;
void (* download) (guchar *dst_data,
gsize dst_stride,
@@ -133,348 +135,35 @@ download_memcpy_3_1 (guchar *dst_data,
}
}
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static const GdkDrmFormatInfo *
get_drm_format_info (guint32 fourcc);
static void
download_nv12 (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])
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])
{
const guchar *y_data, *uv_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
const GdkDrmFormatInfo *info = get_drm_format_info (dmabuf->fourcc);
GdkDataBuffer buffer = {
.format = info->data_format,
.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 }
},
};
switch (dmabuf->fourcc)
{
case DRM_FORMAT_NV12:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_NV21:
U = 1; V = 0; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_NV16:
U = 0; V = 1; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_NV61:
U = 1; V = 0; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_NV24:
U = 0; V = 1; X_SUB = 1; Y_SUB = 1;
break;
case DRM_FORMAT_NV42:
U = 1; V = 0; X_SUB = 1; Y_SUB = 1;
break;
default:
g_assert_not_reached ();
return;
}
y_stride = dmabuf->planes[0].stride;
y_data = src_data[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
uv_stride = dmabuf->planes[1].stride;
uv_data = src_data[1] + dmabuf->planes[1].offset;
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * uv_stride);
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
uv_data += uv_stride;
}
}
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static void
download_p010 (guchar *dst,
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])
{
const guint16 *y_data, *uv_data;
guint16 *dst_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
guint16 SIZE, MASK;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_P010:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 10;
break;
case DRM_FORMAT_P012:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 12;
break;
case DRM_FORMAT_P016:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 16;
break;
default:
g_assert_not_reached ();
return;
}
MASK = 0xFFFF << (16 - SIZE);
y_stride = dmabuf->planes[0].stride / 2;
y_data = (const guint16 *) (src_data[0] + dmabuf->planes[0].offset);
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * dmabuf->planes[0].stride);
uv_stride = dmabuf->planes[1].stride / 2;
uv_data = (const guint16 *) (src_data[1] + dmabuf->planes[1].offset);
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * dmabuf->planes[1].stride);
dst_data = (guint16 *) dst;
dst_stride /= 2;
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u, v;
u = uv_data[x / X_SUB * 2 + U];
u = (u & MASK) | (u >> SIZE);
v = uv_data[x / X_SUB * 2 + V];
v = (v & MASK) | (v >> SIZE);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = (y_ & MASK) | (y_ >> SIZE);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
uv_data += uv_stride;
}
}
static void
download_yuv_3 (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])
{
const guchar *y_data, *u_data, *v_data;
gsize x, y, y_stride, u_stride, v_stride;
gsize U, V, X_SUB, Y_SUB;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_YUV410:
U = 1; V = 2; X_SUB = 4; Y_SUB = 4;
break;
case DRM_FORMAT_YVU410:
U = 2; V = 1; X_SUB = 4; Y_SUB = 4;
break;
case DRM_FORMAT_YUV411:
U = 1; V = 2; X_SUB = 4; Y_SUB = 1;
break;
case DRM_FORMAT_YVU411:
U = 2; V = 1; X_SUB = 4; Y_SUB = 1;
break;
case DRM_FORMAT_YUV420:
U = 1; V = 2; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_YVU420:
U = 2; V = 1; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_YUV422:
U = 1; V = 2; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_YVU422:
U = 2; V = 1; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_YUV444:
U = 1; V = 2; X_SUB = 1; Y_SUB = 1;
break;
case DRM_FORMAT_YVU444:
U = 2; V = 1; X_SUB = 1; Y_SUB = 1;
break;
default:
g_assert_not_reached ();
return;
}
y_stride = dmabuf->planes[0].stride;
y_data = src_data[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
u_stride = dmabuf->planes[U].stride;
u_data = src_data[U] + dmabuf->planes[U].offset;
g_return_if_fail (sizes[U] >= dmabuf->planes[U].offset + (height + Y_SUB - 1) / Y_SUB * u_stride);
v_stride = dmabuf->planes[V].stride;
v_data = src_data[V] + dmabuf->planes[V].offset;
g_return_if_fail (sizes[V] >= dmabuf->planes[V].offset + (height + Y_SUB - 1) / Y_SUB * v_stride);
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow, u_data[x / X_SUB], v_data[x / X_SUB], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
u_data += u_stride;
v_data += v_stride;
}
}
static void
download_yuyv (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 x, y, src_stride;
gsize Y1, Y2, U, V;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_YUYV:
Y1 = 0; U = 1; Y2 = 2; V = 3;
break;
case DRM_FORMAT_YVYU:
Y1 = 0; V = 1; Y2 = 2; U = 3;
break;
case DRM_FORMAT_UYVY:
U = 0; Y1 = 1; V = 2; Y2 = 3;
break;
case DRM_FORMAT_VYUY:
V = 0; Y1 = 1; U = 2; Y2 = 3;
break;
default:
g_assert_not_reached ();
return;
}
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 + height * src_stride);
for (y = 0; y < height; y ++)
{
for (x = 0; x < width; x += 2)
{
int r, g, b;
get_uv_values (&itu601_narrow, src_data[2 * x + U], src_data[2 * x + V], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + Y1], r, g, b);
if (x + 1 < width)
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + Y2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
}
gdk_data_convert (&buffer,
dst_data,
dst_stride);
}
#define VULKAN_SWIZZLE(_R, _G, _B, _A) { VK_COMPONENT_SWIZZLE_ ## _R, VK_COMPONENT_SWIZZLE_ ## _G, VK_COMPONENT_SWIZZLE_ ## _B, VK_COMPONENT_SWIZZLE_ ## _A }
@@ -1288,7 +977,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUYV,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuyv,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
@@ -1300,7 +989,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVYU,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuyv,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
@@ -1312,7 +1001,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_VYUY,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuyv,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
@@ -1324,7 +1013,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_UYVY,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuyv,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
@@ -1688,7 +1377,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV12,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
@@ -1700,7 +1389,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV21,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
@@ -1712,7 +1401,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV16,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
@@ -1724,7 +1413,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV61,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
@@ -1736,7 +1425,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV24,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
@@ -1748,7 +1437,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_NV42,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_nv12,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
@@ -1784,7 +1473,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P010,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
@@ -1796,7 +1485,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P012,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
@@ -1808,7 +1497,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P016,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
@@ -1857,7 +1546,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUV410,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
@@ -1869,7 +1558,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVU410,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
@@ -1881,7 +1570,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUV411,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
@@ -1893,7 +1582,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVU411,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
@@ -1905,7 +1594,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUV420,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
@@ -1917,7 +1606,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVU420,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
@@ -1929,7 +1618,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUV422,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
@@ -1941,7 +1630,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVU422,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
@@ -1953,7 +1642,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YUV444,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
@@ -1965,7 +1654,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_YVU444,
.memory_format = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.download = download_yuv_3,
.download = download_data_format,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,

View File

@@ -105,8 +105,9 @@ static gboolean
gdk_dmabuf_texture_invoke_callback (gpointer data)
{
Download *download = data;
GdkDisplay *display = download->texture->display;
//GdkDisplay *display = download->texture->display;
#if 0
if (display->egl_downloader &&
gdk_dmabuf_downloader_download (display->egl_downloader,
download->texture,
@@ -127,8 +128,9 @@ gdk_dmabuf_texture_invoke_callback (gpointer data)
{
/* Successfully downloaded using Vulkan */
}
#endif
#ifdef HAVE_DMABUF
else if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
download->format,
download->color_state,
download->data,

View File

@@ -15,6 +15,7 @@ gdk_public_sources = files([
'gdkcontentproviderimpl.c',
'gdkcontentserializer.c',
'gdkcursor.c',
'gdkdataformat.c',
'gdkdevice.c',
'gdkdevicepad.c',
'gdkdevicetool.c',