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

Add drm_fb_xfrm_line_32to24() to implement conversion from 32-bit
pixels to 24-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: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250328141709.217283-4-tzimmermann@suse.de
This commit is contained in:
Thomas Zimmermann
2025-03-28 15:14:59 +01:00
parent d55d0b066f
commit f46bf57299
2 changed files with 31 additions and 24 deletions

View File

@@ -246,6 +246,23 @@ static int drm_fb_xfrm(struct iosys_map *dst,
xfrm_line);
}
static __always_inline void drm_fb_xfrm_line_32to24(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) {
u32 val24 = xfrm_pixel(le32_to_cpup(sbuf32++));
/* write output in reverse order for little endianness */
*dbuf8++ = (val24 & 0x000000ff);
*dbuf8++ = (val24 & 0x0000ff00) >> 8;
*dbuf8++ = (val24 & 0x00ff0000) >> 16;
}
}
static __always_inline void drm_fb_xfrm_line_32to32(void *dbuf, const void *sbuf,
unsigned int pixels,
u32 (*xfrm_pixel)(u32))
@@ -667,18 +684,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgba5551);
static void drm_fb_xrgb8888_to_rgb888_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]);
/* write blue-green-red to output in little endianness */
*dbuf8++ = (pix & 0x000000FF) >> 0;
*dbuf8++ = (pix & 0x0000FF00) >> 8;
*dbuf8++ = (pix & 0x00FF0000) >> 16;
}
drm_fb_xfrm_line_32to24(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_rgb888);
}
/**
@@ -718,18 +724,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888);
static void drm_fb_xrgb8888_to_bgr888_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]);
/* write red-green-blue to output in little endianness */
*dbuf8++ = (pix & 0x00ff0000) >> 16;
*dbuf8++ = (pix & 0x0000ff00) >> 8;
*dbuf8++ = (pix & 0x000000ff) >> 0;
}
drm_fb_xfrm_line_32to24(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_bgr888);
}
/**

View File

@@ -68,6 +68,18 @@ static inline u32 drm_pixel_xrgb8888_to_argb1555(u32 pix)
drm_pixel_xrgb8888_to_xrgb1555(pix);
}
static inline u32 drm_pixel_xrgb8888_to_rgb888(u32 pix)
{
return pix & GENMASK(23, 0);
}
static inline u32 drm_pixel_xrgb8888_to_bgr888(u32 pix)
{
return ((pix & 0x00ff0000) >> 16) |
((pix & 0x0000ff00)) |
((pix & 0x000000ff) << 16);
}
static inline u32 drm_pixel_xrgb8888_to_argb8888(u32 pix)
{
return GENMASK(31, 24) | /* fill alpha bits */