fast, ssse3: Simplify logic to fetch lines in the bilinear iterators
authorSøren Sandmann Pedersen <ssp@redhat.com>
Wed, 11 Sep 2013 04:24:23 +0000 (00:24 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Thu, 26 Sep 2013 14:20:43 +0000 (10:20 -0400)
Instead of having logic to swap the lines around when one of them
doesn't match, store the two lines in an array and use the least
significant bit of the y coordinate as the index into that
array. Since the two lines always have different least significant
bits, they will never collide.

The effect is that lines corresponding to even y coordinates are
stored in info->lines[0] and lines corresponding to odd y coordinates
are stored in info->lines[1].

pixman/pixman-fast-path.c
pixman/pixman-ssse3.c

index 5d52b4a..a344444 100644 (file)
@@ -2269,8 +2269,7 @@ typedef struct
 
 typedef struct
 {
-    line_t             line0;
-    line_t             line1;
+    line_t             lines[2];
     pixman_fixed_t     y;
     pixman_fixed_t     x;
     uint64_t           data[1];
@@ -2352,29 +2351,19 @@ fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
     dist_y = pixman_fixed_to_bilinear_weight (info->y);
     dist_y <<= (8 - BILINEAR_INTERPOLATION_BITS);
 
-    line0 = &info->line0;
-    line1 = &info->line1;
+    line0 = &info->lines[y0 & 0x01];
+    line1 = &info->lines[y1 & 0x01];
 
-    if (line0->y != y0 || line1->y != y1)
+    if (line0->y != y0)
     {
-       if (line0->y == y1 || line1->y == y0)
-       {
-           line_t tmp = *line0;
-           *line0 = *line1;
-           *line1 = tmp;
-       }
-
-       if (line0->y != y0)
-       {
-           fetch_horizontal (
-               &iter->image->bits, line0, y0, fx, ux, iter->width);
-       }
+       fetch_horizontal (
+           &iter->image->bits, line0, y0, fx, ux, iter->width);
+    }
 
-       if (line1->y != y1)
-       {
-           fetch_horizontal (
-               &iter->image->bits, line1, y1, fx, ux, iter->width);
-       }
+    if (line1->y != y1)
+    {
+       fetch_horizontal (
+           &iter->image->bits, line1, y1, fx, ux, iter->width);
     }
 
     for (i = 0; i < iter->width; ++i)
@@ -2470,10 +2459,10 @@ fast_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *it
      * because COVER_CLIP_BILINEAR ensures that we will only
      * be asked to fetch lines in the [0, height) interval
      */
-    info->line0.y = -1;
-    info->line0.buffer = &(info->data[0]);
-    info->line1.y = -1;
-    info->line1.buffer = &(info->data[width]);
+    info->lines[0].y = -1;
+    info->lines[0].buffer = &(info->data[0]);
+    info->lines[1].y = -1;
+    info->lines[1].buffer = &(info->data[width]);
 
     iter->get_scanline = fast_fetch_bilinear_cover;
     iter->fini = bilinear_cover_iter_fini;
index 34763e2..680d6b9 100644 (file)
@@ -43,8 +43,7 @@ typedef struct
 
 typedef struct
 {
-    line_t             line0;
-    line_t             line1;
+    line_t             lines[2];
     pixman_fixed_t     y;
     pixman_fixed_t     x;
     uint64_t           data[1];
@@ -172,29 +171,19 @@ ssse3_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
     y0 = pixman_fixed_to_int (info->y);
     y1 = y0 + 1;
 
-    line0 = &info->line0;
-    line1 = &info->line1;
+    line0 = &info->lines[y0 & 0x01];
+    line1 = &info->lines[y1 & 0x01];
 
-    if (line0->y != y0 || line1->y != y1)
+    if (line0->y != y0)
     {
-       if (line0->y == y1 || line1->y == y0)
-       {
-           line_t tmp = *line0;
-           *line0 = *line1;
-           *line1 = tmp;
-       }
-
-       if (line0->y != y0)
-       {
-           ssse3_fetch_horizontal (
-               &iter->image->bits, line0, y0, fx, ux, iter->width);
-       }
+       ssse3_fetch_horizontal (
+           &iter->image->bits, line0, y0, fx, ux, iter->width);
+    }
 
-       if (line1->y != y1)
-       {
-           ssse3_fetch_horizontal (
-               &iter->image->bits, line1, y1, fx, ux, iter->width);
-       }
+    if (line1->y != y1)
+    {
+       ssse3_fetch_horizontal (
+           &iter->image->bits, line1, y1, fx, ux, iter->width);
     }
 
     dist_y = pixman_fixed_to_bilinear_weight (info->y);
@@ -308,10 +297,10 @@ ssse3_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *i
      * because COVER_CLIP_BILINEAR ensures that we will only
      * be asked to fetch lines in the [0, height) interval
      */
-    info->line0.y = -1;
-    info->line0.buffer = ALIGN (&(info->data[0]));
-    info->line1.y = -1;
-    info->line1.buffer = ALIGN (info->line0.buffer + width);
+    info->lines[0].y = -1;
+    info->lines[0].buffer = ALIGN (&(info->data[0]));
+    info->lines[1].y = -1;
+    info->lines[1].buffer = ALIGN (info->lines[0].buffer + width);
 
     iter->get_scanline = ssse3_fetch_bilinear_cover;
     iter->fini = ssse3_bilinear_cover_iter_fini;