From: Søren Sandmann Pedersen <s...@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

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to