pixman: Branch 'master' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 6 13:32:12 UTC 2018


 pixman/pixman-access.c     |  128 ++++++++++++++++++++++++++++++++++++++++++++-
 pixman/pixman-bits-image.c |    3 +
 pixman/pixman-image.c      |    4 +
 pixman/pixman.c            |    5 +
 pixman/pixman.h            |   35 +++++++++---
 test/alphamap.c            |   73 ++++++++++++++++++-------
 test/stress-test.c         |   75 +++++++++++++++++++-------
 test/utils.c               |   76 ++++++++++++++++++++++++++
 test/utils.h               |    2 
 9 files changed, 352 insertions(+), 49 deletions(-)

New commits:
commit 489fa0df11eef83912932f7be881f35bbe0a1b93
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Wed Jul 11 12:10:41 2018 +0200

    pixman: Add tests for (a)rgb floating point formats.
    
    Add some basic tests to ensure that the newly added formats work as
    intended.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/alphamap.c b/test/alphamap.c
index 4d09076..150d33e 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -10,7 +10,8 @@ static const pixman_format_code_t formats[] =
     PIXMAN_a8r8g8b8,
     PIXMAN_a2r10g10b10,
     PIXMAN_a4r4g4b4,
-    PIXMAN_a8
+    PIXMAN_a8,
+    PIXMAN_rgba_float,
 };
 
 static const pixman_format_code_t alpha_formats[] =
@@ -18,7 +19,8 @@ static const pixman_format_code_t alpha_formats[] =
     PIXMAN_null,
     PIXMAN_a8,
     PIXMAN_a2r10g10b10,
-    PIXMAN_a4r4g4b4
+    PIXMAN_a4r4g4b4,
+    PIXMAN_rgba_float,
 };
 
 static const int origins[] =
@@ -41,7 +43,10 @@ make_image (pixman_format_code_t format)
     uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
     pixman_image_t *image;
 
-    bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
+    if (format != PIXMAN_rgba_float)
+	bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
+    else
+	bits = (uint32_t *)make_random_floats (WIDTH * HEIGHT * bpp);
 
     image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
 
@@ -51,11 +56,11 @@ make_image (pixman_format_code_t format)
     return image;
 }
 
-static uint8_t
+static float
 get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
 {
     uint8_t *bits;
-    uint8_t r;
+    uint32_t r;
 
     if (image->common.alpha_map)
     {
@@ -69,7 +74,7 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
 	}
 	else
 	{
-	    return 0;
+	    return 0.f;
 	}
     }
 
@@ -78,28 +83,32 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
     if (image->bits.format == PIXMAN_a8)
     {
 	r = bits[y * WIDTH + x];
+	return r / 255.f;
     }
     else if (image->bits.format == PIXMAN_a2r10g10b10)
     {
 	r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
-	r |= r << 2;
-	r |= r << 4;
+	return r / 3.f;
     }
     else if (image->bits.format == PIXMAN_a8r8g8b8)
     {
 	r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
+	return r / 255.f;
     }
     else if (image->bits.format == PIXMAN_a4r4g4b4)
     {
 	r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
-	r |= r << 4;
+	return r / 15.f;
+    }
+    else if (image->bits.format == PIXMAN_rgba_float)
+    {
+	return ((float *)bits)[y * WIDTH * 4 + x * 4 + 3];
     }
     else
     {
 	assert (0);
+	return 0.f;
     }
-
-    return r;
 }
 
 static uint16_t
@@ -133,6 +142,11 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
 	r |= r << 4;
 	r |= r << 8;
     }
+    else if (image->bits.format == PIXMAN_rgba_float)
+    {
+	double tmp = ((float *)bits)[y * WIDTH * 4 + x * 4];
+	return tmp * 65535.;
+    }
     else
     {
 	assert (0);
@@ -141,6 +155,23 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
     return r;
 }
 
