[Pixman] [PATCH 3/7] Split bits_image_fetch_transformed() into two functions.

Søren Sandmann sandmann at daimi.au.dk
Thu Jul 29 07:12:44 PDT 2010


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

One function deals with the common affine, no-alpha-map case. The
other deals with perspective transformations and alpha maps.
---
 pixman/pixman-bits-image.c |  222 +++++++++++++++++++++++++-------------------
 1 files changed, 128 insertions(+), 94 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 0372217..09b69df 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -95,48 +95,9 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 
 /* Fetch functions */
 
-static uint32_t
-fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
-{
-    uint32_t pixel;
-
-    if (check_bounds &&
-	(x < 0 || x >= image->width || y < 0 || y >= image->height))
-    {
-	return 0;
-    }
-
-    pixel = image->fetch_pixel_raw_32 (image, x, y);
-
-    if (image->common.alpha_map)
-    {
-	uint32_t pixel_a;
-
-	x -= image->common.alpha_origin_x;
-	y -= image->common.alpha_origin_y;
-
-	if (x < 0 || x >= image->common.alpha_map->width ||
-	    y < 0 || y >= image->common.alpha_map->height)
-	{
-	    pixel_a = 0;
-	}
-	else
-	{
-	    pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
-		image->common.alpha_map, x, y);
-
-	    pixel_a = ALPHA_8 (pixel_a);
-	}
-
-	pixel &= 0x00ffffff;
-	pixel |= (pixel_a << 24);
-    }
-
-    return pixel;
-}
-
 static force_inline uint32_t
-fetch_pixel_no_alpha (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
+fetch_pixel_no_alpha (bits_image_t *image,
+		      int x, int y, pixman_bool_t check_bounds)
 {
     if (check_bounds &&
 	(x < 0 || x >= image->width || y < 0 || y >= image->height))
@@ -654,12 +615,101 @@ bits_image_fetch_pixel_filtered (bits_image_t *image,
 }
 
 static void
-bits_image_fetch_transformed (pixman_image_t * image,
-                              int              offset,
-                              int              line,
-                              int              width,
-                              uint32_t *       buffer,
-                              const uint32_t * mask)
+bits_image_fetch_affine_no_alpha (pixman_image_t * image,
+				  int              offset,
+				  int              line,
+				  int              width,
+				  uint32_t *       buffer,
+				  const uint32_t * mask)
+{
+    pixman_fixed_t x, y;
+    pixman_fixed_t ux, uy;
+    pixman_vector_t v;
+    int i;
+
+    /* reference point is the center of the pixel */
+    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+    v.vector[2] = pixman_fixed_1;
+
+    if (image->common.transform)
+    {
+	if (!pixman_transform_point_3d (image->common.transform, &v))
+	    return;
+
+	ux = image->common.transform->matrix[0][0];
+	uy = image->common.transform->matrix[1][0];
+    }
+    else
+    {
+	ux = pixman_fixed_1;
+	uy = 0;
+    }
+
+    x = v.vector[0];
+    y = v.vector[1];
+
+    for (i = 0; i < width; ++i)
+    {
+	if (!mask || mask[i])
+	{
+	    buffer[i] = bits_image_fetch_pixel_filtered (
+		&image->bits, x, y, fetch_pixel_no_alpha);
+	}
+	
+	x += ux;
+	y += uy;
+    }
+}
+
+/* General fetcher */
+static force_inline uint32_t
+fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
+{
+    uint32_t pixel;
+
+    if (check_bounds &&
+	(x < 0 || x >= image->width || y < 0 || y >= image->height))
+    {
+	return 0;
+    }
+
+    pixel = image->fetch_pixel_raw_32 (image, x, y);
+
+    if (image->common.alpha_map)
+    {
+	uint32_t pixel_a;
+
+	x -= image->common.alpha_origin_x;
+	y -= image->common.alpha_origin_y;
+
+	if (x < 0 || x >= image->common.alpha_map->width ||
+	    y < 0 || y >= image->common.alpha_map->height)
+	{
+	    pixel_a = 0;
+	}
+	else
+	{
+	    pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
+		image->common.alpha_map, x, y);
+
+	    pixel_a = ALPHA_8 (pixel_a);
+	}
+
+	pixel &= 0x00ffffff;
+	pixel |= (pixel_a << 24);
+    }
+
+    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)
 {
     pixman_fixed_t x, y, w;
     pixman_fixed_t ux, uy, uw;
@@ -671,8 +721,6 @@ bits_image_fetch_transformed (pixman_image_t * image,
     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
-    /* when using convolution filters or PIXMAN_REPEAT_PAD one
-     * might get here without a transform */
     if (image->common.transform)
     {
 	if (!pixman_transform_point_3d (image->common.transform, &v))
@@ -693,47 +741,30 @@ bits_image_fetch_transformed (pixman_image_t * image,
     y = v.vector[1];
     w = v.vector[2];
 
-    if (w == pixman_fixed_1 && uw == 0) /* Affine */
+    for (i = 0; i < width; ++i)
     {
-	for (i = 0; i < width; ++i)
+	pixman_fixed_t x0, y0;
+
+	if (!mask || mask[i])
 	{
-	    if (!mask || mask[i])
+	    if (w != 0)
 	    {
-		buffer[i] =
-		    bits_image_fetch_pixel_filtered (&image->bits, x, y, fetch_pixel_general);
+		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
+		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
 	    }
-
-	    x += ux;
-	    y += uy;
-	}
-    }
-    else
-    {
-	for (i = 0; i < width; ++i)
-	{
-	    if (!mask || mask[i])
+	    else
 	    {
-		pixman_fixed_t x0, y0;
-
-		if (w != 0)
-		{
-		    x0 = ((pixman_fixed_48_16_t)x << 16) / w;
-		    y0 = ((pixman_fixed_48_16_t)y << 16) / w;
-		}
-		else
-		{
-		    x0 = 0;
-		    y0 = 0;
-		}
-
-		buffer[i] =
-		    bits_image_fetch_pixel_filtered (&image->bits, x0, y0, fetch_pixel_general);
+		x0 = 0;
+		y0 = 0;
 	    }
 
-	    x += ux;
-	    y += uy;
-	    w += uw;
+	    buffer[i] = bits_image_fetch_pixel_filtered (
+		&image->bits, x0, y0, fetch_pixel_general);
 	}
+
+	x += ux;
+	y += uy;
+	w += uw;
     }
 }
 
@@ -903,10 +934,8 @@ bits_image_property_changed (pixman_image_t *image)
 
     if (bits->common.alpha_map)
     {
-	image->common.get_scanline_64 =
-	    _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 =
-	    bits_image_fetch_transformed;
+	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
+	image->common.get_scanline_32 = bits_image_fetch_general;
     }
     else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
              bits->width == 1 &&
@@ -937,17 +966,22 @@ bits_image_property_changed (pixman_image_t *image)
 	     (bits->format == PIXMAN_a8r8g8b8	||
 	      bits->format == PIXMAN_x8r8g8b8))
     {
-	image->common.get_scanline_64 =
-	    _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 =
-	    bits_image_fetch_bilinear_no_repeat_8888;
+	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
+	image->common.get_scanline_32 = bits_image_fetch_bilinear_no_repeat_8888;
+    }
+    else if (bits->common.transform					&&
+	     bits->common.transform->matrix[2][0] == 0			&&
+	     bits->common.transform->matrix[2][1] == 0			&&
+	     bits->common.transform->matrix[2][2] == pixman_fixed_1)
+	     
+    {
+	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
+	image->common.get_scanline_32 = bits_image_fetch_affine_no_alpha;
     }
     else
     {
-	image->common.get_scanline_64 =
-	    _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 =
-	    bits_image_fetch_transformed;
+	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
+	image->common.get_scanline_32 = bits_image_fetch_general;
     }
 
     bits->store_scanline_64 = bits_image_store_scanline_64;
-- 
1.7.1.1



More information about the Pixman mailing list