[Pixman] [PATCH 1/2] pixman: Add support for argb/xrgb float formats, v3.

Bryce Harrington bryce at bryceharrington.org
Fri Aug 3 05:01:53 UTC 2018


On Wed, Aug 01, 2018 at 02:41:33PM +0200, Maarten Lankhorst wrote:
> Pixman is already using the floating point formats internally, expose
> this capability in case someone wants to support higher bit per
> component formats.
> 
> This is useful for igt which depends on cairo to do the rendering.
> It can use it to convert floats internally to planar Y'CbCr formats,
> or to F16.
> 
> Changes since v1:
> - Use RGBA 128 bits and RGB 96 bits memory layouts, to better match the opengl format.
> Changes since v2:
> - Add asserts in accessor and for strides to force alignment.
> - Move test changes to their own commit.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> ---
>  pixman/pixman-access.c     | 128 ++++++++++++++++++++++++++++++++++++-
>  pixman/pixman-bits-image.c |   3 +
>  pixman/pixman-image.c      |   4 ++
>  pixman/pixman.h            |  32 ++++++----
>  4 files changed, 155 insertions(+), 12 deletions(-)
> 
> diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
> index 4f0642d77785..10fa049becf4 100644
> --- a/pixman/pixman-access.c
> +++ b/pixman/pixman-access.c
> @@ -642,6 +642,48 @@ fetch_scanline_a2r10g10b10_float (bits_image_t *  image,
>  }
>  
>  /* Expects a float buffer */
> +#ifndef PIXMAN_FB_ACCESSORS
> +static void
> +fetch_scanline_rgb_float_float (bits_image_t   *image,

Just out of curiosity, why are these routines named with float twice?

Bryce

> +				int             x,
> +				int             y,
> +				int             width,
> +				uint32_t *      b,
> +				const uint32_t *mask)
> +{
> +    const float *bits = (float *)image->bits + y * image->rowstride;
> +    const float *pixel = bits + x * 3;
> +    argb_t *buffer = (argb_t *)b;
> +
> +    for (; width--; buffer++) {
> +	buffer->r = *pixel++;
> +	buffer->g = *pixel++;
> +	buffer->b = *pixel++;
> +	buffer->a = 1.f;
> +    }
> +}
> +
> +static void
> +fetch_scanline_rgba_float_float (bits_image_t   *image,
> +				int             x,
> +				int             y,
> +				int             width,
> +				uint32_t *      b,
> +				const uint32_t *mask)
> +{
> +    const float *bits = (float *)image->bits + y * image->rowstride;
> +    const float *pixel = bits + x * 4;
> +    argb_t *buffer = (argb_t *)b;
> +
> +    for (; width--; buffer++) {
> +	buffer->r = *pixel++;
> +	buffer->g = *pixel++;
> +	buffer->b = *pixel++;
> +	buffer->a = *pixel++;
> +    }
> +}
> +#endif
> +
>  static void
>  fetch_scanline_x2r10g10b10_float (bits_image_t   *image,
>  				  int             x,
> @@ -805,6 +847,40 @@ fetch_scanline_yv12 (bits_image_t   *image,
>  
>  /**************************** Pixel wise fetching *****************************/
>  
> +#ifndef PIXMAN_FB_ACCESSORS
> +static argb_t
> +fetch_pixel_rgb_float_float (bits_image_t *image,
> +			     int	    offset,
> +			     int	    line)
> +{
> +    float *bits = (float *)image->bits + line * image->rowstride;
> +    argb_t argb;
> +
> +    argb.r = bits[offset * 3];
> +    argb.g = bits[offset * 3 + 1];
> +    argb.b = bits[offset * 3 + 2];
> +    argb.a = 1.f;
> +
> +    return argb;
> +}
> +
> +static argb_t
> +fetch_pixel_rgba_float_float (bits_image_t *image,
> +			      int	    offset,
> +			      int	    line)
> +{
> +    float *bits = (float *)image->bits + line * image->rowstride;
> +    argb_t argb;
> +
> +    argb.r = bits[offset * 4];
> +    argb.g = bits[offset * 4 + 1];
> +    argb.b = bits[offset * 4 + 2];
> +    argb.a = bits[offset * 4 + 3];
> +
> +    return argb;
> +}
> +#endif
> +
>  static argb_t
>  fetch_pixel_x2r10g10b10_float (bits_image_t *image,
>  			       int	   offset,
> @@ -962,6 +1038,45 @@ fetch_pixel_yv12 (bits_image_t *image,
>  
>  /*********************************** Store ************************************/
>  
> +#ifndef PIXMAN_FB_ACCESSORS
> +static void
> +store_scanline_rgba_float_float (bits_image_t *  image,
> +				 int             x,
> +				 int             y,
> +				 int             width,
> +				 const uint32_t *v)
> +{
> +    float *bits = (float *)image->bits + image->rowstride * y + 4 * x;
> +    const argb_t *values = (argb_t *)v;
> +
> +    for (; width; width--, values++)
> +    {
> +	*bits++ = values->r;
> +	*bits++ = values->g;
> +	*bits++ = values->b;
> +	*bits++ = values->a;
> +    }
> +}
> +
> +static void
> +store_scanline_rgb_float_float (bits_image_t *  image,
> +				int             x,
> +				int             y,
> +				int             width,
> +				const uint32_t *v)
> +{
> +    float *bits = (float *)image->bits + image->rowstride * y + 3 * x;
> +    const argb_t *values = (argb_t *)v;
> +
> +    for (; width; width--, values++)
> +    {
> +	*bits++ = values->r;
> +	*bits++ = values->g;
> +	*bits++ = values->b;
> +    }
> +}
> +#endif
> +
>  static void
>  store_scanline_a2r10g10b10_float (bits_image_t *  image,
>  				  int             x,
> @@ -1351,7 +1466,18 @@ static const format_info_t accessors[] =
>      FORMAT_INFO (g1),
>      
>  /* Wide formats */
> -    
> +#ifndef PIXMAN_FB_ACCESSORS
> +    { PIXMAN_rgba_float,
> +      NULL, fetch_scanline_rgba_float_float,
> +      fetch_pixel_generic_lossy_32, fetch_pixel_rgba_float_float,
> +      NULL, store_scanline_rgba_float_float },
> +
> +    { PIXMAN_rgb_float,
> +      NULL, fetch_scanline_rgb_float_float,
> +      fetch_pixel_generic_lossy_32, fetch_pixel_rgb_float_float,
> +      NULL, store_scanline_rgb_float_float },
> +#endif
> +
>      { PIXMAN_a2r10g10b10,
>        NULL, fetch_scanline_a2r10g10b10_float,
>        fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float,
> diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
> index dcdcc69946de..9fb91ff5831d 100644
> --- a/pixman/pixman-bits-image.c
> +++ b/pixman/pixman-bits-image.c
> @@ -948,6 +948,9 @@ _pixman_bits_image_init (pixman_image_t *     image,
>  {
>      uint32_t *free_me = NULL;
>  
> +    if (PIXMAN_FORMAT_BPP (format) == 128)
> +	return_val_if_fail(!(rowstride % 4), FALSE);
> +
>      if (!bits && width && height)
>      {
>  	int rowstride_bytes;
> diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
> index 681864eb7d17..7a851e221992 100644
> --- a/pixman/pixman-image.c
> +++ b/pixman/pixman-image.c
> @@ -842,6 +842,10 @@ pixman_image_set_accessors (pixman_image_t *           image,
>  
>      if (image->type == BITS)
>      {
> +	/* Accessors only work for <= 32 bpp. */
> +	if (PIXMAN_FORMAT_BPP(image->bits.format) > 32)
> +	    return_if_fail (!read_func && !write_func);
> +
>  	image->bits.read_func = read_func;
>  	image->bits.write_func = write_func;
>  
> diff --git a/pixman/pixman.h b/pixman/pixman.h
> index 509ba5e534a8..c9bf4faa80d4 100644
> --- a/pixman/pixman.h
> +++ b/pixman/pixman.h
> @@ -647,19 +647,24 @@ struct pixman_indexed
>   * sample implementation allows only packed RGB and GBR
>   * representations for data to simplify software rendering,
>   */
> -#define PIXMAN_FORMAT(bpp,type,a,r,g,b)	(((bpp) << 24) |  \
> +#define PIXMAN_FORMAT_PACKC(val) ((val) <= 10 ? (val) : \
> +				 (val) == 32 ? 11 : 0)
> +#define PIXMAN_FORMAT_UNPACKC(val) ((val) <= 10 ? (val) : \
> +				    (val) == 11 ? 32 : 0)
> +
> +#define PIXMAN_FORMAT(bpp,type,a,r,g,b)	((((uint32_t)(bpp)) << 24) |  \
>  					 ((type) << 16) | \
> -					 ((a) << 12) |	  \
> -					 ((r) << 8) |	  \
> -					 ((g) << 4) |	  \
> -					 ((b)))
> +					 (PIXMAN_FORMAT_PACKC(a) << 12) |	  \
> +					 (PIXMAN_FORMAT_PACKC(r) << 8) |	  \
> +					 (PIXMAN_FORMAT_PACKC(g) << 4) |	  \
> +					 (PIXMAN_FORMAT_PACKC(b)))
>  
> -#define PIXMAN_FORMAT_BPP(f)	(((f) >> 24)       )
> +#define PIXMAN_FORMAT_BPP(f)	(((uint32_t)(f)) >> 24)
>  #define PIXMAN_FORMAT_TYPE(f)	(((f) >> 16) & 0xff)
> -#define PIXMAN_FORMAT_A(f)	(((f) >> 12) & 0x0f)
> -#define PIXMAN_FORMAT_R(f)	(((f) >>  8) & 0x0f)
> -#define PIXMAN_FORMAT_G(f)	(((f) >>  4) & 0x0f)
> -#define PIXMAN_FORMAT_B(f)	(((f)      ) & 0x0f)
> +#define PIXMAN_FORMAT_A(f)	PIXMAN_FORMAT_UNPACKC(((f) >> 12) & 0x0f)
> +#define PIXMAN_FORMAT_R(f)	PIXMAN_FORMAT_UNPACKC(((f) >>  8) & 0x0f)
> +#define PIXMAN_FORMAT_G(f)	PIXMAN_FORMAT_UNPACKC(((f) >>  4) & 0x0f)
> +#define PIXMAN_FORMAT_B(f)	PIXMAN_FORMAT_UNPACKC(((f) >>  0) & 0x0f)
>  #define PIXMAN_FORMAT_RGB(f)	(((f)      ) & 0xfff)
>  #define PIXMAN_FORMAT_VIS(f)	(((f)      ) & 0xffff)
>  #define PIXMAN_FORMAT_DEPTH(f)	(PIXMAN_FORMAT_A(f) +	\
> @@ -685,8 +690,13 @@ struct pixman_indexed
>  	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA ||	\
>  	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA)
>  
> -/* 32bpp formats */
>  typedef enum {
> +/* 128bpp formats */
> +    PIXMAN_rgba_float =	PIXMAN_FORMAT(128,PIXMAN_TYPE_ARGB,32,32,32,32),
> +/* 96bpp formats */
> +    PIXMAN_rgb_float =	PIXMAN_FORMAT(96,PIXMAN_TYPE_ARGB,0,32,32,32),
> +
> +/* 32bpp formats */
>      PIXMAN_a8r8g8b8 =	 PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8),
>      PIXMAN_x8r8g8b8 =	 PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8),
>      PIXMAN_a8b8g8r8 =	 PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8),
> -- 
> 2.18.0
> 
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pixman


More information about the Pixman mailing list