From: Søren Sandmann Pedersen <s...@redhat.com> Instead of calling _pixman_image_get_scanline32/64(), move the iterator initialization to the respective image files and call the scanline generators directly. --- pixman/pixman-conical-gradient.c | 33 ++++++++++++++++++++++++++++ pixman/pixman-general.c | 44 ++++++++++++++++++------------------- pixman/pixman-linear-gradient.c | 43 +++++++++++++++++++++++++++++++++++++ pixman/pixman-private.h | 31 ++++++++++++++++++++++++++ pixman/pixman-radial-gradient.c | 33 ++++++++++++++++++++++++++++ pixman/pixman-solid-fill.c | 20 +++++++++++++++++ pixman/pixman-utils.c | 6 +++++ 7 files changed, 187 insertions(+), 23 deletions(-)
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c index a3685d1..35913cb 100644 --- a/pixman/pixman-conical-gradient.c +++ b/pixman/pixman-conical-gradient.c @@ -163,6 +163,39 @@ conical_gradient_property_changed (pixman_image_t *image) image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } +static uint32_t * +conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + conical_gradient_get_scanline_32 (iter->image, iter->x, iter->y, + iter->width, iter->buffer, + mask); + + iter->y++; + return iter->buffer; +} + +static uint32_t * +conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_conical_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = conical_get_scanline_narrow; + else + iter->get_scanline = conical_get_scanline_wide; +} + PIXMAN_EXPORT pixman_image_t * pixman_image_create_conical_gradient (pixman_point_fixed_t * center, pixman_fixed_t angle, diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index 3b7b59d..4b837fa 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -45,24 +45,6 @@ src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) return NULL; } -static uint32_t * -src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) -{ - _pixman_image_get_scanline_32 ( - iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask); - - return iter->buffer; -} - -static uint32_t * -src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) -{ - _pixman_image_get_scanline_64 ( - iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask); - - return iter->buffer; -} - static void src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter, @@ -80,18 +62,34 @@ src_iter_init (pixman_implementation_t *imp, { iter->get_scanline = src_get_scanline_null; } - else if (image->type == BITS) + else if (image->type == SOLID) { - _pixman_bits_image_src_iter_init ( + _pixman_solid_fill_iter_init ( image, iter, x, y, width, height, buffer, flags); } - else if (flags & ITER_NARROW) + else if (image->type == LINEAR) { - iter->get_scanline = src_get_scanline_narrow; + _pixman_linear_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == RADIAL) + { + _pixman_radial_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == CONICAL) + { + _pixman_conical_gradient_iter_init ( + image, iter, x, y, width, height, buffer, flags); + } + else if (image->type == BITS) + { + _pixman_bits_image_src_iter_init ( + image, iter, x, y, width, height, buffer, flags); } else { - iter->get_scanline = src_get_scanline_wide; + _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); } } diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c index 1547882..2f032a8 100644 --- a/pixman/pixman-linear-gradient.c +++ b/pixman/pixman-linear-gradient.c @@ -226,6 +226,49 @@ linear_gradient_property_changed (pixman_image_t *image) image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } +static uint32_t * +linear_gradient_get_scanline_narrow (pixman_iter_t *iter, + const uint32_t *mask) +{ + pixman_image_t *image = iter->image; + int x = iter->x; + int y = iter->y; + int width = iter->width; + uint32_t * buffer = iter->buffer; + + linear_gradient_get_scanline_32 (image, x, y, width, buffer, mask); + + iter->y++; + + return iter->buffer; +} + +static uint32_t * +linear_gradient_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = linear_gradient_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, + int y, + int width, + int height, + uint8_t *buffer, + iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = linear_gradient_get_scanline_narrow; + else + iter->get_scanline = linear_gradient_get_scanline_wide; +} + PIXMAN_EXPORT pixman_image_t * pixman_image_create_linear_gradient (pixman_point_fixed_t * p1, pixman_point_fixed_t * p2, diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index d9d19ce..5a32c22 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -225,6 +225,35 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image, uint8_t *buffer, iter_flags_t flags); void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_linear_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void +_pixman_conical_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags); + +void _pixman_image_get_scanline_generic_64 (pixman_image_t *image, int x, int y, @@ -537,6 +566,8 @@ _pixman_choose_implementation (void); /* * Utilities */ +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask); /* These "formats" all have depth 0, so they * will never clash with any real ones diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c index b595ba7..d0eb08c 100644 --- a/pixman/pixman-radial-gradient.c +++ b/pixman/pixman-radial-gradient.c @@ -377,6 +377,39 @@ radial_gradient_property_changed (pixman_image_t *image) image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64; } +static uint32_t * +radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + radial_gradient_get_scanline_32 ( + iter->image, iter->x, iter->y, iter->width, + iter->buffer, mask); + + iter->y++; + return iter->buffer; +} + +static uint32_t * +radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) +{ + uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); + + pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); + + return buffer; +} + +void +_pixman_radial_gradient_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + iter->get_scanline = radial_get_scanline_narrow; + else + iter->get_scanline = radial_get_scanline_wide; +} + PIXMAN_EXPORT pixman_image_t * pixman_image_create_radial_gradient (pixman_point_fixed_t * inner, pixman_point_fixed_t * outer, diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c index 1d911e9..0af4df0 100644 --- a/pixman/pixman-solid-fill.c +++ b/pixman/pixman-solid-fill.c @@ -76,6 +76,26 @@ solid_fill_property_changed (pixman_image_t *image) image->common.get_scanline_64 = solid_fill_get_scanline_64; } +void +_pixman_solid_fill_iter_init (pixman_image_t *image, + pixman_iter_t *iter, + int x, int y, int width, int height, + uint8_t *buffer, iter_flags_t flags) +{ + if (flags & ITER_NARROW) + { + solid_fill_get_scanline_32 ( + image, x, y, width, (uint32_t *)buffer, NULL); + } + else + { + solid_fill_get_scanline_64 ( + image, x, y, width, (uint32_t *)buffer, NULL); + } + + iter->get_scanline = _pixman_iter_get_scanline_noop; +} + static uint32_t color_to_uint32 (const pixman_color_t *color) { diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 3ef88b7..cb4e621 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -167,6 +167,12 @@ pixman_contract (uint32_t * dst, } } +uint32_t * +_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask) +{ + return iter->buffer; +} + #define N_TMP_BOXES (16) pixman_bool_t -- 1.6.0.6 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman