[PATCH 21/23] [DO NOT MERGE] drm/format-helper: Add color palette

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux