From 8d465c2a5d62affc8bdc54980f7c1de9355d1fd5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Wed, 11 Sep 2013 00:24:23 -0400 Subject: [PATCH] fast, ssse3: Simplify logic to fetch lines in the bilinear iterators 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 | 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; -- 2.7.4