pixman: Branch 'master' - 11 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Wed May 29 12:27:40 PDT 2013


 pixman/pixman-fast-path.c      |   99 ++++------------------
 pixman/pixman-general.c        |   92 +++++++++++---------
 pixman/pixman-image.c          |   10 +-
 pixman/pixman-implementation.c |   89 +++++++++-----------
 pixman/pixman-mmx.c            |   59 +++----------
 pixman/pixman-noop.c           |  181 +++++++++++++++++++----------------------
 pixman/pixman-private.h        |   70 ++++++++-------
 pixman/pixman-sse2.c           |   59 +++----------
 pixman/pixman-utils.c          |   11 ++
 pixman/pixman.c                |    2 
 10 files changed, 282 insertions(+), 390 deletions(-)

New commits:
commit 2acfac5f8e097ee2ae225d986f981b55d65dd152
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed May 22 09:01:36 2013 -0400

    Consolidate all the iter_init_bits_stride functions
    
    The SSE2, MMX, and fast implementations all have a copy of the
    function iter_init_bits_stride that computes an image buffer and
    stride.
    
    Move that function to pixman-utils.c and share it among all the
    implementations.

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 9af26af..3982dce 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2261,17 +2261,6 @@ fast_write_back_r5g6b5 (pixman_iter_t *iter)
     }
 }
 
-static void
-iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
-{
-    pixman_image_t *image = iter->image;
-    uint8_t *b = (uint8_t *)image->bits.bits;
-    int s = image->bits.rowstride * 4;
-
-    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
-    iter->stride = s;
-}
-
 #define IMAGE_FLAGS							\
     (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
      FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
@@ -2279,15 +2268,17 @@ iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 static const pixman_iter_info_t fast_iters[] = 
 {
     { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW | ITER_SRC,
-      iter_init_bits_stride, fast_fetch_r5g6b5, NULL },
+      _pixman_iter_init_bits_stride, fast_fetch_r5g6b5, NULL },
 
     { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
       ITER_NARROW | ITER_DEST,
-      iter_init_bits_stride, fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
+      _pixman_iter_init_bits_stride,
+      fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
     
     { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
       ITER_NARROW | ITER_DEST | ITER_IGNORE_RGB | ITER_IGNORE_ALPHA,
-      iter_init_bits_stride, fast_dest_fetch_noop, fast_write_back_r5g6b5 },
+      _pixman_iter_init_bits_stride,
+      fast_dest_fetch_noop, fast_write_back_r5g6b5 },
 
     { PIXMAN_null },
 };
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 861b856..c94d282 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3922,17 +3922,6 @@ mmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
     return iter->buffer;
 }
 
-static void
-iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
-{
-    pixman_image_t *image = iter->image;
-    uint8_t *b = (uint8_t *)image->bits.bits;
-    int s = image->bits.rowstride * 4;
-
-    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
-    iter->stride = s;
-}
-
 #define IMAGE_FLAGS							\
     (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
      FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
@@ -3940,13 +3929,13 @@ iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 static const pixman_iter_info_t mmx_iters[] = 
 {
     { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, mmx_fetch_x8r8g8b8, NULL
+      _pixman_iter_init_bits_stride, mmx_fetch_x8r8g8b8, NULL
     },
     { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, mmx_fetch_r5g6b5, NULL
+      _pixman_iter_init_bits_stride, mmx_fetch_r5g6b5, NULL
     },
     { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, mmx_fetch_a8, NULL
+      _pixman_iter_init_bits_stride, mmx_fetch_a8, NULL
     },
     { PIXMAN_null },
 };
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index aa0a842..af4a0b6 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -652,6 +652,9 @@ _pixman_compute_composite_region32 (pixman_region32_t * region,
 uint32_t *
 _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
 
+void
+_pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info);
+
 /* These "formats" all have depth 0, so they
  * will never clash with any real ones
  */
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index bc834b5..dde9235 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6340,17 +6340,6 @@ sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
     return iter->buffer;
 }
 
-static void
-iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
-{
-    pixman_image_t *image = iter->image;
-    uint8_t *b = (uint8_t *)image->bits.bits;
-    int s = image->bits.rowstride * 4;
-
-    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
-    iter->stride = s;
-}
-
 #define IMAGE_FLAGS							\
     (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
      FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
@@ -6358,13 +6347,13 @@ iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 static const pixman_iter_info_t sse2_iters[] = 
 {
     { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, sse2_fetch_x8r8g8b8, NULL
+      _pixman_iter_init_bits_stride, sse2_fetch_x8r8g8b8, NULL
     },
     { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, sse2_fetch_r5g6b5, NULL
+      _pixman_iter_init_bits_stride, sse2_fetch_r5g6b5, NULL
     },
     { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW,
-      iter_init_bits_stride, sse2_fetch_a8, NULL
+      _pixman_iter_init_bits_stride, sse2_fetch_a8, NULL
     },
     { PIXMAN_null },
 };
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index f31171f..98723a8 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -214,6 +214,17 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
     return iter->buffer;
 }
 
+void
+_pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
+{
+    pixman_image_t *image = iter->image;
+    uint8_t *b = (uint8_t *)image->bits.bits;
+    int s = image->bits.rowstride * 4;
+
+    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
+    iter->stride = s;
+}
+
 #define N_TMP_BOXES (16)
 
 pixman_bool_t
commit 533f54430a73199020ce49208d50f448c871a481
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 06:40:59 2013 -0400

    Delete the old src/dest_iter_init() functions
    
    Now that we are using the new _pixman_implementation_iter_init(), the
    old _src/_dest_iter_init() functions are no longer needed, so they can
    be deleted, and the corresponding fields in pixman_implementation_t
    can be removed.

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index d5f707f..9af26af 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2292,50 +2292,12 @@ static const pixman_iter_info_t fast_iters[] =
     { PIXMAN_null },
 };
 
-static pixman_bool_t
-fast_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    const pixman_iter_info_t *info;
-
-    for (info = fast_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)
-	{
-	    iter->get_scanline = info->get_scanline;
-	    iter->write_back = info->write_back;
-
-	    if (info->initializer)
-		info->initializer (iter, info);
-	    return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
-static pixman_bool_t
-fast_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    return fast_iter_init_common (imp, iter);
-}
-
-static pixman_bool_t
-fast_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    return fast_iter_init_common (imp, iter);
-}
-
 pixman_implementation_t *
 _pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
 {
     pixman_implementation_t *imp = _pixman_implementation_create (fallback, c_fast_paths);
 
     imp->fill = fast_path_fill;
-    imp->src_iter_init = fast_src_iter_init;
-    imp->dest_iter_init = fast_dest_iter_init;
     imp->iter_info = fast_iters;
 
     return imp;
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index c469a81..4da5da5 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -79,42 +79,6 @@ static const pixman_iter_info_t general_iters[] =
     { PIXMAN_null },
 };
 
-static pixman_bool_t
-general_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    const pixman_iter_info_t *info;
-
-    for (info = general_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)
-	{
-	    iter->get_scanline = info->get_scanline;
-	    iter->write_back = info->write_back;
-
-	    if (info->initializer)
-		info->initializer (iter, info);
-	    return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
-static pixman_bool_t
-general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    return general_iter_init_common (imp, iter);
-}
-
-static pixman_bool_t
-general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    return general_iter_init_common (imp, iter);
-}
-
 typedef struct op_info_t op_info_t;
 struct op_info_t
 {
@@ -262,8 +226,6 @@ _pixman_implementation_create_general (void)
     _pixman_setup_combiner_functions_32 (imp);
     _pixman_setup_combiner_functions_float (imp);
 
-    imp->src_iter_init = general_src_iter_init;
-    imp->dest_iter_init = general_dest_iter_init;
     imp->iter_info = general_iters;
 
     return imp;
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 4bdc836..160847a 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -349,70 +349,6 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp,
 }
 
 pixman_bool_t
-_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		 iter_flags,
-				      uint32_t                   image_flags)
-{
-    iter->image = image;
-    iter->buffer = (uint32_t *)buffer;
-    iter->x = x;
-    iter->y = y;
-    iter->width = width;
-    iter->height = height;
-    iter->iter_flags = iter_flags;
-    iter->image_flags = image_flags;
-
-    while (imp)
-    {
-	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
-	    return TRUE;
-
-	imp = imp->fallback;
-    }
-
-    return FALSE;
-}
-
-pixman_bool_t
-_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		 iter_flags,
-				       uint32_t                  image_flags)
-{
-    iter->image = image;
-    iter->buffer = (uint32_t *)buffer;
-    iter->x = x;
-    iter->y = y;
-    iter->width = width;
-    iter->height = height;
-    iter->iter_flags = iter_flags;
-    iter->image_flags = image_flags;
-
-    while (imp)
-    {
-	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
-	    return TRUE;
-
-	imp = imp->fallback;
-    }
-
-    return FALSE;
-}
-
-pixman_bool_t
 _pixman_disabled (const char *name)
 {
     const char *env;
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index c3d81e0..861b856 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3951,30 +3951,6 @@ static const pixman_iter_info_t mmx_iters[] =
     { PIXMAN_null },
 };
 
-static pixman_bool_t
-mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    const pixman_iter_info_t *info;
-
-    for (info = mmx_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)
-	{
-	    iter->get_scanline = info->get_scanline;
-	    iter->write_back = info->write_back;
-
-	    if (info->initializer)
-		info->initializer (iter, info);
-	    return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
 static const pixman_fast_path_t mmx_fast_paths[] =
 {
     PIXMAN_STD_FAST_PATH    (OVER, solid,    a8,       r5g6b5,   mmx_composite_over_n_8_0565       ),
@@ -4104,7 +4080,6 @@ _pixman_implementation_create_mmx (pixman_implementation_t *fallback)
     imp->fill = mmx_fill;
 
     imp->iter_info = mmx_iters;
-    imp->src_iter_init = mmx_src_iter_init;
 
     return imp;
 }
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 68b3bc6..e598904 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -37,12 +37,6 @@ noop_composite (pixman_implementation_t *imp,
     return;
 }
 
-static void
-dest_write_back_direct (pixman_iter_t *iter)
-{
-    iter->buffer += iter->image->bits.rowstride;
-}
-
 static uint32_t *
 noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
 {
@@ -53,12 +47,6 @@ noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
     return result;
 }
 
-static uint32_t *
-get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
-{
-    return NULL;
-}
-
 static void
 noop_init_solid_narrow (pixman_iter_t *iter,
 			const pixman_iter_info_t *info)
@@ -104,6 +92,12 @@ noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info)
 	image->bits.bits + iter->y * image->bits.rowstride + iter->x;
 }
 
