diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-07-31 05:19:36 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-11-09 17:07:32 -0500 |
commit | 768cfee64f8a7d05375b09090e854a3e88652cfe (patch) | |
tree | e0f929b8c38730610aadba9d6d7b43881ff0aacc | |
parent | b8898d77d0e7cc1c50321fcb216af3ba6c634959 (diff) |
Add some transformed fast paths generated by a preprocessor macro.macro-fast-path
-rw-r--r-- | pixman/pixman-bits-image.c | 143 |
1 files changed, 127 insertions, 16 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index 5a5a6905..1738d032 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -167,6 +167,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord) static force_inline uint32_t bits_image_fetch_pixel_nearest (bits_image_t *image, + pixman_format_code_t format, + pixman_repeat_t repeat_mode, pixman_fixed_t x, pixman_fixed_t y) { @@ -278,11 +280,12 @@ bilinear_interpolation (uint32_t tl, uint32_t tr, #endif static force_inline uint32_t -bits_image_fetch_pixel_bilinear (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y) +bits_image_fetch_pixel_bilinear (bits_image_t *image, + pixman_format_code_t format, + pixman_repeat_t repeat_mode, + pixman_fixed_t x, + pixman_fixed_t y) { - pixman_repeat_t repeat_mode = image->common.repeat; int width = image->width; int height = image->height; int x1, y1, x2, y2; @@ -535,9 +538,11 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, } static force_inline uint32_t -bits_image_fetch_pixel_convolution (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y) +bits_image_fetch_pixel_convolution (bits_image_t *image, + pixman_format_code_t format, + pixman_repeat_t repeat_mode, + pixman_fixed_t x, + pixman_fixed_t y) { pixman_fixed_t *params = image->common.filter_params; int x_off = (params[0] - pixman_fixed_1) >> 1; @@ -546,7 +551,6 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, int32_t cheight = pixman_fixed_to_int (params[1]); int32_t srtot, sgtot, sbtot, satot; int32_t i, j, x1, x2, y1, y2; - pixman_repeat_t repeat_mode = image->common.repeat; int width = image->width; int height = image->height; @@ -609,24 +613,27 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, static force_inline uint32_t bits_image_fetch_pixel_filtered (bits_image_t *image, + pixman_format_code_t format, + pixman_filter_t filter, + pixman_repeat_t repeat_mode, pixman_fixed_t x, pixman_fixed_t y) { - switch (image->common.filter) + switch (filter) { case PIXMAN_FILTER_NEAREST: case PIXMAN_FILTER_FAST: - return bits_image_fetch_pixel_nearest (image, x, y); + return bits_image_fetch_pixel_nearest (image, format, repeat_mode, x, y); break; case PIXMAN_FILTER_BILINEAR: case PIXMAN_FILTER_GOOD: case PIXMAN_FILTER_BEST: - return bits_image_fetch_pixel_bilinear (image, x, y); + return bits_image_fetch_pixel_bilinear (image, format, repeat_mode, x, y); break; case PIXMAN_FILTER_CONVOLUTION: - return bits_image_fetch_pixel_convolution (image, x, y); + return bits_image_fetch_pixel_convolution (image, format, repeat_mode, x, y); break; default: @@ -683,8 +690,12 @@ bits_image_fetch_transformed (pixman_image_t * image, { if (!mask || (mask[i] & mask_bits)) { - buffer[i] = - bits_image_fetch_pixel_filtered (&image->bits, x, y); + buffer[i] = bits_image_fetch_pixel_filtered ( + &image->bits, + image->bits.format, + image->common.filter, + image->common.repeat, + x, y); } x += ux; @@ -702,8 +713,12 @@ bits_image_fetch_transformed (pixman_image_t * image, x0 = ((pixman_fixed_48_16_t)x << 16) / w; y0 = ((pixman_fixed_48_16_t)y << 16) / w; - buffer[i] = - bits_image_fetch_pixel_filtered (&image->bits, x0, y0); + buffer[i] = bits_image_fetch_pixel_filtered ( + &image->bits, + image->bits.format, + image->common.filter, + image->common.repeat, + x0, y0); } x += ux; @@ -713,6 +728,82 @@ bits_image_fetch_transformed (pixman_image_t * image, } } +#define MAKE_FAST_PATH(name, format, filter, repeat) \ + static void \ + bits_image_fetch_ ## name (pixman_image_t * image, \ + int offset, \ + int line, \ + int width, \ + uint32_t * buffer, \ + const uint32_t * mask, \ + uint32_t mask_bits) \ + { \ + pixman_fixed_t x, y, w; \ + pixman_fixed_t ux, uy, uw; \ + pixman_vector_t v; \ + int i; \ + \ + /* reference point is the center of the pixel */ \ + v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; \ + v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; \ + v.vector[2] = pixman_fixed_1; \ + \ + /* when using convolution filters or PIXMAN_REPEAT_PAD one \ + * might get here without a transform */ \ + if (image->common.transform) \ + { \ + if (!pixman_transform_point_3d (image->common.transform, &v)) \ + return; \ + \ + ux = image->common.transform->matrix[0][0]; \ + uy = image->common.transform->matrix[1][0]; \ + uw = image->common.transform->matrix[2][0]; \ + } \ + else \ + { \ + ux = pixman_fixed_1; \ + uy = 0; \ + uw = 0; \ + } \ + \ + x = v.vector[0]; \ + y = v.vector[1]; \ + w = v.vector[2]; \ + \ + for (i = 0; i < width; ++i) \ + { \ + if (!mask || (mask[i] & mask_bits)) \ + { \ + buffer[i] = \ + bits_image_fetch_pixel_filtered ( \ + &image->bits, format, filter, repeat, x, y); \ + } \ + \ + x += ux; \ + y += uy; \ + } \ + } + +MAKE_FAST_PATH ( + a8r8g8b8_bilinear_pad, + PIXMAN_a8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_PAD); + +MAKE_FAST_PATH ( + a8r8g8b8_nearest_pad, + PIXMAN_a8r8g8b8, PIXMAN_FILTER_NEAREST, PIXMAN_REPEAT_PAD); + +MAKE_FAST_PATH ( + x8r8g8b8_bilinear_pad, + PIXMAN_x8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_PAD); + +MAKE_FAST_PATH ( + x8r8g8b8_nearest_pad, + PIXMAN_x8r8g8b8, PIXMAN_FILTER_NEAREST, PIXMAN_REPEAT_PAD); + +MAKE_FAST_PATH ( + x8r8g8b8_bilinear_none, + PIXMAN_x8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_NONE); + static void bits_image_fetch_solid_32 (pixman_image_t * image, int x, @@ -987,6 +1078,26 @@ bits_image_property_changed (pixman_image_t *image) bits->common.need_workaround = source_image_needs_out_of_bounds_workaround (bits); + + + if (bits->format == PIXMAN_a8r8g8b8 && + bits->common.filter == PIXMAN_FILTER_BILINEAR && + bits->common.repeat == PIXMAN_REPEAT_PAD && + !bits->read_func && + !bits->write_func && + !bits->common.alpha_map) + { + bits->common.get_scanline_32 = bits_image_fetch_a8r8g8b8_bilinear_pad; + } + else if (bits->format == PIXMAN_x8r8g8b8 && + (bits->common.filter == PIXMAN_FILTER_BILINEAR || + bits->common.filter == PIXMAN_FILTER_GOOD) && + !bits->read_func && + !bits->write_func && + !bits->common.alpha_map) + { + bits->common.get_scanline_32 = bits_image_fetch_x8r8g8b8_bilinear_none; + } } static uint32_t * |