drm/format-helper: Add generic conversion to 8-bit formats
authorThomas Zimmermann <tzimmermann@suse.de>
Fri, 28 Mar 2025 14:15:01 +0000 (15:15 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 1 Apr 2025 13:35:22 +0000 (15:35 +0200)
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: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250328141709.217283-6-tzimmermann@suse.de
drivers/gpu/drm/drm_format_helper.c
drivers/gpu/drm/drm_format_internal.h

index aecf55c1fc6ba03163710a2130bd27c8fe7b9a06..a926aa6671fcd436076208e7c80f8793ea9649b5 100644 (file)
@@ -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);
 }
 
 /**
index 4f20b63cb6f60cfd61066ad16f513b5c067a2666..9f857bfa368d10d4a8155c7d0828d38c4f23e6b7 100644 (file)
  * 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) |