diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2025-03-28 15:14:59 +0100 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-04-01 15:35:21 +0200 |
commit | f46bf57299b0a8395263de0bcfcb72a600adaae9 (patch) | |
tree | 0464fa5dbab7dd75c15700c534c94a68284c1388 | |
parent | d55d0b066f4eedf030c9c1a67a2a0abffece3abc (diff) |
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
-rw-r--r-- | drivers/gpu/drm/drm_format_helper.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_format_internal.h | 12 |
2 files changed, 31 insertions, 24 deletions
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index abd18c23cfbb..5a2fe3d685a2 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -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); } /** diff --git a/drivers/gpu/drm/drm_format_internal.h b/drivers/gpu/drm/drm_format_internal.h index 5f82f0b9c8e8..e7fcf260a914 100644 --- a/drivers/gpu/drm/drm_format_internal.h +++ b/drivers/gpu/drm/drm_format_internal.h @@ -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 */ |