diff options
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/configure | 24 | ||||
-rw-r--r-- | pixman/configure.ac | 2 | ||||
-rw-r--r-- | pixman/pixman/pixman-arm-neon-asm.S | 198 | ||||
-rw-r--r-- | pixman/pixman/pixman-arm-neon.c | 15 | ||||
-rw-r--r-- | pixman/pixman/pixman-bits-image.c | 52 | ||||
-rw-r--r-- | pixman/pixman/pixman-image.c | 283 | ||||
-rw-r--r-- | pixman/pixman/pixman-private.h | 15 | ||||
-rw-r--r-- | pixman/pixman/pixman-version.h | 4 | ||||
-rw-r--r-- | pixman/pixman/pixman.c | 196 | ||||
-rw-r--r-- | pixman/test/blitters-test.c | 2 |
10 files changed, 502 insertions, 289 deletions
diff --git a/pixman/configure b/pixman/configure index e3d0dd93b..dbfa7b756 100644 --- a/pixman/configure +++ b/pixman/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for pixman 0.17.8. +# Generated by GNU Autoconf 2.63 for pixman 0.17.10. # # Report bugs to <"sandmann@daimi.au.dk">. # @@ -745,8 +745,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='pixman' PACKAGE_TARNAME='pixman' -PACKAGE_VERSION='0.17.8' -PACKAGE_STRING='pixman 0.17.8' +PACKAGE_VERSION='0.17.10' +PACKAGE_STRING='pixman 0.17.10' PACKAGE_BUGREPORT='"sandmann@daimi.au.dk"' # Factoring default headers for most tests. @@ -1517,7 +1517,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures pixman 0.17.8 to adapt to many kinds of systems. +\`configure' configures pixman 0.17.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1587,7 +1587,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pixman 0.17.8:";; + short | recursive ) echo "Configuration of pixman 0.17.10:";; esac cat <<\_ACEOF @@ -1702,7 +1702,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pixman configure 0.17.8 +pixman configure 0.17.10 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1716,7 +1716,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by pixman $as_me 0.17.8, which was +It was created by pixman $as_me 0.17.10, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -2565,7 +2565,7 @@ fi # Define the identity of the package. PACKAGE='pixman' - VERSION='0.17.8' + VERSION='0.17.10' cat >>confdefs.h <<_ACEOF @@ -12350,13 +12350,13 @@ fi -LT_VERSION_INFO="17:8:17" +LT_VERSION_INFO="17:10:17" PIXMAN_VERSION_MAJOR=0 PIXMAN_VERSION_MINOR=17 -PIXMAN_VERSION_MICRO=8 +PIXMAN_VERSION_MICRO=10 @@ -13999,7 +13999,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by pixman $as_me 0.17.8, which was +This file was extended by pixman $as_me 0.17.10, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14062,7 +14062,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -pixman config.status 0.17.8 +pixman config.status 0.17.10 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/pixman/configure.ac b/pixman/configure.ac index 0089c2b4d..a84d56059 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -54,7 +54,7 @@ AC_PREREQ([2.57]) m4_define([pixman_major], 0) m4_define([pixman_minor], 17) -m4_define([pixman_micro], 8) +m4_define([pixman_micro], 10) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) diff --git a/pixman/pixman/pixman-arm-neon-asm.S b/pixman/pixman/pixman-arm-neon-asm.S index 298688442..eb8cc4c96 100644 --- a/pixman/pixman/pixman-arm-neon-asm.S +++ b/pixman/pixman/pixman-arm-neon-asm.S @@ -680,6 +680,61 @@ generate_composite_function \ /******************************************************************************/ +.macro pixman_composite_over_reverse_n_8888_process_pixblock_tail_head + vrshr.u16 q14, q8, #8 + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + PF cmp PF_X, ORIG_W + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 + vld4.8 {d0, d1, d2, d3}, [DST_R, :128]! + vmvn.8 d22, d3 + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF subge PF_X, PF_X, ORIG_W + vmull.u8 q8, d22, d4 + PF subges PF_CTL, PF_CTL, #0x10 + vmull.u8 q9, d22, d5 + vmull.u8 q10, d22, d6 + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vmull.u8 q11, d22, d7 +.endm + +.macro pixman_composite_over_reverse_n_8888_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d7[0]}, [DUMMY] + vdup.8 d4, d7[0] + vdup.8 d5, d7[1] + vdup.8 d6, d7[2] + vdup.8 d7, d7[3] +.endm + +generate_composite_function \ + pixman_composite_over_reverse_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_reverse_n_8888_init, \ + default_cleanup, \ + pixman_composite_over_8888_8888_process_pixblock_head, \ + pixman_composite_over_8888_8888_process_pixblock_tail, \ + pixman_composite_over_reverse_n_8888_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 4, /* src_basereg */ \ + 24 /* mask_basereg */ + +/******************************************************************************/ + .macro pixman_composite_over_n_8_0565_process_pixblock_head /* in */ vmull.u8 q0, d24, d8 @@ -947,6 +1002,44 @@ generate_composite_function \ /******************************************************************************/ +.macro pixman_composite_src_x888_8888_process_pixblock_head + vorr q0, q0, q2 + vorr q1, q1, q2 +.endm + +.macro pixman_composite_src_x888_8888_process_pixblock_tail +.endm + +.macro pixman_composite_src_x888_8888_process_pixblock_tail_head + vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! + vld1.32 {d0, d1, d2, d3}, [SRC]! + vorr q0, q0, q2 + vorr q1, q1, q2 + cache_preload 8, 8 +.endm + +.macro pixman_composite_src_x888_8888_init + vmov.u8 q2, #0xFF + vshl.u32 q2, q2, #24 +.endm + +generate_composite_function \ + pixman_composite_src_x888_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + pixman_composite_src_x888_8888_init, \ + default_cleanup, \ + pixman_composite_src_x888_8888_process_pixblock_head, \ + pixman_composite_src_x888_8888_process_pixblock_tail, \ + pixman_composite_src_x888_8888_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + .macro pixman_composite_over_n_8_8888_process_pixblock_head /* expecting deinterleaved source data in {d8, d9, d10, d11} */ /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ @@ -1026,6 +1119,111 @@ generate_composite_function \ /******************************************************************************/ +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_head + /* + * 'combine_mask_ca' replacement + * + * input: solid src (n) in {d8, d9, d10, d11} + * dest in {d4, d5, d6, d7 } + * mask in {d24, d25, d26, d27} + * output: updated src in {d0, d1, d2, d3 } + * updated mask in {d24, d25, d26, d3 } + */ + vmull.u8 q0, d24, d8 + vmull.u8 q1, d25, d9 + vmull.u8 q6, d26, d10 + vmull.u8 q7, d27, d11 + vmull.u8 q9, d11, d25 + vmull.u8 q12, d11, d24 + vmull.u8 q13, d11, d26 + vrshr.u16 q8, q0, #8 + vrshr.u16 q10, q1, #8 + vrshr.u16 q11, q6, #8 + vraddhn.u16 d0, q0, q8 + vraddhn.u16 d1, q1, q10 + vraddhn.u16 d2, q6, q11 + vrshr.u16 q11, q12, #8 + vrshr.u16 q8, q9, #8 + vrshr.u16 q6, q13, #8 + vrshr.u16 q10, q7, #8 + vraddhn.u16 d24, q12, q11 + vraddhn.u16 d25, q9, q8 + vraddhn.u16 d26, q13, q6 + vraddhn.u16 d3, q7, q10 + /* + * 'combine_over_ca' replacement + * + * output: updated dest in {d28, d29, d30, d31} + */ + vmvn.8 d24, d24 + vmvn.8 d25, d25 + vmull.u8 q8, d24, d4 + vmull.u8 q9, d25, d5 + vmvn.8 d26, d26 + vmvn.8 d27, d3 + vmull.u8 q10, d26, d6 + vmull.u8 q11, d27, d7 +.endm + +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail + /* ... continue 'combine_over_ca' replacement */ + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vrshr.u16 q6, q10, #8 + vrshr.u16 q7, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q6, q10 + vraddhn.u16 d31, q7, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 +.endm + +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vrshr.u16 q6, q10, #8 + vrshr.u16 q7, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q6, q10 + vraddhn.u16 d31, q7, q11 + vld4.8 {d24, d25, d26, d27}, [MASK]! + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 + cache_preload 8, 8 + pixman_composite_over_n_8888_8888_ca_process_pixblock_head + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! +.endm + +.macro pixman_composite_over_n_8888_8888_ca_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vpush {d8-d15} + vld1.32 {d11[0]}, [DUMMY] + vdup.8 d8, d11[0] + vdup.8 d9, d11[1] + vdup.8 d10, d11[2] + vdup.8 d11, d11[3] +.endm + +.macro pixman_composite_over_n_8888_8888_ca_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_n_8888_8888_ca_asm_neon, 0, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_8888_8888_ca_init, \ + pixman_composite_over_n_8888_8888_ca_cleanup, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_head, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_tail, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head + +/******************************************************************************/ + .macro pixman_composite_add_n_8_8_process_pixblock_head /* expecting source data in {d8, d9, d10, d11} */ /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ diff --git a/pixman/pixman/pixman-arm-neon.c b/pixman/pixman/pixman-arm-neon.c index 557301e34..24ceeeb97 100644 --- a/pixman/pixman/pixman-arm-neon.c +++ b/pixman/pixman/pixman-arm-neon.c @@ -251,6 +251,7 @@ neon_composite_##name (pixman_implementation_t *imp, \ BIND_SRC_NULL_DST(src_8888_8888, uint32_t, 1, uint32_t, 1) +BIND_SRC_NULL_DST(src_x888_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) @@ -263,12 +264,14 @@ 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_N_NULL_DST(over_reverse_n_8888, 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(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(over_n_8888_8888_ca, uint32_t, 1, uint32_t, 1) BIND_N_MASK_DST(add_n_8_8, uint8_t, 1, uint8_t, 1) BIND_SRC_N_DST(over_8888_n_8888, uint32_t, 1, uint32_t, 1) @@ -399,6 +402,10 @@ static const pixman_fast_path_t arm_neon_fast_paths[] = 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, a8r8g8b8, null, a8r8g8b8, neon_composite_src_8888_8888), + PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, neon_composite_src_8888_8888), + PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888), + PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_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), @@ -412,6 +419,10 @@ static const pixman_fast_path_t arm_neon_fast_paths[] = 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_CA (OVER, solid, a8r8g8b8, a8r8g8b8, neon_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, neon_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, neon_composite_over_n_8888_8888_ca), + PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, neon_composite_over_n_8888_8888_ca), 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), @@ -425,12 +436,16 @@ static const pixman_fast_path_t arm_neon_fast_paths[] = 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 (OVER, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888), + PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_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_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, neon_composite_over_reverse_n_8888), + PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888), { PIXMAN_OP_NONE }, }; diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c index 6befcbb48..3d78ff079 100644 --- a/pixman/pixman/pixman-bits-image.c +++ b/pixman/pixman/pixman-bits-image.c @@ -875,55 +875,6 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image, } } -static pixman_bool_t out_of_bounds_workaround = TRUE; - -/* 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 - * pointing to some bogus position in memory, but then they set a clip - * region to the position where the actual bits are. - * - * Due to a bug in old versions of pixman, where it would not clip - * against the image bounds when a clip region was set, this would - * actually work. So by default we allow certain out-of-bound access - * to happen unless explicitly disabled. - * - * Fixed X servers should call this function to disable the workaround. - */ -PIXMAN_EXPORT void -pixman_disable_out_of_bounds_workaround (void) -{ - out_of_bounds_workaround = FALSE; -} - -static pixman_bool_t -source_image_needs_out_of_bounds_workaround (bits_image_t *image) -{ - if (image->common.clip_sources && - image->common.repeat == PIXMAN_REPEAT_NONE && - image->common.have_clip_region && - out_of_bounds_workaround) - { - if (!image->common.client_clip) - { - /* There is no client clip, so if the clip region extends beyond the - * drawable geometry, it must be because the X server generated the - * bogus clip region. - */ - const pixman_box32_t *extents = pixman_region32_extents (&image->common.clip_region); - - if (extents->x1 >= 0 && extents->x2 <= image->width && - extents->y1 >= 0 && extents->y2 <= image->height) - { - return FALSE; - } - } - - return TRUE; - } - - return FALSE; -} - static void bits_image_property_changed (pixman_image_t *image) { @@ -985,9 +936,6 @@ bits_image_property_changed (pixman_image_t *image) bits->store_scanline_64 = bits_image_store_scanline_64; bits->store_scanline_32 = bits_image_store_scanline_32; - - bits->common.need_workaround = - source_image_needs_out_of_bounds_workaround (bits); } static uint32_t * diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 6036c568e..d09d19301 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -117,7 +117,6 @@ _pixman_image_allocate (void) common->client_clip = FALSE; common->destroy_func = NULL; common->destroy_data = NULL; - common->need_workaround = FALSE; common->dirty = TRUE; } @@ -243,12 +242,220 @@ _pixman_image_reset_clip_region (pixman_image_t *image) image->common.have_clip_region = FALSE; } +static pixman_bool_t out_of_bounds_workaround = TRUE; + +/* 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 + * pointing to some bogus position in memory, but then they set a clip + * region to the position where the actual bits are. + * + * Due to a bug in old versions of pixman, where it would not clip + * against the image bounds when a clip region was set, this would + * actually work. So by default we allow certain out-of-bound access + * to happen unless explicitly disabled. + * + * Fixed X servers should call this function to disable the workaround. + */ +PIXMAN_EXPORT void +pixman_disable_out_of_bounds_workaround (void) +{ + out_of_bounds_workaround = FALSE; +} + +static pixman_bool_t +source_image_needs_out_of_bounds_workaround (bits_image_t *image) +{ + if (image->common.clip_sources && + image->common.repeat == PIXMAN_REPEAT_NONE && + image->common.have_clip_region && + out_of_bounds_workaround) + { + if (!image->common.client_clip) + { + /* There is no client clip, so if the clip region extends beyond the + * drawable geometry, it must be because the X server generated the + * bogus clip region. + */ + const pixman_box32_t *extents = + pixman_region32_extents (&image->common.clip_region); + + if (extents->x1 >= 0 && extents->x2 <= image->width && + extents->y1 >= 0 && extents->y2 <= image->height) + { + return FALSE; + } + } + + return TRUE; + } + + return FALSE; +} + +static void +compute_image_info (pixman_image_t *image) +{ + pixman_format_code_t code; + uint32_t flags = 0; + + /* Transform */ + 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; + } + + /* Alpha map */ + if (!image->common.alpha_map) + flags |= FAST_PATH_NO_ALPHA_MAP; + + /* Filter */ + switch (image->common.filter) + { + case PIXMAN_FILTER_NEAREST: + case PIXMAN_FILTER_FAST: + flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + break; + + case PIXMAN_FILTER_CONVOLUTION: + break; + + default: + flags |= FAST_PATH_NO_CONVOLUTION_FILTER; + break; + } + + /* Repeat mode */ + switch (image->common.repeat) + { + case PIXMAN_REPEAT_REFLECT: + flags |= FAST_PATH_NO_PAD_REPEAT; + break; + + case PIXMAN_REPEAT_PAD: + flags |= FAST_PATH_NO_REFLECT_REPEAT; + break; + + default: + flags |= (FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_PAD_REPEAT); + break; + } + + /* Component alpha */ + if (image->common.component_alpha) + flags |= FAST_PATH_COMPONENT_ALPHA; + else + flags |= FAST_PATH_UNIFIED_ALPHA; + + flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NO_WIDE_FORMAT); + + /* Type specific checks */ + switch (image->type) + { + case SOLID: + code = PIXMAN_solid; + + if (image->solid.color.alpha == 0xffff) + flags |= FAST_PATH_IS_OPAQUE; + break; + + case BITS: + if (image->bits.width == 1 && + image->bits.height == 1 && + image->common.repeat != PIXMAN_REPEAT_NONE) + { + code = PIXMAN_solid; + } + else + { + code = image->bits.format; + + if (!image->common.transform && + image->common.repeat == PIXMAN_REPEAT_NORMAL) + { + flags |= FAST_PATH_SIMPLE_REPEAT; + } + } + + if (image->common.repeat != PIXMAN_REPEAT_NONE && + !PIXMAN_FORMAT_A (image->bits.format)) + { + flags |= FAST_PATH_IS_OPAQUE; + } + + if (source_image_needs_out_of_bounds_workaround (&image->bits)) + flags |= FAST_PATH_NEEDS_WORKAROUND; + + 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; + break; + + case LINEAR: + case RADIAL: + code = PIXMAN_unknown; + + if (image->common.repeat != PIXMAN_REPEAT_NONE) + { + int i; + + flags |= FAST_PATH_IS_OPAQUE; + for (i = 0; i < image->gradient.n_stops; ++i) + { + if (image->gradient.stops[i].color.alpha != 0xffff) + { + flags &= ~FAST_PATH_IS_OPAQUE; + break; + } + } + } + break; + + default: + code = PIXMAN_unknown; + break; + } + + /* Both alpha maps and convolution filters can introduce + * non-opaqueness in otherwise opaque images. Also + * an image with component alpha turned on is only opaque + * if all channels are opaque, so we simply turn it off + * unconditionally for those images. + */ + if (image->common.alpha_map || + image->common.filter == PIXMAN_FILTER_CONVOLUTION || + image->common.component_alpha) + { + flags &= ~FAST_PATH_IS_OPAQUE; + } + + image->common.flags = flags; + image->common.extended_format_code = code; +} + void _pixman_image_validate (pixman_image_t *image) { if (image->common.dirty) { + compute_image_info (image); + + /* It is important that property_changed is + * called *after* compute_image_info() because + * property_changed() can make use of the flags + * to set up accessors etc. + */ image->common.property_changed (image); + image->common.dirty = FALSE; } @@ -522,25 +729,6 @@ pixman_image_get_depth (pixman_image_t *image) return 0; } -pixman_bool_t -_pixman_image_is_solid (pixman_image_t *image) -{ - if (image->type == SOLID) - return TRUE; - - if (image->type != BITS || - image->bits.width != 1 || - image->bits.height != 1) - { - return FALSE; - } - - if (image->common.repeat == PIXMAN_REPEAT_NONE) - return FALSE; - - return TRUE; -} - uint32_t _pixman_image_get_solid (pixman_image_t * image, pixman_format_code_t format) @@ -560,58 +748,3 @@ _pixman_image_get_solid (pixman_image_t * image, return result; } - -pixman_bool_t -_pixman_image_is_opaque (pixman_image_t *image) -{ - int i; - - if (image->common.alpha_map) - return FALSE; - - switch (image->type) - { - case BITS: - if (image->common.repeat == PIXMAN_REPEAT_NONE) - return FALSE; - - if (PIXMAN_FORMAT_A (image->bits.format)) - return FALSE; - break; - - case LINEAR: - case RADIAL: - if (image->common.repeat == PIXMAN_REPEAT_NONE) - return FALSE; - - for (i = 0; i < image->gradient.n_stops; ++i) - { - if (image->gradient.stops[i].color.alpha != 0xffff) - return FALSE; - } - break; - - case CONICAL: - /* Conical gradients always have a transparent border */ - return FALSE; - break; - - case SOLID: - if (image->solid.color.alpha != 0xffff) - return FALSE; - break; - - default: - return FALSE; - break; - } - - /* Convolution filters can introduce translucency if the sum of the - * weights is lower than 1. - */ - if (image->common.filter == PIXMAN_FILTER_CONVOLUTION) - return FALSE; - - return TRUE; -} - diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index 7ed8aa7a1..94451d332 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -86,7 +86,6 @@ struct image_common * the image is used as a source */ pixman_bool_t dirty; - pixman_bool_t need_workaround; pixman_transform_t * transform; pixman_repeat_t repeat; pixman_filter_t filter; @@ -103,6 +102,9 @@ struct image_common pixman_image_destroy_func_t destroy_func; void * destroy_data; + + uint32_t flags; + pixman_format_code_t extended_format_code; }; struct source_image @@ -281,12 +283,6 @@ _pixman_image_reset_clip_region (pixman_image_t *image); void _pixman_image_validate (pixman_image_t *image); -pixman_bool_t -_pixman_image_is_opaque (pixman_image_t *image); - -pixman_bool_t -_pixman_image_is_solid (pixman_image_t *image); - uint32_t _pixman_image_get_solid (pixman_image_t * image, pixman_format_code_t format); @@ -562,7 +558,7 @@ _pixman_choose_implementation (void); #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_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0) #define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1) @@ -578,6 +574,9 @@ _pixman_choose_implementation (void); #define FAST_PATH_UNIFIED_ALPHA (1 << 9) #define FAST_PATH_SCALE_TRANSFORM (1 << 10) #define FAST_PATH_NEAREST_FILTER (1 << 11) +#define FAST_PATH_SIMPLE_REPEAT (1 << 12) +#define FAST_PATH_IS_OPAQUE (1 << 13) +#define FAST_PATH_NEEDS_WORKAROUND (1 << 14) #define _FAST_PATH_STANDARD_FLAGS \ (FAST_PATH_ID_TRANSFORM | \ diff --git a/pixman/pixman/pixman-version.h b/pixman/pixman/pixman-version.h index 6422670fe..9acad60a1 100644 --- a/pixman/pixman/pixman-version.h +++ b/pixman/pixman/pixman-version.h @@ -33,9 +33,9 @@ #define PIXMAN_VERSION_MAJOR 0 #define PIXMAN_VERSION_MINOR 17 -#define PIXMAN_VERSION_MICRO 8 +#define PIXMAN_VERSION_MICRO 10 -#define PIXMAN_VERSION_STRING "0.17.8" +#define PIXMAN_VERSION_STRING "0.17.10" #define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \ ((major) * 10000) \ diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c index 6a260ed40..3aa265f8b 100644 --- a/pixman/pixman/pixman.c +++ b/pixman/pixman/pixman.c @@ -88,14 +88,13 @@ pixman_optimize_operator (pixman_op_t op, pixman_bool_t is_source_opaque; pixman_bool_t is_dest_opaque; const optimized_operator_info_t *info = pixman_operator_can_be_optimized (op); - if (!info || mask_image) return op; - is_source_opaque = _pixman_image_is_opaque (src_image); - is_dest_opaque = _pixman_image_is_opaque (dst_image); + is_source_opaque = src_image->common.flags & FAST_PATH_IS_OPAQUE; + is_dest_opaque = dst_image->common.flags & FAST_PATH_IS_OPAQUE; - if (is_source_opaque == FALSE && is_dest_opaque == FALSE) + if (!is_source_opaque && !is_dest_opaque) return op; if (is_source_opaque && is_dest_opaque) @@ -117,7 +116,7 @@ apply_workaround (pixman_image_t *image, int * save_dx, int * save_dy) { - if (image && image->common.need_workaround) + if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND)) { /* Some X servers generate images that point to the * wrong place in memory, but then set the clip region @@ -153,7 +152,7 @@ apply_workaround (pixman_image_t *image, static void unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy) { - if (image && image->common.need_workaround) + if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND)) { image->bits.bits = bits; pixman_region32_translate (&image->common.clip_region, dx, dy); @@ -448,69 +447,6 @@ walk_region_internal (pixman_implementation_t *imp, } } -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, @@ -548,22 +484,33 @@ do_composite (pixman_implementation_t *imp, { 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; + 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; + + src_format = src->common.extended_format_code; + src_flags = src->common.flags; - get_image_info (src, &src_format, &src_flags); if (mask) { - get_image_info (mask, &mask_format, &mask_flags); + mask_format = mask->common.extended_format_code; + mask_flags = mask->common.flags; } else { mask_format = PIXMAN_null; mask_flags = 0; } - get_image_info (dest, &dest_format, &dest_flags); - + + dest_format = dest->common.extended_format_code; + dest_flags = dest->common.flags; + /* Check for pixbufs */ if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) && (src->type == BITS && src->bits.bits == mask->bits.bits) && @@ -575,20 +522,17 @@ do_composite (pixman_implementation_t *imp, 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; - + + /* Check for workaround */ + need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND; + + if (need_workaround) + { + apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy); + apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy); + apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy); + } + pixman_region32_init (®ion); if (!pixman_compute_composite_region32 ( @@ -631,7 +575,8 @@ do_composite (pixman_implementation_t *imp, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height, - src_repeat, mask_repeat, + (src_flags & FAST_PATH_SIMPLE_REPEAT), + (mask_flags & FAST_PATH_SIMPLE_REPEAT), ®ion, info->func); @@ -643,9 +588,34 @@ do_composite (pixman_implementation_t *imp, } done: + if (need_workaround) + { + unapply_workaround (src, src_bits, src_dx, src_dy); + unapply_workaround (mask, mask_bits, mask_dx, mask_dy); + unapply_workaround (dest, dest_bits, dest_dx, dest_dy); + } + pixman_region32_fini (®ion); } +PIXMAN_EXPORT void +pixman_image_composite (pixman_op_t op, + pixman_image_t * src, + pixman_image_t * mask, + pixman_image_t * dest, + 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_image_composite32 (op, src, mask, dest, src_x, src_y, + mask_x, mask_y, dest_x, dest_y, width, height); +} + /* * Work around GCC bug causing crashes in Mozilla with SSE2 * @@ -666,24 +636,6 @@ done: __attribute__((__force_align_arg_pointer__)) #endif PIXMAN_EXPORT void -pixman_image_composite (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - 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_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, @@ -697,14 +649,6 @@ pixman_image_composite32 (pixman_op_t op, 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) _pixman_image_validate (mask); @@ -726,34 +670,12 @@ pixman_image_composite32 (pixman_op_t op, if (!imp) imp = _pixman_choose_implementation (); - 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); - apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy); - apply_workaround (dest, &dest_x, &dest_y, &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 diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 4664db63b..0b4b6c98c 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -27,8 +27,6 @@ #include <config.h> #include "utils.h" -/* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */ - static void * aligned_malloc (size_t align, size_t size) { |