This is principally used by external renderers to convert a procedural
pixman_image_t (SourcePict) into an image that they can handle, using a
simple pixman_image_composite(SRC, source, NULL, dst). For these cases
we typicall hit the general_composite_rect and so retrieve the source
into a temporary buffer before copying back to the destination. This
allows us to eliminate that extra copy.

Only benefit for cairo-image is lost in the noise.

Signed-off-by: Chris Wilson <[email protected]>
---
 pixman/pixman-general.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 93a1b9a..a5a4974 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -106,6 +106,51 @@ static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
 #define SCANLINE_BUFFER_LENGTH 8192
 
 static void
+general_SRC_inplace (pixman_implementation_t *imp,
+                    pixman_composite_info_t *info)
+{
+    PIXMAN_COMPOSITE_ARGS (info);
+    uint32_t *dst_line;
+    int dst_stride;
+    pixman_iter_t src_iter;
+
+    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, 
dst_line, 1);
+
+    _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
+                                         src_x, src_y, width, height,
+                                         (uint8_t *)dst_line,
+                                         op_flags[op].src | ITER_NARROW,
+                                         info->src_flags);
+    if (src_iter.get_scanline == _pixman_iter_get_scanline_noop)
+    {
+       while (--height)
+       {
+           dst_line += dst_stride;
+           memcpy(dst_line, src_iter.buffer, 4*width);
+       }
+    }
+    else
+    {
+       while (height--)
+       {
+           uint32_t *s;
+
+           s = src_iter.get_scanline (&src_iter, NULL);
+           if (s != dst_line)
+           {
+               memcpy(dst_line, s, 4*width);
+               dst_line += dst_stride;
+           }
+           else
+           {
+               dst_line += dst_stride;
+               src_iter.buffer = dst_line;
+           }
+       }
+    }
+}
+
+static void
 general_composite_rect  (pixman_implementation_t *imp,
                          pixman_composite_info_t *info)
 {
@@ -207,7 +252,11 @@ general_composite_rect  (pixman_implementation_t *imp,
 
 static const pixman_fast_path_t general_fast_path[] =
 {
+    { PIXMAN_OP_SRC, PIXMAN_any, FAST_PATH_NARROW_FORMAT, PIXMAN_null, 0, 
PIXMAN_a8r8g8b8, FAST_PATH_STD_DEST_FLAGS, general_SRC_inplace },
+    { PIXMAN_OP_SRC, PIXMAN_any, FAST_PATH_NARROW_FORMAT, PIXMAN_null, 0, 
PIXMAN_x8r8g8b8, FAST_PATH_STD_DEST_FLAGS, general_SRC_inplace },
+
     { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any,        0, PIXMAN_any, 0, 
general_composite_rect },
+
     { PIXMAN_OP_NONE }
 };
 
-- 
1.7.10.4

_______________________________________________
Pixman mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to