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

Reply via email to