[Pixman] [PATCH 1/2] Shortcut for the source iterator to fetch directly to destination

Siarhei Siamashka siarhei.siamashka at gmail.com
Wed Aug 28 18:16:07 PDT 2013


In the case if combine step is going to be a simple memcpy from
the temporary buffer to the destination (SRC  operator, no mask,
x8r8g8b8 or a8r8g8b8 destination format), just route the source
iterator-based fetch operation to the destination buffer.

Earlier the source iterator was getting a constant pointer to
the temporary buffer. Now it also gets a pointer to the current
destination scanline pointer provided by the destination iterator.
If the source fetcher wants to support fetching directly to the
destination, it can use this new pointer instead of the temporary
buffer.
---
 pixman/pixman-general.c        | 28 ++++++++++++++++++++--------
 pixman/pixman-image.c          |  2 +-
 pixman/pixman-implementation.c |  2 ++
 pixman/pixman-private.h        |  2 ++
 4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 6310bff..749a8a9 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -121,6 +121,8 @@ general_composite_rect  (pixman_implementation_t *imp,
     pixman_combine_32_func_t compose;
     pixman_bool_t component_alpha;
     iter_flags_t width_flag, src_iter_flags;
+    uint32_t *d;
+    uint32_t **direct_dest_buffer_ptr = NULL;
     int Bpp;
     int i;
 
@@ -156,14 +158,22 @@ general_composite_rect  (pixman_implementation_t *imp,
 	memset (mask_buffer, 0, width * Bpp);
 	memset (dest_buffer, 0, width * Bpp);
     }
-    
+
+    /* Shortcut the source fetcher to the destination image for SRC operator */
+    if (op == PIXMAN_OP_SRC && !mask_image &&
+        (dest_image->bits.format == PIXMAN_x8r8g8b8 ||
+         dest_image->bits.format == PIXMAN_a8r8g8b8))
+    {
+	direct_dest_buffer_ptr = &d;
+    }
+
     /* src iter */
     src_iter_flags = width_flag | op_flags[op].src | ITER_SRC;
 
     _pixman_implementation_iter_init (imp->toplevel, &src_iter, src_image,
                                       src_x, src_y, width, height,
-                                      src_buffer, src_iter_flags,
-                                      info->src_flags);
+                                      src_buffer, direct_dest_buffer_ptr,
+                                      src_iter_flags, info->src_flags);
 
     /* mask iter */
     if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
@@ -183,27 +193,29 @@ general_composite_rect  (pixman_implementation_t *imp,
 
     _pixman_implementation_iter_init (
 	imp->toplevel, &mask_iter,
-	mask_image, mask_x, mask_y, width, height, mask_buffer,
+	mask_image, mask_x, mask_y, width, height, mask_buffer, NULL,
 	ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB),
 	info->mask_flags);
 
     /* dest iter */
     _pixman_implementation_iter_init (
 	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
-	dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
+	dest_buffer, NULL, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
 
     compose = _pixman_implementation_lookup_combiner (
 	imp->toplevel, op, component_alpha, width_flag != ITER_WIDE);
 
     for (i = 0; i < height; ++i)
     {
-	uint32_t *s, *m, *d;
+	uint32_t *s, *m;
 
+	d = dest_iter.get_scanline (&dest_iter, NULL);
 	m = mask_iter.get_scanline (&mask_iter, NULL);
 	s = src_iter.get_scanline (&src_iter, m);
-	d = dest_iter.get_scanline (&dest_iter, NULL);
 
-	compose (imp->toplevel, op, d, s, m, width);
+	/* Skip the compose step if fetching directly to the destination */
+	if (!direct_dest_buffer_ptr || s != d)
+	    compose (imp->toplevel, op, d, s, m, width);
 
 	dest_iter.write_back (&dest_iter);
     }
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 1ff1a49..ac93863 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -922,7 +922,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
     otherwise:
 	_pixman_implementation_iter_init (
 	    imp, &iter, image, 0, 0, 1, 1,
-	    (uint8_t *)&result,
+	    (uint8_t *)&result, NULL,
 	    ITER_NARROW | ITER_SRC, image->common.flags);
 	
 	result = *iter.get_scanline (&iter, NULL);
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 5884054..1dd70db 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -300,6 +300,7 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp,
                                   int                      width,
                                   int                      height,
                                   uint8_t                 *buffer,
+                                  uint32_t               **direct_dest_buffer_ptr,
                                   iter_flags_t             iter_flags,
                                   uint32_t                 image_flags)
 {
@@ -307,6 +308,7 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp,
 
     iter->image = image;
     iter->buffer = (uint32_t *)buffer;
+    iter->direct_dest_buffer_ptr = direct_dest_buffer_ptr;
     iter->x = x;
     iter->y = y;
     iter->width = width;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9646605..30e696c 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -247,6 +247,7 @@ struct pixman_iter_t
     /* These are initialized by _pixman_implementation_{src,dest}_init */
     pixman_image_t *		image;
     uint32_t *			buffer;
+    uint32_t **			direct_dest_buffer_ptr;
     int				x, y;
     int				width;
     int				height;
@@ -570,6 +571,7 @@ _pixman_implementation_iter_init (pixman_implementation_t       *imp,
                                   int                            width,
                                   int                            height,
                                   uint8_t                       *buffer,
+                                  uint32_t                     **direct_dest_buffer_ptr,
                                   iter_flags_t                   flags,
                                   uint32_t                       image_flags);
 
-- 
1.8.1.5



More information about the Pixman mailing list