+static void
+dest_write_back_direct (pixman_iter_t *iter)
+{
+    iter->buffer += iter->image->bits.rowstride;
+}
+
 static const pixman_iter_info_t noop_iters[] =
 {
     /* Source iters */
@@ -149,48 +143,6 @@ static const pixman_iter_info_t noop_iters[] =
     { 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;
-    }
-
-    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)
-	{
-	    iter->get_scanline = info->get_scanline;
-	    iter->write_back = info->write_back;
-
-	    if (info->initializer)
-		info->initializer (iter, info);
-	    return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
-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)
-{
-    return noop_iter_init_common (imp, iter);
-}
-
 static const pixman_fast_path_t noop_fast_paths[] =
 {
     { PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite },
@@ -203,8 +155,6 @@ _pixman_implementation_create_noop (pixman_implementation_t *fallback)
     pixman_implementation_t *imp =
 	_pixman_implementation_create (fallback, noop_fast_paths);
  
-    imp->src_iter_init = noop_src_iter_init;
-    imp->dest_iter_init = noop_dest_iter_init;
     imp->iter_info = noop_iters;
 
     return imp;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 6859c4a..aa0a842 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -474,8 +474,6 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
 					     int                      width,
 					     int                      height,
 					     uint32_t                 filler);
-typedef pixman_bool_t (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
-						  pixman_iter_t           *iter);
 
 void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
 void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp);
@@ -501,8 +499,6 @@ struct pixman_implementation_t
 
     pixman_blt_func_t		blt;
     pixman_fill_func_t		fill;
-    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];
@@ -575,30 +571,6 @@ _pixman_implementation_iter_init (pixman_implementation_t       *imp,
                                   iter_flags_t                   flags,
                                   uint32_t                       image_flags);
 
-pixman_bool_t
-_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,
-				      uint32_t                       image_flags);
-
-pixman_bool_t
-_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,
-				       uint32_t                       image_flags);
-
 /* Specific implementations */
 pixman_implementation_t *
 _pixman_implementation_create_general (void);
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 1f357e1..bc834b5 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6369,30 +6369,6 @@ static const pixman_iter_info_t sse2_iters[] =
     { PIXMAN_null },
 };
 
-static pixman_bool_t
-sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
-{
-    const pixman_iter_info_t *info;
-
-    for (info = sse2_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)
-	{
-	    iter->get_scanline = info->get_scanline;
-	    iter->write_back = info->write_back;
-
-	    if (info->initializer)
-		info->initializer (iter, info);
-	    return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
 #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
 __attribute__((__force_align_arg_pointer__))
 #endif
@@ -6450,7 +6426,6 @@ _pixman_implementation_create_sse2 (pixman_implementation_t *fallback)
     imp->fill = sse2_fill;
 
     imp->iter_info = sse2_iters;
-    imp->src_iter_init = sse2_src_iter_init;
 
     return imp;
 }
commit 125a4fd36f94a06d220bc6709f3ddfd23bdb6ef9
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 08:15:41 2013 -0400

    Add _pixman_implementation_iter_init() and use instead of _src/_dest_init()
    
    A new field, 'iter_info', is added to the implementation struct, and
    all the implementations store a pointer to their iterator tables in
    it. A new function, _pixman_implementation_iter_init(), is then added
    that searches those tables, and the new function is called in
    pixman-general.c and pixman-image.c instead of the old
    _pixman_implementation_src_init() and _pixman_implementation_dest_init().

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 047675c..d5f707f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2336,6 +2336,7 @@ _pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
     imp->fill = fast_path_fill;
     imp->src_iter_init = fast_src_iter_init;
     imp->dest_iter_init = fast_dest_iter_init;
+    imp->iter_info = fast_iters;
 
     return imp;
 }
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 91e33c4..c469a81 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -196,9 +196,10 @@ general_composite_rect  (pixman_implementation_t *imp,
     /* src iter */
     src_iter_flags = width_flag | op_flags[op].src | ITER_SRC;
 
-    _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
-					  src_x, src_y, width, height,
-					  src_buffer, src_iter_flags, info->src_flags);
+    _pixman_implementation_iter_init (imp->toplevel, &src_iter, src_image,
+                                      src_x, src_y, width, height,
+                                      src_buffer, src_iter_flags,
+                                      info->src_flags);
 
     /* mask iter */
     if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
@@ -216,14 +217,14 @@ general_composite_rect  (pixman_implementation_t *imp,
         mask_image->common.component_alpha    &&
         PIXMAN_FORMAT_RGB (mask_image->bits.format);
 
-    _pixman_implementation_src_iter_init (
+    _pixman_implementation_iter_init (
 	imp->toplevel, &mask_iter,
 	mask_image, mask_x, mask_y, width, height, mask_buffer,
 	ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB),
 	info->mask_flags);
 
     /* dest iter */
-    _pixman_implementation_dest_iter_init (
+    _pixman_implementation_iter_init (
 	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
 	dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
 
@@ -263,6 +264,7 @@ _pixman_implementation_create_general (void)
 
     imp->src_iter_init = general_src_iter_init;
     imp->dest_iter_init = general_dest_iter_init;
+    imp->iter_info = general_iters;
 
     return imp;
 }
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 78c8610..4f9c2f9 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -920,7 +920,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
 	pixman_iter_t iter;
 
     otherwise:
-	_pixman_implementation_src_iter_init (
+	_pixman_implementation_iter_init (
 	    imp, &iter, image, 0, 0, 1, 1,
 	    (uint8_t *)&result,
 	    ITER_NARROW | ITER_SRC, image->common.flags);
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index cfb82bb..4bdc836 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -285,6 +285,69 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
     return FALSE;
 }
 
+static uint32_t *
+get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
+{
+    return NULL;
+}
+
+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             iter_flags,
+                                  uint32_t                 image_flags)
+{
+    pixman_format_code_t format;
+
+    iter->image = image;
+    iter->buffer = (uint32_t *)buffer;
+    iter->x = x;
+    iter->y = y;
+    iter->width = width;
+    iter->height = height;
+    iter->iter_flags = iter_flags;
+    iter->image_flags = image_flags;
+
+    if (!iter->image)
+    {
+	iter->get_scanline = get_scanline_null;
+	return;
+    }
+
+    format = iter->image->common.extended_format_code;
+
+    while (imp)
+    {
+        if (imp->iter_info)
+        {
+            const pixman_iter_info_t *info;
+
+            for (info = imp->iter_info; info->format != PIXMAN_null; ++info)
+            {
+                if ((info->format == PIXMAN_any || info->format == format) &&
+                    (info->image_flags & image_flags) == info->image_flags &&
+                    (info->iter_flags & iter_flags) == info->iter_flags)
+                {
+                    iter->get_scanline = info->get_scanline;
+                    iter->write_back = info->write_back;
+
+                    if (info->initializer)
+                        info->initializer (iter, info);
+                    return;
+                }
+            }
+        }
+
+        imp = imp->fallback;
+    }
+}
+
 pixman_bool_t
 _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
 				      pixman_iter_t             *iter,
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 02ec998..c3d81e0 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -4103,6 +4103,7 @@ _pixman_implementation_create_mmx (pixman_implementation_t *fallback)
     imp->blt = mmx_blt;
     imp->fill = mmx_fill;
 
+    imp->iter_info = mmx_iters;
     imp->src_iter_init = mmx_src_iter_init;
 
     return imp;
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index d01665e..68b3bc6 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -205,6 +205,7 @@ _pixman_implementation_create_noop (pixman_implementation_t *fallback)
  
     imp->src_iter_init = noop_src_iter_init;
     imp->dest_iter_init = noop_dest_iter_init;
+    imp->iter_info = noop_iters;
 
     return imp;
 }
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0365901..6859c4a 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -497,6 +497,7 @@ struct pixman_implementation_t
     pixman_implementation_t *	toplevel;
     pixman_implementation_t *	fallback;
     const pixman_fast_path_t *	fast_paths;
+    const pixman_iter_info_t *  iter_info;
 
     pixman_blt_func_t		blt;
     pixman_fill_func_t		fill;
@@ -562,6 +563,18 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
                              int                      height,
                              uint32_t                 filler);
 
+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,
+                                  uint32_t                       image_flags);
+
 pixman_bool_t
 _pixman_implementation_src_iter_init (pixman_implementation_t       *imp,
 				      pixman_iter_t                 *iter,
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 344cc46..1f357e1 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6449,6 +6449,7 @@ _pixman_implementation_create_sse2 (pixman_implementation_t *fallback)
     imp->blt = sse2_blt;
     imp->fill = sse2_fill;
 
+    imp->iter_info = sse2_iters;
     imp->src_iter_init = sse2_src_iter_init;
 
     return imp;
commit 245d0090c596eb3ca50294d0dec0fb0933eff0db
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed May 22 08:05:55 2013 -0400

    general: Store the iter initializer in a one-entry pixman_iter_info_t table
    
    In preparation for sharing all iterator initialization code from all
    the implementations, move the general implementation to use a table of
    pixman_iter_info_t.
    
    The existing src_iter_init and dest_iter_init functions are
    consolidated into one general_iter_init() function that checks the
    iter_flags for whether it is dealing with a source or destination
    iterator.
    
    Unlike in the other implementations, the general_iter_init() function
    stores its own get_scanline() and write_back() functions in the
    iterator, so it relies on the initializer being called after
    get_scanline and write_back being copied from the struct to the
    iterator.

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index c674ffa..91e33c4 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -37,42 +37,82 @@
 #include <string.h>
 #include "pixman-private.h"
 
-static pixman_bool_t
-general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+static void
+general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info)
 {
     pixman_image_t *image = iter->image;
 
-    if (image->type == LINEAR)
-	_pixman_linear_gradient_iter_init (image, iter);
-    else if (image->type == RADIAL)
+    switch (image->type)
+    {
+    case BITS:
+        if ((iter->iter_flags & ITER_SRC) == ITER_SRC)
+            _pixman_bits_image_src_iter_init (image, iter);
+        else
+            _pixman_bits_image_dest_iter_init (image, iter);
+        break;
+
+    case LINEAR:
+        _pixman_linear_gradient_iter_init (image, iter);
+        break;
+
+    case RADIAL:
 	_pixman_radial_gradient_iter_init (image, iter);
-    else if (image->type == CONICAL)
+        break;
+
+    case CONICAL:
 	_pixman_conical_gradient_iter_init (image, iter);
-    else if (image->type == BITS)
-	_pixman_bits_image_src_iter_init (image, iter);
-    else if (image->type == SOLID)
+        break;
+
+    case SOLID:
         _pixman_log_error (FUNC, "Solid image not handled by noop");
-    else         
-	_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+        break;
 
-    return TRUE;
+    default:
+	_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+        break;
+    }
 }
 
+static const pixman_iter_info_t general_iters[] =
+{
+    { PIXMAN_any, 0, 0, general_iter_init, NULL, NULL },
+    { PIXMAN_null },
+};
+
 static pixman_bool_t
-general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+general_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    if (iter->image->type == BITS)
-    {
-	_pixman_bits_image_dest_iter_init (iter->image, iter);
+    const pixman_iter_info_t *info;
 
-	return TRUE;
-    }
-    else
+    for (info = general_iters; info->format != PIXMAN_null; ++info)
     {
-	_pixman_log_error (FUNC, "Trying to write to a non-writable image");
-
-	return FALSE;
+	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)
+	{
+	    iter->get_scanline = info->get_scanline;
+	    iter->write_back = info->write_back;
+
+	    if (info->initializer)
+		info->initializer (iter, info);
+	    return TRUE;
+	}
     }
+
+    return FALSE;
+}
+
+static pixman_bool_t
+general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+{
+    return general_iter_init_common (imp, iter);
+}
+
+static pixman_bool_t
+general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+{
+    return general_iter_init_common (imp, iter);
 }
 
 typedef struct op_info_t op_info_t;
commit 9c15afb105ee0c5b166b9bd07c28857927b1aecb
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 03:59:06 2013 -0400

    fast: Replace the fetcher_info_t table with a pixman_iter_info_t table
    
    Similar to the SSE2 and MMX patches, this commit replaces a table of
    fetcher_info_t with a table of pixman_iter_info_t, and similar to the
    noop patch, both fast_src_iter_init() and fast_dest_iter_init() are
    now doing exactly the same thing, so their code can be shared in a new
    function called fast_iter_init_common().

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 247aea6..047675c 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2261,46 +2261,55 @@ fast_write_back_r5g6b5 (pixman_iter_t *iter)
     }
 }
 
-typedef struct
+static void
+iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 {
-    pixman_format_code_t	format;
-    pixman_iter_get_scanline_t	get_scanline;
-    pixman_iter_write_back_t	write_back;
-} fetcher_info_t;
+    pixman_image_t *image = iter->image;
+    uint8_t *b = (uint8_t *)image->bits.bits;
+    int s = image->bits.rowstride * 4;
+
+    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
+    iter->stride = s;
+}
+
+#define IMAGE_FLAGS							\
+    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
+     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
 
-static const fetcher_info_t fetchers[] =
+static const pixman_iter_info_t fast_iters[] = 
 {
-    { PIXMAN_r5g6b5, fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
-    { PIXMAN_null }
+    { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW | ITER_SRC,
+      iter_init_bits_stride, fast_fetch_r5g6b5, NULL },
+
+    { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
+      ITER_NARROW | ITER_DEST,
+      iter_init_bits_stride, fast_fetch_r5g6b5, fast_write_back_r5g6b5 },
+    
+    { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS,
+      ITER_NARROW | ITER_DEST | ITER_IGNORE_RGB | ITER_IGNORE_ALPHA,
+      iter_init_bits_stride, fast_dest_fetch_noop, fast_write_back_r5g6b5 },
+
+    { PIXMAN_null },
 };
 
 static pixman_bool_t
-fast_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+fast_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    pixman_image_t *image = iter->image;
-
-#define FLAGS								\
-    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
-     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
+    const pixman_iter_info_t *info;
 
-    if ((iter->iter_flags & ITER_NARROW)			&&
-	(iter->image_flags & FLAGS) == FLAGS)
+    for (info = fast_iters; info->format != PIXMAN_null; ++info)
     {
-	const fetcher_info_t *f;
-
-	for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
+	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)
 	{
-	    if (image->common.extended_format_code == f->format)
-	    {
-		uint8_t *b = (uint8_t *)image->bits.bits;
-		int s = image->bits.rowstride * 4;
-
-		iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
-		iter->stride = s;
+	    iter->get_scanline = info->get_scanline;
+	    iter->write_back = info->write_back;
 
-		iter->get_scanline = f->get_scanline;
-		return TRUE;
-	    }
+	    if (info->initializer)
+		info->initializer (iter, info);
+	    return TRUE;
 	}
     }
 
@@ -2308,42 +2317,16 @@ fast_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 }
 
 static pixman_bool_t
-fast_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+fast_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    pixman_image_t *image = iter->image;
-
-    if ((iter->iter_flags & ITER_NARROW)		&&
-	(iter->image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS)
-    {
-	const fetcher_info_t *f;
-
-	for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
-	{
-	    if (image->common.extended_format_code == f->format)
-	    {
-		uint8_t *b = (uint8_t *)image->bits.bits;
-		int s = image->bits.rowstride * 4;
-
-		iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
-		iter->stride = s;
-
-		if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
-		    (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
-		{
-		    iter->get_scanline = fast_dest_fetch_noop;
-		}
-		else
-		{
-		    iter->get_scanline = f->get_scanline;
-		}
-		iter->write_back = f->write_back;
-		return TRUE;
-	    }
-	}
-    }
-    return FALSE;
+    return fast_iter_init_common (imp, iter);
 }
 
+static pixman_bool_t
+fast_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+{
+    return fast_iter_init_common (imp, iter);
+}
 
 pixman_implementation_t *
 _pixman_implementation_create_fast_path (pixman_implementation_t *fallback)
commit 71c2d519d0abb8217b7ddb20148861e2ef71f3e6
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 03:32:32 2013 -0400

    mmx: Replace the fetcher_info_t table with a pixman_iter_info_t table
    
    Similar to the SSE2 commit, information about the iterators is stored
    in a table of pixman_iter_info_t.

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 746ecd6..02ec998 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3922,47 +3922,53 @@ mmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
     return iter->buffer;
 }
 
-typedef struct
+static void
+iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 {
-    pixman_format_code_t	format;
-    pixman_iter_get_scanline_t	get_scanline;
-} fetcher_info_t;
+    pixman_image_t *image = iter->image;
+    uint8_t *b = (uint8_t *)image->bits.bits;
+    int s = image->bits.rowstride * 4;
+
+    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
+    iter->stride = s;
+}
+
+#define IMAGE_FLAGS							\
+    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
+     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
 
-static const fetcher_info_t fetchers[] =
+static const pixman_iter_info_t mmx_iters[] = 
 {
-    { PIXMAN_x8r8g8b8,		mmx_fetch_x8r8g8b8 },
-    { PIXMAN_r5g6b5,		mmx_fetch_r5g6b5 },
-    { PIXMAN_a8,		mmx_fetch_a8 },
-    { PIXMAN_null }
+    { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, mmx_fetch_x8r8g8b8, NULL
+    },
+    { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, mmx_fetch_r5g6b5, NULL
+    },
+    { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, mmx_fetch_a8, NULL
+    },
+    { PIXMAN_null },
 };
 
 static pixman_bool_t
 mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    pixman_image_t *image = iter->image;
-
-#define FLAGS								\
-    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
-     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
+    const pixman_iter_info_t *info;
 
-    if ((iter->iter_flags & ITER_NARROW)			&&
-	(iter->image_flags & FLAGS) == FLAGS)
+    for (info = mmx_iters; info->format != PIXMAN_null; ++info)
     {
-	const fetcher_info_t *f;
-
-	for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
+	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)
 	{
-	    if (image->common.extended_format_code == f->format)
-	    {
-		uint8_t *b = (uint8_t *)image->bits.bits;
-		int s = image->bits.rowstride * 4;
+	    iter->get_scanline = info->get_scanline;
+	    iter->write_back = info->write_back;
 
-		iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
-		iter->stride = s;
-
-		iter->get_scanline = f->get_scanline;
-		return TRUE;
-	    }
+	    if (info->initializer)
+		info->initializer (iter, info);
+	    return TRUE;
 	}
     }
 
commit 78f437d61e20476fa1c2324b14744aa62a232a43
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 03:29:09 2013 -0400

    sse2: Replace the fetcher_info_t table with a pixman_iter_info_t table
    
    Similar to the changes to noop, put all the iterators into a table of
    pixman_iter_info_t and then do a generic search of that table during
    iterator initialization.

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 863bc18..344cc46 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6340,47 +6340,53 @@ sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
     return iter->buffer;
 }
 
-typedef struct
+static void
+iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
 {
-    pixman_format_code_t	format;
-    pixman_iter_get_scanline_t	get_scanline;
-} fetcher_info_t;
+    pixman_image_t *image = iter->image;
+    uint8_t *b = (uint8_t *)image->bits.bits;
+    int s = image->bits.rowstride * 4;
+
+    iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
+    iter->stride = s;
+}
 
-static const fetcher_info_t fetchers[] =
+#define IMAGE_FLAGS							\
+    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
+     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
+
+static const pixman_iter_info_t sse2_iters[] = 
 {
-    { PIXMAN_x8r8g8b8,		sse2_fetch_x8r8g8b8 },
-    { PIXMAN_r5g6b5,		sse2_fetch_r5g6b5 },
-    { PIXMAN_a8,		sse2_fetch_a8 },
-    { PIXMAN_null }
+    { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, sse2_fetch_x8r8g8b8, NULL
+    },
+    { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, sse2_fetch_r5g6b5, NULL
+    },
+    { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW,
+      iter_init_bits_stride, sse2_fetch_a8, NULL
+    },
+    { PIXMAN_null },
 };
 
 static pixman_bool_t
 sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    pixman_image_t *image = iter->image;
