diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-09-13 05:29:48 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2010-02-14 11:10:15 -0500 |
commit | 87430cfc35c6e51bb1a947795e0ddb198c460253 (patch) | |
tree | bf50a2ae6cc6c6802ba5d887cc2edfbf668550dd | |
parent | d7e281e0a1f7b1aecd245070736e03d2953b0911 (diff) |
Make general_composite_rect() just another fast path.
We introduce a new PIXMAN_OP_any fake operator and a PIXMAN_any fake
format that match anything. Then general_composite_rect() can be used
as another fast path.
Because general_composite_rect() does not require the sources to cover
the clip region, we add a new flag FAST_PATH_COVERS_CLIP which is part
of the set of standard flags for fast paths.
Because this flag cannot be computed until after the clip region is
available, we have to call pixman_compute_composite_region32() before
checking for fast paths. This will resolve itself when we get to the
point where _pixman_run_fast_path() is only called once per composite
operation.
-rw-r--r-- | pixman/pixman-general.c | 25 | ||||
-rw-r--r-- | pixman/pixman-private.h | 8 | ||||
-rw-r--r-- | pixman/pixman-utils.c | 107 |
3 files changed, 85 insertions, 55 deletions
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index c96a3f97..83500b99 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -264,6 +264,17 @@ general_composite_rect (pixman_implementation_t *imp, free (scanline_buffer); } +static const pixman_fast_path_t general_fast_path[] = +{ + { PIXMAN_OP_any, + PIXMAN_any, 0, + PIXMAN_any, 0, + PIXMAN_any, 0, + general_composite_rect, + }, + { PIXMAN_OP_NONE } +}; + static void general_composite (pixman_implementation_t * imp, pixman_op_t op, @@ -279,10 +290,16 @@ general_composite (pixman_implementation_t * imp, int32_t width, int32_t height) { - _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y, - mask_x, mask_y, dest_x, dest_y, - width, height, - general_composite_rect); + pixman_bool_t result; + + result = _pixman_run_fast_path (general_fast_path, imp, + op, src, mask, dest, + src_x, src_y, + mask_x, mask_y, + dest_x, dest_y, + width, height); + + assert (result); } static pixman_bool_t diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index c99b1017..0ed3662e 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -564,6 +564,9 @@ _pixman_choose_implementation (void); #define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0) #define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0) #define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0) +#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0) + +#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1) #define FAST_PATH_ID_TRANSFORM (1 << 0) #define FAST_PATH_NO_ALPHA_MAP (1 << 1) @@ -572,7 +575,7 @@ _pixman_choose_implementation (void); #define FAST_PATH_NO_REFLECT_REPEAT (1 << 4) #define FAST_PATH_NO_ACCESSORS (1 << 5) #define FAST_PATH_NO_WIDE_FORMAT (1 << 6) -#define FAST_PATH_reserved (1 << 7) +#define FAST_PATH_COVERS_CLIP (1 << 7) #define FAST_PATH_COMPONENT_ALPHA (1 << 8) #define FAST_PATH_UNIFIED_ALPHA (1 << 9) @@ -583,7 +586,8 @@ _pixman_choose_implementation (void); FAST_PATH_NO_PAD_REPEAT | \ FAST_PATH_NO_REFLECT_REPEAT | \ FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NO_WIDE_FORMAT) + FAST_PATH_NO_WIDE_FORMAT | \ + FAST_PATH_COVERS_CLIP) #define FAST_PATH_STD_SRC_FLAGS \ _FAST_PATH_STANDARD_FLAGS diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 5441b6b8..66bdb303 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -614,7 +614,9 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths, pixman_composite_func_t func; const pixman_fast_path_t *info; pixman_bool_t result; - + pixman_region32_t region; + pixman_box32_t *extents; + get_image_info (src, &src_format, &src_flags); get_image_info (mask, &mask_format, &mask_flags); get_image_info (dest, &dest_format, &dest_flags); @@ -631,15 +633,40 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths, src_format = mask_format = PIXMAN_rpixbuf; } + pixman_region32_init (®ion); + + if (!pixman_compute_composite_region32 ( + ®ion, src, mask, dest, + src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) + { + return TRUE; + } + + result = FALSE; + + extents = pixman_region32_extents (®ion); + + if (image_covers (src, extents, dest_x - src_x, dest_y - src_y)) + src_flags |= FAST_PATH_COVERS_CLIP; + + if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y)) + mask_flags |= FAST_PATH_COVERS_CLIP; + func = NULL; for (info = paths; info->op != PIXMAN_OP_NONE; ++info) { - if (info->op == op && - (info->src_format == src_format) && + if ((info->op == op || info->op == PIXMAN_OP_any) && + /* src */ + ((info->src_format == src_format) || + (info->src_format == PIXMAN_any)) && (info->src_flags & src_flags) == info->src_flags && - (info->mask_format == mask_format) && + /* mask */ + ((info->mask_format == mask_format) || + (info->mask_format == PIXMAN_any)) && (info->mask_flags & mask_flags) == info->mask_flags && - (info->dest_format == dest_format) && + /* dest */ + ((info->dest_format == dest_format) || + (info->dest_format == PIXMAN_any)) && (info->dest_flags & dest_flags) == info->dest_flags) { func = info->func; @@ -647,54 +674,36 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths, } } - result = FALSE; - if (func) { - pixman_region32_t region; - pixman_region32_init (®ion); - - if (pixman_compute_composite_region32 ( - ®ion, src, mask, dest, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) - { - pixman_box32_t *extents = pixman_region32_extents (®ion); - - if (sources_cover ( - src, mask, extents, - src_x, src_y, mask_x, mask_y, dest_x, dest_y)) - { - pixman_bool_t src_repeat, mask_repeat; - - src_repeat = - src->type == BITS && - src_flags & FAST_PATH_ID_TRANSFORM && - src->common.repeat == PIXMAN_REPEAT_NORMAL && - src_format != PIXMAN_solid; - - mask_repeat = - mask && - mask->type == BITS && - mask_flags & FAST_PATH_ID_TRANSFORM && - mask->common.repeat == PIXMAN_REPEAT_NORMAL && - mask_format != PIXMAN_solid; - - walk_region_internal (imp, op, - src, mask, dest, - src_x, src_y, mask_x, mask_y, - dest_x, dest_y, - width, height, - src_repeat, mask_repeat, - ®ion, - func); - - result = TRUE; - } - - pixman_region32_fini (®ion); - } + pixman_bool_t src_repeat, mask_repeat; + + src_repeat = + src->type == BITS && + src_flags & FAST_PATH_ID_TRANSFORM && + src->common.repeat == PIXMAN_REPEAT_NORMAL && + src_format != PIXMAN_solid; + + mask_repeat = + mask && + mask->type == BITS && + mask_flags & FAST_PATH_ID_TRANSFORM && + mask->common.repeat == PIXMAN_REPEAT_NORMAL && + mask_format != PIXMAN_solid; + + walk_region_internal (imp, op, + src, mask, dest, + src_x, src_y, mask_x, mask_y, + dest_x, dest_y, + width, height, + src_repeat, mask_repeat, + ®ion, + func); + + result = TRUE; } + pixman_region32_fini (®ion); return result; } |