summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-02-22 07:39:54 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-03-14 12:59:37 -0400
commita0f127692f5a4379caa88383819e5340829cb0af (patch)
tree0cf8ee950b0e9d7894a222cd8ef9b7c0b4204067
parent9ae66f9a5670ccdbac70fdbf6ed761d3df21ecd6 (diff)
Move fast path lookup to its own function
-rw-r--r--pixman/pixman.c209
1 files changed, 113 insertions, 96 deletions
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 27eefbb0..7ac8fcd4 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -494,6 +494,107 @@ image_covers (pixman_image_t *image,
return TRUE;
}
+static pixman_composite_func_t
+lookup_fast_path (pixman_implementation_t *imp,
+ pixman_op_t op,
+ pixman_format_code_t src_format,
+ pixman_format_code_t mask_format,
+ pixman_format_code_t dest_format,
+ uint32_t src_flags,
+ uint32_t mask_flags,
+ uint32_t dest_flags)
+{
+#define N_CACHED_FAST_PATHS 8
+ static THREAD_LOCAL pixman_fast_path_t tls_cache[N_CACHED_FAST_PATHS];
+ pixman_fast_path_t *cache = tls_cache;
+ const pixman_fast_path_t *info;
+ pixman_composite_func_t func;
+ int i;
+
+ /* Check cache for fast paths */
+ for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
+ {
+ info = &(cache[i]);
+
+ /* 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)
+ {
+ goto found;
+ }
+ }
+
+ /* Check implementations for fast paths */
+ 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;
+ }
+
+ /* None found */
+ return NULL;
+
+found:
+ /* Make a copy of info->func, because since info points into
+ * the cache, it may change during move-to-front.
+ */
+ func = info->func;
+
+ if (i)
+ {
+ while (i--)
+ cache[i + 1] = cache[i];
+
+ cache[0].op = op;
+ cache[0].src_format = src_format;
+ cache[0].src_flags = src_flags;
+ cache[0].mask_format = mask_format;
+ cache[0].mask_flags = mask_flags;
+ cache[0].dest_format = dest_format;
+ cache[0].dest_flags = dest_flags;
+ cache[0].func = func;
+ }
+
+ return func;
+}
+
static void
do_composite (pixman_implementation_t *imp,
pixman_op_t op,
@@ -509,8 +610,6 @@ do_composite (pixman_implementation_t *imp,
int width,
int height)
{
-#define N_CACHED_FAST_PATHS 8
- static THREAD_LOCAL pixman_fast_path_t tls_cache[N_CACHED_FAST_PATHS];
pixman_format_code_t src_format, mask_format, dest_format;
uint32_t src_flags, mask_flags, dest_flags;
pixman_region32_t region;
@@ -522,9 +621,7 @@ do_composite (pixman_implementation_t *imp,
uint32_t *dest_bits;
int dest_dx, dest_dy;
pixman_bool_t need_workaround;
- pixman_fast_path_t *cache;
- const pixman_fast_path_t *info;
- int i;
+ pixman_composite_func_t func;
src_format = src->common.extended_format_code;
src_flags = src->common.flags;
@@ -590,100 +687,20 @@ do_composite (pixman_implementation_t *imp,
if (op == PIXMAN_OP_DST)
return;
- /* Check cache for fast paths */
- cache = tls_cache;
-
- for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
- {
- info = &(cache[i]);
-
- /* 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)
- {
- 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;
-
-found:
- walk_region_internal (imp, op,
- src, mask, dest,
- src_x, src_y, mask_x, mask_y,
- dest_x, dest_y,
- width, height,
- (src_flags & FAST_PATH_SIMPLE_REPEAT),
- (mask_flags & FAST_PATH_SIMPLE_REPEAT),
- &region, info->func);
-
- if (i)
+ if ((func = lookup_fast_path (imp, op,
+ src_format, mask_format, dest_format,
+ src_flags, mask_flags, dest_flags)))
{
- /* 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[i + 1] = cache[i];
-
- cache[0].op = op;
- cache[0].src_format = src_format;
- cache[0].src_flags = src_flags;
- cache[0].mask_format = mask_format;
- cache[0].mask_flags = mask_flags;
- cache[0].dest_format = dest_format;
- cache[0].dest_flags = dest_flags;
- cache[0].func = func;
+ walk_region_internal (imp, op,
+ src, mask, dest,
+ src_x, src_y, mask_x, mask_y,
+ dest_x, dest_y,
+ width, height,
+ (src_flags & FAST_PATH_SIMPLE_REPEAT),
+ (mask_flags & FAST_PATH_SIMPLE_REPEAT),
+ &region, func);
}
-out:
if (unlikely (need_workaround))
{
unapply_workaround (src, src_bits, src_dx, src_dy);