diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2025-02-17 13:22:05 +0100 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-02-20 08:38:33 +0100 |
| commit | 966a0d49d1cd57165ad3e6232cf9de6fe43ecc63 (patch) | |
| tree | 312a8a021d381075b299416f2000418ff349ebf5 /drivers/gpu/drm/drm_format_helper.c | |
| parent | 6ec054a52d92fd172560996e3b2a4234a31f5265 (diff) | |
drm/ast: cursor: Move format conversion to shared helper
User-space cursor-image data is encoded in ARBG8888, while hardware
supports ARGB4444. Implement the format conversion as part of the
format-helper framework, so that other drivers can benefit.
This allows to respect the damage area of the cursor update. In
previous code, all cursor image data had to be converted on each
update. Now, only the changed areas require an update. The hardware
image is always updated completely, as it is required for the
checksum update.
The format-conversion helper still contains the old implementation's
optimization of writing 2 output pixels at the same time.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250217122336.230067-3-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/drm_format_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_format_helper.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index b1be458ed4dd..ecb278b63e8c 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -978,6 +978,75 @@ void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pit } EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); +static void drm_fb_argb8888_to_argb4444_line(void *dbuf, const void *sbuf, unsigned int pixels) +{ + unsigned int pixels2 = pixels & ~GENMASK_ULL(0, 0); + __le32 *dbuf32 = dbuf; + __le16 *dbuf16 = dbuf + pixels2 * sizeof(*dbuf16); + const __le32 *sbuf32 = sbuf; + unsigned int x; + u32 val32; + u16 val16; + u32 pix[2]; + + for (x = 0; x < pixels2; x += 2, ++dbuf32) { + pix[0] = le32_to_cpu(sbuf32[x]); + pix[1] = le32_to_cpu(sbuf32[x + 1]); + val32 = ((pix[0] & 0xf0000000) >> 16) | + ((pix[0] & 0x00f00000) >> 12) | + ((pix[0] & 0x0000f000) >> 8) | + ((pix[0] & 0x000000f0) >> 4) | + ((pix[1] & 0xf0000000) >> 0) | + ((pix[1] & 0x00f00000) << 4) | + ((pix[1] & 0x0000f000) << 8) | + ((pix[1] & 0x000000f0) << 12); + *dbuf32 = cpu_to_le32(val32); + } + for (; x < pixels; x++) { + pix[0] = le32_to_cpu(sbuf32[x]); + val16 = ((pix[0] & 0xf0000000) >> 16) | + ((pix[0] & 0x00f00000) >> 12) | + ((pix[0] & 0x0000f000) >> 8) | + ((pix[0] & 0x000000f0) >> 4); + dbuf16[x] = cpu_to_le16(val16); + } +} + +/** + * drm_fb_argb8888_to_argb4444 - Convert ARGB8888 to ARGB4444 clip buffer + * @dst: Array of ARGB4444 destination buffers + * @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. + * @src: Array of ARGB8888 source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * @state: Transform and conversion state + * + * This function copies parts of a framebuffer to display memory and converts + * the color format during the process. The parameters @dst, @dst_pitch and + * @src 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). + * + * Drivers can use this function for ARGB4444 devices that don't support + * ARGB8888 natively. + */ +void drm_fb_argb8888_to_argb4444(struct iosys_map *dst, const unsigned int *dst_pitch, + const struct iosys_map *src, const struct drm_framebuffer *fb, + const struct drm_rect *clip, struct drm_format_conv_state *state) +{ + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { + 2, + }; + + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, + drm_fb_argb8888_to_argb4444_line); +} +EXPORT_SYMBOL(drm_fb_argb8888_to_argb4444); + /** * drm_fb_blit - Copy parts of a framebuffer to display memory * @dst: Array of display-memory addresses to copy to |