Add struct drm_pixmap to wrap the source parameters for all drawing operations. This consists of the format, the clipping rectangle, the line pitch and source data buffers. Also add a helper that creates a pixmap from a framebuffer. Existing code uses struct drm_framebuffer for drawing. Converting the drawing interfaces to struct drm_pixmap will allow for other types of source buffers, such as plain memory buffers or font data from struct font_desc. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/drm_format_helper.c | 49 +++++++++++++++++++++++++++++ include/drm/drm_format_helper.h | 36 ++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index b1be458ed4dda..0b69b16d5802a 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -132,6 +132,55 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info } EXPORT_SYMBOL(drm_fb_clip_offset); +static void drm_pixmap_init(struct drm_pixmap *pix, const struct drm_format_info *format, + const struct iosys_map *data, const unsigned int *pitches, + const struct drm_rect *clip) +{ + size_t i; + + pix->format = format; + + /* + * TODO: Set the size and data pointers from the + * clipping rectangle and remove their computation + * from the xfrm helpers. + */ + memcpy(&pix->clip, clip, sizeof(pix->clip)); + + for (i = 0; i < format->num_planes; ++i) + pix->pitches[i] = pitches[i]; + for (; i < ARRAY_SIZE(pix->pitches); ++i) + pix->pitches[i] = 0; + + for (i = 0; i < format->num_planes; ++i) + pix->data[i] = data[i]; + for (; i < ARRAY_SIZE(pix->data); ++i) + iosys_map_clear(&pix->data[i]); +} + +/** + * drm_pixmap_init_from_framebuffer - Initializes a pixmap from a DRM framebuffer + * @pix: The pixmap to initialize + * @fb: DRM framebuffer + * @data: Array of source buffers + * @clip: Clip rectangle area to copy + * + * The parameter @data refers to an array with 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. + */ +void drm_pixmap_init_from_framebuffer(struct drm_pixmap *pix, const struct drm_framebuffer *fb, + const struct iosys_map *data, const struct drm_rect *clip) +{ + const struct drm_rect full_clip = DRM_RECT_INIT(0, 0, fb->width, fb->height); + + if (!clip) + clip = &full_clip; + + drm_pixmap_init(pix, fb->format, data, fb->pitches, clip); +} +EXPORT_SYMBOL(drm_pixmap_init_from_framebuffer); + /* TODO: Make this function work with multi-plane formats. */ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, const void *vaddr, const struct drm_framebuffer *fb, diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index f13b34e0b752b..56a98999503e2 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -6,14 +6,14 @@ #ifndef __LINUX_DRM_FORMAT_HELPER_H #define __LINUX_DRM_FORMAT_HELPER_H +#include <linux/iosys-map.h> #include <linux/types.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_rect.h> + struct drm_device; -struct drm_format_info; struct drm_framebuffer; -struct drm_rect; - -struct iosys_map; /** * struct drm_format_conv_state - Stores format-conversion state @@ -66,6 +66,34 @@ void *drm_format_conv_state_reserve(struct drm_format_conv_state *state, size_t new_size, gfp_t flags); void drm_format_conv_state_release(struct drm_format_conv_state *state); +/** + * struct drm_pixmap - source pixmap for format-conversion helpers + * + * A pixmap represents the source data for drawing operations. All + * fields are considered private. + */ +struct drm_pixmap { + /** + * @format: The pixmap's color format + */ + const struct drm_format_info *format; + /** + * @clip: The cliping rectangle. + */ + struct drm_rect clip; + /** + * @pitches: Per-plane offset between two consecutive rows of pixels in Bytes + */ + unsigned int pitches[DRM_FORMAT_MAX_PLANES]; + /** + * @data: Per-plane source buffer + */ + struct iosys_map data[DRM_FORMAT_MAX_PLANES]; +}; + +void drm_pixmap_init_from_framebuffer(struct drm_pixmap *pix, const struct drm_framebuffer *fb, + const struct iosys_map *data, const struct drm_rect *clip); + unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, const struct drm_rect *clip); -- 2.43.0