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@xxxxxxx> --- 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