[PATCH 21/23] [DO NOT MERGE] drm/format-helper: Add color palette
Thomas Zimmermann
tzimmermann at suse.de
Tue Jan 30 09:53:56 UTC 2024
Add a color palette to struct drm_format_conv_state. The palette
points to an array of struct drm_color_lut. It allows to blit from
an index color formats to a component-based destination.
The palette exists independently from the source pixmap and is
thus stored struct drm_format_conv_state instead of struct drm_pixmap.
As a nice side effect, this also allows for techniques like palette
swapping and color cycling.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
drivers/gpu/drm/drm_format_helper.c | 71 +++++++++++++++++++----------
include/drm/drm_format_helper.h | 2 +
2 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c
index ed90745f4d9fb..2588871672b6d 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -212,7 +212,8 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p
const void *src, unsigned long src_pitch, unsigned long src_pixsize,
const struct drm_rect *src_clip, bool src_cached_hint,
struct drm_format_conv_state *state,
- void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
+ void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels,
+ const struct drm_color_lut *palette))
{
unsigned long pixels = drm_rect_width(src_clip);
unsigned long lines = drm_rect_height(src_clip);
@@ -241,7 +242,7 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p
sbuf = memcpy(stmp, src, sbuf_len);
else
sbuf = src;
- xfrm_line(dst, sbuf, pixels);
+ xfrm_line(dst, sbuf, pixels, state->palette);
src += src_pitch;
dst += dst_pitch;
}
@@ -253,7 +254,8 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign
const void *src, unsigned long src_pitch, unsigned long src_pixsize,
const struct drm_rect *src_clip, bool src_cached_hint,
struct drm_format_conv_state *state,
- void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
+ void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels,
+ const struct drm_color_lut* palette))
{
unsigned long npixels = drm_rect_width(src_clip);
unsigned long lines = drm_rect_height(src_clip);
@@ -283,7 +285,7 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign
sbuf = memcpy(stmp, src, sbuf_len);
else
sbuf = src;
- xfrm_line(dbuf, sbuf, npixels);
+ xfrm_line(dbuf, sbuf, npixels, state->palette);
memcpy_toio(dst, dbuf, dbuf_len);
src += src_pitch;
dst += dst_pitch;
@@ -297,7 +299,8 @@ static int drm_fb_xfrm(struct iosys_map *dst,
const unsigned int *dst_pitch, const u8 *dst_pixsize,
const struct drm_pixmap *src_pix, bool vaddr_cached_hint,
struct drm_format_conv_state *state,
- void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))
+ void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels,
+ const struct drm_color_lut *palette))
{
static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
0, 0, 0, 0
@@ -373,7 +376,8 @@ void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch,
}
EXPORT_SYMBOL(drm_fb_memcpy);
-static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u16 *dbuf16 = dbuf;
const u16 *sbuf16 = sbuf;
@@ -383,7 +387,8 @@ static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int pixels
*dbuf16++ = swab16(*sbuf16++);
}
-static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u32 *dbuf32 = dbuf;
const u32 *sbuf32 = sbuf;
@@ -421,7 +426,8 @@ void drm_fb_swab(struct drm_device *dev,
{
const struct drm_format_info *format = src_pix->format;
u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8);
- void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels);
+ void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels,
+ const struct drm_color_lut *palette);
switch (cpp) {
case 4:
@@ -440,7 +446,8 @@ void drm_fb_swab(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_fb_swab);
-static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u8 *dbuf8 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -486,7 +493,8 @@ void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pi
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332);
-static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le16 *dbuf16 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -505,7 +513,8 @@ static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigne
/* TODO: implement this helper as conversion to RGB565|BIG_ENDIAN */
static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,
- unsigned int pixels)
+ unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le16 *dbuf16 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -550,7 +559,8 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi
2,
};
- void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels);
+ void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels,
+ const struct drm_color_lut *palette);
if (swab)
xfrm_line = drm_fb_xrgb8888_to_rgb565_swab_line;
@@ -561,7 +571,8 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565);
-static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le16 *dbuf16 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -611,7 +622,8 @@ void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb1555);
-static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le16 *dbuf16 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -662,7 +674,8 @@ void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb1555);
-static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le16 *dbuf16 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -713,7 +726,8 @@ void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgba5551);
-static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u8 *dbuf8 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -762,7 +776,8 @@ void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pi
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888);
-static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le32 *dbuf32 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -809,7 +824,8 @@ void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb8888);
-static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le32 *dbuf32 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -838,7 +854,8 @@ static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned in
drm_fb_xrgb8888_to_abgr8888_line);
}
-static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le32 *dbuf32 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -867,7 +884,8 @@ static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned in
drm_fb_xrgb8888_to_xbgr8888_line);
}
-static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le32 *dbuf32 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -918,7 +936,8 @@ void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *d
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010);
-static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
__le32 *dbuf32 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -970,7 +989,8 @@ void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *d
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb2101010);
-static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u8 *dbuf8 = dbuf;
const __le32 *sbuf32 = sbuf;
@@ -1109,7 +1129,8 @@ int drm_fb_blit(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_fb_blit);
-static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int pixels)
+static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int pixels,
+ const struct drm_color_lut *palette)
{
u8 *dbuf8 = dbuf;
const u8 *sbuf8 = sbuf;
@@ -1208,8 +1229,8 @@ void drm_fb_xrgb8888_to_mono(struct drm_device *dev,
vaddr += clip_offset(clip, src_pix->pitches[0], cpp);
for (y = 0; y < lines; y++) {
src32 = memcpy(src32, vaddr, len_src32);
- drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels);
- drm_fb_gray8_to_mono_line(mono, gray8, linepixels);
+ drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels, state->palette);
+ drm_fb_gray8_to_mono_line(mono, gray8, linepixels, state->palette);
vaddr += src_pix->pitches[0];
mono += dst_pitch_0;
}
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index 098e6f8412465..464812080f3dc 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -31,6 +31,8 @@ struct drm_format_conv_state {
size_t size;
bool preallocated;
} tmp;
+
+ const struct drm_color_lut *palette;
};
#define __DRM_FORMAT_CONV_STATE_INIT(_mem, _size, _preallocated) { \
--
2.43.0
More information about the dri-devel
mailing list