pixman: Branch 'master' - 3 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Thu Jul 15 09:37:48 PDT 2010


 pixman/pixman.c |  230 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 126 insertions(+), 104 deletions(-)

New commits:
commit 5dd59c8b7cf1543605713a2ac30f31d8726f5444
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Jul 10 16:49:51 2010 -0400

    Split the fast path caching into its own force_inline function
    
    The do_composite() function is a lot more readable this way.

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 4dfd3ae..80a766a 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -572,9 +572,105 @@ typedef struct
 
 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
 
+static force_inline void
+lookup_composite_function (pixman_op_t			op,
+			   pixman_format_code_t		src_format,
+			   uint32_t			src_flags,
+			   pixman_format_code_t		mask_format,
+			   uint32_t			mask_flags,
+			   pixman_format_code_t		dest_format,
+			   uint32_t			dest_flags,
+			   pixman_implementation_t    **out_imp,
+			   pixman_composite_func_t     *out_func)
+{
+    pixman_implementation_t *imp;
+    cache_t *cache;
+    int i;
+
+    /* Check cache for fast paths */
+    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
+
+    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
+    {
+	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
+
+	/* Note that we check for equality here, not whether
+	 * the cached fast path matches. This is to prevent
+	 * us from selecting an overly general fast path
+	 * when a more specific one would work.
+	 */
+	if (info->op == op			&&
+	    info->src_format == src_format	&&
+	    info->mask_format == mask_format	&&
+	    info->dest_format == dest_format	&&
+	    info->src_flags == src_flags	&&
+	    info->mask_flags == mask_flags	&&
+	    info->dest_flags == dest_flags	&&
+	    info->func)
+	{
+	    *out_imp = cache->cache[i].imp;
+	    *out_func = cache->cache[i].fast_path.func;
+
+	    goto update_cache;
+	}
+    }
+
+    for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
+    {
+	const pixman_fast_path_t *info = imp->fast_paths;
+
+	while (info->op != PIXMAN_OP_NONE)
+	{
+	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
+		/* Formats */
+		((info->src_format == src_format) ||
+		 (info->src_format == PIXMAN_any))			&&
+		((info->mask_format == mask_format) ||
+		 (info->mask_format == PIXMAN_any))			&&
+		((info->dest_format == dest_format) ||
+		 (info->dest_format == PIXMAN_any))			&&
+		/* Flags */
+		(info->src_flags & src_flags) == info->src_flags	&&
+		(info->mask_flags & mask_flags) == info->mask_flags	&&
+		(info->dest_flags & dest_flags) == info->dest_flags)
+	    {
+		*out_imp = imp;
+		*out_func = info->func;
+
+		/* Set i to the last spot in the cache so that the
+		 * move-to-front code below will work
+		 */
+		i = N_CACHED_FAST_PATHS - 1;
+
+		goto update_cache;
+	    }
+
+	    ++info;
+	}
+    }
+    return;
+
+update_cache:
+    if (i)
+    {
+	while (i--)
+	    cache->cache[i + 1] = cache->cache[i];
+
+	cache->cache[0].imp = *out_imp;
+	cache->cache[0].fast_path.op = op;
+	cache->cache[0].fast_path.src_format = src_format;
+	cache->cache[0].fast_path.src_flags = src_flags;
+	cache->cache[0].fast_path.mask_format = mask_format;
+	cache->cache[0].fast_path.mask_flags = mask_flags;
+	cache->cache[0].fast_path.dest_format = dest_format;
+	cache->cache[0].fast_path.dest_flags = dest_flags;
+	cache->cache[0].fast_path.func = *out_func;
+    }
+}
+
+
 static void
