From: Søren Sandmann Pedersen <s...@redhat.com> In pixman-bits-image.c, remove bits_image_fetch_untransformed_64() and add bits_image_fetch_untransformed_float(); change dest_get_scanline_wide() to produce a floating point buffer,
In the gradients, change *_get_scanline_wide() to call pixman_expand_to_float() instead of pixman_expand(). In pixman-general.c change the wide Bpp to 16 instead of 8, and initialize the buffers to 0 to prevent NaNs from causing trouble. In pixman-noop.c make the wide solid iterator generate floating point pixels. In pixman-solid-fill.c, cache a floating point pixel, and make the wide iterator generate floating point pixels. --- pixman/pixman-bits-image.c | 64 ++++++++++++++++++-------------------- pixman/pixman-conical-gradient.c | 3 +- pixman/pixman-general.c | 10 +++++- pixman/pixman-implementation.c | 4 +- pixman/pixman-linear-gradient.c | 3 +- pixman/pixman-noop.c | 6 ++-- pixman/pixman-private.h | 3 +- pixman/pixman-radial-gradient.c | 3 +- pixman/pixman-solid-fill.c | 10 ++++-- 9 files changed, 59 insertions(+), 47 deletions(-) diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 07353dc..81a5a6f 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -979,17 +979,17 @@ replicate_pixel_32 (bits_image_t * bits, } static void -replicate_pixel_64 (bits_image_t * bits, - int x, - int y, - int width, - uint32_t * b) +replicate_pixel_float (bits_image_t * bits, + int x, + int y, + int width, + uint32_t * b) { - uint64_t color; - uint64_t *buffer = (uint64_t *)b; - uint64_t *end; + argb_t color; + argb_t *buffer = (argb_t *)b; + argb_t *end; - color = bits->fetch_pixel_64 (bits, x, y); + color = bits->fetch_pixel_float (bits, x, y); end = buffer + width; while (buffer < end) @@ -1008,7 +1008,7 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, if (y < 0 || y >= image->height) { - memset (buffer, 0, width * (wide? 8 : 4)); + memset (buffer, 0, width * (wide? sizeof (argb_t) : 4)); return; } @@ -1016,10 +1016,10 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, { w = MIN (width, -x); - memset (buffer, 0, w * (wide ? 8 : 4)); + memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4)); width -= w; - buffer += w * (wide? 2 : 1); + buffer += w * (wide? 4 : 1); x += w; } @@ -1028,16 +1028,16 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, w = MIN (width, image->width - x); if (wide) - image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); else image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); width -= w; - buffer += w * (wide? 2 : 1); + buffer += w * (wide? 4 : 1); x += w; } - memset (buffer, 0, width * (wide ? 8 : 4)); + memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4)); } static void @@ -1059,7 +1059,7 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, if (image->width == 1) { if (wide) - replicate_pixel_64 (image, 0, y, width, buffer); + replicate_pixel_float (image, 0, y, width, buffer); else replicate_pixel_32 (image, 0, y, width, buffer); @@ -1076,7 +1076,7 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, w = MIN (width, image->width - x); if (wide) - image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); else image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); @@ -1112,9 +1112,8 @@ bits_image_fetch_untransformed_32 (pixman_iter_t * iter, } static uint32_t * -bits_image_fetch_untransformed_64 (pixman_iter_t * iter, - const uint32_t *mask) - +bits_image_fetch_untransformed_float (pixman_iter_t * iter, + const uint32_t *mask) { pixman_image_t *image = iter->image; int x = iter->x; @@ -1155,8 +1154,8 @@ static const fetcher_info_t fetcher_info[] = FAST_PATH_NO_PAD_REPEAT | FAST_PATH_NO_REFLECT_REPEAT), bits_image_fetch_untransformed_32, - bits_image_fetch_untransformed_64, - _pixman_image_get_scanline_generic_float + NULL, + bits_image_fetch_untransformed_float }, #define FAST_BILINEAR_FLAGS \ @@ -1278,7 +1277,7 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) else { iter->data = info->get_scanline_32; - iter->get_scanline = info->get_scanline_64; + iter->get_scanline = info->get_scanline_float; } return; } @@ -1333,30 +1332,27 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) int x = iter->x; int y = iter->y; int width = iter->width; - uint64_t * buffer = (uint64_t *)iter->buffer; + argb_t * buffer = (argb_t *)iter->buffer; - image->fetch_scanline_64 ( + image->fetch_scanline_float ( (pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask); if (image->common.alpha_map) { - uint64_t *alpha; + argb_t *alpha; - if ((alpha = malloc (width * sizeof (uint64_t)))) + if ((alpha = malloc (width * sizeof (argb_t)))) { int i; x -= image->common.alpha_origin_x; y -= image->common.alpha_origin_y; - image->common.alpha_map->fetch_scanline_64 ( + image->common.alpha_map->fetch_scanline_float ( (pixman_image_t *)image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask); for (i = 0; i < width; ++i) - { - buffer[i] &= ~0xffff000000000000ULL; - buffer[i] |= (alpha[i] & 0xffff000000000000ULL); - } + buffer[i].a = alpha[i].a; free (alpha); } @@ -1397,14 +1393,14 @@ dest_write_back_wide (pixman_iter_t *iter) int width = iter->width; const uint32_t *buffer = iter->buffer; - image->store_scanline_64 (image, x, y, width, buffer); + image->store_scanline_float (image, x, y, width, buffer); if (image->common.alpha_map) { x -= image->common.alpha_origin_x; y -= image->common.alpha_origin_y; - image->common.alpha_map->store_scanline_64 ( + image->common.alpha_map->store_scanline_float ( image->common.alpha_map, x, y, width, buffer); } diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c index 8b52176..1e971fd 100644 --- a/pixman/pixman-conical-gradient.c +++ b/pixman/pixman-conical-gradient.c @@ -165,7 +165,8 @@ conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + pixman_expand_to_float ( + (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); return buffer; } diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 2d92014..12294e8 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -130,7 +130,7 @@ general_composite_rect (pixman_implementation_t *imp, else { narrow = 0; - Bpp = 8; + Bpp = 16; } if (width * Bpp > SCANLINE_BUFFER_LENGTH) @@ -145,6 +145,14 @@ general_composite_rect (pixman_implementation_t *imp, mask_buffer = src_buffer + width * Bpp; dest_buffer = mask_buffer + width * Bpp; + if (!narrow) + { + /* To make sure there aren't any NANs in the buffers */ + memset (src_buffer, 0, width * Bpp); + memset (mask_buffer, 0, width * Bpp); + memset (dest_buffer, 0, width * Bpp); + } + /* src iter */ src_iter_flags = narrow | op_flags[op].src; diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index 5dd0501..a70892c 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -177,11 +177,11 @@ _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, switch ((narrow << 1) | component_alpha) { case 0: /* not narrow, not component alpha */ - f = (pixman_combine_32_func_t)imp->combine_64[op]; + f = (pixman_combine_32_func_t)imp->combine_float[op]; break; case 1: /* not narrow, component_alpha */ - f = (pixman_combine_32_func_t)imp->combine_64_ca[op]; + f = (pixman_combine_32_func_t)imp->combine_float_ca[op]; break; case 2: /* narrow, not component alpha */ diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c index 32b8ba7..e6d6884 100644 --- a/pixman/pixman-linear-gradient.c +++ b/pixman/pixman-linear-gradient.c @@ -227,7 +227,8 @@ linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + pixman_expand_to_float ( + (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); return buffer; } diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c index 7b9759f..850caa1 100644 --- a/pixman/pixman-noop.c +++ b/pixman/pixman-noop.c @@ -93,9 +93,9 @@ noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) } else { - uint64_t color = bits->fetch_pixel_64 (bits, 0, 0); - uint64_t *buffer = (uint64_t *)iter->buffer; - uint64_t *end = buffer + iter->width; + argb_t color = bits->fetch_pixel_float (bits, 0, 0); + argb_t *buffer = (argb_t *)iter->buffer; + argb_t *end = buffer + iter->width; while (buffer < end) *(buffer++) = color; diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 766dafa..9d77a72 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -126,9 +126,10 @@ struct solid_fill { image_common_t common; pixman_color_t color; - + uint32_t color_32; uint64_t color_64; + argb_t color_float; }; struct gradient diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c index 715711f..39d0cb3 100644 --- a/pixman/pixman-radial-gradient.c +++ b/pixman/pixman-radial-gradient.c @@ -405,7 +405,8 @@ radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + pixman_expand_to_float ( + (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); return buffer; } diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c index 8b25d5d..1b774d9 100644 --- a/pixman/pixman-solid-fill.c +++ b/pixman/pixman-solid-fill.c @@ -40,9 +40,9 @@ _pixman_solid_fill_iter_init (pixman_image_t *image, pixman_iter_t *iter) } else { - uint64_t *b = (uint64_t *)iter->buffer; - uint64_t *e = b + iter->width; - uint64_t color = image->solid.color_64; + argb_t *b = (argb_t *)iter->buffer; + argb_t *e = b + iter->width; + argb_t color = image->solid.color_float; while (b < e) *(b++) = color; @@ -83,6 +83,10 @@ pixman_image_create_solid_fill (pixman_color_t *color) img->solid.color = *color; img->solid.color_32 = color_to_uint32 (color); img->solid.color_64 = color_to_uint64 (color); + img->solid.color_float.a = pixman_unorm_to_float (color->alpha, 16); + img->solid.color_float.r = pixman_unorm_to_float (color->red, 16); + img->solid.color_float.g = pixman_unorm_to_float (color->green, 16); + img->solid.color_float.b = pixman_unorm_to_float (color->blue, 16); return img; } -- 1.7.4 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman