[Pixman] [PATCH] bits-image: Turn all the fetchers into iterator getters

Søren Sandmann sandmann at cs.au.dk
Mon Jun 4 02:19:58 PDT 2012


From: Søren Sandmann Pedersen <ssp at redhat.com>

Instead of caching these fetchers in the image structure, and then
have the iterator getter call them from there, simply change them to
be iterator getters themselves.

This avoids an extra indirect function call and lets us get rid of the
get_scanline_32/64 fields in pixman_image_t.
---
 pixman/pixman-bits-image.c |  214 +++++++++++++++++++++++---------------------
 pixman/pixman-private.h    |    4 +-
 2 files changed, 114 insertions(+), 104 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 3ba6739..05eab96 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -42,14 +42,14 @@
  * we  could produce smoother gradients by evaluating them at higher color
  * depth, but that's a project for the future.
  */
-static void
-_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
-                                       int              x,
-                                       int              y,
-                                       int              width,
-                                       uint32_t *       buffer,
-                                       const uint32_t * mask)
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t * iter,
+                                       const uint32_t *mask)
 {
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
+    pixman_iter_get_scanline_t fetch_32 = iter->data;
     uint32_t *mask8 = NULL;
 
     /* Contract the mask image, if one exists, so that the 32-bit fetch
@@ -59,18 +59,20 @@ _pixman_image_get_scanline_generic_64 (pixman_image_t * image,
     {
 	mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
 	if (!mask8)
-	    return;
+	    return buffer;
 
 	pixman_contract (mask8, (uint64_t *)mask, width);
     }
 
     /* Fetch the source image into the first half of buffer. */
-    image->bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
+    fetch_32 (iter, mask8);
 
     /* Expand from 32bpp to 64bpp in place. */
     pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
 
     free (mask8);
+
+    return buffer;
 }
 
 /* Fetch functions */
@@ -160,14 +162,17 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     return bilinear_interpolation (tl, tr, bl, br, distx, disty);
 }
 
-static void
-bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
-					  int              offset,
-					  int              line,
-					  int              width,
-					  uint32_t *       buffer,
-					  const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
+					  const uint32_t *mask)
 {
+
+    pixman_image_t * ima = iter->image;
+    int              offset = iter->x;
+    int              line = iter->y++;
+    int              width = iter->width;
+    uint32_t *       buffer = iter->buffer;
+
     bits_image_t *bits = &ima->bits;
     pixman_fixed_t x_top, x_bottom, x;
     pixman_fixed_t ux_top, ux_bottom, ux;
@@ -189,7 +194,7 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
     v.vector[2] = pixman_fixed_1;
 
     if (!pixman_transform_point_3d (bits->common.transform, &v))
-	return;
+	return iter->buffer;
 
     ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
     x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
@@ -256,7 +261,7 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
     if (top_row == zero && bottom_row == zero)
     {
 	memset (buffer, 0, width * sizeof (uint32_t));
-	return;
+	return iter->buffer;
     }
     else if (bits->format == PIXMAN_x8r8g8b8)
     {
@@ -368,6 +373,8 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
     /* Zero fill to the left of the image */
     while (buffer < end)
 	*buffer++ = 0;
+
+    return iter->buffer;
 }
 
 static force_inline uint32_t
@@ -474,14 +481,16 @@ bits_image_fetch_pixel_filtered (bits_image_t *image,
     return 0;
 }
 
-static void
-bits_image_fetch_affine_no_alpha (pixman_image_t * image,
-				  int              offset,
-				  int              line,
-				  int              width,
-				  uint32_t *       buffer,
+static uint32_t *
+bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
 				  const uint32_t * mask)
 {
+    pixman_image_t *image  = iter->image;
+    int             offset = iter->x;
+    int             line   = iter->y++;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     pixman_fixed_t x, y;
     pixman_fixed_t ux, uy;
     pixman_vector_t v;
@@ -495,7 +504,7 @@ bits_image_fetch_affine_no_alpha (pixman_image_t * image,
     if (image->common.transform)
     {
 	if (!pixman_transform_point_3d (image->common.transform, &v))
-	    return;
+	    return iter->buffer;
 
 	ux = image->common.transform->matrix[0][0];
 	uy = image->common.transform->matrix[1][0];
@@ -520,6 +529,8 @@ bits_image_fetch_affine_no_alpha (pixman_image_t * image,
 	x += ux;
 	y += uy;
     }
+
+    return buffer;
 }
 
 /* General fetcher */
@@ -563,14 +574,16 @@ fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_boun
     return pixel;
 }
 
-static void
-bits_image_fetch_general (pixman_image_t * image,
-			  int              offset,
-			  int              line,
-			  int              width,
-			  uint32_t *       buffer,
-			  const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_general (pixman_iter_t  *iter,
+			  const uint32_t *mask)
 {
+    pixman_image_t *image  = iter->image;
+    int             offset = iter->x;
+    int             line   = iter->y++;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     pixman_fixed_t x, y, w;
     pixman_fixed_t ux, uy, uw;
     pixman_vector_t v;
@@ -584,7 +597,7 @@ bits_image_fetch_general (pixman_image_t * image,
     if (image->common.transform)
     {
 	if (!pixman_transform_point_3d (image->common.transform, &v))
-	    return;
+	    return buffer;
 
 	ux = image->common.transform->matrix[0][0];
 	uy = image->common.transform->matrix[1][0];
@@ -626,6 +639,8 @@ bits_image_fetch_general (pixman_image_t * image,
 	y += uy;
 	w += uw;
     }
+
+    return buffer;
 }
 
 static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -882,35 +897,33 @@ convert_r5g6b5 (const uint8_t *row, int x)
 }
 
 #define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)		\
-    static void								\
-    bits_image_fetch_bilinear_affine_ ## name (pixman_image_t *image,	\
-					       int              offset,	\
-					       int              line,	\
-					       int              width,	\
-					       uint32_t *       buffer,	\
+    static uint32_t *							\
+    bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,	\
 					       const uint32_t * mask)	\
     {									\
-	bits_image_fetch_bilinear_affine (image, offset, line,		\
-					  width, buffer, mask,		\
+	bits_image_fetch_bilinear_affine (iter->image,			\
+					  iter->x, iter->y++,		\
+					  iter->width,			\
+					  iter->buffer, mask,		\
 					  convert_ ## format,		\
 					  PIXMAN_ ## format,		\
 					  repeat_mode);			\
+	return iter->buffer;						\
     }
 
 #define MAKE_NEAREST_FETCHER(name, format, repeat_mode)			\
-    static void								\
-    bits_image_fetch_nearest_affine_ ## name (pixman_image_t *image,	\
-					      int              offset,	\
-					      int              line,	\
-					      int              width,	\
-					      uint32_t *       buffer,	\
+    static uint32_t *							\
+    bits_image_fetch_nearest_affine_ ## name (pixman_iter_t   *iter,	\
 					      const uint32_t * mask)	\
     {									\
-	bits_image_fetch_nearest_affine (image, offset, line,		\
-					 width, buffer, mask,		\
+	bits_image_fetch_nearest_affine (iter->image,			\
+					 iter->x, iter->y++,		\
+					 iter->width,			\
+					 iter->buffer, mask,		\
 					 convert_ ## format,		\
 					 PIXMAN_ ## format,		\
 					 repeat_mode);			\
+	return iter->buffer;						\
     }
 
 #define MAKE_FETCHERS(name, format, repeat_mode)			\
@@ -1059,14 +1072,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
     }
 }
 
-static void
-bits_image_fetch_untransformed_32 (pixman_image_t * image,
-                                   int              x,
-                                   int              y,
-                                   int              width,
-                                   uint32_t *       buffer,
-                                   const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_untransformed_32 (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;
+
     if (image->common.repeat == PIXMAN_REPEAT_NONE)
     {
 	bits_image_fetch_untransformed_repeat_none (
@@ -1077,16 +1092,22 @@ bits_image_fetch_untransformed_32 (pixman_image_t * image,
 	bits_image_fetch_untransformed_repeat_normal (
 	    &image->bits, FALSE, x, y, width, buffer);
     }
+
+    iter->y++;
+    return buffer;
 }
 
-static void
-bits_image_fetch_untransformed_64 (pixman_image_t * image,
-                                   int              x,
-                                   int              y,
-                                   int              width,
-                                   uint32_t *       buffer,
-                                   const uint32_t * unused)
+static uint32_t *
+bits_image_fetch_untransformed_64 (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;
+
     if (image->common.repeat == PIXMAN_REPEAT_NONE)
     {
 	bits_image_fetch_untransformed_repeat_none (
@@ -1097,14 +1118,21 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image,
 	bits_image_fetch_untransformed_repeat_normal (
 	    &image->bits, TRUE, x, y, width, buffer);
     }
+
+    iter->y++;
+    return buffer;
 }
 
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t   *iter,
+				       const uint32_t * mask);
+
 typedef struct
 {
     pixman_format_code_t	format;
     uint32_t			flags;
-    fetch_scanline_t		fetch_32;
-    fetch_scanline_t		fetch_64;
+    pixman_iter_get_scanline_t	get_scanline_32;
+    pixman_iter_get_scanline_t	get_scanline_64;
 } fetcher_info_t;
 
 static const fetcher_info_t fetcher_info[] =
@@ -1206,52 +1234,36 @@ static const fetcher_info_t fetcher_info[] =
 static void
 bits_image_property_changed (pixman_image_t *image)
 {
-    uint32_t flags = image->common.flags;
+    _pixman_bits_image_setup_accessors (&image->bits);
+}
+
+void
+_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
+{
     pixman_format_code_t format = image->common.extended_format_code;
+    uint32_t flags = image->common.flags;
     const fetcher_info_t *info;
 
-    _pixman_bits_image_setup_accessors (&image->bits);
-
-    info = fetcher_info;
-    while (info->format != PIXMAN_null)
+    for (info = fetcher_info; info->format != PIXMAN_null; ++info)
     {
 	if ((info->format == format || info->format == PIXMAN_any)	&&
 	    (info->flags & flags) == info->flags)
 	{
-	    image->bits.get_scanline_32 = info->fetch_32;
-	    image->bits.get_scanline_64 = info->fetch_64;
-	    break;
+	    if (iter->iter_flags & ITER_NARROW)
+	    {
+		iter->get_scanline = info->get_scanline_32;
+	    }
+	    else
+	    {
+		iter->data = info->get_scanline_32;
+		iter->get_scanline = info->get_scanline_64;
+	    }
+	    return;
 	}
-
-	info++;
     }
-}
 
-static uint32_t *
-src_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);
-
-    return iter->buffer;
-}
-
-static uint32_t *
-src_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);
-
-    return iter->buffer;
-}
-
-void
-_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
-{
-    if (iter->iter_flags & ITER_NARROW)
-	iter->get_scanline = src_get_scanline_narrow;
-    else
-	iter->get_scanline = src_get_scanline_wide;
+    /* Just in case we somehow didn't find a scanline function */
+    iter->get_scanline = _pixman_iter_get_scanline_noop;
 }
 
 static uint32_t *
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index f4ca632..7922773 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -154,9 +154,6 @@ struct bits_image
     uint32_t *                 free_me;
     int                        rowstride;  /* in number of uint32_t's */
 
-    fetch_scanline_t           get_scanline_32;
-    fetch_scanline_t           get_scanline_64;
-
     fetch_scanline_t           fetch_scanline_32;
     fetch_pixel_32_t	       fetch_pixel_32;
     store_scanline_t           store_scanline_32;
@@ -226,6 +223,7 @@ struct pixman_iter_t
     pixman_iter_write_back_t	write_back;
 
     /* These fields are scratch data that implementations can use */
+    void *			data;
     uint8_t *			bits;
     int				stride;
 };
-- 
1.7.4



More information about the Pixman mailing list