+static float get_alpha_err(pixman_format_code_t sf, pixman_format_code_t saf,
+			   pixman_format_code_t df, pixman_format_code_t daf)
+{
+	pixman_format_code_t s = saf != PIXMAN_null ? saf : sf;
+	pixman_format_code_t d = daf != PIXMAN_null ? daf : df;
+
+	/* There are cases where we go through the 8 bit compositing
+	 * path even with 10bpc and higher formats.
+	 */
+	if (PIXMAN_FORMAT_A(s) == PIXMAN_FORMAT_A(d))
+		return 1.f / 255.f;
+	else if (PIXMAN_FORMAT_A(s) > PIXMAN_FORMAT_A(d))
+		return 1.f / ((1 << PIXMAN_FORMAT_A(d)) - 1);
+	else
+		return 1.f / ((1 << PIXMAN_FORMAT_A(s)) - 1);
+}
+
 static int
 run_test (int s, int d, int sa, int da, int soff, int doff)
 {
@@ -151,15 +182,11 @@ run_test (int s, int d, int sa, int da, int soff, int doff)
     pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha;
     pixman_transform_t t1;
     int j, k;
-    int n_alpha_bits, n_red_bits;
+    int n_red_bits;
 
     soff = origins[soff];
     doff = origins[doff];
 
-    n_alpha_bits = PIXMAN_FORMAT_A (df);
-    if (daf != PIXMAN_null)
-	n_alpha_bits = PIXMAN_FORMAT_A (daf);
-
     n_red_bits = PIXMAN_FORMAT_R (df);
 
     /* Source */
@@ -211,21 +238,25 @@ run_test (int s, int d, int sa, int da, int soff, int doff)
     {
 	for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
 	{
-	    uint8_t sa, da, oda, refa;
+	    float sa, da, oda, refa;
 	    uint16_t sr, dr, odr, refr;
+	    float err;
+
+	    err = get_alpha_err(sf, saf, df, daf);
 
 	    sa = get_alpha (src, k, j, soff, soff);
 	    da = get_alpha (dst, k, j, doff, doff);
 	    oda = get_alpha (orig_dst, k, j, doff, doff);
 
-	    if (sa + oda > 255)
-		refa = 255;
+	    if (sa + oda > 1.f)
+		refa = 1.f;
 	    else
 		refa = sa + oda;
 
-	    if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits))
+	    if (da - err > refa ||
+	        da + err < refa)
 	    {
-		printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
+		printf ("\nWrong alpha value at (%d, %d). Should be %g; got %g. Source was %g, original dest was %g\n",
 			k, j, refa, da, sa, oda);
 
 		printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
diff --git a/test/stress-test.c b/test/stress-test.c
index 85d1293..6b4f7d6 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -11,6 +11,8 @@
 
 static const pixman_format_code_t image_formats[] =
 {
+    PIXMAN_rgba_float,
+    PIXMAN_rgb_float,
     PIXMAN_a8r8g8b8,
     PIXMAN_x8r8g8b8,
     PIXMAN_r5g6b5,
@@ -100,6 +102,14 @@ get_size (void)
     }
 }
 
+static uint32_t
+real_reader (const void *src, int size);
+
+static void *xor_ptr(const void *ptr)
+{
+	return (void *)(((intptr_t)ptr) ^ (intptr_t)0x8000000080000000);
+}
+
 static void
 destroy (pixman_image_t *image, void *data)
 {
@@ -114,6 +124,9 @@ destroy (pixman_image_t *image, void *data)
 	    if (image->bits.rowstride < 0)
 		bits -= (- image->bits.rowstride * (image->bits.height - 1));
 
+	    if (image->bits.read_func == real_reader)
+		bits = xor_ptr(bits);
+
 	    fence_free (bits);
 	}
     }
