[Pixman] [PATCH 2/4] general: Fetch the source directly into the destination

Chris Wilson chris at chris-wilson.co.uk
Sun Jan 27 06:10:26 PST 2013


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 <chris at chris-wilson.co.uk>
---
 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



More information about the Pixman mailing list