C fast path function for 'over_n_1_8888'
authorSiarhei Siamashka <siarhei.siamashka@nokia.com>
Tue, 27 Oct 2009 10:25:13 +0000 (12:25 +0200)
committerSiarhei Siamashka <siarhei.siamashka@nokia.com>
Tue, 27 Oct 2009 10:32:04 +0000 (12:32 +0200)
This function is needed to improve performance of xfce4 terminal.
Some other applications may potentially benefit too.

pixman/pixman-fast-path.c

index 2bff8b4..e8857b1 100644 (file)
@@ -1083,6 +1083,98 @@ fast_composite_add_1000_1000 (pixman_implementation_t *imp,
     }
 }
 
+static void
+fast_composite_over_n_1_8888 (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;
+    uint32_t    *dst, *dst_line;
+    uint32_t    *mask, *mask_line;
+    int          mask_stride, dst_stride;
+    uint32_t     bitcache, bitmask;
+    int32_t      w;
+
+    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, uint32_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)
+    {
+       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 = src;
+               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)
+                   *dst = over (src, *dst);
+               bitmask = UPDATE_BITMASK (bitmask);
+               dst++;
+           }
+       }
+    }
+}
+
 /*
  * Simple bitblt
  */
@@ -1165,6 +1257,10 @@ static const pixman_fast_path_t c_fast_paths[] =
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fast_composite_over_n_8_8888, 0 },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fast_composite_over_n_8_8888, 0 },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fast_composite_over_n_8_8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,       PIXMAN_a8r8g8b8, fast_composite_over_n_1_8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,       PIXMAN_x8r8g8b8, fast_composite_over_n_1_8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,       PIXMAN_a8b8g8r8, fast_composite_over_n_1_8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,       PIXMAN_x8b8g8r8, fast_composite_over_n_1_8888, 0 },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fast_composite_over_n_8888_8888_ca, NEED_COMPONENT_ALPHA },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fast_composite_over_n_8888_8888_ca, NEED_COMPONENT_ALPHA },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fast_composite_over_n_8888_0565_ca, NEED_COMPONENT_ALPHA },