diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-07-10 16:49:51 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-07-11 09:43:56 -0400 |
commit | 5dd59c8b7cf1543605713a2ac30f31d8726f5444 (patch) | |
tree | 490d2d15f9a3706692830a1877ad2504526707b2 | |
parent | 98d19d9abd9d62b8d2871871b0be74e022f1f89f (diff) |
Split the fast path caching into its own force_inline function
The do_composite() function is a lot more readable this way.
-rw-r--r-- | pixman/pixman.c | 200 |
1 files changed, 107 insertions, 93 deletions
diff --git a/pixman/pixman.c b/pixman/pixman.c index 4dfd3aee..80a766aa 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, |