Commit a376dcf4 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/format-helper: Add generic conversion to 8-bit formats



Add drm_fb_xfrm_line_32to8() to implement conversion from 32-bit
pixels to 8-bit pixels. The pixel-conversion is specified by the
given callback parameter. Mark the helper as always_inline to avoid
overhead from function calls.

Then implement all existing line-conversion functions with the new
generic call and the respective pixel-conversion helper.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250328141709.217283-6-tzimmermann@suse.de
parent b39e5ba0
Loading
Loading
Loading
Loading
+14 −24
Original line number Diff line number Diff line
@@ -246,6 +246,18 @@ static int drm_fb_xfrm(struct iosys_map *dst,
				     xfrm_line);
}

static __always_inline void drm_fb_xfrm_line_32to8(void *dbuf, const void *sbuf,
						   unsigned int pixels,
						   u32 (*xfrm_pixel)(u32))
{
	u8 *dbuf8 = dbuf;
	const __le32 *sbuf32 = sbuf;
	const __le32 *send32 = sbuf32 + pixels;

	while (sbuf32 < send32)
		*dbuf8++ = xfrm_pixel(le32_to_cpup(sbuf32++));
}

static __always_inline void drm_fb_xfrm_line_32to16(void *dbuf, const void *sbuf,
						    unsigned int pixels,
						    u32 (*xfrm_pixel)(u32))
@@ -411,17 +423,7 @@ EXPORT_SYMBOL(drm_fb_swab);

static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels)
{
	u8 *dbuf8 = dbuf;
	const __le32 *sbuf32 = sbuf;
	unsigned int x;
	u32 pix;

	for (x = 0; x < pixels; x++) {
		pix = le32_to_cpu(sbuf32[x]);
		dbuf8[x] = ((pix & 0x00e00000) >> 16) |
			   ((pix & 0x0000e000) >> 11) |
			   ((pix & 0x000000c0) >> 6);
	}
	drm_fb_xfrm_line_32to8(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_rgb332);
}

/**
@@ -879,19 +881,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb2101010);

static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels)
{
	u8 *dbuf8 = dbuf;
	const __le32 *sbuf32 = sbuf;
	unsigned int x;

	for (x = 0; x < pixels; x++) {
		u32 pix = le32_to_cpu(sbuf32[x]);
		u8 r = (pix & 0x00ff0000) >> 16;
		u8 g = (pix & 0x0000ff00) >> 8;
		u8 b =  pix & 0x000000ff;

		/* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
		*dbuf8++ = (3 * r + 6 * g + b) / 10;
	}
	drm_fb_xfrm_line_32to8(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_r8_bt601);
}

/**
+17 −0
Original line number Diff line number Diff line
@@ -35,6 +35,23 @@
 * Conversions from XRGB8888
 */

static inline u32 drm_pixel_xrgb8888_to_r8_bt601(u32 pix)
{
	u32 r = (pix & 0x00ff0000) >> 16;
	u32 g = (pix & 0x0000ff00) >> 8;
	u32 b =  pix & 0x000000ff;

	/* ITU-R BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
	return (3 * r + 6 * g + b) / 10;
}

static inline u32 drm_pixel_xrgb8888_to_rgb332(u32 pix)
{
	return ((pix & 0x00e00000) >> 16) |
	       ((pix & 0x0000e000) >> 11) |
	       ((pix & 0x000000c0) >> 6);
}

static inline u32 drm_pixel_xrgb8888_to_rgb565(u32 pix)
{
	return ((pix & 0x00f80000) >> 8) |