We can easily support REPEAT_NORMAL by adding stitching method
to ARM std fast path macro templates. So the templates now can
support SAMPLES_COVER_CLIP and NORMAL_REPEAT fast path flags.
Currently we have to ditinguish between these two cases at
runtime. Flags or somethings can be added later to do compile
time code branching just like bilinear macros do.
---
 pixman/pixman-arm-common.h |  229 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 204 insertions(+), 25 deletions(-)

diff --git a/pixman/pixman-arm-common.h b/pixman/pixman-arm-common.h
index f1d212c..9e971d0 100644
--- a/pixman/pixman-arm-common.h
+++ b/pixman/pixman-arm-common.h
@@ -50,6 +50,15 @@
 #define SKIP_ZERO_SRC  1
 #define SKIP_ZERO_MASK 2
 
+#define REPEAT_NORMAL(c, size)  \
+    do                          \
+    {                           \
+        while ((c) >= (size))   \
+            (c) -= (size);      \
+        while ((c) < 0)         \
+            (c) += (size);      \
+    } while(0)
+
 #define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name,                \
                                           src_type, src_cnt,            \
                                           dst_type, dst_cnt)            \
@@ -70,14 +79,60 @@ cputype##_composite_##name (pixman_implementation_t *imp,               \
     src_type *src_line;                                                 \
     int32_t dst_stride, src_stride;                                     \
                                                                         \
-    PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
-                           src_stride, src_line, src_cnt);              \
-    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,        \
-                           dst_stride, dst_line, dst_cnt);              \
+     /* SAMPLES_COVER_CLIP case */                                      \
+    if (((src_x >= 0 && (src_x + width) <= src_image->bits.width) &&    \
+          src_y >= 0 && (src_y + height) <= src_image->bits.height))    \
+    {                                                                   \
+        PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,       \
+                               src_stride, src_line, src_cnt);          \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_line, dst_cnt);          \
                                                                         \
-    pixman_composite_##name##_asm_##cputype (width, height,             \
-                                             dst_line, dst_stride,      \
-                                             src_line, src_stride);     \
+        pixman_composite_##name##_asm_##cputype (width, height,         \
+                                                 dst_line, dst_stride,  \
+                                                 src_line, src_stride); \
+    }                                                                   \
+    else if (src_image->common.repeat == PIXMAN_REPEAT_NORMAL )         \
+    {                                                                   \
+        int32_t     y = src_y;                                          \
+        int32_t     width_remain;                                       \
+        int32_t     num_pixels;                                         \
+        int32_t     x;                                                  \
+        dst_type *  dst_start_line;                                     \
+                                                                        \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_start_line, dst_cnt);    \
+                                                                        \
+        while (--height >= 0)                                           \
+        {                                                               \
+            REPEAT_NORMAL (y, src_image->bits.height);                  \
+            width_remain = width;                                       \
+            dst_line = dst_start_line;                                  \
+            PIXMAN_IMAGE_GET_LINE (src_image, 0, y, src_type,           \
+                                   src_stride, src_line, src_cnt);      \
+            x = src_x;                                                  \
+            REPEAT_NORMAL (x, src_image->bits.width);                   \
+                                                                        \
+            while (width_remain > 0)                                    \
+            {                                                           \
+                num_pixels = src_image->bits.width - x;                 \
+                                                                        \
+                if (num_pixels > width_remain)                          \
+                    num_pixels = width_remain;                          \
+                                                                        \
+                pixman_composite_##name##_asm_##cputype                 \
+                                           (num_pixels, 1, dst_line, 0, \
+                                            src_line + x, 0);           \
+                                                                        \
+                width_remain -= num_pixels;                             \
+                x = 0;                                                  \
+                dst_line += num_pixels;                                 \
+            }                                                           \
+                                                                        \
+            y++;                                                        \
+            dst_start_line += dst_stride;                               \
+        }                                                               \
+    }                                                                   \
 }
 
 #define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name,           \
@@ -180,15 +235,61 @@ cputype##_composite_##name (pixman_implementation_t *imp,               \
     if ((flags & SKIP_ZERO_MASK) && mask == 0)                          \
 	return;                                                         \
                                                                         \
-    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,        \
-                           dst_stride, dst_line, dst_cnt);              \
-    PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
-                           src_stride, src_line, src_cnt);              \
+    /* SAMPLES_COVER_CLIP case */                                       \
+    if (src_x >= 0 && (src_x + width) <= src_image->bits.width &&       \
+        src_y >= 0 && (src_y + height) <= src_image->bits.height)       \
+    {                                                                   \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_line, dst_cnt);          \
+        PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,       \
+                               src_stride, src_line, src_cnt);          \
                                                                         \
-    pixman_composite_##name##_asm_##cputype (width, height,             \
-                                             dst_line, dst_stride,      \
-                                             src_line, src_stride,      \
-                                             mask);                     \
+        pixman_composite_##name##_asm_##cputype (width, height,         \
+                                                 dst_line, dst_stride,  \
+                                                 src_line, src_stride,  \
+                                                 mask);                 \
+    }                                                                   \
+    else if (src_image->common.repeat == PIXMAN_REPEAT_NORMAL)          \
+    {                                                                   \
+        int32_t     y = src_y;                                          \
+        int32_t     width_remain;                                       \
+        int32_t     num_pixels;                                         \
+        int32_t     x;                                                  \
+        dst_type    *dst_start_line;                                    \
+                                                                        \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_start_line, dst_cnt);    \
+                                                                        \
+        while (--height >= 0)                                           \
+        {                                                               \
+            REPEAT_NORMAL (y, src_image->bits.height);                  \
+            width_remain = width;                                       \
+            dst_line = dst_start_line;                                  \
+            PIXMAN_IMAGE_GET_LINE (src_image, 0, y, src_type,           \
+                                   src_stride, src_line, src_cnt);      \
+            x = src_x;                                                  \
+            REPEAT_NORMAL (x, src_image->bits.width);                   \
+                                                                        \
+            while (width_remain > 0)                                    \
+            {                                                           \
+                num_pixels = src_image->bits.width - x;                 \
+                                                                        \
+                if (num_pixels > width_remain)                          \
+                    num_pixels = width_remain;                          \
+                                                                        \
+                pixman_composite_##name##_asm_##cputype                 \
+                                     (num_pixels, 1, dst_line, 0,       \
+                                      src_line + x, 0, mask);           \
+                                                                        \
+                width_remain -= num_pixels;                             \
+                x = 0;                                                  \
+                dst_line += num_pixels;                                 \
+            }                                                           \
+                                                                        \
+            y++;                                                        \
+            dst_start_line += dst_stride;                               \
+        }                                                               \
+    }                                                                   \
 }
 
 #define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name,           \