+    const pixman_iter_info_t *info;
 
-#define FLAGS								\
-    (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |		\
-     FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
-
-    if ((iter->iter_flags & ITER_NARROW)			&&
-	(iter->image_flags & FLAGS) == FLAGS)
+    for (info = sse2_iters; info->format != PIXMAN_null; ++info)
     {
-	const fetcher_info_t *f;
-
-	for (f = &fetchers[0]; f->format != PIXMAN_null; f++)
+	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)
 	{
-	    if (image->common.extended_format_code == f->format)
-	    {
-		uint8_t *b = (uint8_t *)image->bits.bits;
-		int s = image->bits.rowstride * 4;
-
-		iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (f->format) / 8;
-		iter->stride = s;
+	    iter->get_scanline = info->get_scanline;
+	    iter->write_back = info->write_back;
 
-		iter->get_scanline = f->get_scanline;
-		return TRUE;
-	    }
+	    if (info->initializer)
+		info->initializer (iter, info);
+	    return TRUE;
 	}
     }
 
commit c7b0da8a96c9196f751dab2af42adb5560ba6557
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue May 21 08:14:44 2013 -0400

    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.

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);
 
commit 3b96ee4e77ff01217f7fefc4718babbf68a13147
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Mon May 20 09:44:05 2013 -0400

    Always set the FAST_PATH_NO_ALPHA_MAP flag for non-BITS images
    
    We only support alpha maps for BITS images, so it's always to ignore
    the alpha map for non-BITS image. This makes it possible get rid of
    the check for SOLID images since it will now be subsumed by the check
    for FAST_PATH_NO_ALPHA_MAP.
    
    Opaque masks are reduced to NULL images in pixman.c, and those can
    also safely be treated as not having an alpha map, so set the
    FAST_PATH_NO_ALPHA_MAP bit for those as well.

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index ebf55cd..78c8610 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -502,8 +502,10 @@ compute_image_info (pixman_image_t *image)
 	break;
     }
 
