From: Søren Sandmann Pedersen <s...@redhat.com> Add two new iterator flags, ITER_IGNORE_ALPHA and ITER_IGNORE_RGB that are set when the alpha and rgb values are not needed. If both are set, then we can skip fetching entirely and just use _pixman_iter_get_scanline_noop. --- pixman/pixman-bits-image.c | 11 +++++- pixman/pixman-general.c | 74 +++++++++++++++++++++++++++------------ pixman/pixman-implementation.c | 7 ++++ pixman/pixman-private.h | 4 ++- 4 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index df8d56e..7d588a9 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -1444,7 +1444,16 @@ _pixman_bits_image_iter_init (pixman_image_t *image, } else { - iter->get_scanline = get_scanline_narrow; + if ((flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == + (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) + { + iter->get_scanline = _pixman_iter_get_scanline_noop; + } + else + { + iter->get_scanline = get_scanline_narrow; + } + iter->next_line = next_line_write_narrow; } } diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 84b52c2..25d1fe4 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -83,6 +83,34 @@ general_iter_init (pixman_implementation_t *imp, } } +typedef struct op_info_t op_info_t; +struct op_info_t +{ + uint8_t src, dst; +}; + +#define ITER_IGNORE_BOTH \ + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA) + +static const op_info_t op_flags[PIXMAN_N_OPERATORS] = +{ + /* Src Dst */ + { ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */ + { ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */ + { 0, ITER_LOCALIZED_ALPHA }, /* OVER */ + { ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */ + { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */ + { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */ + { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */ + { 0, 0 }, /* ATOP */ + { 0, 0 }, /* ATOP_REVERSE */ + { 0, 0 }, /* XOR */ + { ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */ + { 0, 0 }, /* SATURATE */ +}; + #define SCANLINE_BUFFER_LENGTH 8192 static void @@ -106,7 +134,7 @@ general_composite_rect (pixman_implementation_t *imp, pixman_iter_t src_iter, mask_iter, dest_iter; pixman_combine_32_func_t compose; pixman_bool_t component_alpha; - iter_flags_t narrow, dest_flags; + iter_flags_t narrow, src_flags; int Bpp; int i; @@ -135,39 +163,39 @@ general_composite_rect (pixman_implementation_t *imp, mask_buffer = src_buffer + width * Bpp; dest_buffer = mask_buffer + width * Bpp; + /* src iter */ + src_flags = narrow | op_flags[op].src; + _pixman_implementation_iter_init (imp->toplevel, &src_iter, src, src_x, src_y, width, height, - src_buffer, narrow); - - _pixman_implementation_iter_init (imp->toplevel, &mask_iter, mask, - mask_x, mask_y, width, height, - mask_buffer, narrow); - - if (op == PIXMAN_OP_CLEAR || - op == PIXMAN_OP_SRC || - op == PIXMAN_OP_DST || - op == PIXMAN_OP_OVER || - op == PIXMAN_OP_IN_REVERSE || - op == PIXMAN_OP_OUT_REVERSE || - op == PIXMAN_OP_ADD) - { - dest_flags = narrow | ITER_WRITE | ITER_LOCALIZED_ALPHA; - } - else + src_buffer, src_flags); + + /* mask iter */ + if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == + (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) { - dest_flags = narrow | ITER_WRITE; + /* If it doesn't matter what the source is, then it doesn't matter + * what the mask is + */ + mask = NULL; } - _pixman_implementation_iter_init (imp->toplevel, &dest_iter, dest, - dest_x, dest_y, width, height, - dest_buffer, dest_flags); - component_alpha = mask && mask->common.type == BITS && mask->common.component_alpha && PIXMAN_FORMAT_RGB (mask->bits.format); + _pixman_implementation_iter_init ( + imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height, + mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB)); + + /* dest iter */ + _pixman_implementation_iter_init (imp->toplevel, &dest_iter, dest, + dest_x, dest_y, width, height, + dest_buffer, + narrow | ITER_WRITE | op_flags[op].dst); + if (narrow) { if (component_alpha) diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c index 1aa28d1..57134cb 100644 --- a/pixman/pixman-implementation.c +++ b/pixman/pixman-implementation.c @@ -258,11 +258,18 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp, uint8_t *buffer, iter_flags_t flags) { +#define NOOP (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB) + if (!image) { iter->get_scanline = get_scanline_null; iter->next_line = _pixman_iter_next_line_noop; } + else if ((flags & (NOOP | ITER_WRITE)) == NOOP) + { + iter->get_scanline = _pixman_iter_get_scanline_noop; + iter->next_line = _pixman_iter_next_line_noop; + } else { (*imp->iter_init) ( diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 8532b98..2a00dc4 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -201,7 +201,9 @@ typedef enum * we can treat it as ARGB, which means in some cases we can avoid copying * it to a temporary buffer. */ - ITER_LOCALIZED_ALPHA = (1 << 2) + ITER_LOCALIZED_ALPHA = (1 << 2), + ITER_IGNORE_ALPHA = (1 << 3), + ITER_IGNORE_RGB = (1 << 4) } iter_flags_t; struct pixman_iter_t -- 1.6.0.6 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman