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.lankho...@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@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pixman
_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to