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),
- ®ion, 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;
- }
+ ®ion, 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