]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/format-helper: Rework XRGB8888-to-MONO conversion
authorThomas Zimmermann <tzimmermann@suse.de>
Mon, 8 Aug 2022 12:54:04 +0000 (14:54 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 10 Aug 2022 07:18:53 +0000 (09:18 +0200)
Update XRGB8888-to-MONO conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

v2:
* rebase after renaming CMA helpers to DMA helpers
* update documentation (Sam)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220808125406.20752-13-tzimmermann@suse.de
drivers/gpu/drm/drm_format_helper.c
drivers/gpu/drm/solomon/ssd130x.c
drivers/gpu/drm/tiny/repaper.c
include/drm/drm_format_helper.h

index 890370c0424ffac883fc47e760c4fb98fefef440..53a313f83dc2d25f2578ff02d62b9307539c44f7 100644 (file)
@@ -753,46 +753,64 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int
 
 /**
  * drm_fb_xrgb8888_to_mono - Convert XRGB8888 to monochrome
- * @dst: monochrome destination buffer (0=black, 1=white)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB8888 source buffer
+ * @dst: Array of monochrome destination buffers (0=black, 1=white)
+ * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines
+ *             within @dst; can be NULL if scanlines are stored next to each other.
+ * @vmap: Array of XRGB8888 source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
- * DRM doesn't have native monochrome support.
- * Such drivers can announce the commonly supported XR24 format to userspace
- * and use this function to convert to the native format.
+ * This function copies parts of a framebuffer to display memory and converts the
+ * color format during the process. Destination and framebuffer formats must match. The
+ * parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must have at
+ * least as many entries as there are planes in @fb's format. Each entry stores the
+ * value for the format's respective color plane at the same index.
+ *
+ * This function does not apply clipping on @dst (i.e. the destination is at the
+ * top-left corner). The first pixel (upper left corner of the clip rectangle) will
+ * be converted and copied to the first bit (LSB) in the first byte of the monochrome
+ * destination buffer. If the caller requires that the first pixel in a byte must
+ * be located at an x-coordinate that is a multiple of 8, then the caller must take
+ * care itself of supplying a suitable clip rectangle.
+ *
+ * DRM doesn't have native monochrome support. Drivers can use this function for
+ * monochrome devices that don't support XRGB8888 natively. Such drivers can
+ * announce the commonly supported XR24 format to userspace and use this function
+ * to convert to the native format.
  *
  * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and
  * then the result is converted from grayscale to monochrome.
- *
- * The first pixel (upper left corner of the clip rectangle) will be converted
- * and copied to the first bit (LSB) in the first byte of the monochrome
- * destination buffer.
- * If the caller requires that the first pixel in a byte must be located at an
- * x-coordinate that is a multiple of 8, then the caller must take care itself
- * of supplying a suitable clip rectangle.
  */
-void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vaddr,
-                            const struct drm_framebuffer *fb, const struct drm_rect *clip)
+void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch,
+                            const struct iosys_map *vmap, const struct drm_framebuffer *fb,
+                            const struct drm_rect *clip)
 {
+       static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+               0, 0, 0, 0
+       };
        unsigned int linepixels = drm_rect_width(clip);
        unsigned int lines = drm_rect_height(clip);
        unsigned int cpp = fb->format->cpp[0];
        unsigned int len_src32 = linepixels * cpp;
        struct drm_device *dev = fb->dev;
+       void *vaddr = vmap[0].vaddr;
+       unsigned int dst_pitch_0;
        unsigned int y;
-       u8 *mono = dst, *gray8;
+       u8 *mono = dst[0].vaddr, *gray8;
        u32 *src32;
 
        if (drm_WARN_ON(dev, fb->format->format != DRM_FORMAT_XRGB8888))
                return;
 
+       if (!dst_pitch)
+               dst_pitch = default_dst_pitch;
+       dst_pitch_0 = dst_pitch[0];
+
        /*
         * The mono destination buffer contains 1 bit per pixel
         */
-       if (!dst_pitch)
-               dst_pitch = DIV_ROUND_UP(linepixels, 8);
+       if (!dst_pitch_0)
+               dst_pitch_0 = DIV_ROUND_UP(linepixels, 8);
 
        /*
         * The dma memory is write-combined so reads are uncached.
@@ -817,7 +835,7 @@ void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vadd
                drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels);
                drm_fb_gray8_to_mono_line(mono, gray8, linepixels);
                vaddr += fb->pitches[0];
-               mono += dst_pitch;
+               mono += dst_pitch_0;
        }
 
        kfree(src32);
index 973ae2dfb2f8742e230dd418d5fe4981145e68a0..f87f5443e714b1cc807a22b7b2cc8cc8fa121b02 100644 (file)
@@ -536,11 +536,11 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x)
        kfree(buf);
 }
 
-static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *map,
+static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *vmap,
                                struct drm_rect *rect)
 {
        struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
-       void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */
+       struct iosys_map dst;
        unsigned int dst_pitch;
        int ret = 0;
        u8 *buf = NULL;
@@ -554,7 +554,8 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m
        if (!buf)
                return -ENOMEM;
 
-       drm_fb_xrgb8888_to_mono(buf, dst_pitch, vmap, fb, rect);
+       iosys_map_set_vaddr(&dst, buf);
+       drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect);
 
        ssd130x_update_rect(ssd130x, buf, rect);
 
index 4cd24b54ac74d5aeaa1ccad75cd2d4bd02e2bbe2..c4c1be3ac0b86a8401c860fe891f8ff87c7fedd0 100644 (file)
@@ -513,6 +513,8 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
 {
        struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
        struct repaper_epd *epd = drm_to_epd(fb->dev);
+       unsigned int dst_pitch = 0;
+       struct iosys_map dst, vmap;
        struct drm_rect clip;
        int idx, ret = 0;
        u8 *buf = NULL;
@@ -541,7 +543,9 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
        if (ret)
                goto out_free;
 
-       drm_fb_xrgb8888_to_mono(buf, 0, dma_obj->vaddr, fb, &clip);
+       iosys_map_set_vaddr(&dst, buf);
+       iosys_map_set_vaddr(&vmap, dma_obj->vaddr);
+       drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, &vmap, fb, &clip);
 
        drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
 
index 68087c982497932b72bf21d4773f171dc0fa684f..1e1d8f356cc106dcece58c55aec499941c45b446 100644 (file)
@@ -40,7 +40,8 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d
                const struct iosys_map *vmap, const struct drm_framebuffer *fb,
                const struct drm_rect *rect);
 
-void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *src,
-                            const struct drm_framebuffer *fb, const struct drm_rect *clip);
+void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch,
+                            const struct iosys_map *vmap, const struct drm_framebuffer *fb,
+                            const struct drm_rect *clip);
 
 #endif /* __LINUX_DRM_FORMAT_HELPER_H */