[Pixman] [PATCH 2/3] Add a pair of fast-paths for lerp

Chris Wilson chris at chris-wilson.co.uk
Wed Sep 14 08:06:45 PDT 2011


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 pixman/pixman-fast-path.c |   96 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index bbdc8e8..a0f4d34 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -261,6 +261,98 @@ fast_composite_in_8_8 (pixman_implementation_t *imp,
     }
 }
 
+static force_inline uint32_t
+lerp (uint32_t src,
+      uint8_t a,
+      uint32_t dest)
+{
+    uint8_t ia = ~a;
+    UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (dest, ia, src, a);
+    return dest;
+}
+
+static void
+fast_composite_lerp_src_n_8_8888 (pixman_implementation_t *imp,
+				  pixman_composite_info_t *info)
+{
+    PIXMAN_COMPOSITE_ARGS (info);
+    uint32_t src;
+    uint32_t    *dst_line, *dst;
+    uint8_t     *mask_line, *mask, m;
+    int dst_stride, mask_stride;
+    int32_t w;
+
+    src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
+
+    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+    PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
+
+    while (height--)
+    {
+	dst = dst_line;
+	dst_line += dst_stride;
+	mask = mask_line;
+	mask_line += mask_stride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		*dst = src;
+	    }
+	    else if (m)
+	    {
+		*dst = lerp (src, m, *dst);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fast_composite_lerp_src_8888_8_8888 (pixman_implementation_t *imp,
+				     pixman_composite_info_t *info)
+{
+    PIXMAN_COMPOSITE_ARGS (info);
+    uint32_t    *src_line, *src;
+    uint32_t    *dst_line, *dst;
+    uint8_t     *mask_line, *mask, m;
+    int dst_stride, src_stride,mask_stride;
+    int32_t w;
+
+    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+    PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
+    PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
+
+    while (height--)
+    {
+	dst = dst_line;
+	dst_line += dst_stride;
+	mask = mask_line;
+	mask_line += mask_stride;
+	src = src_line;
+	src_line += src_stride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		*dst = *src;
+	    }
+	    else if (m)
+	    {
+		*dst = lerp (*src, m, *dst);
+	    }
+	    src++;
+	    dst++;
+	}
+    }
+}
+
 static void
 fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
                               pixman_composite_info_t *info)
@@ -1703,6 +1795,10 @@ static const pixman_fast_path_t c_fast_paths[] =
     PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565),
     PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565),
     PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, fast_composite_src_x888_0565),
+
+    PIXMAN_STD_FAST_PATH (LERP_SRC, solid, a8, a8r8g8b8, fast_composite_lerp_src_n_8_8888),
+    PIXMAN_STD_FAST_PATH (LERP_SRC, a8r8g8b8, a8, a8r8g8b8, fast_composite_lerp_src_8888_8_8888),
+
     PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8),
     PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8),
 
-- 
1.7.5.4



More information about the Pixman mailing list