[igt-dev] [PATCH v7 07/14] fb: Add support for conversions through pixman

Petri Latvala petri.latvala at intel.com
Mon Oct 1 09:26:58 UTC 2018


On Tue, Sep 11, 2018 at 10:47:34AM +0200, Maxime Ripard wrote:
> Pixman allows for much more conversions than cairo, and we don't want to
> open code conversions routine for the common formats.
> 
> Let's plug pixman in our conversion function so that we can benefit from it
> when possible.
> 
> Reviewed-by: Eric Anholt <eric at anholt.net>
> Signed-off-by: Maxime Ripard <maxime.ripard at bootlin.com>
> ---
>  lib/igt_fb.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 624fddbd465b..64370e01c1d6 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -29,6 +29,7 @@
>  #include <math.h>
>  #include <wchar.h>
>  #include <inttypes.h>
> +#include <pixman.h>
>  

Currently pixman is only there if you enable chamelium. Doing this
requires making it mandatory, doing some refactoring on meson.build
and configure.ac. And README.


-- 
Petri Latvala


>  #include "drmtest.h"
>  #include "igt_aux.h"
> @@ -59,29 +60,36 @@
>   * functions to work with these pixel format codes.
>   */
>  
> +#define PIXMAN_invalid	0
> +
>  /* drm fourcc/cairo format maps */
>  static struct format_desc_struct {
>  	const char *name;
>  	uint32_t drm_id;
>  	cairo_format_t cairo_id;
> +	pixman_format_code_t pixman_id;
>  	int depth;
>  	int num_planes;
>  	int plane_bpp[4];
>  } format_desc[] = {
>  	{ .name = "RGB565", .depth = 16, .drm_id = DRM_FORMAT_RGB565,
>  	  .cairo_id = CAIRO_FORMAT_RGB16_565,
> +	  .pixman_id = PIXMAN_r5g6b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
>  	},
>  	{ .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .pixman_id = PIXMAN_x8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
>  	},
>  	{ .name = "XRGB2101010", .depth = 30, .drm_id = DRM_FORMAT_XRGB2101010,
>  	  .cairo_id = CAIRO_FORMAT_RGB30,
> +	  .pixman_id = PIXMAN_x2r10g10b10,
>  	  .num_planes = 1, .plane_bpp = { 32, },
>  	},
>  	{ .name = "ARGB8888", .depth = 24, .drm_id = DRM_FORMAT_ARGB8888,
>  	  .cairo_id = CAIRO_FORMAT_ARGB32,
> +	  .pixman_id = PIXMAN_a8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
>  	},
>  	{ .name = "NV12", .depth = -1, .drm_id = DRM_FORMAT_NV12,
> @@ -90,6 +98,7 @@ static struct format_desc_struct {
>  	},
>  	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .pixman_id = PIXMAN_yuy2,
>  	  .num_planes = 1, .plane_bpp = { 16, },
>  	},
>  	{ .name = "YVYU", .depth = -1, .drm_id = DRM_FORMAT_YVYU,
> @@ -1178,6 +1187,18 @@ unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
>  	return fb_id;
>  }
>  
> +static pixman_format_code_t drm_format_to_pixman(uint32_t drm_format)
> +{
> +	struct format_desc_struct *f;
> +
> +	for_each_format(f)
> +		if (f->drm_id == drm_format)
> +			return f->pixman_id;
> +
> +	igt_assert_f(0, "can't find a pixman format for %08x (%s)\n",
> +		     drm_format, igt_format_str(drm_format));
> +}
> +
>  static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
>  {
>  	struct format_desc_struct *f;
> @@ -1774,9 +1795,38 @@ static void convert_rgb24_to_yuyv(struct fb_convert *cvt)
>  	}
>  }
>  
> +static void convert_pixman(struct fb_convert *cvt)
> +{
> +	pixman_format_code_t src_pixman = drm_format_to_pixman(cvt->src.fb->drm_format);
> +	pixman_format_code_t dst_pixman = drm_format_to_pixman(cvt->dst.fb->drm_format);
> +	pixman_image_t *dst_image, *src_image;
> +
> +	igt_assert((src_pixman != PIXMAN_invalid) &&
> +		   (dst_pixman != PIXMAN_invalid));
> +
> +	src_image = pixman_image_create_bits(src_pixman,
> +					     cvt->width, cvt->height,
> +					     cvt->src.ptr, cvt->src.fb->stride);
> +	igt_assert(src_image);
> +
> +	dst_image = pixman_image_create_bits(dst_pixman,
> +					     cvt->width, cvt->height,
> +					     cvt->dst.ptr, cvt->dst.fb->stride);
> +	igt_assert(dst_image);
> +
> +	pixman_image_composite(PIXMAN_OP_SRC, src_image, NULL, dst_image,
> +			       0, 0, 0, 0, 0, 0, cvt->width, cvt->height);
> +	pixman_image_unref(dst_image);
> +	pixman_image_unref(src_image);
> +}
> +
>  static void fb_convert(struct fb_convert *cvt)
>  {
> -	if (cvt->dst.fb->drm_format == DRM_FORMAT_RGB888) {
> +	if ((drm_format_to_pixman(cvt->src.fb->drm_format) != PIXMAN_invalid) &&
> +	    (drm_format_to_pixman(cvt->dst.fb->drm_format) != PIXMAN_invalid)) {
> +		convert_pixman(cvt);
> +		return;
> +	} else if (cvt->dst.fb->drm_format == DRM_FORMAT_RGB888) {
>  		switch (cvt->src.fb->drm_format) {
>  		case DRM_FORMAT_NV12:
>  			convert_nv12_to_rgb24(cvt);
> @@ -2130,7 +2180,8 @@ bool igt_fb_supported_format(uint32_t drm_format)
>  
>  	for_each_format(f)
>  		if (f->drm_id == drm_format)
> -			return f->cairo_id != CAIRO_FORMAT_INVALID;
> +			return (f->cairo_id != CAIRO_FORMAT_INVALID) ||
> +				(f->pixman_id != PIXMAN_invalid);
>  
>  	return false;
>  }
> -- 
> git-series 0.9.1


More information about the igt-dev mailing list