From: Taekyun Kim <tkq....@samsung.com> Too short scanlines can cause repeat handling overhead and optimized pixman composite functions usually process a bunch of pixels in a single loop iteration it might be beneficial to pre-extend source scanlines. The temporary buffers will usually reside in cache, so accessing them should be quite efficient. --- pixman/pixman-fast-path.c | 95 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 2dda24b..0e254c7 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1191,6 +1191,8 @@ FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE) FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD) FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL) +#define REPEAT_MIN_WIDTH 32 + static void fast_composite_tiled_repeat (pixman_implementation_t *imp, pixman_composite_info_t *info) @@ -1223,27 +1225,114 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp, int32_t sx, sy; int32_t width_remain; int32_t num_pixels; + int32_t src_width; + int32_t i, j; + pixman_image_t extended_src_image; + uint32_t extended_src[REPEAT_MIN_WIDTH*2]; + pixman_bool_t need_src_extension; + uint32_t *src_line; + int32_t src_stride; + int32_t src_bpp; pixman_composite_info_t info2 = *info; + src_bpp = PIXMAN_FORMAT_BPP (src_image->bits.format); + + if (src_image->bits.width < REPEAT_MIN_WIDTH && + (src_bpp == 32 || src_bpp == 16 || src_bpp == 8)) + { + sx = src_x; + sx = MOD (sx, src_image->bits.width); + sx += width; + src_width = 0; + + while (src_width < REPEAT_MIN_WIDTH && src_width <= sx) + src_width += src_image->bits.width; + + need_src_extension = TRUE; + extended_src_image.bits = src_image->bits; + extended_src_image.bits.bits = &extended_src[0]; + extended_src_image.bits.width = src_width; + extended_src_image.bits.height = 1; + info2.src_image = &extended_src_image; + } + else + { + src_width = src_image->bits.width; + need_src_extension = FALSE; + } + sx = src_x; sy = src_y; while (--height >= 0) { - sx = MOD (sx, src_image->bits.width); + sx = MOD (sx, src_width); sy = MOD (sy, src_image->bits.height); + if (need_src_extension) + { + if (src_bpp == 32) + { + PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, src_stride, src_line, 1); + + for (i=0; i<src_width; ) + { + for (j=0; j<src_image->bits.width; j++, i++) + { + extended_src[i] = src_line[j]; + } + } + } + else if (src_bpp == 16) + { + uint16_t *src_line_16; + + PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint16_t, src_stride, + src_line_16, 1); + src_line = (uint32_t*)src_line_16; + + for (i=0; i<src_width; ) + { + for (j=0; j<src_image->bits.width; j++, i++) + { + ((uint16_t*)extended_src)[i] = ((uint16_t*)src_line)[j]; + } + } + } + else if (src_bpp == 8) + { + uint8_t *src_line_8; + + PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint8_t, src_stride, + src_line_8, 1); + src_line = (uint32_t*)src_line_8; + + for (i=0; i<src_width; ) + { + for (j=0; j<src_image->bits.width; j++, i++) + { + ((uint8_t*)extended_src)[i] = ((uint8_t*)src_line)[j]; + } + } + } + + info2.src_y = 0; + } + else + { + info2.src_y = sy; + } + width_remain = width; while (width_remain > 0) { - num_pixels = src_image->bits.width - sx; + num_pixels = src_width - sx; if (num_pixels > width_remain) num_pixels = width_remain; info2.src_x = sx; - info2.src_y = sy; info2.width = num_pixels; info2.height = 1; -- 1.7.1 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman