[Pixman] [PATCH] fast, ssse3: Simplify logic to fetch lines in the bilinear iterators

Søren Sandmann sandmann at cs.au.dk
Mon Sep 16 14:58:05 PDT 2013


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

Instead of having logic to swap the lines around when one of them
doesn't match, instead 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 clash.

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 |   41 +++++++++++++++--------------------------
 pixman/pixman-ssse3.c     |   41 +++++++++++++++--------------------------
 2 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 5d52b4a..a344444 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -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;
diff --git a/pixman/pixman-ssse3.c b/pixman/pixman-ssse3.c
index 34763e2..680d6b9 100644
--- a/pixman/pixman-ssse3.c
+++ b/pixman/pixman-ssse3.c
@@ -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;
-- 
1.7.1



More information about the Pixman mailing list