diff options
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/pixman/pixman-arm-neon.c | 89 | ||||
-rw-r--r-- | pixman/pixman/pixman-fast-path.c | 8 | ||||
-rw-r--r-- | pixman/pixman/pixman-general.c | 46 | ||||
-rw-r--r-- | pixman/pixman/pixman-glyph.c | 4 | ||||
-rw-r--r-- | pixman/pixman/pixman-implementation.c | 276 | ||||
-rw-r--r-- | pixman/pixman/pixman-mips-dspr2.c | 89 | ||||
-rw-r--r-- | pixman/pixman/pixman-mmx.c | 119 | ||||
-rw-r--r-- | pixman/pixman/pixman-noop.c | 14 | ||||
-rw-r--r-- | pixman/pixman/pixman-private.h | 36 | ||||
-rw-r--r-- | pixman/pixman/pixman-sse2.c | 146 | ||||
-rw-r--r-- | pixman/pixman/pixman-utils.c | 112 | ||||
-rw-r--r-- | pixman/pixman/pixman.c | 2 | ||||
-rw-r--r-- | pixman/test/scaling-test.c | 40 |
13 files changed, 388 insertions, 593 deletions
diff --git a/pixman/pixman/pixman-arm-neon.c b/pixman/pixman/pixman-arm-neon.c index ca139de0b..60e9c78d2 100644 --- a/pixman/pixman/pixman-arm-neon.c +++ b/pixman/pixman/pixman-arm-neon.c @@ -183,14 +183,15 @@ pixman_composite_src_n_8888_asm_neon (int32_t w, uint32_t src); static pixman_bool_t -pixman_fill_neon (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor) +arm_neon_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t _xor) { /* stride is always multiple of 32bit units in pixman */ uint32_t byte_stride = stride * sizeof(uint32_t); @@ -227,18 +228,19 @@ pixman_fill_neon (uint32_t *bits, } static pixman_bool_t -pixman_blt_neon (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) +arm_neon_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) { if (src_bpp != dst_bpp) return FALSE; @@ -422,53 +424,6 @@ static const pixman_fast_path_t arm_neon_fast_paths[] = { PIXMAN_OP_NONE }, }; -static pixman_bool_t -arm_neon_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (!pixman_blt_neon ( - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height)) - - { - return _pixman_implementation_blt ( - imp->delegate, - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height); - } - - return TRUE; -} - -static pixman_bool_t -arm_neon_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor)) - return TRUE; - - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); -} - #define BIND_COMBINE_U(name) \ void \ pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \ diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index 9778b0cbe..86ed821d6 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -1258,7 +1258,7 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp, mask_flags = FAST_PATH_IS_OPAQUE; } - if (_pixman_lookup_composite_function ( + if (_pixman_implementation_lookup_composite ( imp->toplevel, info->op, src_image->common.extended_format_code, src_flags, mask_format, mask_flags, @@ -1458,7 +1458,7 @@ fetch_nearest (pixman_repeat_t src_repeat, { if (repeat (src_repeat, &x, src_width)) { - if (format == PIXMAN_x8r8g8b8) + if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8) return *(src + x) | 0xff000000; else return *(src + x); @@ -2192,9 +2192,7 @@ fast_path_fill (pixman_implementation_t *imp, break; default: - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); - break; + return FALSE; } return TRUE; diff --git a/pixman/pixman/pixman-general.c b/pixman/pixman/pixman-general.c index d4b2daa37..42a84a0b4 100644 --- a/pixman/pixman/pixman-general.c +++ b/pixman/pixman/pixman-general.c @@ -37,7 +37,7 @@ #include <string.h> #include "pixman-private.h" -static void +static pixman_bool_t general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; @@ -54,18 +54,24 @@ general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) _pixman_bits_image_src_iter_init (image, iter); else _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); + + return TRUE; } -static void +static pixman_bool_t general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { if (iter->image->type == BITS) { _pixman_bits_image_dest_iter_init (iter->image, iter); + + return TRUE; } else { _pixman_log_error (FUNC, "Trying to write to a non-writable image"); + + return FALSE; } } @@ -200,40 +206,6 @@ static const pixman_fast_path_t general_fast_path[] = { PIXMAN_OP_NONE } }; -static pixman_bool_t -general_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - /* We can't blit unless we have sse2 or mmx */ - - return FALSE; -} - -static pixman_bool_t -general_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - return FALSE; -} - pixman_implementation_t * _pixman_implementation_create_general (void) { @@ -242,8 +214,6 @@ _pixman_implementation_create_general (void) _pixman_setup_combiner_functions_32 (imp); _pixman_setup_combiner_functions_64 (imp); - imp->blt = general_blt; - imp->fill = general_fill; imp->src_iter_init = general_src_iter_init; imp->dest_iter_init = general_dest_iter_init; diff --git a/pixman/pixman/pixman-glyph.c b/pixman/pixman/pixman-glyph.c index cbc3637fa..30a409908 100644 --- a/pixman/pixman/pixman-glyph.c +++ b/pixman/pixman/pixman-glyph.c @@ -464,7 +464,7 @@ pixman_composite_glyphs_no_mask (pixman_op_t op, glyph_format = glyph_img->common.extended_format_code; glyph_flags = glyph_img->common.flags; - _pixman_lookup_composite_function ( + _pixman_implementation_lookup_composite ( get_implementation(), op, src->common.extended_format_code, src->common.flags, glyph_format, glyph_flags | extra, @@ -576,7 +576,7 @@ add_glyphs (pixman_glyph_cache_t *cache, white_src = TRUE; } - _pixman_lookup_composite_function ( + _pixman_implementation_lookup_composite ( get_implementation(), PIXMAN_OP_ADD, src_format, info.src_flags, mask_format, info.mask_flags, diff --git a/pixman/pixman/pixman-implementation.c b/pixman/pixman/pixman-implementation.c index 77d0906c8..5dd050199 100644 --- a/pixman/pixman/pixman-implementation.c +++ b/pixman/pixman/pixman-implementation.c @@ -27,92 +27,141 @@ #include <stdlib.h> #include "pixman-private.h" -static pixman_bool_t -delegate_blt (pixman_implementation_t * imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) +pixman_implementation_t * +_pixman_implementation_create (pixman_implementation_t *fallback, + const pixman_fast_path_t *fast_paths) { - return _pixman_implementation_blt ( - imp->delegate, src_bits, dst_bits, src_stride, dst_stride, - src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y, - width, height); -} + pixman_implementation_t *imp; -static pixman_bool_t -delegate_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); -} + assert (fast_paths); -static void -delegate_src_iter_init (pixman_implementation_t *imp, - pixman_iter_t * iter) -{ - imp->delegate->src_iter_init (imp->delegate, iter); + if ((imp = malloc (sizeof (pixman_implementation_t)))) + { + pixman_implementation_t *d; + + memset (imp, 0, sizeof *imp); + + imp->fallback = fallback; + imp->fast_paths = fast_paths; + + /* Make sure the whole fallback chain has the right toplevel */ + for (d = imp; d != NULL; d = d->fallback) + d->toplevel = imp; + } + + return imp; } -static void -delegate_dest_iter_init (pixman_implementation_t *imp, - pixman_iter_t * iter) +#define N_CACHED_FAST_PATHS 8 + +typedef struct { - imp->delegate->dest_iter_init (imp->delegate, iter); -} + struct + { + pixman_implementation_t * imp; + pixman_fast_path_t fast_path; + } cache [N_CACHED_FAST_PATHS]; +} cache_t; -pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *delegate, - const pixman_fast_path_t *fast_paths) +PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); + +pixman_bool_t +_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, + 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 = malloc (sizeof (pixman_implementation_t)); - pixman_implementation_t *d; + pixman_implementation_t *imp; + cache_t *cache; int i; - if (!imp) - return NULL; + /* Check cache for fast paths */ + cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); - assert (fast_paths); + 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; - /* Make sure the whole delegate chain has the right toplevel */ - imp->delegate = delegate; - for (d = imp; d != NULL; d = d->delegate) - d->toplevel = imp; + goto update_cache; + } + } + + for (imp = toplevel; imp != NULL; imp = imp->fallback) + { + 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; - /* Fill out function pointers with ones that just delegate - */ - imp->blt = delegate_blt; - imp->fill = delegate_fill; - imp->src_iter_init = delegate_src_iter_init; - imp->dest_iter_init = delegate_dest_iter_init; + /* 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; - imp->fast_paths = fast_paths; + goto update_cache; + } - for (i = 0; i < PIXMAN_N_OPERATORS; ++i) + ++info; + } + } + return FALSE; + +update_cache: + if (i) { - imp->combine_32[i] = NULL; - imp->combine_64[i] = NULL; - imp->combine_32_ca[i] = NULL; - imp->combine_64_ca[i] = NULL; + 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; } - return imp; + return TRUE; } pixman_combine_32_func_t @@ -121,25 +170,36 @@ _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, pixman_bool_t component_alpha, pixman_bool_t narrow) { - pixman_combine_32_func_t f; - - do + while (imp) { - pixman_combine_32_func_t (*combiners[]) = + pixman_combine_32_func_t f = NULL; + + switch ((narrow << 1) | component_alpha) { - (pixman_combine_32_func_t *)imp->combine_64, - (pixman_combine_32_func_t *)imp->combine_64_ca, - imp->combine_32, - imp->combine_32_ca, - }; + case 0: /* not narrow, not component alpha */ + f = (pixman_combine_32_func_t)imp->combine_64[op]; + break; + + case 1: /* not narrow, component_alpha */ + f = (pixman_combine_32_func_t)imp->combine_64_ca[op]; + break; + + case 2: /* narrow, not component alpha */ + f = imp->combine_32[op]; + break; + + case 3: /* narrow, component_alpha */ + f = imp->combine_32_ca[op]; + break; + } - f = combiners[component_alpha | (narrow << 1)][op]; + if (f) + return f; - imp = imp->delegate; + imp = imp->fallback; } - while (!f); - return f; + return NULL; } pixman_bool_t @@ -157,9 +217,20 @@ _pixman_implementation_blt (pixman_implementation_t * imp, int width, int height) { - return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride, - src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y, - width, height); + while (imp) + { + if (imp->blt && + (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride, + src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y, + width, height)) + { + return TRUE; + } + + imp = imp->fallback; + } + + return FALSE; } pixman_bool_t @@ -173,10 +244,21 @@ _pixman_implementation_fill (pixman_implementation_t *imp, int height, uint32_t xor) { - return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor); + while (imp) + { + if (imp->fill && + ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor))) + { + return TRUE; + } + + imp = imp->fallback; + } + + return FALSE; } -void +pixman_bool_t _pixman_implementation_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, pixman_image_t *image, @@ -197,10 +279,18 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp, iter->iter_flags = iter_flags; iter->image_flags = image_flags; - (*imp->src_iter_init) (imp, iter); + while (imp) + { + if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter)) + return TRUE; + + imp = imp->fallback; + } + + return FALSE; } -void +pixman_bool_t _pixman_implementation_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, pixman_image_t *image, @@ -221,7 +311,15 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t *imp, iter->iter_flags = iter_flags; iter->image_flags = image_flags; - (*imp->dest_iter_init) (imp, iter); + while (imp) + { + if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter)) + return TRUE; + + imp = imp->fallback; + } + + return FALSE; } pixman_bool_t diff --git a/pixman/pixman/pixman-mips-dspr2.c b/pixman/pixman/pixman-mips-dspr2.c index 63a0225a2..1a9e6103a 100644 --- a/pixman/pixman/pixman-mips-dspr2.c +++ b/pixman/pixman/pixman-mips-dspr2.c @@ -85,14 +85,15 @@ PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, ADD, uint32_t, uint32_t) static pixman_bool_t -pixman_fill_mips (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor) +mips_dspr2_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t _xor) { uint8_t *byte_line; uint32_t byte_width; @@ -130,18 +131,19 @@ pixman_fill_mips (uint32_t *bits, } static pixman_bool_t -pixman_blt_mips (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) +mips_dspr2_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) { if (src_bpp != dst_bpp) return FALSE; @@ -266,53 +268,6 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] = { PIXMAN_OP_NONE }, }; -static pixman_bool_t -mips_dspr2_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (!pixman_blt_mips ( - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height)) - - { - return _pixman_implementation_blt ( - imp->delegate, - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height); - } - - return TRUE; -} - -static pixman_bool_t -mips_dspr2_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - if (pixman_fill_mips (bits, stride, bpp, x, y, width, height, xor)) - return TRUE; - - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); -} - pixman_implementation_t * _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback) { diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c index cde5026a3..de57db930 100644 --- a/pixman/pixman/pixman-mmx.c +++ b/pixman/pixman/pixman-mmx.c @@ -2079,15 +2079,16 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp, _mm_empty (); } -pixman_bool_t -pixman_fill_mmx (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) +static pixman_bool_t +mmx_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) { uint64_t fill; __m64 vfill; @@ -2305,9 +2306,9 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp, srca = src >> 24; if (src == 0) { - pixman_fill_mmx (dest_image->bits.bits, dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (dest_image->bits.format), - dest_x, dest_y, width, height, 0); + mmx_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride, + PIXMAN_FORMAT_BPP (dest_image->bits.format), + dest_x, dest_y, width, height, 0); return; } @@ -3264,18 +3265,19 @@ mmx_composite_add_8888_8888 (pixman_implementation_t *imp, } static pixman_bool_t -pixman_blt_mmx (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) +mmx_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) { uint8_t * src_bytes; uint8_t * dst_bytes; @@ -3420,13 +3422,13 @@ mmx_composite_copy_area (pixman_implementation_t *imp, { PIXMAN_COMPOSITE_ARGS (info); - pixman_blt_mmx (src_image->bits.bits, - dest_image->bits.bits, - src_image->bits.rowstride, - dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (src_image->bits.format), - PIXMAN_FORMAT_BPP (dest_image->bits.format), - src_x, src_y, dest_x, dest_y, width, height); + mmx_blt (imp, src_image->bits.bits, + dest_image->bits.bits, + src_image->bits.rowstride, + dest_image->bits.rowstride, + PIXMAN_FORMAT_BPP (src_image->bits.format), + PIXMAN_FORMAT_BPP (dest_image->bits.format), + src_x, src_y, dest_x, dest_y, width, height); } static void @@ -3940,7 +3942,7 @@ static const fetcher_info_t fetchers[] = { PIXMAN_null } }; -static void +static pixman_bool_t mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; @@ -3965,12 +3967,12 @@ mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) iter->stride = s; iter->get_scanline = f->get_scanline; - return; + return TRUE; } } } - imp->delegate->src_iter_init (imp->delegate, iter); + return FALSE; } static const pixman_fast_path_t mmx_fast_paths[] = @@ -4069,55 +4071,6 @@ static const pixman_fast_path_t mmx_fast_paths[] = { PIXMAN_OP_NONE }, }; -static pixman_bool_t -mmx_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (!pixman_blt_mmx ( - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height)) - - { - return _pixman_implementation_blt ( - imp->delegate, - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height); - } - - return TRUE; -} - -static pixman_bool_t -mmx_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - if (!pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor)) - { - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); - } - - return TRUE; -} - pixman_implementation_t * _pixman_implementation_create_mmx (pixman_implementation_t *fallback) { diff --git a/pixman/pixman/pixman-noop.c b/pixman/pixman/pixman-noop.c index 7b017e8ec..7b9759ffb 100644 --- a/pixman/pixman/pixman-noop.c +++ b/pixman/pixman/pixman-noop.c @@ -59,7 +59,7 @@ get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) return NULL; } -static void +static pixman_bool_t noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; @@ -117,11 +117,13 @@ noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) } else { - (* imp->delegate->src_iter_init) (imp->delegate, iter); + return FALSE; } + + return TRUE; } -static void +static pixman_bool_t noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; @@ -138,10 +140,12 @@ noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) iter->get_scanline = _pixman_iter_get_scanline_noop; iter->write_back = dest_write_back_direct; + + return TRUE; } else { - (* imp->delegate->dest_iter_init) (imp->delegate, iter); + return FALSE; } } @@ -156,7 +160,7 @@ _pixman_implementation_create_noop (pixman_implementation_t *fallback) { pixman_implementation_t *imp = _pixman_implementation_create (fallback, noop_fast_paths); - + imp->src_iter_init = noop_src_iter_init; imp->dest_iter_init = noop_dest_iter_init; diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index dbfa82952..b9c8319df 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -445,8 +445,8 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp, int width, int height, uint32_t xor); -typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp, - pixman_iter_t *iter); +typedef pixman_bool_t (*pixman_iter_init_func_t) (pixman_implementation_t *imp, + pixman_iter_t *iter); void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); @@ -466,7 +466,7 @@ typedef struct struct pixman_implementation_t { pixman_implementation_t * toplevel; - pixman_implementation_t * delegate; + pixman_implementation_t * fallback; const pixman_fast_path_t * fast_paths; pixman_blt_func_t blt; @@ -486,9 +486,21 @@ _pixman_image_get_solid (pixman_implementation_t *imp, pixman_format_code_t format); pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *delegate, +_pixman_implementation_create (pixman_implementation_t *fallback, const pixman_fast_path_t *fast_paths); +pixman_bool_t +_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, + 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_combine_32_func_t _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, @@ -521,7 +533,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp, int height, uint32_t xor); -void +pixman_bool_t _pixman_implementation_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, pixman_image_t *image, @@ -533,7 +545,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp, iter_flags_t flags, uint32_t image_flags); -void +pixman_bool_t _pixman_implementation_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, pixman_image_t *image, @@ -770,18 +782,6 @@ pixman_contract (uint32_t * dst, const uint64_t *src, int width); -pixman_bool_t -_pixman_lookup_composite_function (pixman_implementation_t *toplevel, - 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); - /* Region Helpers */ pixman_bool_t pixman_region32_copy_from_region16 (pixman_region32_t *dst, diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c index ba067bc31..d9d96d672 100644 --- a/pixman/pixman/pixman-sse2.c +++ b/pixman/pixman/pixman-sse2.c @@ -3309,18 +3309,22 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp, } +#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) +__attribute__((__force_align_arg_pointer__)) +#endif static pixman_bool_t -pixman_fill_sse2 (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t data) +sse2_fill (pixman_implementation_t *imp, + uint32_t * bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) { uint32_t byte_width; - uint8_t *byte_line; + uint8_t *byte_line; __m128i xmm_def; @@ -3334,9 +3338,9 @@ pixman_fill_sse2 (uint32_t *bits, byte_width = width; stride *= 1; - b = data & 0xff; + b = xor & 0xff; w = (b << 8) | b; - data = (w << 16) | w; + xor = (w << 16) | w; } else if (bpp == 16) { @@ -3345,7 +3349,7 @@ pixman_fill_sse2 (uint32_t *bits, byte_width = 2 * width; stride *= 2; - data = (data & 0xffff) * 0x00010001; + xor = (xor & 0xffff) * 0x00010001; } else if (bpp == 32) { @@ -3359,7 +3363,7 @@ pixman_fill_sse2 (uint32_t *bits, return FALSE; } - xmm_def = create_mask_2x32_128 (data, data); + xmm_def = create_mask_2x32_128 (xor, xor); while (height--) { @@ -3370,21 +3374,21 @@ pixman_fill_sse2 (uint32_t *bits, if (w >= 1 && ((unsigned long)d & 1)) { - *(uint8_t *)d = data&0xff; + *(uint8_t *)d = xor&0xff; w -= 1; d += 1; } while (w >= 2 && ((unsigned long)d & 3)) { - *(uint16_t *)d = data&0xffff; + *(uint16_t *)d = xor&0xffff; w -= 2; d += 2; } while (w >= 4 && ((unsigned long)d & 15)) { - *(uint32_t *)d = data; + *(uint32_t *)d = xor; w -= 4; d += 4; @@ -3435,7 +3439,7 @@ pixman_fill_sse2 (uint32_t *bits, while (w >= 4) { - *(uint32_t *)d = data; + *(uint32_t *)d = xor; w -= 4; d += 4; @@ -3443,14 +3447,14 @@ pixman_fill_sse2 (uint32_t *bits, if (w >= 2) { - *(uint16_t *)d = data&0xffff; + *(uint16_t *)d = xor&0xffff; w -= 2; d += 2; } if (w >= 1) { - *(uint8_t *)d = data&0xff; + *(uint8_t *)d = xor&0xff; w -= 1; d += 1; } @@ -3479,9 +3483,9 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp, srca = src >> 24; if (src == 0) { - pixman_fill_sse2 (dest_image->bits.bits, dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (dest_image->bits.format), - dest_x, dest_y, width, height, 0); + sse2_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride, + PIXMAN_FORMAT_BPP (dest_image->bits.format), + dest_x, dest_y, width, height, 0); return; } @@ -4523,18 +4527,19 @@ sse2_composite_add_8888_8888 (pixman_implementation_t *imp, } static pixman_bool_t -pixman_blt_sse2 (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) +sse2_blt (pixman_implementation_t *imp, + uint32_t * src_bits, + uint32_t * dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) { uint8_t * src_bytes; uint8_t * dst_bytes; @@ -4640,7 +4645,6 @@ pixman_blt_sse2 (uint32_t *src_bits, } } - return TRUE; } @@ -4649,13 +4653,13 @@ sse2_composite_copy_area (pixman_implementation_t *imp, pixman_composite_info_t *info) { PIXMAN_COMPOSITE_ARGS (info); - pixman_blt_sse2 (src_image->bits.bits, - dest_image->bits.bits, - src_image->bits.rowstride, - dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (src_image->bits.format), - PIXMAN_FORMAT_BPP (dest_image->bits.format), - src_x, src_y, dest_x, dest_y, width, height); + sse2_blt (imp, src_image->bits.bits, + dest_image->bits.bits, + src_image->bits.rowstride, + dest_image->bits.rowstride, + PIXMAN_FORMAT_BPP (src_image->bits.format), + PIXMAN_FORMAT_BPP (dest_image->bits.format), + src_x, src_y, dest_x, dest_y, width, height); } static void @@ -5878,58 +5882,6 @@ static const pixman_fast_path_t sse2_fast_paths[] = { PIXMAN_OP_NONE }, }; -static pixman_bool_t -sse2_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (!pixman_blt_sse2 ( - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height)) - - { - return _pixman_implementation_blt ( - imp->delegate, - src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp, - src_x, src_y, dest_x, dest_y, width, height); - } - - return TRUE; -} - -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -static pixman_bool_t -sse2_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) -{ - if (!pixman_fill_sse2 (bits, stride, bpp, x, y, width, height, xor)) - { - return _pixman_implementation_fill ( - imp->delegate, bits, stride, bpp, x, y, width, height, xor); - } - - return TRUE; -} - static uint32_t * sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) { @@ -6072,7 +6024,7 @@ static const fetcher_info_t fetchers[] = { PIXMAN_null } }; -static void +static pixman_bool_t sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; @@ -6097,12 +6049,12 @@ sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) iter->stride = s; iter->get_scanline = f->get_scanline; - return; + return TRUE; } } } - imp->delegate->src_iter_init (imp->delegate, iter); + return FALSE; } #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) diff --git a/pixman/pixman/pixman-utils.c b/pixman/pixman/pixman-utils.c index 93c061ad2..5633f8f79 100644 --- a/pixman/pixman/pixman-utils.c +++ b/pixman/pixman/pixman-utils.c @@ -30,118 +30,6 @@ #include "pixman-private.h" -#define N_CACHED_FAST_PATHS 8 - -typedef struct -{ - 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); - -pixman_bool_t -_pixman_lookup_composite_function (pixman_implementation_t *toplevel, - 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 = toplevel; 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 FALSE; - -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; - } - - return TRUE; -} - pixman_bool_t _pixman_multiply_overflows_size (size_t a, size_t b) { diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c index 994ef388c..739cc7994 100644 --- a/pixman/pixman/pixman.c +++ b/pixman/pixman/pixman.c @@ -669,7 +669,7 @@ pixman_image_composite32 (pixman_op_t op, */ op = optimize_operator (op, src_flags, mask_flags, dest_flags); - if (_pixman_lookup_composite_function ( + if (_pixman_implementation_lookup_composite ( get_implementation (), op, src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags, &imp, &func)) diff --git a/pixman/test/scaling-test.c b/pixman/test/scaling-test.c index 44c4f3de4..273612395 100644 --- a/pixman/test/scaling-test.c +++ b/pixman/test/scaling-test.c @@ -20,6 +20,31 @@ /* * Composite operation with pseudorandom images */ + +static pixman_format_code_t +get_format (int bpp) +{ + if (bpp == 4) + { + switch (lcg_rand_n (4)) + { + default: + case 0: + return PIXMAN_a8r8g8b8; + case 1: + return PIXMAN_x8r8g8b8; + case 2: + return PIXMAN_a8b8g8r8; + case 3: + return PIXMAN_x8b8g8r8; + } + } + else + { + return PIXMAN_r5g6b5; + } +} + uint32_t test_composite (int testnum, int verbose) @@ -124,11 +149,8 @@ test_composite (int testnum, for (i = 0; i < dst_stride * dst_height; i++) *((uint8_t *)dstbuf + i) = lcg_rand_n (256); - src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ? - PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; - - dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ? - PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; + src_fmt = get_format (src_bpp); + dst_fmt = get_format (dst_bpp); src_img = pixman_image_create_bits ( src_fmt, src_width, src_height, srcbuf, src_stride); @@ -322,7 +344,7 @@ test_composite (int testnum, pixman_image_composite (op, src_img, mask_img, dst_img, src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); - if (dst_fmt == PIXMAN_x8r8g8b8) + if (dst_fmt == PIXMAN_x8r8g8b8 || dst_fmt == PIXMAN_x8b8g8r8) { /* ignore unused part */ for (i = 0; i < dst_stride * dst_height / 4; i++) @@ -358,11 +380,11 @@ test_composite (int testnum, } #if BILINEAR_INTERPOLATION_BITS == 8 -#define CHECKSUM 0x80DF1CB2 +#define CHECKSUM 0x8D3A7539 #elif BILINEAR_INTERPOLATION_BITS == 7 -#define CHECKSUM 0x2818D5FB +#define CHECKSUM 0x03A23E0C #elif BILINEAR_INTERPOLATION_BITS == 4 -#define CHECKSUM 0x387540A5 +#define CHECKSUM 0xE96D1A5E #else #define CHECKSUM 0x00000000 #endif |