From a0f127692f5a4379caa88383819e5340829cb0af Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Mon, 22 Feb 2010 07:39:54 -0500 Subject: Move fast path lookup to its own function --- pixman/pixman.c | 209 ++++++++++++++++++++++++++++++-------------------------- 1 file 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), - ®ion, 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), + ®ion, func); } -out: if (unlikely (need_workaround)) { unapply_workaround (src, src_bits, src_dx, src_dy); -- cgit v1.2.3