-do_composite (pixman_implementation_t *imp,
-	      pixman_op_t	       op,
+do_composite (pixman_op_t	       op,
 	      pixman_image_t	      *src,
 	      pixman_image_t	      *mask,
 	      pixman_image_t	      *dest,
@@ -598,9 +694,8 @@ do_composite (pixman_implementation_t *imp,
     uint32_t *dest_bits;
     int dest_dx, dest_dy;
     pixman_bool_t need_workaround;
-    const pixman_fast_path_t *info;
-    cache_t *cache;
-    int i;
+    pixman_implementation_t *imp;
+    pixman_composite_func_t func;
 
     src_format = src->common.extended_format_code;
     src_flags = src->common.flags;
@@ -666,71 +761,12 @@ do_composite (pixman_implementation_t *imp,
     if (op == PIXMAN_OP_DST)
 	return;
 
-    /* Check cache for fast paths */
-    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
-
-    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
-    {
-	info = &(cache->cache[i].fast_path);
-
-	/* Note that we check for equality here, not whether
-	 * the cached fast path matches. This is to prevent
-	 * us from selecting an overly general fast path
-	 * when a more specific one would work.
-	 */
-	if (info->op == op			&&
-	    info->src_format == src_format	&&
-	    info->mask_format == mask_format	&&
-	    info->dest_format == dest_format	&&
-	    info->src_flags == src_flags	&&
-	    info->mask_flags == mask_flags	&&
-	    info->dest_flags == dest_flags	&&
-	    info->func)
-	{
-	    imp = cache->cache[i].imp;
-	    goto found;
-	}
-    }
-
-    while (imp)
-    {
-	info = imp->fast_paths;
-
-	while (info->op != PIXMAN_OP_NONE)
-	{
-	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
-		/* Formats */
-		((info->src_format == src_format) ||
-		 (info->src_format == PIXMAN_any))			&&
-		((info->mask_format == mask_format) ||
-		 (info->mask_format == PIXMAN_any))			&&
-		((info->dest_format == dest_format) ||
-		 (info->dest_format == PIXMAN_any))			&&
-		/* Flags */
-		(info->src_flags & src_flags) == info->src_flags	&&
-		(info->mask_flags & mask_flags) == info->mask_flags	&&
-		(info->dest_flags & dest_flags) == info->dest_flags)
-	    {
-		/* Set i to the last spot in the cache so that the
-		 * move-to-front code below will work
-		 */
-		i = N_CACHED_FAST_PATHS - 1;
-
-		goto found;
-	    }
-
-	    ++info;
-	}
-
-	imp = imp->delegate;
-    }
-
-    /* We didn't find a compositing routine. This should not happen, but if
-     * it somehow does, just exit rather than crash.
-     */
-    goto out;
+    lookup_composite_function (op,
+			       src_format, src_flags,
+			       mask_format, mask_flags,
+			       dest_format, dest_flags,
+			       &imp, &func);			       
 
-found:
     walk_region_internal (imp, op,
 			  src, mask, dest,
 			  src_x, src_y, mask_x, mask_y,
@@ -738,30 +774,8 @@ found:
 			  width, height,
 			  (src_flags & FAST_PATH_SIMPLE_REPEAT),
 			  (mask_flags & FAST_PATH_SIMPLE_REPEAT),
-			  &region, info->func);
-
-    if (i)
-    {
-	/* Make a copy of info->func, because info->func may change when
-	 * we update the cache.
-	 */
-	pixman_composite_func_t func = info->func;
-	
-	while (i--)
-	    cache->cache[i + 1] = cache->cache[i];
-
-	cache->cache[0].imp = imp;
-	cache->cache[0].fast_path.op = op;
-	cache->cache[0].fast_path.src_format = src_format;
-	cache->cache[0].fast_path.src_flags = src_flags;
-	cache->cache[0].fast_path.mask_format = mask_format;
-	cache->cache[0].fast_path.mask_flags = mask_flags;
-	cache->cache[0].fast_path.dest_format = dest_format;
-	cache->cache[0].fast_path.dest_flags = dest_flags;
-	cache->cache[0].fast_path.func = func;
-    }
+			  &region, func);
 
-out:
     if (need_workaround)
     {
 	unapply_workaround (src, src_bits, src_dx, src_dy);
@@ -828,7 +842,7 @@ pixman_image_composite32 (pixman_op_t      op,
 	_pixman_image_validate (mask);
     _pixman_image_validate (dest);
 
-    do_composite (get_implementation(), op,
+    do_composite (op,
 		  src, mask, dest,
 		  src_x, src_y,
 		  mask_x, mask_y,
commit 98d19d9abd9d62b8d2871871b0be74e022f1f89f
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Jul 10 16:08:51 2010 -0400

    Cache the implementation along with the fast paths.
    
    When calling a fast path, we need to pass the corresponding
    implementation since it might contain information necessary to run the
    fast path.

diff --git a/pixman/pixman.c b/pixman/pixman.c
index b76143f..4dfd3ae 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -563,7 +563,11 @@ compute_src_extents_flags (pixman_image_t *image,
 
 typedef struct
 {
-    pixman_fast_path_t cache [N_CACHED_FAST_PATHS];
+    struct
+    {
+	pixman_implementation_t *	imp;
+	pixman_fast_path_t		fast_path;
+    } cache [N_CACHED_FAST_PATHS];
 } cache_t;
 
 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
@@ -667,7 +671,7 @@ do_composite (pixman_implementation_t *imp,
 
     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
     {
-	info = &(cache->cache[i]);
+	info = &(cache->cache[i].fast_path);
 
 	/* Note that we check for equality here, not whether
 	 * the cached fast path matches. This is to prevent
@@ -683,6 +687,7 @@ do_composite (pixman_implementation_t *imp,
 	    info->dest_flags == dest_flags	&&
 	    info->func)
 	{
+	    imp = cache->cache[i].imp;
 	    goto found;
 	}
     }
@@ -745,14 +750,15 @@ found:
 	while (i--)
 	    cache->cache[i + 1] = cache->cache[i];
 
-	cache->cache[0].op = op;
-	cache->cache[0].src_format = src_format;
-	cache->cache[0].src_flags = src_flags;
-	cache->cache[0].mask_format = mask_format;
-	cache->cache[0].mask_flags = mask_flags;
-	cache->cache[0].dest_format = dest_format;
-	cache->cache[0].dest_flags = dest_flags;
-	cache->cache[0].func = func;
+	cache->cache[0].imp = imp;
+	cache->cache[0].fast_path.op = op;
+	cache->cache[0].fast_path.src_format = src_format;
+	cache->cache[0].fast_path.src_flags = src_flags;
+	cache->cache[0].fast_path.mask_format = mask_format;
+	cache->cache[0].fast_path.mask_flags = mask_flags;
+	cache->cache[0].fast_path.dest_format = dest_format;
+	cache->cache[0].fast_path.dest_flags = dest_flags;
+	cache->cache[0].fast_path.func = func;
     }
 
 out:
commit f18bcf1f6e984c33dca30ad1ce03c58628fe39df
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Jul 10 15:47:12 2010 -0400

    Hide the global implementation variable behind a force_inline function.
    
    Previously the global variable was called 'imp' which was confusing
    with the argument to various other functions also being called imp.

diff --git a/pixman/pixman.c b/pixman/pixman.c
index 56c9536..b76143f 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -30,7 +30,16 @@
 
 #include <stdlib.h>
 
-static pixman_implementation_t *imp;
+static force_inline pixman_implementation_t *
+get_implementation (void)
+{
+    static pixman_implementation_t *global_implementation;
+
+    if (!global_implementation)
+	global_implementation = _pixman_choose_implementation ();
+
+    return global_implementation;
+}
 
 typedef struct operator_info_t operator_info_t;
 
@@ -813,10 +822,7 @@ pixman_image_composite32 (pixman_op_t      op,
 	_pixman_image_validate (mask);
     _pixman_image_validate (dest);
 
-    if (!imp)
-	imp = _pixman_choose_implementation ();
-
-    do_composite (imp, op,
+    do_composite (get_implementation(), op,
 		  src, mask, dest,
 		  src_x, src_y,
 		  mask_x, mask_y,
@@ -838,10 +844,8 @@ pixman_blt (uint32_t *src_bits,
             int       width,
             int       height)
 {
-    if (!imp)
-	imp = _pixman_choose_implementation ();
-
-    return _pixman_implementation_blt (imp, src_bits, dst_bits, src_stride, dst_stride,
+    return _pixman_implementation_blt (get_implementation(),
+				       src_bits, dst_bits, src_stride, dst_stride,
                                        src_bpp, dst_bpp,
                                        src_x, src_y,
                                        dst_x, dst_y,
@@ -858,10 +862,8 @@ pixman_fill (uint32_t *bits,
              int       height,
              uint32_t xor)
 {
-    if (!imp)
-	imp = _pixman_choose_implementation ();
-
-    return _pixman_implementation_fill (imp, bits, stride, bpp, x, y, width, height, xor);
+    return _pixman_implementation_fill (
+	get_implementation(), bits, stride, bpp, x, y, width, height, xor);
 }
 
 static uint32_t


More information about the xorg-commit mailing list