From b099957887ef69b795d542f8f2980b5a94fb823f Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Wed, 2 Feb 2011 18:14:56 +0200 Subject: [PATCH] Better support for NONE repeat in nearest scaling main loop template Scaling function now gets an extra boolean argument, which is set to TRUE when we are fetching padding pixels for NONE repeat. This allows to make a decision whether to interpret alpha as 0xFF or 0x00 for such pixels when working with formats which don't have alpha channel (for example x8r8g8b8 and r5g6b5). --- pixman/pixman-arm-common.h | 3 ++- pixman/pixman-fast-path.c | 3 ++- pixman/pixman-fast-path.h | 27 ++++++++++++++++----------- pixman/pixman-sse2.c | 6 +++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/pixman/pixman-arm-common.h b/pixman/pixman-arm-common.h index 525a2c4..6043d4e 100644 --- a/pixman/pixman-arm-common.h +++ b/pixman/pixman-arm-common.h @@ -294,7 +294,8 @@ scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \ int32_t w, \ pixman_fixed_t vx, \ pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx) \ + pixman_fixed_t max_vx, \ + pixman_bool_t zero_src) \ { \ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ vx, unit_x);\ diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c index 0cbe375..92f0308 100644 --- a/pixman/pixman-fast-path.c +++ b/pixman/pixman-fast-path.c @@ -1415,7 +1415,8 @@ scaled_nearest_scanline_565_565_SRC (uint16_t * dst, int32_t w, pixman_fixed_t vx, pixman_fixed_t unit_x, - pixman_fixed_t max_vx) + pixman_fixed_t max_vx, + pixman_bool_t fully_transparent_src) { uint16_t tmp1, tmp2, tmp3, tmp4; while ((w -= 4) >= 0) diff --git a/pixman/pixman-fast-path.h b/pixman/pixman-fast-path.h index a71f6f0..d081222 100644 --- a/pixman/pixman-fast-path.h +++ b/pixman/pixman-fast-path.h @@ -143,13 +143,17 @@ scanline_func_name (dst_type_t *dst, \ int32_t w, \ pixman_fixed_t vx, \ pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx) \ + pixman_fixed_t max_vx, \ + pixman_bool_t fully_transparent_src) \ { \ uint32_t d; \ src_type_t s1, s2; \ uint8_t a1, a2; \ int x1, x2; \ \ + if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER && fully_transparent_src) \ + return; \ + \ if (PIXMAN_OP_ ## OP != PIXMAN_OP_SRC && PIXMAN_OP_ ## OP != PIXMAN_OP_OVER) \ abort(); \ \ @@ -348,18 +352,18 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, src = src_first_line + src_stride * y; \ if (left_pad > 0) \ { \ - scanline_func (mask, dst, src, left_pad, 0, 0, 0); \ + scanline_func (mask, dst, src, left_pad, 0, 0, 0, FALSE); \ } \ if (width > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src, width, vx, unit_x, 0); \ + dst + left_pad, src, width, vx, unit_x, 0, FALSE); \ } \ if (right_pad > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad + width), \ dst + left_pad + width, src + src_image->bits.width - 1, \ - right_pad, 0, 0, 0); \ + right_pad, 0, 0, 0, FALSE); \ } \ } \ else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ @@ -367,29 +371,29 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, static const src_type_t zero[1] = { 0 }; \ if (y < 0 || y >= src_image->bits.height) \ { \ - scanline_func (mask, dst, zero, left_pad + width + right_pad, 0, 0, 0); \ + scanline_func (mask, dst, zero, left_pad + width + right_pad, 0, 0, 0, TRUE); \ continue; \ } \ src = src_first_line + src_stride * y; \ if (left_pad > 0) \ { \ - scanline_func (mask, dst, zero, left_pad, 0, 0, 0); \ + scanline_func (mask, dst, zero, left_pad, 0, 0, 0, TRUE); \ } \ if (width > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src, width, vx, unit_x, 0); \ + dst + left_pad, src, width, vx, unit_x, 0, FALSE); \ } \ if (right_pad > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad + width), \ - dst + left_pad + width, zero, right_pad, 0, 0, 0); \ + dst + left_pad + width, zero, right_pad, 0, 0, 0, TRUE); \ } \ } \ else \ { \ src = src_first_line + src_stride * y; \ - scanline_func (mask, dst, src, width, vx, unit_x, max_vx); \ + scanline_func (mask, dst, src, width, vx, unit_x, max_vx, FALSE); \ } \ } \ } @@ -410,9 +414,10 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, int32_t w, \ pixman_fixed_t vx, \ pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx) \ + pixman_fixed_t max_vx, \ + pixman_bool_t fully_transparent_src) \ { \ - scanline_func (dst, src, w, vx, unit_x, max_vx); \ + scanline_func (dst, src, w, vx, unit_x, max_vx, fully_transparent_src); \ } \ FAST_NEAREST_MAINLOOP_INT (scale_func_name, scanline_func##scale_func_name##_wrapper, \ src_type_t, uint8_t, dst_type_t, repeat_mode, FALSE, FALSE) diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c index 91adc05..6c494bc 100644 --- a/pixman/pixman-sse2.c +++ b/pixman/pixman-sse2.c @@ -5800,7 +5800,8 @@ scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, int32_t w, pixman_fixed_t vx, pixman_fixed_t unit_x, - pixman_fixed_t max_vx) + pixman_fixed_t max_vx, + pixman_bool_t fully_transparent_src) { uint32_t s, d; const uint32_t* pm = NULL; @@ -5809,6 +5810,9 @@ scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, __m128i xmm_src_lo, xmm_src_hi; __m128i xmm_alpha_lo, xmm_alpha_hi; + if (fully_transparent_src) + return; + /* Align dst on a 16-byte boundary */ while (w && ((unsigned long)pd & 15)) { -- 2.7.4