@@ -124,6 +137,7 @@ destroy (pixman_image_t *image, void *data)
 static uint32_t
 real_reader (const void *src, int size)
 {
+    src = xor_ptr(src);
     switch (size)
     {
     case 1:
@@ -141,6 +155,7 @@ real_reader (const void *src, int size)
 static void
 real_writer (void *src, uint32_t value, int size)
 {
+    src = xor_ptr(src);
     switch (size)
     {
     case 1:
@@ -247,9 +262,20 @@ create_random_bits_image (alpha_preference_t alpha_preference)
     pixman_filter_t filter;
     pixman_fixed_t *coefficients = NULL;
     int n_coefficients = 0;
+    int align_add, align_mask;
 
     /* format */
     format = random_format (alpha_preference);
+    switch (PIXMAN_FORMAT_BPP (format)) {
+    case 128:
+	align_mask = 15;
+	align_add = align_mask + prng_rand_n (65);
+	break;
+    default:
+	align_mask = 3;
+	align_add = align_mask + prng_rand_n (17);
+	break;
+    }
 
     indexed = NULL;
     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
@@ -291,9 +317,12 @@ create_random_bits_image (alpha_preference_t alpha_preference)
     {
     default:
     case 0:
-	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17);
-	stride = (stride + 3) & (~3);
-	bits = (uint32_t *)make_random_bytes (height * stride);
+	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8;
+	stride = (stride + align_add) & (~align_mask);
+	if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float)
+	    bits = (uint32_t *)make_random_floats (height * stride);
+	else
+	    bits = (uint32_t *)make_random_bytes (height * stride);
 	break;
 
     case 1:
@@ -302,8 +331,8 @@ create_random_bits_image (alpha_preference_t alpha_preference)
 	break;
 
     case 2: /* Zero-filled */
-	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17);
-	stride = (stride + 3) & (~3);
+	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8;
+	stride = (stride + align_add) & (~align_mask);
 	bits = fence_malloc (height * stride);
 	if (!bits)
 	    return NULL;
@@ -311,8 +340,8 @@ create_random_bits_image (alpha_preference_t alpha_preference)
 	break;
 
     case 3: /* Filled with 0xFF */
-	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17);
-	stride = (stride + 3) & (~3);
+	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8;
+	stride = (stride + align_add) & (~align_mask);
 	bits = fence_malloc (height * stride);
 	if (!bits)
 	    return NULL;
@@ -320,27 +349,35 @@ create_random_bits_image (alpha_preference_t alpha_preference)
 	break;
 
     case 4: /* bits is a bad pointer, has read/write functions */
-	stride = 232;
-	bits = (void *)0x01;
-	read_func = fake_reader;
-	write_func = fake_writer;
-	break;
+	if (PIXMAN_FORMAT_BPP (format) <= 32) {
+	    stride = 232;
+	    bits = (void *)0x01;
+	    read_func = fake_reader;
+	    write_func = fake_writer;
+	    break;
+	}
 
     case 5: /* bits is a real pointer, has read/write functions */
-	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17);
-	stride = (stride + 3) & (~3);
+	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8;
+	stride = (stride + align_add) & (~align_mask);
 	bits = fence_malloc (height * stride);
 	if (!bits)
 	    return NULL;
 	memset (bits, 0xff, height * stride);
-	read_func = real_reader;
-	write_func = real_writer;
+	if (PIXMAN_FORMAT_BPP (format) <= 32) {
+	    bits = xor_ptr(bits);
+	    read_func = real_reader;
+	    write_func = real_writer;
+	}
 	break;
 
     case 6: /* bits is a real pointer, stride is negative */
-	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17);
-	stride = (stride + 3) & (~3);
-	bits = (uint32_t *)make_random_bytes (height * stride);
+	stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8;
+	stride = (stride + align_add) & (~align_mask);
+	if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float)
+	    bits = (uint32_t *)make_random_floats (height * stride);
+	else
+	    bits = (uint32_t *)make_random_bytes (height * stride);
 	if (!bits)
 	    return NULL;
 	bits += ((height - 1) * stride) / 4;
diff --git a/test/utils.c b/test/utils.c
index f8e42a5..4eeb068 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -595,6 +595,21 @@ make_random_bytes (int n_bytes)
     return bytes;
 }
 
+float *
+make_random_floats (int n_bytes)
+{
+    uint8_t *bytes = fence_malloc (n_bytes);
+    float *vals = (float *)bytes;
+
+    if (!bytes)
+	return 0;
+
+    for (n_bytes /= 4; n_bytes; vals++, n_bytes--)
+	*vals = (float)rand() / (float)RAND_MAX;
+
+    return (float *)bytes;
+}
+
 void
 a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels)
 {
@@ -1180,6 +1195,11 @@ static const format_entry_t format_list[] =
      * Aliases are not listed by list_formats ().
      */
 
+/* 128bpp formats */
+    ENTRY (rgba_float),
+/* 96bpp formats */
+    ENTRY (rgb_float),
+
 /* 32bpp formats */
     ENTRY (a8r8g8b8),
     ALIAS (a8r8g8b8,		"8888"),
@@ -1914,6 +1934,10 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format)
 
     checker->format = format;
 
