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
