diff options
author | marha <marha@users.sourceforge.net> | 2012-09-27 15:15:06 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-09-27 15:15:06 +0200 |
commit | 24703f26d8ed55b1971aa2e94d33636e871bff0b (patch) | |
tree | 3e57b600f4446a1db1d8e73cb8a83519570eb678 /pixman | |
parent | 94ef26cb962261d0b47daf7ef3c856510999bd4c (diff) | |
parent | 2cf1e3de4759264eac2fa8ac758ea750636542f8 (diff) | |
download | vcxsrv-24703f26d8ed55b1971aa2e94d33636e871bff0b.tar.gz vcxsrv-24703f26d8ed55b1971aa2e94d33636e871bff0b.tar.bz2 vcxsrv-24703f26d8ed55b1971aa2e94d33636e871bff0b.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
mesa xserver pixman xkeyboard-config git update 27 sep 2012
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/pixman/pixman-arm-common.h | 24 | ||||
-rw-r--r-- | pixman/pixman/pixman-arm-neon-asm.h | 45 | ||||
-rw-r--r-- | pixman/pixman/pixman-arm-simd-asm.S | 47 | ||||
-rw-r--r-- | pixman/pixman/pixman-combine.c.template | 42 | ||||
-rw-r--r-- | pixman/pixman/pixman-fast-path.c | 14 | ||||
-rw-r--r-- | pixman/pixman/pixman-image.c | 4 | ||||
-rw-r--r-- | pixman/pixman/pixman-inlines.h | 61 | ||||
-rw-r--r-- | pixman/pixman/pixman-mips-dspr2-asm.S | 460 | ||||
-rw-r--r-- | pixman/pixman/pixman-mips-dspr2.c | 56 | ||||
-rw-r--r-- | pixman/pixman/pixman-mips-dspr2.h | 83 | ||||
-rw-r--r-- | pixman/pixman/pixman-sse2.c | 68 | ||||
-rw-r--r-- | pixman/test/Makefile.sources | 2 | ||||
-rw-r--r-- | pixman/test/affine-test.c | 16 | ||||
-rw-r--r-- | pixman/test/blitters-test.c | 2 | ||||
-rw-r--r-- | pixman/test/infinite-loop.c | 39 | ||||
-rw-r--r-- | pixman/test/rotate-test.c | 111 |
16 files changed, 947 insertions, 127 deletions
diff --git a/pixman/pixman/pixman-arm-common.h b/pixman/pixman/pixman-arm-common.h index f56264e8c..3a7cb2bef 100644 --- a/pixman/pixman/pixman-arm-common.h +++ b/pixman/pixman/pixman-arm-common.h @@ -236,7 +236,8 @@ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \ dst_type * dst, \ const src_type * src, \ pixman_fixed_t vx, \ - pixman_fixed_t unit_x); \ + pixman_fixed_t unit_x, \ + pixman_fixed_t max_vx); \ \ static force_inline void \ scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \ @@ -248,7 +249,8 @@ scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \ pixman_bool_t zero_src) \ { \ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ - vx, unit_x);\ + vx, unit_x, \ + max_vx); \ } \ \ FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \ @@ -259,13 +261,17 @@ FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \ src_type, dst_type, NONE) \ FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \ scaled_nearest_scanline_##cputype##_##name##_##op, \ - src_type, dst_type, PAD) + src_type, dst_type, PAD) \ +FAST_NEAREST_MAINLOOP (cputype##_##name##_normal_##op, \ + scaled_nearest_scanline_##cputype##_##name##_##op, \ + src_type, dst_type, NORMAL) /* Provide entries for the fast path table */ #define PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \ SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func) + SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func), \ + SIMPLE_NEAREST_FAST_PATH_NORMAL (op,s,d,func) #define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST(flags, cputype, name, op, \ src_type, dst_type) \ @@ -276,6 +282,7 @@ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \ const src_type * src, \ pixman_fixed_t vx, \ pixman_fixed_t unit_x, \ + pixman_fixed_t max_vx, \ const uint8_t * mask); \ \ static force_inline void \ @@ -292,6 +299,7 @@ scaled_nearest_scanline_##cputype##_##name##_##op (const uint8_t * mask, \ return; \ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ vx, unit_x, \ + max_vx, \ mask); \ } \ \ @@ -303,13 +311,17 @@ FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_none_##op, \ src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \ FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \ scaled_nearest_scanline_##cputype##_##name##_##op,\ - src_type, uint8_t, dst_type, PAD, TRUE, FALSE) + src_type, uint8_t, dst_type, PAD, TRUE, FALSE) \ +FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \ + scaled_nearest_scanline_##cputype##_##name##_##op,\ + src_type, uint8_t, dst_type, NORMAL, TRUE, FALSE) /* Provide entries for the fast path table */ #define PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \ SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func), \ SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func) + SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func), \ + SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL (op,s,d,func) /*****************************************************************************/ diff --git a/pixman/pixman/pixman-arm-neon-asm.h b/pixman/pixman/pixman-arm-neon-asm.h index 97adc6a87..1673b080f 100644 --- a/pixman/pixman/pixman-arm-neon-asm.h +++ b/pixman/pixman/pixman-arm-neon-asm.h @@ -212,27 +212,39 @@ .macro pixld1_s elem_size, reg1, mem_operand .if elem_size == 16 mov TMP1, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP1, mem_operand, TMP1, asl #1 mov TMP2, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP2, mem_operand, TMP2, asl #1 vld1.16 {d®1&[0]}, [TMP1, :16] mov TMP1, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP1, mem_operand, TMP1, asl #1 vld1.16 {d®1&[1]}, [TMP2, :16] mov TMP2, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP2, mem_operand, TMP2, asl #1 vld1.16 {d®1&[2]}, [TMP1, :16] vld1.16 {d®1&[3]}, [TMP2, :16] .elseif elem_size == 32 mov TMP1, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP1, mem_operand, TMP1, asl #2 mov TMP2, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP2, mem_operand, TMP2, asl #2 vld1.32 {d®1&[0]}, [TMP1, :32] vld1.32 {d®1&[1]}, [TMP2, :32] @@ -242,7 +254,7 @@ .endm .macro pixld2_s elem_size, reg1, reg2, mem_operand -.if elem_size == 32 +.if 0 /* elem_size == 32 */ mov TMP1, VX, asr #16 add VX, VX, UNIT_X, asl #1 add TMP1, mem_operand, TMP1, asl #2 @@ -268,12 +280,16 @@ .macro pixld0_s elem_size, reg1, idx, mem_operand .if elem_size == 16 mov TMP1, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP1, mem_operand, TMP1, asl #1 vld1.16 {d®1&[idx]}, [TMP1, :16] .elseif elem_size == 32 mov TMP1, VX, asr #16 - add VX, VX, UNIT_X + adds VX, VX, UNIT_X +5: subpls VX, VX, SRC_WIDTH_FIXED + bpl 5b add TMP1, mem_operand, TMP1, asl #2 vld1.32 {d®1&[idx]}, [TMP1, :32] .endif @@ -964,15 +980,17 @@ fname: TMP1 .req r4 TMP2 .req r5 DST_R .req r6 + SRC_WIDTH_FIXED .req r7 .macro pixld_src x:vararg pixld_s x .endm ldr UNIT_X, [sp] - push {r4-r6, lr} + push {r4-r8, lr} + ldr SRC_WIDTH_FIXED, [sp, #(24 + 4)] .if mask_bpp != 0 - ldr MASK, [sp, #(16 + 4)] + ldr MASK, [sp, #(24 + 8)] .endif .else /* @@ -1044,7 +1062,7 @@ fname: cleanup .if use_nearest_scaling != 0 - pop {r4-r6, pc} /* exit */ + pop {r4-r8, pc} /* exit */ .else bx lr /* exit */ .endif @@ -1058,7 +1076,7 @@ fname: cleanup .if use_nearest_scaling != 0 - pop {r4-r6, pc} /* exit */ + pop {r4-r8, pc} /* exit */ .unreq DST_R .unreq SRC @@ -1069,6 +1087,7 @@ fname: .unreq TMP2 .unreq DST_W .unreq MASK + .unreq SRC_WIDTH_FIXED .else bx lr /* exit */ diff --git a/pixman/pixman/pixman-arm-simd-asm.S b/pixman/pixman/pixman-arm-simd-asm.S index 8fe1b5038..b438001d3 100644 --- a/pixman/pixman/pixman-arm-simd-asm.S +++ b/pixman/pixman/pixman-arm-simd-asm.S @@ -355,49 +355,57 @@ pixman_asm_function pixman_composite_over_n_8_8888_asm_armv6 prefetch_braking_distance pixman_asm_function fname - W .req r0 - DST .req r1 - SRC .req r2 - VX .req r3 - UNIT_X .req ip - TMP1 .req r4 - TMP2 .req r5 - VXMASK .req r6 - PF_OFFS .req r7 + W .req r0 + DST .req r1 + SRC .req r2 + VX .req r3 + UNIT_X .req ip + TMP1 .req r4 + TMP2 .req r5 + VXMASK .req r6 + PF_OFFS .req r7 + SRC_WIDTH_FIXED .req r8 ldr UNIT_X, [sp] - push {r4, r5, r6, r7} + push {r4, r5, r6, r7, r8, r10} mvn VXMASK, #((1 << bpp_shift) - 1) + ldr SRC_WIDTH_FIXED, [sp, #28] /* define helper macro */ .macro scale_2_pixels ldr&t TMP1, [SRC, TMP1] - and TMP2, VXMASK, VX, lsr #(16 - bpp_shift) - add VX, VX, UNIT_X + and TMP2, VXMASK, VX, asr #(16 - bpp_shift) + adds VX, VX, UNIT_X str&t TMP1, [DST], #(1 << bpp_shift) +9: subpls VX, VX, SRC_WIDTH_FIXED + bpl 9b ldr&t TMP2, [SRC, TMP2] - and TMP1, VXMASK, VX, lsr #(16 - bpp_shift) - add VX, VX, UNIT_X + and TMP1, VXMASK, VX, asr #(16 - bpp_shift) + adds VX, VX, UNIT_X str&t TMP2, [DST], #(1 << bpp_shift) +9: subpls VX, VX, SRC_WIDTH_FIXED + bpl 9b .endm /* now do the scaling */ - and TMP1, VXMASK, VX, lsr #(16 - bpp_shift) - add VX, VX, UNIT_X + and TMP1, VXMASK, VX, asr #(16 - bpp_shift) + adds VX, VX, UNIT_X +9: subpls VX, VX, SRC_WIDTH_FIXED + bpl 9b subs W, W, #(8 + prefetch_braking_distance) blt 2f /* calculate prefetch offset */ mov PF_OFFS, #prefetch_distance mla PF_OFFS, UNIT_X, PF_OFFS, VX 1: /* main loop, process 8 pixels per iteration with prefetch */ - subs W, W, #8 + pld [SRC, PF_OFFS, asr #(16 - bpp_shift)] add PF_OFFS, UNIT_X, lsl #3 scale_2_pixels scale_2_pixels scale_2_pixels scale_2_pixels - pld [SRC, PF_OFFS, lsr #(16 - bpp_shift)] + subs W, W, #8 bge 1b 2: subs W, W, #(4 - 8 - prefetch_braking_distance) @@ -426,8 +434,9 @@ pixman_asm_function fname .unreq TMP2 .unreq VXMASK .unreq PF_OFFS + .unreq SRC_WIDTH_FIXED /* return */ - pop {r4, r5, r6, r7} + pop {r4, r5, r6, r7, r8, r10} bx lr .endfunc .endm diff --git a/pixman/pixman/pixman-combine.c.template b/pixman/pixman/pixman-combine.c.template index cd008d967..f405312d4 100644 --- a/pixman/pixman/pixman-combine.c.template +++ b/pixman/pixman/pixman-combine.c.template @@ -6,10 +6,9 @@ #include <string.h> #include "pixman-private.h" - #include "pixman-combine.h" -/*** per channel helper functions ***/ +/* component alpha helper functions */ static void combine_mask_ca (comp4_t *src, comp4_t *mask) @@ -91,15 +90,11 @@ combine_mask_alpha_ca (const comp4_t *src, comp4_t *mask) /* * There are two ways of handling alpha -- either as a single unified value or * a separate value for each component, hence each macro must have two - * versions. The unified alpha version has a 'U' at the end of the name, - * the component version has a 'C'. Similarly, functions which deal with + * versions. The unified alpha version has a 'u' at the end of the name, + * the component version has a 'ca'. Similarly, functions which deal with * this difference will have two versions using the same convention. */ -/* - * All of the composing functions - */ - static force_inline comp4_t combine_mask (const comp4_t *src, const comp4_t *mask, int i) { @@ -154,7 +149,9 @@ combine_src_u (pixman_implementation_t *imp, int i; if (!mask) + { memcpy (dest, src, width * sizeof (comp4_t)); + } else { for (i = 0; i < width; ++i) @@ -166,7 +163,6 @@ combine_src_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_src_u */ static void combine_over_u (pixman_implementation_t *imp, pixman_op_t op, @@ -188,7 +184,6 @@ combine_over_u (pixman_implementation_t *imp, } } -/* if the Dst is opaque, this is a noop */ static void combine_over_reverse_u (pixman_implementation_t *imp, pixman_op_t op, @@ -209,7 +204,6 @@ combine_over_reverse_u (pixman_implementation_t *imp, } } -/* if the Dst is opaque, call combine_src_u */ static void combine_in_u (pixman_implementation_t *imp, pixman_op_t op, @@ -229,7 +223,6 @@ combine_in_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, this is a noop */ static void combine_in_reverse_u (pixman_implementation_t *imp, pixman_op_t op, @@ -250,7 +243,6 @@ combine_in_reverse_u (pixman_implementation_t *imp, } } -/* if the Dst is opaque, call combine_clear */ static void combine_out_u (pixman_implementation_t *imp, pixman_op_t op, @@ -270,7 +262,6 @@ combine_out_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_clear */ static void combine_out_reverse_u (pixman_implementation_t *imp, pixman_op_t op, @@ -291,9 +282,6 @@ combine_out_reverse_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_in_u */ -/* if the Dst is opaque, call combine_over_u */ -/* if both the Src and Dst are opaque, call combine_src_u */ static void combine_atop_u (pixman_implementation_t *imp, pixman_op_t op, @@ -316,9 +304,6 @@ combine_atop_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_over_reverse_u */ -/* if the Dst is opaque, call combine_in_reverse_u */ -/* if both the Src and Dst are opaque, call combine_dst_u */ static void combine_atop_reverse_u (pixman_implementation_t *imp, pixman_op_t op, @@ -341,9 +326,6 @@ combine_atop_reverse_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_over_u */ -/* if the Dst is opaque, call combine_over_reverse_u */ -/* if both the Src and Dst are opaque, call combine_clear */ static void combine_xor_u (pixman_implementation_t *imp, pixman_op_t op, @@ -385,9 +367,6 @@ combine_add_u (pixman_implementation_t *imp, } } -/* if the Src is opaque, call combine_add_u */ -/* if the Dst is opaque, call combine_add_u */ -/* if both the Src and Dst are opaque, call combine_add_u */ static void combine_saturate_u (pixman_implementation_t *imp, pixman_op_t op, @@ -444,7 +423,6 @@ combine_saturate_u (pixman_implementation_t *imp, * Multiply * B(Dca, ad, Sca, as) = Dca.Sca */ - static void combine_multiply_u (pixman_implementation_t *imp, pixman_op_t op, @@ -489,7 +467,7 @@ combine_multiply_ca (pixman_implementation_t *imp, comp4_t r = d; comp4_t dest_ia = ALPHA_c (~d); - combine_mask_value_ca (&s, &m); + combine_mask_ca (&s, &m); UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia); UNcx4_MUL_UNcx4 (d, s); @@ -546,7 +524,7 @@ combine_multiply_ca (pixman_implementation_t *imp, comp1_t ida = ~da; \ comp4_t result; \ \ - combine_mask_value_ca (&s, &m); \ + combine_mask_ca (&s, &m); \ \ result = d; \ UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \ @@ -1579,9 +1557,8 @@ combine_conjoint_xor_u (pixman_implementation_t *imp, combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR); } -/************************************************************************/ -/*********************** Per Channel functions **************************/ -/************************************************************************/ + +/* Component alpha combiners */ static void combine_clear_ca (pixman_implementation_t *imp, @@ -2458,4 +2435,3 @@ _pixman_setup_combiner_functions_width (pixman_implementation_t *imp) imp->combine_width_ca[PIXMAN_OP_HSL_COLOR] = combine_dst; imp->combine_width_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst; } - diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index 86ed821d6..22bfd301c 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -1415,13 +1415,13 @@ scaled_nearest_scanline_565_565_SRC (uint16_t * dst, uint16_t tmp1, tmp2, tmp3, tmp4; while ((w -= 4) >= 0) { - tmp1 = src[pixman_fixed_to_int (vx)]; + tmp1 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp2 = src[pixman_fixed_to_int (vx)]; + tmp2 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp3 = src[pixman_fixed_to_int (vx)]; + tmp3 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp4 = src[pixman_fixed_to_int (vx)]; + tmp4 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; *dst++ = tmp1; *dst++ = tmp2; @@ -1430,15 +1430,15 @@ scaled_nearest_scanline_565_565_SRC (uint16_t * dst, } if (w & 2) { - tmp1 = src[pixman_fixed_to_int (vx)]; + tmp1 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp2 = src[pixman_fixed_to_int (vx)]; + tmp2 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; *dst++ = tmp1; *dst++ = tmp2; } if (w & 1) - *dst++ = src[pixman_fixed_to_int (vx)]; + *dst = *(src + pixman_fixed_to_int (vx)); } FAST_NEAREST_MAINLOOP (565_565_cover_SRC, diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 15597bd61..d9c303441 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -301,9 +301,9 @@ compute_image_info (pixman_image_t *image) pixman_fixed_t m01 = image->common.transform->matrix[0][1]; pixman_fixed_t m10 = image->common.transform->matrix[1][0]; - if (m01 == -1 && m10 == 1) + if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1) flags |= FAST_PATH_ROTATE_90_TRANSFORM; - else if (m01 == 1 && m10 == -1) + else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1) flags |= FAST_PATH_ROTATE_270_TRANSFORM; } } diff --git a/pixman/pixman/pixman-inlines.h b/pixman/pixman/pixman-inlines.h index f78bc212f..13f901485 100644 --- a/pixman/pixman/pixman-inlines.h +++ b/pixman/pixman/pixman-inlines.h @@ -271,7 +271,7 @@ 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 src_width_fixed, \ pixman_bool_t fully_transparent_src) \ { \ uint32_t d; \ @@ -287,25 +287,25 @@ scanline_func_name (dst_type_t *dst, \ \ while ((w -= 2) >= 0) \ { \ - x1 = vx >> 16; \ + x1 = pixman_fixed_to_int (vx); \ vx += unit_x; \ if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ { \ /* This works because we know that unit_x is positive */ \ - while (vx >= max_vx) \ - vx -= max_vx; \ + while (vx >= 0) \ + vx -= src_width_fixed; \ } \ - s1 = src[x1]; \ + s1 = *(src + x1); \ \ - x2 = vx >> 16; \ + x2 = pixman_fixed_to_int (vx); \ vx += unit_x; \ if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ { \ /* This works because we know that unit_x is positive */ \ - while (vx >= max_vx) \ - vx -= max_vx; \ + while (vx >= 0) \ + vx -= src_width_fixed; \ } \ - s2 = src[x2]; \ + s2 = *(src + x2); \ \ if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \ { \ @@ -349,8 +349,8 @@ scanline_func_name (dst_type_t *dst, \ \ if (w & 1) \ { \ - x1 = vx >> 16; \ - s1 = src[x1]; \ + x1 = pixman_fixed_to_int (vx); \ + s1 = *(src + x1); \ \ if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \ { \ @@ -388,7 +388,7 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, mask_type_t *mask_line; \ src_type_t *src_first_line; \ int y; \ - pixman_fixed_t max_vx = INT32_MAX; /* suppress uninitialized variable warning */ \ + pixman_fixed_t src_width_fixed = pixman_int_to_fixed (src_image->bits.width); \ pixman_fixed_t max_vy; \ pixman_vector_t v; \ pixman_fixed_t vx, vy; \ @@ -434,11 +434,10 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, \ if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ { \ - /* Clamp repeating positions inside the actual samples */ \ - max_vx = src_image->bits.width << 16; \ - max_vy = src_image->bits.height << 16; \ + max_vy = pixman_int_to_fixed (src_image->bits.height); \ \ - repeat (PIXMAN_REPEAT_NORMAL, &vx, max_vx); \ + /* Clamp repeating positions inside the actual samples */ \ + repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \ } \ \ @@ -460,7 +459,7 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, mask_line += mask_stride; \ } \ \ - y = vy >> 16; \ + y = pixman_fixed_to_int (vy); \ vy += unit_y; \ if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \ @@ -470,18 +469,21 @@ 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, FALSE); \ + scanline_func (mask, dst, \ + src + src_image->bits.width - src_image->bits.width + 1, \ + left_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE); \ } \ if (width > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src, width, vx, unit_x, 0, FALSE); \ + dst + left_pad, src + src_image->bits.width, width, \ + vx - src_width_fixed, unit_x, src_width_fixed, 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, FALSE); \ + dst + left_pad + width, src + src_image->bits.width, \ + right_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE); \ } \ } \ else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ @@ -489,29 +491,34 @@ 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, TRUE); \ + scanline_func (mask, dst, zero + 1, left_pad + width + right_pad, \ + -pixman_fixed_e, 0, src_width_fixed, TRUE); \ continue; \ } \ src = src_first_line + src_stride * y; \ if (left_pad > 0) \ { \ - scanline_func (mask, dst, zero, left_pad, 0, 0, 0, TRUE); \ + scanline_func (mask, dst, zero + 1, left_pad, \ + -pixman_fixed_e, 0, src_width_fixed, TRUE); \ } \ if (width > 0) \ { \ scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src, width, vx, unit_x, 0, FALSE); \ + dst + left_pad, src + src_image->bits.width, width, \ + vx - src_width_fixed, unit_x, src_width_fixed, 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, TRUE); \ + dst + left_pad + width, zero + 1, right_pad, \ + -pixman_fixed_e, 0, src_width_fixed, TRUE); \ } \ } \ else \ { \ src = src_first_line + src_stride * y; \ - scanline_func (mask, dst, src, width, vx, unit_x, max_vx, FALSE); \ + scanline_func (mask, dst, src + src_image->bits.width, width, vx - src_width_fixed, \ + unit_x, src_width_fixed, FALSE); \ } \ } \ } @@ -859,7 +866,7 @@ fast_composite_scaled_bilinear ## scale_func_name (pixman_implementation_t *imp, { \ vx = v.vector[0]; \ repeat (PIXMAN_REPEAT_NORMAL, &vx, pixman_int_to_fixed(src_image->bits.width)); \ - max_x = pixman_fixed_to_int (vx + (width - 1) * unit_x) + 1; \ + max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1; \ \ if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH) \ { \ diff --git a/pixman/pixman/pixman-mips-dspr2-asm.S b/pixman/pixman/pixman-mips-dspr2-asm.S index a8fccd5ad..3a6b26a30 100644 --- a/pixman/pixman/pixman-mips-dspr2-asm.S +++ b/pixman/pixman/pixman-mips-dspr2-asm.S @@ -749,6 +749,466 @@ LEAF_MIPS_DSPR2(pixman_composite_over_n_8_0565_asm_mips) END(pixman_composite_over_n_8_0565_asm_mips) +LEAF_MIPS_DSPR2(pixman_composite_over_8888_n_8888_asm_mips) +/* + * a0 - dst (a8r8g8b8) + * a1 - src (a8r8g8b8) + * a2 - mask (32bit constant) + * a3 - w + */ + + SAVE_REGS_ON_STACK 0, s0 + li t4, 0x00ff00ff + beqz a3, 3f + nop + addiu t1, a3, -1 + srl a2, a2, 24 + beqz t1, 2f + nop + +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + /* a2 = mask (32bit constant) */ + lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ + lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ + addiu a1, a1, 8 + + OVER_2x8888_2x8_2x8888 t0, t1, a2, a2, t2, t3, \ + t5, t6, t4, t7, t8, t9, t0, t1, s0 + + sw t5, 0(a0) + sw t6, 4(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 8 +2: + beqz a3, 3f + nop + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + /* a2 = mask (32bit constant) */ + lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ + + OVER_8888_8_8888 t0, a2, t1, t3, t4, t5, t6, t7, t8 + + sw t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 0, s0 + j ra + nop + +END(pixman_composite_over_8888_n_8888_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_8888_n_0565_asm_mips) +/* + * a0 - dst (r5g6b5) + * a1 - src (a8r8g8b8) + * a2 - mask (32bit constant) + * a3 - w + */ + + SAVE_REGS_ON_STACK 0, s0, s1, s2, s3 + li t6, 0x00ff00ff + li t7, 0xf800f800 + li t8, 0x07e007e0 + li t9, 0x001F001F + beqz a3, 3f + nop + srl a2, a2, 24 + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + /* a2 = mask (32bit constant) */ + lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ + lhu t3, 2(a0) /* t2 = destination (r5g6b5) */ + addiu a1, a1, 8 + + CONVERT_2x0565_TO_2x8888 t2, t3, t4, t5, t8, t9, s0, s1, t2, t3 + OVER_2x8888_2x8_2x8888 t0, t1, a2, a2, t4, t5, \ + t2, t3, t6, t0, t1, s0, s1, s2, s3 + CONVERT_2x8888_TO_2x0565 t2, t3, t4, t5, t7, t8, t9, s0, s1 + + sh t4, 0(a0) + sh t5, 2(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 4 +2: + beqz a3, 3f + nop + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + /* a2 = mask (32bit constant) */ + lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ + + CONVERT_1x0565_TO_1x8888 t1, t2, t4, t5 + OVER_8888_8_8888 t0, a2, t2, t1, t6, t3, t4, t5, t7 + CONVERT_1x8888_TO_1x0565 t1, t3, t4, t5 + + sh t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + j ra + nop + +END(pixman_composite_over_8888_n_0565_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_0565_n_0565_asm_mips) +/* + * a0 - dst (r5g6b5) + * a1 - src (r5g6b5) + * a2 - mask (32bit constant) + * a3 - w + */ + + SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 + li t6, 0x00ff00ff + li t7, 0xf800f800 + li t8, 0x07e007e0 + li t9, 0x001F001F + beqz a3, 3f + nop + srl a2, a2, 24 + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lhu t0, 0(a1) /* t0 = source (r5g6b5) */ + lhu t1, 2(a1) /* t1 = source (r5g6b5) */ + /* a2 = mask (32bit constant) */ + lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ + lhu t3, 2(a0) /* t3 = destination (r5g6b5) */ + addiu a1, a1, 4 + + CONVERT_2x0565_TO_2x8888 t0, t1, t4, t5, t8, t9, s0, s1, s2, s3 + CONVERT_2x0565_TO_2x8888 t2, t3, s0, s1, t8, t9, s2, s3, s4, s5 + OVER_2x8888_2x8_2x8888 t4, t5, a2, a2, s0, s1, \ + t0, t1, t6, s2, s3, s4, s5, t4, t5 + CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t7, t8, t9, s2, s3 + + sh s0, 0(a0) + sh s1, 2(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 4 +2: + beqz a3, 3f + nop + lhu t0, 0(a1) /* t0 = source (r5g6b5) */ + /* a2 = mask (32bit constant) */ + lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ + + CONVERT_1x0565_TO_1x8888 t0, t2, t4, t5 + CONVERT_1x0565_TO_1x8888 t1, t3, t4, t5 + OVER_8888_8_8888 t2, a2, t3, t0, t6, t1, t4, t5, t7 + CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 + + sh t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 + j ra + nop + +END(pixman_composite_over_0565_n_0565_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_8888_8_8888_asm_mips) +/* + * a0 - dst (a8r8g8b8) + * a1 - src (a8r8g8b8) + * a2 - mask (a8) + * a3 - w + */ + + SAVE_REGS_ON_STACK 0, s0, s1 + li t4, 0x00ff00ff + beqz a3, 3f + nop + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + lbu t2, 0(a2) /* t2 = mask (a8) */ + lbu t3, 1(a2) /* t3 = mask (a8) */ + lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ + lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ + addiu a1, a1, 8 + addiu a2, a2, 2 + + OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, t5, t6, \ + t7, t8, t4, t9, s0, s1, t0, t1, t2 + + sw t7, 0(a0) + sw t8, 4(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 8 +2: + beqz a3, 3f + nop + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lbu t1, 0(a2) /* t1 = mask (a8) */ + lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ + + OVER_8888_8_8888 t0, t1, t2, t3, t4, t5, t6, t7, t8 + + sw t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 0, s0, s1 + j ra + nop + +END(pixman_composite_over_8888_8_8888_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_8888_8_0565_asm_mips) +/* + * a0 - dst (r5g6b5) + * a1 - src (a8r8g8b8) + * a2 - mask (a8) + * a3 - w + */ + + SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 + li t6, 0x00ff00ff + li t7, 0xf800f800 + li t8, 0x07e007e0 + li t9, 0x001F001F + beqz a3, 3f + nop + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + lbu t2, 0(a2) /* t2 = mask (a8) */ + lbu t3, 1(a2) /* t3 = mask (a8) */ + lhu t4, 0(a0) /* t4 = destination (r5g6b5) */ + lhu t5, 2(a0) /* t5 = destination (r5g6b5) */ + addiu a1, a1, 8 + addiu a2, a2, 2 + + CONVERT_2x0565_TO_2x8888 t4, t5, s0, s1, t8, t9, s2, s3, s4, s5 + OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, s0, s1, \ + t4, t5, t6, s2, s3, s4, s5, t0, t1 + CONVERT_2x8888_TO_2x0565 t4, t5, s0, s1, t7, t8, t9, s2, s3 + + sh s0, 0(a0) + sh s1, 2(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 4 +2: + beqz a3, 3f + nop + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lbu t1, 0(a2) /* t1 = mask (a8) */ + lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ + + CONVERT_1x0565_TO_1x8888 t2, t3, t4, t5 + OVER_8888_8_8888 t0, t1, t3, t2, t6, t4, t5, t7, t8 + CONVERT_1x8888_TO_1x0565 t2, t3, t4, t5 + + sh t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 + j ra + nop + +END(pixman_composite_over_8888_8_0565_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_0565_8_0565_asm_mips) +/* + * a0 - dst (r5g6b5) + * a1 - src (r5g6b5) + * a2 - mask (a8) + * a3 - w + */ + + SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 + li t4, 0xf800f800 + li t5, 0x07e007e0 + li t6, 0x001F001F + li t7, 0x00ff00ff + beqz a3, 3f + nop + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lhu t0, 0(a1) /* t0 = source (r5g6b5) */ + lhu t1, 2(a1) /* t1 = source (r5g6b5) */ + lbu t2, 0(a2) /* t2 = mask (a8) */ + lbu t3, 1(a2) /* t3 = mask (a8) */ + lhu t8, 0(a0) /* t8 = destination (r5g6b5) */ + lhu t9, 2(a0) /* t9 = destination (r5g6b5) */ + addiu a1, a1, 4 + addiu a2, a2, 2 + + CONVERT_2x0565_TO_2x8888 t0, t1, s0, s1, t5, t6, s2, s3, s4, s5 + CONVERT_2x0565_TO_2x8888 t8, t9, s2, s3, t5, t6, s4, s5, t0, t1 + OVER_2x8888_2x8_2x8888 s0, s1, t2, t3, s2, s3, \ + t0, t1, t7, s4, s5, t8, t9, s0, s1 + CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t4, t5, t6, s2, s3 + + sh s0, 0(a0) + sh s1, 2(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 4 +2: + beqz a3, 3f + nop + lhu t0, 0(a1) /* t0 = source (r5g6b5) */ + lbu t1, 0(a2) /* t1 = mask (a8) */ + lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ + + CONVERT_1x0565_TO_1x8888 t0, t3, t4, t5 + CONVERT_1x0565_TO_1x8888 t2, t4, t5, t6 + OVER_8888_8_8888 t3, t1, t4, t0, t7, t2, t5, t6, t8 + CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 + + sh t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 + j ra + nop + +END(pixman_composite_over_0565_8_0565_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_8888_8888_8888_asm_mips) +/* + * a0 - dst (a8r8g8b8) + * a1 - src (a8r8g8b8) + * a2 - mask (a8r8g8b8) + * a3 - w + */ + + SAVE_REGS_ON_STACK 0, s0, s1, s2 + li t4, 0x00ff00ff + beqz a3, 3f + nop + addiu t1, a3, -1 + beqz t1, 2f + nop +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + lw t2, 0(a2) /* t2 = mask (a8r8g8b8) */ + lw t3, 4(a2) /* t3 = mask (a8r8g8b8) */ + lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ + lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ + addiu a1, a1, 8 + addiu a2, a2, 8 + srl t2, t2, 24 + srl t3, t3, 24 + + OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, t5, t6, t7, t8, t4, t9, s0, s1, s2, t0, t1 + + sw t7, 0(a0) + sw t8, 4(a0) + addiu a3, a3, -2 + addiu t1, a3, -1 + bgtz t1, 1b + addiu a0, a0, 8 +2: + beqz a3, 3f + nop + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 0(a2) /* t1 = mask (a8r8g8b8) */ + lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ + srl t1, t1, 24 + + OVER_8888_8_8888 t0, t1, t2, t3, t4, t5, t6, t7, t8 + + sw t3, 0(a0) +3: + RESTORE_REGS_FROM_STACK 0, s0, s1, s2 + j ra + nop + +END(pixman_composite_over_8888_8888_8888_asm_mips) + +LEAF_MIPS_DSPR2(pixman_composite_over_8888_8888_asm_mips) +/* + * a0 - dst (a8r8g8b8) + * a1 - src (a8r8g8b8) + * a2 - w + */ + + SAVE_REGS_ON_STACK 0, s0, s1, s2 + li t4, 0x00ff00ff + beqz a2, 3f + nop + addiu t1, a2, -1 + beqz t1, 2f + nop +1: + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ + lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ + lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ + addiu a1, a1, 8 + + not t5, t0 + srl t5, t5, 24 + not t6, t1 + srl t6, t6, 24 + + or t7, t5, t6 + beqz t7, 11f + or t8, t0, t1 + beqz t8, 12f + + MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t5, t6, t7, t8, t4, t9, s0, s1, s2, t2, t3 + + addu_s.qb t0, t7, t0 + addu_s.qb t1, t8, t1 +11: + sw t0, 0(a0) + sw t1, 4(a0) +12: + addiu a2, a2, -2 + addiu t1, a2, -1 + bgtz t1, 1b + addiu a0, a0, 8 +2: + beqz a2, 3f + nop + + lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ + lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ + addiu a1, a1, 4 + + not t2, t0 + srl t2, t2, 24 + + beqz t2, 21f + nop + beqz t0, 3f + + MIPS_UN8x4_MUL_UN8 t1, t2, t3, t4, t5, t6, t7 + + addu_s.qb t0, t3, t0 +21: + sw t0, 0(a0) + +3: + RESTORE_REGS_FROM_STACK 0, s0, s1, s2 + j ra + nop + +END(pixman_composite_over_8888_8888_asm_mips) + LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8888_SRC_asm_mips) /* * a0 - *dst diff --git a/pixman/pixman/pixman-mips-dspr2.c b/pixman/pixman/pixman-mips-dspr2.c index 1a9e6103a..e80bbb661 100644 --- a/pixman/pixman/pixman-mips-dspr2.c +++ b/pixman/pixman/pixman-mips-dspr2.c @@ -48,6 +48,8 @@ PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_8888_8888, uint32_t, 1, uint32_t, 1) PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0888_0888, uint8_t, 3, uint8_t, 3) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_8888, + uint32_t, 1, uint32_t, 1) PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_8888_ca, uint32_t, 1, uint32_t, 1) @@ -58,6 +60,22 @@ PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8888, PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_0565, uint8_t, 1, uint16_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_8888, + uint32_t, 1, uint32_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_0565, + uint32_t, 1, uint16_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_0565_n_0565, + uint16_t, 1, uint16_t, 1) + +PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_8888, uint32_t, 1, + uint8_t, 1, uint32_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_0565, uint32_t, 1, + uint8_t, 1, uint16_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_0565_8_0565, uint16_t, 1, + uint8_t, 1, uint16_t, 1) +PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8888_8888, uint32_t, 1, + uint32_t, 1, uint32_t, 1) + PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_8888, SRC, uint32_t, uint32_t) PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_0565, SRC, @@ -234,6 +252,26 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] = PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mips_composite_over_n_8_0565), PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mips_composite_over_n_8_0565), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mips_composite_over_8888_n_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mips_composite_over_8888_n_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, mips_composite_over_8888_n_0565), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, mips_composite_over_8888_n_0565), + PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, mips_composite_over_0565_n_0565), + PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, mips_composite_over_0565_n_0565), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, mips_composite_over_8888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, mips_composite_over_8888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, mips_composite_over_8888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, mips_composite_over_8888_8_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, mips_composite_over_8888_8_0565), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, mips_composite_over_8888_8_0565), + PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, mips_composite_over_0565_8_0565), + PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, mips_composite_over_0565_8_0565), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_over_8888_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mips_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mips_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mips_composite_over_8888_8888), + PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mips_composite_over_8888_8888), + SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8888), SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8888), SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8888), @@ -268,12 +306,30 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] = { PIXMAN_OP_NONE }, }; +static void +mips_dspr2_combine_over_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + if (mask) + pixman_composite_over_8888_8888_8888_asm_mips ( + dest, (uint32_t *)src, (uint32_t *)mask, width); + else + pixman_composite_over_8888_8888_asm_mips ( + dest, (uint32_t *)src, width); +} + pixman_implementation_t * _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback) { pixman_implementation_t *imp = _pixman_implementation_create (fallback, mips_dspr2_fast_paths); + imp->combine_32[PIXMAN_OP_OVER] = mips_dspr2_combine_over_u; + imp->blt = mips_dspr2_blt; imp->fill = mips_dspr2_fill; diff --git a/pixman/pixman/pixman-mips-dspr2.h b/pixman/pixman/pixman-mips-dspr2.h index a3d774fcb..bddcfd827 100644 --- a/pixman/pixman/pixman-mips-dspr2.h +++ b/pixman/pixman/pixman-mips-dspr2.h @@ -127,6 +127,89 @@ mips_composite_##name (pixman_implementation_t *imp, \ } \ } +/*******************************************************************/ + +#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST(flags, name, \ + src_type, src_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_mips (dst_type *dst, \ + src_type *src, \ + uint32_t mask, \ + int32_t w); \ + \ +static void \ +mips_composite_##name (pixman_implementation_t *imp, \ + pixman_composite_info_t *info) \ +{ \ + PIXMAN_COMPOSITE_ARGS (info); \ + dst_type *dst_line, *dst; \ + src_type *src_line, *src; \ + int32_t dst_stride, src_stride; \ + uint32_t mask; \ + \ + mask = _pixman_image_get_solid ( \ + imp, mask_image, dest_image->bits.format); \ + \ + 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); \ + \ + while (height--) \ + { \ + dst = dst_line; \ + dst_line += dst_stride; \ + src = src_line; \ + src_line += src_stride; \ + \ + pixman_composite_##name##_asm_mips (dst, src, mask, width); \ + } \ +} + +/************************************************************************/ + +#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST(name, src_type, src_cnt, \ + mask_type, mask_cnt, \ + dst_type, dst_cnt) \ +void \ +pixman_composite_##name##_asm_mips (dst_type *dst, \ + src_type *src, \ + mask_type *mask, \ + int32_t w); \ + \ +static void \ +mips_composite_##name (pixman_implementation_t *imp, \ + pixman_composite_info_t *info) \ +{ \ + PIXMAN_COMPOSITE_ARGS (info); \ + dst_type *dst_line, *dst; \ + src_type *src_line, *src; \ + mask_type *mask_line, *mask; \ + 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); \ + \ + while (height--) \ + { \ + dst = dst_line; \ + dst_line += dst_stride; \ + mask = mask_line; \ + mask_line += mask_stride; \ + src = src_line; \ + src_line += src_stride; \ + pixman_composite_##name##_asm_mips (dst, src, mask, width); \ + } \ +} + /****************************************************************************/ #define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \ diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c index d9d96d672..29e3c2e7c 100644 --- a/pixman/pixman/pixman-sse2.c +++ b/pixman/pixman/pixman-sse2.c @@ -146,7 +146,7 @@ pack_565_2packedx128_128 (__m128i lo, __m128i hi) return _mm_packs_epi32 (t0, t1); } -__m128i +static force_inline __m128i pack_565_2x128_128 (__m128i lo, __m128i hi) { __m128i data; @@ -5159,7 +5159,7 @@ 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 src_width_fixed, pixman_bool_t fully_transparent_src) { uint32_t s, d; @@ -5176,8 +5176,10 @@ scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, while (w && ((unsigned long)pd & 15)) { d = *pd; - s = combine1 (ps + (vx >> 16), pm); + s = combine1 (ps + pixman_fixed_to_int (vx), pm); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; *pd++ = core_combine_over_u_pixel_sse2 (s, d); if (pm) @@ -5190,14 +5192,22 @@ scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, __m128i tmp; uint32_t tmp1, tmp2, tmp3, tmp4; - tmp1 = ps[vx >> 16]; + tmp1 = *(ps + pixman_fixed_to_int (vx)); vx += unit_x; - tmp2 = ps[vx >> 16]; + while (vx >= 0) + vx -= src_width_fixed; + tmp2 = *(ps + pixman_fixed_to_int (vx)); vx += unit_x; - tmp3 = ps[vx >> 16]; + while (vx >= 0) + vx -= src_width_fixed; + tmp3 = *(ps + pixman_fixed_to_int (vx)); vx += unit_x; - tmp4 = ps[vx >> 16]; + while (vx >= 0) + vx -= src_width_fixed; + tmp4 = *(ps + pixman_fixed_to_int (vx)); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; tmp = _mm_set_epi32 (tmp4, tmp3, tmp2, tmp1); @@ -5235,8 +5245,10 @@ scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, while (w) { d = *pd; - s = combine1 (ps + (vx >> 16), pm); + s = combine1 (ps + pixman_fixed_to_int (vx), pm); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; *pd++ = core_combine_over_u_pixel_sse2 (s, d); if (pm) @@ -5255,6 +5267,9 @@ FAST_NEAREST_MAINLOOP (sse2_8888_8888_none_OVER, FAST_NEAREST_MAINLOOP (sse2_8888_8888_pad_OVER, scaled_nearest_scanline_sse2_8888_8888_OVER, uint32_t, uint32_t, PAD) +FAST_NEAREST_MAINLOOP (sse2_8888_8888_normal_OVER, + scaled_nearest_scanline_sse2_8888_8888_OVER, + uint32_t, uint32_t, NORMAL) static force_inline void scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, @@ -5263,7 +5278,7 @@ scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, int32_t w, pixman_fixed_t vx, pixman_fixed_t unit_x, - pixman_fixed_t max_vx, + pixman_fixed_t src_width_fixed, pixman_bool_t zero_src) { __m128i xmm_mask; @@ -5278,8 +5293,10 @@ scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, while (w && (unsigned long)dst & 15) { - uint32_t s = src[pixman_fixed_to_int (vx)]; + uint32_t s = *(src + pixman_fixed_to_int (vx)); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; if (s) { @@ -5301,14 +5318,22 @@ scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, { uint32_t tmp1, tmp2, tmp3, tmp4; - tmp1 = src[pixman_fixed_to_int (vx)]; + tmp1 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp2 = src[pixman_fixed_to_int (vx)]; + while (vx >= 0) + vx -= src_width_fixed; + tmp2 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp3 = src[pixman_fixed_to_int (vx)]; + while (vx >= 0) + vx -= src_width_fixed; + tmp3 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; - tmp4 = src[pixman_fixed_to_int (vx)]; + while (vx >= 0) + vx -= src_width_fixed; + tmp4 = *(src + pixman_fixed_to_int (vx)); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; xmm_src = _mm_set_epi32 (tmp4, tmp3, tmp2, tmp1); @@ -5336,8 +5361,10 @@ scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, while (w) { - uint32_t s = src[pixman_fixed_to_int (vx)]; + uint32_t s = *(src + pixman_fixed_to_int (vx)); vx += unit_x; + while (vx >= 0) + vx -= src_width_fixed; if (s) { @@ -5367,6 +5394,9 @@ FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_pad_OVER, FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_none_OVER, scaled_nearest_scanline_sse2_8888_n_8888_OVER, uint32_t, uint32_t, uint32_t, NONE, TRUE, TRUE) +FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_normal_OVER, + scaled_nearest_scanline_sse2_8888_n_8888_OVER, + uint32_t, uint32_t, uint32_t, NORMAL, TRUE, TRUE) #define BMSK ((1 << BILINEAR_INTERPOLATION_BITS) - 1) @@ -5856,11 +5886,19 @@ static const pixman_fast_path_t sse2_fast_paths[] = SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888), SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888), SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888), + SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888), + SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888), + SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888), + SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888), SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888), SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888), SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888), SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888), + SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888), + SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888), + SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888), + SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888), SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, sse2_8888_8888), SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, sse2_8888_8888), diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index fad8c6f69..0f344116d 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -5,7 +5,9 @@ TESTPROGRAMS = \ region-test \ region-translate-test \ fetch-test \ + rotate-test \ oob-test \ + infinite-loop \ trap-crasher \ alpha-loop \ scaling-crash-test \ diff --git a/pixman/test/affine-test.c b/pixman/test/affine-test.c index 6827cc3a8..7bc28b4cd 100644 --- a/pixman/test/affine-test.c +++ b/pixman/test/affine-test.c @@ -200,11 +200,19 @@ test_composite (int testnum, if (verbose) { +#define M(r,c) \ + transform.matrix[r][c] + printf ("src_fmt=%08X, dst_fmt=%08X\n", src_fmt, dst_fmt); - printf ("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n", - op, scale_x, scale_y, repeat); - printf ("translate_x=%d, translate_y=%d\n", - translate_x, translate_y); + printf ("op=%d, repeat=%d, transform=\n", + op, repeat); + printf (" { { { 0x%08x, 0x%08x, 0x%08x },\n" + " { 0x%08x, 0x%08x, 0x%08x },\n" + " { 0x%08x, 0x%08x, 0x%08x },\n" + " } };\n", + M(0,0), M(0,1), M(0,2), + M(1,0), M(1,1), M(1,2), + M(2,0), M(2,1), M(2,2)); printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", src_width, src_height, dst_width, dst_height); printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 6a3cc8649..8c46cef97 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -395,6 +395,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0xA364B5BF, + 0x3E1DD2E8, test_composite, argc, argv); } diff --git a/pixman/test/infinite-loop.c b/pixman/test/infinite-loop.c new file mode 100644 index 000000000..02addaab2 --- /dev/null +++ b/pixman/test/infinite-loop.c @@ -0,0 +1,39 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "utils.h" + +int +main (int argc, char **argv) +{ +#define SRC_WIDTH 16 +#define SRC_HEIGHT 12 +#define DST_WIDTH 7 +#define DST_HEIGHT 2 + + static const pixman_transform_t transform = { + { { 0x200017bd, 0x00000000, 0x000e6465 }, + { 0x00000000, 0x000a42fd, 0x000e6465 }, + { 0x00000000, 0x00000000, 0x00010000 }, + } + }; + pixman_image_t *src, *dest; + + src = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, SRC_WIDTH, SRC_HEIGHT, NULL, -1); + dest = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, DST_WIDTH, DST_HEIGHT, NULL, -1); + + pixman_image_set_transform (src, &transform); + pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL); + pixman_image_set_filter (src, PIXMAN_FILTER_BILINEAR, NULL, 0); + + if (argc == 1 || strcmp (argv[1], "-nf") != 0) + fail_after (1, "infinite loop detected"); + + pixman_image_composite ( + PIXMAN_OP_OVER, src, NULL, dest, -3, -3, 0, 0, 0, 0, 6, 2); + + return 0; +} diff --git a/pixman/test/rotate-test.c b/pixman/test/rotate-test.c new file mode 100644 index 000000000..bc44281e3 --- /dev/null +++ b/pixman/test/rotate-test.c @@ -0,0 +1,111 @@ +#include <stdlib.h> +#include "utils.h" + +#define WIDTH 32 +#define HEIGHT 32 + +static const pixman_format_code_t formats[] = +{ + PIXMAN_a8r8g8b8, + PIXMAN_a8b8g8r8, + PIXMAN_x8r8g8b8, + PIXMAN_x8b8g8r8, + PIXMAN_r5g6b5, + PIXMAN_b5g6r5, + PIXMAN_a8, + PIXMAN_a1, +}; + +static const pixman_op_t ops[] = +{ + PIXMAN_OP_OVER, + PIXMAN_OP_SRC, + PIXMAN_OP_ADD, +}; + +#define TRANSFORM(v00, v01, v10, v11) \ + { { { v00, v01, WIDTH * pixman_fixed_1 / 2 }, \ + { v10, v11, HEIGHT * pixman_fixed_1 / 2 }, \ + { 0, 0, pixman_fixed_1 } } } + +#define F1 pixman_fixed_1 + +static const pixman_transform_t transforms[] = +{ + TRANSFORM (0, -1, 1, 0), /* wrong 90 degree rotation */ + TRANSFORM (0, 1, -1, 0), /* wrong 270 degree rotation */ + TRANSFORM (1, 0, 0, 1), /* wrong identity */ + TRANSFORM (-1, 0, 0, -1), /* wrong 180 degree rotation */ + TRANSFORM (0, -F1, F1, 0), /* correct 90 degree rotation */ + TRANSFORM (0, F1, -F1, 0), /* correct 270 degree rotation */ + TRANSFORM (F1, 0, 0, F1), /* correct identity */ + TRANSFORM (-F1, 0, 0, -F1), /* correct 180 degree rotation */ +}; + +#define RANDOM_FORMAT() \ + (formats[lcg_rand_n (ARRAY_LENGTH (formats))]) + +#define RANDOM_OP() \ + (ops[lcg_rand_n (ARRAY_LENGTH (ops))]) + +#define RANDOM_TRANSFORM() \ + (&(transforms[lcg_rand_n (ARRAY_LENGTH (transforms))])) + +static void +on_destroy (pixman_image_t *image, void *data) +{ + free (data); +} + +static pixman_image_t * +make_image (void) +{ + pixman_format_code_t format = RANDOM_FORMAT(); + uint32_t *bytes = malloc (WIDTH * HEIGHT * 4); + pixman_image_t *image; + int i; + + for (i = 0; i < WIDTH * HEIGHT * 4; ++i) + ((uint8_t *)bytes)[i] = lcg_rand_n (256); + + image = pixman_image_create_bits ( + format, WIDTH, HEIGHT, bytes, WIDTH * 4); + + pixman_image_set_transform (image, RANDOM_TRANSFORM()); + pixman_image_set_destroy_function (image, on_destroy, bytes); + pixman_image_set_repeat (image, PIXMAN_REPEAT_NORMAL); + + return image; +} + +static uint32_t +test_transform (int testnum, int verbose) +{ + pixman_image_t *src, *dest; + uint32_t crc; + + lcg_srand (testnum); + + src = make_image (); + dest = make_image (); + + pixman_image_composite (RANDOM_OP(), + src, NULL, dest, + 0, 0, 0, 0, WIDTH / 2, HEIGHT / 2, + WIDTH, HEIGHT); + + crc = compute_crc32_for_image (0, dest); + + pixman_image_unref (src); + pixman_image_unref (dest); + + return crc; +} + +int +main (int argc, const char *argv[]) +{ + return fuzzer_test_main ("rotate", 15000, + 0x03A24D51, + test_transform, argc, argv); +} |