diff options
author | Siarhei Siamashka <siarhei.siamashka@nokia.com> | 2009-11-09 14:10:00 +0200 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-11-20 11:18:58 +0100 |
commit | 6e2c7d54c6786b52ae7dc683d2dbb4c7c033bb09 (patch) | |
tree | 7cb5072f55a39c1f75ec6656e884a544cdb79eb1 | |
parent | 98bb0a509f401563b8e6e15f4ee26947e9c3d419 (diff) |
C fast path function for 'over_n_1_0565'
This function is needed to improve performance of xfce4 terminal when
using bitmap fonts and running with 16bpp desktop. Some other applications
may potentially benefit too.
After applying this patch, top functions from Xorg process in
oprofile log change from
samples % image name symbol name
13296 29.1528 libpixman-1.so.0.17.1 combine_over_u
6452 14.1466 libpixman-1.so.0.17.1 fetch_scanline_r5g6b5
5516 12.0944 libpixman-1.so.0.17.1 fetch_scanline_a1
2273 4.9838 libpixman-1.so.0.17.1 store_scanline_r5g6b5
1741 3.8173 libpixman-1.so.0.17.1 fast_composite_add_1000_1000
1718 3.7669 libc-2.9.so memcpy
to
samples % image name symbol name
5594 14.7033 libpixman-1.so.0.17.1 fast_composite_over_n_1_0565
4323 11.3626 libc-2.9.so memcpy
3695 9.7119 libpixman-1.so.0.17.1 fast_composite_add_1000_1000
when scrolling text in terminal (reading man page).
-rw-r--r-- | pixman/pixman-fast-path.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index d2c456b6..75a0c1e0 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1175,6 +1175,104 @@ fast_composite_over_n_1_8888 (pixman_implementation_t *imp, } } +static void +fast_composite_over_n_1_0565 (pixman_implementation_t *imp, + pixman_op_t op, + pixman_image_t * src_image, + pixman_image_t * mask_image, + pixman_image_t * dst_image, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + uint32_t src, srca; + uint16_t *dst, *dst_line; + uint32_t *mask, *mask_line; + int mask_stride, dst_stride; + uint32_t bitcache, bitmask; + int32_t w; + uint32_t d; + uint16_t src565; + + if (width <= 0) + return; + + src = _pixman_image_get_solid (src_image, dst_image->bits.format); + srca = src >> 24; + if (src == 0) + return; + + PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, + dst_stride, dst_line, 1); + PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t, + mask_stride, mask_line, 1); + mask_line += mask_x >> 5; + + if (srca == 0xff) + { + src565 = CONVERT_8888_TO_0565 (src); + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + bitcache = *mask++; + bitmask = CREATE_BITMASK (mask_x & 31); + + while (w--) + { + if (bitmask == 0) + { + bitcache = *mask++; + bitmask = CREATE_BITMASK (0); + } + if (bitcache & bitmask) + *dst = src565; + bitmask = UPDATE_BITMASK (bitmask); + dst++; + } + } + } + else + { + while (height--) + { + dst = dst_line; + dst_line += dst_stride; + mask = mask_line; + mask_line += mask_stride; + w = width; + + bitcache = *mask++; + bitmask = CREATE_BITMASK (mask_x & 31); + + while (w--) + { + if (bitmask == 0) + { + bitcache = *mask++; + bitmask = CREATE_BITMASK (0); + } + if (bitcache & bitmask) + { + d = over (src, CONVERT_0565_TO_0888 (*dst)); + *dst = CONVERT_8888_TO_0565 (d); + } + bitmask = UPDATE_BITMASK (bitmask); + dst++; + } + } + } +} + /* * Simple bitblt */ @@ -1261,6 +1359,8 @@ static const pixman_fast_path_t c_fast_paths[] = { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8r8g8b8, fast_composite_over_n_1_8888, }, { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_a8b8g8r8, fast_composite_over_n_1_8888, }, { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8b8g8r8, fast_composite_over_n_1_8888, }, + { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_r5g6b5, fast_composite_over_n_1_0565 }, + { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_b5g6r5, fast_composite_over_n_1_0565 }, { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, fast_composite_over_n_8888_8888_ca }, { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_x8r8g8b8, fast_composite_over_n_8888_8888_ca }, { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_r5g6b5, fast_composite_over_n_8888_0565_ca }, |