summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING1
-rw-r--r--RELEASING1
-rw-r--r--configure.ac4
-rw-r--r--pixman/pixman-arm-neon-asm.S494
-rw-r--r--pixman/pixman-arm-neon-asm.h153
-rw-r--r--pixman/pixman-arm-neon.c474
-rw-r--r--pixman/pixman-arm-simd.c154
-rw-r--r--pixman/pixman-bits-image.c11
-rw-r--r--pixman/pixman-conical-gradient.c2
-rw-r--r--pixman/pixman-cpu.c12
-rw-r--r--pixman/pixman-edge-imp.h8
-rw-r--r--pixman/pixman-fast-path.c578
-rw-r--r--pixman/pixman-general.c26
-rw-r--r--pixman/pixman-image.c11
-rw-r--r--pixman/pixman-implementation.c53
-rw-r--r--pixman/pixman-mmx.c276
-rw-r--r--pixman/pixman-private.h240
-rw-r--r--pixman/pixman-region.c334
-rw-r--r--pixman/pixman-solid-fill.c35
-rw-r--r--pixman/pixman-sse2.c253
-rw-r--r--pixman/pixman-utils.c622
-rw-r--r--pixman/pixman-vmx.c7
-rw-r--r--pixman/pixman.c782
-rw-r--r--pixman/pixman.h42
-rw-r--r--pixman/solaris-hwcap.mapfile36
-rw-r--r--test/Makefile.am27
-rw-r--r--test/a1-trap-test.c50
-rw-r--r--test/alphamap.c49
-rw-r--r--test/blitters-test.c61
-rw-r--r--test/fetch-test.c102
-rw-r--r--test/region-test.c49
-rw-r--r--test/utils.c14
-rw-r--r--test/utils.h4
33 files changed, 3124 insertions, 1841 deletions
diff --git a/COPYING b/COPYING
index 286158f..b0571e6 100644
--- a/COPYING
+++ b/COPYING
@@ -18,6 +18,7 @@ Copyright 2008 Rodrigo Kumpera
Copyright 2008 André Tupinambá
Copyright 2008 Mozilla Corporation
Copyright 2008 Frederic Plourde
+Copyright 2009 Sun Microsystems, Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/RELEASING b/RELEASING
index e3e4214..66b9554 100644
--- a/RELEASING
+++ b/RELEASING
@@ -48,7 +48,6 @@ Here are the steps to follow to create a new pixman release:
xorg-announce@lists.freedesktop.org
-
7) Increment pixman_micro to the next larger (odd) number in
configure.ac. Commit this change, and push all commits created
during this process using
diff --git a/configure.ac b/configure.ac
index 8ee91d3..df0965e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,7 +54,7 @@ AC_PREREQ([2.57])
m4_define([pixman_major], 0)
m4_define([pixman_minor], 17)
-m4_define([pixman_micro], 1)
+m4_define([pixman_micro], 7)
m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro])
@@ -253,7 +253,7 @@ AC_COMPILE_IFELSE([
#include <xmmintrin.h>
#include <emmintrin.h>
int main () {
- __m128i a, b, c;
+ __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
c = _mm_xor_si128 (a, b);
return 0;
}], have_sse2_intrinsics=yes)
diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S
index e8ccf77..2986884 100644
--- a/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman-arm-neon-asm.S
@@ -1,24 +1,24 @@
/*
* Copyright © 2009 Nokia Corporation
*
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Nokia Corporation not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Nokia Corporation makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
* Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
*/
@@ -41,6 +41,7 @@
.text
.fpu neon
+ .arch armv7a
.altmacro
#include "pixman-arm-neon-asm.h"
@@ -343,6 +344,75 @@ generate_composite_function \
/******************************************************************************/
+.macro pixman_composite_over_n_0565_process_pixblock_head
+ /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format
+ and put data into d6 - red, d7 - green, d30 - blue */
+ vshrn.u16 d6, q2, #8
+ vshrn.u16 d7, q2, #3
+ vsli.u16 q2, q2, #5
+ vsri.u8 d6, d6, #5
+ vsri.u8 d7, d7, #6
+ vshrn.u16 d30, q2, #2
+ /* now do alpha blending, storing results in 8-bit planar format
+ into d16 - red, d19 - green, d18 - blue */
+ vmull.u8 q10, d3, d6
+ vmull.u8 q11, d3, d7
+ vmull.u8 q12, d3, d30
+ vrshr.u16 q13, q10, #8
+ vrshr.u16 q3, q11, #8
+ vrshr.u16 q15, q12, #8
+ vraddhn.u16 d20, q10, q13
+ vraddhn.u16 d23, q11, q3
+ vraddhn.u16 d22, q12, q15
+.endm
+
+.macro pixman_composite_over_n_0565_process_pixblock_tail
+ /* ... continue alpha blending */
+ vqadd.u8 d16, d2, d20
+ vqadd.u8 q9, q0, q11
+ /* convert the result to r5g6b5 and store it into {d28, d29} */
+ vshll.u8 q14, d16, #8
+ vshll.u8 q8, d19, #8
+ vshll.u8 q9, d18, #8
+ vsri.u16 q14, q8, #5
+ vsri.u16 q14, q9, #11
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_0565_process_pixblock_tail_head
+ pixman_composite_over_n_0565_process_pixblock_tail
+ vld1.16 {d4, d5}, [DST_R, :128]!
+ vst1.16 {d28, d29}, [DST_W, :128]!
+ pixman_composite_over_n_0565_process_pixblock_head
+.endm
+
+.macro pixman_composite_over_n_0565_init
+ add DUMMY, sp, #ARGS_STACK_OFFSET
+ vld1.32 {d3[0]}, [DUMMY]
+ vdup.8 d0, d3[0]
+ vdup.8 d1, d3[1]
+ vdup.8 d2, d3[2]
+ vdup.8 d3, d3[3]
+ vmvn.8 d3, d3 /* invert source alpha */
+.endm
+
+generate_composite_function \
+ pixman_composite_over_n_0565_asm_neon, 0, 0, 16, \
+ FLAG_DST_READWRITE, \
+ 8, /* number of pixels, processed in a single block */ \
+ 5, /* prefetch distance */ \
+ pixman_composite_over_n_0565_init, \
+ default_cleanup, \
+ pixman_composite_over_n_0565_process_pixblock_head, \
+ pixman_composite_over_n_0565_process_pixblock_tail, \
+ pixman_composite_over_n_0565_process_pixblock_tail_head, \
+ 28, /* dst_w_basereg */ \
+ 4, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 24 /* mask_basereg */
+
+/******************************************************************************/
+
.macro pixman_composite_src_8888_0565_process_pixblock_head
vshll.u8 q8, d1, #8
vshll.u8 q14, d2, #8
@@ -386,6 +456,41 @@ generate_composite_function \
/******************************************************************************/
+.macro pixman_composite_src_0565_8888_process_pixblock_head
+ vshrn.u16 d30, q0, #8
+ vshrn.u16 d29, q0, #3
+ vsli.u16 q0, q0, #5
+ vmov.u8 d31, #255
+ vsri.u8 d30, d30, #5
+ vsri.u8 d29, d29, #6
+ vshrn.u16 d28, q0, #2
+.endm
+
+.macro pixman_composite_src_0565_8888_process_pixblock_tail
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_src_0565_8888_process_pixblock_tail_head
+ pixman_composite_src_0565_8888_process_pixblock_tail
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ vld1.16 {d0, d1}, [SRC]!
+ pixman_composite_src_0565_8888_process_pixblock_head
+ cache_preload 8, 8
+.endm
+
+generate_composite_function \
+ pixman_composite_src_0565_8888_asm_neon, 16, 0, 32, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_0565_8888_process_pixblock_head, \
+ pixman_composite_src_0565_8888_process_pixblock_tail, \
+ pixman_composite_src_0565_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
.macro pixman_composite_add_8000_8000_process_pixblock_head
vqadd.u8 q14, q0, q2
vqadd.u8 q15, q1, q3
@@ -426,6 +531,48 @@ generate_composite_function \
/******************************************************************************/
+.macro pixman_composite_add_8888_8888_process_pixblock_tail_head
+ vld1.8 {d0, d1, d2, d3}, [SRC]!
+ PF add PF_X, PF_X, #8
+ PF tst PF_CTL, #0xF
+ vld1.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ PF addne PF_X, PF_X, #8
+ PF subne PF_CTL, PF_CTL, #1
+ vst1.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ PF cmp PF_X, ORIG_W
+ PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
+ PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+ PF subge PF_X, PF_X, ORIG_W
+ PF subges PF_CTL, PF_CTL, #0x10
+ vqadd.u8 q14, q0, q2
+ PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]!
+ PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+ vqadd.u8 q15, q1, q3
+.endm
+
+generate_composite_function \
+ pixman_composite_add_8888_8888_asm_neon, 32, 0, 32, \
+ FLAG_DST_READWRITE, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_add_8000_8000_process_pixblock_head, \
+ pixman_composite_add_8000_8000_process_pixblock_tail, \
+ pixman_composite_add_8888_8888_process_pixblock_tail_head
+
+generate_composite_function_single_scanline \
+ pixman_composite_scanline_add_asm_neon, 32, 0, 32, \
+ FLAG_DST_READWRITE, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_add_8000_8000_process_pixblock_head, \
+ pixman_composite_add_8000_8000_process_pixblock_tail, \
+ pixman_composite_add_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
.macro pixman_composite_over_8888_8888_process_pixblock_head
vmvn.8 d24, d3 /* get inverted alpha */
/* do alpha blending */
@@ -491,6 +638,46 @@ generate_composite_function \
pixman_composite_over_8888_8888_process_pixblock_tail, \
pixman_composite_over_8888_8888_process_pixblock_tail_head
+generate_composite_function_single_scanline \
+ pixman_composite_scanline_over_asm_neon, 32, 0, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_over_8888_8888_process_pixblock_head, \
+ pixman_composite_over_8888_8888_process_pixblock_tail, \
+ pixman_composite_over_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_8888_process_pixblock_tail_head
+ pixman_composite_over_8888_8888_process_pixblock_tail
+ vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ pixman_composite_over_8888_8888_process_pixblock_head
+.endm
+
+.macro pixman_composite_over_n_8888_init
+ add DUMMY, sp, #ARGS_STACK_OFFSET
+ vld1.32 {d3[0]}, [DUMMY]
+ vdup.8 d0, d3[0]
+ vdup.8 d1, d3[1]
+ vdup.8 d2, d3[2]
+ vdup.8 d3, d3[3]
+.endm
+
+generate_composite_function \
+ pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 5, /* prefetch distance */ \
+ pixman_composite_over_n_8888_init, \
+ default_cleanup, \
+ pixman_composite_over_8888_8888_process_pixblock_head, \
+ pixman_composite_over_8888_8888_process_pixblock_tail, \
+ pixman_composite_over_n_8888_process_pixblock_tail_head
+
/******************************************************************************/
.macro pixman_composite_over_n_8_0565_process_pixblock_head
@@ -950,6 +1137,63 @@ generate_composite_function \
/******************************************************************************/
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_head
+ /* expecting source data in {d0, d1, d2, d3} */
+ /* destination data in {d4, d5, d6, d7} */
+ /* mask in {d24, d25, d26, d27} */
+ vmull.u8 q8, d27, d0
+ vmull.u8 q9, d27, d1
+ vmull.u8 q10, d27, d2
+ vmull.u8 q11, d27, d3
+ vrshr.u16 q0, q8, #8
+ vrshr.u16 q1, q9, #8
+ vrshr.u16 q12, q10, #8
+ vrshr.u16 q13, q11, #8
+ vraddhn.u16 d0, q0, q8
+ vraddhn.u16 d1, q1, q9
+ vraddhn.u16 d2, q12, q10
+ vraddhn.u16 d3, q13, q11
+ vqadd.u8 q14, q0, q2
+ vqadd.u8 q15, q1, q3
+.endm
+
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+ pixman_composite_add_8888_8888_8888_process_pixblock_tail
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ vld4.8 {d24, d25, d26, d27}, [MASK]!
+ vld4.8 {d0, d1, d2, d3}, [SRC]!
+ cache_preload 8, 8
+ pixman_composite_add_8888_8888_8888_process_pixblock_head
+.endm
+
+generate_composite_function \
+ pixman_composite_add_8888_8888_8888_asm_neon, 32, 32, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_head, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_tail, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+
+generate_composite_function_single_scanline \
+ pixman_composite_scanline_add_mask_asm_neon, 32, 32, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_head, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_tail, \
+ pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
.macro pixman_composite_over_8888_n_8888_process_pixblock_head
/* expecting source data in {d0, d1, d2, d3} */
/* destination data in {d4, d5, d6, d7} */
@@ -1023,6 +1267,92 @@ generate_composite_function \
/******************************************************************************/
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_8888_8888_8888_process_pixblock_tail_head
+ vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ pixman_composite_over_8888_n_8888_process_pixblock_tail
+ vld4.8 {d0, d1, d2, d3}, [SRC]!
+ cache_preload 8, 8
+ vld4.8 {d12, d13, d14, d15}, [MASK]!
+ pixman_composite_over_8888_n_8888_process_pixblock_head
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+.endm
+
+.macro pixman_composite_over_8888_8888_8888_init
+ vpush {d8-d15}
+.endm
+
+.macro pixman_composite_over_8888_8888_8888_cleanup
+ vpop {d8-d15}
+.endm
+
+generate_composite_function \
+ pixman_composite_over_8888_8888_8888_asm_neon, 32, 32, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 5, /* prefetch distance */ \
+ pixman_composite_over_8888_8888_8888_init, \
+ pixman_composite_over_8888_8888_8888_cleanup, \
+ pixman_composite_over_8888_n_8888_process_pixblock_head, \
+ pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+ pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \
+ 28, /* dst_w_basereg */ \
+ 4, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 12 /* mask_basereg */
+
+generate_composite_function_single_scanline \
+ pixman_composite_scanline_over_mask_asm_neon, 32, 32, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ pixman_composite_over_8888_8888_8888_init, \
+ pixman_composite_over_8888_8888_8888_cleanup, \
+ pixman_composite_over_8888_n_8888_process_pixblock_head, \
+ pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+ pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \
+ 28, /* dst_w_basereg */ \
+ 4, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 12 /* mask_basereg */
+
+/******************************************************************************/
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_8888_8_8888_process_pixblock_tail_head
+ vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ pixman_composite_over_8888_n_8888_process_pixblock_tail
+ vld4.8 {d0, d1, d2, d3}, [SRC]!
+ cache_preload 8, 8
+ vld1.8 {d15}, [MASK]!
+ pixman_composite_over_8888_n_8888_process_pixblock_head
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+.endm
+
+.macro pixman_composite_over_8888_8_8888_init
+ vpush {d8-d15}
+.endm
+
+.macro pixman_composite_over_8888_8_8888_cleanup
+ vpop {d8-d15}
+.endm
+
+generate_composite_function \
+ pixman_composite_over_8888_8_8888_asm_neon, 32, 8, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 5, /* prefetch distance */ \
+ pixman_composite_over_8888_8_8888_init, \
+ pixman_composite_over_8888_8_8888_cleanup, \
+ pixman_composite_over_8888_n_8888_process_pixblock_head, \
+ pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+ pixman_composite_over_8888_8_8888_process_pixblock_tail_head \
+ 28, /* dst_w_basereg */ \
+ 4, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 15 /* mask_basereg */
+
+/******************************************************************************/
+
.macro pixman_composite_src_0888_0888_process_pixblock_head
.endm
@@ -1049,3 +1379,133 @@ generate_composite_function \
0, /* dst_r_basereg */ \
0, /* src_basereg */ \
0 /* mask_basereg */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_head
+ vswp d0, d2
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail_head
+ vst4.8 {d0, d1, d2, d3}, [DST_W]!
+ vld3.8 {d0, d1, d2}, [SRC]!
+ vswp d0, d2
+ cache_preload 8, 8
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_init
+ veor d3, d3, d3
+.endm
+
+generate_composite_function \
+ pixman_composite_src_0888_8888_rev_asm_neon, 24, 0, 32, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ pixman_composite_src_0888_8888_rev_init, \
+ default_cleanup, \
+ pixman_composite_src_0888_8888_rev_process_pixblock_head, \
+ pixman_composite_src_0888_8888_rev_process_pixblock_tail, \
+ pixman_composite_src_0888_8888_rev_process_pixblock_tail_head, \
+ 0, /* dst_w_basereg */ \
+ 0, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 0 /* mask_basereg */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_head
+ vshll.u8 q8, d1, #8
+ vshll.u8 q9, d2, #8
+.endm
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail
+ vshll.u8 q14, d0, #8
+ vsri.u16 q14, q8, #5
+ vsri.u16 q14, q9, #11
+.endm
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail_head
+ vshll.u8 q14, d0, #8
+ vld3.8 {d0, d1, d2}, [SRC]!
+ vsri.u16 q14, q8, #5
+ vsri.u16 q14, q9, #11
+ vshll.u8 q8, d1, #8
+ vst1.16 {d28, d29}, [DST_W, :128]!
+ vshll.u8 q9, d2, #8
+.endm
+
+generate_composite_function \
+ pixman_composite_src_0888_0565_rev_asm_neon, 24, 0, 16, \
+ FLAG_DST_WRITEONLY, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_0888_0565_rev_process_pixblock_head, \
+ pixman_composite_src_0888_0565_rev_process_pixblock_tail, \
+ pixman_composite_src_0888_0565_rev_process_pixblock_tail_head, \
+ 28, /* dst_w_basereg */ \
+ 0, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 0 /* mask_basereg */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_head
+ vmull.u8 q8, d3, d0
+ vmull.u8 q9, d3, d1
+ vmull.u8 q10, d3, d2
+.endm
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail
+ vrshr.u16 q11, q8, #8
+ vswp d3, d31
+ vrshr.u16 q12, q9, #8
+ vrshr.u16 q13, q10, #8
+ vraddhn.u16 d30, q11, q8
+ vraddhn.u16 d29, q12, q9
+ vraddhn.u16 d28, q13, q10
+.endm
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail_head
+ vrshr.u16 q11, q8, #8
+ vswp d3, d31
+ vrshr.u16 q12, q9, #8
+ vrshr.u16 q13, q10, #8
+ vld4.8 {d0, d1, d2, d3}, [SRC]!
+ vraddhn.u16 d30, q11, q8
+ PF add PF_X, PF_X, #8
+ PF tst PF_CTL, #0xF
+ PF addne PF_X, PF_X, #8
+ PF subne PF_CTL, PF_CTL, #1
+ vraddhn.u16 d29, q12, q9
+ vraddhn.u16 d28, q13, q10
+ vmull.u8 q8, d3, d0
+ vmull.u8 q9, d3, d1
+ vmull.u8 q10, d3, d2
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ PF cmp PF_X, ORIG_W
+ PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
+ PF subge PF_X, PF_X, ORIG_W
+ PF subges PF_CTL, PF_CTL, #0x10
+ PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]!
+.endm
+
+generate_composite_function \
+ pixman_composite_src_pixbuf_8888_asm_neon, 32, 0, 32, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ 10, /* prefetch distance */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_pixbuf_8888_process_pixblock_head, \
+ pixman_composite_src_pixbuf_8888_process_pixblock_tail, \
+ pixman_composite_src_pixbuf_8888_process_pixblock_tail_head, \
+ 28, /* dst_w_basereg */ \
+ 0, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 0 /* mask_basereg */
diff --git a/pixman/pixman-arm-neon-asm.h b/pixman/pixman-arm-neon-asm.h
index e7be5cd..56c3fae 100644
--- a/pixman/pixman-arm-neon-asm.h
+++ b/pixman/pixman-arm-neon-asm.h
@@ -1,24 +1,24 @@
/*
* Copyright © 2009 Nokia Corporation
*
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Nokia Corporation not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Nokia Corporation makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
* Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
*/
@@ -780,6 +780,125 @@ fname:
.endfunc
.endm
+/*
+ * A simplified variant of function generation template for a single
+ * scanline processing (for implementing pixman combine functions)
+ */
+.macro generate_composite_function_single_scanline fname, \
+ src_bpp_, \
+ mask_bpp_, \
+ dst_w_bpp_, \
+ flags, \
+ pixblock_size_, \
+ init, \
+ cleanup, \
+ process_pixblock_head, \
+ process_pixblock_tail, \
+ process_pixblock_tail_head, \
+ dst_w_basereg_ = 28, \
+ dst_r_basereg_ = 4, \
+ src_basereg_ = 0, \
+ mask_basereg_ = 24
+
+ .func fname
+ .global fname
+ /* For ELF format also set function visibility to hidden */
+#ifdef __ELF__
+ .hidden fname
+ .type fname, %function
+#endif
+fname:
+ .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE
+/*
+ * Make some macro arguments globally visible and accessible
+ * from other macros
+ */
+ .set src_bpp, src_bpp_
+ .set mask_bpp, mask_bpp_
+ .set dst_w_bpp, dst_w_bpp_
+ .set pixblock_size, pixblock_size_
+ .set dst_w_basereg, dst_w_basereg_
+ .set dst_r_basereg, dst_r_basereg_
+ .set src_basereg, src_basereg_
+ .set mask_basereg, mask_basereg_
+/*
+ * Assign symbolic names to registers
+ */
+ W .req r0 /* width (is updated during processing) */
+ DST_W .req r1 /* destination buffer pointer for writes */
+ SRC .req r2 /* source buffer pointer */
+ DST_R .req ip /* destination buffer pointer for reads */
+ MASK .req r3 /* mask pointer */
+
+.if (((flags) & FLAG_DST_READWRITE) != 0)
+ .set dst_r_bpp, dst_w_bpp
+.else
+ .set dst_r_bpp, 0
+.endif
+.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0)
+ .set DEINTERLEAVE_32BPP_ENABLED, 1
+.else
+ .set DEINTERLEAVE_32BPP_ENABLED, 0
+.endif
+
+ init
+ mov DST_R, DST_W
+
+ cmp W, #pixblock_size
+ blt 8f
+
+ ensure_destination_ptr_alignment process_pixblock_head, \
+ process_pixblock_tail, \
+ process_pixblock_tail_head
+
+ subs W, W, #pixblock_size
+ blt 7f
+
+ /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */
+ pixld_a pixblock_size, dst_r_bpp, \
+ (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R
+ pixld pixblock_size, src_bpp, \
+ (src_basereg - pixblock_size * src_bpp / 64), SRC
+ pixld pixblock_size, mask_bpp, \
+ (mask_basereg - pixblock_size * mask_bpp / 64), MASK
+ process_pixblock_head
+ subs W, W, #pixblock_size
+ blt 2f
+1:
+ process_pixblock_tail_head
+ subs W, W, #pixblock_size
+ bge 1b
+2:
+ process_pixblock_tail
+ pixst_a pixblock_size, dst_w_bpp, \
+ (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W
+7:
+ /* Process the remaining trailing pixels in the scanline (dst aligned) */
+ process_trailing_pixels 0, 1, \
+ process_pixblock_head, \
+ process_pixblock_tail, \
+ process_pixblock_tail_head
+
+ cleanup
+ bx lr /* exit */
+8:
+ /* Process the remaining trailing pixels in the scanline (dst unaligned) */
+ process_trailing_pixels 0, 0, \
+ process_pixblock_head, \
+ process_pixblock_tail, \
+ process_pixblock_tail_head
+
+ cleanup
+ bx lr /* exit */
+
+ .unreq SRC
+ .unreq MASK
+ .unreq DST_R
+ .unreq DST_W
+ .unreq W
+ .endfunc
+.endm
+
.macro default_init
.endm
diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index 2ed8b4b..557301e 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -35,27 +35,27 @@
#define BIND_SRC_NULL_DST(name, src_type, src_cnt, dst_type, dst_cnt) \
void \
-pixman_##name##_asm_neon (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride); \
+pixman_composite_##name##_asm_neon (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride); \
\
static void \
-neon_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
+neon_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
{ \
dst_type *dst_line; \
src_type *src_line; \
@@ -66,36 +66,76 @@ neon_##name (pixman_implementation_t *imp, \
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
\
- pixman_##name##_asm_neon (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride); \
+ pixman_composite_##name##_asm_neon (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride); \
+}
+
+#define BIND_N_NULL_DST(name, dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_neon (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ uint32_t src); \
+ \
+static void \
+neon_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ int32_t dst_stride; \
+ uint32_t src; \
+ \
+ src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
+ \
+ if (src == 0) \
+ return; \
+ \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ \
+ pixman_composite_##name##_asm_neon (width, height, \
+ dst_line, dst_stride, \
+ src); \
}
#define BIND_N_MASK_DST(name, mask_type, mask_cnt, dst_type, dst_cnt) \
void \
-pixman_##name##_asm_neon (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- uint32_t src, \
- int32_t unused, \
- mask_type *mask, \
- int32_t mask_stride); \
+pixman_composite_##name##_asm_neon (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ uint32_t src, \
+ int32_t unused, \
+ mask_type *mask, \
+ int32_t mask_stride); \
\
static void \
-neon_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
+neon_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
{ \
dst_type *dst_line; \
mask_type *mask_line; \
@@ -112,36 +152,36 @@ neon_##name (pixman_implementation_t *imp, \
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
mask_stride, mask_line, mask_cnt); \
\
- pixman_##name##_asm_neon (width, height, \
- dst_line, dst_stride, \
- src, 0, \
- mask_line, mask_stride); \
+ pixman_composite_##name##_asm_neon (width, height, \
+ dst_line, dst_stride, \
+ src, 0, \
+ mask_line, mask_stride); \
}
#define BIND_SRC_N_DST(name, src_type, src_cnt, dst_type, dst_cnt) \
void \
-pixman_##name##_asm_neon (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- uint32_t mask); \
+pixman_composite_##name##_asm_neon (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride, \
+ uint32_t mask); \
\
static void \
-neon_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
+neon_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
{ \
dst_type *dst_line; \
src_type *src_line; \
@@ -158,38 +198,38 @@ neon_##name (pixman_implementation_t *imp, \
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
src_stride, src_line, src_cnt); \
\
- pixman_##name##_asm_neon (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask); \
+ pixman_composite_##name##_asm_neon (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride, \
+ mask); \
}
#define BIND_SRC_MASK_DST(name, src_type, src_cnt, mask_type, mask_cnt, \
dst_type, dst_cnt) \
void \
-pixman_##name##_asm_neon (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- mask_type *mask, \
- int32_t mask_stride); \
+pixman_composite_##name##_asm_neon (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride, \
+ mask_type *mask, \
+ int32_t mask_stride); \
\
static void \
-neon_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
+neon_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
{ \
dst_type *dst_line; \
src_type *src_line; \
@@ -203,29 +243,40 @@ neon_##name (pixman_implementation_t *imp, \
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
mask_stride, mask_line, mask_cnt); \
\
- pixman_##name##_asm_neon (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask_line, mask_stride); \
+ pixman_composite_##name##_asm_neon (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride, \
+ mask_line, mask_stride); \
}
-BIND_SRC_NULL_DST(composite_src_8888_8888, uint32_t, 1, uint32_t, 1)
-BIND_SRC_NULL_DST(composite_src_0565_0565, uint16_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_src_0888_0888, uint8_t, 3, uint8_t, 3)
-BIND_SRC_NULL_DST(composite_src_8888_0565, uint32_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_add_8000_8000, uint8_t, 1, uint8_t, 1)
+BIND_SRC_NULL_DST(src_8888_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0565_0565, uint16_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(src_0888_0888, uint8_t, 3, uint8_t, 3)
+BIND_SRC_NULL_DST(src_8888_0565, uint32_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(src_0565_8888, uint16_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0888_8888_rev, uint8_t, 3, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0888_0565_rev, uint8_t, 3, uint16_t, 1)
+BIND_SRC_NULL_DST(src_pixbuf_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(add_8000_8000, uint8_t, 1, uint8_t, 1)
+BIND_SRC_NULL_DST(add_8888_8888, uint32_t, 1, uint32_t, 1)
+
+BIND_N_NULL_DST(over_n_0565, uint16_t, 1)
+BIND_N_NULL_DST(over_n_8888, uint32_t, 1)
-BIND_SRC_NULL_DST(composite_over_8888_0565, uint32_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_over_8888_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(over_8888_0565, uint32_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(over_8888_8888, uint32_t, 1, uint32_t, 1)
-BIND_N_MASK_DST(composite_over_n_8_0565, uint8_t, 1, uint16_t, 1)
-BIND_N_MASK_DST(composite_over_n_8_8888, uint8_t, 1, uint32_t, 1)
-BIND_N_MASK_DST(composite_add_n_8_8, uint8_t, 1, uint8_t, 1)
+BIND_N_MASK_DST(over_n_8_0565, uint8_t, 1, uint16_t, 1)
+BIND_N_MASK_DST(over_n_8_8888, uint8_t, 1, uint32_t, 1)
+BIND_N_MASK_DST(add_n_8_8, uint8_t, 1, uint8_t, 1)
-BIND_SRC_N_DST(composite_over_8888_n_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_N_DST(over_8888_n_8888, uint32_t, 1, uint32_t, 1)
-BIND_SRC_MASK_DST(composite_add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
+BIND_SRC_MASK_DST(add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
+BIND_SRC_MASK_DST(add_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
+BIND_SRC_MASK_DST(over_8888_8_8888, uint32_t, 1, uint8_t, 1, uint32_t, 1)
+BIND_SRC_MASK_DST(over_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
void
pixman_composite_src_n_8_asm_neon (int32_t w,
@@ -292,72 +343,125 @@ pixman_fill_neon (uint32_t *bits,
}
}
-static const pixman_fast_path_t arm_neon_fast_path_array[] =
+static pixman_bool_t
+pixman_blt_neon (uint32_t *src_bits,
+ uint32_t *dst_bits,
+ int src_stride,
+ int dst_stride,
+ int src_bpp,
+ int dst_bpp,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height)
{
- { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_0565_0565 },
- { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_0565_0565 },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_src_8888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_src_8888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888 },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_src_8888_8888 },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888 },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_src_8888_8888 },
- { PIXMAN_OP_SRC, PIXMAN_r8g8b8, PIXMAN_null, PIXMAN_r8g8b8, neon_composite_src_0888_0888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, neon_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, neon_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, neon_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, neon_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, neon_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, neon_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, neon_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, neon_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, neon_composite_over_8888_0565 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, neon_composite_over_8888_0565 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, neon_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, neon_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, neon_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, neon_composite_over_8888_8888 },
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, neon_composite_add_n_8_8 },
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_a8, PIXMAN_a8, neon_composite_add_8_8_8 },
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, neon_composite_add_8000_8000 },
+ if (src_bpp != dst_bpp)
+ return FALSE;
+
+ switch (src_bpp)
+ {
+ case 16:
+ pixman_composite_src_0565_0565_asm_neon (
+ width, height,
+ (uint16_t *)(((char *) dst_bits) +
+ dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
+ (uint16_t *)(((char *) src_bits) +
+ src_y * src_stride * 4 + src_x * 2), src_stride * 2);
+ return TRUE;
+ case 32:
+ pixman_composite_src_8888_8888_asm_neon (
+ width, height,
+ (uint32_t *)(((char *) dst_bits) +
+ dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
+ (uint32_t *)(((char *) src_bits) +
+ src_y * src_stride * 4 + src_x * 4), src_stride);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static const pixman_fast_path_t arm_neon_fast_paths[] =
+{
+ PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, neon_composite_src_0565_0565),
+ PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, neon_composite_src_0565_0565),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, neon_composite_src_0565_8888),
+ PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, neon_composite_src_0565_8888),
+ PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, neon_composite_src_0565_8888),
+ PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, neon_composite_src_0565_8888),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
+ PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, neon_composite_src_0888_0888),
+ PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, neon_composite_src_0888_8888_rev),
+ PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, neon_composite_src_0888_0565_rev),
+ PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, neon_composite_src_pixbuf_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, neon_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, neon_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, neon_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, neon_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, neon_composite_over_n_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, neon_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, neon_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, neon_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, neon_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, neon_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, neon_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, neon_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, neon_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_over_8888_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, neon_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, neon_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, neon_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, neon_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, neon_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, neon_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, neon_composite_add_n_8_8),
+ PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, neon_composite_add_8_8_8),
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_add_8888_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8000_8000),
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, neon_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, neon_composite_add_8888_8888),
+
{ PIXMAN_OP_NONE },
};
-const pixman_fast_path_t *const arm_neon_fast_paths = arm_neon_fast_path_array;
-
-static void
-arm_neon_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+static pixman_bool_t
+arm_neon_blt (pixman_implementation_t *imp,
+ uint32_t * src_bits,
+ uint32_t * dst_bits,
+ int src_stride,
+ int dst_stride,
+ int src_bpp,
+ int dst_bpp,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height)
{
- if (_pixman_run_fast_path (arm_neon_fast_paths, imp,
- op, src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height))
+ if (!pixman_blt_neon (
+ src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
+ src_x, src_y, dst_x, dst_y, width, height))
+
{
- return;
+ return _pixman_implementation_blt (
+ imp->delegate,
+ src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
+ src_x, src_y, dst_x, dst_y, width, height);
}
- _pixman_implementation_composite (imp->delegate, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
+ return TRUE;
}
static pixman_bool_t
@@ -378,13 +482,47 @@ arm_neon_fill (pixman_implementation_t *imp,
imp->delegate, bits, stride, bpp, x, y, width, height, xor);
}
+#define BIND_COMBINE_U(name) \
+void \
+pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \
+ const uint32_t *dst, \
+ const uint32_t *src, \
+ const uint32_t *mask); \
+ \
+void \
+pixman_composite_scanline_##name##_asm_neon (int32_t w, \
+ const uint32_t *dst, \
+ const uint32_t *src); \
+ \
+static void \
+neon_combine_##name##_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_scanline_##name##_mask_asm_neon (width, dest, \
+ src, mask); \
+ else \
+ pixman_composite_scanline_##name##_asm_neon (width, dest, src); \
+}
+
+BIND_COMBINE_U (over)
+BIND_COMBINE_U (add)
+
pixman_implementation_t *
_pixman_implementation_create_arm_neon (void)
{
pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
- pixman_implementation_t *imp = _pixman_implementation_create (general);
+ pixman_implementation_t *imp =
+ _pixman_implementation_create (general, arm_neon_fast_paths);
+
+ imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u;
+ imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u;
- imp->composite = arm_neon_composite;
+ imp->blt = arm_neon_blt;
imp->fill = arm_neon_fill;
return imp;
diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c
index 265c820..09a2888 100644
--- a/pixman/pixman-arm-simd.c
+++ b/pixman/pixman-arm-simd.c
@@ -31,23 +31,23 @@
static void
arm_composite_add_8000_8000 (pixman_implementation_t * impl,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
{
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint8_t s, d;
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
@@ -103,23 +103,23 @@ arm_composite_add_8000_8000 (pixman_implementation_t * impl,
static void
arm_composite_over_8888_8888 (pixman_implementation_t * impl,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
{
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint32_t component_half = 0x800080;
uint32_t upper_component_mask = 0xff00ff00;
uint32_t alpha_mask = 0xff;
@@ -188,33 +188,32 @@ arm_composite_over_8888_8888 (pixman_implementation_t * impl,
"2:\n\t"
: [w] "+r" (w), [dest] "+r" (dst), [src] "+r" (src)
: [component_half] "r" (component_half), [upper_component_mask] "r" (upper_component_mask),
- [alpha_mask] "r" (alpha_mask)
+ [alpha_mask] "r" (alpha_mask)
: "r4", "r5", "r6", "r7", "r8", "cc", "memory"
);
}
}
static void
-arm_composite_over_8888_n_8888 (
- pixman_implementation_t * impl,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+arm_composite_over_8888_n_8888 (pixman_implementation_t * impl,
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
{
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
uint32_t mask;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint32_t component_half = 0x800080;
uint32_t alpha_mask = 0xff;
@@ -298,7 +297,7 @@ arm_composite_over_8888_n_8888 (
"2:\n\t"
: [w] "+r" (w), [dest] "+r" (dst), [src] "+r" (src)
: [component_half] "r" (component_half), [mask_alpha] "r" (mask),
- [alpha_mask] "r" (alpha_mask)
+ [alpha_mask] "r" (alpha_mask)
: "r4", "r5", "r6", "r7", "r8", "r9", "cc", "memory"
);
}
@@ -323,7 +322,7 @@ arm_composite_over_n_8_8888 (pixman_implementation_t * impl,
uint32_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -384,7 +383,8 @@ arm_composite_over_n_8_8888 (pixman_implementation_t * impl,
"uxtb16 r7, r4, ror #8\n\t"
/* we could simplify this to use 'sub' if we were
- * willing to give up a register for alpha_mask */
+ * willing to give up a register for alpha_mask
+ */
"mvn r8, r5\n\t"
"mov r8, r8, lsr #24\n\t"
@@ -419,68 +419,30 @@ arm_composite_over_n_8_8888 (pixman_implementation_t * impl,
}
}
-static const pixman_fast_path_t arm_simd_fast_path_array[] =
+static const pixman_fast_path_t arm_simd_fast_paths[] =
{
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, arm_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, arm_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, arm_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, arm_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, arm_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, arm_composite_over_8888_n_8888 },
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, arm_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, arm_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, arm_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, arm_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, arm_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, arm_composite_over_8888_n_8888),
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, arm_composite_add_8000_8000 },
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, arm_composite_add_8000_8000),
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, arm_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, arm_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, arm_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, arm_composite_over_n_8_8888 },
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, arm_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, arm_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, arm_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, arm_composite_over_n_8_8888),
{ PIXMAN_OP_NONE },
};
-const pixman_fast_path_t *const arm_simd_fast_paths = arm_simd_fast_path_array;
-
-static void
-arm_simd_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- if (_pixman_run_fast_path (arm_simd_fast_paths, imp,
- op, src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height))
- {
- return;
- }
-
- _pixman_implementation_composite (imp->delegate, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
-}
-
pixman_implementation_t *
_pixman_implementation_create_arm_simd (void)
{
pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
- pixman_implementation_t *imp = _pixman_implementation_create (general);
-
- imp->composite = arm_simd_composite;
+ pixman_implementation_t *imp = _pixman_implementation_create (general, arm_simd_fast_paths);
return imp;
}
-
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 5a5a690..6befcbb 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -115,12 +115,13 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
}
else
{
- pixel_a = image->fetch_pixel_raw_32 (
+ pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
image->common.alpha_map, x, y);
pixel_a = ALPHA_8 (pixel_a);
}
- UN8x4_MUL_UN8 (pixel, pixel_a);
+ pixel &= 0x00ffffff;
+ pixel |= (pixel_a << 24);
return pixel;
}
@@ -1040,8 +1041,10 @@ pixman_image_create_bits (pixman_format_code_t format,
/* must be a whole number of uint32_t's
*/
- return_val_if_fail (bits == NULL ||
- (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
+ return_val_if_fail (
+ bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
+
+ return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
if (!bits && width && height)
{
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index d720db3..369a7a5 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -49,7 +49,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
double rx = x + 0.5;
double ry = y + 0.5;
double rz = 1.;
- double a = conical->angle / (180. * 65536);
+ double a = (conical->angle * M_PI) / (180. * 65536);
_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 5d5469b..e96b140 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -253,8 +253,6 @@ pixman_arm_read_auxv ()
if (aux.a_type == AT_HWCAP)
{
uint32_t hwcap = aux.a_un.a_val;
- if (getenv ("ARM_FORCE_HWCAP"))
- hwcap = strtoul (getenv ("ARM_FORCE_HWCAP"), NULL, 0);
/* hardcode these values to avoid depending on specific
* versions of the hwcap header, e.g. HWCAP_NEON
*/
@@ -266,8 +264,6 @@ pixman_arm_read_auxv ()
else if (aux.a_type == AT_PLATFORM)
{
const char *plat = (const char*) aux.a_un.a_val;
- if (getenv ("ARM_FORCE_PLATFORM"))
- plat = getenv ("ARM_FORCE_PLATFORM");
if (strncmp (plat, "v7l", 3) == 0)
{
arm_has_v7 = TRUE;
@@ -280,12 +276,6 @@ pixman_arm_read_auxv ()
}
}
close (fd);
-
- /* if we don't have 2.6.29, we have to do this hack; set
- * the env var to trust HWCAP.
- */
- if (!getenv ("ARM_TRUST_HWCAP") && arm_has_v7)
- arm_has_neon = TRUE;
}
arm_tests_initialized = TRUE;
@@ -319,7 +309,7 @@ pixman_have_arm_neon (void)
#endif /* USE_ARM_SIMD || USE_ARM_NEON */
-#ifdef USE_MMX
+#if defined(USE_MMX) || defined(USE_SSE2)
/* The CPU detection code needs to be in a file not compiled with
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
* that would lead to SIGILL instructions on old CPUs that don't have
diff --git a/pixman/pixman-edge-imp.h b/pixman/pixman-edge-imp.h
index d786ea7..a4698ed 100644
--- a/pixman/pixman-edge-imp.h
+++ b/pixman/pixman-edge-imp.h
@@ -83,14 +83,6 @@ RASTERIZE_EDGES (pixman_image_t *image,
#if N_BITS == 1
{
-#ifdef WORDS_BIGENDIAN
-# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
-#else
-# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
-#endif
-
#define LEFT_MASK(x) \
(((x) & 0x1f) ? \
SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index d2c456b..4d26b0f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -125,7 +125,7 @@ fast_composite_over_x888_8_8888 (pixman_implementation_t *imp,
int src_stride, mask_stride, dst_stride;
uint8_t m;
uint32_t s, d;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (dst_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);
@@ -183,7 +183,7 @@ fast_composite_in_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask, m;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint16_t t;
src = _pixman_image_get_solid (src_image, dest_image->bits.format);
@@ -260,7 +260,7 @@ fast_composite_in_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint8_t s;
uint16_t t;
@@ -308,7 +308,7 @@ fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst, d;
uint8_t *mask_line, *mask, m;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -366,7 +366,7 @@ fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
uint32_t *dst_line, *dst, d;
uint32_t *mask_line, *mask, ma;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -423,7 +423,7 @@ fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
uint32_t *dst_line, *dst, d;
uint32_t *mask_line, *mask, ma;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -490,7 +490,7 @@ fast_composite_over_n_8_0888 (pixman_implementation_t *imp,
uint32_t d;
uint8_t *mask_line, *mask, m;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -555,7 +555,7 @@ fast_composite_over_n_8_0565 (pixman_implementation_t *imp,
uint32_t d;
uint8_t *mask_line, *mask, m;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -622,7 +622,7 @@ fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
uint32_t d;
uint32_t *mask_line, *mask, ma;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
@@ -697,7 +697,7 @@ fast_composite_over_8888_8888 (pixman_implementation_t *imp,
uint32_t *src_line, *src, s;
int dst_stride, src_stride;
uint8_t a;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
@@ -744,7 +744,7 @@ fast_composite_over_8888_0888 (pixman_implementation_t *imp,
uint32_t *src_line, *src, s;
uint8_t a;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3);
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
@@ -796,7 +796,7 @@ fast_composite_over_8888_0565 (pixman_implementation_t *imp,
uint32_t *src_line, *src, s;
uint8_t a;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
@@ -849,7 +849,7 @@ fast_composite_src_x888_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst;
uint32_t *src_line, *src, s;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
@@ -889,7 +889,7 @@ fast_composite_add_8000_8000 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint8_t s, d;
uint16_t t;
@@ -940,7 +940,7 @@ fast_composite_add_8888_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint32_t s, d;
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
@@ -990,7 +990,7 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t src;
uint8_t sa;
@@ -1033,10 +1033,10 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp,
#define UPDATE_BITMASK(n) ((n) << 1)
#endif
-#define TEST_BIT(p, n) \
- (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31))
-#define SET_BIT(p, n) \
- do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0);
+#define TEST_BIT(p, n) \
+ (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31))
+#define SET_BIT(p, n) \
+ do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0);
static void
fast_composite_add_1000_1000 (pixman_implementation_t *imp,
@@ -1175,6 +1175,104 @@ fast_composite_over_n_1_8888 (pixman_implementation_t *imp,
}
}
+static void
+fast_composite_over_n_1_0565 (pixman_implementation_t *imp,
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
+{
+ uint32_t src, srca;
+ uint16_t *dst, *dst_line;
+ uint32_t *mask, *mask_line;
+ int mask_stride, dst_stride;
+ uint32_t bitcache, bitmask;
+ int32_t w;
+ uint32_t d;
+ uint16_t src565;
+
+ if (width <= 0)
+ return;
+
+ src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint16_t,
+ dst_stride, dst_line, 1);
+ PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t,
+ mask_stride, mask_line, 1);
+ mask_line += mask_x >> 5;
+
+ if (srca == 0xff)
+ {
+ src565 = CONVERT_8888_TO_0565 (src);
+ while (height--)
+ {
+ dst = dst_line;
+ dst_line += dst_stride;
+ mask = mask_line;
+ mask_line += mask_stride;
+ w = width;
+
+ bitcache = *mask++;
+ bitmask = CREATE_BITMASK (mask_x & 31);
+
+ while (w--)
+ {
+ if (bitmask == 0)
+ {
+ bitcache = *mask++;
+ bitmask = CREATE_BITMASK (0);
+ }
+ if (bitcache & bitmask)
+ *dst = src565;
+ bitmask = UPDATE_BITMASK (bitmask);
+ dst++;
+ }
+ }
+ }
+ else
+ {
+ while (height--)
+ {
+ dst = dst_line;
+ dst_line += dst_stride;
+ mask = mask_line;
+ mask_line += mask_stride;
+ w = width;
+
+ bitcache = *mask++;
+ bitmask = CREATE_BITMASK (mask_x & 31);
+
+ while (w--)
+ {
+ if (bitmask == 0)
+ {
+ bitcache = *mask++;
+ bitmask = CREATE_BITMASK (0);
+ }
+ if (bitcache & bitmask)
+ {
+ d = over (src, CONVERT_0565_TO_0888 (*dst));
+ *dst = CONVERT_8888_TO_0565 (d);
+ }
+ bitmask = UPDATE_BITMASK (bitmask);
+ dst++;
+ }
+ }
+ }
+}
+
/*
* Simple bitblt
*/
@@ -1247,86 +1345,102 @@ fast_composite_src_8888_x888 (pixman_implementation_t *imp,
}
}
-static const pixman_fast_path_t c_fast_paths[] =
+static force_inline pixman_bool_t
+repeat (pixman_repeat_t repeat, int *c, int size)
{
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, fast_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, fast_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r8g8b8, fast_composite_over_n_8_0888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b8g8r8, fast_composite_over_n_8_0888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, fast_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, fast_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, fast_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, fast_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_a8r8g8b8, fast_composite_over_n_1_8888, },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8r8g8b8, fast_composite_over_n_1_8888, },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_a8b8g8r8, fast_composite_over_n_1_8888, },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a1, PIXMAN_x8b8g8r8, fast_composite_over_n_1_8888, },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, fast_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_x8r8g8b8, fast_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_r5g6b5, fast_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_a8b8g8r8, fast_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_x8b8g8r8, fast_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_b5g6r5, fast_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, fast_composite_over_x888_8_8888, },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, fast_composite_over_x888_8_8888, },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, fast_composite_over_x888_8_8888, },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, fast_composite_over_x888_8_8888, },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fast_composite_over_8888_8888, },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fast_composite_over_8888_8888, },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fast_composite_over_8888_0565, },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fast_composite_over_8888_8888, },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fast_composite_over_8888_8888, },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fast_composite_over_8888_0565, },
- { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, fast_composite_add_8888_8888, },
- { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, fast_composite_add_8888_8888, },
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fast_composite_add_8000_8000, },
- { PIXMAN_OP_ADD, PIXMAN_a1, PIXMAN_null, PIXMAN_a1, fast_composite_add_1000_1000, },
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, fast_composite_add_n_8888_8888_ca },
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fast_composite_add_n_8_8, },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8b8g8r8, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_x8b8g8r8, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_a8, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, fast_composite_solid_fill },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fast_composite_src_8888_x888 },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, fast_composite_src_8888_x888 },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fast_composite_src_8888_x888 },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, fast_composite_src_8888_x888 },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fast_composite_src_x888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, fast_composite_src_x888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fast_composite_src_x888_0565 },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, fast_composite_src_x888_0565 },
- { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, fast_composite_in_8_8, },
- { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, fast_composite_in_n_8_8 },
- { PIXMAN_OP_NONE },
-};
+ if (repeat == PIXMAN_REPEAT_NONE)
+ {
+ if (*c < 0 || *c >= size)
+ return FALSE;
+ }
+ else if (repeat == PIXMAN_REPEAT_NORMAL)
+ {
+ while (*c >= size)
+ *c -= size;
+ while (*c < 0)
+ *c += size;
+ }
+ else if (repeat == PIXMAN_REPEAT_PAD)
+ {
+ *c = CLIP (*c, 0, size - 1);
+ }
+ else /* REFLECT */
+ {
+ *c = MOD (*c, size * 2);
+ if (*c >= size)
+ *c = size * 2 - *c - 1;
+ }
+ return TRUE;
+}
+
+static force_inline uint32_t
+fetch_nearest (pixman_repeat_t src_repeat,
+ pixman_format_code_t format,
+ uint32_t *src, int x, int src_width)
+{
+ if (repeat (src_repeat, &x, src_width))
+ {
+ if (format == PIXMAN_x8r8g8b8)
+ return *(src + x) | 0xff000000;
+ else
+ return *(src + x);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static force_inline void
+combine_over (uint32_t s, uint32_t *dst)
+{
+ if (s)
+ {
+ uint8_t ia = 0xff - (s >> 24);
+
+ if (ia)
+ UN8x4_MUL_UN8_ADD_UN8x4 (*dst, ia, s);
+ else
+ *dst = s;
+ }
+}
+
+static force_inline void
+combine_src (uint32_t s, uint32_t *dst)
+{
+ *dst = s;
+}
static void
-fast_composite_src_scale_nearest (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+fast_composite_scaled_nearest (pixman_implementation_t *imp,
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
{
- uint32_t *dst;
- uint32_t *src;
- int dst_stride, src_stride;
- int i, j;
+ uint32_t *dst_line;
+ uint32_t *src_line;
+ int dst_stride, src_stride;
+ int src_width, src_height;
+ pixman_repeat_t src_repeat;
+ pixman_fixed_t unit_x, unit_y;
+ pixman_format_code_t src_format;
pixman_vector_t v;
+ pixman_fixed_t vy;
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst, 1);
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
/* pass in 0 instead of src_x and src_y because src_x and src_y need to be
- * transformed from destination space to source space */
- PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, uint32_t, src_stride, src, 1);
+ * transformed from destination space to source space
+ */
+ PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, uint32_t, src_stride, src_line, 1);
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2;
@@ -1336,145 +1450,181 @@ fast_composite_src_scale_nearest (pixman_implementation_t *imp,
if (!pixman_transform_point_3d (src_image->common.transform, &v))
return;
+ unit_x = src_image->common.transform->matrix[0][0];
+ unit_y = src_image->common.transform->matrix[1][1];
+
/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
v.vector[0] -= pixman_fixed_e;
v.vector[1] -= pixman_fixed_e;
- for (j = 0; j < height; j++)
+ src_height = src_image->bits.height;
+ src_width = src_image->bits.width;
+ src_repeat = src_image->common.repeat;
+ src_format = src_image->bits.format;
+
+ vy = v.vector[1];
+ while (height--)
{
- pixman_fixed_t vx = v.vector[0];
- pixman_fixed_t vy = v.vector[1];
+ pixman_fixed_t vx = v.vector[0];
+ int y = pixman_fixed_to_int (vy);
+ uint32_t *dst = dst_line;
- for (i = 0; i < width; ++i)
+ dst_line += dst_stride;
+
+ /* adjust the y location by a unit vector in the y direction
+ * this is equivalent to transforming y+1 of the destination point to source space */
+ vy += unit_y;
+
+ if (!repeat (src_repeat, &y, src_height))
{
- pixman_bool_t inside_bounds;
- uint32_t result;
- int x, y;
- x = vx >> 16;
- y = vy >> 16;
-
- /* apply the repeat function */
- switch (src_image->common.repeat)
- {
- case PIXMAN_REPEAT_NORMAL:
- x = MOD (x, src_image->bits.width);
- y = MOD (y, src_image->bits.height);
- inside_bounds = TRUE;
- break;
-
- case PIXMAN_REPEAT_PAD:
- x = CLIP (x, 0, src_image->bits.width - 1);
- y = CLIP (y, 0, src_image->bits.height - 1);
- inside_bounds = TRUE;
- break;
-
- case PIXMAN_REPEAT_REFLECT:
- x = MOD (x, src_image->bits.width * 2);
- if (x >= src_image->bits.width)
- x = src_image->bits.width * 2 - x - 1;
- y = MOD (y, src_image->bits.height * 2);
- if (y >= src_image->bits.height)
- y = src_image->bits.height * 2 - y - 1;
- inside_bounds = TRUE;
- break;
-
- case PIXMAN_REPEAT_NONE:
- default:
- inside_bounds =
- (x >= 0 &&
- x < src_image->bits.width &&
- y >= 0 &&
- y < src_image->bits.height);
- break;
- }
+ if (op == PIXMAN_OP_SRC)
+ memset (dst, 0, sizeof (*dst) * width);
+ }
+ else
+ {
+ int w = width;
+
+ uint32_t *src = src_line + y * src_stride;
- if (inside_bounds)
+ while (w >= 2)
{
- /* XXX: we should move this multiplication out of the loop */
- result = *(src + y * src_stride + x);
+ uint32_t s1, s2;
+ int x1, x2;
+
+ x1 = pixman_fixed_to_int (vx);
+ vx += unit_x;
+
+ x2 = pixman_fixed_to_int (vx);
+ vx += unit_x;
+
+ w -= 2;
+
+ s1 = fetch_nearest (src_repeat, src_format, src, x1, src_width);
+ s2 = fetch_nearest (src_repeat, src_format, src, x2, src_width);
+
+ if (op == PIXMAN_OP_OVER)
+ {
+ combine_over (s1, dst++);
+ combine_over (s2, dst++);
+ }
+ else
+ {
+ combine_src (s1, dst++);
+ combine_src (s2, dst++);
+ }
}
- else
+
+ while (w--)
{
- result = 0;
- }
- *(dst + i) = result;
+ uint32_t s;
+ int x;
- /* adjust the x location by a unit vector in the x direction:
- * this is equivalent to transforming x+1 of the destination
- * point to source space
- */
- vx += src_image->common.transform->matrix[0][0];
+ x = pixman_fixed_to_int (vx);
+ vx += unit_x;
+
+ s = fetch_nearest (src_repeat, src_format, src, x, src_width);
+
+ if (op == PIXMAN_OP_OVER)
+ combine_over (s, dst++);
+ else
+ combine_src (s, dst++);
+ }
}
- /* adjust the y location by a unit vector in the y direction
- * this is equivalent to transforming y+1 of the destination point
- * to source space
- */
- v.vector[1] += src_image->common.transform->matrix[1][1];
- dst += dst_stride;
}
}
-static void
-fast_path_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+static const pixman_fast_path_t c_fast_paths[] =
{
- if (src->type == BITS
- && src->common.transform
- && !mask
- && op == PIXMAN_OP_SRC
- && !src->common.alpha_map && !dest->common.alpha_map
- && (src->common.filter == PIXMAN_FILTER_NEAREST)
- && PIXMAN_FORMAT_BPP (dest->bits.format) == 32
- && src->bits.format == dest->bits.format
- && !src->bits.read_func && !src->bits.write_func
- && !dest->bits.read_func && !dest->bits.write_func)
- {
- /* ensure that the transform matrix only has a scale */
- if (src->common.transform->matrix[0][1] == 0 &&
- src->common.transform->matrix[1][0] == 0 &&
- src->common.transform->matrix[2][0] == 0 &&
- src->common.transform->matrix[2][1] == 0 &&
- src->common.transform->matrix[2][2] == pixman_fixed_1)
- {
- _pixman_walk_composite_region (imp, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height,
- fast_composite_src_scale_nearest);
- return;
- }
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5, fast_composite_over_n_1_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5, fast_composite_over_n_1_0565),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8000_8000),
+ PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1000_1000),
+ PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_8888_x888),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_8888_x888),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, fast_composite_src_x888_0565),
+ 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 (IN, a8, null, a8, fast_composite_in_8_8),
+ PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8),
+
+#define SCALED_NEAREST_FLAGS \
+ (FAST_PATH_SCALE_TRANSFORM | \
+ FAST_PATH_NO_ALPHA_MAP | \
+ FAST_PATH_NEAREST_FILTER | \
+ FAST_PATH_NO_ACCESSORS | \
+ FAST_PATH_NO_WIDE_FORMAT)
+
+#define NEAREST_FAST_PATH(op,s,d) \
+ { PIXMAN_OP_ ## op, \
+ PIXMAN_ ## s, SCALED_NEAREST_FLAGS, \
+ PIXMAN_null, 0, \
+ PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
+ fast_composite_scaled_nearest, \
}
- if (_pixman_run_fast_path (c_fast_paths, imp,
- op, src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height))
- {
- return;
- }
+ NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8),
+ NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8),
+ NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8),
+ NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8),
- _pixman_implementation_composite (imp->delegate, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
-}
+ NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8),
+ NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8),
+ NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8),
+ NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8),
+
+ NEAREST_FAST_PATH (OVER, x8r8g8b8, x8r8g8b8),
+ NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8),
+ NEAREST_FAST_PATH (OVER, x8b8g8r8, x8b8g8r8),
+ NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8),
+
+ NEAREST_FAST_PATH (OVER, x8r8g8b8, a8r8g8b8),
+ NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8),
+ NEAREST_FAST_PATH (OVER, x8b8g8r8, a8b8g8r8),
+ NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8),
+
+ { PIXMAN_OP_NONE },
+};
static void
pixman_fill8 (uint32_t *bits,
@@ -1587,11 +1737,9 @@ pixman_implementation_t *
_pixman_implementation_create_fast_path (void)
{
pixman_implementation_t *general = _pixman_implementation_create_general ();
- pixman_implementation_t *imp = _pixman_implementation_create (general);
+ pixman_implementation_t *imp = _pixman_implementation_create (general, c_fast_paths);
- imp->composite = fast_path_composite;
imp->fill = fast_path_fill;
return imp;
}
-
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index c96a3f9..bddf79a 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -264,26 +264,11 @@ general_composite_rect (pixman_implementation_t *imp,
free (scanline_buffer);
}
-static void
-general_composite (pixman_implementation_t * imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
+static const pixman_fast_path_t general_fast_path[] =
{
- _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y,
- mask_x, mask_y, dest_x, dest_y,
- width, height,
- general_composite_rect);
-}
+ { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
+ { PIXMAN_OP_NONE }
+};
static pixman_bool_t
general_blt (pixman_implementation_t *imp,
@@ -322,12 +307,11 @@ general_fill (pixman_implementation_t *imp,
pixman_implementation_t *
_pixman_implementation_create_general (void)
{
- pixman_implementation_t *imp = _pixman_implementation_create (NULL);
+ pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
_pixman_setup_combiner_functions_32 (imp);
_pixman_setup_combiner_functions_64 (imp);
- imp->composite = general_composite;
imp->blt = general_blt;
imp->fill = general_fill;
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index e55ba2c..6036c56 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -231,6 +231,12 @@ pixman_image_set_destroy_function (pixman_image_t * image,
image->common.destroy_data = data;
}
+PIXMAN_EXPORT void *
+pixman_image_get_destroy_data (pixman_image_t *image)
+{
+ return image->common.destroy_data;
+}
+
void
_pixman_image_reset_clip_region (pixman_image_t *image)
{
@@ -245,6 +251,9 @@ _pixman_image_validate (pixman_image_t *image)
image->common.property_changed (image);
image->common.dirty = FALSE;
}
+
+ if (image->common.alpha_map)
+ _pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
}
PIXMAN_EXPORT pixman_bool_t
@@ -588,7 +597,7 @@ _pixman_image_is_opaque (pixman_image_t *image)
break;
case SOLID:
- if (ALPHA_8 (image->solid.color) != 0xff)
+ if (image->solid.color.alpha != 0xffff)
return FALSE;
break;
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 6488332..bc3749e 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -28,30 +28,6 @@
#include "pixman-private.h"
static void
-delegate_composite (pixman_implementation_t * imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- _pixman_implementation_composite (imp->delegate,
- op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
-}
-
-static void
delegate_combine_32 (pixman_implementation_t * imp,
pixman_op_t op,
uint32_t * dest,
@@ -136,7 +112,8 @@ delegate_fill (pixman_implementation_t *imp,
}
pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate)
+_pixman_implementation_create (pixman_implementation_t *delegate,
+ const pixman_fast_path_t *fast_paths)
{
pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t));
pixman_implementation_t *d;
@@ -145,6 +122,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate)
if (!imp)
return NULL;
+ assert (fast_paths);
+
/* Make sure the whole delegate chain has the right toplevel */
imp->delegate = delegate;
for (d = imp; d != NULL; d = d->delegate)
@@ -152,7 +131,6 @@ _pixman_implementation_create (pixman_implementation_t *delegate)
/* Fill out function pointers with ones that just delegate
*/
- imp->composite = delegate_composite;
imp->blt = delegate_blt;
imp->fill = delegate_fill;
@@ -164,6 +142,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate)
imp->combine_64_ca[i] = delegate_combine_64_ca;
}
+ imp->fast_paths = fast_paths;
+
return imp;
}
@@ -211,27 +191,6 @@ _pixman_implementation_combine_64_ca (pixman_implementation_t * imp,
(*imp->combine_64_ca[op]) (imp, op, dest, src, mask, width);
}
-void
-_pixman_implementation_composite (pixman_implementation_t * imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- (*imp->composite) (imp, op,
- src, mask, dest,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y,
- width, height);
-}
-
pixman_bool_t
_pixman_implementation_blt (pixman_implementation_t * imp,
uint32_t * src_bits,
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 819e3a0..e084e7f 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -485,7 +485,7 @@ mmx_combine_over_reverse_u (pixman_implementation_t *imp,
{
__m64 d, da;
uint32_t s = combine (src, mask);
-
+
d = load8888 (*dest);
da = expand_alpha (d);
*dest = store8888 (over (d, da, load8888 (s)));
@@ -511,12 +511,12 @@ mmx_combine_in_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 x, a;
-
+
x = load8888 (combine (src, mask));
a = load8888 (*dest);
a = expand_alpha (a);
x = pix_multiply (x, a);
-
+
*dest = store8888 (x);
++dest;
@@ -540,7 +540,7 @@ mmx_combine_in_reverse_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 x, a;
-
+
x = load8888 (*dest);
a = load8888 (combine (src, mask));
a = expand_alpha (a);
@@ -568,7 +568,7 @@ mmx_combine_out_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 x, a;
-
+
x = load8888 (combine (src, mask));
a = load8888 (*dest);
a = expand_alpha (a);
@@ -597,7 +597,7 @@ mmx_combine_out_reverse_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 x, a;
-
+
x = load8888 (*dest);
a = load8888 (combine (src, mask));
a = expand_alpha (a);
@@ -627,7 +627,7 @@ mmx_combine_atop_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 s, da, d, sia;
-
+
s = load8888 (combine (src, mask));
d = load8888 (*dest);
sia = expand_alpha (s);
@@ -659,7 +659,7 @@ mmx_combine_atop_reverse_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 s, dia, d, sa;
-
+
s = load8888 (combine (src, mask));
d = load8888 (*dest);
sa = expand_alpha (s);
@@ -689,7 +689,7 @@ mmx_combine_xor_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 s, dia, d, sia;
-
+
s = load8888 (combine (src, mask));
d = load8888 (*dest);
sia = expand_alpha (s);
@@ -720,7 +720,7 @@ mmx_combine_add_u (pixman_implementation_t *imp,
while (dest < end)
{
__m64 s, d;
-
+
s = load8888 (combine (src, mask));
d = load8888 (*dest);
s = pix_add (s, d);
@@ -785,7 +785,7 @@ mmx_combine_src_ca (pixman_implementation_t *imp,
{
__m64 a = load8888 (*mask);
__m64 s = load8888 (*src);
-
+
s = pix_multiply (s, a);
*dest = store8888 (s);
@@ -864,7 +864,7 @@ mmx_combine_in_ca (pixman_implementation_t *imp,
__m64 s = load8888 (*src);
__m64 d = load8888 (*dest);
__m64 da = expand_alpha (d);
-
+
s = pix_multiply (s, a);
s = pix_multiply (s, da);
*dest = store8888 (s);
@@ -892,7 +892,7 @@ mmx_combine_in_reverse_ca (pixman_implementation_t *imp,
__m64 s = load8888 (*src);
__m64 d = load8888 (*dest);
__m64 sa = expand_alpha (s);
-
+
a = pix_multiply (a, sa);
d = pix_multiply (d, a);
*dest = store8888 (d);
@@ -920,7 +920,7 @@ mmx_combine_out_ca (pixman_implementation_t *imp,
__m64 s = load8888 (*src);
__m64 d = load8888 (*dest);
__m64 da = expand_alpha (d);
-
+
da = negate (da);
s = pix_multiply (s, a);
s = pix_multiply (s, da);
@@ -1102,7 +1102,7 @@ mmx_composite_over_n_8888 (pixman_implementation_t *imp,
{
uint32_t src;
uint32_t *dst_line, *dst;
- uint16_t w;
+ int32_t w;
int dst_stride;
__m64 vsrc, vsrca;
@@ -1181,7 +1181,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
{
uint32_t src;
uint16_t *dst_line, *dst;
- uint16_t w;
+ int32_t w;
int dst_stride;
__m64 vsrc, vsrca;
@@ -1209,7 +1209,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
{
uint64_t d = *dst;
__m64 vdest = expand565 (M64 (d), 0);
-
+
vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
*dst = UINT64 (vdest);
@@ -1240,7 +1240,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
{
uint64_t d = *dst;
__m64 vdest = expand565 (M64 (d), 0);
-
+
vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
*dst = UINT64 (vdest);
@@ -1376,7 +1376,7 @@ mmx_composite_over_8888_n_8888 (pixman_implementation_t *imp,
uint32_t mask;
__m64 vmask;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
__m64 srca;
CHECKPOINT ();
@@ -1461,7 +1461,7 @@ mmx_composite_over_x888_n_8888 (pixman_implementation_t *imp,
uint32_t mask;
__m64 vmask;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
__m64 srca;
CHECKPOINT ();
@@ -1596,7 +1596,7 @@ mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
uint32_t s;
int dst_stride, src_stride;
uint8_t a;
- uint16_t w;
+ int32_t w;
CHECKPOINT ();
@@ -1615,7 +1615,7 @@ mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
{
s = *src++;
a = s >> 24;
-
+
if (a == 0xff)
{
*dst = s;
@@ -1627,7 +1627,7 @@ mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
sa = expand_alpha (ms);
*dst = store8888 (over (ms, sa, load8888 (*dst)));
}
-
+
dst++;
}
}
@@ -1652,7 +1652,7 @@ mmx_composite_over_8888_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
CHECKPOINT ();
@@ -1756,7 +1756,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
__m64 vsrc, vsrca;
uint64_t srcsrc;
@@ -1795,7 +1795,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
__m64 vdest = in_over (vsrc, vsrca,
expand_alpha_rev (M64 (m)),
load8888 (*dst));
-
+
*dst = store8888 (vdest);
}
@@ -1809,7 +1809,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
while (w >= 2)
{
uint64_t m0, m1;
-
+
m0 = *mask;
m1 = *(mask + 1);
@@ -1883,22 +1883,13 @@ pixman_fill_mmx (uint32_t *bits,
if (bpp != 16 && bpp != 32 && bpp != 8)
return FALSE;
- if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
- return FALSE;
-
- if (bpp == 8 &&
- ((xor >> 16 != (xor & 0xffff)) ||
- (xor >> 24 != (xor & 0x00ff) >> 16)))
- {
- return FALSE;
- }
-
if (bpp == 8)
{
stride = stride * (int) sizeof (uint32_t) / 1;
byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x);
byte_width = width;
stride *= 1;
+ xor = (xor & 0xff) * 0x01010101;
}
else if (bpp == 16)
{
@@ -1906,6 +1897,7 @@ pixman_fill_mmx (uint32_t *bits,
byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
byte_width = 2 * width;
stride *= 2;
+ xor = (xor & 0xffff) * 0x00010001;
}
else
{
@@ -1928,7 +1920,7 @@ pixman_fill_mmx (uint32_t *bits,
"movq %7, %5\n"
"movq %7, %6\n"
: "=y" (v1), "=y" (v2), "=y" (v3),
- "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+ "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
: "y" (vfill));
#endif
@@ -1936,7 +1928,7 @@ pixman_fill_mmx (uint32_t *bits,
{
int w;
uint8_t *d = byte_line;
-
+
byte_line += stride;
w = byte_width;
@@ -1976,8 +1968,8 @@ pixman_fill_mmx (uint32_t *bits,
"movq %8, 56(%0)\n"
:
: "r" (d),
- "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
- "y" (v4), "y" (v5), "y" (v6), "y" (v7)
+ "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
+ "y" (v4), "y" (v5), "y" (v6), "y" (v7)
: "memory");
#else
*(__m64*) (d + 0) = vfill;
@@ -2038,7 +2030,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
__m64 vsrc, vsrca;
uint64_t srcsrc;
@@ -2080,7 +2072,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
if (m)
{
__m64 vdest = in (vsrc, expand_alpha_rev (M64 (m)));
-
+
*dst = store8888 (vdest);
}
else
@@ -2136,7 +2128,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
if (m)
{
__m64 vdest = load8888 (*dst);
-
+
vdest = in (vsrc, expand_alpha_rev (M64 (m)));
*dst = store8888 (vdest);
}
@@ -2173,7 +2165,7 @@ mmx_composite_over_n_8_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
__m64 vsrc, vsrca, tmp;
uint64_t srcsrcsrcsrc, src16;
@@ -2218,7 +2210,7 @@ mmx_composite_over_n_8_0565 (pixman_implementation_t *imp,
__m64 vd = M64 (d);
__m64 vdest = in_over (
vsrc, vsrca, expand_alpha_rev (M64 (m)), expand565 (vd, 0));
-
+
vd = pack_565 (vdest, _mm_setzero_si64 (), 0);
*dst = UINT64 (vd);
}
@@ -2313,7 +2305,7 @@ mmx_composite_over_pixbuf_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
CHECKPOINT ();
@@ -2433,7 +2425,7 @@ mmx_composite_over_pixbuf_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
CHECKPOINT ();
@@ -2641,7 +2633,7 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t src;
uint8_t sa;
__m64 vsrc, vsrca;
@@ -2723,7 +2715,7 @@ mmx_composite_in_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int src_stride, dst_stride;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
@@ -2788,7 +2780,7 @@ mmx_composite_add_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t src;
uint8_t sa;
__m64 vsrc, vsrca;
@@ -2868,7 +2860,7 @@ mmx_composite_add_8000_8000 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint8_t s, d;
uint16_t t;
@@ -2942,7 +2934,7 @@ mmx_composite_add_8888_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
CHECKPOINT ();
@@ -3082,8 +3074,8 @@ pixman_blt_mmx (uint32_t *src_bits,
:
: "r" (d), "r" (s)
: "memory",
- "%mm0", "%mm1", "%mm2", "%mm3",
- "%mm4", "%mm5", "%mm6", "%mm7");
+ "%mm0", "%mm1", "%mm2", "%mm3",
+ "%mm4", "%mm5", "%mm6", "%mm7");
#else
__m64 v0 = *(__m64 *)(s + 0);
__m64 v1 = *(__m64 *)(s + 8);
@@ -3173,7 +3165,7 @@ mmx_composite_over_x888_8_8888 (pixman_implementation_t *imp,
uint32_t *dst, *dst_line;
uint8_t *mask, *mask_line;
int src_stride, mask_stride, dst_stride;
- uint16_t w;
+ int32_t w;
PIXMAN_IMAGE_GET_LINE (dst_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);
@@ -3224,107 +3216,78 @@ mmx_composite_over_x888_8_8888 (pixman_implementation_t *imp,
static const pixman_fast_path_t mmx_fast_paths[] =
{
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, mmx_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, mmx_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, mmx_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, mmx_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, mmx_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, mmx_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, mmx_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_x8r8g8b8, mmx_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_r5g6b5, mmx_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_a8b8g8r8, mmx_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_x8b8g8r8, mmx_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_b5g6r5, mmx_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_a8r8g8b8, mmx_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_x8r8g8b8, mmx_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_r5g6b5, mmx_composite_over_pixbuf_0565 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_a8b8g8r8, mmx_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_x8b8g8r8, mmx_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_b5g6r5, mmx_composite_over_pixbuf_0565 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, mmx_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, mmx_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_solid, PIXMAN_a8b8g8r8, mmx_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_solid, PIXMAN_x8b8g8r8, mmx_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, mmx_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, mmx_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_solid, PIXMAN_a8b8g8r8, mmx_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_solid, PIXMAN_x8b8g8r8, mmx_composite_over_8888_n_8888 },
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mmx_composite_over_n_8_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mmx_composite_over_n_8_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mmx_composite_over_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mmx_composite_over_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mmx_composite_over_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mmx_composite_over_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mmx_composite_over_n_8888_8888_ca ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mmx_composite_over_n_8888_8888_ca ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mmx_composite_over_n_8888_0565_ca ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mmx_composite_over_n_8888_8888_ca ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mmx_composite_over_n_8888_8888_ca ),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mmx_composite_over_n_8888_0565_ca ),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, mmx_composite_over_pixbuf_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, mmx_composite_over_pixbuf_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, mmx_composite_over_pixbuf_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, mmx_composite_over_pixbuf_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, mmx_composite_over_pixbuf_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, mmx_composite_over_pixbuf_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, mmx_composite_over_x888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, mmx_composite_over_x888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, mmx_composite_over_x888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, mmx_composite_over_x888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mmx_composite_over_8888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mmx_composite_over_8888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, mmx_composite_over_8888_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, mmx_composite_over_8888_n_8888 ),
#if 0
- /* FIXME: This code is commented out since it's apparently not actually faster than the generic code. */
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, mmx_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, mmx_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_x8b8g8r8, mmx_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8, PIXMAN_a8r8g8b8, mmx_composite_over_x888_8_8888 },
+ /* FIXME: This code is commented out since it's apparently
+ * not actually faster than the generic code.
+ */
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, mmx_composite_over_x888_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, x8b8g8r8, mmx_composite_over_x888_8_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8r8g8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ),
#endif
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, mmx_composite_over_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, mmx_composite_over_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, mmx_composite_over_n_0565 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, mmx_composite_copy_area },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, mmx_composite_copy_area },
-
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, mmx_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, mmx_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, mmx_composite_over_8888_0565 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, mmx_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, mmx_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, mmx_composite_over_8888_0565 },
-
- { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, mmx_composite_add_8888_8888 },
- { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, mmx_composite_add_8888_8888 },
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, mmx_composite_add_8000_8000 },
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, mmx_composite_add_n_8_8 },
-
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, mmx_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, mmx_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, mmx_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, mmx_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, mmx_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, mmx_composite_copy_area },
-
- { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, mmx_composite_in_8_8 },
- { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, mmx_composite_in_n_8_8 },
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mmx_composite_over_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mmx_composite_over_n_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mmx_composite_over_n_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
+
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mmx_composite_over_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mmx_composite_over_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mmx_composite_over_8888_0565 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mmx_composite_over_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mmx_composite_over_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mmx_composite_over_8888_0565 ),
+
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mmx_composite_add_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mmx_composite_add_8888_8888 ),
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mmx_composite_add_8000_8000 ),
+ PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mmx_composite_add_n_8_8 ),
+
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mmx_composite_src_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mmx_composite_src_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mmx_composite_src_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mmx_composite_src_n_8_8888 ),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mmx_composite_copy_area ),
+ PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mmx_composite_copy_area ),
+
+ PIXMAN_STD_FAST_PATH (IN, a8, null, a8, mmx_composite_in_8_8 ),
+ PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, mmx_composite_in_n_8_8 ),
{ PIXMAN_OP_NONE },
};
-static void
-mmx_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- if (_pixman_run_fast_path (mmx_fast_paths, imp,
- op, src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height))
- {
- return;
- }
-
- _pixman_implementation_composite (imp->delegate,
- op, src, mask, dest, src_x, src_y,
- mask_x, mask_y, dest_x, dest_y,
- width, height);
-}
-
static pixman_bool_t
mmx_blt (pixman_implementation_t *imp,
uint32_t * src_bits,
@@ -3346,9 +3309,9 @@ mmx_blt (pixman_implementation_t *imp,
{
return _pixman_implementation_blt (
- imp->delegate,
- src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
- src_x, src_y, dst_x, dst_y, width, height);
+ imp->delegate,
+ src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
+ src_x, src_y, dst_x, dst_y, width, height);
}
return TRUE;
@@ -3368,7 +3331,7 @@ mmx_fill (pixman_implementation_t *imp,
if (!pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
{
return _pixman_implementation_fill (
- imp->delegate, bits, stride, bpp, x, y, width, height, xor);
+ imp->delegate, bits, stride, bpp, x, y, width, height, xor);
}
return TRUE;
@@ -3378,7 +3341,7 @@ pixman_implementation_t *
_pixman_implementation_create_mmx (void)
{
pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
- pixman_implementation_t *imp = _pixman_implementation_create (general);
+ pixman_implementation_t *imp = _pixman_implementation_create (general, mmx_fast_paths);
imp->combine_32[PIXMAN_OP_OVER] = mmx_combine_over_u;
imp->combine_32[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_u;
@@ -3404,7 +3367,6 @@ _pixman_implementation_create_mmx (void)
imp->combine_32_ca[PIXMAN_OP_XOR] = mmx_combine_xor_ca;
imp->combine_32_ca[PIXMAN_OP_ADD] = mmx_combine_add_ca;
- imp->composite = mmx_composite;
imp->blt = mmx_blt;
imp->fill = mmx_fill;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0745149..7ed8aa7 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -114,7 +114,10 @@ struct source_image
struct solid_fill
{
source_image_t common;
- uint32_t color; /* FIXME: shouldn't this be a pixman_color_t? */
+ pixman_color_t color;
+
+ uint32_t color_32;
+ uint64_t color_64;
};
struct gradient
@@ -254,10 +257,6 @@ _pixman_image_store_scanline_32 (bits_image_t * image,
int y,
int width,
const uint32_t *buffer);
-void
-_pixman_image_fetch_pixels (bits_image_t *image,
- uint32_t * buffer,
- int n_pixels);
/* Even though the type of buffer is uint32_t *, the function
* actually expects a uint64_t *buffer.
@@ -373,7 +372,6 @@ pixman_rasterize_edges_accessors (pixman_image_t *image,
/*
* Implementations
*/
-
typedef struct pixman_implementation_t pixman_implementation_t;
typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
@@ -429,23 +427,36 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
-struct pixman_implementation_t
+typedef struct
{
- pixman_implementation_t *toplevel;
- pixman_implementation_t *delegate;
-
- pixman_composite_func_t composite;
- pixman_blt_func_t blt;
- pixman_fill_func_t fill;
+ pixman_op_t op;
+ pixman_format_code_t src_format;
+ uint32_t src_flags;
+ pixman_format_code_t mask_format;
+ uint32_t mask_flags;
+ pixman_format_code_t dest_format;
+ uint32_t dest_flags;
+ pixman_composite_func_t func;
+} pixman_fast_path_t;
- pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
- pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
- pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS];
- pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS];
+struct pixman_implementation_t
+{
+ pixman_implementation_t * toplevel;
+ pixman_implementation_t * delegate;
+ const pixman_fast_path_t * fast_paths;
+
+ pixman_blt_func_t blt;
+ pixman_fill_func_t fill;
+
+ pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
+ pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
+ pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS];
+ pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS];
};
pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate);
+_pixman_implementation_create (pixman_implementation_t *delegate,
+ const pixman_fast_path_t *fast_paths);
void
_pixman_implementation_combine_32 (pixman_implementation_t *imp,
@@ -475,20 +486,6 @@ _pixman_implementation_combine_64_ca (pixman_implementation_t *imp,
const uint64_t * src,
const uint64_t * mask,
int width);
-void
-_pixman_implementation_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height);
pixman_bool_t
_pixman_implementation_blt (pixman_implementation_t *imp,
@@ -562,19 +559,73 @@ _pixman_choose_implementation (void);
*/
#define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0)
#define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0)
-#define PIXMAN_a8r8g8b8_ca PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
-#define PIXMAN_a8b8g8r8_ca PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
-#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
-#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
-
-typedef struct
-{
- pixman_op_t op;
- pixman_format_code_t src_format;
- pixman_format_code_t mask_format;
- pixman_format_code_t dest_format;
- pixman_composite_func_t func;
-} pixman_fast_path_t;
+#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
+#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
+#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
+#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
+
+#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1)
+
+#define FAST_PATH_ID_TRANSFORM (1 << 0)
+#define FAST_PATH_NO_ALPHA_MAP (1 << 1)
+#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2)
+#define FAST_PATH_NO_PAD_REPEAT (1 << 3)
+#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4)
+#define FAST_PATH_NO_ACCESSORS (1 << 5)
+#define FAST_PATH_NO_WIDE_FORMAT (1 << 6)
+#define FAST_PATH_COVERS_CLIP (1 << 7)
+#define FAST_PATH_COMPONENT_ALPHA (1 << 8)
+#define FAST_PATH_UNIFIED_ALPHA (1 << 9)
+#define FAST_PATH_SCALE_TRANSFORM (1 << 10)
+#define FAST_PATH_NEAREST_FILTER (1 << 11)
+
+#define _FAST_PATH_STANDARD_FLAGS \
+ (FAST_PATH_ID_TRANSFORM | \
+ FAST_PATH_NO_ALPHA_MAP | \
+ FAST_PATH_NO_CONVOLUTION_FILTER | \
+ FAST_PATH_NO_PAD_REPEAT | \
+ FAST_PATH_NO_REFLECT_REPEAT | \
+ FAST_PATH_NO_ACCESSORS | \
+ FAST_PATH_NO_WIDE_FORMAT | \
+ FAST_PATH_COVERS_CLIP)
+
+#define FAST_PATH_STD_SRC_FLAGS \
+ _FAST_PATH_STANDARD_FLAGS
+#define FAST_PATH_STD_MASK_U_FLAGS \
+ (_FAST_PATH_STANDARD_FLAGS | \
+ FAST_PATH_UNIFIED_ALPHA)
+#define FAST_PATH_STD_MASK_CA_FLAGS \
+ (_FAST_PATH_STANDARD_FLAGS | \
+ FAST_PATH_COMPONENT_ALPHA)
+#define FAST_PATH_STD_DEST_FLAGS \
+ (FAST_PATH_NO_ACCESSORS | \
+ FAST_PATH_NO_WIDE_FORMAT)
+
+#define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \
+ PIXMAN_OP_ ## op, \
+ PIXMAN_ ## src, \
+ src_flags, \
+ PIXMAN_ ## mask, \
+ mask_flags, \
+ PIXMAN_ ## dest, \
+ dest_flags, \
+ func
+
+#define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \
+ { FAST_PATH ( \
+ op, \
+ src, FAST_PATH_STD_SRC_FLAGS, \
+ mask, (PIXMAN_ ## mask) ? FAST_PATH_STD_MASK_U_FLAGS : 0, \
+ dest, FAST_PATH_STD_DEST_FLAGS, \
+ func) }
+
+#define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \
+ { FAST_PATH ( \
+ op, \
+ src, FAST_PATH_STD_SRC_FLAGS, \
+ mask, FAST_PATH_STD_MASK_CA_FLAGS, \
+ dest, FAST_PATH_STD_DEST_FLAGS, \
+ func) }
/* Memory allocation helpers */
void *
@@ -590,38 +641,6 @@ pixman_bool_t
pixman_addition_overflows_int (unsigned int a, unsigned int b);
/* Compositing utilities */
-pixman_bool_t
-_pixman_run_fast_path (const pixman_fast_path_t *paths,
- pixman_implementation_t * imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height);
-
-void
-_pixman_walk_composite_region (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height,
- pixman_composite_func_t composite_rect);
-
void
pixman_expand (uint64_t * dst,
const uint32_t * src,
@@ -690,23 +709,50 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
PIXMAN_FORMAT_G (f) > 8 || \
PIXMAN_FORMAT_B (f) > 8)
+#ifdef WORDS_BIGENDIAN
+# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
+#else
+# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
+#endif
+
/*
* Various debugging code
*/
#undef DEBUG
-#define DEBUG 0
-#if DEBUG
+/* Turn on debugging depending on what type of release this is
+ */
+#if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1))
+
+/* Debugging gets turned on for development releases because these
+ * are the things that end up in bleeding edge distributions such
+ * as Rawhide etc.
+ *
+ * For performance reasons we don't turn it on for stable releases or
+ * random git checkouts. (Random git checkouts are often used for
+ * performance work).
+ */
+
+# define DEBUG
+
+#endif
+
+#ifdef DEBUG
+
+void
+_pixman_log_error (const char *function, const char *message);
#define return_if_fail(expr) \
do \
{ \
- if (!(expr)) \
- { \
- fprintf (stderr, "In %s: %s failed\n", FUNC, # expr); \
- return; \
- } \
+ if (!(expr)) \
+ { \
+ _pixman_log_error (FUNC, "The expression " # expr " was false"); \
+ return; \
+ } \
} \
while (0)
@@ -714,16 +760,27 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
do \
{ \
if (!(expr)) \
- { \
- fprintf (stderr, "In %s: %s failed\n", FUNC, # expr); \
- return (retval); \
- } \
+ { \
+ _pixman_log_error (FUNC, "The expression " # expr " was false"); \
+ return (retval); \
+ } \
} \
while (0)
+#define critical_if_fail(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ _pixman_log_error (FUNC, "The expression " # expr " was false"); \
+ } \
+ while (0)
+
+
#else
-#define return_if_fail(expr) \
+#define _pixman_log_error(f,m) do { } while (0) \
+
+#define return_if_fail(expr) \
do \
{ \
if (!(expr)) \
@@ -739,6 +796,11 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
} \
while (0)
+#define critical_if_fail(expr) \
+ do \
+ { \
+ } \
+ while (0)
#endif
/*
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index f88955f..a6a4005 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -42,6 +42,25 @@
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
@@ -66,41 +85,17 @@
#define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
#define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
-#define noPIXMAN_REGION_LOG_FAILURES
-
-#if defined PIXMAN_REGION_LOG_FAILURES || defined PIXMAN_REGION_DEBUG
-
-static void
-log_region_error (const char *function, const char *message)
-{
- static int n_messages = 0;
-
- if (n_messages < 50)
- {
- fprintf (stderr,
- "*** BUG ***\n"
- "%s: %s\n"
- "Set a breakpoint on 'log_region_error' to debug\n\n",
- function, message);
-
-#if defined PIXMAN_REGION_DEBUG
- abort ();
-#endif
-
- n_messages++;
- }
-}
+#ifdef DEBUG
#define GOOD(reg) \
do \
{ \
if (!PREFIX (_selfcheck (reg))) \
- log_region_error (FUNC, "Malformed region " # reg); \
+ _pixman_log_error (FUNC, "Malformed region " # reg); \
} while (0)
#else
-#define log_region_error(function, name)
#define GOOD(reg)
#endif
@@ -262,7 +257,7 @@ alloc_data (size_t n)
} \
ADDRECT (next_rect, nx1, ny1, nx2, ny2); \
region->data->numRects++; \
- assert (region->data->numRects <= region->data->size); \
+ critical_if_fail (region->data->numRects <= region->data->size); \
} while (0)
#define DOWNSIZE(reg, numRects) \
@@ -387,7 +382,7 @@ PREFIX (_init_rect) (region_type_t * region,
if (!GOOD_RECT (&region->extents))
{
if (BAD_RECT (&region->extents))
- log_region_error (FUNC, "Invalid rectangle passed");
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
PREFIX (_init) (region);
return;
}
@@ -401,7 +396,7 @@ PREFIX (_init_with_extents) (region_type_t *region, box_type_t *extents)
if (!GOOD_RECT (extents))
{
if (BAD_RECT (extents))
- log_region_error (FUNC, "Invalid rectangle passed");
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
PREFIX (_init) (region);
return;
}
@@ -579,7 +574,7 @@ pixman_coalesce (region_type_t * region, /* Region to coalesce */
* Figure out how many rectangles are in the band.
*/
numRects = cur_start - prev_start;
- assert (numRects == region->data->numRects - cur_start);
+ critical_if_fail (numRects == region->data->numRects - cur_start);
if (!numRects) return cur_start;
@@ -667,8 +662,8 @@ pixman_region_append_non_o (region_type_t * region,
new_rects = r_end - r;
- assert (y1 < y2);
- assert (new_rects != 0);
+ critical_if_fail (y1 < y2);
+ critical_if_fail (new_rects != 0);
/* Make sure we have enough space for all rectangles to be added */
RECTALLOC (region, new_rects);
@@ -677,7 +672,7 @@ pixman_region_append_non_o (region_type_t * region,
do
{
- assert (r->x1 < r->x2);
+ critical_if_fail (r->x1 < r->x2);
ADDRECT (next_rect, r->x1, y1, r->x2, y2);
r++;
}
@@ -802,8 +797,8 @@ pixman_op (region_type_t * new_reg, /* Place to store result
r2 = PIXREGION_RECTS (reg2);
r2_end = r2 + numRects;
- assert (r1 != r1_end);
- assert (r2 != r2_end);
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
old_data = (region_data_type_t *)NULL;
@@ -871,8 +866,8 @@ pixman_op (region_type_t * new_reg, /* Place to store result
* rectangle after the last one in the current band for their
* respective regions.
*/
- assert (r1 != r1_end);
- assert (r2 != r2_end);
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
FIND_BAND (r1, r1_band_end, r1_end, r1y1);
FIND_BAND (r2, r2_band_end, r2_end, r2y1);
@@ -1079,7 +1074,7 @@ pixman_set_extents (region_type_t *region)
region->extents.x2 = box_end->x2;
region->extents.y2 = box_end->y2;
- assert (region->extents.y1 < region->extents.y2);
+ critical_if_fail (region->extents.y1 < region->extents.y2);
while (box <= box_end)
{
@@ -1090,7 +1085,7 @@ pixman_set_extents (region_type_t *region)
box++;
}
- assert (region->extents.x1 < region->extents.x2);
+ critical_if_fail (region->extents.x1 < region->extents.x2);
}
/*======================================================================
@@ -1126,8 +1121,8 @@ pixman_region_intersect_o (region_type_t *region,
next_rect = PIXREGION_TOP (region);
- assert (y1 < y2);
- assert (r1 != r1_end && r2 != r2_end);
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
do
{
@@ -1284,8 +1279,8 @@ pixman_region_union_o (region_type_t *region,
int x1; /* left and right side of current union */
int x2;
- assert (y1 < y2);
- assert (r1 != r1_end && r2 != r2_end);
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
next_rect = PIXREGION_TOP (region);
@@ -1355,10 +1350,10 @@ PREFIX (_union_rect) (region_type_t *dest,
if (!GOOD_RECT (&region.extents))
{
if (BAD_RECT (&region.extents))
- log_region_error (FUNC, "Invalid rectangle passed");
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
return PREFIX (_copy) (dest, source);
}
-
+
region.data = NULL;
return PREFIX (_union) (dest, source, &region);
@@ -1848,8 +1843,8 @@ pixman_region_subtract_o (region_type_t * region,
x1 = r1->x1;
- assert (y1 < y2);
- assert (r1 != r1_end && r2 != r2_end);
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
next_rect = PIXREGION_TOP (region);
@@ -1893,7 +1888,7 @@ pixman_region_subtract_o (region_type_t * region,
* Left part of subtrahend covers part of minuend: add uncovered
* part of minuend to region and skip to next subtrahend.
*/
- assert (x1 < r2->x1);
+ critical_if_fail (x1 < r2->x1);
NEWRECT (region, next_rect, x1, y1, r2->x1, y2);
x1 = r2->x2;
@@ -1935,7 +1930,7 @@ pixman_region_subtract_o (region_type_t * region,
*/
while (r1 != r1_end)
{
- assert (x1 < r1->x2);
+ critical_if_fail (x1 < r1->x2);
NEWRECT (region, next_rect, x1, y1, r1->x2, y2);
@@ -2297,7 +2292,7 @@ PREFIX (_reset) (region_type_t *region, box_type_t *box)
{
GOOD (region);
- assert (GOOD_RECT (box));
+ critical_if_fail (GOOD_RECT (box));
region->extents = *box;
@@ -2437,7 +2432,7 @@ PREFIX (_selfcheck) (region_type_t *reg)
PIXMAN_EXPORT pixman_bool_t
PREFIX (_init_rects) (region_type_t *region,
- box_type_t *boxes, int count)
+ const box_type_t *boxes, int count)
{
box_type_t *rects;
int displacement;
@@ -2517,3 +2512,240 @@ PREFIX (_init_rects) (region_type_t *region,
return validate (region, &i);
}
+
+#define READ(_ptr) (*(_ptr))
+
+static inline box_type_t *
+bitmap_addrect (region_type_t *reg,
+ box_type_t *r,
+ box_type_t **first_rect,
+ int rx1, int ry1,
+ int rx2, int ry2)
+{
+ if ((rx1 < rx2) && (ry1 < ry2) &&
+ (!(reg->data->numRects &&
+ ((r-1)->y1 == ry1) && ((r-1)->y2 == ry2) &&
+ ((r-1)->x1 <= rx1) && ((r-1)->x2 >= rx2))))
+ {
+ if (!reg->data ||
+ reg->data->numRects == reg->data->size)
+ {
+ if (!pixman_rect_alloc (reg, 1))
+ return NULL;
+ *first_rect = PIXREGION_BOXPTR(reg);
+ r = *first_rect + reg->data->numRects;
+ }
+ r->x1 = rx1;
+ r->y1 = ry1;
+ r->x2 = rx2;
+ r->y2 = ry2;
+ reg->data->numRects++;
+ if (r->x1 < reg->extents.x1)
+ reg->extents.x1 = r->x1;
+ if (r->x2 > reg->extents.x2)
+ reg->extents.x2 = r->x2;
+ r++;
+ }
+ return r;
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ * Stride is in number of uint32_t per line.
+ */
+PIXMAN_EXPORT void
+PREFIX (_init_from_image) (region_type_t *region,
+ pixman_image_t *image)
+{
+ uint32_t mask0 = 0xffffffff & ~SCREEN_SHIFT_RIGHT(0xffffffff, 1);
+ box_type_t *first_rect, *rects, *prect_line_start;
+ box_type_t *old_rect, *new_rect;
+ uint32_t *pw, w, *pw_line, *pw_line_end;
+ int irect_prev_start, irect_line_start;
+ int h, base, rx1 = 0, crects;
+ int ib;
+ pixman_bool_t in_box, same;
+ int width, height, stride;
+
+ PREFIX(_init) (region);
+
+ return_if_fail (image->type == BITS);
+ return_if_fail (image->bits.format == PIXMAN_a1);
+
+ pw_line = pixman_image_get_data (image);
+ width = pixman_image_get_width (image);
+ height = pixman_image_get_height (image);
+ stride = pixman_image_get_stride (image) / 4;
+
+ first_rect = PIXREGION_BOXPTR(region);
+ rects = first_rect;
+
+ region->extents.x1 = width - 1;
+ region->extents.x2 = 0;
+ irect_prev_start = -1;
+ for (h = 0; h < height; h++)
+ {
+ pw = pw_line;
+ pw_line += stride;
+ irect_line_start = rects - first_rect;
+
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if (READ(pw) & mask0)
+ {
+ in_box = TRUE;
+ rx1 = 0;
+ }
+ else
+ {
+ in_box = FALSE;
+ }
+
+ /* Process all words which are fully in the pixmap */
+ pw_line_end = pw + (width >> 5);
+ for (base = 0; pw < pw_line_end; base += 32)
+ {
+ w = READ(pw++);
+ if (in_box)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for (ib = 0; ib < 32; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ rects = bitmap_addrect (region, rects, &first_rect,
+ rx1, h, base + ib, h + 1);
+ if (rects == NULL)
+ goto error;
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+
+ if (width & 31)
+ {
+ /* Process final partial word on line */
+ w = READ(pw++);
+ for (ib = 0; ib < (width & 31); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ rects = bitmap_addrect(region, rects, &first_rect,
+ rx1, h, base + ib, h + 1);
+ if (rects == NULL)
+ goto error;
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if (in_box)
+ {
+ rects = bitmap_addrect(region, rects, &first_rect,
+ rx1, h, base + (width & 31), h + 1);
+ if (rects == NULL)
+ goto error;
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ same = FALSE;
+ if (irect_prev_start != -1)
+ {
+ crects = irect_line_start - irect_prev_start;
+ if (crects != 0 &&
+ crects == ((rects - first_rect) - irect_line_start))
+ {
+ old_rect = first_rect + irect_prev_start;
+ new_rect = prect_line_start = first_rect + irect_line_start;
+ same = TRUE;
+ while (old_rect < prect_line_start)
+ {
+ if ((old_rect->x1 != new_rect->x1) ||
+ (old_rect->x2 != new_rect->x2))
+ {
+ same = FALSE;
+ break;
+ }
+ old_rect++;
+ new_rect++;
+ }
+ if (same)
+ {
+ old_rect = first_rect + irect_prev_start;
+ while (old_rect < prect_line_start)
+ {
+ old_rect->y2 += 1;
+ old_rect++;
+ }
+ rects -= crects;
+ region->data->numRects -= crects;
+ }
+ }
+ }
+ if(!same)
+ irect_prev_start = irect_line_start;
+ }
+ if (!region->data->numRects)
+ {
+ region->extents.x1 = region->extents.x2 = 0;
+ }
+ else
+ {
+ region->extents.y1 = PIXREGION_BOXPTR(region)->y1;
+ region->extents.y2 = PIXREGION_END(region)->y2;
+ if (region->data->numRects == 1)
+ {
+ free (region->data);
+ region->data = NULL;
+ }
+ }
+
+ error:
+ return;
+}
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 38675dc..48c999a 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -36,7 +36,7 @@ solid_fill_get_scanline_32 (pixman_image_t *image,
uint32_t mask_bits)
{
uint32_t *end = buffer + width;
- register uint32_t color = ((solid_fill_t *)image)->color;
+ uint32_t color = image->solid.color_32;
while (buffer < end)
*(buffer++) = color;
@@ -44,6 +44,23 @@ solid_fill_get_scanline_32 (pixman_image_t *image,
return;
}
+static void
+solid_fill_get_scanline_64 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask,
+ uint32_t mask_bits)
+{
+ uint64_t *b = (uint64_t *)buffer;
+ uint64_t *e = b + width;
+ uint64_t color = image->solid.color_64;
+
+ while (b < e)
+ *(b++) = color;
+}
+
static source_image_class_t
solid_fill_classify (pixman_image_t *image,
int x,
@@ -58,7 +75,7 @@ static void
solid_fill_property_changed (pixman_image_t *image)
{
image->common.get_scanline_32 = solid_fill_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
+ image->common.get_scanline_64 = solid_fill_get_scanline_64;
}
static uint32_t
@@ -71,6 +88,16 @@ color_to_uint32 (const pixman_color_t *color)
(color->blue >> 8);
}
+static uint64_t
+color_to_uint64 (const pixman_color_t *color)
+{
+ return
+ ((uint64_t)color->alpha << 48) |
+ ((uint64_t)color->red << 32) |
+ ((uint64_t)color->green << 16) |
+ ((uint64_t)color->blue);
+}
+
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_solid_fill (pixman_color_t *color)
{
@@ -80,7 +107,9 @@ pixman_image_create_solid_fill (pixman_color_t *color)
return NULL;
img->type = SOLID;
- img->solid.color = color_to_uint32 (color);
+ img->solid.color = *color;
+ img->solid.color_32 = color_to_uint32 (color);
+ img->solid.color_64 = color_to_uint64 (color);
img->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
img->common.classify = solid_fill_classify;
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 78b0ad1..946e7ba 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -998,7 +998,7 @@ core_combine_reverse_out_u_sse2 (uint32_t* pd,
pix_multiply_1x64 (
unpack_32_1x64 (d), negate_1x64 (
expand_alpha_1x64 (unpack_32_1x64 (s)))));
-
+
if (pm)
pm++;
ps++;
@@ -2652,8 +2652,8 @@ create_mask_2x32_64 (uint32_t mask0,
/* Work around a code generation bug in Sun Studio 12. */
#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
-# define create_mask_2x32_128(mask0, mask1) \
- (_mm_set_epi32 ((mask0), (mask1), (mask0), (mask1)))
+# define create_mask_2x32_128(mask0, mask1) \
+ (_mm_set_epi32 ((mask0), (mask1), (mask0), (mask1)))
#else
static force_inline __m128i
create_mask_2x32_128 (uint32_t mask0,
@@ -2950,7 +2950,7 @@ sse2_composite_over_n_8888 (pixman_implementation_t *imp,
{
uint32_t src;
uint32_t *dst_line, *dst, d;
- uint16_t w;
+ int32_t w;
int dst_stride;
__m128i xmm_src, xmm_alpha;
__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
@@ -3041,7 +3041,7 @@ sse2_composite_over_n_0565 (pixman_implementation_t *imp,
{
uint32_t src;
uint16_t *dst_line, *dst, d;
- uint16_t w;
+ int32_t w;
int dst_stride;
__m128i xmm_src, xmm_alpha;
__m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3;
@@ -3152,7 +3152,7 @@ sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
src = _pixman_image_get_solid (src_image, dst_image->bits.format);
srca = src >> 24;
-
+
if (src == 0)
return;
@@ -3187,7 +3187,7 @@ sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
if (m)
{
d = *pd;
-
+
mmx_mask = unpack_32_1x64 (m);
mmx_dest = unpack_32_1x64 (d);
@@ -3226,7 +3226,7 @@ sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
&xmm_mask_lo, &xmm_mask_hi,
&xmm_mask_lo, &xmm_mask_hi);
xmm_mask_hi = pack_2x128_128 (xmm_mask_lo, xmm_mask_hi);
-
+
save_128_aligned (
(__m128i*)pd, _mm_adds_epu8 (xmm_mask_hi, xmm_dst));
}
@@ -3421,7 +3421,7 @@ sse2_composite_over_8888_n_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint32_t *src_line, *src;
uint32_t mask;
- uint16_t w;
+ int32_t w;
int dst_stride, src_stride;
__m128i xmm_mask;
@@ -3539,7 +3539,7 @@ sse2_composite_over_x888_n_8888 (pixman_implementation_t *imp,
uint32_t *src_line, *src;
uint32_t mask;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
__m128i xmm_mask, xmm_alpha;
__m128i xmm_src, xmm_src_lo, xmm_src_hi;
@@ -3707,7 +3707,7 @@ sse2_composite_over_8888_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst, d;
uint32_t *src_line, *src, s;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
__m128i xmm_alpha_lo, xmm_alpha_hi;
__m128i xmm_src, xmm_src_lo, xmm_src_hi;
@@ -3837,7 +3837,7 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t m, d;
__m128i xmm_src, xmm_alpha, xmm_def;
@@ -3981,9 +3981,6 @@ pixman_fill_sse2 (uint32_t *bits,
__m128i xmm_def;
- if (bpp == 16 && (data >> 16 != (data & 0xffff)))
- return FALSE;
-
if (bpp != 16 && bpp != 32)
return FALSE;
@@ -3993,6 +3990,7 @@ pixman_fill_sse2 (uint32_t *bits,
byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
byte_width = 2 * width;
stride *= 2;
+ data = (data & 0xffff) * 0x00010001;
}
else
{
@@ -4122,7 +4120,7 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t m;
__m128i xmm_src, xmm_def;
@@ -4268,7 +4266,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst, d;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t m;
__m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
@@ -4431,7 +4429,7 @@ sse2_composite_over_pixbuf_0565 (pixman_implementation_t *imp,
uint16_t *dst_line, *dst, d;
uint32_t *src_line, *src, s;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint32_t opaque, zero;
__m64 ms;
@@ -4577,7 +4575,7 @@ sse2_composite_over_pixbuf_8888 (pixman_implementation_t *imp,
uint32_t *dst_line, *dst, d;
uint32_t *src_line, *src, s;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint32_t opaque, zero;
__m128i xmm_src_lo, xmm_src_hi;
@@ -4863,9 +4861,10 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w, d, m;
+ uint32_t d, m;
uint32_t src;
uint8_t sa;
+ int32_t w;
__m128i xmm_alpha;
__m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
@@ -4978,7 +4977,7 @@ sse2_composite_in_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int src_stride, dst_stride;
- uint16_t w;
+ int32_t w;
uint32_t s, d;
__m128i xmm_src, xmm_src_lo, xmm_src_hi;
@@ -5076,7 +5075,7 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *mask_line, *mask;
int dst_stride, mask_stride;
- uint16_t w;
+ int32_t w;
uint32_t src;
uint8_t sa;
uint32_t m, d;
@@ -5192,7 +5191,7 @@ sse2_composite_add_8000_8000 (pixman_implementation_t *imp,
uint8_t *dst_line, *dst;
uint8_t *src_line, *src;
int dst_stride, src_stride;
- uint16_t w;
+ int32_t w;
uint16_t t;
PIXMAN_IMAGE_GET_LINE (
@@ -5470,7 +5469,7 @@ sse2_composite_over_x888_8_8888 (pixman_implementation_t *imp,
uint8_t *mask, *mask_line;
uint32_t m;
int src_stride, mask_stride, dst_stride;
- uint16_t w;
+ int32_t w;
__m64 ms;
__m128i xmm_src, xmm_src_lo, xmm_src_hi;
@@ -5617,7 +5616,7 @@ sse2_composite_over_8888_8_8888 (pixman_implementation_t *imp,
uint8_t *mask, *mask_line;
uint32_t m;
int src_stride, mask_stride, dst_stride;
- uint16_t w;
+ int32_t w;
__m128i xmm_src, xmm_src_lo, xmm_src_hi, xmm_srca_lo, xmm_srca_hi;
__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
@@ -5714,7 +5713,7 @@ sse2_composite_over_8888_8_8888 (pixman_implementation_t *imp,
expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi);
expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi);
-
+
in_over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi,
&xmm_mask_lo, &xmm_mask_hi, &xmm_dst_lo, &xmm_dst_hi);
@@ -5768,132 +5767,81 @@ sse2_composite_over_8888_8_8888 (pixman_implementation_t *imp,
static const pixman_fast_path_t sse2_fast_paths[] =
{
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_r5g6b5, sse2_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_b5g6r5, sse2_composite_over_n_8_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_a8r8g8b8, sse2_composite_over_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_x8r8g8b8, sse2_composite_over_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_null, PIXMAN_r5g6b5, sse2_composite_over_n_0565 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, sse2_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, sse2_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, sse2_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, sse2_composite_over_8888_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_r5g6b5, sse2_composite_over_8888_0565 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_b5g6r5, sse2_composite_over_8888_0565 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, sse2_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, sse2_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, sse2_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, sse2_composite_over_n_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, sse2_composite_over_8888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, sse2_composite_over_8888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, sse2_composite_over_8888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, sse2_composite_over_8888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_x8r8g8b8, sse2_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8, PIXMAN_a8r8g8b8, sse2_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_x8b8g8r8, sse2_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8, PIXMAN_a8b8g8r8, sse2_composite_over_x888_8_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, sse2_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, sse2_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_solid, PIXMAN_a8b8g8r8, sse2_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_solid, PIXMAN_x8b8g8r8, sse2_composite_over_x888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_a8r8g8b8, sse2_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid, PIXMAN_x8r8g8b8, sse2_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_solid, PIXMAN_a8b8g8r8, sse2_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_solid, PIXMAN_x8b8g8r8, sse2_composite_over_8888_n_8888 },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, sse2_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_x8r8g8b8, sse2_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_a8b8g8r8, sse2_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_x8b8g8r8, sse2_composite_over_n_8888_8888_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_r5g6b5, sse2_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_solid, PIXMAN_a8b8g8r8_ca, PIXMAN_b5g6r5, sse2_composite_over_n_8888_0565_ca },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_a8r8g8b8, sse2_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_x8r8g8b8, sse2_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_a8b8g8r8, sse2_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_x8b8g8r8, sse2_composite_over_pixbuf_8888 },
- { PIXMAN_OP_OVER, PIXMAN_pixbuf, PIXMAN_pixbuf, PIXMAN_r5g6b5, sse2_composite_over_pixbuf_0565 },
- { PIXMAN_OP_OVER, PIXMAN_rpixbuf, PIXMAN_rpixbuf, PIXMAN_b5g6r5, sse2_composite_over_pixbuf_0565 },
- { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, sse2_composite_copy_area },
- { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, sse2_composite_copy_area },
-
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8r8g8b8_ca, PIXMAN_a8r8g8b8, sse2_composite_add_n_8888_8888_ca },
- { PIXMAN_OP_ADD, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, sse2_composite_add_8000_8000 },
- { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, sse2_composite_add_8888_8888 },
- { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, sse2_composite_add_8888_8888 },
- { PIXMAN_OP_ADD, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, sse2_composite_add_n_8_8 },
-
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8r8g8b8, sse2_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8r8g8b8, sse2_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8b8g8r8, sse2_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_solid, PIXMAN_a8, PIXMAN_x8b8g8r8, sse2_composite_src_n_8_8888 },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_a8r8g8b8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_a8b8g8r8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8, PIXMAN_null, PIXMAN_x8r8g8b8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8, PIXMAN_null, PIXMAN_x8b8g8r8, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_r5g6b5, PIXMAN_null, PIXMAN_r5g6b5, sse2_composite_copy_area },
- { PIXMAN_OP_SRC, PIXMAN_b5g6r5, PIXMAN_null, PIXMAN_b5g6r5, sse2_composite_copy_area },
-
- { PIXMAN_OP_IN, PIXMAN_a8, PIXMAN_null, PIXMAN_a8, sse2_composite_in_8_8 },
- { PIXMAN_OP_IN, PIXMAN_solid, PIXMAN_a8, PIXMAN_a8, sse2_composite_in_n_8_8 },
+ /* PIXMAN_OP_OVER */
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, sse2_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, sse2_composite_over_n_8_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, sse2_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, sse2_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, sse2_composite_over_n_0565),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, sse2_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, sse2_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, sse2_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, sse2_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, sse2_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, sse2_composite_over_8888_0565),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, sse2_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, sse2_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, sse2_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, sse2_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, sse2_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, sse2_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, sse2_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, sse2_composite_over_8888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, sse2_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, sse2_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, sse2_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, sse2_composite_over_x888_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, sse2_composite_over_x888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, sse2_composite_over_x888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, sse2_composite_over_x888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, sse2_composite_over_x888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, sse2_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, sse2_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, sse2_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, sse2_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, sse2_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, sse2_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, sse2_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, sse2_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, sse2_composite_over_n_8888_0565_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, sse2_composite_over_n_8888_0565_ca),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, sse2_composite_over_pixbuf_8888),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, sse2_composite_over_pixbuf_8888),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, sse2_composite_over_pixbuf_8888),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, sse2_composite_over_pixbuf_8888),
+ PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, sse2_composite_over_pixbuf_0565),
+ PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, sse2_composite_over_pixbuf_0565),
+ PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area),
+
+ /* PIXMAN_OP_ADD */
+ PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, sse2_composite_add_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, sse2_composite_add_8000_8000),
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, sse2_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, sse2_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, sse2_composite_add_n_8_8),
+
+ /* PIXMAN_OP_SRC */
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, sse2_composite_src_n_8_8888),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, sse2_composite_src_n_8_8888),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, sse2_composite_src_n_8_8888),
+ PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, sse2_composite_src_n_8_8888),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, sse2_composite_copy_area),
+ PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, sse2_composite_copy_area),
+
+ /* PIXMAN_OP_IN */
+ PIXMAN_STD_FAST_PATH (IN, a8, null, a8, sse2_composite_in_8_8),
+ PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, sse2_composite_in_n_8_8),
{ PIXMAN_OP_NONE },
};
-/*
- * Work around GCC bug causing crashes in Mozilla with SSE2
- *
- * When using -msse, gcc generates movdqa instructions assuming that
- * the stack is 16 byte aligned. Unfortunately some applications, such
- * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
- * causes the movdqa instructions to fail.
- *
- * The __force_align_arg_pointer__ makes gcc generate a prologue that
- * realigns the stack pointer to 16 bytes.
- *
- * On x86-64 this is not necessary because the standard ABI already
- * calls for a 16 byte aligned stack.
- *
- * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
- */
-#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
-__attribute__((__force_align_arg_pointer__))
-#endif
-static void
-sse2_composite (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- if (_pixman_run_fast_path (sse2_fast_paths, imp,
- op, src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height))
- {
- return;
- }
-
- _pixman_implementation_composite (imp->delegate, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
-}
-
-#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
-__attribute__((__force_align_arg_pointer__))
-#endif
static pixman_bool_t
sse2_blt (pixman_implementation_t *imp,
uint32_t * src_bits,
@@ -5952,8 +5900,12 @@ __attribute__((__force_align_arg_pointer__))
pixman_implementation_t *
_pixman_implementation_create_sse2 (void)
{
- pixman_implementation_t *mmx = _pixman_implementation_create_mmx ();
- pixman_implementation_t *imp = _pixman_implementation_create (mmx);
+#ifdef USE_MMX
+ pixman_implementation_t *fallback = _pixman_implementation_create_mmx ();
+#else
+ pixman_implementation_t *fallback = _pixman_implementation_create_fast_path ();
+#endif
+ pixman_implementation_t *imp = _pixman_implementation_create (fallback, sse2_fast_paths);
/* SSE2 constants */
mask_565_r = create_mask_2x32_128 (0x00f80000, 0x00f80000);
@@ -6011,7 +5963,6 @@ _pixman_implementation_create_sse2 (void)
imp->combine_32_ca[PIXMAN_OP_XOR] = sse2_combine_xor_ca;
imp->combine_32_ca[PIXMAN_OP_ADD] = sse2_combine_add_ca;
- imp->composite = sse2_composite;
imp->blt = sse2_blt;
imp->fill = sse2_fill;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 6d03f3c..3ef88b7 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -30,208 +30,6 @@
#include "pixman-private.h"
-/*
- * Computing composite region
- */
-static inline pixman_bool_t
-clip_general_image (pixman_region32_t * region,
- pixman_region32_t * clip,
- int dx,
- int dy)
-{
- if (pixman_region32_n_rects (region) == 1 &&
- pixman_region32_n_rects (clip) == 1)
- {
- pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
- pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
- int v;
-
- if (rbox->x1 < (v = cbox->x1 + dx))
- rbox->x1 = v;
- if (rbox->x2 > (v = cbox->x2 + dx))
- rbox->x2 = v;
- if (rbox->y1 < (v = cbox->y1 + dy))
- rbox->y1 = v;
- if (rbox->y2 > (v = cbox->y2 + dy))
- rbox->y2 = v;
- if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
- {
- pixman_region32_init (region);
- return FALSE;
- }
- }
- else if (!pixman_region32_not_empty (clip))
- {
- return FALSE;
- }
- else
- {
- if (dx || dy)
- pixman_region32_translate (region, -dx, -dy);
-
- if (!pixman_region32_intersect (region, region, clip))
- return FALSE;
-
- if (dx || dy)
- pixman_region32_translate (region, dx, dy);
- }
-
- return pixman_region32_not_empty (region);
-}
-
-static inline pixman_bool_t
-clip_source_image (pixman_region32_t * region,
- pixman_image_t * image,
- int dx,
- int dy)
-{
- /* Source clips are ignored, unless they are explicitly turned on
- * and the clip in question was set by an X client. (Because if
- * the clip was not set by a client, then it is a hierarchy
- * clip and those should always be ignored for sources).
- */
- if (!image->common.clip_sources || !image->common.client_clip)
- return TRUE;
-
- return clip_general_image (region,
- &image->common.clip_region,
- dx, dy);
-}
-
-/*
- * returns FALSE if the final region is empty. Indistinguishable from
- * an allocation failure, but rendering ignores those anyways.
- */
-static pixman_bool_t
-pixman_compute_composite_region32 (pixman_region32_t * region,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- region->extents.x1 = dest_x;
- region->extents.x2 = dest_x + width;
- region->extents.y1 = dest_y;
- region->extents.y2 = dest_y + height;
-
- region->extents.x1 = MAX (region->extents.x1, 0);
- region->extents.y1 = MAX (region->extents.y1, 0);
- region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
- region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
-
- region->data = 0;
-
- /* Check for empty operation */
- if (region->extents.x1 >= region->extents.x2 ||
- region->extents.y1 >= region->extents.y2)
- {
- pixman_region32_init (region);
- return FALSE;
- }
-
- if (dst_image->common.have_clip_region)
- {
- if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- }
-
- if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
- -dst_image->common.alpha_origin_x,
- -dst_image->common.alpha_origin_y))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- }
-
- /* clip against src */
- if (src_image->common.have_clip_region)
- {
- if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- }
- if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
- dest_x - (src_x - src_image->common.alpha_origin_x),
- dest_y - (src_y - src_image->common.alpha_origin_y)))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- }
- /* clip against mask */
- if (mask_image && mask_image->common.have_clip_region)
- {
- if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
- dest_x - (mask_x - mask_image->common.alpha_origin_x),
- dest_y - (mask_y - mask_image->common.alpha_origin_y)))
- {
- pixman_region32_fini (region);
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_compute_composite_region (pixman_region16_t * region,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int16_t src_x,
- int16_t src_y,
- int16_t mask_x,
- int16_t mask_y,
- int16_t dest_x,
- int16_t dest_y,
- uint16_t width,
- uint16_t height)
-{
- pixman_region32_t r32;
- pixman_bool_t retval;
-
- pixman_region32_init (&r32);
-
- retval = pixman_compute_composite_region32 (
- &r32, src_image, mask_image, dst_image,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y,
- width, height);
-
- if (retval)
- {
- if (!pixman_region16_copy_from_region32 (region, &r32))
- retval = FALSE;
- }
-
- pixman_region32_fini (&r32);
- return retval;
-}
-
pixman_bool_t
pixman_multiply_overflows_int (unsigned int a,
unsigned int b)
@@ -369,405 +167,6 @@ pixman_contract (uint32_t * dst,
}
}
-static void
-walk_region_internal (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height,
- pixman_bool_t src_repeat,
- pixman_bool_t mask_repeat,
- pixman_region32_t * region,
- pixman_composite_func_t composite_rect)
-{
- int n;
- const pixman_box32_t *pbox;
- int w, h, w_this, h_this;
- int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
-
- pbox = pixman_region32_rectangles (region, &n);
- while (n--)
- {
- h = pbox->y2 - pbox->y1;
- y_src = pbox->y1 - dest_y + src_y;
- y_msk = pbox->y1 - dest_y + mask_y;
- y_dst = pbox->y1;
-
- while (h)
- {
- h_this = h;
- w = pbox->x2 - pbox->x1;
- x_src = pbox->x1 - dest_x + src_x;
- x_msk = pbox->x1 - dest_x + mask_x;
- x_dst = pbox->x1;
-
- if (mask_repeat)
- {
- y_msk = MOD (y_msk, mask_image->bits.height);
- if (h_this > mask_image->bits.height - y_msk)
- h_this = mask_image->bits.height - y_msk;
- }
-
- if (src_repeat)
- {
- y_src = MOD (y_src, src_image->bits.height);
- if (h_this > src_image->bits.height - y_src)
- h_this = src_image->bits.height - y_src;
- }
-
- while (w)
- {
- w_this = w;
-
- if (mask_repeat)
- {
- x_msk = MOD (x_msk, mask_image->bits.width);
- if (w_this > mask_image->bits.width - x_msk)
- w_this = mask_image->bits.width - x_msk;
- }
-
- if (src_repeat)
- {
- x_src = MOD (x_src, src_image->bits.width);
- if (w_this > src_image->bits.width - x_src)
- w_this = src_image->bits.width - x_src;
- }
-
- (*composite_rect) (imp, op,
- src_image, mask_image, dst_image,
- x_src, y_src, x_msk, y_msk, x_dst, y_dst,
- w_this, h_this);
- w -= w_this;
-
- x_src += w_this;
- x_msk += w_this;
- x_dst += w_this;
- }
-
- h -= h_this;
- y_src += h_this;
- y_msk += h_this;
- y_dst += h_this;
- }
-
- pbox++;
- }
-}
-
-void
-_pixman_walk_composite_region (pixman_implementation_t *imp,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height,
- pixman_composite_func_t composite_rect)
-{
- pixman_region32_t region;
-
- pixman_region32_init (&region);
-
- if (pixman_compute_composite_region32 (
- &region, src_image, mask_image, dst_image,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y,
- width, height))
- {
- walk_region_internal (imp, op,
- src_image, mask_image, dst_image,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y,
- width, height, FALSE, FALSE,
- &region,
- composite_rect);
-
- pixman_region32_fini (&region);
- }
-}
-
-static const pixman_fast_path_t *
-get_fast_path (const pixman_fast_path_t *fast_paths,
- pixman_op_t op,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y)
-{
- pixman_format_code_t src_format, mask_format;
- const pixman_fast_path_t *info;
-
- /* Check for pixbufs */
- if (mask_image && mask_image->type == BITS &&
- (mask_image->bits.format == PIXMAN_a8r8g8b8 || mask_image->bits.format == PIXMAN_a8b8g8r8) &&
- (src_image->type == BITS && src_image->bits.bits == mask_image->bits.bits) &&
- (src_image->common.repeat == mask_image->common.repeat) &&
- (src_x == mask_x && src_y == mask_y))
- {
- if (src_image->bits.format == PIXMAN_x8b8g8r8)
- src_format = mask_format = PIXMAN_pixbuf;
- else if (src_image->bits.format == PIXMAN_x8r8g8b8)
- src_format = mask_format = PIXMAN_rpixbuf;
- else
- return NULL;
- }
- else
- {
- if (_pixman_image_is_solid (src_image))
- {
- src_format = PIXMAN_solid;
- }
- else if (src_image->type == BITS)
- {
- src_format = src_image->bits.format;
- }
- else
- {
- return NULL;
- }
-
- if (!mask_image)
- {
- mask_format = PIXMAN_null;
- }
- else if (mask_image->common.component_alpha)
- {
- if (mask_image->type == BITS)
- {
- /* These are the *only* component_alpha formats
- * we support for fast paths
- */
- if (mask_image->bits.format == PIXMAN_a8r8g8b8)
- mask_format = PIXMAN_a8r8g8b8_ca;
- else if (mask_image->bits.format == PIXMAN_a8b8g8r8)
- mask_format = PIXMAN_a8b8g8r8_ca;
- else
- return NULL;
- }
- else
- {
- return NULL;
- }
- }
- else if (_pixman_image_is_solid (mask_image))
- {
- mask_format = PIXMAN_solid;
- }
- else if (mask_image->common.type == BITS)
- {
- mask_format = mask_image->bits.format;
- }
- else
- {
- return NULL;
- }
- }
-
- for (info = fast_paths; info->op != PIXMAN_OP_NONE; info++)
- {
- if (info->op != op)
- continue;
-
- if (info->src_format != src_format)
- continue;
- if (info->mask_format != mask_format)
- continue;
-
- if (info->dest_format != dst_image->bits.format)
- continue;
-
- return info;
- }
-
- return NULL;
-}
-
-static force_inline pixman_bool_t
-image_covers (pixman_image_t *image,
- pixman_box32_t *extents,
- int x,
- int y)
-{
- if (image->common.type == BITS &&
- image->common.repeat == PIXMAN_REPEAT_NONE)
- {
- if (x > extents->x1 || y > extents->y1 ||
- x + image->bits.width < extents->x2 ||
- y + image->bits.height < extents->y2)
- {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static force_inline pixman_bool_t
-sources_cover (pixman_image_t *src,
- pixman_image_t *mask,
- pixman_box32_t *extents,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y,
- int dest_x,
- int dest_y)
-{
- if (!image_covers (src, extents, dest_x - src_x, dest_y - src_y))
- return FALSE;
-
- if (!mask)
- return TRUE;
-
- if (!image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))
- return FALSE;
-
- return TRUE;
-}
-
-pixman_bool_t
-_pixman_run_fast_path (const pixman_fast_path_t *paths,
- pixman_implementation_t * imp,
- pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- pixman_composite_func_t func = NULL;
- pixman_bool_t src_repeat =
- src->common.repeat == PIXMAN_REPEAT_NORMAL;
- pixman_bool_t mask_repeat =
- mask && mask->common.repeat == PIXMAN_REPEAT_NORMAL;
- pixman_bool_t result;
- pixman_bool_t has_fast_path;
-
- has_fast_path = !dest->common.alpha_map &&
- !dest->bits.read_func &&
- !dest->bits.write_func;
-
- if (has_fast_path)
- {
- has_fast_path = !src->common.transform &&
- !src->common.alpha_map &&
- src->common.filter != PIXMAN_FILTER_CONVOLUTION &&
- src->common.repeat != PIXMAN_REPEAT_PAD &&
- src->common.repeat != PIXMAN_REPEAT_REFLECT;
- if (has_fast_path && src->type == BITS)
- {
- has_fast_path = !src->bits.read_func &&
- !src->bits.write_func &&
- !PIXMAN_FORMAT_IS_WIDE (src->bits.format);
- }
- }
-
- if (mask && has_fast_path)
- {
- has_fast_path =
- !mask->common.transform &&
- !mask->common.alpha_map &&
- !mask->bits.read_func &&
- !mask->bits.write_func &&
- mask->common.filter != PIXMAN_FILTER_CONVOLUTION &&
- mask->common.repeat != PIXMAN_REPEAT_PAD &&
- mask->common.repeat != PIXMAN_REPEAT_REFLECT &&
- !PIXMAN_FORMAT_IS_WIDE (mask->bits.format);
- }
-
- if (has_fast_path)
- {
- const pixman_fast_path_t *info;
-
- if ((info = get_fast_path (paths, op, src, mask, dest, src_x, src_y, mask_x, mask_y)))
- {
- func = info->func;
-
- if (info->src_format == PIXMAN_solid)
- src_repeat = FALSE;
-
- if (info->mask_format == PIXMAN_solid)
- {
- mask_repeat = FALSE;
- }
-
- if ((src_repeat &&
- src->bits.width == 1 &&
- src->bits.height == 1) ||
- (mask_repeat &&
- mask->bits.width == 1 &&
- mask->bits.height == 1))
- {
- /* If src or mask are repeating 1x1 images and src_repeat or
- * mask_repeat are still TRUE, it means the fast path we
- * selected does not actually handle repeating images.
- *
- * So rather than call the "fast path" with a zillion
- * 1x1 requests, we just fall back to the general code (which
- * does do something sensible with 1x1 repeating images).
- */
- func = NULL;
- }
- }
- }
-
- result = FALSE;
-
- if (func)
- {
- pixman_region32_t region;
- pixman_region32_init (&region);
-
- if (pixman_compute_composite_region32 (
- &region, src, mask, dest,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
- {
- pixman_box32_t *extents = pixman_region32_extents (&region);
-
- if (sources_cover (
- src, mask, extents,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y))
- {
- walk_region_internal (imp, op,
- src, mask, dest,
- src_x, src_y, mask_x, mask_y,
- dest_x, dest_y,
- width, height,
- src_repeat, mask_repeat,
- &region,
- func);
-
- result = TRUE;
- }
-
- pixman_region32_fini (&region);
- }
- }
-
- return result;
-}
-
#define N_TMP_BOXES (16)
pixman_bool_t
@@ -836,3 +235,24 @@ pixman_region32_copy_from_region16 (pixman_region32_t *dst,
return retval;
}
+
+#ifdef DEBUG
+
+void
+_pixman_log_error (const char *function, const char *message)
+{
+ static int n_messages = 0;
+
+ if (n_messages < 10)
+ {
+ fprintf (stderr,
+ "*** BUG ***\n"
+ "In %s: %s\n"
+ "Set a breakpoint on '_pixman_log_error' to debug\n\n",
+ function, message);
+
+ n_messages++;
+ }
+}
+
+#endif
diff --git a/pixman/pixman-vmx.c b/pixman/pixman-vmx.c
index 06325a7..e811cf7 100644
--- a/pixman/pixman-vmx.c
+++ b/pixman/pixman-vmx.c
@@ -1607,11 +1607,16 @@ vmx_combine_add_ca (pixman_implementation_t *imp,
}
}
+static const pixman_fast_path_t vmx_fast_paths[] =
+{
+ { PIXMAN_OP_NONE },
+};
+
pixman_implementation_t *
_pixman_implementation_create_vmx (void)
{
pixman_implementation_t *fast = _pixman_implementation_create_fast_path ();
- pixman_implementation_t *imp = _pixman_implementation_create (fast);
+ pixman_implementation_t *imp = _pixman_implementation_create (fast, vmx_fast_paths);
/* Set up function pointers */
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 0edd967..6a260ed 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -28,6 +28,8 @@
#endif
#include "pixman-private.h"
+#include <stdlib.h>
+
/*
* Operator optimizations based on source or destination opacity
*/
@@ -109,49 +111,560 @@ pixman_optimize_operator (pixman_op_t op,
static void
apply_workaround (pixman_image_t *image,
- int16_t * x,
- int16_t * y,
+ int32_t * x,
+ int32_t * y,
uint32_t ** save_bits,
int * save_dx,
int * save_dy)
{
- /* Some X servers generate images that point to the
- * wrong place in memory, but then set the clip region
- * to point to the right place. Because of an old bug
- * in pixman, this would actually work.
- *
- * Here we try and undo the damage
+ if (image && image->common.need_workaround)
+ {
+ /* Some X servers generate images that point to the
+ * wrong place in memory, but then set the clip region
+ * to point to the right place. Because of an old bug
+ * in pixman, this would actually work.
+ *
+ * Here we try and undo the damage
+ */
+ int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
+ pixman_box32_t *extents;
+ uint8_t *t;
+ int dx, dy;
+
+ extents = pixman_region32_extents (&(image->common.clip_region));
+ dx = extents->x1;
+ dy = extents->y1;
+
+ *save_bits = image->bits.bits;
+
+ *x -= dx;
+ *y -= dy;
+ pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
+
+ t = (uint8_t *)image->bits.bits;
+ t += dy * image->bits.rowstride * 4 + dx * bpp;
+ image->bits.bits = (uint32_t *)t;
+
+ *save_dx = dx;
+ *save_dy = dy;
+ }
+}
+
+static void
+unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
+{
+ if (image && image->common.need_workaround)
+ {
+ image->bits.bits = bits;
+ pixman_region32_translate (&image->common.clip_region, dx, dy);
+ }
+}
+
+/*
+ * Computing composite region
+ */
+static inline pixman_bool_t
+clip_general_image (pixman_region32_t * region,
+ pixman_region32_t * clip,
+ int dx,
+ int dy)
+{
+ if (pixman_region32_n_rects (region) == 1 &&
+ pixman_region32_n_rects (clip) == 1)
+ {
+ pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
+ pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
+ int v;
+
+ if (rbox->x1 < (v = cbox->x1 + dx))
+ rbox->x1 = v;
+ if (rbox->x2 > (v = cbox->x2 + dx))
+ rbox->x2 = v;
+ if (rbox->y1 < (v = cbox->y1 + dy))
+ rbox->y1 = v;
+ if (rbox->y2 > (v = cbox->y2 + dy))
+ rbox->y2 = v;
+ if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
+ {
+ pixman_region32_init (region);
+ return FALSE;
+ }
+ }
+ else if (!pixman_region32_not_empty (clip))
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (dx || dy)
+ pixman_region32_translate (region, -dx, -dy);
+
+ if (!pixman_region32_intersect (region, region, clip))
+ return FALSE;
+
+ if (dx || dy)
+ pixman_region32_translate (region, dx, dy);
+ }
+
+ return pixman_region32_not_empty (region);
+}
+
+static inline pixman_bool_t
+clip_source_image (pixman_region32_t * region,
+ pixman_image_t * image,
+ int dx,
+ int dy)
+{
+ /* Source clips are ignored, unless they are explicitly turned on
+ * and the clip in question was set by an X client. (Because if
+ * the clip was not set by a client, then it is a hierarchy
+ * clip and those should always be ignored for sources).
*/
- int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
- pixman_box32_t *extents;
- uint8_t *t;
- int dx, dy;
+ if (!image->common.clip_sources || !image->common.client_clip)
+ return TRUE;
- extents = pixman_region32_extents (&(image->common.clip_region));
- dx = extents->x1;
- dy = extents->y1;
+ return clip_general_image (region,
+ &image->common.clip_region,
+ dx, dy);
+}
- *save_bits = image->bits.bits;
+/*
+ * returns FALSE if the final region is empty. Indistinguishable from
+ * an allocation failure, but rendering ignores those anyways.
+ */
+static pixman_bool_t
+pixman_compute_composite_region32 (pixman_region32_t * region,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
+{
+ region->extents.x1 = dest_x;
+ region->extents.x2 = dest_x + width;
+ region->extents.y1 = dest_y;
+ region->extents.y2 = dest_y + height;
- *x -= dx;
- *y -= dy;
- pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
+ region->extents.x1 = MAX (region->extents.x1, 0);
+ region->extents.y1 = MAX (region->extents.y1, 0);
+ region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
+ region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
- t = (uint8_t *)image->bits.bits;
- t += dy * image->bits.rowstride * 4 + dx * bpp;
- image->bits.bits = (uint32_t *)t;
+ region->data = 0;
- *save_dx = dx;
- *save_dy = dy;
+ /* Check for empty operation */
+ if (region->extents.x1 >= region->extents.x2 ||
+ region->extents.y1 >= region->extents.y2)
+ {
+ pixman_region32_init (region);
+ return FALSE;
+ }
+
+ if (dst_image->common.have_clip_region)
+ {
+ if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ }
+
+ if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
+ -dst_image->common.alpha_origin_x,
+ -dst_image->common.alpha_origin_y))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ }
+
+ /* clip against src */
+ if (src_image->common.have_clip_region)
+ {
+ if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ }
+ if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
+ dest_x - (src_x - src_image->common.alpha_origin_x),
+ dest_y - (src_y - src_image->common.alpha_origin_y)))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ }
+ /* clip against mask */
+ if (mask_image && mask_image->common.have_clip_region)
+ {
+ if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
+ dest_x - (mask_x - mask_image->common.alpha_origin_x),
+ dest_y - (mask_y - mask_image->common.alpha_origin_y)))
+ {
+ pixman_region32_fini (region);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
}
static void
-unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
+walk_region_internal (pixman_implementation_t *imp,
+ pixman_op_t op,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height,
+ pixman_bool_t src_repeat,
+ pixman_bool_t mask_repeat,
+ pixman_region32_t * region,
+ pixman_composite_func_t composite_rect)
{
- image->bits.bits = bits;
- pixman_region32_translate (&image->common.clip_region, dx, dy);
+ int w, h, w_this, h_this;
+ int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
+ int src_dy = src_y - dest_y;
+ int src_dx = src_x - dest_x;
+ int mask_dy = mask_y - dest_y;
+ int mask_dx = mask_x - dest_x;
+ const pixman_box32_t *pbox;
+ int n;
+
+ pbox = pixman_region32_rectangles (region, &n);
+
+ /* Fast path for non-repeating sources */
+ if (!src_repeat && !mask_repeat)
+ {
+ while (n--)
+ {
+ (*composite_rect) (imp, op,
+ src_image, mask_image, dst_image,
+ pbox->x1 + src_dx,
+ pbox->y1 + src_dy,
+ pbox->x1 + mask_dx,
+ pbox->y1 + mask_dy,
+ pbox->x1,
+ pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ pbox++;
+ }
+
+ return;
+ }
+
+ while (n--)
+ {
+ h = pbox->y2 - pbox->y1;
+ y_src = pbox->y1 + src_dy;
+ y_msk = pbox->y1 + mask_dy;
+ y_dst = pbox->y1;
+
+ while (h)
+ {
+ h_this = h;
+ w = pbox->x2 - pbox->x1;
+ x_src = pbox->x1 + src_dx;
+ x_msk = pbox->x1 + mask_dx;
+ x_dst = pbox->x1;
+
+ if (mask_repeat)
+ {
+ y_msk = MOD (y_msk, mask_image->bits.height);
+ if (h_this > mask_image->bits.height - y_msk)
+ h_this = mask_image->bits.height - y_msk;
+ }
+
+ if (src_repeat)
+ {
+ y_src = MOD (y_src, src_image->bits.height);
+ if (h_this > src_image->bits.height - y_src)
+ h_this = src_image->bits.height - y_src;
+ }
+
+ while (w)
+ {
+ w_this = w;
+
+ if (mask_repeat)
+ {
+ x_msk = MOD (x_msk, mask_image->bits.width);
+ if (w_this > mask_image->bits.width - x_msk)
+ w_this = mask_image->bits.width - x_msk;
+ }
+
+ if (src_repeat)
+ {
+ x_src = MOD (x_src, src_image->bits.width);
+ if (w_this > src_image->bits.width - x_src)
+ w_this = src_image->bits.width - x_src;
+ }
+
+ (*composite_rect) (imp, op,
+ src_image, mask_image, dst_image,
+ x_src, y_src, x_msk, y_msk, x_dst, y_dst,
+ w_this, h_this);
+ w -= w_this;
+
+ x_src += w_this;
+ x_msk += w_this;
+ x_dst += w_this;
+ }
+
+ h -= h_this;
+ y_src += h_this;
+ y_msk += h_this;
+ y_dst += h_this;
+ }
+
+ pbox++;
+ }
}
+static void
+get_image_info (pixman_image_t *image,
+ pixman_format_code_t *code,
+ uint32_t *flags)
+{
+ *flags = 0;
+
+ if (!image->common.transform)
+ {
+ *flags |= FAST_PATH_ID_TRANSFORM;
+ }
+ else
+ {
+ if (image->common.transform->matrix[0][1] == 0 &&
+ image->common.transform->matrix[1][0] == 0 &&
+ image->common.transform->matrix[2][0] == 0 &&
+ image->common.transform->matrix[2][1] == 0 &&
+ image->common.transform->matrix[2][2] == pixman_fixed_1)
+ {
+ *flags |= FAST_PATH_SCALE_TRANSFORM;
+ }
+ }
+
+ if (!image->common.alpha_map)
+ *flags |= FAST_PATH_NO_ALPHA_MAP;
+
+ if (image->common.filter != PIXMAN_FILTER_CONVOLUTION)
+ {
+ *flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
+
+ if (image->common.filter == PIXMAN_FILTER_NEAREST)
+ *flags |= FAST_PATH_NEAREST_FILTER;
+ }
+
+ if (image->common.repeat != PIXMAN_REPEAT_PAD)
+ *flags |= FAST_PATH_NO_PAD_REPEAT;
+
+ if (image->common.repeat != PIXMAN_REPEAT_REFLECT)
+ *flags |= FAST_PATH_NO_REFLECT_REPEAT;
+
+ *flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NO_WIDE_FORMAT);
+ if (image->type == BITS)
+ {
+ if (image->bits.read_func || image->bits.write_func)
+ *flags &= ~FAST_PATH_NO_ACCESSORS;
+
+ if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
+ *flags &= ~FAST_PATH_NO_WIDE_FORMAT;
+ }
+
+ if (image->common.component_alpha)
+ *flags |= FAST_PATH_COMPONENT_ALPHA;
+ else
+ *flags |= FAST_PATH_UNIFIED_ALPHA;
+
+ if (_pixman_image_is_solid (image))
+ *code = PIXMAN_solid;
+ else if (image->common.type == BITS)
+ *code = image->bits.format;
+ else
+ *code = PIXMAN_unknown;
+}
+
+static force_inline pixman_bool_t
+image_covers (pixman_image_t *image,
+ pixman_box32_t *extents,
+ int x,
+ int y)
+{
+ if (image->common.type == BITS &&
+ image->common.repeat == PIXMAN_REPEAT_NONE)
+ {
+ if (x > extents->x1 || y > extents->y1 ||
+ x + image->bits.width < extents->x2 ||
+ y + image->bits.height < extents->y2)
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+do_composite (pixman_implementation_t *imp,
+ pixman_op_t op,
+ pixman_image_t *src,
+ pixman_image_t *mask,
+ pixman_image_t *dest,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dest_x,
+ int dest_y,
+ int width,
+ int height)
+{
+ pixman_format_code_t src_format, mask_format, dest_format;
+ uint32_t src_flags, mask_flags, dest_flags;
+ pixman_bool_t src_repeat, mask_repeat;
+ pixman_region32_t region;
+ pixman_box32_t *extents;
+
+ get_image_info (src, &src_format, &src_flags);
+ if (mask)
+ {
+ get_image_info (mask, &mask_format, &mask_flags);
+ }
+ else
+ {
+ mask_format = PIXMAN_null;
+ mask_flags = 0;
+ }
+ get_image_info (dest, &dest_format, &dest_flags);
+
+ /* Check for pixbufs */
+ if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
+ (src->type == BITS && src->bits.bits == mask->bits.bits) &&
+ (src->common.repeat == mask->common.repeat) &&
+ (src_x == mask_x && src_y == mask_y))
+ {
+ if (src_format == PIXMAN_x8b8g8r8)
+ src_format = mask_format = PIXMAN_pixbuf;
+ else if (src_format == PIXMAN_x8r8g8b8)
+ src_format = mask_format = PIXMAN_rpixbuf;
+ }
+
+ src_repeat =
+ src->type == BITS &&
+ src_flags & FAST_PATH_ID_TRANSFORM &&
+ src->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ src_format != PIXMAN_solid;
+
+ mask_repeat =
+ mask &&
+ mask->type == BITS &&
+ mask_flags & FAST_PATH_ID_TRANSFORM &&
+ mask->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ mask_format != PIXMAN_solid;
+
+ pixman_region32_init (&region);
+
+ if (!pixman_compute_composite_region32 (
+ &region, src, mask, dest,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+ {
+ return;
+ }
+
+ extents = pixman_region32_extents (&region);
+
+ if (image_covers (src, extents, dest_x - src_x, dest_y - src_y))
+ src_flags |= FAST_PATH_COVERS_CLIP;
+
+ if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))
+ mask_flags |= FAST_PATH_COVERS_CLIP;
+
+ while (imp)
+ {
+ const pixman_fast_path_t *info;
+
+ for (info = imp->fast_paths; info->op != PIXMAN_OP_NONE; ++info)
+ {
+ if ((info->op == op || info->op == PIXMAN_OP_any) &&
+ /* src */
+ ((info->src_format == src_format) ||
+ (info->src_format == PIXMAN_any)) &&
+ (info->src_flags & src_flags) == info->src_flags &&
+ /* mask */
+ ((info->mask_format == mask_format) ||
+ (info->mask_format == PIXMAN_any)) &&
+ (info->mask_flags & mask_flags) == info->mask_flags &&
+ /* dest */
+ ((info->dest_format == dest_format) ||
+ (info->dest_format == PIXMAN_any)) &&
+ (info->dest_flags & dest_flags) == info->dest_flags)
+ {
+ walk_region_internal (imp, op,
+ src, mask, dest,
+ src_x, src_y, mask_x, mask_y,
+ dest_x, dest_y,
+ width, height,
+ src_repeat, mask_repeat,
+ &region,
+ info->func);
+
+ goto done;
+ }
+ }
+
+ imp = imp->delegate;
+ }
+
+done:
+ pixman_region32_fini (&region);
+}
+
+/*
+ * Work around GCC bug causing crashes in Mozilla with SSE2
+ *
+ * When using -msse, gcc generates movdqa instructions assuming that
+ * the stack is 16 byte aligned. Unfortunately some applications, such
+ * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
+ * causes the movdqa instructions to fail.
+ *
+ * The __force_align_arg_pointer__ makes gcc generate a prologue that
+ * realigns the stack pointer to 16 bytes.
+ *
+ * On x86-64 this is not necessary because the standard ABI already
+ * calls for a 16 byte aligned stack.
+ *
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
+ */
+#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
+__attribute__((__force_align_arg_pointer__))
+#endif
PIXMAN_EXPORT void
pixman_image_composite (pixman_op_t op,
pixman_image_t * src,
@@ -166,12 +679,31 @@ pixman_image_composite (pixman_op_t op,
uint16_t width,
uint16_t height)
{
+ pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
+ mask_x, mask_y, dest_x, dest_y, width, height);
+}
+
+PIXMAN_EXPORT void
+pixman_image_composite32 (pixman_op_t op,
+ pixman_image_t * src,
+ pixman_image_t * mask,
+ pixman_image_t * dest,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
+{
uint32_t *src_bits;
int src_dx, src_dy;
uint32_t *mask_bits;
int mask_dx, mask_dy;
uint32_t *dest_bits;
int dest_dx, dest_dy;
+ pixman_bool_t need_workaround;
_pixman_image_validate (src);
if (mask)
@@ -194,26 +726,34 @@ pixman_image_composite (pixman_op_t op,
if (!imp)
imp = _pixman_choose_implementation ();
- if (src->common.need_workaround)
+ need_workaround =
+ (src->common.need_workaround) ||
+ (mask && mask->common.need_workaround) ||
+ (dest->common.need_workaround);
+
+ if (need_workaround)
+ {
apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
- if (mask && mask->common.need_workaround)
apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
- if (dest->common.need_workaround)
apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
+ }
- _pixman_implementation_composite (imp, op,
- src, mask, dest,
- src_x, src_y,
- mask_x, mask_y,
- dest_x, dest_y,
- width, height);
-
- if (src->common.need_workaround)
- unapply_workaround (src, src_bits, src_dx, src_dy);
- if (mask && mask->common.need_workaround)
- unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
- if (dest->common.need_workaround)
- unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
+ do_composite (imp, op,
+ src, mask, dest,
+ src_x, src_y,
+ mask_x, mask_y,
+ dest_x, dest_y,
+ width, height);
+
+ if (need_workaround)
+ {
+ if (src->common.need_workaround)
+ unapply_workaround (src, src_bits, src_dx, src_dy);
+ if (mask && mask->common.need_workaround)
+ unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
+ if (dest->common.need_workaround)
+ unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
+ }
}
PIXMAN_EXPORT pixman_bool_t
@@ -323,6 +863,45 @@ pixman_image_fill_rectangles (pixman_op_t op,
int n_rects,
const pixman_rectangle16_t *rects)
{
+ pixman_box32_t stack_boxes[6];
+ pixman_box32_t *boxes;
+ pixman_bool_t result;
+ int i;
+
+ if (n_rects > 6)
+ {
+ boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
+ if (boxes == NULL)
+ return FALSE;
+ }
+ else
+ {
+ boxes = stack_boxes;
+ }
+
+ for (i = 0; i < n_rects; ++i)
+ {
+ boxes[i].x1 = rects[i].x;
+ boxes[i].y1 = rects[i].y;
+ boxes[i].x2 = boxes[i].x1 + rects[i].width;
+ boxes[i].y2 = boxes[i].y1 + rects[i].height;
+ }
+
+ result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
+
+ if (boxes != stack_boxes)
+ free (boxes);
+
+ return result;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_image_fill_boxes (pixman_op_t op,
+ pixman_image_t * dest,
+ pixman_color_t * color,
+ int n_boxes,
+ const pixman_box32_t *boxes)
+{
pixman_image_t *solid;
pixman_color_t c;
int i;
@@ -331,71 +910,69 @@ pixman_image_fill_rectangles (pixman_op_t op,
if (color->alpha == 0xffff)
{
- if (op == PIXMAN_OP_OVER)
- op = PIXMAN_OP_SRC;
+ if (op == PIXMAN_OP_OVER)
+ op = PIXMAN_OP_SRC;
}
if (op == PIXMAN_OP_CLEAR)
{
- c.red = 0;
- c.green = 0;
- c.blue = 0;
- c.alpha = 0;
+ c.red = 0;
+ c.green = 0;
+ c.blue = 0;
+ c.alpha = 0;
- color = &c;
+ color = &c;
- op = PIXMAN_OP_SRC;
+ op = PIXMAN_OP_SRC;
}
if (op == PIXMAN_OP_SRC)
{
- uint32_t pixel;
+ uint32_t pixel;
- if (color_to_pixel (color, &pixel, dest->bits.format))
- {
- for (i = 0; i < n_rects; ++i)
- {
- pixman_region32_t fill_region;
- int n_boxes, j;
- pixman_box32_t *boxes;
+ if (color_to_pixel (color, &pixel, dest->bits.format))
+ {
+ pixman_region32_t fill_region;
+ int n_rects, j;
+ pixman_box32_t *rects;
- pixman_region32_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+ if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
+ return FALSE;
- if (dest->common.have_clip_region)
- {
- if (!pixman_region32_intersect (&fill_region,
- &fill_region,
- &dest->common.clip_region))
- return FALSE;
- }
+ if (dest->common.have_clip_region)
+ {
+ if (!pixman_region32_intersect (&fill_region,
+ &fill_region,
+ &dest->common.clip_region))
+ return FALSE;
+ }
- boxes = pixman_region32_rectangles (&fill_region, &n_boxes);
- for (j = 0; j < n_boxes; ++j)
- {
- const pixman_box32_t *box = &(boxes[j]);
- pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
- box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1,
- pixel);
- }
+ rects = pixman_region32_rectangles (&fill_region, &n_rects);
+ for (j = 0; j < n_rects; ++j)
+ {
+ const pixman_box32_t *rect = &(rects[j]);
+ pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
+ rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
+ pixel);
+ }
- pixman_region32_fini (&fill_region);
- }
- return TRUE;
- }
+ pixman_region32_fini (&fill_region);
+ return TRUE;
+ }
}
solid = pixman_image_create_solid_fill (color);
if (!solid)
- return FALSE;
+ return FALSE;
- for (i = 0; i < n_rects; ++i)
+ for (i = 0; i < n_boxes; ++i)
{
- const pixman_rectangle16_t *rect = &(rects[i]);
+ const pixman_box32_t *box = &(boxes[i]);
- pixman_image_composite (op, solid, NULL, dest,
- 0, 0, 0, 0,
- rect->x, rect->y,
- rect->width, rect->height);
+ pixman_image_composite32 (op, solid, NULL, dest,
+ 0, 0, 0, 0,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
}
pixman_image_unref (solid);
@@ -541,3 +1118,36 @@ pixman_format_supported_destination (pixman_format_code_t format)
return pixman_format_supported_source (format);
}
+PIXMAN_EXPORT pixman_bool_t
+pixman_compute_composite_region (pixman_region16_t * region,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int16_t src_x,
+ int16_t src_y,
+ int16_t mask_x,
+ int16_t mask_y,
+ int16_t dest_x,
+ int16_t dest_y,
+ uint16_t width,
+ uint16_t height)
+{
+ pixman_region32_t r32;
+ pixman_bool_t retval;
+
+ pixman_region32_init (&r32);
+
+ retval = pixman_compute_composite_region32 (
+ &r32, src_image, mask_image, dst_image,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y,
+ width, height);
+
+ if (retval)
+ {
+ if (!pixman_region16_copy_from_region32 (region, &r32))
+ retval = FALSE;
+ }
+
+ pixman_region32_fini (&r32);
+ return retval;
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index ba2b242..69af0f9 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -71,6 +71,16 @@ SOFTWARE.
#include <pixman-version.h>
+#ifdef __cplusplus
+#define PIXMAN_BEGIN_DECLS extern "C" {
+#define PIXMAN_END_DECLS }
+#else
+#define PIXMAN_BEGIN_DECLS
+#define PIXMAN_END_DECLS
+#endif
+
+PIXMAN_BEGIN_DECLS
+
/*
* Standard integers
*/
@@ -166,6 +176,7 @@ struct pixman_transform
/* forward declaration (sorry) */
struct pixman_box16;
+typedef union pixman_image pixman_image_t;
void pixman_transform_init_identity (struct pixman_transform *matrix);
pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform,
@@ -393,10 +404,12 @@ void pixman_region_init_rect (pixman_region16_t *reg
unsigned int width,
unsigned int height);
pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
- pixman_box16_t *boxes,
+ const pixman_box16_t *boxes,
int count);
void pixman_region_init_with_extents (pixman_region16_t *region,
pixman_box16_t *extents);
+void pixman_region_init_from_image (pixman_region16_t *region,
+ pixman_image_t *image);
void pixman_region_fini (pixman_region16_t *region);
@@ -429,7 +442,7 @@ pixman_bool_t pixman_region_contains_point (pixman_region16_t *reg
int x,
int y,
pixman_box16_t *box);
-pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *pixman_region16_t,
+pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region,
pixman_box16_t *prect);
pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
pixman_box16_t * pixman_region_extents (pixman_region16_t *region);
@@ -480,10 +493,12 @@ void pixman_region32_init_rect (pixman_region32_t *r
unsigned int width,
unsigned int height);
pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region,
- pixman_box32_t *boxes,
+ const pixman_box32_t *boxes,
int count);
void pixman_region32_init_with_extents (pixman_region32_t *region,
pixman_box32_t *extents);
+void pixman_region32_init_from_image (pixman_region32_t *region,
+ pixman_image_t *image);
void pixman_region32_fini (pixman_region32_t *region);
@@ -557,7 +572,6 @@ const char* pixman_version_string (void);
/*
* Images
*/
-typedef union pixman_image pixman_image_t;
typedef struct pixman_indexed pixman_indexed_t;
typedef struct pixman_gradient_stop pixman_gradient_stop_t;
@@ -722,6 +736,7 @@ pixman_bool_t pixman_image_unref (pixman_image_t
void pixman_image_set_destroy_function (pixman_image_t *image,
pixman_image_destroy_func_t function,
void *data);
+void * pixman_image_get_destroy_data (pixman_image_t *image);
/* Set properties */
pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image,
@@ -761,6 +776,11 @@ pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op,
pixman_color_t *color,
int n_rects,
const pixman_rectangle16_t *rects);
+pixman_bool_t pixman_image_fill_boxes (pixman_op_t op,
+ pixman_image_t *dest,
+ pixman_color_t *color,
+ int n_boxes,
+ const pixman_box32_t *boxes);
/* Composite */
pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
@@ -787,6 +807,18 @@ void pixman_image_composite (pixman_op_t op,
int16_t dest_y,
uint16_t width,
uint16_t height);
+void pixman_image_composite32 (pixman_op_t op,
+ pixman_image_t *src,
+ pixman_image_t *mask,
+ pixman_image_t *dest,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height);
/* Old X servers rely on out-of-bounds accesses when they are asked
* to composite with a window as the source. They create a pixman image
@@ -892,4 +924,6 @@ void pixman_rasterize_trapezoid (pixman_image_t *image,
int x_off,
int y_off);
+PIXMAN_END_DECLS
+
#endif /* PIXMAN_H__ */
diff --git a/pixman/solaris-hwcap.mapfile b/pixman/solaris-hwcap.mapfile
index 7f439a9..3605ca7 100644
--- a/pixman/solaris-hwcap.mapfile
+++ b/pixman/solaris-hwcap.mapfile
@@ -3,29 +3,23 @@
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, and/or sell copies of the Software, and to permit persons
-# to whom the Software is furnished to do so, provided that the above
-# copyright notice(s) and this permission notice appear in all copies of
-# the Software and that both the above copyright notice(s) and this
-# permission notice appear in supporting documentation.
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-# OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-# HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
-# INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
-# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
#
-# Except as contained in this notice, the name of a copyright holder
-# shall not be used in advertising or otherwise to promote the sale, use
-# or other dealings in this Software without prior written authorization
-# of the copyright holder.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
#
###############################################################################
#
diff --git a/test/Makefile.am b/test/Makefile.am
index 89d32e9..841ff8d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -2,28 +2,36 @@ TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la
INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
TESTPROGRAMS = \
+ a1-trap-test \
region-test \
- scaling-test \
- blitters-test \
- composite \
fetch-test \
oob-test \
window-test \
- trap-crasher
+ trap-crasher \
+ alphamap \
+ blitters-test \
+ scaling-test \
+ composite
+a1_trap_test_LDADD = $(TEST_LDADD)
fetch_test_LDADD = $(TEST_LDADD)
-region_test_LDADD = $(TEST_LDADD)
composite_LDADD = $(TEST_LDADD)
trap_crasher_LDADD = $(TEST_LDADD)
oob_test_LDADD = $(TEST_LDADD)
window_test_LDADD = $(TEST_LDADD)
+region_test_LDADD = $(TEST_LDADD)
+region_test_SOURCES = region-test.c utils.c utils.h
+
blitters_test_LDADD = $(TEST_LDADD)
blitters_test_SOURCES = blitters-test.c utils.c utils.h
scaling_test_LDADD = $(TEST_LDADD)
scaling_test_SOURCES = scaling-test.c utils.c utils.h
+alphamap_LDADD = $(TEST_LDADD)
+alphamap_SOURCES = alphamap.c utils.c utils.h
+
# GTK using test programs
if HAVE_GTK
@@ -31,7 +39,7 @@ if HAVE_GTK
GTK_LDADD = $(TEST_LDADD) $(GTK_LIBS)
GTK_UTILS = gtk-utils.c gtk-utils.h
-TESTPROGRAMS += \
+TESTPROGRAMS_GTK = \
clip-test \
clip-in \
composite-test \
@@ -39,7 +47,8 @@ TESTPROGRAMS += \
alpha-test \
screen-test \
convolution-test \
- trap-test
+ trap-test \
+ alphamap
INCLUDES += $(GTK_CFLAGS)
@@ -69,5 +78,7 @@ convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
endif
-noinst_PROGRAMS = $(TESTPROGRAMS)
+noinst_PROGRAMS = $(TESTPROGRAMS) $(TESTPROGRAMS_GTK)
+
+TESTS = $(TESTPROGRAMS)
diff --git a/test/a1-trap-test.c b/test/a1-trap-test.c
new file mode 100644
index 0000000..6163e7c
--- /dev/null
+++ b/test/a1-trap-test.c
@@ -0,0 +1,50 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pixman.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 20
+#define HEIGHT 20
+
+ pixman_image_t *src_img;
+ pixman_image_t *mask_img;
+ pixman_image_t *dest_img;
+ pixman_trap_t trap;
+ pixman_color_t red = { 0xffff, 0x0000, 0x0000, 0xffff };
+ uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
+ uint32_t *mbits = malloc (WIDTH * HEIGHT);
+
+ memset (mbits, 0, WIDTH * HEIGHT);
+ memset (bits, 0xff, WIDTH * HEIGHT * 4);
+
+ trap.top.l = pixman_double_to_fixed (0.5);
+ trap.top.r = pixman_double_to_fixed (1.5);
+ trap.top.y = pixman_double_to_fixed (0.5);
+
+ trap.bot.l = pixman_double_to_fixed (0.5);
+ trap.bot.r = pixman_double_to_fixed (1.5);
+ trap.bot.y = pixman_double_to_fixed (1.5);
+
+ mask_img = pixman_image_create_bits (
+ PIXMAN_a1, WIDTH, HEIGHT, mbits, WIDTH);
+ src_img = pixman_image_create_solid_fill (&red);
+ dest_img = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4);
+
+ pixman_add_traps (mask_img, 0, 0, 1, &trap);
+
+ pixman_image_composite (PIXMAN_OP_OVER,
+ src_img, mask_img, dest_img,
+ 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+ assert (bits[0] == 0xffff0000);
+ assert (bits[1] == 0xffffffff);
+ assert (bits[1 * WIDTH + 0] == 0xffffffff);
+ assert (bits[1 * WIDTH + 1] == 0xffffffff);
+
+ return 0;
+}
diff --git a/test/alphamap.c b/test/alphamap.c
new file mode 100644
index 0000000..e6a25ef
--- /dev/null
+++ b/test/alphamap.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+#define WIDTH 400
+#define HEIGHT 200
+
+int
+main (int argc, char **argv)
+{
+ uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
+ uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+ uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+ int i;
+
+ pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
+ pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+
+ for (i = 0; i < 2; ++i)
+ {
+ pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : PIXMAN_a2r10g10b10;
+ pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, src, WIDTH * 4);
+ int j, k;
+
+ pixman_image_set_alpha_map (s, a, 0, 0);
+
+ pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+ for (j = 0; j < HEIGHT; ++j)
+ {
+ for (k = 0; k < WIDTH; ++k)
+ {
+ uint8_t ap = ((uint8_t *)alpha)[j * WIDTH + k];
+ uint32_t dap = (dest[j * WIDTH + k] >> 24);
+ uint32_t sap = (src[j * WIDTH + k] >> 24);
+
+ if (ap != dap)
+ {
+ printf ("Wrong alpha value at (%d, %d). Should be %d; got %d (src was %d)\n", k, j, ap, dap, sap);
+ return 1;
+ }
+ }
+ }
+
+ pixman_image_unref (s);
+ }
+
+ return 0;
+}
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 979af24..4664db6 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -96,7 +96,7 @@ free_random_image (uint32_t initcrc,
uint32_t crc32 = 0;
int stride = pixman_image_get_stride (img);
uint32_t *data = pixman_image_get_data (img);
- int height = pixman_image_get_height (img);;
+ int height = pixman_image_get_height (img);
if (fmt != -1)
{
@@ -270,7 +270,7 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
int w, h;
int op;
pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
- uint32_t *dstbuf;
+ uint32_t *dstbuf, *srcbuf, *maskbuf;
uint32_t crc32;
int max_width, max_height, max_extra_stride;
@@ -308,12 +308,43 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
dst_img = create_random_image (img_fmt_list, max_width, max_height,
max_extra_stride, &dst_fmt);
+ src_width = pixman_image_get_width (src_img);
+ src_height = pixman_image_get_height (src_img);
+ src_stride = pixman_image_get_stride (src_img);
+
+ dst_width = pixman_image_get_width (dst_img);
+ dst_height = pixman_image_get_height (dst_img);
+ dst_stride = pixman_image_get_stride (dst_img);
+
+ dstbuf = pixman_image_get_data (dst_img);
+ srcbuf = pixman_image_get_data (src_img);
+
+ src_x = lcg_rand_n (src_width);
+ src_y = lcg_rand_n (src_height);
+ dst_x = lcg_rand_n (dst_width);
+ dst_y = lcg_rand_n (dst_height);
+
mask_img = NULL;
mask_fmt = -1;
mask_x = 0;
mask_y = 0;
+ maskbuf = NULL;
- if (lcg_rand_n (2))
+ if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
+ (lcg_rand_n (4) == 0))
+ {
+ /* PIXBUF */
+ mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
+ mask_img = pixman_image_create_bits (mask_fmt,
+ src_width,
+ src_height,
+ srcbuf,
+ src_stride);
+ mask_x = src_x;
+ mask_y = src_y;
+ maskbuf = srcbuf;
+ }
+ else if (lcg_rand_n (2))
{
if (lcg_rand_n (2))
{
@@ -335,20 +366,6 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
}
- src_width = pixman_image_get_width (src_img);
- src_height = pixman_image_get_height (src_img);
- src_stride = pixman_image_get_stride (src_img);
-
- dst_width = pixman_image_get_width (dst_img);
- dst_height = pixman_image_get_height (dst_img);
- dst_stride = pixman_image_get_stride (dst_img);
-
- dstbuf = pixman_image_get_data (dst_img);
-
- src_x = lcg_rand_n (src_width);
- src_y = lcg_rand_n (src_height);
- dst_x = lcg_rand_n (dst_width);
- dst_y = lcg_rand_n (dst_height);
w = lcg_rand_n (dst_width - dst_x + 1);
h = lcg_rand_n (dst_height - dst_y + 1);
@@ -392,7 +409,13 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
crc32 = free_random_image (initcrc, dst_img, dst_fmt);
if (mask_img)
- free_random_image (initcrc, mask_img, -1);
+ {
+ if (srcbuf == maskbuf)
+ pixman_image_unref(mask_img);
+ else
+ free_random_image (initcrc, mask_img, -1);
+ }
+
return crc32;
}
@@ -440,7 +463,7 @@ main (int argc, char *argv[])
/* Predefined value for running with all the fastpath functions
disabled. It needs to be updated every time when changes are
introduced to this program or behavior of pixman changes! */
- if (crc == 0x1911E2C3)
+ if (crc == 0x20CBE02C)
{
printf ("blitters test passed\n");
}
diff --git a/test/fetch-test.c b/test/fetch-test.c
index 6306a4c..2ca16dd 100644
--- a/test/fetch-test.c
+++ b/test/fetch-test.c
@@ -6,7 +6,8 @@
#define SIZE 1024
-pixman_indexed_t mono_pallete = {
+static pixman_indexed_t mono_palette =
+{
.rgba = { 0x00000000, 0x00ffffff },
};
@@ -20,14 +21,15 @@ typedef struct {
pixman_indexed_t *indexed;
} testcase_t;
-testcase_t testcases[] = {
+static testcase_t testcases[] =
+{
{
.format = PIXMAN_a8r8g8b8,
.width = 2, .height = 2,
.stride = 8,
- .src = { 0x00112233, 0x44556677,
+ .src = { 0x00112233, 0x44556677,
0x8899aabb, 0xccddeeff },
- .dst = { 0x00112233, 0x44556677,
+ .dst = { 0x00112233, 0x44556677,
0x8899aabb, 0xccddeeff },
.indexed = NULL,
},
@@ -36,24 +38,33 @@ testcase_t testcases[] = {
.width = 8, .height = 2,
.stride = 4,
#ifdef WORDS_BIGENDIAN
- .src = { 0xaa000000,
- 0x55000000 },
+ .src =
+ {
+ 0xaa000000,
+ 0x55000000
+ },
#else
- .src = { 0x00000055,
- 0x000000aa },
+ .src =
+ {
+ 0x00000055,
+ 0x000000aa
+ },
#endif
- .dst = { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000,
- 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
- .indexed = &mono_pallete,
+ .dst =
+ {
+ 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000,
+ 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff
+ },
+ .indexed = &mono_palette,
},
#if 0
{
.format = PIXMAN_g8,
.width = 4, .height = 2,
.stride = 4,
- .src = { 0x01234567,
+ .src = { 0x01234567,
0x89abcdef },
- .dst = { 0x00010101, 0x00232323, 0x00454545, 0x00676767,
+ .dst = { 0x00010101, 0x00232323, 0x00454545, 0x00676767,
0x00898989, 0x00ababab, 0x00cdcdcd, 0x00efefef, },
},
#endif
@@ -63,28 +74,33 @@ testcase_t testcases[] = {
.width = 8, .height = 2,
.stride = 8,
#ifdef WORDS_BIGENDIAN
- .src = { 0x00ff00ff, 0x00ff00ff,
- 0xff00ff00, 0xff00ff00,
- 0x80ff8000,
- 0x800080ff
+ .src =
+ {
+ 0x00ff00ff, 0x00ff00ff,
+ 0xff00ff00, 0xff00ff00,
+ 0x80ff8000,
+ 0x800080ff
},
#else
- .src = { 0xff00ff00, 0xff00ff00,
- 0x00ff00ff, 0x00ff00ff,
- 0x0080ff80,
- 0xff800080
- },
+ .src =
+ {
+ 0xff00ff00, 0xff00ff00,
+ 0x00ff00ff, 0x00ff00ff,
+ 0x0080ff80,
+ 0xff800080
+ },
#endif
- .dst = {
- 0xff000000, 0xffffffff, 0xffb80000, 0xffffe113,
- 0xff000000, 0xffffffff, 0xff0023ee, 0xff4affff,
- 0xffffffff, 0xff000000, 0xffffe113, 0xffb80000,
- 0xffffffff, 0xff000000, 0xff4affff, 0xff0023ee,
+ .dst =
+ {
+ 0xff000000, 0xffffffff, 0xffb80000, 0xffffe113,
+ 0xff000000, 0xffffffff, 0xff0023ee, 0xff4affff,
+ 0xffffffff, 0xff000000, 0xffffe113, 0xffb80000,
+ 0xffffffff, 0xff000000, 0xff4affff, 0xff0023ee,
},
},
};
-const int ntestcases = sizeof(testcases)/sizeof(testcases[0]);
+int n_test_cases = sizeof(testcases)/sizeof(testcases[0]);
static uint32_t
@@ -133,26 +149,29 @@ main (int argc, char **argv)
int i, j, x, y;
int ret = 0;
- for (i = 0; i < ntestcases; ++i) {
- for (j = 0; j < 2; ++j) {
+ for (i = 0; i < n_test_cases; ++i)
+ {
+ for (j = 0; j < 2; ++j)
+ {
src_img = pixman_image_create_bits (testcases[i].format,
- testcases[i].width,
+ testcases[i].width,
testcases[i].height,
testcases[i].src,
testcases[i].stride);
pixman_image_set_indexed(src_img, testcases[i].indexed);
dst_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
- testcases[i].width,
+ testcases[i].width,
testcases[i].height,
dst,
testcases[i].width*4);
- if (j) {
+ if (j)
+ {
pixman_image_set_accessors (src_img, reader, writer);
pixman_image_set_accessors (dst_img, reader, writer);
}
-
+
pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
0, 0, 0, 0, 0, 0, testcases[i].width, testcases[i].height);
@@ -160,18 +179,23 @@ main (int argc, char **argv)
pixman_image_unref (dst_img);
for (y = 0; y < testcases[i].height; ++y)
- for (x = 0; x < testcases[i].width; ++x) {
- int offset = y*testcases[i].width + x;
- if (dst[offset] != testcases[i].dst[offset]) {
+ {
+ for (x = 0; x < testcases[i].width; ++x)
+ {
+ int offset = y * testcases[i].width + x;
+
+ if (dst[offset] != testcases[i].dst[offset])
+ {
printf ("test %i%c: pixel mismatch at (x=%d,y=%d): %08x expected, %08x obtained\n",
i + 1, 'a' + j,
- x, y,
+ x, y,
testcases[i].dst[offset], dst[offset]);
ret = 1;
}
}
+ }
}
}
-
+
return ret;
}
diff --git a/test/region-test.c b/test/region-test.c
index 3568969..9d5a41e 100644
--- a/test/region-test.c
+++ b/test/region-test.c
@@ -1,7 +1,7 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
-#include "pixman.h"
+#include "utils.h"
int
main ()
@@ -22,8 +22,15 @@ main ()
{ 2, 6, 7, 6 },
{ 4, 1, 6, 1 },
};
- int i;
+ int i, j;
pixman_box32_t *b;
+ pixman_image_t *image, *fill;
+ pixman_color_t white = {
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff
+ };
/* This used to go into an infinite loop before pixman-region.c
* was fixed to not use explict "short" variables
@@ -74,5 +81,43 @@ main ()
assert (i == 0);
+ fill = pixman_image_create_solid_fill (&white);
+ for (i = 0; i < 100; i++)
+ {
+ int image_size = 128;
+
+ pixman_region32_init (&r1);
+
+ /* Add some random rectangles */
+ for (j = 0; j < 64; j++)
+ pixman_region32_union_rect (&r1, &r1,
+ lcg_rand_n (image_size),
+ lcg_rand_n (image_size),
+ lcg_rand_n (25),
+ lcg_rand_n (25));
+
+ /* Clip to image size */
+ pixman_region32_init_rect (&r2, 0, 0, image_size, image_size);
+ pixman_region32_intersect (&r1, &r1, &r2);
+ pixman_region32_fini (&r2);
+
+ /* render region to a1 mask */
+ image = pixman_image_create_bits (PIXMAN_a1, image_size, image_size, NULL, 0);
+ pixman_image_set_clip_region32 (image, &r1);
+ pixman_image_composite32 (PIXMAN_OP_SRC,
+ fill, NULL, image,
+ 0, 0, 0, 0, 0, 0,
+ image_size, image_size);
+ pixman_region32_init_from_image (&r2, image);
+
+ pixman_image_unref (image);
+
+ assert (pixman_region32_equal (&r1, &r2));
+ pixman_region32_fini (&r1);
+ pixman_region32_fini (&r2);
+
+ }
+ pixman_image_unref (fill);
+
return 0;
}
diff --git a/test/utils.c b/test/utils.c
index 1e42d89..58cd100 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -192,3 +192,17 @@ image_endian_swap (pixman_image_t *img, int bpp)
}
}
+uint8_t *
+make_random_bytes (int n_bytes)
+{
+ uint8_t *bytes = malloc (n_bytes);
+ int i;
+
+ if (!bytes)
+ return NULL;
+
+ for (i = 0; i < n_bytes; ++i)
+ bytes[i] = lcg_rand () & 0xff;
+
+ return bytes;
+}
diff --git a/test/utils.h b/test/utils.h
index 8fdb2ce..fb1ccec 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -39,3 +39,7 @@ compute_crc32 (uint32_t in_crc32,
*/
void
image_endian_swap (pixman_image_t *img, int bpp);
+
+/* Generate n_bytes random bytes in malloced memory */
+uint8_t *
+make_random_bytes (int n_bytes);