-    /* Alpha map */
-    if (!image->common.alpha_map)
+    /* Alpha maps are only supported for BITS images, so it's always
+     * safe to ignore their presense for non-BITS images
+     */
+    if (!image->common.alpha_map || image->type != BITS)
     {
 	flags |= FAST_PATH_NO_ALPHA_MAP;
     }
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 955e9c8..6afd4b9 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -78,8 +78,7 @@ noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 	iter->get_scanline = _pixman_iter_get_scanline_noop;
     }
     else if (image->common.extended_format_code == PIXMAN_solid		&&
-	     (iter->image->type == SOLID ||
-	      (iter->image_flags & FAST_PATH_NO_ALPHA_MAP)))
+	     (iter->image_flags & FAST_PATH_NO_ALPHA_MAP))
     {
 	if (iter->iter_flags & ITER_NARROW)
 	{
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 184f0c4..9555cea 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -605,7 +605,7 @@ pixman_image_composite32 (pixman_op_t      op,
     else
     {
 	mask_format = PIXMAN_null;
-	info.mask_flags = FAST_PATH_IS_OPAQUE;
+	info.mask_flags = FAST_PATH_IS_OPAQUE | FAST_PATH_NO_ALPHA_MAP;
     }
 
     dest_format = dest->common.extended_format_code;
commit 52ff5f0cd992e0384fa2babcb25780c3182548e6
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Thu Dec 6 02:25:35 2012 -0500

    Add ITER_WIDE iter flag
    
    This will be useful for putting iterators into tables where they can
    be looked up by iterator flags. Without this flag, wide iterators can
    only be recognized by the absence of ITER_NARROW, which makes testing
    for a match difficult.

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index a4935c7..c674ffa 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -116,7 +116,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, src_iter_flags;
+    iter_flags_t width_flag, src_iter_flags;
     int Bpp;
     int i;
 
@@ -124,12 +124,12 @@ general_composite_rect  (pixman_implementation_t *imp,
 	(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
 	(dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
     {
-	narrow = ITER_NARROW;
+	width_flag = ITER_NARROW;
 	Bpp = 4;
     }
     else
     {
-	narrow = 0;
+	width_flag = ITER_WIDE;
 	Bpp = 16;
     }
 
@@ -145,7 +145,7 @@ general_composite_rect  (pixman_implementation_t *imp,
     mask_buffer = src_buffer + width * Bpp;
     dest_buffer = mask_buffer + width * Bpp;
 
-    if (!narrow)
+    if (width_flag == ITER_WIDE)
     {
 	/* To make sure there aren't any NANs in the buffers */
 	memset (src_buffer, 0, width * Bpp);
@@ -154,7 +154,7 @@ general_composite_rect  (pixman_implementation_t *imp,
     }
     
     /* src iter */
-    src_iter_flags = narrow | op_flags[op].src | ITER_SRC;
+    src_iter_flags = width_flag | op_flags[op].src | ITER_SRC;
 
     _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
 					  src_x, src_y, width, height,
@@ -179,18 +179,16 @@ general_composite_rect  (pixman_implementation_t *imp,
     _pixman_implementation_src_iter_init (
 	imp->toplevel, &mask_iter,
 	mask_image, mask_x, mask_y, width, height, mask_buffer,
-	ITER_SRC | narrow | (component_alpha? 0 : ITER_IGNORE_RGB),
+	ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB),
 	info->mask_flags);
 
     /* dest iter */
     _pixman_implementation_dest_iter_init (
-	imp->toplevel, &dest_iter,
-	dest_image, dest_x, dest_y, width, height, dest_buffer,
-	ITER_DEST | narrow | op_flags[op].dst,
-	info->dest_flags);
+	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
+	dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
 
     compose = _pixman_implementation_lookup_combiner (
-	imp->toplevel, op, component_alpha, narrow);
+	imp->toplevel, op, component_alpha, width_flag != ITER_WIDE);
 
     for (i = 0; i < height; ++i)
     {
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9b6353e..0fe86ca 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -212,7 +212,8 @@ typedef void      (* pixman_iter_write_back_t)   (pixman_iter_t *iter);
 
 typedef enum
 {
-    ITER_NARROW =		(1 << 0),
+    ITER_NARROW =               (1 << 0),
+    ITER_WIDE =                 (1 << 1),
 
     /* "Localized alpha" is when the alpha channel is used only to compute
      * the alpha value of the destination. This means that the computation
@@ -229,15 +230,15 @@ typedef enum
      * we can treat it as if it were ARGB, which means in some cases we can
      * avoid copying it to a temporary buffer.
      */
-    ITER_LOCALIZED_ALPHA =	(1 << 1),
-    ITER_IGNORE_ALPHA =		(1 << 2),
-    ITER_IGNORE_RGB =		(1 << 3),
+    ITER_LOCALIZED_ALPHA =	(1 << 2),
+    ITER_IGNORE_ALPHA =		(1 << 3),
+    ITER_IGNORE_RGB =		(1 << 4),
 
     /* These indicate whether the iterator is for a source
      * or a destination image
      */
-    ITER_SRC =			(1 << 4),
-    ITER_DEST =			(1 << 5)
+    ITER_SRC =			(1 << 5),
+    ITER_DEST =			(1 << 6)
 } iter_flags_t;
 
 struct pixman_iter_t
commit e8a180797c726a8990291158be8db843c26b98d3
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Mon May 20 09:04:22 2013 -0400

    Add ITER_SRC and ITER_DEST iter flags
    
    These indicate whether the iterator is for a source or a destination
    image. Note iterator initializers are allowed to rely on one of these
    being set, so they can't be left out the way it's generally harmless
    (aside from potentil performance degradation) to leave out a
    particular fast path flag.

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 93a1b9a..a4935c7 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -154,7 +154,7 @@ general_composite_rect  (pixman_implementation_t *imp,
     }
     
     /* src iter */
-    src_iter_flags = narrow | op_flags[op].src;
+    src_iter_flags = narrow | op_flags[op].src | ITER_SRC;
 
     _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
 					  src_x, src_y, width, height,
@@ -177,13 +177,17 @@ general_composite_rect  (pixman_implementation_t *imp,
         PIXMAN_FORMAT_RGB (mask_image->bits.format);
 
     _pixman_implementation_src_iter_init (
-	imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
-	mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB), info->mask_flags);
+	imp->toplevel, &mask_iter,
+	mask_image, mask_x, mask_y, width, height, mask_buffer,
+	ITER_SRC | narrow | (component_alpha? 0 : ITER_IGNORE_RGB),
+	info->mask_flags);
 
     /* dest iter */
     _pixman_implementation_dest_iter_init (
-	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
-	dest_buffer, narrow | op_flags[op].dst, info->dest_flags);
+	imp->toplevel, &dest_iter,
+	dest_image, dest_x, dest_y, width, height, dest_buffer,
+	ITER_DEST | narrow | op_flags[op].dst,
+	info->dest_flags);
 
     compose = _pixman_implementation_lookup_combiner (
 	imp->toplevel, op, component_alpha, narrow);
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 65041b4..ebf55cd 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -921,7 +921,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
 	_pixman_implementation_src_iter_init (
 	    imp, &iter, image, 0, 0, 1, 1,
 	    (uint8_t *)&result,
-	    ITER_NARROW, image->common.flags);
+	    ITER_NARROW | ITER_SRC, image->common.flags);
 	
 	result = *iter.get_scanline (&iter, NULL);
     }
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 6d9c053..9b6353e 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -231,7 +231,13 @@ typedef enum
      */
     ITER_LOCALIZED_ALPHA =	(1 << 1),
     ITER_IGNORE_ALPHA =		(1 << 2),
-    ITER_IGNORE_RGB =		(1 << 3)
+    ITER_IGNORE_RGB =		(1 << 3),
+
+    /* These indicate whether the iterator is for a source
+     * or a destination image
+     */
+    ITER_SRC =			(1 << 4),
+    ITER_DEST =			(1 << 5)
 } iter_flags_t;
 
 struct pixman_iter_t


More information about the xorg-commit mailing list