+    if (format == PIXMAN_rgba_float ||
+	format == PIXMAN_rgb_float)
+	return;
+
     switch (PIXMAN_FORMAT_TYPE (format))
     {
     case PIXMAN_TYPE_A:
@@ -1970,10 +1994,19 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format)
     checker->bw = PIXMAN_FORMAT_B (format);
 }
 
+static void
+pixel_checker_require_uint32_format (const pixel_checker_t *checker)
+{
+    assert (checker->format != PIXMAN_rgba_float &&
+	    checker->format != PIXMAN_rgb_float);
+}
+
 void
 pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel,
 			   int *a, int *r, int *g, int *b)
 {
+    pixel_checker_require_uint32_format(checker);
+
     *a = (pixel & checker->am) >> checker->as;
     *r = (pixel & checker->rm) >> checker->rs;
     *g = (pixel & checker->gm) >> checker->gs;
@@ -1987,6 +2020,8 @@ pixel_checker_get_masks (const pixel_checker_t *checker,
                          uint32_t              *gm,
                          uint32_t              *bm)
 {
+    pixel_checker_require_uint32_format(checker);
+
     if (am)
         *am = checker->am;
     if (rm)
@@ -2003,6 +2038,8 @@ pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker,
 {
     int a, r, g, b;
 
+    pixel_checker_require_uint32_format(checker);
+
     pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b);
 
     if (checker->am == 0)
@@ -2078,6 +2115,8 @@ void
 pixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
 		       int *am, int *rm, int *gm, int *bm)
 {
+    pixel_checker_require_uint32_format(checker);
+
     get_limits (checker, DEVIATION, color, am, rm, gm, bm);
 }
 
@@ -2085,6 +2124,8 @@ void
 pixel_checker_get_min (const pixel_checker_t *checker, color_t *color,
 		       int *am, int *rm, int *gm, int *bm)
 {
+    pixel_checker_require_uint32_format(checker);
+
     get_limits (checker, - DEVIATION, color, am, rm, gm, bm);
 }
 
@@ -2096,6 +2137,8 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
     int32_t ai, ri, gi, bi;
     pixman_bool_t result;
 
+    pixel_checker_require_uint32_format(checker);
+
     pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo);
     pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi);
     pixel_checker_split_pixel (checker, pixel, &ai, &ri, &gi, &bi);
@@ -2108,3 +2151,36 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel,
 
     return result;
 }
+
+static void
+color_limits (const pixel_checker_t *checker,
+	      double limit, const color_t *color, color_t *out)
+{
+    if (PIXMAN_FORMAT_A(checker->format))
+	out->a = color->a + limit;
+    else
+	out->a = 1.;
+
+    out->r = color->r + limit;
+    out->g = color->g + limit;
+    out->b = color->b + limit;
+}
+
+pixman_bool_t
+pixel_checker_check_color (const pixel_checker_t *checker,
+			   const color_t *actual, const color_t *reference)
+{
+    color_t min, max;
+    pixman_bool_t result;
+
+    color_limits(checker, -DEVIATION, reference, &min);
+    color_limits(checker, DEVIATION, reference, &max);
+
+    result =
+	actual->a >= min.a && actual->a <= max.a &&
+	actual->r >= min.r && actual->r <= max.r &&
+	actual->g >= min.g && actual->g <= max.g &&
+	actual->b >= min.b && actual->b <= max.b;
+
+    return result;
+}
diff --git a/test/utils.h b/test/utils.h
index e299d1d..e5ac945 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -119,6 +119,8 @@ fence_get_page_size ();
 /* Generate n_bytes random bytes in fence_malloced memory */
 uint8_t *
 make_random_bytes (int n_bytes);
+float *
+make_random_floats (int n_bytes);
 
 /* Return current time in seconds */
 double
