Commit 900d3e4a authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/format-helper: Add blitter functions



The blitter functions copy a framebuffer to I/O memory using one of
the existing conversion functions.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: default avatarMaxime Ripard <maxime@cerno.tech>
Tested-by: default avatarnerdopolis <bluescreen_avenger@verizon.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20210430105840.30515-3-tzimmermann@suse.de
parent 5ab7af71
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
@@ -344,3 +344,90 @@ void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
}
EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);

/**
 * drm_fb_blit_rect_dstclip - Copy parts of a framebuffer to display memory
 * @dst:	The display memory to copy to
 * @dst_pitch:	Number of bytes between two consecutive scanlines within dst
 * @dst_format:	FOURCC code of the display's color format
 * @vmap:	The framebuffer memory to copy from
 * @fb:		The framebuffer to copy from
 * @clip:	Clip rectangle area to copy
 *
 * This function copies parts of a framebuffer to display memory. If the
 * formats of the display and the framebuffer mismatch, the blit function
 * will attempt to convert between them.
 *
 * Use drm_fb_blit_dstclip() to copy the full framebuffer.
 *
 * Returns:
 * 0 on success, or
 * -EINVAL if the color-format conversion failed, or
 * a negative error code otherwise.
 */
int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned int dst_pitch,
			     uint32_t dst_format, void *vmap,
			     struct drm_framebuffer *fb,
			     struct drm_rect *clip)
{
	uint32_t fb_format = fb->format->format;

	/* treat alpha channel like filler bits */
	if (fb_format == DRM_FORMAT_ARGB8888)
		fb_format = DRM_FORMAT_XRGB8888;
	if (dst_format == DRM_FORMAT_ARGB8888)
		dst_format = DRM_FORMAT_XRGB8888;

	if (dst_format == fb_format) {
		drm_fb_memcpy_dstclip(dst, dst_pitch, vmap, fb, clip);
		return 0;

	} else if (dst_format == DRM_FORMAT_RGB565) {
		if (fb_format == DRM_FORMAT_XRGB8888) {
			drm_fb_xrgb8888_to_rgb565_dstclip(dst, dst_pitch,
							  vmap, fb, clip,
							  false);
			return 0;
		}
	} else if (dst_format == DRM_FORMAT_RGB888) {
		if (fb_format == DRM_FORMAT_XRGB8888) {
			drm_fb_xrgb8888_to_rgb888_dstclip(dst, dst_pitch,
							  vmap, fb, clip);
			return 0;
		}
	}

	return -EINVAL;
}
EXPORT_SYMBOL(drm_fb_blit_rect_dstclip);

/**
 * drm_fb_blit_dstclip - Copy framebuffer to display memory
 * @dst:	The display memory to copy to
 * @dst_pitch:	Number of bytes between two consecutive scanlines within dst
 * @dst_format:	FOURCC code of the display's color format
 * @vmap:	The framebuffer memory to copy from
 * @fb:		The framebuffer to copy from
 *
 * This function copies a full framebuffer to display memory. If the formats
 * of the display and the framebuffer mismatch, the copy function will
 * attempt to convert between them.
 *
 * See drm_fb_blit_rect_dstclip() for more inforamtion.
 *
 * Returns:
 * 0 on success, or a negative error code otherwise.
 */
int drm_fb_blit_dstclip(void __iomem *dst, unsigned int dst_pitch,
			uint32_t dst_format, void *vmap,
			struct drm_framebuffer *fb)
{
	struct drm_rect fullscreen = {
		.x1 = 0,
		.x2 = fb->width,
		.y1 = 0,
		.y2 = fb->height,
	};
	return drm_fb_blit_rect_dstclip(dst, dst_pitch, dst_format, vmap, fb,
					&fullscreen);
}
EXPORT_SYMBOL(drm_fb_blit_dstclip);
+8 −0
Original line number Diff line number Diff line
@@ -28,4 +28,12 @@ void drm_fb_xrgb8888_to_rgb888_dstclip(void __iomem *dst, unsigned int dst_pitch
void drm_fb_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
			      struct drm_rect *clip);

int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned int dst_pitch,
			     uint32_t dst_format, void *vmap,
			     struct drm_framebuffer *fb,
			     struct drm_rect *rect);
int drm_fb_blit_dstclip(void __iomem *dst, unsigned int dst_pitch,
			uint32_t dst_format, void *vmap,
			struct drm_framebuffer *fb);

#endif /* __LINUX_DRM_FORMAT_HELPER_H */