From: Siarhei Siamashka Date: Mon, 15 Nov 2010 16:26:43 +0000 (+0200) Subject: C fast path for a1 fill operation X-Git-Tag: pixman-0.21.4~53 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b5b5a2a832cd67f2a0ec231f75a2825b45571fa;p=platform%2Fupstream%2Fpixman.git C fast path for a1 fill operation Can be used as one of the solutions to fix bug https://bugs.freedesktop.org/show_bug.cgi?id=31604 --- diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 5d5fa95..37dfbae 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1334,7 +1334,11 @@ fast_composite_solid_fill (pixman_implementation_t *imp, src = _pixman_image_get_solid (src_image, dst_image->bits.format); - if (dst_image->bits.format == PIXMAN_a8) + if (dst_image->bits.format == PIXMAN_a1) + { + src = src >> 31; + } + else if (dst_image->bits.format == PIXMAN_a8) { src = src >> 24; } @@ -1655,6 +1659,7 @@ static const pixman_fast_path_t c_fast_paths[] = PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill), PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill), PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill), + PIXMAN_STD_FAST_PATH (SRC, solid, null, a1, fast_composite_solid_fill), PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill), PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill), PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, fast_composite_src_x888_8888), @@ -1733,6 +1738,82 @@ static const pixman_fast_path_t c_fast_paths[] = { PIXMAN_OP_NONE }, }; +#ifdef WORDS_BIGENDIAN +#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (32 - (offs) - (n))) +#else +#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (offs)) +#endif + +static force_inline void +pixman_fill1_line (uint32_t *dst, int offs, int width, int v) +{ + if (offs) + { + int leading_pixels = 32 - offs; + if (leading_pixels >= width) + { + if (v) + *dst |= A1_FILL_MASK (width, offs); + else + *dst &= ~A1_FILL_MASK (width, offs); + return; + } + else + { + if (v) + *dst++ |= A1_FILL_MASK (leading_pixels, offs); + else + *dst++ &= ~A1_FILL_MASK (leading_pixels, offs); + width -= leading_pixels; + } + } + while (width >= 32) + { + if (v) + *dst++ = 0xFFFFFFFF; + else + *dst++ = 0; + width -= 32; + } + if (width > 0) + { + if (v) + *dst |= A1_FILL_MASK (width, 0); + else + *dst &= ~A1_FILL_MASK (width, 0); + } +} + +static void +pixman_fill1 (uint32_t *bits, + int stride, + int x, + int y, + int width, + int height, + uint32_t xor) +{ + uint32_t *dst = bits + y * stride + (x >> 5); + int offs = x & 31; + + if (xor & 1) + { + while (height--) + { + pixman_fill1_line (dst, offs, width, 1); + dst += stride; + } + } + else + { + while (height--) + { + pixman_fill1_line (dst, offs, width, 0); + dst += stride; + } + } +} + static void pixman_fill8 (uint32_t *bits, int stride, @@ -1819,6 +1900,10 @@ fast_path_fill (pixman_implementation_t *imp, { switch (bpp) { + case 1: + pixman_fill1 (bits, stride, x, y, width, height, xor); + break; + case 8: pixman_fill8 (bits, stride, x, y, width, height, xor); break; diff --git a/pixman/pixman.c b/pixman/pixman.c index 045c556..ec565f9 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -875,7 +875,8 @@ color_to_pixel (pixman_color_t * color, format == PIXMAN_b8g8r8x8 || format == PIXMAN_r5g6b5 || format == PIXMAN_b5g6r5 || - format == PIXMAN_a8)) + format == PIXMAN_a8 || + format == PIXMAN_a1)) { return FALSE; } @@ -895,7 +896,9 @@ color_to_pixel (pixman_color_t * color, ((c & 0x000000ff) << 24); } - if (format == PIXMAN_a8) + if (format == PIXMAN_a1) + c = c >> 31; + else if (format == PIXMAN_a8) c = c >> 24; else if (format == PIXMAN_r5g6b5 || format == PIXMAN_b5g6r5)