From c7b0da8a96c9196f751dab2af42adb5560ba6557 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Tue, 21 May 2013 08:14:44 -0400 Subject: [PATCH] noop: Keep information about iterators in an array of pixman_iter_info_t Instead of having a nest of if statements, store the information about iterators in a table of a new struct type, pixman_iter_info_t, and then walk that table when initializing iterators. The new struct contains a format, a set of image flags, and a set of iter flags, plus a pixman_iter_get_scanline_t, a pixman_iter_write_back_t, and a new function type pixman_iter_initializer_t. If the iterator matches an entry, it is first initialized with the given get_scanline and write_back functions, and then the provided iter_initializer (if present) is run. Running the iter_initializer after setting get_scanline and write_back allows the initializer to override those fields if it wishes. The table contains both source and destination iterators, distinguished based on the recently-added ITER_SRC and ITER_DEST; similarly, wide iterators are recognized with the ITER_WIDE flag. Having both source and destination iterators in the table means the noop_src_iter_init() and noop_dest_iter_init() functions become identical, so this patch factors out their code in a new function noop_iter_init_common() that both calls. The following patches in this series will change all the implementations to use an iterator table, and then move the table search code to pixman-implementation.c. --- pixman/pixman-noop.c | 185 +++++++++++++++++++++++++++++------------------- pixman/pixman-private.h | 13 ++++ 2 files changed, 124 insertions(+), 74 deletions(-) diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c index 6afd4b9..d01665e 100644 --- a/pixman/pixman-noop.c +++ b/pixman/pixman-noop.c @@ -59,99 +59,136 @@ get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) return NULL; } -static pixman_bool_t -noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) +static void +noop_init_solid_narrow (pixman_iter_t *iter, + const pixman_iter_info_t *info) +{ + pixman_image_t *image = iter->image; + uint32_t *buffer = iter->buffer; + uint32_t *end = buffer + iter->width; + uint32_t color; + + if (iter->image->type == SOLID) + color = image->solid.color_32; + else + color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); + + while (buffer < end) + *(buffer++) = color; +} + +static void +noop_init_solid_wide (pixman_iter_t *iter, + const pixman_iter_info_t *info) { pixman_image_t *image = iter->image; + argb_t *buffer = (argb_t *)iter->buffer; + argb_t *end = buffer + iter->width; + argb_t color; -#define FLAGS \ - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) + if (iter->image->type == SOLID) + color = image->solid.color_float; + else + color = image->bits.fetch_pixel_float (&image->bits, 0, 0); - if (!image) + while (buffer < end) + *(buffer++) = color; +} + +static void +noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info) +{ + pixman_image_t *image = iter->image; + + iter->buffer = + image->bits.bits + iter->y * image->bits.rowstride + iter->x; +} + +static const pixman_iter_info_t noop_iters[] = +{ + /* Source iters */ + { PIXMAN_any, + 0, ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_SRC, + NULL, + _pixman_iter_get_scanline_noop, + NULL + }, + { PIXMAN_solid, + FAST_PATH_NO_ALPHA_MAP, ITER_NARROW | ITER_SRC, + noop_init_solid_narrow, + _pixman_iter_get_scanline_noop, + NULL, + }, + { PIXMAN_solid, + FAST_PATH_NO_ALPHA_MAP, ITER_WIDE | ITER_SRC, + noop_init_solid_wide, + _pixman_iter_get_scanline_noop, + NULL + }, + { PIXMAN_a8r8g8b8, + FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | + FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, + ITER_NARROW | ITER_SRC, + noop_init_direct_buffer, + noop_get_scanline, + NULL + }, + /* Dest iters */ + { PIXMAN_a8r8g8b8, + FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST, + noop_init_direct_buffer, + _pixman_iter_get_scanline_noop, + dest_write_back_direct + }, + { PIXMAN_x8r8g8b8, + FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST | ITER_LOCALIZED_ALPHA, + noop_init_direct_buffer, + _pixman_iter_get_scanline_noop, + dest_write_back_direct + }, + { PIXMAN_null }, +}; + +static pixman_bool_t +noop_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter) +{ + const pixman_iter_info_t *info; + + if (!iter->image) { iter->get_scanline = get_scanline_null; + return TRUE; } - else if ((iter->iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == - (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) - { - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else if (image->common.extended_format_code == PIXMAN_solid && - (iter->image_flags & FAST_PATH_NO_ALPHA_MAP)) - { - if (iter->iter_flags & ITER_NARROW) - { - uint32_t *buffer = iter->buffer; - uint32_t *end = buffer + iter->width; - uint32_t color; - - if (image->type == SOLID) - color = image->solid.color_32; - else - color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); - while (buffer < end) - *(buffer++) = color; - } - else + for (info = noop_iters; info->format != PIXMAN_null; ++info) + { + if ((info->format == PIXMAN_any || + info->format == iter->image->common.extended_format_code) && + (info->image_flags & iter->image_flags) == info->image_flags && + (info->iter_flags & iter->iter_flags) == info->iter_flags) { - argb_t *buffer = (argb_t *)iter->buffer; - argb_t *end = buffer + iter->width; - argb_t color; - - if (image->type == SOLID) - color = image->solid.color_float; - else - color = image->bits.fetch_pixel_float (&image->bits, 0, 0); + iter->get_scanline = info->get_scanline; + iter->write_back = info->write_back; - while (buffer < end) - *(buffer++) = color; + if (info->initializer) + info->initializer (iter, info); + return TRUE; } - - iter->get_scanline = _pixman_iter_get_scanline_noop; } - else if (image->common.extended_format_code == PIXMAN_a8r8g8b8 && - (iter->iter_flags & ITER_NARROW) && - (iter->image_flags & FLAGS) == FLAGS) - { - iter->buffer = - image->bits.bits + iter->y * image->bits.rowstride + iter->x; - iter->get_scanline = noop_get_scanline; - } - else - { - return FALSE; - } + return FALSE; +} - return TRUE; +static pixman_bool_t +noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) +{ + return noop_iter_init_common (imp, iter); } static pixman_bool_t noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { - pixman_image_t *image = iter->image; - uint32_t image_flags = iter->image_flags; - uint32_t iter_flags = iter->iter_flags; - - if ((image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS && - (iter_flags & ITER_NARROW) == ITER_NARROW && - ((image->common.extended_format_code == PIXMAN_a8r8g8b8) || - (image->common.extended_format_code == PIXMAN_x8r8g8b8 && - (iter_flags & (ITER_LOCALIZED_ALPHA))))) - { - iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x; - - iter->get_scanline = _pixman_iter_get_scanline_noop; - iter->write_back = dest_write_back_direct; - - return TRUE; - } - else - { - return FALSE; - } + return noop_iter_init_common (imp, iter); } static const pixman_fast_path_t noop_fast_paths[] = diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 0fe86ca..0365901 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -262,6 +262,19 @@ struct pixman_iter_t int stride; }; +typedef struct pixman_iter_info_t pixman_iter_info_t; +typedef void (* pixman_iter_initializer_t) (pixman_iter_t *iter, + const pixman_iter_info_t *info); +struct pixman_iter_info_t +{ + pixman_format_code_t format; + uint32_t image_flags; + iter_flags_t iter_flags; + pixman_iter_initializer_t initializer; + pixman_iter_get_scanline_t get_scanline; + pixman_iter_write_back_t write_back; +}; + void _pixman_bits_image_setup_accessors (bits_image_t *image); -- 2.7.4