commit a4b8a26d2b741e1b3a17b58d34b67bffa17bf15c
Author: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Date:   Wed May 30 16:07:10 2018 +0200

    pixman: Add support for argb/xrgb float formats, v5.
    
    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.
    
    We add a new type PIXMAN_TYPE_RGBA_FLOAT for this format, which is an
    all float array of R, G, B, and A. Formats that use mixed float/int
    RGBA aren't supported, and will probably need their own type.
    
    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.
    Changes since v3:
    - Define 32bpc as PIXMAN_FORMAT_PACKED_C32
    - Rename pixman accessors from rgb*_float_float to rgb*f_float
    Changes since v4:
    - Create a new PIXMAN_FORMAT_BYTE for fitting up to 64 bits per component.
      (based on Siarhei Siamashka's suggestion)
    - Use new format type PIXMAN_TYPE_RGBA_FLOAT
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> #v4
    [mlankhorst: Fix missing braces in PIXMAN_FORMAT_RESHIFT macro]

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 4f0642d..8dfd35f 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_rgbf_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 * 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_rgbaf_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_rgbf_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_rgbaf_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_rgbaf_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_rgbf_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_rgbaf_float,
+      fetch_pixel_generic_lossy_32, fetch_pixel_rgbaf_float,
+      NULL, store_scanline_rgbaf_float },
+
+    { PIXMAN_rgb_float,
+      NULL, fetch_scanline_rgbf_float,
+      fetch_pixel_generic_lossy_32, fetch_pixel_rgbf_float,
+      NULL, store_scanline_rgbf_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 dcdcc69..9fb91ff 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 681864e..7a851e2 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.c b/pixman/pixman.c
index f932eac..c09b528 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -777,6 +777,11 @@ color_to_pixel (const pixman_color_t *color,
 {
     uint32_t c = color_to_uint32 (color);
 
+    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA_FLOAT)
+    {
+	return FALSE;
+    }
+
     if (!(format == PIXMAN_a8r8g8b8     ||
           format == PIXMAN_x8r8g8b8     ||
           format == PIXMAN_a8b8g8r8     ||
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 509ba5e..d644589 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -654,12 +654,24 @@ struct pixman_indexed
 					 ((g) << 4) |	  \
 					 ((b)))
 
-#define PIXMAN_FORMAT_BPP(f)	(((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_BYTE(bpp,type,a,r,g,b) \
+	(((bpp >> 3) << 24) | \
+	(3 << 22) | ((type) << 16) | \
+	((a >> 3) << 12) | \
+	((r >> 3) << 8) | \
+	((g >> 3) << 4) | \
+	((b >> 3)))
+
+#define PIXMAN_FORMAT_RESHIFT(val, ofs, num) \
+	(((val >> (ofs)) & ((1 << (num)) - 1)) << ((val >> 22) & 3))
+
+#define PIXMAN_FORMAT_BPP(f)	PIXMAN_FORMAT_RESHIFT(f, 24, 8)
+#define PIXMAN_FORMAT_SHIFT(f)	((uint32_t)((f >> 22) & 3))
+#define PIXMAN_FORMAT_TYPE(f)	(((f) >> 16) & 0x3f)
+#define PIXMAN_FORMAT_A(f)	PIXMAN_FORMAT_RESHIFT(f, 12, 4)
+#define PIXMAN_FORMAT_R(f)	PIXMAN_FORMAT_RESHIFT(f, 8, 4)
+#define PIXMAN_FORMAT_G(f)	PIXMAN_FORMAT_RESHIFT(f, 4, 4)
+#define PIXMAN_FORMAT_B(f)	PIXMAN_FORMAT_RESHIFT(f, 0, 4)
 #define PIXMAN_FORMAT_RGB(f)	(((f)      ) & 0xfff)
 #define PIXMAN_FORMAT_VIS(f)	(((f)      ) & 0xffff)
 #define PIXMAN_FORMAT_DEPTH(f)	(PIXMAN_FORMAT_A(f) +	\
@@ -678,15 +690,22 @@ struct pixman_indexed
 #define PIXMAN_TYPE_BGRA	8
 #define PIXMAN_TYPE_RGBA	9
 #define PIXMAN_TYPE_ARGB_SRGB	10
+#define PIXMAN_TYPE_RGBA_FLOAT	11
 
 #define PIXMAN_FORMAT_COLOR(f)				\
 	(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB ||	\
 	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR ||	\
 	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA ||	\
-	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA)
+	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA ||	\
+	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA_FLOAT)
 
-/* 32bpp formats */
 typedef enum {
+/* 128bpp formats */
+    PIXMAN_rgba_float =	PIXMAN_FORMAT_BYTE(128,PIXMAN_TYPE_RGBA_FLOAT,32,32,32,32),
+/* 96bpp formats */
+    PIXMAN_rgb_float =	PIXMAN_FORMAT_BYTE(96,PIXMAN_TYPE_RGBA_FLOAT,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),


More information about the xorg-commit mailing list