[Pixman] [PATCH 18/18] Fix destination fetching.
Andrea Canciani
ranma42 at gmail.com
Fri Jan 7 07:36:09 PST 2011
On Thu, Jan 6, 2011 at 3:28 AM, Søren Sandmann <sandmann at cs.au.dk> wrote:
> From: Søren Sandmann Pedersen <ssp at redhat.com>
>
> When fetching from destinations, we need to ignore transformations,
> repeat and filtering. Currently we don't ignore them, which means all
> kinds of bad things can happen.
>
> This bug fixes this problem by separating the concepts of source and
> destination iterator instead of using the ITER_WRITE flag to indicate
> which is which.
>
> Apart from making it simple for destination iterators to plug in
> alternate fetchers, this also allows a small optimization where source
> iterators no longer have a separate "next line" call; instead they are
> supposed to prepare themselves for the next line in the "get_scanline"
> call.
This patch changes the iterators interface. How about starting with
this interface? Would it bloat the previous commits a lot?
>
> Destination iterators do now have a separate "write_back" call that is
> supposed to write the pixels back to the destination and prepare the
> iterator for the next scanline.
> ---
> pixman/pixman-bits-image.c | 107 ++++++++++++++++++++++++++-----------
> pixman/pixman-conical-gradient.c | 3 +-
> pixman/pixman-general.c | 59 ++++++++++++++------
> pixman/pixman-image.c | 2 +-
> pixman/pixman-implementation.c | 77 +++++++++++++++++++---------
> pixman/pixman-linear-gradient.c | 4 +-
> pixman/pixman-private.h | 60 ++++++++++++---------
> pixman/pixman-radial-gradient.c | 3 +-
> pixman/pixman-solid-fill.c | 1 -
> pixman/pixman-utils.c | 11 ----
> 10 files changed, 208 insertions(+), 119 deletions(-)
>
> diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
> index 7d588a9..4d8c1dc 100644
> --- a/pixman/pixman-bits-image.c
> +++ b/pixman/pixman-bits-image.c
> @@ -1350,7 +1350,7 @@ static uint32_t *
> get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
> {
> iter->image->bits.get_scanline_32 (
> - iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
> + iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
>
> return iter->buffer;
> }
> @@ -1359,13 +1359,59 @@ static uint32_t *
> get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
> {
> iter->image->bits.get_scanline_64 (
> - iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
> + iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
> +
> + return iter->buffer;
> +}
> +
> +static uint32_t *
> +dest_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;
> +
> + image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
> + if (image->common.alpha_map)
> + {
> + x -= image->common.alpha_origin_x;
> + y -= image->common.alpha_origin_y;
> +
> + image->common.alpha_map->fetch_scanline_32 (
> + (pixman_image_t *)image->common.alpha_map,
> + x, y, width, buffer, mask);
> + }
> +
> + return iter->buffer;
> +}
> +
> +static uint32_t *
> +dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
> +{
> + bits_image_t * image = &iter->image->bits;
> + int x = iter->x;
> + int y = iter->y;
> + int width = iter->width;
> + uint32_t * buffer = iter->buffer;
> +
> + image->fetch_scanline_64 (
> + (pixman_image_t *)image, x, y, width, buffer, mask);
> + if (image->common.alpha_map)
> + {
> + x -= image->common.alpha_origin_x;
> + y -= image->common.alpha_origin_y;
> +
> + image->common.alpha_map->fetch_scanline_64 (
> + (pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask);
> + }
>
> return iter->buffer;
> }
>
> static void
> -next_line_write_narrow (pixman_iter_t *iter)
> +write_back_narrow (pixman_iter_t *iter)
> {
> bits_image_t * image = &iter->image->bits;
> int x = iter->x;
> @@ -1388,7 +1434,7 @@ next_line_write_narrow (pixman_iter_t *iter)
> }
>
> static void
> -next_line_write_wide (pixman_iter_t *iter)
> +write_back_wide (pixman_iter_t *iter)
> {
> bits_image_t * image = &iter->image->bits;
> int x = iter->x;
> @@ -1410,25 +1456,19 @@ next_line_write_wide (pixman_iter_t *iter)
> iter->y++;
> }
>
> -static uint32_t *
> -get_scanline_direct_write (pixman_iter_t *iter, const uint32_t *mask)
> -{
> - return iter->buffer;
> -}
> -
> static void
> -next_line_direct_write (pixman_iter_t *iter)
> +write_back_direct (pixman_iter_t *iter)
> {
> iter->buffer += iter->image->bits.rowstride;
> }
>
> void
> -_pixman_bits_image_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)
> +_pixman_bits_image_dest_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_WRITE)) == (ITER_NARROW | ITER_WRITE))
> + if (flags & ITER_NARROW)
> {
> if (((image->common.flags &
> (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
> @@ -1439,40 +1479,43 @@ _pixman_bits_image_iter_init (pixman_image_t *image,
> {
> iter->buffer = image->bits.bits + y * image->bits.rowstride + x;
>
> - iter->get_scanline = get_scanline_direct_write;
> - iter->next_line = next_line_direct_write;
> + iter->get_scanline = _pixman_iter_get_scanline_noop;
> + iter->write_back = write_back_direct;
> }
> else
> {
> if ((flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
> - (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
> + (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
This looks like a whitespace fix. Can it be merged with the patch
which adds this code?
> {
> iter->get_scanline = _pixman_iter_get_scanline_noop;
> }
> else
> {
> - iter->get_scanline = get_scanline_narrow;
> + iter->get_scanline = dest_get_scanline_narrow;
> }
>
> - iter->next_line = next_line_write_narrow;
> + iter->write_back = write_back_narrow;
> }
> }
> - else if (flags & ITER_WRITE)
> - {
> - iter->get_scanline = get_scanline_wide;
> - iter->next_line = next_line_write_wide;
> - }
> else
> {
> - if (flags & ITER_NARROW)
> - iter->get_scanline = get_scanline_narrow;
> - else
> - iter->get_scanline = get_scanline_wide;
> -
> - iter->next_line = _pixman_iter_next_line_regular;
> + iter->get_scanline = dest_get_scanline_wide;
> + iter->write_back = write_back_wide;
> }
> }
>
> +void
> +_pixman_bits_image_src_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 = get_scanline_narrow;
> + else
> + iter->get_scanline = get_scanline_wide;
> +}
> +
> static uint32_t *
> create_bits (pixman_format_code_t format,
> int width,
> diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
> index a0eeae2..9d7d2e8 100644
> --- a/pixman/pixman-conical-gradient.c
> +++ b/pixman/pixman-conical-gradient.c
> @@ -156,6 +156,7 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
> }
> }
>
> + iter->y++;
> return iter->buffer;
> }
>
> @@ -179,8 +180,6 @@ _pixman_conical_gradient_iter_init (pixman_image_t *image,
> iter->get_scanline = conical_get_scanline_narrow;
> else
> iter->get_scanline = conical_get_scanline_wide;
> -
> - iter->next_line = _pixman_iter_next_line_regular;
> }
>
> PIXMAN_EXPORT pixman_image_t *
> diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
> index 25d1fe4..16ea3a4 100644
> --- a/pixman/pixman-general.c
> +++ b/pixman/pixman-general.c
> @@ -40,11 +40,11 @@
> #include "pixman-private.h"
>
> static void
> -general_iter_init (pixman_implementation_t *imp,
> - pixman_iter_t *iter,
> - pixman_image_t *image,
> - int x, int y, int width, int height,
> - uint8_t *buffer, iter_flags_t flags)
> +general_src_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x, int y, int width, int height,
> + uint8_t *buffer, iter_flags_t flags)
> {
> iter->image = image;
> iter->x = x;
> @@ -74,7 +74,7 @@ general_iter_init (pixman_implementation_t *imp,
> }
> else if (image->type == BITS)
> {
> - _pixman_bits_image_iter_init (
> + _pixman_bits_image_src_iter_init (
> image, iter, x, y, width, height, buffer, flags);
> }
> else
> @@ -83,6 +83,30 @@ general_iter_init (pixman_implementation_t *imp,
> }
> }
>
> +static void
> +general_dest_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x, int y, int width, int height,
> + uint8_t *buffer, iter_flags_t flags)
> +{
> + iter->image = image;
> + iter->x = x;
> + iter->y = y;
> + iter->width = width;
> + iter->buffer = (uint32_t *)buffer;
> +
> + if (image->type == BITS)
> + {
> + _pixman_bits_image_dest_iter_init (
> + image, iter, x, y, width, height, buffer, flags);
> + }
> + else
> + {
> + _pixman_log_error (FUNC, "Trying to write to a non-writable image");
> + }
> +}
> +
> typedef struct op_info_t op_info_t;
> struct op_info_t
> {
> @@ -166,9 +190,9 @@ general_composite_rect (pixman_implementation_t *imp,
> /* 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, src_flags);
> + _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
> + src_x, src_y, width, height,
> + src_buffer, src_flags);
>
> /* mask iter */
> if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
> @@ -186,15 +210,15 @@ general_composite_rect (pixman_implementation_t *imp,
> mask->common.component_alpha &&
> PIXMAN_FORMAT_RGB (mask->bits.format);
>
> - _pixman_implementation_iter_init (
> + _pixman_implementation_src_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);
> + _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
> + dest_x, dest_y, width, height,
> + dest_buffer,
> + narrow | op_flags[op].dst);
>
> if (narrow)
> {
> @@ -224,9 +248,7 @@ general_composite_rect (pixman_implementation_t *imp,
>
> compose (imp->toplevel, op, d, s, m, width);
>
> - mask_iter.next_line (&mask_iter);
> - src_iter.next_line (&src_iter);
> - dest_iter.next_line (&dest_iter);
> + dest_iter.write_back (&dest_iter);
> }
>
> if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
> @@ -283,7 +305,8 @@ _pixman_implementation_create_general (void)
>
> imp->blt = general_blt;
> imp->fill = general_fill;
> - imp->iter_init = general_iter_init;
> + imp->src_iter_init = general_src_iter_init;
> + imp->dest_iter_init = general_dest_iter_init;
>
> return imp;
> }
> diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
> index e276eac..a72299b 100644
> --- a/pixman/pixman-image.c
> +++ b/pixman/pixman-image.c
> @@ -728,7 +728,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
> uint32_t result;
> pixman_iter_t iter;
>
> - _pixman_implementation_iter_init (
> + _pixman_implementation_src_iter_init (
> imp, &iter, image, 0, 0, 1, 1,
> (uint8_t *)&result, ITER_NARROW);
>
> diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
> index 57134cb..6b7216f 100644
> --- a/pixman/pixman-implementation.c
> +++ b/pixman/pixman-implementation.c
> @@ -112,17 +112,32 @@ delegate_fill (pixman_implementation_t *imp,
> }
>
> static void
> -delegate_iter_init (pixman_implementation_t *imp,
> - pixman_iter_t * iter,
> - pixman_image_t * image,
> - int x,
> - int y,
> - int width,
> - int height,
> - uint8_t * buffer,
> - iter_flags_t flags)
> +delegate_src_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t * iter,
> + pixman_image_t * image,
> + int x,
> + int y,
> + int width,
> + int height,
> + uint8_t * buffer,
> + iter_flags_t flags)
> {
> - _pixman_implementation_iter_init (
> + _pixman_implementation_src_iter_init (
> + imp->delegate, iter, image, x, y, width, height, buffer, flags);
> +}
> +
> +static void
> +delegate_dest_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t * iter,
> + pixman_image_t * image,
> + int x,
> + int y,
> + int width,
> + int height,
> + uint8_t * buffer,
> + iter_flags_t flags)
> +{
> + _pixman_implementation_dest_iter_init (
> imp->delegate, iter, image, x, y, width, height, buffer, flags);
> }
>
> @@ -148,7 +163,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
> */
> imp->blt = delegate_blt;
> imp->fill = delegate_fill;
> - imp->iter_init = delegate_iter_init;
> + imp->src_iter_init = delegate_src_iter_init;
> + imp->dest_iter_init = delegate_dest_iter_init;
>
> for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
> {
> @@ -248,31 +264,44 @@ get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
> }
>
> void
> -_pixman_implementation_iter_init (pixman_implementation_t *imp,
> - pixman_iter_t *iter,
> - pixman_image_t *image,
> - int x,
> - int y,
> - int width,
> - int height,
> - uint8_t *buffer,
> - iter_flags_t flags)
> +_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x,
> + int y,
> + int width,
> + int height,
> + 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)
> + else if ((flags & NOOP) == NOOP)
> {
> iter->get_scanline = _pixman_iter_get_scanline_noop;
> - iter->next_line = _pixman_iter_next_line_noop;
> }
> else
> {
> - (*imp->iter_init) (
> + (*imp->src_iter_init) (
> imp, iter, image, x, y, width, height, buffer, flags);
> }
> }
> +
> +void
> +_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x,
> + int y,
> + int width,
> + int height,
> + uint8_t *buffer,
> + iter_flags_t flags)
> +{
> + (*imp->dest_iter_init) (
> + imp, iter, image, x, y, width, height, buffer, flags);
> +}
> diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
> index b778601..68845eb 100644
> --- a/pixman/pixman-linear-gradient.c
> +++ b/pixman/pixman-linear-gradient.c
> @@ -220,6 +220,7 @@ linear_gradient_get_scanline_narrow (pixman_iter_t *iter,
> }
> }
>
> + iter->y++;
> return iter->buffer;
> }
>
> @@ -251,7 +252,6 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
> linear_gradient_get_scanline_wide (iter, NULL);
>
> iter->get_scanline = _pixman_iter_get_scanline_noop;
> - iter->next_line = _pixman_iter_next_line_noop;
> }
> else
> {
> @@ -259,8 +259,6 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
> iter->get_scanline = linear_gradient_get_scanline_narrow;
> else
> iter->get_scanline = linear_gradient_get_scanline_wide;
> -
> - iter->next_line = _pixman_iter_next_line_regular;
> }
> }
>
> diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
> index 2a00dc4..9e62c97 100644
> --- a/pixman/pixman-private.h
> +++ b/pixman/pixman-private.h
> @@ -186,7 +186,6 @@ typedef struct pixman_iter_t pixman_iter_t;
> typedef enum
> {
> ITER_NARROW = (1 << 0),
> - ITER_WRITE = (1 << 1),
>
> /* "Localized alpha" is when the alpha channel is used only to compute the
> * alpha value of the destination and doesn't influence the RGB part.
> @@ -201,15 +200,15 @@ 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_IGNORE_ALPHA = (1 << 3),
> - ITER_IGNORE_RGB = (1 << 4)
> + ITER_LOCALIZED_ALPHA = (1 << 1),
> + ITER_IGNORE_ALPHA = (1 << 2),
> + ITER_IGNORE_RGB = (1 << 3)
> } iter_flags_t;
>
> struct pixman_iter_t
> {
> uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
> - void (* next_line) (pixman_iter_t *iter);
> + void (* write_back) (pixman_iter_t *iter);
>
> pixman_image_t * image;
> uint32_t * buffer;
> @@ -221,10 +220,15 @@ void
> _pixman_bits_image_setup_accessors (bits_image_t *image);
>
> void
> -_pixman_bits_image_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);
> +_pixman_bits_image_src_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_bits_image_dest_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,
> @@ -432,7 +436,8 @@ struct pixman_implementation_t
>
> pixman_blt_func_t blt;
> pixman_fill_func_t fill;
> - pixman_iter_init_func_t iter_init;
> + pixman_iter_init_func_t src_iter_init;
> + pixman_iter_init_func_t dest_iter_init;
>
> pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
> pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
> @@ -505,15 +510,26 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
> uint32_t xor);
>
> void
> -_pixman_implementation_iter_init (pixman_implementation_t *imp,
> - pixman_iter_t *iter,
> - pixman_image_t *image,
> - int x,
> - int y,
> - int width,
> - int height,
> - uint8_t *buffer,
> - iter_flags_t flags);
> +_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x,
> + int y,
> + int width,
> + int height,
> + uint8_t *buffer,
> + iter_flags_t flags);
> +
> +void
> +_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
> + pixman_iter_t *iter,
> + pixman_image_t *image,
> + int x,
> + int y,
> + int width,
> + int height,
> + uint8_t *buffer,
> + iter_flags_t flags);
>
> /* Specific implementations */
> pixman_implementation_t *
> @@ -555,12 +571,6 @@ _pixman_choose_implementation (void);
> /*
> * Utilities
> */
> -void
> -_pixman_iter_next_line_regular (pixman_iter_t *iter);
> -
> -void
> -_pixman_iter_next_line_noop (pixman_iter_t *iter);
> -
> uint32_t *
> _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
>
> diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
> index e74a027..2f3e2e6 100644
> --- a/pixman/pixman-radial-gradient.c
> +++ b/pixman/pixman-radial-gradient.c
> @@ -369,6 +369,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
> }
> }
>
> + iter->y++;
> return iter->buffer;
> }
>
> @@ -392,8 +393,6 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image,
> iter->get_scanline = radial_get_scanline_narrow;
> else
> iter->get_scanline = radial_get_scanline_wide;
> -
> - iter->next_line = _pixman_iter_next_line_regular;
> }
>
> PIXMAN_EXPORT pixman_image_t *
> diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
> index 9795fd9..67681f2 100644
> --- a/pixman/pixman-solid-fill.c
> +++ b/pixman/pixman-solid-fill.c
> @@ -52,7 +52,6 @@ _pixman_solid_fill_iter_init (pixman_image_t *image,
> }
>
> iter->get_scanline = _pixman_iter_get_scanline_noop;
> - iter->next_line = _pixman_iter_next_line_noop;
> }
>
> static uint32_t
> diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
> index 09e4ee0..cb4e621 100644
> --- a/pixman/pixman-utils.c
> +++ b/pixman/pixman-utils.c
> @@ -167,17 +167,6 @@ pixman_contract (uint32_t * dst,
> }
> }
>
> -void
> -_pixman_iter_next_line_regular (pixman_iter_t *iter)
> -{
> - iter->y++;
> -}
> -
> -void
> -_pixman_iter_next_line_noop (pixman_iter_t *iter)
> -{
> -}
> -
> uint32_t *
> _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
> {
> --
> 1.6.0.6
>
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pixman
>
More information about the Pixman
mailing list