[Pixman] [PATCH 4/8] Better support for NONE repeat in nearest scaling main loop template

Siarhei Siamashka siarhei.siamashka at gmail.com
Thu Feb 3 18:10:57 PST 2011


From: Siarhei Siamashka <siarhei.siamashka at nokia.com>

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 c4299e0..b628445 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 8b7c5ba..d9ef00e 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))
     {
-- 
1.7.3.4



More information about the Pixman mailing list