@@ -215,19 +316,97 @@ cputype##_composite_##name (pixman_implementation_t *imp,               \
     mask_type *mask_line;                                               \
     int32_t    dst_stride, src_stride, mask_stride;                     \
                                                                         \
-    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,        \
-                           dst_stride, dst_line, dst_cnt);              \
-    PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
-                           src_stride, src_line, src_cnt);              \
-    PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,       \
-                           mask_stride, mask_line, mask_cnt);           \
+    /* SAMPLES_COVER_CLIP case */                                       \
+    if (((src_x >= 0 && (src_x + width) <= src_image->bits.width) &&    \
+          src_y >= 0 && (src_y + height) <= src_image->bits.height))    \
+    {                                                                   \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_line, dst_cnt);          \
+        PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,       \
+                               src_stride, src_line, src_cnt);          \
+        PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,   \
+                               mask_stride, mask_line, mask_cnt);       \
                                                                         \
-    pixman_composite_##name##_asm_##cputype (width, height,             \
-                                             dst_line, dst_stride,      \
-                                             src_line, src_stride,      \
-                                             mask_line, mask_stride);   \
+        pixman_composite_##name##_asm_##cputype (width, height,         \
+                                                 dst_line, dst_stride,  \
+                                                 src_line, src_stride,  \
+                                                 mask_line, mask_stride);\
+    }                                                                   \
+    else if (src_image->common.repeat == PIXMAN_REPEAT_NORMAL )         \
+    {                                                                   \
+        int32_t     y = src_y;                                          \
+        int32_t     width_remain;                                       \
+        int32_t     num_pixels;                                         \
+        int32_t     x;                                                  \
+        dst_type    *dst_start_line;                                    \
+        mask_type   *mask_start_line;                                   \
+                                                                        \
+        PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type,    \
+                               dst_stride, dst_start_line, dst_cnt);    \
+        PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,   \
+                               mask_stride, mask_start_line, mask_cnt); \
+                                                                        \
+        while (--height >= 0)                                           \
+        {                                                               \
+            REPEAT_NORMAL (y, src_image->bits.height);                  \
+            width_remain = width;                                       \
+            dst_line = dst_start_line;                                  \
+            mask_line = mask_start_line;                                \
+            PIXMAN_IMAGE_GET_LINE (src_image, 0, y, src_type,           \
+                                   src_stride, src_line, src_cnt);      \
+            x = src_x;                                                  \
+            REPEAT_NORMAL (x, src_image->bits.width);                   \
+                                                                        \
+            while (width_remain > 0)                                    \
+            {                                                           \
+                num_pixels = src_image->bits.width - x;                 \
+                                                                        \
+                if (num_pixels > width_remain)                          \
+                    num_pixels = width_remain;                          \
+                                                                        \
+                pixman_composite_##name##_asm_##cputype                 \
+                                          (num_pixels, 1, dst_line, 0,  \
+                                           src_line + x, 0,             \
+                                           mask_line, 0);               \
+                                                                        \
+                width_remain -= num_pixels;                             \
+                x = 0;                                                  \
+                dst_line += num_pixels;                                 \
+                mask_line += num_pixels;                                \
+            }                                                           \
+                                                                        \
+            y++;                                                        \
+            dst_start_line += dst_stride;                               \
+            mask_start_line += mask_stride;                             \
+        }                                                               \
+    }                                                                   \
 }
 
+/* STD fast path entries for ARM.
+ * REPEAT_NORMAL is added.
+ */
+#define PIXMAN_ARM_FAST_PATH(op, src, mask, dest, func)                 \
+    PIXMAN_STD_FAST_PATH (op, src, mask, dest, func),                   \
+    { FAST_PATH (                                                       \
+            op,                                                         \
+            src,  (FAST_PATH_STANDARD_FLAGS   |                         \
+                   FAST_PATH_ID_TRANSFORM     |                         \
+                   FAST_PATH_NORMAL_REPEAT),                            \
+            mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA),           \
+            dest, FAST_PATH_STD_DEST_FLAGS,                             \
+            func) }
+
+#define PIXMAN_ARM_FAST_PATH_CA(op, src, mask, dest, func)              \
+    PIXMAN_STD_FAST_PATH_CA (op, src, mask, dest, func),                \
+    { FAST_PATH (                                                       \
+            op,                                                         \
+            src,  (FAST_PATH_STANDARD_FLAGS   |                         \
+                   FAST_PATH_ID_TRANSFORM     |                         \
+                   FAST_PATH_NORMAL_REPEAT),                            \
+            mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA),         \
+            dest, FAST_PATH_STD_DEST_FLAGS,                             \
+            func) }
+
 #define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op,             \
                                                src_type, dst_type)            \
 void                                                                          \
_______________________________________________
Pixman mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to