summaryrefslogtreecommitdiff
path: root/lib/pixman
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2016-10-01 10:17:45 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2016-10-01 10:17:45 +0000
commit6e29ee4062908ba8e6124bf8b3a2083e1b2d3e36 (patch)
treee254d752e6bbd8d1b208522c3a952e16f2167f29 /lib/pixman
parentaa49994dd96792e111dc00188e3c73a2e20b9780 (diff)
Update to pixman 0.34.0.
Diffstat (limited to 'lib/pixman')
-rw-r--r--lib/pixman/config.h.in3
-rw-r--r--lib/pixman/configure114
-rw-r--r--lib/pixman/configure.ac42
-rw-r--r--lib/pixman/pixman/Makefile.am2
-rw-r--r--lib/pixman/pixman/Makefile.in8
-rw-r--r--lib/pixman/pixman/pixman-arm-asm.h37
-rw-r--r--lib/pixman/pixman/pixman-arm-common.h11
-rw-r--r--lib/pixman/pixman/pixman-arm-neon-asm-bilinear.S12
-rw-r--r--lib/pixman/pixman/pixman-arm-neon-asm.S12
-rw-r--r--lib/pixman/pixman/pixman-arm-neon-asm.h20
-rw-r--r--lib/pixman/pixman/pixman-arm-neon.c24
-rw-r--r--lib/pixman/pixman/pixman-arm-simd-asm-scaled.S11
-rw-r--r--lib/pixman/pixman/pixman-arm-simd-asm.S566
-rw-r--r--lib/pixman/pixman/pixman-arm-simd-asm.h116
-rw-r--r--lib/pixman/pixman/pixman-arm-simd.c50
-rw-r--r--lib/pixman/pixman/pixman-combine-float.c338
-rw-r--r--lib/pixman/pixman/pixman-combine32.c1556
-rw-r--r--lib/pixman/pixman/pixman-fast-path.c2
-rw-r--r--lib/pixman/pixman/pixman-general.c31
-rw-r--r--lib/pixman/pixman/pixman-gradient-walker.c2
-rw-r--r--lib/pixman/pixman/pixman-implementation.c16
-rw-r--r--lib/pixman/pixman/pixman-inlines.h3
-rw-r--r--lib/pixman/pixman/pixman-mips-dspr2-asm.S2
-rw-r--r--lib/pixman/pixman/pixman-mips-dspr2-asm.h4
-rw-r--r--lib/pixman/pixman/pixman-mips-dspr2.c10
-rw-r--r--lib/pixman/pixman/pixman-mips-dspr2.h8
-rw-r--r--lib/pixman/pixman/pixman-mmx.c126
-rw-r--r--lib/pixman/pixman/pixman-private.h6
-rw-r--r--lib/pixman/pixman/pixman-sse2.c24
-rw-r--r--lib/pixman/pixman/pixman-vmx.c1229
-rw-r--r--lib/pixman/pixman/pixman.c35
-rw-r--r--lib/pixman/test/Makefile.in187
-rw-r--r--lib/pixman/test/Makefile.sources62
-rw-r--r--lib/pixman/test/affine-bench.c448
-rw-r--r--lib/pixman/test/blitters-test.c20
-rw-r--r--lib/pixman/test/check-formats.c176
-rw-r--r--lib/pixman/test/composite.c11
-rw-r--r--lib/pixman/test/cover-test.c449
-rw-r--r--lib/pixman/test/fence-image-self-test.c239
-rw-r--r--lib/pixman/test/lowlevel-blt-bench.c513
-rw-r--r--lib/pixman/test/pixel-test.c2780
-rw-r--r--lib/pixman/test/radial-invalid.c54
-rw-r--r--lib/pixman/test/scaling-test.c66
-rw-r--r--lib/pixman/test/solid-test.c353
-rw-r--r--lib/pixman/test/thread-test.c29
-rw-r--r--lib/pixman/test/tolerance-test.c360
-rw-r--r--lib/pixman/test/utils.c786
-rw-r--r--lib/pixman/test/utils.h34
48 files changed, 8562 insertions, 2425 deletions
diff --git a/lib/pixman/config.h.in b/lib/pixman/config.h.in
index 17d825034..ab705701e 100644
--- a/lib/pixman/config.h.in
+++ b/lib/pixman/config.h.in
@@ -12,6 +12,9 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Whether we have FE_DIVBYZERO */
+#undef HAVE_FEDIVBYZERO
+
/* Whether we have feenableexcept() */
#undef HAVE_FEENABLEEXCEPT
diff --git a/lib/pixman/configure b/lib/pixman/configure
index d6f22cbe9..a79b6206b 100644
--- a/lib/pixman/configure
+++ b/lib/pixman/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pixman 0.32.8.
+# Generated by GNU Autoconf 2.69 for pixman 0.34.0.
#
# Report bugs to <pixman@lists.freedesktop.org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pixman'
PACKAGE_TARNAME='pixman'
-PACKAGE_VERSION='0.32.8'
-PACKAGE_STRING='pixman 0.32.8'
+PACKAGE_VERSION='0.34.0'
+PACKAGE_STRING='pixman 0.34.0'
PACKAGE_BUGREPORT='pixman@lists.freedesktop.org'
PACKAGE_URL=''
@@ -1390,7 +1390,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.32.8 to adapt to many kinds of systems.
+\`configure' configures pixman 0.34.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1460,7 +1460,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of pixman 0.32.8:";;
+ short | recursive ) echo "Configuration of pixman 0.34.0:";;
esac
cat <<\_ACEOF
@@ -1595,7 +1595,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-pixman configure 0.32.8
+pixman configure 0.34.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2193,7 +2193,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.32.8, which was
+It was created by pixman $as_me 0.34.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3017,7 +3017,7 @@ fi
# Define the identity of the package.
PACKAGE='pixman'
- VERSION='0.32.8'
+ VERSION='0.34.0'
cat >>confdefs.h <<_ACEOF
@@ -12201,13 +12201,13 @@ fi
-LT_VERSION_INFO="32:8:32"
+LT_VERSION_INFO="34:0:34"
PIXMAN_VERSION_MAJOR=0
-PIXMAN_VERSION_MINOR=32
+PIXMAN_VERSION_MINOR=34
-PIXMAN_VERSION_MICRO=8
+PIXMAN_VERSION_MICRO=0
@@ -12308,6 +12308,53 @@ rm -f core conftest.err conftest.$ac_objext \
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_yesno" >&5
$as_echo "$_yesno" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wno-unused-local-typedefs" >&5
+$as_echo_n "checking whether the compiler supports -Wno-unused-local-typedefs... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+ save_LIBS="$LIBS"
+ CFLAGS=""
+ LDFLAGS=""
+ LIBS=""
+ CFLAGS="$WERROR -Wno-unused-local-typedefs"
+ CFLAGS="$save_CFLAGS $CFLAGS"
+ LDFLAGS="$save_LDFLAGS $LDFLAGS"
+ LIBS="$save_LIBS $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ int main(int c, char **v) { (void)c; (void)v; return 0; }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ pixman_cc_stderr=`test -f conftest.err && cat conftest.err`
+ pixman_cc_flag=yes
+else
+ pixman_cc_stderr=`test -f conftest.err && cat conftest.err`
+ pixman_cc_flag=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test "x$pixman_cc_stderr" != "x"; then
+ pixman_cc_flag=no
+ fi
+
+ if test "x$pixman_cc_flag" = "xyes"; then
+ _yesno=yes
+ else
+ _yesno=no
+ fi
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+
+ if test "x$_yesno" = xyes; then
+ CFLAGS="$CFLAGS -Wno-unused-local-typedefs"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_yesno" >&5
+$as_echo "$_yesno" >&6; }
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -fno-strict-aliasing" >&5
$as_echo_n "checking whether the compiler supports -fno-strict-aliasing... " >&6; }
save_CFLAGS="$CFLAGS"
@@ -12718,15 +12765,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#error "Need GCC >= 3.4 for MMX intrinsics"
#endif
#include <mmintrin.h>
+#include <stdint.h>
+
+/* Check support for block expressions */
+#define _mm_shuffle_pi16(A, N) \
+ ({ \
+ __m64 ret; \
+ \
+ /* Some versions of clang will choke on K */ \
+ asm ("pshufw %2, %1, %0\n\t" \
+ : "=y" (ret) \
+ : "y" (A), "K" ((const int8_t)N) \
+ ); \
+ \
+ ret; \
+ })
+
int main () {
__m64 v = _mm_cvtsi32_si64 (1);
__m64 w;
- /* Some versions of clang will choke on K */
- asm ("pshufw %2, %1, %0\n\t"
- : "=y" (w)
- : "y" (v), "K" (5)
- );
+ w = _mm_shuffle_pi16(v, 5);
/* Some versions of clang will choke on this */
asm ("pmulhuw %1, %0\n\t"
@@ -12807,10 +12866,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>
+int param;
int main () {
- __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
+ __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
c = _mm_xor_si128 (a, b);
- return 0;
+ return _mm_cvtsi128_si32(c);
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
@@ -12870,10 +12930,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#include <xmmintrin.h>
#include <emmintrin.h>
#include <tmmintrin.h>
+int param;
int main () {
- __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
+ __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
c = _mm_maddubs_epi16 (a, b);
- return 0;
+ return _mm_cvtsi128_si32(c);
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
@@ -13920,6 +13981,15 @@ $as_echo "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h
fi
+ac_fn_c_check_decl "$LINENO" "FE_DIVBYZERO" "ac_cv_have_decl_FE_DIVBYZERO" "#include <fenv.h>
+"
+if test "x$ac_cv_have_decl_FE_DIVBYZERO" = xyes; then :
+
+$as_echo "#define HAVE_FEDIVBYZERO 1" >>confdefs.h
+
+fi
+
+
ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday"
if test "x$ac_cv_func_gettimeofday" = xyes; then :
have_gettimeofday=yes
@@ -15259,7 +15329,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.32.8, which was
+This file was extended by pixman $as_me 0.34.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -15325,7 +15395,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-pixman config.status 0.32.8
+pixman config.status 0.34.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/lib/pixman/configure.ac b/lib/pixman/configure.ac
index 40fcb8bb2..09991f61a 100644
--- a/lib/pixman/configure.ac
+++ b/lib/pixman/configure.ac
@@ -53,8 +53,8 @@ AC_PREREQ([2.57])
#
m4_define([pixman_major], 0)
-m4_define([pixman_minor], 32)
-m4_define([pixman_micro], 8)
+m4_define([pixman_minor], 34)
+m4_define([pixman_micro], 0)
m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro])
@@ -184,6 +184,7 @@ AC_SUBST(LT_VERSION_INFO)
PIXMAN_CHECK_CFLAG([-Wall])
PIXMAN_CHECK_CFLAG([-Wdeclaration-after-statement])
+PIXMAN_CHECK_CFLAG([-Wno-unused-local-typedefs])
PIXMAN_CHECK_CFLAG([-fno-strict-aliasing])
dnl =========================================================================
@@ -346,15 +347,27 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#error "Need GCC >= 3.4 for MMX intrinsics"
#endif
#include <mmintrin.h>
+#include <stdint.h>
+
+/* Check support for block expressions */
+#define _mm_shuffle_pi16(A, N) \
+ ({ \
+ __m64 ret; \
+ \
+ /* Some versions of clang will choke on K */ \
+ asm ("pshufw %2, %1, %0\n\t" \
+ : "=y" (ret) \
+ : "y" (A), "K" ((const int8_t)N) \
+ ); \
+ \
+ ret; \
+ })
+
int main () {
__m64 v = _mm_cvtsi32_si64 (1);
__m64 w;
- /* Some versions of clang will choke on K */
- asm ("pshufw %2, %1, %0\n\t"
- : "=y" (w)
- : "y" (v), "K" (5)
- );
+ w = _mm_shuffle_pi16(v, 5);
/* Some versions of clang will choke on this */
asm ("pmulhuw %1, %0\n\t"
@@ -416,10 +429,11 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>
+int param;
int main () {
- __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
+ __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
c = _mm_xor_si128 (a, b);
- return 0;
+ return _mm_cvtsi128_si32(c);
}]])], have_sse2_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
@@ -460,10 +474,11 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <xmmintrin.h>
#include <emmintrin.h>
#include <tmmintrin.h>
+int param;
int main () {
- __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
+ __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
c = _mm_maddubs_epi16 (a, b);
- return 0;
+ return _mm_cvtsi128_si32(c);
}]])], have_ssse3_intrinsics=yes)
CFLAGS=$xserver_save_CFLAGS
@@ -890,6 +905,11 @@ if test x$have_feenableexcept = xyes; then
AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
fi
+AC_CHECK_DECL([FE_DIVBYZERO],
+ [AC_DEFINE(HAVE_FEDIVBYZERO, 1, [Whether we have FE_DIVBYZERO])],
+ [],
+ [[#include <fenv.h>]])
+
AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
diff --git a/lib/pixman/pixman/Makefile.am b/lib/pixman/pixman/Makefile.am
index b376d9aeb..581b6f61e 100644
--- a/lib/pixman/pixman/Makefile.am
+++ b/lib/pixman/pixman/Makefile.am
@@ -72,6 +72,7 @@ libpixman_arm_simd_la_SOURCES = \
pixman-arm-common.h \
pixman-arm-simd-asm.S \
pixman-arm-simd-asm-scaled.S \
+ pixman-arm-asm.h \
pixman-arm-simd-asm.h
libpixman_1_la_LIBADD += libpixman-arm-simd.la
@@ -86,6 +87,7 @@ libpixman_arm_neon_la_SOURCES = \
pixman-arm-common.h \
pixman-arm-neon-asm.S \
pixman-arm-neon-asm-bilinear.S \
+ pixman-arm-asm.h \
pixman-arm-neon-asm.h
libpixman_1_la_LIBADD += libpixman-arm-neon.la
diff --git a/lib/pixman/pixman/Makefile.in b/lib/pixman/pixman/Makefile.in
index 26c5fbe4f..db2fb9882 100644
--- a/lib/pixman/pixman/Makefile.in
+++ b/lib/pixman/pixman/Makefile.in
@@ -160,7 +160,8 @@ libpixman_1_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
libpixman_arm_neon_la_LIBADD =
am__libpixman_arm_neon_la_SOURCES_DIST = pixman-arm-neon.c \
pixman-arm-common.h pixman-arm-neon-asm.S \
- pixman-arm-neon-asm-bilinear.S pixman-arm-neon-asm.h
+ pixman-arm-neon-asm-bilinear.S pixman-arm-asm.h \
+ pixman-arm-neon-asm.h
@USE_ARM_NEON_TRUE@am_libpixman_arm_neon_la_OBJECTS = \
@USE_ARM_NEON_TRUE@ pixman-arm-neon.lo pixman-arm-neon-asm.lo \
@USE_ARM_NEON_TRUE@ pixman-arm-neon-asm-bilinear.lo
@@ -169,7 +170,8 @@ libpixman_arm_neon_la_OBJECTS = $(am_libpixman_arm_neon_la_OBJECTS)
libpixman_arm_simd_la_LIBADD =
am__libpixman_arm_simd_la_SOURCES_DIST = pixman-arm-simd.c \
pixman-arm-common.h pixman-arm-simd-asm.S \
- pixman-arm-simd-asm-scaled.S pixman-arm-simd-asm.h
+ pixman-arm-simd-asm-scaled.S pixman-arm-asm.h \
+ pixman-arm-simd-asm.h
@USE_ARM_SIMD_TRUE@am_libpixman_arm_simd_la_OBJECTS = \
@USE_ARM_SIMD_TRUE@ pixman-arm-simd.lo pixman-arm-simd-asm.lo \
@USE_ARM_SIMD_TRUE@ pixman-arm-simd-asm-scaled.lo
@@ -547,6 +549,7 @@ EXTRA_DIST = \
@USE_ARM_SIMD_TRUE@ pixman-arm-common.h \
@USE_ARM_SIMD_TRUE@ pixman-arm-simd-asm.S \
@USE_ARM_SIMD_TRUE@ pixman-arm-simd-asm-scaled.S \
+@USE_ARM_SIMD_TRUE@ pixman-arm-asm.h \
@USE_ARM_SIMD_TRUE@ pixman-arm-simd-asm.h
@USE_ARM_SIMD_TRUE@ASM_CFLAGS_arm_simd =
@@ -555,6 +558,7 @@ EXTRA_DIST = \
@USE_ARM_NEON_TRUE@ pixman-arm-common.h \
@USE_ARM_NEON_TRUE@ pixman-arm-neon-asm.S \
@USE_ARM_NEON_TRUE@ pixman-arm-neon-asm-bilinear.S \
+@USE_ARM_NEON_TRUE@ pixman-arm-asm.h \
@USE_ARM_NEON_TRUE@ pixman-arm-neon-asm.h
@USE_ARM_NEON_TRUE@ASM_CFLAGS_arm_neon =
diff --git a/lib/pixman/pixman/pixman-arm-asm.h b/lib/pixman/pixman/pixman-arm-asm.h
new file mode 100644
index 000000000..ee7854108
--- /dev/null
+++ b/lib/pixman/pixman/pixman-arm-asm.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2008 Mozilla Corporation
+ * Copyright © 2010 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 Mozilla Corporation not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Mozilla Corporation makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ *
+ * Author: Jeff Muizelaar (jeff@infidigm.net)
+ *
+ */
+
+/* Supplementary macro for setting function attributes */
+.macro pixman_asm_function fname
+ .func fname
+ .global fname
+#ifdef __ELF__
+ .hidden fname
+ .type fname, %function
+#endif
+fname:
+.endm
diff --git a/lib/pixman/pixman/pixman-arm-common.h b/lib/pixman/pixman/pixman-arm-common.h
index 3a7cb2bef..953768830 100644
--- a/lib/pixman/pixman/pixman-arm-common.h
+++ b/lib/pixman/pixman/pixman-arm-common.h
@@ -266,13 +266,6 @@ FAST_NEAREST_MAINLOOP (cputype##_##name##_normal_##op, \
scaled_nearest_scanline_##cputype##_##name##_##op, \
src_type, dst_type, NORMAL)
-/* Provide entries for the fast path table */
-#define PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
- SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
- SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
- SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func), \
- SIMPLE_NEAREST_FAST_PATH_NORMAL (op,s,d,func)
-
#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST(flags, cputype, name, op, \
src_type, dst_type) \
void \
@@ -318,9 +311,7 @@ FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
/* Provide entries for the fast path table */
#define PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func), \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func), \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func), \
+ SIMPLE_NEAREST_A8_MASK_FAST_PATH (op,s,d,func), \
SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL (op,s,d,func)
/*****************************************************************************/
diff --git a/lib/pixman/pixman/pixman-arm-neon-asm-bilinear.S b/lib/pixman/pixman/pixman-arm-neon-asm-bilinear.S
index e37b5c298..0fd92d61c 100644
--- a/lib/pixman/pixman/pixman-arm-neon-asm-bilinear.S
+++ b/lib/pixman/pixman/pixman-arm-neon-asm-bilinear.S
@@ -65,23 +65,13 @@
.p2align 2
#include "pixman-private.h"
+#include "pixman-arm-asm.h"
#include "pixman-arm-neon-asm.h"
/*
* Bilinear macros from pixman-arm-neon-asm.S
*/
-/* Supplementary macro for setting function attributes */
-.macro pixman_asm_function fname
- .func fname
- .global fname
-#ifdef __ELF__
- .hidden fname
- .type fname, %function
-#endif
-fname:
-.endm
-
/*
* Bilinear scaling support code which tries to provide pixel fetching, color
* format conversion, and interpolation as separate macros which can be used
diff --git a/lib/pixman/pixman/pixman-arm-neon-asm.S b/lib/pixman/pixman/pixman-arm-neon-asm.S
index 187197dc3..7e949a38f 100644
--- a/lib/pixman/pixman/pixman-arm-neon-asm.S
+++ b/lib/pixman/pixman/pixman-arm-neon-asm.S
@@ -50,6 +50,7 @@
.p2align 2
#include "pixman-private.h"
+#include "pixman-arm-asm.h"
#include "pixman-arm-neon-asm.h"
/* Global configuration options and preferences */
@@ -2830,17 +2831,6 @@ generate_composite_function_nearest_scanline \
/******************************************************************************/
-/* Supplementary macro for setting function attributes */
-.macro pixman_asm_function fname
- .func fname
- .global fname
-#ifdef __ELF__
- .hidden fname
- .type fname, %function
-#endif
-fname:
-.endm
-
/*
* Bilinear scaling support code which tries to provide pixel fetching, color
* format conversion, and interpolation as separate macros which can be used
diff --git a/lib/pixman/pixman/pixman-arm-neon-asm.h b/lib/pixman/pixman/pixman-arm-neon-asm.h
index d0d92d74c..bdcf6a9d4 100644
--- a/lib/pixman/pixman/pixman-arm-neon-asm.h
+++ b/lib/pixman/pixman/pixman-arm-neon-asm.h
@@ -631,14 +631,8 @@ local skip1
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:
+ pixman_asm_function fname
+
push {r4-r12, lr} /* save all registers */
/*
@@ -945,14 +939,8 @@ fname:
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:
+ pixman_asm_function fname
+
.set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE
/*
* Make some macro arguments globally visible and accessible
diff --git a/lib/pixman/pixman/pixman-arm-neon.c b/lib/pixman/pixman/pixman-arm-neon.c
index 60e9c78d2..be761c965 100644
--- a/lib/pixman/pixman/pixman-arm-neon.c
+++ b/lib/pixman/pixman/pixman-arm-neon.c
@@ -362,21 +362,21 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565),
+ SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888),
/* Note: NONE repeat is not supported yet */
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
diff --git a/lib/pixman/pixman/pixman-arm-simd-asm-scaled.S b/lib/pixman/pixman/pixman-arm-simd-asm-scaled.S
index 711099548..e050292e0 100644
--- a/lib/pixman/pixman/pixman-arm-simd-asm-scaled.S
+++ b/lib/pixman/pixman/pixman-arm-simd-asm-scaled.S
@@ -37,16 +37,7 @@
.altmacro
.p2align 2
-/* Supplementary macro for setting function attributes */
-.macro pixman_asm_function fname
- .func fname
- .global fname
-#ifdef __ELF__
- .hidden fname
- .type fname, %function
-#endif
-fname:
-.endm
+#include "pixman-arm-asm.h"
/*
* Note: This code is only using armv5te instructions (not even armv6),
diff --git a/lib/pixman/pixman/pixman-arm-simd-asm.S b/lib/pixman/pixman/pixman-arm-simd-asm.S
index c20968879..a74a0a8f3 100644
--- a/lib/pixman/pixman/pixman-arm-simd-asm.S
+++ b/lib/pixman/pixman/pixman-arm-simd-asm.S
@@ -37,6 +37,7 @@
.altmacro
.p2align 2
+#include "pixman-arm-asm.h"
#include "pixman-arm-simd-asm.h"
/* A head macro should do all processing which results in an output of up to
@@ -303,6 +304,83 @@ generate_composite_function \
/******************************************************************************/
+.macro src_x888_0565_init
+ /* Hold loop invariant in MASK */
+ ldr MASK, =0x001F001F
+ line_saved_regs STRIDE_S, ORIG_W
+.endm
+
+.macro src_x888_0565_1pixel s, d
+ and WK&d, MASK, WK&s, lsr #3 @ 00000000000rrrrr00000000000bbbbb
+ and STRIDE_S, WK&s, #0xFC00 @ 0000000000000000gggggg0000000000
+ orr WK&d, WK&d, WK&d, lsr #5 @ 00000000000-----rrrrr000000bbbbb
+ orr WK&d, WK&d, STRIDE_S, lsr #5 @ 00000000000-----rrrrrggggggbbbbb
+ /* Top 16 bits are discarded during the following STRH */
+.endm
+
+.macro src_x888_0565_2pixels slo, shi, d, tmp
+ and SCRATCH, WK&shi, #0xFC00 @ 0000000000000000GGGGGG0000000000
+ and WK&tmp, MASK, WK&shi, lsr #3 @ 00000000000RRRRR00000000000BBBBB
+ and WK&shi, MASK, WK&slo, lsr #3 @ 00000000000rrrrr00000000000bbbbb
+ orr WK&tmp, WK&tmp, WK&tmp, lsr #5 @ 00000000000-----RRRRR000000BBBBB
+ orr WK&tmp, WK&tmp, SCRATCH, lsr #5 @ 00000000000-----RRRRRGGGGGGBBBBB
+ and SCRATCH, WK&slo, #0xFC00 @ 0000000000000000gggggg0000000000
+ orr WK&shi, WK&shi, WK&shi, lsr #5 @ 00000000000-----rrrrr000000bbbbb
+ orr WK&shi, WK&shi, SCRATCH, lsr #5 @ 00000000000-----rrrrrggggggbbbbb
+ pkhbt WK&d, WK&shi, WK&tmp, lsl #16 @ RRRRRGGGGGGBBBBBrrrrrggggggbbbbb
+.endm
+
+.macro src_x888_0565_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ WK4 .req STRIDE_S
+ WK5 .req STRIDE_M
+ WK6 .req WK3
+ WK7 .req ORIG_W
+ .if numbytes == 16
+ pixld , 16, 4, SRC, 0
+ src_x888_0565_2pixels 4, 5, 0, 0
+ pixld , 8, 4, SRC, 0
+ src_x888_0565_2pixels 6, 7, 1, 1
+ pixld , 8, 6, SRC, 0
+ .else
+ pixld , numbytes*2, 4, SRC, 0
+ .endif
+.endm
+
+.macro src_x888_0565_process_tail cond, numbytes, firstreg
+ .if numbytes == 16
+ src_x888_0565_2pixels 4, 5, 2, 2
+ src_x888_0565_2pixels 6, 7, 3, 4
+ .elseif numbytes == 8
+ src_x888_0565_2pixels 4, 5, 1, 1
+ src_x888_0565_2pixels 6, 7, 2, 2
+ .elseif numbytes == 4
+ src_x888_0565_2pixels 4, 5, 1, 1
+ .else
+ src_x888_0565_1pixel 4, 1
+ .endif
+ .if numbytes == 16
+ pixst , numbytes, 0, DST
+ .else
+ pixst , numbytes, 1, DST
+ .endif
+ .unreq WK4
+ .unreq WK5
+ .unreq WK6
+ .unreq WK7
+.endm
+
+generate_composite_function \
+ pixman_composite_src_x888_0565_asm_armv6, 32, 0, 16, \
+ FLAG_DST_WRITEONLY | FLAG_BRANCH_OVER | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH, \
+ 3, /* prefetch distance */ \
+ src_x888_0565_init, \
+ nop_macro, /* newline */ \
+ nop_macro, /* cleanup */ \
+ src_x888_0565_process_head, \
+ src_x888_0565_process_tail
+
+/******************************************************************************/
+
.macro add_8_8_8pixels cond, dst1, dst2
uqadd8&cond WK&dst1, WK&dst1, MASK
uqadd8&cond WK&dst2, WK&dst2, STRIDE_M
@@ -611,3 +689,491 @@ generate_composite_function \
/******************************************************************************/
+.macro over_reverse_n_8888_init
+ ldr SRC, [sp, #ARGS_STACK_OFFSET]
+ ldr MASK, =0x00800080
+ /* Split source pixel into RB/AG parts */
+ uxtb16 STRIDE_S, SRC
+ uxtb16 STRIDE_M, SRC, ror #8
+ /* Set GE[3:0] to 0101 so SEL instructions do what we want */
+ uadd8 SCRATCH, MASK, MASK
+ line_saved_regs STRIDE_D, ORIG_W
+.endm
+
+.macro over_reverse_n_8888_newline
+ mov STRIDE_D, #0xFF
+.endm
+
+.macro over_reverse_n_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ pixld , numbytes, firstreg, DST, 0
+.endm
+
+.macro over_reverse_n_8888_1pixel d, is_only
+ teq WK&d, #0
+ beq 8f /* replace with source */
+ bics ORIG_W, STRIDE_D, WK&d, lsr #24
+ .if is_only == 1
+ beq 49f /* skip store */
+ .else
+ beq 9f /* write same value back */
+ .endif
+ mla SCRATCH, STRIDE_S, ORIG_W, MASK /* red/blue */
+ mla ORIG_W, STRIDE_M, ORIG_W, MASK /* alpha/green */
+ uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8
+ uxtab16 ORIG_W, ORIG_W, ORIG_W, ror #8
+ mov SCRATCH, SCRATCH, ror #8
+ sel ORIG_W, SCRATCH, ORIG_W
+ uqadd8 WK&d, WK&d, ORIG_W
+ b 9f
+8: mov WK&d, SRC
+9:
+.endm
+
+.macro over_reverse_n_8888_tail numbytes, reg1, reg2, reg3, reg4
+ .if numbytes == 4
+ over_reverse_n_8888_1pixel reg1, 1
+ .else
+ and SCRATCH, WK&reg1, WK&reg2
+ .if numbytes == 16
+ and SCRATCH, SCRATCH, WK&reg3
+ and SCRATCH, SCRATCH, WK&reg4
+ .endif
+ mvns SCRATCH, SCRATCH, asr #24
+ beq 49f /* skip store if all opaque */
+ over_reverse_n_8888_1pixel reg1, 0
+ over_reverse_n_8888_1pixel reg2, 0
+ .if numbytes == 16
+ over_reverse_n_8888_1pixel reg3, 0
+ over_reverse_n_8888_1pixel reg4, 0
+ .endif
+ .endif
+ pixst , numbytes, reg1, DST
+49:
+.endm
+
+.macro over_reverse_n_8888_process_tail cond, numbytes, firstreg
+ over_reverse_n_8888_tail numbytes, firstreg, %(firstreg+1), %(firstreg+2), %(firstreg+3)
+.endm
+
+generate_composite_function \
+ pixman_composite_over_reverse_n_8888_asm_armv6, 0, 0, 32 \
+ FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH, \
+ 3, /* prefetch distance */ \
+ over_reverse_n_8888_init, \
+ over_reverse_n_8888_newline, \
+ nop_macro, /* cleanup */ \
+ over_reverse_n_8888_process_head, \
+ over_reverse_n_8888_process_tail
+
+/******************************************************************************/
+
+.macro over_white_8888_8888_ca_init
+ HALF .req SRC
+ TMP0 .req STRIDE_D
+ TMP1 .req STRIDE_S
+ TMP2 .req STRIDE_M
+ TMP3 .req ORIG_W
+ WK4 .req SCRATCH
+ line_saved_regs STRIDE_D, STRIDE_M, ORIG_W
+ ldr SCRATCH, =0x800080
+ mov HALF, #0x80
+ /* Set GE[3:0] to 0101 so SEL instructions do what we want */
+ uadd8 SCRATCH, SCRATCH, SCRATCH
+ .set DST_PRELOAD_BIAS, 8
+.endm
+
+.macro over_white_8888_8888_ca_cleanup
+ .set DST_PRELOAD_BIAS, 0
+ .unreq HALF
+ .unreq TMP0
+ .unreq TMP1
+ .unreq TMP2
+ .unreq TMP3
+ .unreq WK4
+.endm
+
+.macro over_white_8888_8888_ca_combine m, d
+ uxtb16 TMP1, TMP0 /* rb_notmask */
+ uxtb16 TMP2, d /* rb_dest; 1 stall follows */
+ smlatt TMP3, TMP2, TMP1, HALF /* red */
+ smlabb TMP2, TMP2, TMP1, HALF /* blue */
+ uxtb16 TMP0, TMP0, ror #8 /* ag_notmask */
+ uxtb16 TMP1, d, ror #8 /* ag_dest; 1 stall follows */
+ smlatt d, TMP1, TMP0, HALF /* alpha */
+ smlabb TMP1, TMP1, TMP0, HALF /* green */
+ pkhbt TMP0, TMP2, TMP3, lsl #16 /* rb; 1 stall follows */
+ pkhbt TMP1, TMP1, d, lsl #16 /* ag */
+ uxtab16 TMP0, TMP0, TMP0, ror #8
+ uxtab16 TMP1, TMP1, TMP1, ror #8
+ mov TMP0, TMP0, ror #8
+ sel d, TMP0, TMP1
+ uqadd8 d, d, m /* d is a late result */
+.endm
+
+.macro over_white_8888_8888_ca_1pixel_head
+ pixld , 4, 1, MASK, 0
+ pixld , 4, 3, DST, 0
+.endm
+
+.macro over_white_8888_8888_ca_1pixel_tail
+ mvn TMP0, WK1
+ teq WK1, WK1, asr #32
+ bne 01f
+ bcc 03f
+ mov WK3, WK1
+ b 02f
+01: over_white_8888_8888_ca_combine WK1, WK3
+02: pixst , 4, 3, DST
+03:
+.endm
+
+.macro over_white_8888_8888_ca_2pixels_head
+ pixld , 8, 1, MASK, 0
+.endm
+
+.macro over_white_8888_8888_ca_2pixels_tail
+ pixld , 8, 3, DST
+ mvn TMP0, WK1
+ teq WK1, WK1, asr #32
+ bne 01f
+ movcs WK3, WK1
+ bcs 02f
+ teq WK2, #0
+ beq 05f
+ b 02f
+01: over_white_8888_8888_ca_combine WK1, WK3
+02: mvn TMP0, WK2
+ teq WK2, WK2, asr #32
+ bne 03f
+ movcs WK4, WK2
+ b 04f
+03: over_white_8888_8888_ca_combine WK2, WK4
+04: pixst , 8, 3, DST
+05:
+.endm
+
+.macro over_white_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ .if numbytes == 4
+ over_white_8888_8888_ca_1pixel_head
+ .else
+ .if numbytes == 16
+ over_white_8888_8888_ca_2pixels_head
+ over_white_8888_8888_ca_2pixels_tail
+ .endif
+ over_white_8888_8888_ca_2pixels_head
+ .endif
+.endm
+
+.macro over_white_8888_8888_ca_process_tail cond, numbytes, firstreg
+ .if numbytes == 4
+ over_white_8888_8888_ca_1pixel_tail
+ .else
+ over_white_8888_8888_ca_2pixels_tail
+ .endif
+.endm
+
+generate_composite_function \
+ pixman_composite_over_white_8888_8888_ca_asm_armv6, 0, 32, 32 \
+ FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH \
+ 2, /* prefetch distance */ \
+ over_white_8888_8888_ca_init, \
+ nop_macro, /* newline */ \
+ over_white_8888_8888_ca_cleanup, \
+ over_white_8888_8888_ca_process_head, \
+ over_white_8888_8888_ca_process_tail
+
+
+.macro over_n_8888_8888_ca_init
+ /* Set up constants. RB_SRC and AG_SRC are in registers;
+ * RB_FLDS, A_SRC, and the two HALF values need to go on the
+ * stack (and the ful SRC value is already there) */
+ ldr SCRATCH, [sp, #ARGS_STACK_OFFSET]
+ mov WK0, #0x00FF0000
+ orr WK0, WK0, #0xFF /* RB_FLDS (0x00FF00FF) */
+ mov WK1, #0x80 /* HALF default value */
+ mov WK2, SCRATCH, lsr #24 /* A_SRC */
+ orr WK3, WK1, WK1, lsl #16 /* HALF alternate value (0x00800080) */
+ push {WK0-WK3}
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+16
+ uxtb16 SRC, SCRATCH
+ uxtb16 STRIDE_S, SCRATCH, ror #8
+
+ /* Set GE[3:0] to 0101 so SEL instructions do what we want */
+ uadd8 SCRATCH, WK3, WK3
+
+ .unreq WK0
+ .unreq WK1
+ .unreq WK2
+ .unreq WK3
+ WK0 .req Y
+ WK1 .req STRIDE_D
+ RB_SRC .req SRC
+ AG_SRC .req STRIDE_S
+ WK2 .req STRIDE_M
+ RB_FLDS .req r8 /* the reloaded constants have to be at consecutive registers starting at an even one */
+ A_SRC .req r8
+ HALF .req r9
+ WK3 .req r10
+ WK4 .req r11
+ WK5 .req SCRATCH
+ WK6 .req ORIG_W
+
+ line_saved_regs Y, STRIDE_D, STRIDE_M, ORIG_W
+.endm
+
+.macro over_n_8888_8888_ca_cleanup
+ add sp, sp, #16
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-16
+
+ .unreq WK0
+ .unreq WK1
+ .unreq RB_SRC
+ .unreq AG_SRC
+ .unreq WK2
+ .unreq RB_FLDS
+ .unreq A_SRC
+ .unreq HALF
+ .unreq WK3
+ .unreq WK4
+ .unreq WK5
+ .unreq WK6
+ WK0 .req r8
+ WK1 .req r9
+ WK2 .req r10
+ WK3 .req r11
+.endm
+
+.macro over_n_8888_8888_ca_1pixel_head
+ pixld , 4, 6, MASK, 0
+ pixld , 4, 0, DST, 0
+.endm
+
+.macro over_n_8888_8888_ca_1pixel_tail
+ ldrd A_SRC, HALF, [sp, #LOCALS_STACK_OFFSET+8]
+ uxtb16 WK1, WK6 /* rb_mask (first step of hard case placed in what would otherwise be a stall) */
+ teq WK6, WK6, asr #32 /* Zc if transparent, ZC if opaque */
+ bne 20f
+ bcc 40f
+ /* Mask is fully opaque (all channels) */
+ ldr WK6, [sp, #ARGS_STACK_OFFSET] /* get SRC back */
+ eors A_SRC, A_SRC, #0xFF
+ bne 10f
+ /* Source is also opaque - same as src_8888_8888 */
+ mov WK0, WK6
+ b 30f
+10: /* Same as over_8888_8888 */
+ mul_8888_8 WK0, A_SRC, WK5, HALF
+ uqadd8 WK0, WK0, WK6
+ b 30f
+20: /* No simplifications possible - do it the hard way */
+ uxtb16 WK2, WK6, ror #8 /* ag_mask */
+ mla WK3, WK1, A_SRC, HALF /* rb_mul; 2 cycles */
+ mla WK4, WK2, A_SRC, HALF /* ag_mul; 2 cycles */
+ ldrd RB_FLDS, HALF, [sp, #LOCALS_STACK_OFFSET]
+ uxtb16 WK5, WK0 /* rb_dest */
+ uxtab16 WK3, WK3, WK3, ror #8
+ uxtb16 WK6, WK0, ror #8 /* ag_dest */
+ uxtab16 WK4, WK4, WK4, ror #8
+ smlatt WK0, RB_SRC, WK1, HALF /* red1 */
+ smlabb WK1, RB_SRC, WK1, HALF /* blue1 */
+ bic WK3, RB_FLDS, WK3, lsr #8
+ bic WK4, RB_FLDS, WK4, lsr #8
+ pkhbt WK1, WK1, WK0, lsl #16 /* rb1 */
+ smlatt WK0, WK5, WK3, HALF /* red2 */
+ smlabb WK3, WK5, WK3, HALF /* blue2 */
+ uxtab16 WK1, WK1, WK1, ror #8
+ smlatt WK5, AG_SRC, WK2, HALF /* alpha1 */
+ pkhbt WK3, WK3, WK0, lsl #16 /* rb2 */
+ smlabb WK0, AG_SRC, WK2, HALF /* green1 */
+ smlatt WK2, WK6, WK4, HALF /* alpha2 */
+ smlabb WK4, WK6, WK4, HALF /* green2 */
+ pkhbt WK0, WK0, WK5, lsl #16 /* ag1 */
+ uxtab16 WK3, WK3, WK3, ror #8
+ pkhbt WK4, WK4, WK2, lsl #16 /* ag2 */
+ uxtab16 WK0, WK0, WK0, ror #8
+ uxtab16 WK4, WK4, WK4, ror #8
+ mov WK1, WK1, ror #8
+ mov WK3, WK3, ror #8
+ sel WK2, WK1, WK0 /* recombine source*mask */
+ sel WK1, WK3, WK4 /* recombine dest*(1-source_alpha*mask) */
+ uqadd8 WK0, WK1, WK2 /* followed by 1 stall */
+30: /* The destination buffer is already in the L1 cache, so
+ * there's little point in amalgamating writes */
+ pixst , 4, 0, DST
+40:
+.endm
+
+.macro over_n_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ .rept (numbytes / 4) - 1
+ over_n_8888_8888_ca_1pixel_head
+ over_n_8888_8888_ca_1pixel_tail
+ .endr
+ over_n_8888_8888_ca_1pixel_head
+.endm
+
+.macro over_n_8888_8888_ca_process_tail cond, numbytes, firstreg
+ over_n_8888_8888_ca_1pixel_tail
+.endm
+
+pixman_asm_function pixman_composite_over_n_8888_8888_ca_asm_armv6
+ ldr ip, [sp]
+ cmp ip, #-1
+ beq pixman_composite_over_white_8888_8888_ca_asm_armv6
+ /* else drop through... */
+ .endfunc
+generate_composite_function \
+ pixman_composite_over_n_8888_8888_ca_asm_armv6_helper, 0, 32, 32 \
+ FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH | FLAG_PROCESS_CORRUPTS_WK0 \
+ 2, /* prefetch distance */ \
+ over_n_8888_8888_ca_init, \
+ nop_macro, /* newline */ \
+ over_n_8888_8888_ca_cleanup, \
+ over_n_8888_8888_ca_process_head, \
+ over_n_8888_8888_ca_process_tail
+
+/******************************************************************************/
+
+.macro in_reverse_8888_8888_init
+ /* Hold loop invariant in MASK */
+ ldr MASK, =0x00800080
+ /* Set GE[3:0] to 0101 so SEL instructions do what we want */
+ uadd8 SCRATCH, MASK, MASK
+ /* Offset the source pointer: we only need the alpha bytes */
+ add SRC, SRC, #3
+ line_saved_regs ORIG_W
+.endm
+
+.macro in_reverse_8888_8888_head numbytes, reg1, reg2, reg3
+ ldrb ORIG_W, [SRC], #4
+ .if numbytes >= 8
+ ldrb WK&reg1, [SRC], #4
+ .if numbytes == 16
+ ldrb WK&reg2, [SRC], #4
+ ldrb WK&reg3, [SRC], #4
+ .endif
+ .endif
+ add DST, DST, #numbytes
+.endm
+
+.macro in_reverse_8888_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ in_reverse_8888_8888_head numbytes, firstreg, %(firstreg+1), %(firstreg+2)
+.endm
+
+.macro in_reverse_8888_8888_1pixel s, d, offset, is_only
+ .if is_only != 1
+ movs s, ORIG_W
+ .if offset != 0
+ ldrb ORIG_W, [SRC, #offset]
+ .endif
+ beq 01f
+ teq STRIDE_M, #0xFF
+ beq 02f
+ .endif
+ uxtb16 SCRATCH, d /* rb_dest */
+ uxtb16 d, d, ror #8 /* ag_dest */
+ mla SCRATCH, SCRATCH, s, MASK
+ mla d, d, s, MASK
+ uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8
+ uxtab16 d, d, d, ror #8
+ mov SCRATCH, SCRATCH, ror #8
+ sel d, SCRATCH, d
+ b 02f
+ .if offset == 0
+48: /* Last mov d,#0 of the set - used as part of shortcut for
+ * source values all 0 */
+ .endif
+01: mov d, #0
+02:
+.endm
+
+.macro in_reverse_8888_8888_tail numbytes, reg1, reg2, reg3, reg4
+ .if numbytes == 4
+ teq ORIG_W, ORIG_W, asr #32
+ ldrne WK&reg1, [DST, #-4]
+ .elseif numbytes == 8
+ teq ORIG_W, WK&reg1
+ teqeq ORIG_W, ORIG_W, asr #32 /* all 0 or all -1? */
+ ldmnedb DST, {WK&reg1-WK&reg2}
+ .else
+ teq ORIG_W, WK&reg1
+ teqeq ORIG_W, WK&reg2
+ teqeq ORIG_W, WK&reg3
+ teqeq ORIG_W, ORIG_W, asr #32 /* all 0 or all -1? */
+ ldmnedb DST, {WK&reg1-WK&reg4}
+ .endif
+ cmnne DST, #0 /* clear C if NE */
+ bcs 49f /* no writes to dest if source all -1 */
+ beq 48f /* set dest to all 0 if source all 0 */
+ .if numbytes == 4
+ in_reverse_8888_8888_1pixel ORIG_W, WK&reg1, 0, 1
+ str WK&reg1, [DST, #-4]
+ .elseif numbytes == 8
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg1, -4, 0
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg2, 0, 0
+ stmdb DST, {WK&reg1-WK&reg2}
+ .else
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg1, -12, 0
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg2, -8, 0
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg3, -4, 0
+ in_reverse_8888_8888_1pixel STRIDE_M, WK&reg4, 0, 0
+ stmdb DST, {WK&reg1-WK&reg4}
+ .endif
+49:
+.endm
+
+.macro in_reverse_8888_8888_process_tail cond, numbytes, firstreg
+ in_reverse_8888_8888_tail numbytes, firstreg, %(firstreg+1), %(firstreg+2), %(firstreg+3)
+.endm
+
+generate_composite_function \
+ pixman_composite_in_reverse_8888_8888_asm_armv6, 32, 0, 32 \
+ FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH | FLAG_NO_PRELOAD_DST \
+ 2, /* prefetch distance */ \
+ in_reverse_8888_8888_init, \
+ nop_macro, /* newline */ \
+ nop_macro, /* cleanup */ \
+ in_reverse_8888_8888_process_head, \
+ in_reverse_8888_8888_process_tail
+
+/******************************************************************************/
+
+.macro over_n_8888_init
+ ldr SRC, [sp, #ARGS_STACK_OFFSET]
+ /* Hold loop invariant in MASK */
+ ldr MASK, =0x00800080
+ /* Hold multiplier for destination in STRIDE_M */
+ mov STRIDE_M, #255
+ sub STRIDE_M, STRIDE_M, SRC, lsr #24
+ /* Set GE[3:0] to 0101 so SEL instructions do what we want */
+ uadd8 SCRATCH, MASK, MASK
+.endm
+
+.macro over_n_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
+ pixld , numbytes, firstreg, DST, 0
+.endm
+
+.macro over_n_8888_1pixel dst
+ mul_8888_8 WK&dst, STRIDE_M, SCRATCH, MASK
+ uqadd8 WK&dst, WK&dst, SRC
+.endm
+
+.macro over_n_8888_process_tail cond, numbytes, firstreg
+ .set PROCESS_REG, firstreg
+ .rept numbytes / 4
+ over_n_8888_1pixel %(PROCESS_REG)
+ .set PROCESS_REG, PROCESS_REG+1
+ .endr
+ pixst , numbytes, firstreg, DST
+.endm
+
+generate_composite_function \
+ pixman_composite_over_n_8888_asm_armv6, 0, 0, 32 \
+ FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_DOES_STORE \
+ 2, /* prefetch distance */ \
+ over_n_8888_init, \
+ nop_macro, /* newline */ \
+ nop_macro, /* cleanup */ \
+ over_n_8888_process_head, \
+ over_n_8888_process_tail
+
+/******************************************************************************/
diff --git a/lib/pixman/pixman/pixman-arm-simd-asm.h b/lib/pixman/pixman/pixman-arm-simd-asm.h
index 65436062b..da153c3f5 100644
--- a/lib/pixman/pixman/pixman-arm-simd-asm.h
+++ b/lib/pixman/pixman/pixman-arm-simd-asm.h
@@ -76,6 +76,16 @@
.set FLAG_SPILL_LINE_VARS, 48
.set FLAG_PROCESS_CORRUPTS_SCRATCH, 0
.set FLAG_PROCESS_PRESERVES_SCRATCH, 64
+.set FLAG_PROCESS_PRESERVES_WK0, 0
+.set FLAG_PROCESS_CORRUPTS_WK0, 128 /* if possible, use the specified register(s) instead so WK0 can hold number of leading pixels */
+.set FLAG_PRELOAD_DST, 0
+.set FLAG_NO_PRELOAD_DST, 256
+
+/*
+ * Number of bytes by which to adjust preload offset of destination
+ * buffer (allows preload instruction to be moved before the load(s))
+ */
+.set DST_PRELOAD_BIAS, 0
/*
* Offset into stack where mask and source pointer/stride can be accessed.
@@ -87,6 +97,11 @@
#endif
/*
+ * Offset into stack where space allocated during init macro can be accessed.
+ */
+.set LOCALS_STACK_OFFSET, 0
+
+/*
* Constants for selecting preferable prefetch type.
*/
.set PREFETCH_TYPE_NONE, 0
@@ -196,8 +211,8 @@
PF add, SCRATCH, base, WK0, lsl #bpp_shift-dst_bpp_shift
PF and, SCRATCH, SCRATCH, #31
PF rsb, SCRATCH, SCRATCH, WK0, lsl #bpp_shift-dst_bpp_shift
- PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
- PF movs, SCRATCH, SCRATCH, #32-6 /* so this sets NC / nc / Nc */
+ PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
+ PF movs, SCRATCH, SCRATCH, lsl #32-6 /* so this sets NC / nc / Nc */
PF bcs, 61f
PF bpl, 60f
PF pld, [ptr, #32*(prefetch_distance+2)]
@@ -359,23 +374,41 @@
.macro test_bits_1_0_ptr
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ movs SCRATCH, X, lsl #32-1 /* C,N = bits 1,0 of DST */
+ .else
movs SCRATCH, WK0, lsl #32-1 /* C,N = bits 1,0 of DST */
+ .endif
.endm
.macro test_bits_3_2_ptr
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ movs SCRATCH, X, lsl #32-3 /* C,N = bits 3, 2 of DST */
+ .else
movs SCRATCH, WK0, lsl #32-3 /* C,N = bits 3, 2 of DST */
+ .endif
.endm
.macro leading_15bytes process_head, process_tail
/* On entry, WK0 bits 0-3 = number of bytes until destination is 16-byte aligned */
+ .set DECREMENT_X, 1
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ .set DECREMENT_X, 0
+ sub X, X, WK0, lsr #dst_bpp_shift
+ str X, [sp, #LINE_SAVED_REG_COUNT*4]
+ mov X, WK0
+ .endif
/* Use unaligned loads in all cases for simplicity */
.if dst_w_bpp == 8
- conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, 1
+ conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X
.elseif dst_w_bpp == 16
test_bits_1_0_ptr
- conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, 1
+ conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X
+ .endif
+ conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ ldr X, [sp, #LINE_SAVED_REG_COUNT*4]
.endif
- conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, 1
.endm
.macro test_bits_3_2_pix
@@ -414,7 +447,7 @@
preload_middle src_bpp, SRC, 0
preload_middle mask_bpp, MASK, 0
.endif
- .if (dst_r_bpp > 0) && ((SUBBLOCK % 2) == 0)
+ .if (dst_r_bpp > 0) && ((SUBBLOCK % 2) == 0) && (((flags) & FLAG_NO_PRELOAD_DST) == 0)
/* Because we know that writes are 16-byte aligned, it's relatively easy to ensure that
* destination prefetches are 32-byte aligned. It's also the easiest channel to offset
* preloads for, to achieve staggered prefetches for multiple channels, because there are
@@ -437,11 +470,11 @@
.if dst_r_bpp > 0
tst DST, #16
bne 111f
- process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 16
+ process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 16 + DST_PRELOAD_BIAS
b 112f
111:
.endif
- process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 0
+ process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 0 + DST_PRELOAD_BIAS
112:
/* Just before the final (prefetch_distance+1) 32-byte blocks, deal with final preloads */
.if (src_bpp*pix_per_block > 256) || (mask_bpp*pix_per_block > 256) || (dst_r_bpp*pix_per_block > 256)
@@ -449,7 +482,9 @@
.endif
preload_trailing src_bpp, src_bpp_shift, SRC
preload_trailing mask_bpp, mask_bpp_shift, MASK
+ .if ((flags) & FLAG_NO_PRELOAD_DST) == 0
preload_trailing dst_r_bpp, dst_bpp_shift, DST
+ .endif
add X, X, #(prefetch_distance+2)*pix_per_block - 128/dst_w_bpp
/* The remainder of the line is handled identically to the medium case */
medium_case_inner_loop_and_trailing_pixels process_head, process_tail,, exit_label, unaligned_src, unaligned_mask
@@ -561,13 +596,7 @@
process_tail, \
process_inner_loop
- .func fname
- .global fname
- /* For ELF format also set function visibility to hidden */
-#ifdef __ELF__
- .hidden fname
- .type fname, %function
-#endif
+ pixman_asm_function fname
/*
* Make some macro arguments globally visible and accessible
@@ -679,7 +708,6 @@
SCRATCH .req r12
ORIG_W .req r14 /* width (pixels) */
-fname:
push {r4-r11, lr} /* save all registers */
subs Y, Y, #1
@@ -705,6 +733,13 @@ fname:
#endif
init
+
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ /* Reserve a word in which to store X during leading pixels */
+ sub sp, sp, #4
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET+4
+ .endif
lsl STRIDE_D, #dst_bpp_shift /* stride in bytes */
sub STRIDE_D, STRIDE_D, X, lsl #dst_bpp_shift
@@ -734,42 +769,49 @@ fname:
.if (flags) & FLAG_SPILL_LINE_VARS_WIDE
/* This is stmdb sp!,{} */
.word 0xE92D0000 | LINE_SAVED_REGS
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
.endif
151: /* New line */
newline
preload_leading_step1 src_bpp, WK1, SRC
preload_leading_step1 mask_bpp, WK2, MASK
+ .if ((flags) & FLAG_NO_PRELOAD_DST) == 0
preload_leading_step1 dst_r_bpp, WK3, DST
+ .endif
- tst DST, #15
+ ands WK0, DST, #15
beq 154f
- rsb WK0, DST, #0 /* bits 0-3 = number of leading bytes until destination aligned */
- .if (src_bpp != 0 && src_bpp != 2*dst_w_bpp) || (mask_bpp != 0 && mask_bpp != 2*dst_w_bpp)
- PF and, WK0, WK0, #15
- .endif
+ rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
preload_leading_step2 src_bpp, src_bpp_shift, WK1, SRC
preload_leading_step2 mask_bpp, mask_bpp_shift, WK2, MASK
+ .if ((flags) & FLAG_NO_PRELOAD_DST) == 0
preload_leading_step2 dst_r_bpp, dst_bpp_shift, WK3, DST
+ .endif
leading_15bytes process_head, process_tail
154: /* Destination now 16-byte aligned; we have at least one prefetch on each channel as well as at least one 16-byte output block */
- .if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
+ .if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
and SCRATCH, SRC, #31
rsb SCRATCH, SCRATCH, #32*prefetch_distance
- .elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
+ .elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
and SCRATCH, MASK, #31
rsb SCRATCH, SCRATCH, #32*prefetch_distance
- .endif
- .ifc "process_inner_loop",""
+ .endif
+ .ifc "process_inner_loop",""
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, wide_case_inner_loop, 157f
- .else
+ .else
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, process_inner_loop, 157f
- .endif
+ .endif
157: /* Check for another line */
end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_WIDE), 151b
+ .if (flags) & FLAG_SPILL_LINE_VARS_WIDE
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
+ .endif
.endif
.ltorg
@@ -779,17 +821,21 @@ fname:
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
/* This is stmdb sp!,{} */
.word 0xE92D0000 | LINE_SAVED_REGS
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
.endif
161: /* New line */
newline
preload_line 0, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
preload_line 0, mask_bpp, mask_bpp_shift, MASK
+ .if ((flags) & FLAG_NO_PRELOAD_DST) == 0
preload_line 0, dst_r_bpp, dst_bpp_shift, DST
+ .endif
sub X, X, #128/dst_w_bpp /* simplifies inner loop termination */
- tst DST, #15
+ ands WK0, DST, #15
beq 164f
- rsb WK0, DST, #0 /* bits 0-3 = number of leading bytes until destination aligned */
+ rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
leading_15bytes process_head, process_tail
@@ -813,7 +859,9 @@ fname:
newline
preload_line 1, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
preload_line 1, mask_bpp, mask_bpp_shift, MASK
+ .if ((flags) & FLAG_NO_PRELOAD_DST) == 0
preload_line 1, dst_r_bpp, dst_bpp_shift, DST
+ .endif
.if dst_w_bpp == 8
tst DST, #3
@@ -844,12 +892,22 @@ fname:
177: /* Check for another line */
end_of_line %(dst_w_bpp < 32), %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 171b, last_one
+ .if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
+ .endif
197:
.if (flags) & FLAG_SPILL_LINE_VARS
add sp, sp, #LINE_SAVED_REG_COUNT*4
.endif
198:
+ .if (flags) & FLAG_PROCESS_CORRUPTS_WK0
+ .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-4
+ .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET-4
+ add sp, sp, #4
+ .endif
+
cleanup
#ifdef DEBUG_PARAMS
diff --git a/lib/pixman/pixman/pixman-arm-simd.c b/lib/pixman/pixman/pixman-arm-simd.c
index af062e19d..f0d14540b 100644
--- a/lib/pixman/pixman/pixman-arm-simd.c
+++ b/lib/pixman/pixman/pixman-arm-simd.c
@@ -41,11 +41,20 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8,
uint8_t, 1, uint8_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888,
uint16_t, 1, uint32_t, 1)
+PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_0565,
+ uint32_t, 1, uint16_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8,
uint8_t, 1, uint8_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888,
uint32_t, 1, uint32_t, 1)
+PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, in_reverse_8888_8888,
+ uint32_t, 1, uint32_t, 1)
+
+PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, armv6, over_n_8888,
+ uint32_t, 1)
+PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, armv6, over_reverse_n_8888,
+ uint32_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
uint32_t, 1, uint32_t, 1)
@@ -53,6 +62,9 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888,
uint8_t, 1, uint32_t, 1)
+PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8888_8888_ca,
+ uint32_t, 1, uint32_t, 1)
+
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
uint16_t, uint16_t)
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC,
@@ -216,6 +228,11 @@ static const pixman_fast_path_t arm_simd_fast_paths[] =
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888),
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888),
+ PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
+
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888),
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888),
@@ -225,6 +242,13 @@ static const pixman_fast_path_t arm_simd_fast_paths[] =
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888),
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, armv6_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, armv6_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8b8g8r8, armv6_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8b8g8r8, armv6_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, armv6_composite_over_reverse_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, armv6_composite_over_reverse_n_8888),
+
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888),
@@ -232,15 +256,25 @@ static const pixman_fast_path_t arm_simd_fast_paths[] =
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
+ PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, a8r8g8b8, armv6_composite_in_reverse_8888_8888),
+ PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, x8r8g8b8, armv6_composite_in_reverse_8888_8888),
+ PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, a8b8g8r8, armv6_composite_in_reverse_8888_8888),
+ PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, x8b8g8r8, armv6_composite_in_reverse_8888_8888),
+
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, armv6_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, armv6_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, armv6_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, armv6_composite_over_n_8888_8888_ca),
+
+ SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
+ SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
- PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
{ PIXMAN_OP_NONE },
};
diff --git a/lib/pixman/pixman/pixman-combine-float.c b/lib/pixman/pixman/pixman-combine-float.c
index 5ea739f76..f5145bc9d 100644
--- a/lib/pixman/pixman/pixman-combine-float.c
+++ b/lib/pixman/pixman/pixman-combine-float.c
@@ -319,23 +319,44 @@ MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA)
*
* The following blend modes have been taken from the PDF ISO 32000
* specification, which at this point in time is available from
- * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
- * The relevant chapters are 11.3.5 and 11.3.6.
+ *
+ * http://www.adobe.com/devnet/pdf/pdf_reference.html
+ *
+ * The specific documents of interest are the PDF spec itself:
+ *
+ * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf
+ *
+ * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat
+ * 9.1 and Reader 9.1:
+ *
+ * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf
+ *
+ * that clarifies the specifications for blend modes ColorDodge and
+ * ColorBurn.
+ *
* The formula for computing the final pixel color given in 11.3.6 is:
- * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
- * with B() being the blend function.
- * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs
- *
- * These blend modes should match the SVG filter draft specification, as
- * it has been designed to mirror ISO 32000. Note that at the current point
- * no released draft exists that shows this, as the formulas have not been
- * updated yet after the release of ISO 32000.
- *
- * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
- * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
- * argument. Note that this implementation operates on premultiplied colors,
- * while the PDF specification does not. Therefore the code uses the formula
- * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
+ *
+ * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
+ *
+ * with B() is the blend function. When B(Cb, Cs) = Cs, this formula
+ * reduces to the regular OVER operator.
+ *
+ * Cs and Cb are not premultiplied, so in our implementation we instead
+ * use:
+ *
+ * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs)
+ *
+ * where cr, cs, and cb are premultiplied colors, and where the
+ *
+ * αb × αs × B(cb/αb, cs/αs)
+ *
+ * part is first arithmetically simplified under the assumption that αb
+ * and αs are not 0, and then updated to produce a meaningful result when
+ * they are.
+ *
+ * For all the blend mode operators, the alpha channel is given by
+ *
+ * αr = αs + αb + αb × αs
*/
#define MAKE_SEPARABLE_PDF_COMBINERS(name) \
@@ -355,18 +376,55 @@ MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA)
\
MAKE_COMBINERS (name, combine_ ## name ## _a, combine_ ## name ## _c)
+/*
+ * Multiply
+ *
+ * ad * as * B(d / ad, s / as)
+ * = ad * as * d/ad * s/as
+ * = d * s
+ *
+ */
static force_inline float
blend_multiply (float sa, float s, float da, float d)
{
return d * s;
}
+/*
+ * Screen
+ *
+ * ad * as * B(d/ad, s/as)
+ * = ad * as * (d/ad + s/as - s/as * d/ad)
+ * = ad * s + as * d - s * d
+ */
static force_inline float
blend_screen (float sa, float s, float da, float d)
{
return d * sa + s * da - s * d;
}
+/*
+ * Overlay
+ *
+ * ad * as * B(d/ad, s/as)
+ * = ad * as * Hardlight (s, d)
+ * = if (d / ad < 0.5)
+ * as * ad * Multiply (s/as, 2 * d/ad)
+ * else
+ * as * ad * Screen (s/as, 2 * d / ad - 1)
+ * = if (d < 0.5 * ad)
+ * as * ad * s/as * 2 * d /ad
+ * else
+ * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1))
+ * = if (2 * d < ad)
+ * 2 * s * d
+ * else
+ * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1)
+ * = if (2 * d < ad)
+ * 2 * s * d
+ * else
+ * as * ad - 2 * (ad - d) * (as - s)
+ */
static force_inline float
blend_overlay (float sa, float s, float da, float d)
{
@@ -376,6 +434,13 @@ blend_overlay (float sa, float s, float da, float d)
return sa * da - 2 * (da - d) * (sa - s);
}
+/*
+ * Darken
+ *
+ * ad * as * B(d/ad, s/as)
+ * = ad * as * MIN(d/ad, s/as)
+ * = MIN (as * d, ad * s)
+ */
static force_inline float
blend_darken (float sa, float s, float da, float d)
{
@@ -388,6 +453,13 @@ blend_darken (float sa, float s, float da, float d)
return s;
}
+/*
+ * Lighten
+ *
+ * ad * as * B(d/ad, s/as)
+ * = ad * as * MAX(d/ad, s/as)
+ * = MAX (as * d, ad * s)
+ */
static force_inline float
blend_lighten (float sa, float s, float da, float d)
{
@@ -400,6 +472,24 @@ blend_lighten (float sa, float s, float da, float d)
return d;
}
+/*
+ * Color dodge
+ *
+ * ad * as * B(d/ad, s/as)
+ * = if d/ad = 0
+ * ad * as * 0
+ * else if (d/ad >= (1 - s/as)
+ * ad * as * 1
+ * else
+ * ad * as * ((d/ad) / (1 - s/as))
+ * = if d = 0
+ * 0
+ * elif as * d >= ad * (as - s)
+ * ad * as
+ * else
+ * as * (as * d / (as - s))
+ *
+ */
static force_inline float
blend_color_dodge (float sa, float s, float da, float d)
{
@@ -413,6 +503,26 @@ blend_color_dodge (float sa, float s, float da, float d)
return sa * sa * d / (sa - s);
}
+/*
+ * Color burn
+ *
+ * We modify the first clause "if d = 1" to "if d >= 1" since with
+ * premultiplied colors d > 1 can actually happen.
+ *
+ * ad * as * B(d/ad, s/as)
+ * = if d/ad >= 1
+ * ad * as * 1
+ * elif (1 - d/ad) >= s/as
+ * ad * as * 0
+ * else
+ * ad * as * (1 - ((1 - d/ad) / (s/as)))
+ * = if d >= ad
+ * ad * as
+ * elif as * ad - as * d >= ad * s
+ * 0
+ * else
+ * ad * as - as * as * (ad - d) / s
+ */
static force_inline float
blend_color_burn (float sa, float s, float da, float d)
{
@@ -426,6 +536,23 @@ blend_color_burn (float sa, float s, float da, float d)
return sa * (da - sa * (da - d) / s);
}
+/*
+ * Hard light
+ *
+ * ad * as * B(d/ad, s/as)
+ * = if (s/as <= 0.5)
+ * ad * as * Multiply (d/ad, 2 * s/as)
+ * else
+ * ad * as * Screen (d/ad, 2 * s/as - 1)
+ * = if 2 * s <= as
+ * ad * as * d/ad * 2 * s / as
+ * else
+ * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1))
+ * = if 2 * s <= as
+ * 2 * s * d
+ * else
+ * as * ad - 2 * (ad - d) * (as - s)
+ */
static force_inline float
blend_hard_light (float sa, float s, float da, float d)
{
@@ -435,10 +562,27 @@ blend_hard_light (float sa, float s, float da, float d)
return sa * da - 2 * (da - d) * (sa - s);
}
+/*
+ * Soft light
+ *
+ * ad * as * B(d/ad, s/as)
+ * = if (s/as <= 0.5)
+ * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad))
+ * else if (d/ad <= 0.25)
+ * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad))
+ * else
+ * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad))
+ * = if (2 * s <= as)
+ * d * as - d * (ad - d) * (as - 2 * s) / ad;
+ * else if (4 * d <= ad)
+ * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
+ * else
+ * d * as + (sqrt (d * ad) - d) * (2 * s - as);
+ */
static force_inline float
blend_soft_light (float sa, float s, float da, float d)
{
- if (2 * s < sa)
+ if (2 * s <= sa)
{
if (FLOAT_IS_ZERO (da))
return d * sa;
@@ -449,7 +593,7 @@ blend_soft_light (float sa, float s, float da, float d)
{
if (FLOAT_IS_ZERO (da))
{
- return 0.0f;
+ return d * sa;
}
else
{
@@ -461,6 +605,20 @@ blend_soft_light (float sa, float s, float da, float d)
}
}
+/*
+ * Difference
+ *
+ * ad * as * B(s/as, d/ad)
+ * = ad * as * abs (s/as - d/ad)
+ * = if (s/as <= d/ad)
+ * ad * as * (d/ad - s/as)
+ * else
+ * ad * as * (s/as - d/ad)
+ * = if (ad * s <= as * d)
+ * as * d - ad * s
+ * else
+ * ad * s - as * d
+ */
static force_inline float
blend_difference (float sa, float s, float da, float d)
{
@@ -473,6 +631,13 @@ blend_difference (float sa, float s, float da, float d)
return sda - dsa;
}
+/*
+ * Exclusion
+ *
+ * ad * as * B(s/as, d/ad)
+ * = ad * as * (d/ad + s/as - 2 * d/ad * s/as)
+ * = as * d + ad * s - 2 * s * d
+ */
static force_inline float
blend_exclusion (float sa, float s, float da, float d)
{
@@ -492,116 +657,79 @@ MAKE_SEPARABLE_PDF_COMBINERS (difference)
MAKE_SEPARABLE_PDF_COMBINERS (exclusion)
/*
- * PDF nonseperable blend modes.
- *
- * These are implemented using the following functions to operate in Hsl
- * space, with Cmax, Cmid, Cmin referring to the max, mid and min value
- * of the red, green and blue components.
+ * PDF nonseperable blend modes are implemented using the following functions
+ * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
+ * and min value of the red, green and blue components.
*
* LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
*
* clip_color (C):
- * l = LUM (C)
- * min = Cmin
- * max = Cmax
- * if n < 0.0
- * C = l + (((C – l) × l) ⁄ (l – min))
- * if x > 1.0
- * C = l + (((C – l) × (1 – l)) (max – l))
- * return C
+ * l = LUM (C)
+ * min = Cmin
+ * max = Cmax
+ * if n < 0.0
+ * C = l + (((C – l) × l) ⁄ (l – min))
+ * if x > 1.0
+ * C = l + (((C – l) × (1 – l) ) ⁄ (max – l))
+ * return C
*
* set_lum (C, l):
- * d = l – LUM (C)
- * C += d
- * return clip_color (C)
+ * d = l – LUM (C)
+ * C += d
+ * return clip_color (C)
*
* SAT (C) = CH_MAX (C) - CH_MIN (C)
*
* set_sat (C, s):
- * if Cmax > Cmin
- * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
- * Cmax = s
- * else
- * Cmid = Cmax = 0.0
- * Cmin = 0.0
- * return C
+ * if Cmax > Cmin
+ * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
+ * Cmax = s
+ * else
+ * Cmid = Cmax = 0.0
+ * Cmin = 0.0
+ * return C
*/
/* For premultiplied colors, we need to know what happens when C is
* multiplied by a real number. LUM and SAT are linear:
*
- * LUM (r × C) = r × LUM (C) SAT (r × C) = r × SAT (C)
+ * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C)
*
* If we extend clip_color with an extra argument a and change
*
- * if x >= 1.0
+ * if x >= 1.0
*
* into
*
- * if x >= a
+ * if x >= a
*
* then clip_color is also linear:
*
- * r * clip_color (C, a) = clip_color (r_c, ra);
+ * r * clip_color (C, a) = clip_color (r * C, r * a);
*
* for positive r.
*
* Similarly, we can extend set_lum with an extra argument that is just passed
* on to clip_color:
*
- * r × set_lum ( C, l, a)
+ * r * set_lum (C, l, a)
*
- * = r × clip_color ( C + l - LUM (C), a)
+ * = r × clip_color (C + l - LUM (C), a)
*
- * = clip_color ( r * C + r × l - LUM (r × C), r * a)
+ * = clip_color (r * C + r × l - r * LUM (C), r * a)
*
- * = set_lum ( r * C, r * l, r * a)
+ * = set_lum (r * C, r * l, r * a)
*
* Finally, set_sat:
*
- * r * set_sat (C, s) = set_sat (x * C, r * s)
+ * r * set_sat (C, s) = set_sat (x * C, r * s)
*
- * The above holds for all non-zero x because they x'es in the fraction for
+ * The above holds for all non-zero x, because the x'es in the fraction for
* C_mid cancel out. Specifically, it holds for x = r:
*
- * r * set_sat (C, s) = set_sat (r_c, rs)
- *
- *
- *
- *
- * So, for the non-separable PDF blend modes, we have (using s, d for
- * non-premultiplied colors, and S, D for premultiplied:
- *
- * Color:
- *
- * a_s * a_d * B(s, d)
- * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1)
- * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d)
- *
- *
- * Luminosity:
- *
- * a_s * a_d * B(s, d)
- * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1)
- * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d)
- *
- *
- * Saturation:
- *
- * a_s * a_d * B(s, d)
- * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1)
- * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
- * a_s * LUM (D), a_s * a_d)
- * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
- *
- * Hue:
- *
- * a_s * a_d * B(s, d)
- * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
- * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
+ * r * set_sat (C, s) = set_sat (r * C, r * s)
*
*/
-
typedef struct
{
float r;
@@ -769,9 +897,12 @@ set_sat (rgb_t *src, float sat)
*min = 0.0f;
}
-/*
- * Hue:
- * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
+/* Hue:
+ *
+ * as * ad * B(s/as, d/as)
+ * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1)
+ * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad)
+ *
*/
static force_inline void
blend_hsl_hue (rgb_t *res,
@@ -786,9 +917,14 @@ blend_hsl_hue (rgb_t *res,
set_lum (res, sa * da, get_lum (dest) * sa);
}
-/*
- * Saturation:
- * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
+/*
+ * Saturation
+ *
+ * as * ad * B(s/as, d/ad)
+ * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1)
+ * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)),
+ * as * LUM (d), as * ad)
+ * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad))
*/
static force_inline void
blend_hsl_saturation (rgb_t *res,
@@ -803,9 +939,12 @@ blend_hsl_saturation (rgb_t *res,
set_lum (res, sa * da, get_lum (dest) * sa);
}
-/*
- * Color:
- * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
+/*
+ * Color
+ *
+ * as * ad * B(s/as, d/as)
+ * = as * ad * set_lum (s/as, LUM (d/ad), 1)
+ * = set_lum (s * ad, as * LUM (d), as * ad)
*/
static force_inline void
blend_hsl_color (rgb_t *res,
@@ -820,8 +959,11 @@ blend_hsl_color (rgb_t *res,
}
/*
- * Luminosity:
- * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
+ * Luminosity
+ *
+ * as * ad * B(s/as, d/ad)
+ * = as * ad * set_lum (d/ad, LUM (s/as), 1)
+ * = set_lum (as * d, ad * LUM (s), as * ad)
*/
static force_inline void
blend_hsl_luminosity (rgb_t *res,
diff --git a/lib/pixman/pixman/pixman-combine32.c b/lib/pixman/pixman/pixman-combine32.c
index 450114a52..4c484d3e3 100644
--- a/lib/pixman/pixman/pixman-combine32.c
+++ b/lib/pixman/pixman/pixman-combine32.c
@@ -434,36 +434,6 @@ combine_add_u (pixman_implementation_t *imp,
}
}
-static void
-combine_saturate_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = combine_mask (src, mask, i);
- uint32_t d = *(dest + i);
- uint16_t sa, da;
-
- sa = s >> A_SHIFT;
- da = ~d >> A_SHIFT;
- if (sa > da)
- {
- sa = DIV_UN8 (da, sa);
- UN8x4_MUL_UN8 (s, sa);
- }
- ;
- UN8x4_ADD_UN8x4 (d, s);
- *(dest + i) = d;
- }
-}
-
-
/*
* PDF blend modes:
*
@@ -571,6 +541,15 @@ combine_multiply_ca (pixman_implementation_t *imp,
}
}
+#define CLAMP(v, low, high) \
+ do \
+ { \
+ if (v < (low)) \
+ v = (low); \
+ if (v > (high)) \
+ v = (high); \
+ } while (0)
+
#define PDF_SEPARABLE_BLEND_MODE(name) \
static void \
combine_ ## name ## _u (pixman_implementation_t *imp, \
@@ -589,16 +568,28 @@ combine_multiply_ca (pixman_implementation_t *imp,
uint8_t isa = ~sa; \
uint8_t da = ALPHA_8 (d); \
uint8_t ida = ~da; \
- uint32_t result; \
- \
- result = d; \
- UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \
+ int32_t ra, rr, rg, rb; \
\
- *(dest + i) = result + \
- (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \
- (blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \
- (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \
- (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa)); \
+ ra = da * 0xff + sa * 0xff - sa * da; \
+ rr = isa * RED_8 (d) + ida * RED_8 (s); \
+ rg = isa * GREEN_8 (d) + ida * GREEN_8 (s); \
+ rb = isa * BLUE_8 (d) + ida * BLUE_8 (s); \
+ \
+ rr += blend_ ## name (RED_8 (d), da, RED_8 (s), sa); \
+ rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa); \
+ rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa); \
+ \
+ CLAMP (ra, 0, 255 * 255); \
+ CLAMP (rr, 0, 255 * 255); \
+ CLAMP (rg, 0, 255 * 255); \
+ CLAMP (rb, 0, 255 * 255); \
+ \
+ ra = DIV_ONE_UN8 (ra); \
+ rr = DIV_ONE_UN8 (rr); \
+ rg = DIV_ONE_UN8 (rg); \
+ rb = DIV_ONE_UN8 (rb); \
+ \
+ *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \
} \
} \
\
@@ -618,20 +609,35 @@ combine_multiply_ca (pixman_implementation_t *imp,
uint32_t d = *(dest + i); \
uint8_t da = ALPHA_8 (d); \
uint8_t ida = ~da; \
- uint32_t result; \
- \
+ int32_t ra, rr, rg, rb; \
+ uint8_t ira, iga, iba; \
+ \
combine_mask_ca (&s, &m); \
- \
- result = d; \
- UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida); \
- \
- result += \
- (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) + \
- (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \
- (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \
- (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \
\
- *(dest + i) = result; \
+ ira = ~RED_8 (m); \
+ iga = ~GREEN_8 (m); \
+ iba = ~BLUE_8 (m); \
+ \
+ ra = da * 0xff + ALPHA_8 (s) * 0xff - ALPHA_8 (s) * da; \
+ rr = ira * RED_8 (d) + ida * RED_8 (s); \
+ rg = iga * GREEN_8 (d) + ida * GREEN_8 (s); \
+ rb = iba * BLUE_8 (d) + ida * BLUE_8 (s); \
+ \
+ rr += blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)); \
+ rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)); \
+ rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m)); \
+ \
+ CLAMP (ra, 0, 255 * 255); \
+ CLAMP (rr, 0, 255 * 255); \
+ CLAMP (rg, 0, 255 * 255); \
+ CLAMP (rb, 0, 255 * 255); \
+ \
+ ra = DIV_ONE_UN8 (ra); \
+ rr = DIV_ONE_UN8 (rr); \
+ rg = DIV_ONE_UN8 (rg); \
+ rb = DIV_ONE_UN8 (rb); \
+ \
+ *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \
} \
}
@@ -642,10 +648,10 @@ combine_multiply_ca (pixman_implementation_t *imp,
* = ad * as * (d/ad + s/as - s/as * d/ad)
* = ad * s + as * d - s * d
*/
-static inline uint32_t
-blend_screen (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_screen (int32_t d, int32_t ad, int32_t s, int32_t as)
{
- return DIV_ONE_UN8 (s * ad + d * as - s * d);
+ return s * ad + d * as - s * d;
}
PDF_SEPARABLE_BLEND_MODE (screen)
@@ -672,8 +678,8 @@ PDF_SEPARABLE_BLEND_MODE (screen)
* else
* as * ad - 2 * (ad - d) * (as - s)
*/
-static inline uint32_t
-blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_overlay (int32_t d, int32_t ad, int32_t s, int32_t as)
{
uint32_t r;
@@ -682,7 +688,7 @@ blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
else
r = as * ad - 2 * (ad - d) * (as - s);
- return DIV_ONE_UN8 (r);
+ return r;
}
PDF_SEPARABLE_BLEND_MODE (overlay)
@@ -694,13 +700,13 @@ PDF_SEPARABLE_BLEND_MODE (overlay)
* = ad * as * MIN(d/ad, s/as)
* = MIN (as * d, ad * s)
*/
-static inline uint32_t
-blend_darken (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_darken (int32_t d, int32_t ad, int32_t s, int32_t as)
{
s = ad * s;
d = as * d;
- return DIV_ONE_UN8 (s > d ? d : s);
+ return s > d ? d : s;
}
PDF_SEPARABLE_BLEND_MODE (darken)
@@ -712,86 +718,18 @@ PDF_SEPARABLE_BLEND_MODE (darken)
* = ad * as * MAX(d/ad, s/as)
* = MAX (as * d, ad * s)
*/
-static inline uint32_t
-blend_lighten (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_lighten (int32_t d, int32_t ad, int32_t s, int32_t as)
{
s = ad * s;
d = as * d;
- return DIV_ONE_UN8 (s > d ? s : d);
+ return s > d ? s : d;
}
PDF_SEPARABLE_BLEND_MODE (lighten)
/*
- * Color dodge
- *
- * ad * as * B(d/ad, s/as)
- * = if d/ad = 0
- * ad * as * 0
- * else if (d/ad >= (1 - s/as)
- * ad * as * 1
- * else
- * ad * as * ((d/ad) / (1 - s/as))
- * = if d = 0
- * 0
- * elif as * d >= ad * (as - s)
- * ad * as
- * else
- * as * (as * d / (as - s))
- *
- */
-static inline uint32_t
-blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
-{
- if (d == 0)
- return 0;
- else if (as * d >= ad * (as - s))
- return DIV_ONE_UN8 (as * ad);
- else if (as - s == 0)
- return DIV_ONE_UN8 (as * ad);
- else
- return DIV_ONE_UN8 (as * ((d * as) / ((as - s))));
-}
-
-PDF_SEPARABLE_BLEND_MODE (color_dodge)
-
-/*
- * Color burn
- *
- * We modify the first clause "if d = 1" to "if d >= 1" since with
- * premultiplied colors d > 1 can actually happen.
- *
- * ad * as * B(d/ad, s/as)
- * = if d/ad >= 1
- * ad * as * 1
- * elif (1 - d/ad) >= s/as
- * ad * as * 0
- * else
- * ad * as * (1 - ((1 - d/ad) / (s/as)))
- * = if d >= ad
- * ad * as
- * elif as * ad - as * d >= ad * s
- * 0
- * else
- * ad * as - as * as * (ad - d) / s
- */
-static inline uint32_t
-blend_color_burn (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
-{
- if (d >= ad)
- return DIV_ONE_UN8 (ad * as);
- else if (as * ad - as * d >= ad * s)
- return 0;
- else if (s == 0)
- return 0;
- else
- return DIV_ONE_UN8 (ad * as - (as * as * (ad - d)) / s);
-}
-
-PDF_SEPARABLE_BLEND_MODE (color_burn)
-
-/*
* Hard light
*
* ad * as * B(d/ad, s/as)
@@ -808,72 +746,18 @@ PDF_SEPARABLE_BLEND_MODE (color_burn)
* else
* as * ad - 2 * (ad - d) * (as - s)
*/
-static inline uint32_t
-blend_hard_light (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_hard_light (int32_t d, int32_t ad, int32_t s, int32_t as)
{
if (2 * s < as)
- return DIV_ONE_UN8 (2 * s * d);
+ return 2 * s * d;
else
- return DIV_ONE_UN8 (as * ad - 2 * (ad - d) * (as - s));
+ return as * ad - 2 * (ad - d) * (as - s);
}
PDF_SEPARABLE_BLEND_MODE (hard_light)
/*
- * Soft light
- *
- * ad * as * B(d/ad, s/as)
- * = if (s/as <= 0.5)
- * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad))
- * else if (d/ad <= 0.25)
- * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad))
- * else
- * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad))
- * = if (2 * s <= as)
- * d * as - d * (ad - d) * (as - 2 * s) / ad;
- * else if (4 * d <= ad)
- * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
- * else
- * d * as + (sqrt (d * ad) - d) * (2 * s - as);
- */
-static inline uint32_t
-blend_soft_light (uint32_t d_org,
- uint32_t ad_org,
- uint32_t s_org,
- uint32_t as_org)
-{
- double d = d_org * (1.0 / MASK);
- double ad = ad_org * (1.0 / MASK);
- double s = s_org * (1.0 / MASK);
- double as = as_org * (1.0 / MASK);
- double r;
-
- if (2 * s < as)
- {
- if (ad == 0)
- r = d * as;
- else
- r = d * as - d * (ad - d) * (as - 2 * s) / ad;
- }
- else if (ad == 0)
- {
- r = 0;
- }
- else if (4 * d <= ad)
- {
- r = d * as +
- (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
- }
- else
- {
- r = d * as + (sqrt (d * ad) - d) * (2 * s - as);
- }
- return r * MASK + 0.5;
-}
-
-PDF_SEPARABLE_BLEND_MODE (soft_light)
-
-/*
* Difference
*
* ad * as * B(s/as, d/ad)
@@ -887,16 +771,16 @@ PDF_SEPARABLE_BLEND_MODE (soft_light)
* else
* ad * s - as * d
*/
-static inline uint32_t
-blend_difference (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_difference (int32_t d, int32_t ad, int32_t s, int32_t as)
{
- uint32_t das = d * as;
- uint32_t sad = s * ad;
+ int32_t das = d * as;
+ int32_t sad = s * ad;
if (sad < das)
- return DIV_ONE_UN8 (das - sad);
+ return das - sad;
else
- return DIV_ONE_UN8 (sad - das);
+ return sad - das;
}
PDF_SEPARABLE_BLEND_MODE (difference)
@@ -912,796 +796,16 @@ PDF_SEPARABLE_BLEND_MODE (difference)
/* This can be made faster by writing it directly and not using
* PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
-static inline uint32_t
-blend_exclusion (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
+static inline int32_t
+blend_exclusion (int32_t d, int32_t ad, int32_t s, int32_t as)
{
- return DIV_ONE_UN8 (s * ad + d * as - 2 * d * s);
+ return s * ad + d * as - 2 * d * s;
}
PDF_SEPARABLE_BLEND_MODE (exclusion)
#undef PDF_SEPARABLE_BLEND_MODE
-/*
- * PDF nonseperable blend modes are implemented using the following functions
- * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
- * and min value of the red, green and blue components.
- *
- * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
- *
- * clip_color (C):
- * l = LUM (C)
- * min = Cmin
- * max = Cmax
- * if n < 0.0
- * C = l + (((C – l) × l) ⁄ (l – min))
- * if x > 1.0
- * C = l + (((C – l) × (1 – l) ) ⁄ (max – l))
- * return C
- *
- * set_lum (C, l):
- * d = l – LUM (C)
- * C += d
- * return clip_color (C)
- *
- * SAT (C) = CH_MAX (C) - CH_MIN (C)
- *
- * set_sat (C, s):
- * if Cmax > Cmin
- * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
- * Cmax = s
- * else
- * Cmid = Cmax = 0.0
- * Cmin = 0.0
- * return C
- */
-
-/* For premultiplied colors, we need to know what happens when C is
- * multiplied by a real number. LUM and SAT are linear:
- *
- * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C)
- *
- * If we extend clip_color with an extra argument a and change
- *
- * if x >= 1.0
- *
- * into
- *
- * if x >= a
- *
- * then clip_color is also linear:
- *
- * r * clip_color (C, a) = clip_color (r * C, r * a);
- *
- * for positive r.
- *
- * Similarly, we can extend set_lum with an extra argument that is just passed
- * on to clip_color:
- *
- * r * set_lum (C, l, a)
- *
- * = r × clip_color (C + l - LUM (C), a)
- *
- * = clip_color (r * C + r × l - r * LUM (C), r * a)
- *
- * = set_lum (r * C, r * l, r * a)
- *
- * Finally, set_sat:
- *
- * r * set_sat (C, s) = set_sat (x * C, r * s)
- *
- * The above holds for all non-zero x, because the x'es in the fraction for
- * C_mid cancel out. Specifically, it holds for x = r:
- *
- * r * set_sat (C, s) = set_sat (r * C, r * s)
- *
- */
-
-#define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
-#define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
-#define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
-#define SAT(c) (CH_MAX (c) - CH_MIN (c))
-
-#define PDF_NON_SEPARABLE_BLEND_MODE(name) \
- static void \
- combine_ ## name ## _u (pixman_implementation_t *imp, \
- pixman_op_t op, \
- uint32_t * dest, \
- const uint32_t * src, \
- const uint32_t * mask, \
- int width) \
- { \
- int i; \
- for (i = 0; i < width; ++i) \
- { \
- uint32_t s = combine_mask (src, mask, i); \
- uint32_t d = *(dest + i); \
- uint8_t sa = ALPHA_8 (s); \
- uint8_t isa = ~sa; \
- uint8_t da = ALPHA_8 (d); \
- uint8_t ida = ~da; \
- uint32_t result; \
- uint32_t sc[3], dc[3], c[3]; \
- \
- result = d; \
- UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \
- dc[0] = RED_8 (d); \
- sc[0] = RED_8 (s); \
- dc[1] = GREEN_8 (d); \
- sc[1] = GREEN_8 (s); \
- dc[2] = BLUE_8 (d); \
- sc[2] = BLUE_8 (s); \
- blend_ ## name (c, dc, da, sc, sa); \
- \
- *(dest + i) = result + \
- (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \
- (DIV_ONE_UN8 (c[0]) << R_SHIFT) + \
- (DIV_ONE_UN8 (c[1]) << G_SHIFT) + \
- (DIV_ONE_UN8 (c[2])); \
- } \
- }
-
-static void
-set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum)
-{
- double a, l, min, max;
- double tmp[3];
-
- a = sa * (1.0 / MASK);
-
- l = lum * (1.0 / MASK);
- tmp[0] = src[0] * (1.0 / MASK);
- tmp[1] = src[1] * (1.0 / MASK);
- tmp[2] = src[2] * (1.0 / MASK);
-
- l = l - LUM (tmp);
- tmp[0] += l;
- tmp[1] += l;
- tmp[2] += l;
-
- /* clip_color */
- l = LUM (tmp);
- min = CH_MIN (tmp);
- max = CH_MAX (tmp);
-
- if (min < 0)
- {
- if (l - min == 0.0)
- {
- tmp[0] = 0;
- tmp[1] = 0;
- tmp[2] = 0;
- }
- else
- {
- tmp[0] = l + (tmp[0] - l) * l / (l - min);
- tmp[1] = l + (tmp[1] - l) * l / (l - min);
- tmp[2] = l + (tmp[2] - l) * l / (l - min);
- }
- }
- if (max > a)
- {
- if (max - l == 0.0)
- {
- tmp[0] = a;
- tmp[1] = a;
- tmp[2] = a;
- }
- else
- {
- tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
- tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
- tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
- }
- }
-
- dest[0] = tmp[0] * MASK + 0.5;
- dest[1] = tmp[1] * MASK + 0.5;
- dest[2] = tmp[2] * MASK + 0.5;
-}
-
-static void
-set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat)
-{
- int id[3];
- uint32_t min, max;
-
- if (src[0] > src[1])
- {
- if (src[0] > src[2])
- {
- id[0] = 0;
- if (src[1] > src[2])
- {
- id[1] = 1;
- id[2] = 2;
- }
- else
- {
- id[1] = 2;
- id[2] = 1;
- }
- }
- else
- {
- id[0] = 2;
- id[1] = 0;
- id[2] = 1;
- }
- }
- else
- {
- if (src[0] > src[2])
- {
- id[0] = 1;
- id[1] = 0;
- id[2] = 2;
- }
- else
- {
- id[2] = 0;
- if (src[1] > src[2])
- {
- id[0] = 1;
- id[1] = 2;
- }
- else
- {
- id[0] = 2;
- id[1] = 1;
- }
- }
- }
-
- max = dest[id[0]];
- min = dest[id[2]];
- if (max > min)
- {
- dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
- dest[id[0]] = sat;
- dest[id[2]] = 0;
- }
- else
- {
- dest[0] = dest[1] = dest[2] = 0;
- }
-}
-
-/* Hue:
- *
- * as * ad * B(s/as, d/as)
- * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1)
- * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad)
- *
- */
-static inline void
-blend_hsl_hue (uint32_t r[3],
- uint32_t d[3],
- uint32_t ad,
- uint32_t s[3],
- uint32_t as)
-{
- r[0] = s[0] * ad;
- r[1] = s[1] * ad;
- r[2] = s[2] * ad;
- set_sat (r, r, SAT (d) * as);
- set_lum (r, r, as * ad, LUM (d) * as);
-}
-
-PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
-
-/*
- * Saturation
- *
- * as * ad * B(s/as, d/ad)
- * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1)
- * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)),
- * as * LUM (d), as * ad)
- * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad))
- */
-static inline void
-blend_hsl_saturation (uint32_t r[3],
- uint32_t d[3],
- uint32_t ad,
- uint32_t s[3],
- uint32_t as)
-{
- r[0] = d[0] * as;
- r[1] = d[1] * as;
- r[2] = d[2] * as;
- set_sat (r, r, SAT (s) * ad);
- set_lum (r, r, as * ad, LUM (d) * as);
-}
-
-PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
-
-/*
- * Color
- *
- * as * ad * B(s/as, d/as)
- * = as * ad * set_lum (s/as, LUM (d/ad), 1)
- * = set_lum (s * ad, as * LUM (d), as * ad)
- */
-static inline void
-blend_hsl_color (uint32_t r[3],
- uint32_t d[3],
- uint32_t ad,
- uint32_t s[3],
- uint32_t as)
-{
- r[0] = s[0] * ad;
- r[1] = s[1] * ad;
- r[2] = s[2] * ad;
- set_lum (r, r, as * ad, LUM (d) * as);
-}
-
-PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
-
-/*
- * Luminosity
- *
- * as * ad * B(s/as, d/ad)
- * = as * ad * set_lum (d/ad, LUM (s/as), 1)
- * = set_lum (as * d, ad * LUM (s), as * ad)
- */
-static inline void
-blend_hsl_luminosity (uint32_t r[3],
- uint32_t d[3],
- uint32_t ad,
- uint32_t s[3],
- uint32_t as)
-{
- r[0] = d[0] * as;
- r[1] = d[1] * as;
- r[2] = d[2] * as;
- set_lum (r, r, as * ad, LUM (s) * ad);
-}
-
-PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
-
-#undef SAT
-#undef LUM
-#undef CH_MAX
-#undef CH_MIN
-#undef PDF_NON_SEPARABLE_BLEND_MODE
-
-/* All of the disjoint/conjoint composing functions
- *
- * The four entries in the first column indicate what source contributions
- * come from each of the four areas of the picture -- areas covered by neither
- * A nor B, areas covered only by A, areas covered only by B and finally
- * areas covered by both A and B.
- *
- * Disjoint Conjoint
- * Fa Fb Fa Fb
- * (0,0,0,0) 0 0 0 0
- * (0,A,0,A) 1 0 1 0
- * (0,0,B,B) 0 1 0 1
- * (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
- * (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
- * (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
- * (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
- * (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
- * (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
- * (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
- * (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
- * (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
- *
- * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
- * information about these operators.
- */
-
-#define COMBINE_A_OUT 1
-#define COMBINE_A_IN 2
-#define COMBINE_B_OUT 4
-#define COMBINE_B_IN 8
-
-#define COMBINE_CLEAR 0
-#define COMBINE_A (COMBINE_A_OUT | COMBINE_A_IN)
-#define COMBINE_B (COMBINE_B_OUT | COMBINE_B_IN)
-#define COMBINE_A_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN)
-#define COMBINE_B_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN)
-#define COMBINE_A_ATOP (COMBINE_B_OUT | COMBINE_A_IN)
-#define COMBINE_B_ATOP (COMBINE_A_OUT | COMBINE_B_IN)
-#define COMBINE_XOR (COMBINE_A_OUT | COMBINE_B_OUT)
-
-/* portion covered by a but not b */
-static uint8_t
-combine_disjoint_out_part (uint8_t a, uint8_t b)
-{
- /* min (1, (1-b) / a) */
-
- b = ~b; /* 1 - b */
- if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
- return MASK; /* 1 */
- return DIV_UN8 (b, a); /* (1-b) / a */
-}
-
-/* portion covered by both a and b */
-static uint8_t
-combine_disjoint_in_part (uint8_t a, uint8_t b)
-{
- /* max (1-(1-b)/a,0) */
- /* = - min ((1-b)/a - 1, 0) */
- /* = 1 - min (1, (1-b)/a) */
-
- b = ~b; /* 1 - b */
- if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
- return 0; /* 1 - 1 */
- return ~DIV_UN8(b, a); /* 1 - (1-b) / a */
-}
-
-/* portion covered by a but not b */
-static uint8_t
-combine_conjoint_out_part (uint8_t a, uint8_t b)
-{
- /* max (1-b/a,0) */
- /* = 1-min(b/a,1) */
-
- /* min (1, (1-b) / a) */
-
- if (b >= a) /* b >= a -> b/a >= 1 */
- return 0x00; /* 0 */
- return ~DIV_UN8(b, a); /* 1 - b/a */
-}
-
-/* portion covered by both a and b */
-static uint8_t
-combine_conjoint_in_part (uint8_t a, uint8_t b)
-{
- /* min (1,b/a) */
-
- if (b >= a) /* b >= a -> b/a >= 1 */
- return MASK; /* 1 */
- return DIV_UN8 (b, a); /* b/a */
-}
-
-#define GET_COMP(v, i) ((uint16_t) (uint8_t) ((v) >> i))
-
-#define ADD(x, y, i, t) \
- ((t) = GET_COMP (x, i) + GET_COMP (y, i), \
- (uint32_t) ((uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
-
-#define GENERIC(x, y, i, ax, ay, t, u, v) \
- ((t) = (MUL_UN8 (GET_COMP (y, i), ay, (u)) + \
- MUL_UN8 (GET_COMP (x, i), ax, (v))), \
- (uint32_t) ((uint8_t) ((t) | \
- (0 - ((t) >> G_SHIFT)))) << (i))
-
-static void
-combine_disjoint_general_u (uint32_t * dest,
- const uint32_t *src,
- const uint32_t *mask,
- int width,
- uint8_t combine)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = combine_mask (src, mask, i);
- uint32_t d = *(dest + i);
- uint32_t m, n, o, p;
- uint16_t Fa, Fb, t, u, v;
- uint8_t sa = s >> A_SHIFT;
- uint8_t da = d >> A_SHIFT;
-
- switch (combine & COMBINE_A)
- {
- default:
- Fa = 0;
- break;
-
- case COMBINE_A_OUT:
- Fa = combine_disjoint_out_part (sa, da);
- break;
-
- case COMBINE_A_IN:
- Fa = combine_disjoint_in_part (sa, da);
- break;
-
- case COMBINE_A:
- Fa = MASK;
- break;
- }
-
- switch (combine & COMBINE_B)
- {
- default:
- Fb = 0;
- break;
-
- case COMBINE_B_OUT:
- Fb = combine_disjoint_out_part (da, sa);
- break;
-
- case COMBINE_B_IN:
- Fb = combine_disjoint_in_part (da, sa);
- break;
-
- case COMBINE_B:
- Fb = MASK;
- break;
- }
- m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
- n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
- o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
- p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
- s = m | n | o | p;
- *(dest + i) = s;
- }
-}
-
-static void
-combine_disjoint_over_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = combine_mask (src, mask, i);
- uint16_t a = s >> A_SHIFT;
-
- if (s != 0x00)
- {
- uint32_t d = *(dest + i);
- a = combine_disjoint_out_part (d >> A_SHIFT, a);
- UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s);
-
- *(dest + i) = d;
- }
- }
-}
-
-static void
-combine_disjoint_in_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
-}
-
-static void
-combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
-}
-
-static void
-combine_disjoint_out_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
-}
-
-static void
-combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
-}
-
-static void
-combine_disjoint_atop_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
-}
-
-static void
-combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
-}
-
-static void
-combine_disjoint_xor_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
-}
-
-static void
-combine_conjoint_general_u (uint32_t * dest,
- const uint32_t *src,
- const uint32_t *mask,
- int width,
- uint8_t combine)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = combine_mask (src, mask, i);
- uint32_t d = *(dest + i);
- uint32_t m, n, o, p;
- uint16_t Fa, Fb, t, u, v;
- uint8_t sa = s >> A_SHIFT;
- uint8_t da = d >> A_SHIFT;
-
- switch (combine & COMBINE_A)
- {
- default:
- Fa = 0;
- break;
-
- case COMBINE_A_OUT:
- Fa = combine_conjoint_out_part (sa, da);
- break;
-
- case COMBINE_A_IN:
- Fa = combine_conjoint_in_part (sa, da);
- break;
-
- case COMBINE_A:
- Fa = MASK;
- break;
- }
-
- switch (combine & COMBINE_B)
- {
- default:
- Fb = 0;
- break;
-
- case COMBINE_B_OUT:
- Fb = combine_conjoint_out_part (da, sa);
- break;
-
- case COMBINE_B_IN:
- Fb = combine_conjoint_in_part (da, sa);
- break;
-
- case COMBINE_B:
- Fb = MASK;
- break;
- }
-
- m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
- n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
- o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
- p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
-
- s = m | n | o | p;
-
- *(dest + i) = s;
- }
-}
-
-static void
-combine_conjoint_over_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
-}
-
-static void
-combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
-}
-
-static void
-combine_conjoint_in_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
-}
-
-static void
-combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
-}
-
-static void
-combine_conjoint_out_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
-}
-
-static void
-combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
-}
-
-static void
-combine_conjoint_atop_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
-}
-
-static void
-combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
-}
-
-static void
-combine_conjoint_xor_u (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
-}
-
-
/* Component alpha combiners */
static void
@@ -2032,428 +1136,6 @@ combine_add_ca (pixman_implementation_t *imp,
}
}
-static void
-combine_saturate_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s, d;
- uint16_t sa, sr, sg, sb, da;
- uint16_t t, u, v;
- uint32_t m, n, o, p;
-
- d = *(dest + i);
- s = *(src + i);
- m = *(mask + i);
-
- combine_mask_ca (&s, &m);
-
- sa = (m >> A_SHIFT);
- sr = (m >> R_SHIFT) & MASK;
- sg = (m >> G_SHIFT) & MASK;
- sb = m & MASK;
- da = ~d >> A_SHIFT;
-
- if (sb <= da)
- m = ADD (s, d, 0, t);
- else
- m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
-
- if (sg <= da)
- n = ADD (s, d, G_SHIFT, t);
- else
- n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
-
- if (sr <= da)
- o = ADD (s, d, R_SHIFT, t);
- else
- o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
-
- if (sa <= da)
- p = ADD (s, d, A_SHIFT, t);
- else
- p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
-
- *(dest + i) = m | n | o | p;
- }
-}
-
-static void
-combine_disjoint_general_ca (uint32_t * dest,
- const uint32_t *src,
- const uint32_t *mask,
- int width,
- uint8_t combine)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s, d;
- uint32_t m, n, o, p;
- uint32_t Fa, Fb;
- uint16_t t, u, v;
- uint32_t sa;
- uint8_t da;
-
- s = *(src + i);
- m = *(mask + i);
- d = *(dest + i);
- da = d >> A_SHIFT;
-
- combine_mask_ca (&s, &m);
-
- sa = m;
-
- switch (combine & COMBINE_A)
- {
- default:
- Fa = 0;
- break;
-
- case COMBINE_A_OUT:
- m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da);
- n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
- o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
- p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
- Fa = m | n | o | p;
- break;
-
- case COMBINE_A_IN:
- m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da);
- n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
- o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
- p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
- Fa = m | n | o | p;
- break;
-
- case COMBINE_A:
- Fa = ~0;
- break;
- }
-
- switch (combine & COMBINE_B)
- {
- default:
- Fb = 0;
- break;
-
- case COMBINE_B_OUT:
- m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0));
- n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
- o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
- p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
- Fb = m | n | o | p;
- break;
-
- case COMBINE_B_IN:
- m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0));
- n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
- o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
- p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
- Fb = m | n | o | p;
- break;
-
- case COMBINE_B:
- Fb = ~0;
- break;
- }
- m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
- n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
- o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
- p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
-
- s = m | n | o | p;
-
- *(dest + i) = s;
- }
-}
-
-static void
-combine_disjoint_over_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
-}
-
-static void
-combine_disjoint_in_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
-}
-
-static void
-combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
-}
-
-static void
-combine_disjoint_out_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
-}
-
-static void
-combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
-}
-
-static void
-combine_disjoint_atop_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
-}
-
-static void
-combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
-}
-
-static void
-combine_disjoint_xor_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
-}
-
-static void
-combine_conjoint_general_ca (uint32_t * dest,
- const uint32_t *src,
- const uint32_t *mask,
- int width,
- uint8_t combine)
-{
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s, d;
- uint32_t m, n, o, p;
- uint32_t Fa, Fb;
- uint16_t t, u, v;
- uint32_t sa;
- uint8_t da;
-
- s = *(src + i);
- m = *(mask + i);
- d = *(dest + i);
- da = d >> A_SHIFT;
-
- combine_mask_ca (&s, &m);
-
- sa = m;
-
- switch (combine & COMBINE_A)
- {
- default:
- Fa = 0;
- break;
-
- case COMBINE_A_OUT:
- m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da);
- n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
- o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
- p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
- Fa = m | n | o | p;
- break;
-
- case COMBINE_A_IN:
- m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da);
- n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
- o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
- p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
- Fa = m | n | o | p;
- break;
-
- case COMBINE_A:
- Fa = ~0;
- break;
- }
-
- switch (combine & COMBINE_B)
- {
- default:
- Fb = 0;
- break;
-
- case COMBINE_B_OUT:
- m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0));
- n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
- o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
- p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
- Fb = m | n | o | p;
- break;
-
- case COMBINE_B_IN:
- m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0));
- n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
- o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
- p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
- Fb = m | n | o | p;
- break;
-
- case COMBINE_B:
- Fb = ~0;
- break;
- }
- m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
- n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
- o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
- p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
-
- s = m | n | o | p;
-
- *(dest + i) = s;
- }
-}
-
-static void
-combine_conjoint_over_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
-}
-
-static void
-combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
-}
-
-static void
-combine_conjoint_in_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
-}
-
-static void
-combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
-}
-
-static void
-combine_conjoint_out_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
-}
-
-static void
-combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
-}
-
-static void
-combine_conjoint_atop_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
-}
-
-static void
-combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
-}
-
-static void
-combine_conjoint_xor_ca (pixman_implementation_t *imp,
- pixman_op_t op,
- uint32_t * dest,
- const uint32_t * src,
- const uint32_t * mask,
- int width)
-{
- combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
-}
-
void
_pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
{
@@ -2471,51 +1153,15 @@ _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u;
imp->combine_32[PIXMAN_OP_ADD] = combine_add_u;
- imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u;
-
- /* Disjoint, unified */
- imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
- imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst;
- imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
- imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
-
- /* Conjoint, unified */
- imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
- imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst;
- imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
- imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u;
imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u;
imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u;
imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
- imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
- imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
- imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
- imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
- imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
- imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
- imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
/* Component alpha combiners */
imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
@@ -2531,51 +1177,13 @@ _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca;
imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca;
- imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
-
- /* Disjoint CA */
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
-
- /* Conjoint CA */
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
- imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
- imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
- imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
- imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
-
- /* It is not clear that these make sense, so make them noops for now */
- imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
- imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
- imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
- imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;
}
diff --git a/lib/pixman/pixman/pixman-fast-path.c b/lib/pixman/pixman/pixman-fast-path.c
index c6e43de10..53d4a1f90 100644
--- a/lib/pixman/pixman/pixman-fast-path.c
+++ b/lib/pixman/pixman/pixman-fast-path.c
@@ -2343,6 +2343,8 @@ fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
int32_t dist_y;
int i;
+ COMPILE_TIME_ASSERT (BILINEAR_INTERPOLATION_BITS < 8);
+
fx = info->x;
ux = iter->image->common.transform->matrix[0][0];
diff --git a/lib/pixman/pixman/pixman-general.c b/lib/pixman/pixman/pixman-general.c
index f82ea7d71..6141cb0a3 100644
--- a/lib/pixman/pixman/pixman-general.c
+++ b/lib/pixman/pixman/pixman-general.c
@@ -109,6 +109,20 @@ static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
#define SCANLINE_BUFFER_LENGTH 8192
+static pixman_bool_t
+operator_needs_division (pixman_op_t op)
+{
+ static const uint8_t needs_division[] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* SATURATE */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* DISJOINT */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* CONJOINT */
+ 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, /* blend ops */
+ };
+
+ return needs_division[op];
+}
+
static void
general_composite_rect (pixman_implementation_t *imp,
pixman_composite_info_t *info)
@@ -124,9 +138,10 @@ general_composite_rect (pixman_implementation_t *imp,
int Bpp;
int i;
- if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
- (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
- (dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
+ if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
+ (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
+ (dest_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
+ !(operator_needs_division (op)))
{
width_flag = ITER_NARROW;
Bpp = 4;
@@ -143,9 +158,9 @@ general_composite_rect (pixman_implementation_t *imp,
if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3))
return;
- if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 32 * 3)
+ if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 15 * 3)
{
- scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 32 * 3);
+ scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 15 * 3);
if (!scanline_buffer)
return;
@@ -181,11 +196,7 @@ general_composite_rect (pixman_implementation_t *imp,
mask_image = NULL;
}
- component_alpha =
- mask_image &&
- mask_image->common.type == BITS &&
- mask_image->common.component_alpha &&
- PIXMAN_FORMAT_RGB (mask_image->bits.format);
+ component_alpha = mask_image && mask_image->common.component_alpha;
_pixman_implementation_iter_init (
imp->toplevel, &mask_iter,
diff --git a/lib/pixman/pixman/pixman-gradient-walker.c b/lib/pixman/pixman/pixman-gradient-walker.c
index 5944a559a..822f8e62b 100644
--- a/lib/pixman/pixman/pixman-gradient-walker.c
+++ b/lib/pixman/pixman/pixman-gradient-walker.c
@@ -54,7 +54,7 @@ static void
gradient_walker_reset (pixman_gradient_walker_t *walker,
pixman_fixed_48_16_t pos)
{
- int32_t x, left_x, right_x;
+ int64_t x, left_x, right_x;
pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
pixman_gradient_stop_t *stops = walker->stops;
diff --git a/lib/pixman/pixman/pixman-implementation.c b/lib/pixman/pixman/pixman-implementation.c
index 588405451..2c7de4c68 100644
--- a/lib/pixman/pixman/pixman-implementation.c
+++ b/lib/pixman/pixman/pixman-implementation.c
@@ -380,6 +380,11 @@ _pixman_disabled (const char *name)
return FALSE;
}
+static const pixman_fast_path_t empty_fast_path[] =
+{
+ { PIXMAN_OP_NONE }
+};
+
pixman_implementation_t *
_pixman_choose_implementation (void)
{
@@ -397,5 +402,16 @@ _pixman_choose_implementation (void)
imp = _pixman_implementation_create_noop (imp);
+ if (_pixman_disabled ("wholeops"))
+ {
+ pixman_implementation_t *cur;
+
+ /* Disable all whole-operation paths except the general one,
+ * so that optimized iterators are used as much as possible.
+ */
+ for (cur = imp; cur->fallback; cur = cur->fallback)
+ cur->fast_paths = empty_fast_path;
+ }
+
return imp;
}
diff --git a/lib/pixman/pixman/pixman-inlines.h b/lib/pixman/pixman/pixman-inlines.h
index dd1c2f17f..1c8441d6d 100644
--- a/lib/pixman/pixman/pixman-inlines.h
+++ b/lib/pixman/pixman/pixman-inlines.h
@@ -747,7 +747,8 @@ fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp,
#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH(op,s,d,func) \
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_COVER (op,s,d,func), \
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NONE (op,s,d,func), \
- SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD (op,s,d,func)
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD (op,s,d,func), \
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (op,s,d,func)
/*****************************************************************************/
diff --git a/lib/pixman/pixman/pixman-mips-dspr2-asm.S b/lib/pixman/pixman/pixman-mips-dspr2-asm.S
index 866e93e58..9dad163b7 100644
--- a/lib/pixman/pixman/pixman-mips-dspr2-asm.S
+++ b/lib/pixman/pixman/pixman-mips-dspr2-asm.S
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Author: Nemanja Lukic (nlukic@mips.com)
+ * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
*/
#include "pixman-private.h"
diff --git a/lib/pixman/pixman/pixman-mips-dspr2-asm.h b/lib/pixman/pixman/pixman-mips-dspr2-asm.h
index 11849bd66..e23856619 100644
--- a/lib/pixman/pixman/pixman-mips-dspr2-asm.h
+++ b/lib/pixman/pixman/pixman-mips-dspr2-asm.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Author: Nemanja Lukic (nlukic@mips.com)
+ * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
*/
#ifndef PIXMAN_MIPS_DSPR2_ASM_H
@@ -72,10 +72,8 @@
#define LEAF_MIPS32R2(symbol) \
.globl symbol; \
.align 2; \
-#ifdef __ELF__
.hidden symbol; \
.type symbol, @function; \
-#endif
.ent symbol, 0; \
symbol: .frame sp, 0, ra; \
.set push; \
diff --git a/lib/pixman/pixman/pixman-mips-dspr2.c b/lib/pixman/pixman/pixman-mips-dspr2.c
index e10c9df0a..87969ae70 100644
--- a/lib/pixman/pixman/pixman-mips-dspr2.c
+++ b/lib/pixman/pixman/pixman-mips-dspr2.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Author: Nemanja Lukic (nlukic@mips.com)
+ * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
*/
#ifdef HAVE_CONFIG_H
@@ -388,11 +388,11 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] =
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, mips_0565_8888),
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, mips_0565_8888),
- PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_8_0565),
- PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_8_0565),
+ SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_8_0565),
+ SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_8_0565),
- PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, mips_0565_8_0565),
- PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, mips_0565_8_0565),
+ SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, mips_0565_8_0565),
+ SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, mips_0565_8_0565),
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8888),
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8888),
diff --git a/lib/pixman/pixman/pixman-mips-dspr2.h b/lib/pixman/pixman/pixman-mips-dspr2.h
index 955ed70b8..57b38359e 100644
--- a/lib/pixman/pixman/pixman-mips-dspr2.h
+++ b/lib/pixman/pixman/pixman-mips-dspr2.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Author: Nemanja Lukic (nlukic@mips.com)
+ * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
*/
#ifndef PIXMAN_MIPS_DSPR2_H
@@ -328,12 +328,6 @@ FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_pad_##op, \
scaled_nearest_scanline_mips_##name##_##op, \
src_type, uint8_t, dst_type, PAD, TRUE, FALSE)
-/* Provide entries for the fast path table */
-#define PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func), \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func), \
- SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func)
-
/****************************************************************************/
#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \
diff --git a/lib/pixman/pixman/pixman-mmx.c b/lib/pixman/pixman/pixman-mmx.c
index f9a92ce09..dec397432 100644
--- a/lib/pixman/pixman/pixman-mmx.c
+++ b/lib/pixman/pixman/pixman-mmx.c
@@ -89,21 +89,7 @@ _mm_mulhi_pu16 (__m64 __A, __m64 __B)
return __A;
}
-# ifdef __OPTIMIZE__
-extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_shuffle_pi16 (__m64 __A, int8_t const __N)
-{
- __m64 ret;
-
- asm ("pshufw %2, %1, %0\n\t"
- : "=y" (ret)
- : "y" (__A), "K" (__N)
- );
-
- return ret;
-}
-# else
-# define _mm_shuffle_pi16(A, N) \
+# define _mm_shuffle_pi16(A, N) \
({ \
__m64 ret; \
\
@@ -114,7 +100,6 @@ _mm_shuffle_pi16 (__m64 __A, int8_t const __N)
\
ret; \
})
-# endif
# endif
#endif
@@ -3555,6 +3540,105 @@ mmx_composite_over_reverse_n_8888 (pixman_implementation_t *imp,
_mm_empty ();
}
+static force_inline void
+scaled_nearest_scanline_mmx_8888_8888_OVER (uint32_t* pd,
+ const uint32_t* ps,
+ int32_t w,
+ pixman_fixed_t vx,
+ pixman_fixed_t unit_x,
+ pixman_fixed_t src_width_fixed,
+ pixman_bool_t fully_transparent_src)
+{
+ if (fully_transparent_src)
+ return;
+
+ while (w)
+ {
+ __m64 d = load (pd);
+ __m64 s = load (ps + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+
+ store8888 (pd, core_combine_over_u_pixel_mmx (s, d));
+ pd++;
+
+ w--;
+ }
+
+ _mm_empty ();
+}
+
+FAST_NEAREST_MAINLOOP (mmx_8888_8888_cover_OVER,
+ scaled_nearest_scanline_mmx_8888_8888_OVER,
+ uint32_t, uint32_t, COVER)
+FAST_NEAREST_MAINLOOP (mmx_8888_8888_none_OVER,
+ scaled_nearest_scanline_mmx_8888_8888_OVER,
+ uint32_t, uint32_t, NONE)
+FAST_NEAREST_MAINLOOP (mmx_8888_8888_pad_OVER,
+ scaled_nearest_scanline_mmx_8888_8888_OVER,
+ uint32_t, uint32_t, PAD)
+FAST_NEAREST_MAINLOOP (mmx_8888_8888_normal_OVER,
+ scaled_nearest_scanline_mmx_8888_8888_OVER,
+ uint32_t, uint32_t, NORMAL)
+
+static force_inline void
+scaled_nearest_scanline_mmx_8888_n_8888_OVER (const uint32_t * mask,
+ uint32_t * dst,
+ const uint32_t * src,
+ int32_t w,
+ pixman_fixed_t vx,
+ pixman_fixed_t unit_x,
+ pixman_fixed_t src_width_fixed,
+ pixman_bool_t zero_src)
+{
+ __m64 mm_mask;
+
+ if (zero_src || (*mask >> 24) == 0)
+ {
+ /* A workaround for https://gcc.gnu.org/PR47759 */
+ _mm_empty ();
+ return;
+ }
+
+ mm_mask = expand_alpha (load8888 (mask));
+
+ while (w)
+ {
+ uint32_t s = *(src + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+
+ if (s)
+ {
+ __m64 ms = load8888 (&s);
+ __m64 alpha = expand_alpha (ms);
+ __m64 dest = load8888 (dst);
+
+ store8888 (dst, (in_over (ms, alpha, mm_mask, dest)));
+ }
+
+ dst++;
+ w--;
+ }
+
+ _mm_empty ();
+}
+
+FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_cover_OVER,
+ scaled_nearest_scanline_mmx_8888_n_8888_OVER,
+ uint32_t, uint32_t, uint32_t, COVER, TRUE, TRUE)
+FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_pad_OVER,
+ scaled_nearest_scanline_mmx_8888_n_8888_OVER,
+ uint32_t, uint32_t, uint32_t, PAD, TRUE, TRUE)
+FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_none_OVER,
+ scaled_nearest_scanline_mmx_8888_n_8888_OVER,
+ uint32_t, uint32_t, uint32_t, NONE, TRUE, TRUE)
+FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_normal_OVER,
+ scaled_nearest_scanline_mmx_8888_n_8888_OVER,
+ uint32_t, uint32_t, uint32_t, NORMAL, TRUE, TRUE)
+
#define BSHIFT ((1 << BILINEAR_INTERPOLATION_BITS))
#define BMSK (BSHIFT - 1)
@@ -3995,6 +4079,16 @@ static const pixman_fast_path_t mmx_fast_paths[] =
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 ),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_8888 ),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_8888 ),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_8888 ),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_8888 ),
+
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_n_8888 ),
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_n_8888 ),
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_n_8888 ),
+ SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_n_8888 ),
+
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mmx_8888_8888 ),
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mmx_8888_8888 ),
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mmx_8888_8888 ),
diff --git a/lib/pixman/pixman/pixman-private.h b/lib/pixman/pixman/pixman-private.h
index 6ca13b216..73108a01d 100644
--- a/lib/pixman/pixman/pixman-private.h
+++ b/lib/pixman/pixman/pixman-private.h
@@ -7,7 +7,7 @@
* The defines which are shared between C and assembly code
*/
-/* bilinear interpolation precision (must be <= 8) */
+/* bilinear interpolation precision (must be < 8) */
#define BILINEAR_INTERPOLATION_BITS 7
#define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS)
@@ -345,8 +345,8 @@ typedef struct
float r_s, r_b;
float g_s, g_b;
float b_s, b_b;
- pixman_fixed_t left_x;
- pixman_fixed_t right_x;
+ pixman_fixed_48_16_t left_x;
+ pixman_fixed_48_16_t right_x;
pixman_gradient_stop_t *stops;
int num_stops;
diff --git a/lib/pixman/pixman/pixman-sse2.c b/lib/pixman/pixman/pixman-sse2.c
index a6e780815..895510372 100644
--- a/lib/pixman/pixman/pixman-sse2.c
+++ b/lib/pixman/pixman/pixman-sse2.c
@@ -6274,31 +6274,15 @@ static const pixman_fast_path_t sse2_fast_paths[] =
PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, sse2_composite_in_n_8_8),
PIXMAN_STD_FAST_PATH (IN, solid, null, a8, sse2_composite_in_n_8),
- SIMPLE_NEAREST_FAST_PATH_COVER (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_COVER (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_COVER (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_COVER (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NONE (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NONE (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NONE (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NONE (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_PAD (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
- SIMPLE_NEAREST_FAST_PATH_NORMAL (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888),
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888),
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888),
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888),
SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888),
- SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888),
- SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888),
- SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888),
- SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888),
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, sse2_8888_8888),
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, sse2_8888_8888),
diff --git a/lib/pixman/pixman/pixman-vmx.c b/lib/pixman/pixman/pixman-vmx.c
index c33631c0e..41efdcfa1 100644
--- a/lib/pixman/pixman/pixman-vmx.c
+++ b/lib/pixman/pixman/pixman-vmx.c
@@ -30,17 +30,41 @@
#endif
#include "pixman-private.h"
#include "pixman-combine32.h"
+#include "pixman-inlines.h"
#include <altivec.h>
#define AVV(x...) {x}
+static vector unsigned int mask_ff000000;
+static vector unsigned int mask_red;
+static vector unsigned int mask_green;
+static vector unsigned int mask_blue;
+static vector unsigned int mask_565_fix_rb;
+static vector unsigned int mask_565_fix_g;
+
static force_inline vector unsigned int
splat_alpha (vector unsigned int pix)
{
+#ifdef WORDS_BIGENDIAN
return vec_perm (pix, pix,
(vector unsigned char)AVV (
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C));
+#else
+ return vec_perm (pix, pix,
+ (vector unsigned char)AVV (
+ 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07,
+ 0x0B, 0x0B, 0x0B, 0x0B, 0x0F, 0x0F, 0x0F, 0x0F));
+#endif
+}
+
+static force_inline vector unsigned int
+splat_pixel (vector unsigned int pix)
+{
+ return vec_perm (pix, pix,
+ (vector unsigned char)AVV (
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03));
}
static force_inline vector unsigned int
@@ -50,12 +74,22 @@ pix_multiply (vector unsigned int p, vector unsigned int a)
/* unpack to short */
hi = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
vec_mergeh ((vector unsigned char)AVV (0),
(vector unsigned char)p);
+#else
+ vec_mergeh ((vector unsigned char) p,
+ (vector unsigned char) AVV (0));
+#endif
mod = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
vec_mergeh ((vector unsigned char)AVV (0),
(vector unsigned char)a);
+#else
+ vec_mergeh ((vector unsigned char) a,
+ (vector unsigned char) AVV (0));
+#endif
hi = vec_mladd (hi, mod, (vector unsigned short)
AVV (0x0080, 0x0080, 0x0080, 0x0080,
@@ -67,11 +101,22 @@ pix_multiply (vector unsigned int p, vector unsigned int a)
/* unpack to short */
lo = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
vec_mergel ((vector unsigned char)AVV (0),
(vector unsigned char)p);
+#else
+ vec_mergel ((vector unsigned char) p,
+ (vector unsigned char) AVV (0));
+#endif
+
mod = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
vec_mergel ((vector unsigned char)AVV (0),
(vector unsigned char)a);
+#else
+ vec_mergel ((vector unsigned char) a,
+ (vector unsigned char) AVV (0));
+#endif
lo = vec_mladd (lo, mod, (vector unsigned short)
AVV (0x0080, 0x0080, 0x0080, 0x0080,
@@ -129,6 +174,7 @@ over (vector unsigned int src,
over (pix_multiply (src, mask), \
pix_multiply (srca, mask), dest)
+#ifdef WORDS_BIGENDIAN
#define COMPUTE_SHIFT_MASK(source) \
source ## _mask = vec_lvsl (0, source);
@@ -140,36 +186,305 @@ over (vector unsigned int src,
mask ## _mask = vec_lvsl (0, mask); \
source ## _mask = vec_lvsl (0, source);
-/* notice you have to declare temp vars...
- * Note: tmp3 and tmp4 must remain untouched!
- */
-
-#define LOAD_VECTORS(dest, source) \
+#define LOAD_VECTOR(source) \
+do \
+{ \
+ vector unsigned char tmp1, tmp2; \
tmp1 = (typeof(tmp1))vec_ld (0, source); \
tmp2 = (typeof(tmp2))vec_ld (15, source); \
- v ## source = (typeof(v ## source)) \
+ v ## source = (typeof(v ## source)) \
vec_perm (tmp1, tmp2, source ## _mask); \
- v ## dest = (typeof(v ## dest))vec_ld (0, dest);
+} while (0)
-#define LOAD_VECTORSC(dest, source, mask) \
- tmp1 = (typeof(tmp1))vec_ld (0, source); \
- tmp2 = (typeof(tmp2))vec_ld (15, source); \
- v ## source = (typeof(v ## source)) \
- vec_perm (tmp1, tmp2, source ## _mask); \
- tmp1 = (typeof(tmp1))vec_ld (0, mask); \
+#define LOAD_VECTORS(dest, source) \
+do \
+{ \
+ LOAD_VECTOR(source); \
v ## dest = (typeof(v ## dest))vec_ld (0, dest); \
- tmp2 = (typeof(tmp2))vec_ld (15, mask); \
- v ## mask = (typeof(v ## mask)) \
- vec_perm (tmp1, tmp2, mask ## _mask);
+} while (0)
+
+#define LOAD_VECTORSC(dest, source, mask) \
+do \
+{ \
+ LOAD_VECTORS(dest, source); \
+ LOAD_VECTOR(mask); \
+} while (0)
+
+#define DECLARE_SRC_MASK_VAR vector unsigned char src_mask
+#define DECLARE_MASK_MASK_VAR vector unsigned char mask_mask
+
+#else
+
+/* Now the COMPUTE_SHIFT_{MASK, MASKS, MASKC} below are just no-op.
+ * They are defined that way because little endian altivec can do unaligned
+ * reads natively and have no need for constructing the permutation pattern
+ * variables.
+ */
+#define COMPUTE_SHIFT_MASK(source)
+
+#define COMPUTE_SHIFT_MASKS(dest, source)
+
+#define COMPUTE_SHIFT_MASKC(dest, source, mask)
+
+# define LOAD_VECTOR(source) \
+ v ## source = *((typeof(v ## source)*)source);
+
+# define LOAD_VECTORS(dest, source) \
+ LOAD_VECTOR(source); \
+ LOAD_VECTOR(dest); \
+
+# define LOAD_VECTORSC(dest, source, mask) \
+ LOAD_VECTORS(dest, source); \
+ LOAD_VECTOR(mask); \
+
+#define DECLARE_SRC_MASK_VAR
+#define DECLARE_MASK_MASK_VAR
+
+#endif /* WORDS_BIGENDIAN */
#define LOAD_VECTORSM(dest, source, mask) \
- LOAD_VECTORSC (dest, source, mask) \
+ LOAD_VECTORSC (dest, source, mask); \
v ## source = pix_multiply (v ## source, \
splat_alpha (v ## mask));
#define STORE_VECTOR(dest) \
vec_st ((vector unsigned int) v ## dest, 0, dest);
+/* load 4 pixels from a 16-byte boundary aligned address */
+static force_inline vector unsigned int
+load_128_aligned (const uint32_t* src)
+{
+ return *((vector unsigned int *) src);
+}
+
+/* load 4 pixels from a unaligned address */
+static force_inline vector unsigned int
+load_128_unaligned (const uint32_t* src)
+{
+ vector unsigned int vsrc;
+ DECLARE_SRC_MASK_VAR;
+
+ COMPUTE_SHIFT_MASK (src);
+ LOAD_VECTOR (src);
+
+ return vsrc;
+}
+
+/* save 4 pixels on a 16-byte boundary aligned address */
+static force_inline void
+save_128_aligned (uint32_t* data,
+ vector unsigned int vdata)
+{
+ STORE_VECTOR(data)
+}
+
+static force_inline vector unsigned int
+create_mask_1x32_128 (const uint32_t *src)
+{
+ vector unsigned int vsrc;
+ DECLARE_SRC_MASK_VAR;
+
+ COMPUTE_SHIFT_MASK (src);
+ LOAD_VECTOR (src);
+ return vec_splat(vsrc, 0);
+}
+
+static force_inline vector unsigned int
+create_mask_32_128 (uint32_t mask)
+{
+ return create_mask_1x32_128(&mask);
+}
+
+static force_inline vector unsigned int
+unpacklo_128_16x8 (vector unsigned int data1, vector unsigned int data2)
+{
+ vector unsigned char lo;
+
+ /* unpack to short */
+ lo = (vector unsigned char)
+#ifdef WORDS_BIGENDIAN
+ vec_mergel ((vector unsigned char) data2,
+ (vector unsigned char) data1);
+#else
+ vec_mergel ((vector unsigned char) data1,
+ (vector unsigned char) data2);
+#endif
+
+ return (vector unsigned int) lo;
+}
+
+static force_inline vector unsigned int
+unpackhi_128_16x8 (vector unsigned int data1, vector unsigned int data2)
+{
+ vector unsigned char hi;
+
+ /* unpack to short */
+ hi = (vector unsigned char)
+#ifdef WORDS_BIGENDIAN
+ vec_mergeh ((vector unsigned char) data2,
+ (vector unsigned char) data1);
+#else
+ vec_mergeh ((vector unsigned char) data1,
+ (vector unsigned char) data2);
+#endif
+
+ return (vector unsigned int) hi;
+}
+
+static force_inline vector unsigned int
+unpacklo_128_8x16 (vector unsigned int data1, vector unsigned int data2)
+{
+ vector unsigned short lo;
+
+ /* unpack to char */
+ lo = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
+ vec_mergel ((vector unsigned short) data2,
+ (vector unsigned short) data1);
+#else
+ vec_mergel ((vector unsigned short) data1,
+ (vector unsigned short) data2);
+#endif
+
+ return (vector unsigned int) lo;
+}
+
+static force_inline vector unsigned int
+unpackhi_128_8x16 (vector unsigned int data1, vector unsigned int data2)
+{
+ vector unsigned short hi;
+
+ /* unpack to char */
+ hi = (vector unsigned short)
+#ifdef WORDS_BIGENDIAN
+ vec_mergeh ((vector unsigned short) data2,
+ (vector unsigned short) data1);
+#else
+ vec_mergeh ((vector unsigned short) data1,
+ (vector unsigned short) data2);
+#endif
+
+ return (vector unsigned int) hi;
+}
+
+static force_inline void
+unpack_128_2x128 (vector unsigned int data1, vector unsigned int data2,
+ vector unsigned int* data_lo, vector unsigned int* data_hi)
+{
+ *data_lo = unpacklo_128_16x8(data1, data2);
+ *data_hi = unpackhi_128_16x8(data1, data2);
+}
+
+static force_inline void
+unpack_128_2x128_16 (vector unsigned int data1, vector unsigned int data2,
+ vector unsigned int* data_lo, vector unsigned int* data_hi)
+{
+ *data_lo = unpacklo_128_8x16(data1, data2);
+ *data_hi = unpackhi_128_8x16(data1, data2);
+}
+
+static force_inline vector unsigned int
+unpack_565_to_8888 (vector unsigned int lo)
+{
+ vector unsigned int r, g, b, rb, t;
+
+ r = vec_and (vec_sl(lo, create_mask_32_128(8)), mask_red);
+ g = vec_and (vec_sl(lo, create_mask_32_128(5)), mask_green);
+ b = vec_and (vec_sl(lo, create_mask_32_128(3)), mask_blue);
+
+ rb = vec_or (r, b);
+ t = vec_and (rb, mask_565_fix_rb);
+ t = vec_sr (t, create_mask_32_128(5));
+ rb = vec_or (rb, t);
+
+ t = vec_and (g, mask_565_fix_g);
+ t = vec_sr (t, create_mask_32_128(6));
+ g = vec_or (g, t);
+
+ return vec_or (rb, g);
+}
+
+static force_inline int
+is_opaque (vector unsigned int x)
+{
+ uint32_t cmp_result;
+ vector bool int ffs = vec_cmpeq(x, x);
+
+ cmp_result = vec_all_eq(x, ffs);
+
+ return (cmp_result & 0x8888) == 0x8888;
+}
+
+static force_inline int
+is_zero (vector unsigned int x)
+{
+ uint32_t cmp_result;
+
+ cmp_result = vec_all_eq(x, (vector unsigned int) AVV(0));
+
+ return cmp_result == 0xffff;
+}
+
+static force_inline int
+is_transparent (vector unsigned int x)
+{
+ uint32_t cmp_result;
+
+ cmp_result = vec_all_eq(x, (vector unsigned int) AVV(0));
+ return (cmp_result & 0x8888) == 0x8888;
+}
+
+static force_inline uint32_t
+core_combine_over_u_pixel_vmx (uint32_t src, uint32_t dst)
+{
+ uint32_t a;
+
+ a = ALPHA_8(src);
+
+ if (a == 0xff)
+ {
+ return src;
+ }
+ else if (src)
+ {
+ UN8x4_MUL_UN8_ADD_UN8x4(dst, (~a & MASK), src);
+ }
+
+ return dst;
+}
+
+static force_inline uint32_t
+combine1 (const uint32_t *ps, const uint32_t *pm)
+{
+ uint32_t s = *ps;
+
+ if (pm)
+ UN8x4_MUL_UN8(s, ALPHA_8(*pm));
+
+ return s;
+}
+
+static force_inline vector unsigned int
+combine4 (const uint32_t* ps, const uint32_t* pm)
+{
+ vector unsigned int src, msk;
+
+ if (pm)
+ {
+ msk = load_128_unaligned(pm);
+
+ if (is_transparent(msk))
+ return (vector unsigned int) AVV(0);
+ }
+
+ src = load_128_unaligned(ps);
+
+ if (pm)
+ src = pix_multiply(src, msk);
+
+ return src;
+}
+
static void
vmx_combine_over_u_no_mask (uint32_t * dest,
const uint32_t *src,
@@ -177,7 +492,7 @@ vmx_combine_over_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -227,7 +542,8 @@ vmx_combine_over_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -298,7 +614,7 @@ vmx_combine_over_reverse_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -346,7 +662,8 @@ vmx_combine_over_reverse_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -414,7 +731,7 @@ vmx_combine_in_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -459,7 +776,8 @@ vmx_combine_in_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -524,7 +842,7 @@ vmx_combine_in_reverse_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -571,7 +889,8 @@ vmx_combine_in_reverse_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -638,7 +957,7 @@ vmx_combine_out_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -685,7 +1004,8 @@ vmx_combine_out_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -750,7 +1070,7 @@ vmx_combine_out_reverse_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -798,7 +1118,8 @@ vmx_combine_out_reverse_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -865,7 +1186,7 @@ vmx_combine_atop_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -917,7 +1238,8 @@ vmx_combine_atop_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -993,7 +1315,7 @@ vmx_combine_atop_reverse_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1045,7 +1367,8 @@ vmx_combine_atop_reverse_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1121,7 +1444,7 @@ vmx_combine_xor_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1173,7 +1496,8 @@ vmx_combine_xor_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1249,7 +1573,7 @@ vmx_combine_add_u_no_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc;
- vector unsigned char tmp1, tmp2, src_mask;
+ DECLARE_SRC_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1295,7 +1619,8 @@ vmx_combine_add_u_mask (uint32_t * dest,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, src_mask, mask_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1363,7 +1688,8 @@ vmx_combine_src_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1413,7 +1739,8 @@ vmx_combine_over_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1471,7 +1798,8 @@ vmx_combine_over_reverse_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1527,7 +1855,8 @@ vmx_combine_in_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1581,7 +1910,8 @@ vmx_combine_in_reverse_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1636,7 +1966,8 @@ vmx_combine_out_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1693,7 +2024,8 @@ vmx_combine_out_reverse_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1750,7 +2082,8 @@ vmx_combine_atop_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask, vsrca;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1816,7 +2149,8 @@ vmx_combine_atop_reverse_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1879,7 +2213,8 @@ vmx_combine_xor_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1942,7 +2277,8 @@ vmx_combine_add_ca (pixman_implementation_t *imp,
{
int i;
vector unsigned int vdest, vsrc, vmask;
- vector unsigned char tmp1, tmp2, mask_mask, src_mask;
+ DECLARE_SRC_MASK_VAR;
+ DECLARE_MASK_MASK_VAR;
while (width && ((uintptr_t)dest & 15))
{
@@ -1986,16 +2322,809 @@ vmx_combine_add_ca (pixman_implementation_t *imp,
}
}
+static void
+vmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint32_t src, srca;
+ uint32_t *dst_line, *dst;
+ uint8_t *mask_line;
+ int dst_stride, mask_stride;
+ int32_t w;
+ uint32_t m, d, s, ia;
+
+ vector unsigned int vsrc, valpha, vmask, vdst;
+
+ src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
+
+ srca = ALPHA_8(src);
+ if (src == 0)
+ return;
+
+ PIXMAN_IMAGE_GET_LINE (
+ dest_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);
+
+ vsrc = (vector unsigned int) {src, src, src, src};
+ valpha = splat_alpha(vsrc);
+
+ while (height--)
+ {
+ const uint8_t *pm = mask_line;
+ dst = dst_line;
+ dst_line += dst_stride;
+ mask_line += mask_stride;
+ w = width;
+
+ while (w && (uintptr_t)dst & 15)
+ {
+ s = src;
+ m = *pm++;
+
+ if (m)
+ {
+ d = *dst;
+ UN8x4_MUL_UN8 (s, m);
+ ia = ALPHA_8 (~s);
+ UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
+ *dst = d;
+ }
+
+ w--;
+ dst++;
+ }
+
+ while (w >= 4)
+ {
+ m = *((uint32_t*)pm);
+
+ if (srca == 0xff && m == 0xffffffff)
+ {
+ save_128_aligned(dst, vsrc);
+ }
+ else if (m)
+ {
+ vmask = splat_pixel((vector unsigned int) {m, m, m, m});
+
+ /* dst is 16-byte aligned */
+ vdst = in_over (vsrc, valpha, vmask, load_128_aligned (dst));
+
+ save_128_aligned(dst, vdst);
+ }
+
+ w -= 4;
+ dst += 4;
+ pm += 4;
+ }
+
+ while (w)
+ {
+ s = src;
+ m = *pm++;
+
+ if (m)
+ {
+ d = *dst;
+ UN8x4_MUL_UN8 (s, m);
+ ia = ALPHA_8 (~s);
+ UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
+ *dst = d;
+ }
+
+ w--;
+ dst++;
+ }
+ }
+
+}
+
+static pixman_bool_t
+vmx_fill (pixman_implementation_t *imp,
+ uint32_t * bits,
+ int stride,
+ int bpp,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint32_t filler)
+{
+ uint32_t byte_width;
+ uint8_t *byte_line;
+
+ vector unsigned int vfiller;
+
+ if (bpp == 8)
+ {
+ uint8_t b;
+ uint16_t w;
+
+ stride = stride * (int) sizeof (uint32_t) / 1;
+ byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x);
+ byte_width = width;
+ stride *= 1;
+
+ b = filler & 0xff;
+ w = (b << 8) | b;
+ filler = (w << 16) | w;
+ }
+ else if (bpp == 16)
+ {
+ stride = stride * (int) sizeof (uint32_t) / 2;
+ byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
+ byte_width = 2 * width;
+ stride *= 2;
+
+ filler = (filler & 0xffff) * 0x00010001;
+ }
+ else if (bpp == 32)
+ {
+ stride = stride * (int) sizeof (uint32_t) / 4;
+ byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
+ byte_width = 4 * width;
+ stride *= 4;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ vfiller = create_mask_1x32_128(&filler);
+
+ while (height--)
+ {
+ int w;
+ uint8_t *d = byte_line;
+ byte_line += stride;
+ w = byte_width;
+
+ if (w >= 1 && ((uintptr_t)d & 1))
+ {
+ *(uint8_t *)d = filler;
+ w -= 1;
+ d += 1;
+ }
+
+ while (w >= 2 && ((uintptr_t)d & 3))
+ {
+ *(uint16_t *)d = filler;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 4 && ((uintptr_t)d & 15))
+ {
+ *(uint32_t *)d = filler;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 128)
+ {
+ vec_st(vfiller, 0, (uint32_t *) d);
+ vec_st(vfiller, 0, (uint32_t *) d + 4);
+ vec_st(vfiller, 0, (uint32_t *) d + 8);
+ vec_st(vfiller, 0, (uint32_t *) d + 12);
+ vec_st(vfiller, 0, (uint32_t *) d + 16);
+ vec_st(vfiller, 0, (uint32_t *) d + 20);
+ vec_st(vfiller, 0, (uint32_t *) d + 24);
+ vec_st(vfiller, 0, (uint32_t *) d + 28);
+
+ d += 128;
+ w -= 128;
+ }
+
+ if (w >= 64)
+ {
+ vec_st(vfiller, 0, (uint32_t *) d);
+ vec_st(vfiller, 0, (uint32_t *) d + 4);
+ vec_st(vfiller, 0, (uint32_t *) d + 8);
+ vec_st(vfiller, 0, (uint32_t *) d + 12);
+
+ d += 64;
+ w -= 64;
+ }
+
+ if (w >= 32)
+ {
+ vec_st(vfiller, 0, (uint32_t *) d);
+ vec_st(vfiller, 0, (uint32_t *) d + 4);
+
+ d += 32;
+ w -= 32;
+ }
+
+ if (w >= 16)
+ {
+ vec_st(vfiller, 0, (uint32_t *) d);
+
+ d += 16;
+ w -= 16;
+ }
+
+ while (w >= 4)
+ {
+ *(uint32_t *)d = filler;
+
+ w -= 4;
+ d += 4;
+ }
+
+ if (w >= 2)
+ {
+ *(uint16_t *)d = filler;
+ w -= 2;
+ d += 2;
+ }
+
+ if (w >= 1)
+ {
+ *(uint8_t *)d = filler;
+ w -= 1;
+ d += 1;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+vmx_composite_src_x888_8888 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint32_t *dst_line, *dst;
+ uint32_t *src_line, *src;
+ int32_t w;
+ int dst_stride, src_stride;
+
+ PIXMAN_IMAGE_GET_LINE (
+ dest_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);
+
+ while (height--)
+ {
+ dst = dst_line;
+ dst_line += dst_stride;
+ src = src_line;
+ src_line += src_stride;
+ w = width;
+
+ while (w && (uintptr_t)dst & 15)
+ {
+ *dst++ = *src++ | 0xff000000;
+ w--;
+ }
+
+ while (w >= 16)
+ {
+ vector unsigned int vmx_src1, vmx_src2, vmx_src3, vmx_src4;
+
+ vmx_src1 = load_128_unaligned (src);
+ vmx_src2 = load_128_unaligned (src + 4);
+ vmx_src3 = load_128_unaligned (src + 8);
+ vmx_src4 = load_128_unaligned (src + 12);
+
+ save_128_aligned (dst, vec_or (vmx_src1, mask_ff000000));
+ save_128_aligned (dst + 4, vec_or (vmx_src2, mask_ff000000));
+ save_128_aligned (dst + 8, vec_or (vmx_src3, mask_ff000000));
+ save_128_aligned (dst + 12, vec_or (vmx_src4, mask_ff000000));
+
+ dst += 16;
+ src += 16;
+ w -= 16;
+ }
+
+ while (w)
+ {
+ *dst++ = *src++ | 0xff000000;
+ w--;
+ }
+ }
+}
+
+static void
+vmx_composite_over_n_8888 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint32_t *dst_line, *dst;
+ uint32_t src, ia;
+ int i, w, dst_stride;
+ vector unsigned int vdst, vsrc, via;
+
+ src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
+
+ if (src == 0)
+ return;
+
+ PIXMAN_IMAGE_GET_LINE (
+ dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+
+ vsrc = (vector unsigned int){src, src, src, src};
+ via = negate (splat_alpha (vsrc));
+ ia = ALPHA_8 (~src);
+
+ while (height--)
+ {
+ dst = dst_line;
+ dst_line += dst_stride;
+ w = width;
+
+ while (w && ((uintptr_t)dst & 15))
+ {
+ uint32_t d = *dst;
+ UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, src);
+ *dst++ = d;
+ w--;
+ }
+
+ for (i = w / 4; i > 0; i--)
+ {
+ vdst = pix_multiply (load_128_aligned (dst), via);
+ save_128_aligned (dst, pix_add (vsrc, vdst));
+ dst += 4;
+ }
+
+ for (i = w % 4; --i >= 0;)
+ {
+ uint32_t d = dst[i];
+ UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, src);
+ dst[i] = d;
+ }
+ }
+}
+
+static void
+vmx_composite_over_8888_8888 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ int dst_stride, src_stride;
+ uint32_t *dst_line, *dst;
+ uint32_t *src_line, *src;
+
+ PIXMAN_IMAGE_GET_LINE (
+ dest_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);
+
+ dst = dst_line;
+ src = src_line;
+
+ while (height--)
+ {
+ vmx_combine_over_u (imp, op, dst, src, NULL, width);
+
+ dst += dst_stride;
+ src += src_stride;
+ }
+}
+
+static void
+vmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint32_t src, ia;
+ uint32_t *dst_line, d;
+ uint32_t *mask_line, m;
+ uint32_t pack_cmp;
+ int dst_stride, mask_stride;
+
+ vector unsigned int vsrc, valpha, vmask, vdest;
+
+ src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
+
+ if (src == 0)
+ return;
+
+ PIXMAN_IMAGE_GET_LINE (
+ dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+ PIXMAN_IMAGE_GET_LINE (
+ mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
+
+ vsrc = (vector unsigned int) {src, src, src, src};
+ valpha = splat_alpha(vsrc);
+ ia = ALPHA_8 (src);
+
+ while (height--)
+ {
+ int w = width;
+ const uint32_t *pm = (uint32_t *)mask_line;
+ uint32_t *pd = (uint32_t *)dst_line;
+ uint32_t s;
+
+ dst_line += dst_stride;
+ mask_line += mask_stride;
+
+ while (w && (uintptr_t)pd & 15)
+ {
+ s = src;
+ m = *pm++;
+
+ if (m)
+ {
+ d = *pd;
+ UN8x4_MUL_UN8x4 (s, m);
+ UN8x4_MUL_UN8 (m, ia);
+ m = ~m;
+ UN8x4_MUL_UN8x4_ADD_UN8x4 (d, m, s);
+ *pd = d;
+ }
+
+ pd++;
+ w--;
+ }
+
+ while (w >= 4)
+ {
+ /* pm is NOT necessarily 16-byte aligned */
+ vmask = load_128_unaligned (pm);
+
+ pack_cmp = vec_all_eq(vmask, (vector unsigned int) AVV(0));
+
+ /* if all bits in mask are zero, pack_cmp is not 0 */
+ if (pack_cmp == 0)
+ {
+ /* pd is 16-byte aligned */
+ vdest = in_over (vsrc, valpha, vmask, load_128_aligned (pd));
+
+ save_128_aligned(pd, vdest);
+ }
+
+ pd += 4;
+ pm += 4;
+ w -= 4;
+ }
+
+ while (w)
+ {
+ s = src;
+ m = *pm++;
+
+ if (m)
+ {
+ d = *pd;
+ UN8x4_MUL_UN8x4 (s, m);
+ UN8x4_MUL_UN8 (m, ia);
+ m = ~m;
+ UN8x4_MUL_UN8x4_ADD_UN8x4 (d, m, s);
+ *pd = d;
+ }
+
+ pd++;
+ w--;
+ }
+ }
+}
+
+static void
+vmx_composite_add_8_8 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint8_t *dst_line, *dst;
+ uint8_t *src_line, *src;
+ int dst_stride, src_stride;
+ int32_t w;
+ uint16_t t;
+
+ PIXMAN_IMAGE_GET_LINE (
+ src_image, src_x, src_y, uint8_t, src_stride, src_line, 1);
+ PIXMAN_IMAGE_GET_LINE (
+ dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
+
+ while (height--)
+ {
+ dst = dst_line;
+ src = src_line;
+
+ dst_line += dst_stride;
+ src_line += src_stride;
+ w = width;
+
+ /* Small head */
+ while (w && (uintptr_t)dst & 3)
+ {
+ t = (*dst) + (*src++);
+ *dst++ = t | (0 - (t >> 8));
+ w--;
+ }
+
+ vmx_combine_add_u (imp, op,
+ (uint32_t*)dst, (uint32_t*)src, NULL, w >> 2);
+
+ /* Small tail */
+ dst += w & 0xfffc;
+ src += w & 0xfffc;
+
+ w &= 3;
+
+ while (w)
+ {
+ t = (*dst) + (*src++);
+ *dst++ = t | (0 - (t >> 8));
+ w--;
+ }
+ }
+}
+
+static void
+vmx_composite_add_8888_8888 (pixman_implementation_t *imp,
+ pixman_composite_info_t *info)
+{
+ PIXMAN_COMPOSITE_ARGS (info);
+ uint32_t *dst_line, *dst;
+ uint32_t *src_line, *src;
+ int dst_stride, src_stride;
+
+ PIXMAN_IMAGE_GET_LINE (
+ src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
+ PIXMAN_IMAGE_GET_LINE (
+ dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+
+ while (height--)
+ {
+ dst = dst_line;
+ dst_line += dst_stride;
+ src = src_line;
+ src_line += src_stride;
+
+ vmx_combine_add_u (imp, op, dst, src, NULL, width);
+ }
+}
+
+static force_inline void
+scaled_nearest_scanline_vmx_8888_8888_OVER (uint32_t* pd,
+ const uint32_t* ps,
+ int32_t w,
+ pixman_fixed_t vx,
+ pixman_fixed_t unit_x,
+ pixman_fixed_t src_width_fixed,
+ pixman_bool_t fully_transparent_src)
+{
+ uint32_t s, d;
+ const uint32_t* pm = NULL;
+
+ vector unsigned int vsrc, vdst;
+
+ if (fully_transparent_src)
+ return;
+
+ /* Align dst on a 16-byte boundary */
+ while (w && ((uintptr_t)pd & 15))
+ {
+ d = *pd;
+ s = combine1 (ps + pixman_fixed_to_int (vx), pm);
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+
+ *pd++ = core_combine_over_u_pixel_vmx (s, d);
+ if (pm)
+ pm++;
+ w--;
+ }
+
+ while (w >= 4)
+ {
+ vector unsigned int tmp;
+ uint32_t tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = *(ps + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+ tmp2 = *(ps + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+ tmp3 = *(ps + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+ tmp4 = *(ps + pixman_fixed_to_int (vx));
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+
+ tmp[0] = tmp1;
+ tmp[1] = tmp2;
+ tmp[2] = tmp3;
+ tmp[3] = tmp4;
+
+ vsrc = combine4 ((const uint32_t *) &tmp, pm);
+
+ if (is_opaque (vsrc))
+ {
+ save_128_aligned (pd, vsrc);
+ }
+ else if (!is_zero (vsrc))
+ {
+ vdst = over(vsrc, splat_alpha(vsrc), load_128_aligned (pd));
+
+ save_128_aligned (pd, vdst);
+ }
+
+ w -= 4;
+ pd += 4;
+ if (pm)
+ pm += 4;
+ }
+
+ while (w)
+ {
+ d = *pd;
+ s = combine1 (ps + pixman_fixed_to_int (vx), pm);
+ vx += unit_x;
+ while (vx >= 0)
+ vx -= src_width_fixed;
+
+ *pd++ = core_combine_over_u_pixel_vmx (s, d);
+ if (pm)
+ pm++;
+
+ w--;
+ }
+}
+
+FAST_NEAREST_MAINLOOP (vmx_8888_8888_cover_OVER,
+ scaled_nearest_scanline_vmx_8888_8888_OVER,
+ uint32_t, uint32_t, COVER)
+FAST_NEAREST_MAINLOOP (vmx_8888_8888_none_OVER,
+ scaled_nearest_scanline_vmx_8888_8888_OVER,
+ uint32_t, uint32_t, NONE)
+FAST_NEAREST_MAINLOOP (vmx_8888_8888_pad_OVER,
+ scaled_nearest_scanline_vmx_8888_8888_OVER,
+ uint32_t, uint32_t, PAD)
+FAST_NEAREST_MAINLOOP (vmx_8888_8888_normal_OVER,
+ scaled_nearest_scanline_vmx_8888_8888_OVER,
+ uint32_t, uint32_t, NORMAL)
+
static const pixman_fast_path_t vmx_fast_paths[] =
{
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, vmx_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, vmx_composite_over_n_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, vmx_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, vmx_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, vmx_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, vmx_composite_over_8888_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, vmx_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, vmx_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, vmx_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, vmx_composite_over_n_8_8888),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, vmx_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, vmx_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, vmx_composite_over_n_8888_8888_ca),
+ PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, vmx_composite_over_n_8888_8888_ca),
+
+ /* PIXMAN_OP_ADD */
+ PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, vmx_composite_add_8_8),
+ PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, vmx_composite_add_8888_8888),
+ PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, vmx_composite_add_8888_8888),
+
+ /* PIXMAN_OP_SRC */
+ PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, vmx_composite_src_x888_8888),
+ PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, vmx_composite_src_x888_8888),
+
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, vmx_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, vmx_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, vmx_8888_8888),
+ SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, vmx_8888_8888),
+
{ PIXMAN_OP_NONE },
};
+static uint32_t *
+vmx_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask)
+{
+ int w = iter->width;
+ vector unsigned int ff000000 = mask_ff000000;
+ uint32_t *dst = iter->buffer;
+ uint32_t *src = (uint32_t *)iter->bits;
+
+ iter->bits += iter->stride;
+
+ while (w && ((uintptr_t)dst) & 0x0f)
+ {
+ *dst++ = (*src++) | 0xff000000;
+ w--;
+ }
+
+ while (w >= 4)
+ {
+ save_128_aligned(dst, vec_or(load_128_unaligned(src), ff000000));
+
+ dst += 4;
+ src += 4;
+ w -= 4;
+ }
+
+ while (w)
+ {
+ *dst++ = (*src++) | 0xff000000;
+ w--;
+ }
+
+ return iter->buffer;
+}
+
+static uint32_t *
+vmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask)
+{
+ int w = iter->width;
+ uint32_t *dst = iter->buffer;
+ uint8_t *src = iter->bits;
+ vector unsigned int vmx0, vmx1, vmx2, vmx3, vmx4, vmx5, vmx6;
+
+ iter->bits += iter->stride;
+
+ while (w && (((uintptr_t)dst) & 15))
+ {
+ *dst++ = *(src++) << 24;
+ w--;
+ }
+
+ while (w >= 16)
+ {
+ vmx0 = load_128_unaligned((uint32_t *) src);
+
+ unpack_128_2x128((vector unsigned int) AVV(0), vmx0, &vmx1, &vmx2);
+ unpack_128_2x128_16((vector unsigned int) AVV(0), vmx1, &vmx3, &vmx4);
+ unpack_128_2x128_16((vector unsigned int) AVV(0), vmx2, &vmx5, &vmx6);
+
+ save_128_aligned(dst, vmx6);
+ save_128_aligned((dst + 4), vmx5);
+ save_128_aligned((dst + 8), vmx4);
+ save_128_aligned((dst + 12), vmx3);
+
+ dst += 16;
+ src += 16;
+ w -= 16;
+ }
+
+ while (w)
+ {
+ *dst++ = *(src++) << 24;
+ w--;
+ }
+
+ return iter->buffer;
+}
+
+#define IMAGE_FLAGS \
+ (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \
+ FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
+
+static const pixman_iter_info_t vmx_iters[] =
+{
+ { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW,
+ _pixman_iter_init_bits_stride, vmx_fetch_x8r8g8b8, NULL
+ },
+ { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW,
+ _pixman_iter_init_bits_stride, vmx_fetch_a8, NULL
+ },
+ { PIXMAN_null },
+};
+
pixman_implementation_t *
_pixman_implementation_create_vmx (pixman_implementation_t *fallback)
{
pixman_implementation_t *imp = _pixman_implementation_create (fallback, vmx_fast_paths);
+ /* VMX constants */
+ mask_ff000000 = create_mask_32_128 (0xff000000);
+ mask_red = create_mask_32_128 (0x00f80000);
+ mask_green = create_mask_32_128 (0x0000fc00);
+ mask_blue = create_mask_32_128 (0x000000f8);
+ mask_565_fix_rb = create_mask_32_128 (0x00e000e0);
+ mask_565_fix_g = create_mask_32_128 (0x0000c000);
+
/* Set up function pointers */
imp->combine_32[PIXMAN_OP_OVER] = vmx_combine_over_u;
@@ -2022,5 +3151,9 @@ _pixman_implementation_create_vmx (pixman_implementation_t *fallback)
imp->combine_32_ca[PIXMAN_OP_XOR] = vmx_combine_xor_ca;
imp->combine_32_ca[PIXMAN_OP_ADD] = vmx_combine_add_ca;
+ imp->fill = vmx_fill;
+
+ imp->iter_info = vmx_iters;
+
return imp;
}
diff --git a/lib/pixman/pixman/pixman.c b/lib/pixman/pixman/pixman.c
index 9555ceaaf..f932eac3c 100644
--- a/lib/pixman/pixman/pixman.c
+++ b/lib/pixman/pixman/pixman.c
@@ -325,18 +325,20 @@ _pixman_compute_composite_region32 (pixman_region32_t * region,
return TRUE;
}
-typedef struct
+typedef struct box_48_16 box_48_16_t;
+
+struct box_48_16
{
- pixman_fixed_48_16_t x1;
- pixman_fixed_48_16_t y1;
- pixman_fixed_48_16_t x2;
- pixman_fixed_48_16_t y2;
-} box_48_16_t;
+ pixman_fixed_48_16_t x1;
+ pixman_fixed_48_16_t y1;
+ pixman_fixed_48_16_t x2;
+ pixman_fixed_48_16_t y2;
+};
static pixman_bool_t
-compute_transformed_extents (pixman_transform_t *transform,
+compute_transformed_extents (pixman_transform_t *transform,
const pixman_box32_t *extents,
- box_48_16_t *transformed)
+ box_48_16_t *transformed)
{
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
pixman_fixed_t x1, y1, x2, y2;
@@ -495,21 +497,12 @@ analyze_extent (pixman_image_t *image,
if (!compute_transformed_extents (transform, extents, &transformed))
return FALSE;
- /* Expand the source area by a tiny bit so account of different rounding that
- * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
- * 0.5 so this won't cause the area computed to be overly pessimistic.
- */
- transformed.x1 -= 8 * pixman_fixed_e;
- transformed.y1 -= 8 * pixman_fixed_e;
- transformed.x2 += 8 * pixman_fixed_e;
- transformed.y2 += 8 * pixman_fixed_e;
-
if (image->common.type == BITS)
{
- if (pixman_fixed_to_int (transformed.x1) >= 0 &&
- pixman_fixed_to_int (transformed.y1) >= 0 &&
- pixman_fixed_to_int (transformed.x2) < image->bits.width &&
- pixman_fixed_to_int (transformed.y2) < image->bits.height)
+ if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_e) >= 0 &&
+ pixman_fixed_to_int (transformed.y1 - pixman_fixed_e) >= 0 &&
+ pixman_fixed_to_int (transformed.x2 - pixman_fixed_e) < image->bits.width &&
+ pixman_fixed_to_int (transformed.y2 - pixman_fixed_e) < image->bits.height)
{
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
}
diff --git a/lib/pixman/test/Makefile.in b/lib/pixman/test/Makefile.in
index d7fa0d297..4461a93b9 100644
--- a/lib/pixman/test/Makefile.in
+++ b/lib/pixman/test/Makefile.in
@@ -74,20 +74,25 @@ AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-am__EXEEXT_1 = prng-test$(EXEEXT) a1-trap-test$(EXEEXT) \
- pdf-op-test$(EXEEXT) region-test$(EXEEXT) \
- region-translate-test$(EXEEXT) combiner-test$(EXEEXT) \
- pixel-test$(EXEEXT) fetch-test$(EXEEXT) rotate-test$(EXEEXT) \
- oob-test$(EXEEXT) infinite-loop$(EXEEXT) trap-crasher$(EXEEXT) \
- alpha-loop$(EXEEXT) thread-test$(EXEEXT) \
- scaling-crash-test$(EXEEXT) scaling-helpers-test$(EXEEXT) \
- gradient-crash-test$(EXEEXT) region-contains-test$(EXEEXT) \
- alphamap$(EXEEXT) matrix-test$(EXEEXT) stress-test$(EXEEXT) \
- composite-traps-test$(EXEEXT) blitters-test$(EXEEXT) \
- glyph-test$(EXEEXT) scaling-test$(EXEEXT) affine-test$(EXEEXT) \
- composite$(EXEEXT)
+am__EXEEXT_1 = oob-test$(EXEEXT) infinite-loop$(EXEEXT) \
+ trap-crasher$(EXEEXT) fence-image-self-test$(EXEEXT) \
+ region-translate-test$(EXEEXT) fetch-test$(EXEEXT) \
+ a1-trap-test$(EXEEXT) prng-test$(EXEEXT) \
+ radial-invalid$(EXEEXT) pdf-op-test$(EXEEXT) \
+ region-test$(EXEEXT) combiner-test$(EXEEXT) \
+ scaling-crash-test$(EXEEXT) alpha-loop$(EXEEXT) \
+ scaling-helpers-test$(EXEEXT) thread-test$(EXEEXT) \
+ rotate-test$(EXEEXT) alphamap$(EXEEXT) \
+ gradient-crash-test$(EXEEXT) pixel-test$(EXEEXT) \
+ matrix-test$(EXEEXT) composite-traps-test$(EXEEXT) \
+ region-contains-test$(EXEEXT) glyph-test$(EXEEXT) \
+ solid-test$(EXEEXT) stress-test$(EXEEXT) cover-test$(EXEEXT) \
+ blitters-test$(EXEEXT) affine-test$(EXEEXT) \
+ scaling-test$(EXEEXT) composite$(EXEEXT) \
+ tolerance-test$(EXEEXT)
am__EXEEXT_2 = lowlevel-blt-bench$(EXEEXT) radial-perf-test$(EXEEXT) \
- check-formats$(EXEEXT) scaling-bench$(EXEEXT)
+ check-formats$(EXEEXT) scaling-bench$(EXEEXT) \
+ affine-bench$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
a1_trap_test_SOURCES = a1-trap-test.c
a1_trap_test_OBJECTS = a1-trap-test.$(OBJEXT)
@@ -96,6 +101,12 @@ am__DEPENDENCIES_1 =
a1_trap_test_DEPENDENCIES = libutils.la \
$(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+affine_bench_SOURCES = affine-bench.c
+affine_bench_OBJECTS = affine-bench.$(OBJEXT)
+affine_bench_LDADD = $(LDADD)
+affine_bench_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
affine_test_SOURCES = affine-test.c
affine_test_OBJECTS = affine-test.$(OBJEXT)
affine_test_LDADD = $(LDADD)
@@ -144,6 +155,18 @@ composite_traps_test_LDADD = $(LDADD)
composite_traps_test_DEPENDENCIES = libutils.la \
$(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+cover_test_SOURCES = cover-test.c
+cover_test_OBJECTS = cover-test.$(OBJEXT)
+cover_test_LDADD = $(LDADD)
+cover_test_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+fence_image_self_test_SOURCES = fence-image-self-test.c
+fence_image_self_test_OBJECTS = fence-image-self-test.$(OBJEXT)
+fence_image_self_test_LDADD = $(LDADD)
+fence_image_self_test_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
fetch_test_SOURCES = fetch-test.c
fetch_test_OBJECTS = fetch-test.$(OBJEXT)
fetch_test_LDADD = $(LDADD)
@@ -204,6 +227,12 @@ prng_test_LDADD = $(LDADD)
prng_test_DEPENDENCIES = libutils.la \
$(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+radial_invalid_SOURCES = radial-invalid.c
+radial_invalid_OBJECTS = radial-invalid.$(OBJEXT)
+radial_invalid_LDADD = $(LDADD)
+radial_invalid_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
radial_perf_test_SOURCES = radial-perf-test.c
radial_perf_test_OBJECTS = radial-perf-test.$(OBJEXT)
radial_perf_test_LDADD = $(LDADD)
@@ -258,6 +287,12 @@ scaling_test_LDADD = $(LDADD)
scaling_test_DEPENDENCIES = libutils.la \
$(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+solid_test_SOURCES = solid-test.c
+solid_test_OBJECTS = solid-test.$(OBJEXT)
+solid_test_LDADD = $(LDADD)
+solid_test_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
stress_test_SOURCES = stress-test.c
stress_test_OBJECTS = stress-test.$(OBJEXT)
stress_test_LDADD = $(LDADD)
@@ -270,6 +305,12 @@ thread_test_LDADD = $(LDADD)
thread_test_DEPENDENCIES = libutils.la \
$(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+tolerance_test_SOURCES = tolerance-test.c
+tolerance_test_OBJECTS = tolerance-test.$(OBJEXT)
+tolerance_test_LDADD = $(LDADD)
+tolerance_test_DEPENDENCIES = libutils.la \
+ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
trap_crasher_SOURCES = trap-crasher.c
trap_crasher_OBJECTS = trap-crasher.$(OBJEXT)
trap_crasher_LDADD = $(LDADD)
@@ -310,26 +351,30 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-test.c \
- alpha-loop.c alphamap.c blitters-test.c check-formats.c \
- combiner-test.c composite.c composite-traps-test.c \
+SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-bench.c \
+ affine-test.c alpha-loop.c alphamap.c blitters-test.c \
+ check-formats.c combiner-test.c composite.c \
+ composite-traps-test.c cover-test.c fence-image-self-test.c \
fetch-test.c glyph-test.c gradient-crash-test.c \
infinite-loop.c lowlevel-blt-bench.c matrix-test.c oob-test.c \
- pdf-op-test.c pixel-test.c prng-test.c radial-perf-test.c \
- region-contains-test.c region-test.c region-translate-test.c \
- rotate-test.c scaling-bench.c scaling-crash-test.c \
- scaling-helpers-test.c scaling-test.c stress-test.c \
- thread-test.c trap-crasher.c
-DIST_SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-test.c \
- alpha-loop.c alphamap.c blitters-test.c check-formats.c \
- combiner-test.c composite.c composite-traps-test.c \
+ pdf-op-test.c pixel-test.c prng-test.c radial-invalid.c \
+ radial-perf-test.c region-contains-test.c region-test.c \
+ region-translate-test.c rotate-test.c scaling-bench.c \
+ scaling-crash-test.c scaling-helpers-test.c scaling-test.c \
+ solid-test.c stress-test.c thread-test.c tolerance-test.c \
+ trap-crasher.c
+DIST_SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-bench.c \
+ affine-test.c alpha-loop.c alphamap.c blitters-test.c \
+ check-formats.c combiner-test.c composite.c \
+ composite-traps-test.c cover-test.c fence-image-self-test.c \
fetch-test.c glyph-test.c gradient-crash-test.c \
infinite-loop.c lowlevel-blt-bench.c matrix-test.c oob-test.c \
- pdf-op-test.c pixel-test.c prng-test.c radial-perf-test.c \
- region-contains-test.c region-test.c region-translate-test.c \
- rotate-test.c scaling-bench.c scaling-crash-test.c \
- scaling-helpers-test.c scaling-test.c stress-test.c \
- thread-test.c trap-crasher.c
+ pdf-op-test.c pixel-test.c prng-test.c radial-invalid.c \
+ radial-perf-test.c region-contains-test.c region-test.c \
+ region-translate-test.c rotate-test.c scaling-bench.c \
+ scaling-crash-test.c scaling-helpers-test.c scaling-test.c \
+ solid-test.c stress-test.c thread-test.c tolerance-test.c \
+ trap-crasher.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -491,33 +536,38 @@ top_srcdir = @top_srcdir@
# Tests (sorted by expected completion time)
TESTPROGRAMS = \
- prng-test \
- a1-trap-test \
- pdf-op-test \
- region-test \
- region-translate-test \
- combiner-test \
- pixel-test \
- fetch-test \
- rotate-test \
- oob-test \
- infinite-loop \
- trap-crasher \
- alpha-loop \
- thread-test \
- scaling-crash-test \
- scaling-helpers-test \
- gradient-crash-test \
- region-contains-test \
- alphamap \
- matrix-test \
- stress-test \
- composite-traps-test \
- blitters-test \
- glyph-test \
- scaling-test \
- affine-test \
- composite \
+ oob-test \
+ infinite-loop \
+ trap-crasher \
+ fence-image-self-test \
+ region-translate-test \
+ fetch-test \
+ a1-trap-test \
+ prng-test \
+ radial-invalid \
+ pdf-op-test \
+ region-test \
+ combiner-test \
+ scaling-crash-test \
+ alpha-loop \
+ scaling-helpers-test \
+ thread-test \
+ rotate-test \
+ alphamap \
+ gradient-crash-test \
+ pixel-test \
+ matrix-test \
+ composite-traps-test \
+ region-contains-test \
+ glyph-test \
+ solid-test \
+ stress-test \
+ cover-test \
+ blitters-test \
+ affine-test \
+ scaling-test \
+ composite \
+ tolerance-test \
$(NULL)
@@ -527,6 +577,7 @@ OTHERPROGRAMS = \
radial-perf-test \
check-formats \
scaling-bench \
+ affine-bench \
$(NULL)
@@ -607,6 +658,9 @@ clean-noinstPROGRAMS:
a1-trap-test$(EXEEXT): $(a1_trap_test_OBJECTS) $(a1_trap_test_DEPENDENCIES) $(EXTRA_a1_trap_test_DEPENDENCIES)
@rm -f a1-trap-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(a1_trap_test_OBJECTS) $(a1_trap_test_LDADD) $(LIBS)
+affine-bench$(EXEEXT): $(affine_bench_OBJECTS) $(affine_bench_DEPENDENCIES) $(EXTRA_affine_bench_DEPENDENCIES)
+ @rm -f affine-bench$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(affine_bench_OBJECTS) $(affine_bench_LDADD) $(LIBS)
affine-test$(EXEEXT): $(affine_test_OBJECTS) $(affine_test_DEPENDENCIES) $(EXTRA_affine_test_DEPENDENCIES)
@rm -f affine-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(affine_test_OBJECTS) $(affine_test_LDADD) $(LIBS)
@@ -631,6 +685,12 @@ composite$(EXEEXT): $(composite_OBJECTS) $(composite_DEPENDENCIES) $(EXTRA_compo
composite-traps-test$(EXEEXT): $(composite_traps_test_OBJECTS) $(composite_traps_test_DEPENDENCIES) $(EXTRA_composite_traps_test_DEPENDENCIES)
@rm -f composite-traps-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(composite_traps_test_OBJECTS) $(composite_traps_test_LDADD) $(LIBS)
+cover-test$(EXEEXT): $(cover_test_OBJECTS) $(cover_test_DEPENDENCIES) $(EXTRA_cover_test_DEPENDENCIES)
+ @rm -f cover-test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cover_test_OBJECTS) $(cover_test_LDADD) $(LIBS)
+fence-image-self-test$(EXEEXT): $(fence_image_self_test_OBJECTS) $(fence_image_self_test_DEPENDENCIES) $(EXTRA_fence_image_self_test_DEPENDENCIES)
+ @rm -f fence-image-self-test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(fence_image_self_test_OBJECTS) $(fence_image_self_test_LDADD) $(LIBS)
fetch-test$(EXEEXT): $(fetch_test_OBJECTS) $(fetch_test_DEPENDENCIES) $(EXTRA_fetch_test_DEPENDENCIES)
@rm -f fetch-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fetch_test_OBJECTS) $(fetch_test_LDADD) $(LIBS)
@@ -661,6 +721,9 @@ pixel-test$(EXEEXT): $(pixel_test_OBJECTS) $(pixel_test_DEPENDENCIES) $(EXTRA_pi
prng-test$(EXEEXT): $(prng_test_OBJECTS) $(prng_test_DEPENDENCIES) $(EXTRA_prng_test_DEPENDENCIES)
@rm -f prng-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(prng_test_OBJECTS) $(prng_test_LDADD) $(LIBS)
+radial-invalid$(EXEEXT): $(radial_invalid_OBJECTS) $(radial_invalid_DEPENDENCIES) $(EXTRA_radial_invalid_DEPENDENCIES)
+ @rm -f radial-invalid$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(radial_invalid_OBJECTS) $(radial_invalid_LDADD) $(LIBS)
radial-perf-test$(EXEEXT): $(radial_perf_test_OBJECTS) $(radial_perf_test_DEPENDENCIES) $(EXTRA_radial_perf_test_DEPENDENCIES)
@rm -f radial-perf-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(radial_perf_test_OBJECTS) $(radial_perf_test_LDADD) $(LIBS)
@@ -688,12 +751,18 @@ scaling-helpers-test$(EXEEXT): $(scaling_helpers_test_OBJECTS) $(scaling_helpers
scaling-test$(EXEEXT): $(scaling_test_OBJECTS) $(scaling_test_DEPENDENCIES) $(EXTRA_scaling_test_DEPENDENCIES)
@rm -f scaling-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(scaling_test_OBJECTS) $(scaling_test_LDADD) $(LIBS)
+solid-test$(EXEEXT): $(solid_test_OBJECTS) $(solid_test_DEPENDENCIES) $(EXTRA_solid_test_DEPENDENCIES)
+ @rm -f solid-test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(solid_test_OBJECTS) $(solid_test_LDADD) $(LIBS)
stress-test$(EXEEXT): $(stress_test_OBJECTS) $(stress_test_DEPENDENCIES) $(EXTRA_stress_test_DEPENDENCIES)
@rm -f stress-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(stress_test_OBJECTS) $(stress_test_LDADD) $(LIBS)
thread-test$(EXEEXT): $(thread_test_OBJECTS) $(thread_test_DEPENDENCIES) $(EXTRA_thread_test_DEPENDENCIES)
@rm -f thread-test$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(thread_test_OBJECTS) $(thread_test_LDADD) $(LIBS)
+tolerance-test$(EXEEXT): $(tolerance_test_OBJECTS) $(tolerance_test_DEPENDENCIES) $(EXTRA_tolerance_test_DEPENDENCIES)
+ @rm -f tolerance-test$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tolerance_test_OBJECTS) $(tolerance_test_LDADD) $(LIBS)
trap-crasher$(EXEEXT): $(trap_crasher_OBJECTS) $(trap_crasher_DEPENDENCIES) $(EXTRA_trap_crasher_DEPENDENCIES)
@rm -f trap-crasher$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(trap_crasher_OBJECTS) $(trap_crasher_LDADD) $(LIBS)
@@ -705,6 +774,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a1-trap-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine-bench.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha-loop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alphamap.Po@am__quote@
@@ -713,6 +783,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/combiner-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/composite-traps-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/composite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cover-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fence-image-self-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyph-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gradient-crash-test.Po@am__quote@
@@ -723,6 +795,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdf-op-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixel-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prng-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radial-invalid.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radial-perf-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region-contains-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region-test.Po@am__quote@
@@ -732,8 +805,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-crash-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-helpers-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solid-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tolerance-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trap-crasher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils-prng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@
diff --git a/lib/pixman/test/Makefile.sources b/lib/pixman/test/Makefile.sources
index 2ae5d9f8d..5d55e676a 100644
--- a/lib/pixman/test/Makefile.sources
+++ b/lib/pixman/test/Makefile.sources
@@ -1,32 +1,37 @@
# Tests (sorted by expected completion time)
-TESTPROGRAMS = \
- prng-test \
- a1-trap-test \
- pdf-op-test \
- region-test \
- region-translate-test \
- combiner-test \
- pixel-test \
- fetch-test \
- rotate-test \
- oob-test \
- infinite-loop \
- trap-crasher \
- alpha-loop \
- thread-test \
- scaling-crash-test \
- scaling-helpers-test \
- gradient-crash-test \
- region-contains-test \
- alphamap \
- matrix-test \
- stress-test \
- composite-traps-test \
- blitters-test \
- glyph-test \
- scaling-test \
- affine-test \
- composite \
+TESTPROGRAMS = \
+ oob-test \
+ infinite-loop \
+ trap-crasher \
+ fence-image-self-test \
+ region-translate-test \
+ fetch-test \
+ a1-trap-test \
+ prng-test \
+ radial-invalid \
+ pdf-op-test \
+ region-test \
+ combiner-test \
+ scaling-crash-test \
+ alpha-loop \
+ scaling-helpers-test \
+ thread-test \
+ rotate-test \
+ alphamap \
+ gradient-crash-test \
+ pixel-test \
+ matrix-test \
+ composite-traps-test \
+ region-contains-test \
+ glyph-test \
+ solid-test \
+ stress-test \
+ cover-test \
+ blitters-test \
+ affine-test \
+ scaling-test \
+ composite \
+ tolerance-test \
$(NULL)
# Other programs
@@ -35,6 +40,7 @@ OTHERPROGRAMS = \
radial-perf-test \
check-formats \
scaling-bench \
+ affine-bench \
$(NULL)
# Utility functions
diff --git a/lib/pixman/test/affine-bench.c b/lib/pixman/test/affine-bench.c
new file mode 100644
index 000000000..86bf46ef7
--- /dev/null
+++ b/lib/pixman/test/affine-bench.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright © 2014 RISC OS Open Ltd
+ *
+ * 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 the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ *
+ * Author: Ben Avison (bavison@riscosopen.org)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdint.h>
+#include "utils.h"
+
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#define WIDTH 1920
+#define HEIGHT 1080
+
+/* How much data to read to flush all cached data to RAM */
+#define MAX_L2CACHE_SIZE (8 * 1024 * 1024)
+
+#define PAGE_SIZE (4 * 1024)
+
+struct bench_info
+{
+ pixman_op_t op;
+ pixman_transform_t transform;
+ pixman_image_t *src_image;
+ pixman_image_t *mask_image;
+ pixman_image_t *dest_image;
+ int32_t src_x;
+ int32_t src_y;
+};
+
+typedef struct bench_info bench_info_t;
+
+struct box_48_16
+{
+ pixman_fixed_48_16_t x1;
+ pixman_fixed_48_16_t y1;
+ pixman_fixed_48_16_t x2;
+ pixman_fixed_48_16_t y2;
+};
+
+typedef struct box_48_16 box_48_16_t;
+
+/* This function is copied verbatim from pixman.c. */
+static pixman_bool_t
+compute_transformed_extents (pixman_transform_t *transform,
+ const pixman_box32_t *extents,
+ box_48_16_t *transformed)
+{
+ pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
+ pixman_fixed_t x1, y1, x2, y2;
+ int i;
+
+ x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
+ y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
+ x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
+ y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
+
+ if (!transform)
+ {
+ transformed->x1 = x1;
+ transformed->y1 = y1;
+ transformed->x2 = x2;
+ transformed->y2 = y2;
+
+ return TRUE;
+ }
+
+ tx1 = ty1 = INT64_MAX;
+ tx2 = ty2 = INT64_MIN;
+
+ for (i = 0; i < 4; ++i)
+ {
+ pixman_fixed_48_16_t tx, ty;
+ pixman_vector_t v;
+
+ v.vector[0] = (i & 0x01)? x1 : x2;
+ v.vector[1] = (i & 0x02)? y1 : y2;
+ v.vector[2] = pixman_fixed_1;
+
+ if (!pixman_transform_point (transform, &v))
+ return FALSE;
+
+ tx = (pixman_fixed_48_16_t)v.vector[0];
+ ty = (pixman_fixed_48_16_t)v.vector[1];
+
+ if (tx < tx1)
+ tx1 = tx;
+ if (ty < ty1)
+ ty1 = ty;
+ if (tx > tx2)
+ tx2 = tx;
+ if (ty > ty2)
+ ty2 = ty;
+ }
+
+ transformed->x1 = tx1;
+ transformed->y1 = ty1;
+ transformed->x2 = tx2;
+ transformed->y2 = ty2;
+
+ return TRUE;
+}
+
+static void
+create_image (uint32_t width,
+ uint32_t height,
+ pixman_format_code_t format,
+ pixman_filter_t filter,
+ uint32_t **bits,
+ pixman_image_t **image)
+{
+ uint32_t stride = (width * PIXMAN_FORMAT_BPP (format) + 31) / 32 * 4;
+
+ *bits = aligned_malloc (PAGE_SIZE, stride * height);
+ memset (*bits, 0xCC, stride * height);
+ *image = pixman_image_create_bits (format, width, height, *bits, stride);
+ pixman_image_set_repeat (*image, PIXMAN_REPEAT_NORMAL);
+ pixman_image_set_filter (*image, filter, NULL, 0);
+}
+
+/* This needs to match the shortest cacheline length we expect to encounter */
+#define CACHE_CLEAN_INCREMENT 32
+
+static void
+flush_cache (void)
+{
+ static const char clean_space[MAX_L2CACHE_SIZE];
+ volatile const char *x = clean_space;
+ const char *clean_end = clean_space + sizeof clean_space;
+
+ while (x < clean_end)
+ {
+ (void) *x;
+ x += CACHE_CLEAN_INCREMENT;
+ }
+}
+
+/* Obtain current time in microseconds modulo 2^32 */
+uint32_t
+gettimei (void)
+{
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ return tv.tv_sec * 1000000 + tv.tv_usec;
+#else
+ return (uint64_t) clock () * 1000000 / CLOCKS_PER_SEC;
+#endif
+}
+
+static void
+pixman_image_composite_wrapper (const pixman_composite_info_t *info)
+{
+ pixman_image_composite (info->op,
+ info->src_image, info->mask_image, info->dest_image,
+ info->src_x, info->src_y,
+ info->mask_x, info->mask_y,
+ info->dest_x, info->dest_y,
+ info->width, info->height);
+}
+
+static void
+pixman_image_composite_empty (const pixman_composite_info_t *info)
+{
+ pixman_image_composite (info->op,
+ info->src_image, info->mask_image, info->dest_image,
+ info->src_x, info->src_y,
+ info->mask_x, info->mask_y,
+ info->dest_x, info->dest_y,
+ 1, 1);
+}
+
+static void
+bench (const bench_info_t *bi,
+ uint32_t max_n,
+ uint32_t max_time,
+ uint32_t *ret_n,
+ uint32_t *ret_time,
+ void (*func) (const pixman_composite_info_t *info))
+{
+ uint32_t n = 0;
+ uint32_t t0;
+ uint32_t t1;
+ uint32_t x = 0;
+ pixman_transform_t t;
+ pixman_composite_info_t info;
+
+ t = bi->transform;
+ info.op = bi->op;
+ info.src_image = bi->src_image;
+ info.mask_image = bi->mask_image;
+ info.dest_image = bi->dest_image;
+ info.src_x = 0;
+ info.src_y = 0;
+ info.mask_x = 0;
+ info.mask_y = 0;
+ /* info.dest_x set below */
+ info.dest_y = 0;
+ info.width = WIDTH;
+ info.height = HEIGHT;
+
+ t0 = gettimei ();
+
+ do
+ {
+
+ if (++x >= 64)
+ x = 0;
+
+ info.dest_x = 63 - x;
+
+ t.matrix[0][2] = pixman_int_to_fixed (bi->src_x + x);
+ t.matrix[1][2] = pixman_int_to_fixed (bi->src_y);
+ pixman_image_set_transform (bi->src_image, &t);
+
+ if (bi->mask_image)
+ pixman_image_set_transform (bi->mask_image, &t);
+
+ func (&info);
+ t1 = gettimei ();
+ }
+ while (++n < max_n && (t1 - t0) < max_time);
+
+ if (ret_n)
+ *ret_n = n;
+
+ *ret_time = t1 - t0;
+}
+
+int
+parse_fixed_argument (char *arg, pixman_fixed_t *value)
+{
+ char *tailptr;
+
+ *value = pixman_double_to_fixed (strtod (arg, &tailptr));
+
+ return *tailptr == '\0';
+}
+
+int
+parse_arguments (int argc,
+ char *argv[],
+ pixman_transform_t *t,
+ pixman_op_t *op,
+ pixman_format_code_t *src_format,
+ pixman_format_code_t *mask_format,
+ pixman_format_code_t *dest_format)
+{
+ if (!parse_fixed_argument (*argv, &t->matrix[0][0]))
+ return 0;
+
+ if (*++argv == NULL)
+ return 1;
+
+ if (!parse_fixed_argument (*argv, &t->matrix[0][1]))
+ return 0;
+
+ if (*++argv == NULL)
+ return 1;
+
+ if (!parse_fixed_argument (*argv, &t->matrix[1][0]))
+ return 0;
+
+ if (*++argv == NULL)
+ return 1;
+
+ if (!parse_fixed_argument (*argv, &t->matrix[1][1]))
+ return 0;
+
+ if (*++argv == NULL)
+ return 1;
+
+ *op = operator_from_string (*argv);
+ if (*op == PIXMAN_OP_NONE)
+ return 0;
+
+ if (*++argv == NULL)
+ return 1;
+
+ *src_format = format_from_string (*argv);
+ if (*src_format == PIXMAN_null)
+ return 0;
+
+ ++argv;
+ if (argv[0] && argv[1])
+ {
+ *mask_format = format_from_string (*argv);
+ if (*mask_format == PIXMAN_null)
+ return 0;
+ ++argv;
+ }
+ if (*argv)
+ {
+ *dest_format = format_from_string (*argv);
+ if (*dest_format == PIXMAN_null)
+ return 0;
+ }
+ return 1;
+}
+
+static void
+run_benchmark (const bench_info_t *bi)
+{
+ uint32_t n; /* number of iterations in at least 5 seconds */
+ uint32_t t1; /* time taken to do n iterations, microseconds */
+ uint32_t t2; /* calling overhead for n iterations, microseconds */
+
+ flush_cache ();
+ bench (bi, UINT32_MAX, 5000000, &n, &t1, pixman_image_composite_wrapper);
+ bench (bi, n, UINT32_MAX, NULL, &t2, pixman_image_composite_empty);
+
+ /* The result indicates the output rate in megapixels/second */
+ printf ("%6.2f\n", (double) n * WIDTH * HEIGHT / (t1 - t2));
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ bench_info_t binfo;
+ pixman_filter_t filter = PIXMAN_FILTER_NEAREST;
+ pixman_format_code_t src_format = PIXMAN_a8r8g8b8;
+ pixman_format_code_t mask_format = 0;
+ pixman_format_code_t dest_format = PIXMAN_a8r8g8b8;
+ pixman_box32_t dest_box = { 0, 0, WIDTH, HEIGHT };
+ box_48_16_t transformed = { 0 };
+ int32_t xmin, ymin, xmax, ymax;
+ uint32_t *src, *mask, *dest;
+
+ binfo.op = PIXMAN_OP_SRC;
+ binfo.mask_image = NULL;
+ pixman_transform_init_identity (&binfo.transform);
+
+ ++argv;
+ if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n')
+ {
+ filter = PIXMAN_FILTER_NEAREST;
+ ++argv;
+ --argc;
+ }
+
+ if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b')
+ {
+ filter = PIXMAN_FILTER_BILINEAR;
+ ++argv;
+ --argc;
+ }
+
+ if (argc == 1 ||
+ !parse_arguments (argc, argv, &binfo.transform, &binfo.op,
+ &src_format, &mask_format, &dest_format))
+ {
+ printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n");
+ printf (" [src format] [mask format] [dest format]\n");
+ printf (" -n : nearest scaling (default)\n");
+ printf (" -b : bilinear scaling\n");
+ printf (" axx : x_out:x_in factor\n");
+ printf (" axy : x_out:y_in factor (default 0)\n");
+ printf (" ayx : y_out:x_in factor (default 0)\n");
+ printf (" ayy : y_out:y_in factor (default 1)\n");
+ printf (" combine type : src, over, in etc (default src)\n");
+ printf (" src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n");
+ printf (" mask format : as for src format, but no mask used if omitted\n");
+ printf (" dest format : as for src format (default a8r8g8b8)\n");
+ printf ("The output is a single number in megapixels/second.\n");
+
+ return EXIT_FAILURE;
+ }
+
+ /* Compute required extents for source and mask image so they qualify
+ * for COVER fast paths and get the flags in pixman.c:analyze_extent().
+ * These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,
+ * but at the same time they also allow COVER_CLIP_NEAREST.
+ */
+ compute_transformed_extents (&binfo.transform, &dest_box, &transformed);
+ xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2);
+ ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2);
+ xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2);
+ ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2);
+ /* Note:
+ * The upper limits can be reduced to the following when fetchers
+ * are guaranteed to not access pixels with zero weight. This concerns
+ * particularly all bilinear samplers.
+ *
+ * xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e);
+ * ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e);
+ * This is equivalent to subtracting 0.5 and rounding up, rather than
+ * subtracting 0.5, rounding down and adding 1.
+ */
+ binfo.src_x = -xmin;
+ binfo.src_y = -ymin;
+
+ /* Always over-allocate width by 64 pixels for all src, mask and dst,
+ * so that we can iterate over an x-offset 0..63 in bench ().
+ * This is similar to lowlevel-blt-bench, which uses the same method
+ * to hit different cacheline misalignments.
+ */
+ create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter,
+ &src, &binfo.src_image);
+
+ if (mask_format)
+ {
+ create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter,
+ &mask, &binfo.mask_image);
+
+ if ((PIXMAN_FORMAT_R(mask_format) ||
+ PIXMAN_FORMAT_G(mask_format) ||
+ PIXMAN_FORMAT_B(mask_format)))
+ {
+ pixman_image_set_component_alpha (binfo.mask_image, 1);
+ }
+ }
+
+ create_image (WIDTH + 64, HEIGHT, dest_format, filter,
+ &dest, &binfo.dest_image);
+
+ run_benchmark (&binfo);
+
+ return EXIT_SUCCESS;
+}
diff --git a/lib/pixman/test/blitters-test.c b/lib/pixman/test/blitters-test.c
index ea03f475d..026f4b006 100644
--- a/lib/pixman/test/blitters-test.c
+++ b/lib/pixman/test/blitters-test.c
@@ -122,6 +122,15 @@ static pixman_op_t op_list[] = {
PIXMAN_OP_ATOP_REVERSE,
PIXMAN_OP_XOR,
PIXMAN_OP_ADD,
+ PIXMAN_OP_MULTIPLY,
+ PIXMAN_OP_SCREEN,
+ PIXMAN_OP_OVERLAY,
+ PIXMAN_OP_DARKEN,
+ PIXMAN_OP_LIGHTEN,
+ PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_OP_DIFFERENCE,
+ PIXMAN_OP_EXCLUSION,
+#if 0 /* these use floating point math and are not always bitexact on different platforms */
PIXMAN_OP_SATURATE,
PIXMAN_OP_DISJOINT_CLEAR,
PIXMAN_OP_DISJOINT_SRC,
@@ -147,17 +156,8 @@ static pixman_op_t op_list[] = {
PIXMAN_OP_CONJOINT_ATOP,
PIXMAN_OP_CONJOINT_ATOP_REVERSE,
PIXMAN_OP_CONJOINT_XOR,
- PIXMAN_OP_MULTIPLY,
- PIXMAN_OP_SCREEN,
- PIXMAN_OP_OVERLAY,
- PIXMAN_OP_DARKEN,
- PIXMAN_OP_LIGHTEN,
PIXMAN_OP_COLOR_DODGE,
PIXMAN_OP_COLOR_BURN,
- PIXMAN_OP_HARD_LIGHT,
- PIXMAN_OP_DIFFERENCE,
- PIXMAN_OP_EXCLUSION,
-#if 0 /* these use floating point math and are not always bitexact on different platforms */
PIXMAN_OP_SOFT_LIGHT,
PIXMAN_OP_HSL_HUE,
PIXMAN_OP_HSL_SATURATION,
@@ -394,6 +394,6 @@ main (int argc, const char *argv[])
}
return fuzzer_test_main("blitters", 2000000,
- 0xE0A07495,
+ 0xCC21DDF0,
test_composite, argc, argv);
}
diff --git a/lib/pixman/test/check-formats.c b/lib/pixman/test/check-formats.c
index 7edc198c1..4e2633c41 100644
--- a/lib/pixman/test/check-formats.c
+++ b/lib/pixman/test/check-formats.c
@@ -104,182 +104,6 @@ check_op (pixman_op_t op,
return retval;
}
-static const pixman_op_t op_list[] =
-{
- PIXMAN_OP_CLEAR,
- PIXMAN_OP_SRC,
- PIXMAN_OP_DST,
- PIXMAN_OP_OVER,
- PIXMAN_OP_OVER_REVERSE,
- PIXMAN_OP_IN,
- PIXMAN_OP_IN_REVERSE,
- PIXMAN_OP_OUT,
- PIXMAN_OP_OUT_REVERSE,
- PIXMAN_OP_ATOP,
- PIXMAN_OP_ATOP_REVERSE,
- PIXMAN_OP_XOR,
- PIXMAN_OP_ADD,
- PIXMAN_OP_SATURATE,
-
- PIXMAN_OP_DISJOINT_CLEAR,
- PIXMAN_OP_DISJOINT_SRC,
- PIXMAN_OP_DISJOINT_DST,
- PIXMAN_OP_DISJOINT_OVER,
- PIXMAN_OP_DISJOINT_OVER_REVERSE,
- PIXMAN_OP_DISJOINT_IN,
- PIXMAN_OP_DISJOINT_IN_REVERSE,
- PIXMAN_OP_DISJOINT_OUT,
- PIXMAN_OP_DISJOINT_OUT_REVERSE,
- PIXMAN_OP_DISJOINT_ATOP,
- PIXMAN_OP_DISJOINT_ATOP_REVERSE,
- PIXMAN_OP_DISJOINT_XOR,
-
- PIXMAN_OP_CONJOINT_CLEAR,
- PIXMAN_OP_CONJOINT_SRC,
- PIXMAN_OP_CONJOINT_DST,
- PIXMAN_OP_CONJOINT_OVER,
- PIXMAN_OP_CONJOINT_OVER_REVERSE,
- PIXMAN_OP_CONJOINT_IN,
- PIXMAN_OP_CONJOINT_IN_REVERSE,
- PIXMAN_OP_CONJOINT_OUT,
- PIXMAN_OP_CONJOINT_OUT_REVERSE,
- PIXMAN_OP_CONJOINT_ATOP,
- PIXMAN_OP_CONJOINT_ATOP_REVERSE,
- PIXMAN_OP_CONJOINT_XOR,
-};
-
-static const pixman_format_code_t format_list[] =
-{
- PIXMAN_a8r8g8b8,
- PIXMAN_x8r8g8b8,
- PIXMAN_a8b8g8r8,
- PIXMAN_x8b8g8r8,
- PIXMAN_b8g8r8a8,
- PIXMAN_b8g8r8x8,
- PIXMAN_r8g8b8a8,
- PIXMAN_r8g8b8x8,
- PIXMAN_x14r6g6b6,
- PIXMAN_x2r10g10b10,
- PIXMAN_a2r10g10b10,
- PIXMAN_x2b10g10r10,
- PIXMAN_a2b10g10r10,
- PIXMAN_a8r8g8b8_sRGB,
- PIXMAN_r8g8b8,
- PIXMAN_b8g8r8,
- PIXMAN_r5g6b5,
- PIXMAN_b5g6r5,
- PIXMAN_a1r5g5b5,
- PIXMAN_x1r5g5b5,
- PIXMAN_a1b5g5r5,
- PIXMAN_x1b5g5r5,
- PIXMAN_a4r4g4b4,
- PIXMAN_x4r4g4b4,
- PIXMAN_a4b4g4r4,
- PIXMAN_x4b4g4r4,
- PIXMAN_a8,
- PIXMAN_r3g3b2,
- PIXMAN_b2g3r3,
- PIXMAN_a2r2g2b2,
- PIXMAN_a2b2g2r2,
- PIXMAN_x4a4,
- PIXMAN_a4,
- PIXMAN_r1g2b1,
- PIXMAN_b1g2r1,
- PIXMAN_a1r1g1b1,
- PIXMAN_a1b1g1r1,
- PIXMAN_a1,
-};
-
-static pixman_format_code_t
-format_from_string (const char *s)
-{
- int i;
-
- for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
- {
- if (strcasecmp (format_name (format_list[i]), s) == 0)
- return format_list[i];
- }
-
- return PIXMAN_null;
-}
-
-static void
-emit (const char *s, int *n_chars)
-{
- *n_chars += printf ("%s,", s);
- if (*n_chars > 60)
- {
- printf ("\n ");
- *n_chars = 0;
- }
- else
- {
- printf (" ");
- (*n_chars)++;
- }
-}
-
-static void
-list_formats (void)
-{
- int n_chars;
- int i;
-
- printf ("Formats:\n ");
-
- n_chars = 0;
- for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
- emit (format_name (format_list[i]), &n_chars);
-
- printf ("\n\n");
-}
-
-static void
-list_operators (void)
-{
- char short_name [128] = { 0 };
- int i, n_chars;
-
- printf ("Operators:\n ");
-
- n_chars = 0;
- for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
- {
- pixman_op_t op = op_list[i];
- int j;
-
- snprintf (short_name, sizeof (short_name) - 1, "%s",
- operator_name (op) + strlen ("PIXMAN_OP_"));
-
- for (j = 0; short_name[j] != '\0'; ++j)
- short_name[j] = tolower (short_name[j]);
-
- emit (short_name, &n_chars);
- }
-
- printf ("\n\n");
-}
-
-static pixman_op_t
-operator_from_string (const char *s)
-{
- char full_name[128] = { 0 };
- int i;
-
- snprintf (full_name, (sizeof full_name) - 1, "PIXMAN_OP_%s", s);
-
- for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
- {
- pixman_op_t op = op_list[i];
-
- if (strcasecmp (operator_name (op), full_name) == 0)
- return op;
- }
-
- return PIXMAN_OP_NONE;
-}
-
int
main (int argc, char **argv)
{
diff --git a/lib/pixman/test/composite.c b/lib/pixman/test/composite.c
index 9e51a8f65..594c69772 100644
--- a/lib/pixman/test/composite.c
+++ b/lib/pixman/test/composite.c
@@ -299,17 +299,6 @@ composite_test (image_t *dst,
}
}
- if (mask)
- {
- if (component_alpha && PIXMAN_FORMAT_R (mask->format) == 0)
- {
- /* Ax component-alpha masks expand alpha into
- * all color channels.
- */
- tmsk.r = tmsk.g = tmsk.b = tmsk.a;
- }
- }
-
if (PIXMAN_FORMAT_TYPE (dst->format) == PIXMAN_TYPE_ARGB_SRGB)
{
tdst.r = convert_linear_to_srgb (tdst.r);
diff --git a/lib/pixman/test/cover-test.c b/lib/pixman/test/cover-test.c
new file mode 100644
index 000000000..83e2972d9
--- /dev/null
+++ b/lib/pixman/test/cover-test.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright © 2015 RISC OS Open Ltd
+ *
+ * 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 the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ *
+ * Author: Ben Avison (bavison@riscosopen.org)
+ *
+ */
+
+/*
+ * This test aims to verify both numerical correctness and the honouring of
+ * array bounds for scaled plots (both nearest-neighbour and bilinear) at or
+ * close to the boundary conditions for applicability of "cover" type fast paths
+ * and iter fetch routines.
+ *
+ * It has a secondary purpose: by setting the env var EXACT (to any value) it
+ * will only test plots that are exactly on the boundary condition. This makes
+ * it possible to ensure that "cover" routines are being used to the maximum,
+ * although this requires the use of a debugger or code instrumentation to
+ * verify.
+ */
+
+#include "utils.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Approximate limits for random scale factor generation - these ensure we can
+ * get at least 8x reduction and 8x enlargement.
+ */
+#define LOG2_MAX_FACTOR (3)
+
+/* 1/sqrt(2) (or sqrt(0.5), or 2^-0.5) as a 0.32 fixed-point number */
+#define INV_SQRT_2_0POINT32_FIXED (0xB504F334u)
+
+/* The largest increment that can be generated by random_scale_factor().
+ * This occurs when the "mantissa" part is 0xFFFFFFFF and the "exponent"
+ * part is -LOG2_MAX_FACTOR.
+ */
+#define MAX_INC ((pixman_fixed_t) \
+ (INV_SQRT_2_0POINT32_FIXED >> (31 - 16 - LOG2_MAX_FACTOR)))
+
+/* Minimum source width (in pixels) based on a typical page size of 4K and
+ * maximum colour depth of 32bpp.
+ */
+#define MIN_SRC_WIDTH (4096 / 4)
+
+/* Derive the destination width so that at max increment we fit within source */
+#define DST_WIDTH (MIN_SRC_WIDTH * pixman_fixed_1 / MAX_INC)
+
+/* Calculate heights the other way round.
+ * No limits due to page alignment here.
+ */
+#define DST_HEIGHT 3
+#define SRC_HEIGHT ((DST_HEIGHT * MAX_INC + pixman_fixed_1 - 1) / pixman_fixed_1)
+
+/* At the time of writing, all the scaled fast paths use SRC, OVER or ADD
+ * Porter-Duff operators. XOR is included in the list to ensure good
+ * representation of iter scanline fetch routines.
+ */
+static const pixman_op_t op_list[] = {
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_XOR,
+};
+
+/* At the time of writing, all the scaled fast paths use a8r8g8b8, x8r8g8b8
+ * or r5g6b5, or red-blue swapped versions of the same. When a mask channel is
+ * used, it is always a8 (and so implicitly not component alpha). a1r5g5b5 is
+ * included because it is the only other format to feature in any iters. */
+static const pixman_format_code_t img_fmt_list[] = {
+ PIXMAN_a8r8g8b8,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_r5g6b5,
+ PIXMAN_a1r5g5b5
+};
+
+/* This is a flag reflecting the environment variable EXACT. It can be used
+ * to ensure that source coordinates corresponding exactly to the "cover" limits
+ * are used, rather than any "near misses". This can, for example, be used in
+ * conjunction with a debugger to ensure that only COVER fast paths are used.
+ */
+static int exact;
+
+static pixman_image_t *
+create_src_image (pixman_format_code_t fmt)
+{
+ pixman_image_t *tmp_img, *img;
+
+ /* We need the left-most and right-most MIN_SRC_WIDTH pixels to have
+ * predictable values, even though fence_image_create_bits() may allocate
+ * an image somewhat larger than that, by an amount that varies depending
+ * upon the page size on the current platform. The solution is to create a
+ * temporary non-fenced image that is exactly MIN_SRC_WIDTH wide and blit it
+ * into the fenced image.
+ */
+ tmp_img = pixman_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT,
+ NULL, 0);
+ if (tmp_img == NULL)
+ return NULL;
+
+ img = fence_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT, TRUE);
+ if (img == NULL)
+ {
+ pixman_image_unref (tmp_img);
+ return NULL;
+ }
+
+ prng_randmemset (tmp_img->bits.bits,
+ tmp_img->bits.rowstride * SRC_HEIGHT * sizeof (uint32_t),
+ 0);
+ image_endian_swap (tmp_img);
+
+ pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img,
+ 0, 0, 0, 0, 0, 0,
+ MIN_SRC_WIDTH, SRC_HEIGHT);
+ pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img,
+ 0, 0, 0, 0, img->bits.width - MIN_SRC_WIDTH, 0,
+ MIN_SRC_WIDTH, SRC_HEIGHT);
+
+ pixman_image_unref (tmp_img);
+
+ return img;
+}
+
+static pixman_fixed_t
+random_scale_factor(void)
+{
+ /* Get a random number with top bit set. */
+ uint32_t f = prng_rand () | 0x80000000u;
+
+ /* In log(2) space, this is still approximately evenly spread between 31
+ * and 32. Divide by sqrt(2) to centre the distribution on 2^31.
+ */
+ f = ((uint64_t) f * INV_SQRT_2_0POINT32_FIXED) >> 32;
+
+ /* Now shift right (ie divide by an integer power of 2) to spread the
+ * distribution between centres at 2^(16 +/- LOG2_MAX_FACTOR).
+ */
+ f >>= 31 - 16 + prng_rand_n (2 * LOG2_MAX_FACTOR + 1) - LOG2_MAX_FACTOR;
+
+ return f;
+}
+
+static pixman_fixed_t
+calc_translate (int dst_size,
+ int src_size,
+ pixman_fixed_t scale,
+ pixman_bool_t low_align,
+ pixman_bool_t bilinear)
+{
+ pixman_fixed_t ref_src, ref_dst, scaled_dst;
+
+ if (low_align)
+ {
+ ref_src = bilinear ? pixman_fixed_1 / 2 : pixman_fixed_e;
+ ref_dst = pixman_fixed_1 / 2;
+ }
+ else
+ {
+ ref_src = pixman_int_to_fixed (src_size) -
+ bilinear * pixman_fixed_1 / 2;
+ ref_dst = pixman_int_to_fixed (dst_size) - pixman_fixed_1 / 2;
+ }
+
+ scaled_dst = ((uint64_t) ref_dst * scale + pixman_fixed_1 / 2) /
+ pixman_fixed_1;
+
+ /* We need the translation to be set such that when ref_dst is fed through
+ * the transformation matrix, we get ref_src as the result.
+ */
+ return ref_src - scaled_dst;
+}
+
+static pixman_fixed_t
+random_offset (void)
+{
+ pixman_fixed_t offset = 0;
+
+ /* Ensure we test the exact case quite a lot */
+ if (prng_rand_n (2))
+ return offset;
+
+ /* What happens when we are close to the edge of the first
+ * interpolation step?
+ */
+ if (prng_rand_n (2))
+ offset += (pixman_fixed_1 >> BILINEAR_INTERPOLATION_BITS) - 16;
+
+ /* Try fine-grained variations */
+ offset += prng_rand_n (32);
+
+ /* Test in both directions */
+ if (prng_rand_n (2))
+ offset = -offset;
+
+ return offset;
+}
+
+static void
+check_transform (pixman_image_t *dst_img,
+ pixman_image_t *src_img,
+ pixman_transform_t *transform,
+ pixman_bool_t bilinear)
+{
+ pixman_vector_t v1, v2;
+
+ v1.vector[0] = pixman_fixed_1 / 2;
+ v1.vector[1] = pixman_fixed_1 / 2;
+ v1.vector[2] = pixman_fixed_1;
+ assert (pixman_transform_point (transform, &v1));
+
+ v2.vector[0] = pixman_int_to_fixed (dst_img->bits.width) -
+ pixman_fixed_1 / 2;
+ v2.vector[1] = pixman_int_to_fixed (dst_img->bits.height) -
+ pixman_fixed_1 / 2;
+ v2.vector[2] = pixman_fixed_1;
+ assert (pixman_transform_point (transform, &v2));
+
+ if (bilinear)
+ {
+ assert (v1.vector[0] >= pixman_fixed_1 / 2);
+ assert (v1.vector[1] >= pixman_fixed_1 / 2);
+ assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width) -
+ pixman_fixed_1 / 2);
+ assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height) -
+ pixman_fixed_1 / 2);
+ }
+ else
+ {
+ assert (v1.vector[0] >= pixman_fixed_e);
+ assert (v1.vector[1] >= pixman_fixed_e);
+ assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width));
+ assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height));
+ }
+}
+
+static uint32_t
+test_cover (int testnum, int verbose)
+{
+ pixman_fixed_t x_scale, y_scale;
+ pixman_bool_t left_align, top_align;
+ pixman_bool_t bilinear;
+ pixman_filter_t filter;
+ pixman_op_t op;
+ size_t src_fmt_index;
+ pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
+ pixman_image_t *src_img, *dst_img, *mask_img;
+ pixman_transform_t src_transform, mask_transform;
+ pixman_fixed_t fuzz[4];
+ uint32_t crc32;
+
+ /* We allocate one fenced image for each pixel format up-front. This is to
+ * avoid spending a lot of time on memory management rather than on testing
+ * Pixman optimisations. We need one per thread because the transformation
+ * matrices and filtering are properties of the source and mask images.
+ */
+ static pixman_image_t *src_imgs[ARRAY_LENGTH (img_fmt_list)];
+ static pixman_image_t *mask_bits_img;
+ static pixman_bool_t fence_images_created;
+#ifdef USE_OPENMP
+#pragma omp threadprivate (src_imgs)
+#pragma omp threadprivate (mask_bits_img)
+#pragma omp threadprivate (fence_images_created)
+#endif
+
+ if (!fence_images_created)
+ {
+ int i;
+
+ prng_srand (0);
+
+ for (i = 0; i < ARRAY_LENGTH (img_fmt_list); i++)
+ src_imgs[i] = create_src_image (img_fmt_list[i]);
+
+ mask_bits_img = create_src_image (PIXMAN_a8);
+
+ fence_images_created = TRUE;
+ }
+
+ prng_srand (testnum);
+
+ x_scale = random_scale_factor ();
+ y_scale = random_scale_factor ();
+ left_align = prng_rand_n (2);
+ top_align = prng_rand_n (2);
+ bilinear = prng_rand_n (2);
+ filter = bilinear ? PIXMAN_FILTER_BILINEAR : PIXMAN_FILTER_NEAREST;
+
+ op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];
+
+ dst_fmt = img_fmt_list[prng_rand_n (ARRAY_LENGTH (img_fmt_list))];
+ dst_img = pixman_image_create_bits (dst_fmt, DST_WIDTH, DST_HEIGHT,
+ NULL, 0);
+ prng_randmemset (dst_img->bits.bits,
+ dst_img->bits.rowstride * DST_HEIGHT * sizeof (uint32_t),
+ 0);
+ image_endian_swap (dst_img);
+
+ src_fmt_index = prng_rand_n (ARRAY_LENGTH (img_fmt_list));
+ src_fmt = img_fmt_list[src_fmt_index];
+ src_img = src_imgs[src_fmt_index];
+ pixman_image_set_filter (src_img, filter, NULL, 0);
+ pixman_transform_init_scale (&src_transform, x_scale, y_scale);
+ src_transform.matrix[0][2] = calc_translate (dst_img->bits.width,
+ src_img->bits.width,
+ x_scale, left_align, bilinear);
+ src_transform.matrix[1][2] = calc_translate (dst_img->bits.height,
+ src_img->bits.height,
+ y_scale, top_align, bilinear);
+
+ if (prng_rand_n (2))
+ {
+ /* No mask */
+ mask_fmt = PIXMAN_null;
+ mask_img = NULL;
+ }
+ else if (prng_rand_n (2))
+ {
+ /* a8 bitmap mask */
+ mask_fmt = PIXMAN_a8;
+ mask_img = mask_bits_img;
+ pixman_image_set_filter (mask_img, filter, NULL, 0);
+ pixman_transform_init_scale (&mask_transform, x_scale, y_scale);
+ mask_transform.matrix[0][2] = calc_translate (dst_img->bits.width,
+ mask_img->bits.width,
+ x_scale, left_align,
+ bilinear);
+ mask_transform.matrix[1][2] = calc_translate (dst_img->bits.height,
+ mask_img->bits.height,
+ y_scale, top_align,
+ bilinear);
+ }
+ else
+ {
+ /* Solid mask */
+ pixman_color_t color;
+ memset (&color, 0xAA, sizeof color);
+ mask_fmt = PIXMAN_solid;
+ mask_img = pixman_image_create_solid_fill (&color);
+ }
+
+ if (!exact)
+ {
+ int i = 0;
+
+ while (i < 4)
+ fuzz[i++] = random_offset ();
+
+ src_transform.matrix[0][2] += fuzz[0];
+ src_transform.matrix[1][2] += fuzz[1];
+ mask_transform.matrix[0][2] += fuzz[2];
+ mask_transform.matrix[1][2] += fuzz[3];
+ }
+
+ pixman_image_set_transform (src_img, &src_transform);
+ if (mask_fmt == PIXMAN_a8)
+ pixman_image_set_transform (mask_img, &mask_transform);
+
+ if (verbose)
+ {
+ printf ("op=%s\n", operator_name (op));
+ printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n",
+ format_name (src_fmt), format_name (dst_fmt),
+ format_name (mask_fmt));
+ printf ("x_scale=0x%08X, y_scale=0x%08X, align %s/%s, %s\n",
+ x_scale, y_scale,
+ left_align ? "left" : "right", top_align ? "top" : "bottom",
+ bilinear ? "bilinear" : "nearest");
+
+ if (!exact)
+ {
+ int i = 0;
+
+ printf ("fuzz factors");
+ while (i < 4)
+ printf (" %d", fuzz[i++]);
+ printf ("\n");
+ }
+ }
+
+ if (exact)
+ {
+ check_transform (dst_img, src_img, &src_transform, bilinear);
+ if (mask_fmt == PIXMAN_a8)
+ check_transform (dst_img, mask_img, &mask_transform, bilinear);
+ }
+
+ pixman_image_composite (op, src_img, mask_img, dst_img,
+ 0, 0, 0, 0, 0, 0,
+ dst_img->bits.width, dst_img->bits.height);
+
+ if (verbose)
+ print_image (dst_img);
+
+ crc32 = compute_crc32_for_image (0, dst_img);
+
+ pixman_image_unref (dst_img);
+ if (mask_fmt == PIXMAN_solid)
+ pixman_image_unref (mask_img);
+
+ return crc32;
+}
+
+#if BILINEAR_INTERPOLATION_BITS == 7
+#define CHECKSUM_FUZZ 0x6B56F607
+#define CHECKSUM_EXACT 0xA669F4A3
+#elif BILINEAR_INTERPOLATION_BITS == 4
+#define CHECKSUM_FUZZ 0x83119ED0
+#define CHECKSUM_EXACT 0x0D3382CD
+#else
+#define CHECKSUM_FUZZ 0x00000000
+#define CHECKSUM_EXACT 0x00000000
+#endif
+
+int
+main (int argc, const char *argv[])
+{
+ unsigned long page_size;
+
+ page_size = fence_get_page_size ();
+ if (page_size == 0 || page_size > 16 * 1024)
+ return 77; /* automake SKIP */
+
+ exact = getenv ("EXACT") != NULL;
+ if (exact)
+ printf ("Doing plots that are exactly aligned to boundaries\n");
+
+ return fuzzer_test_main ("cover", 2000000,
+ exact ? CHECKSUM_EXACT : CHECKSUM_FUZZ,
+ test_cover, argc, argv);
+}
diff --git a/lib/pixman/test/fence-image-self-test.c b/lib/pixman/test/fence-image-self-test.c
new file mode 100644
index 000000000..c80b3cf31
--- /dev/null
+++ b/lib/pixman/test/fence-image-self-test.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright © 2015 Raspberry Pi Foundation
+ *
+ * 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 the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "utils.h"
+
+
+#if FENCE_MALLOC_ACTIVE && defined (HAVE_SIGACTION)
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+pixman_bool_t verbose;
+
+static void
+segv_handler (int sig, siginfo_t *si, void *unused)
+{
+ _exit (EXIT_SUCCESS);
+}
+
+static void
+die (const char *msg, int err)
+{
+ if (err)
+ perror (msg);
+ else
+ fprintf (stderr, "%s\n", msg);
+
+ abort ();
+}
+
+static void
+prinfo (const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!verbose)
+ return;
+
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+}
+
+static void
+do_expect_signal (void (*fn)(void *), void *data)
+{
+ struct sigaction sa;
+
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_sigaction = segv_handler;
+ if (sigaction (SIGSEGV, &sa, NULL) == -1)
+ die ("sigaction failed", errno);
+ if (sigaction (SIGBUS, &sa, NULL) == -1)
+ die ("sigaction failed", errno);
+
+ (*fn)(data);
+
+ _exit (EXIT_FAILURE);
+}
+
+/* Check that calling fn(data) causes a segmentation fault.
+ *
+ * You cannot portably return from a SIGSEGV handler in any way,
+ * so we fork, and do the test in the child process. Child's
+ * exit status will reflect the result. Its SEGV handler causes it
+ * to exit with success, and return failure otherwise.
+ */
+static pixman_bool_t
+expect_signal (void (*fn)(void *), void *data)
+{
+ pid_t pid, wp;
+ int status;
+
+ pid = fork ();
+ if (pid == -1)
+ die ("fork failed", errno);
+
+ if (pid == 0)
+ do_expect_signal (fn, data); /* never returns */
+
+ wp = waitpid (pid, &status, 0);
+ if (wp != pid)
+ die ("waitpid did not work", wp == -1 ? errno : 0);
+
+ if (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_SUCCESS)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+read_u8 (void *data)
+{
+ volatile uint8_t *p = data;
+
+ *p;
+}
+
+static pixman_bool_t
+test_read_fault (uint8_t *p, int offset)
+{
+ prinfo ("*(uint8_t *)(%p + %d)", p, offset);
+
+ if (expect_signal (read_u8, p + offset))
+ {
+ prinfo ("\tsignal OK\n");
+
+ return TRUE;
+ }
+
+ prinfo ("\tFAILED\n");
+
+ return FALSE;
+}
+
+static void
+test_read_ok (uint8_t *p, int offset)
+{
+ prinfo ("*(uint8_t *)(%p + %d)", p, offset);
+
+ /* If fails, SEGV. */
+ read_u8 (p + offset);
+
+ prinfo ("\tOK\n");
+}
+
+static pixman_bool_t
+test_read_faults (pixman_image_t *image)
+{
+ pixman_bool_t ok = TRUE;
+ pixman_format_code_t format = pixman_image_get_format (image);
+ int width = pixman_image_get_width (image);
+ int height = pixman_image_get_height (image);
+ int stride = pixman_image_get_stride (image);
+ uint8_t *p = (void *)pixman_image_get_data (image);
+ int row_bytes = width * PIXMAN_FORMAT_BPP (format) / 8;
+
+ prinfo ("%s %dx%d, row %d B, stride %d B:\n",
+ format_name (format), width, height, row_bytes, stride);
+
+ assert (height > 3);
+
+ test_read_ok (p, 0);
+ test_read_ok (p, row_bytes - 1);
+ test_read_ok (p, stride);
+ test_read_ok (p, stride + row_bytes - 1);
+ test_read_ok (p, 2 * stride);
+ test_read_ok (p, 2 * stride + row_bytes - 1);
+ test_read_ok (p, 3 * stride);
+ test_read_ok (p, (height - 1) * stride + row_bytes - 1);
+
+ ok &= test_read_fault (p, -1);
+ ok &= test_read_fault (p, row_bytes);
+ ok &= test_read_fault (p, stride - 1);
+ ok &= test_read_fault (p, stride + row_bytes);
+ ok &= test_read_fault (p, 2 * stride - 1);
+ ok &= test_read_fault (p, 2 * stride + row_bytes);
+ ok &= test_read_fault (p, 3 * stride - 1);
+ ok &= test_read_fault (p, height * stride);
+
+ return ok;
+}
+
+static pixman_bool_t
+test_image_faults (pixman_format_code_t format, int min_width, int height)
+{
+ pixman_bool_t ok;
+ pixman_image_t *image;
+
+ image = fence_image_create_bits (format, min_width, height, TRUE);
+ ok = test_read_faults (image);
+ pixman_image_unref (image);
+
+ return ok;
+}
+
+int
+main (int argc, char **argv)
+{
+ pixman_bool_t ok = TRUE;
+
+ if (getenv ("VERBOSE") != NULL)
+ verbose = TRUE;
+
+ ok &= test_image_faults (PIXMAN_a8r8g8b8, 7, 5);
+ ok &= test_image_faults (PIXMAN_r8g8b8, 7, 5);
+ ok &= test_image_faults (PIXMAN_r5g6b5, 7, 5);
+ ok &= test_image_faults (PIXMAN_a8, 7, 5);
+ ok &= test_image_faults (PIXMAN_a4, 7, 5);
+ ok &= test_image_faults (PIXMAN_a1, 7, 5);
+
+ if (ok)
+ return EXIT_SUCCESS;
+
+ return EXIT_FAILURE;
+}
+
+#else /* FENCE_MALLOC_ACTIVE */
+
+int
+main (int argc, char **argv)
+{
+ /* Automake return code for test SKIP. */
+ return 77;
+}
+
+#endif /* FENCE_MALLOC_ACTIVE */
diff --git a/lib/pixman/test/lowlevel-blt-bench.c b/lib/pixman/test/lowlevel-blt-bench.c
index 1049e21e7..28ff66991 100644
--- a/lib/pixman/test/lowlevel-blt-bench.c
+++ b/lib/pixman/test/lowlevel-blt-bench.c
@@ -55,7 +55,7 @@ uint32_t *dst;
uint32_t *src;
uint32_t *mask;
-double bandwidth = 0;
+double bandwidth = 0.0;
double
bench_memcpy ()
@@ -90,6 +90,7 @@ bench_memcpy ()
static pixman_bool_t use_scaling = FALSE;
static pixman_filter_t filter = PIXMAN_FILTER_NEAREST;
+static pixman_bool_t use_csv_output = FALSE;
/* nearly 1x scale factor */
static pixman_transform_t m =
@@ -165,7 +166,7 @@ call_func (pixman_composite_func_t func,
func (0, &info);
}
-void
+double
noinline
bench_L (pixman_op_t op,
pixman_image_t * src_img,
@@ -204,9 +205,11 @@ bench_L (pixman_op_t op,
call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 63 - x, 0, width, lines_count);
}
qx = q;
+
+ return (double)n * lines_count * width;
}
-void
+double
noinline
bench_M (pixman_op_t op,
pixman_image_t * src_img,
@@ -224,6 +227,8 @@ bench_M (pixman_op_t op,
x = 0;
call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 1, 0, WIDTH - 64, HEIGHT);
}
+
+ return (double)n * (WIDTH - 64) * HEIGHT;
}
double
@@ -366,15 +371,24 @@ bench_RT (pixman_op_t op,
return pix_cnt;
}
+static double
+Mpx_per_sec (double pix_cnt, double t1, double t2, double t3)
+{
+ double overhead = t2 - t1;
+ double testtime = t3 - t2;
+
+ return pix_cnt / (testtime - overhead) / 1e6;
+}
+
void
-bench_composite (char * testname,
- int src_fmt,
- int src_flags,
- int op,
- int mask_fmt,
- int mask_flags,
- int dst_fmt,
- double npix)
+bench_composite (const char *testname,
+ int src_fmt,
+ int src_flags,
+ int op,
+ int mask_fmt,
+ int mask_flags,
+ int dst_fmt,
+ double npix)
{
pixman_image_t * src_img;
pixman_image_t * dst_img;
@@ -461,9 +475,9 @@ bench_composite (char * testname,
dst,
XWIDTH * 4);
-
- printf ("%24s %c", testname, func != pixman_image_composite_wrapper ?
- '-' : '=');
+ if (!use_csv_output)
+ printf ("%24s %c", testname, func != pixman_image_composite_wrapper ?
+ '-' : '=');
memcpy (dst, src, BUFSIZE);
memcpy (src, dst, BUFSIZE);
@@ -476,13 +490,15 @@ bench_composite (char * testname,
n = 1 + npix / (l1test_width * 8);
t1 = gettime ();
#if EXCLUDE_OVERHEAD
- bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1);
+ pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1);
#endif
t2 = gettime ();
- bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1);
+ pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1);
t3 = gettime ();
- printf (" L1:%7.2f", (double)n * l1test_width * 1 /
- ((t3 - t2) - (t2 - t1)) / 1000000.);
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" L1:%7.2f", Mpx_per_sec (pix_cnt, t1, t2, t3));
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -495,13 +511,15 @@ bench_composite (char * testname,
n = 1 + npix / (l1test_width * nlines);
t1 = gettime ();
#if EXCLUDE_OVERHEAD
- bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines);
+ pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines);
#endif
t2 = gettime ();
- bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines);
+ pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines);
t3 = gettime ();
- printf (" L2:%7.2f", (double)n * l1test_width * nlines /
- ((t3 - t2) - (t2 - t1)) / 1000000.);
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" L2:%7.2f", Mpx_per_sec (pix_cnt, t1, t2, t3));
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -510,14 +528,16 @@ bench_composite (char * testname,
n = 1 + npix / (WIDTH * HEIGHT);
t1 = gettime ();
#if EXCLUDE_OVERHEAD
- bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
+ pix_cnt = bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
#endif
t2 = gettime ();
- bench_M (op, src_img, mask_img, dst_img, n, func);
+ pix_cnt = bench_M (op, src_img, mask_img, dst_img, n, func);
t3 = gettime ();
- printf (" M:%6.2f (%6.2f%%)",
- ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1))) / 1000000.,
- ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) );
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" M:%6.2f (%6.2f%%)", Mpx_per_sec (pix_cnt, t1, t2, t3),
+ (pix_cnt / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) );
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -531,7 +551,10 @@ bench_composite (char * testname,
t2 = gettime ();
pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, func);
t3 = gettime ();
- printf (" HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" HT:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3));
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -545,7 +568,10 @@ bench_composite (char * testname,
t2 = gettime ();
pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, func);
t3 = gettime ();
- printf (" VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" VT:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3));
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -559,7 +585,10 @@ bench_composite (char * testname,
t2 = gettime ();
pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
t3 = gettime ();
- printf (" R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+ if (use_csv_output)
+ printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" R:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3));
fflush (stdout);
memcpy (dst, src, BUFSIZE);
@@ -573,7 +602,10 @@ bench_composite (char * testname,
t2 = gettime ();
pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
t3 = gettime ();
- printf (" RT:%6.2f (%4.0fKops/s)\n", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000., (double) n / ((t3 - t2) * 1000));
+ if (use_csv_output)
+ printf ("%g\n", Mpx_per_sec (pix_cnt, t1, t2, t3));
+ else
+ printf (" RT:%6.2f (%4.0fKops/s)\n", Mpx_per_sec (pix_cnt, t1, t2, t3), (double) n / ((t3 - t2) * 1000));
if (mask_img) {
pixman_image_unref (mask_img);
@@ -587,17 +619,20 @@ bench_composite (char * testname,
#define PIXMAN_OP_OUT_REV (PIXMAN_OP_OUT_REVERSE)
-struct
+struct test_entry
{
- char *testname;
- int src_fmt;
- int src_flags;
- int op;
- int mask_fmt;
- int mask_flags;
- int dst_fmt;
-}
-tests_tbl[] =
+ const char *testname;
+ int src_fmt;
+ int src_flags;
+ int op;
+ int mask_fmt;
+ int mask_flags;
+ int dst_fmt;
+};
+
+typedef struct test_entry test_entry_t;
+
+static const test_entry_t tests_tbl[] =
{
{ "add_8_8_8", PIXMAN_a8, 0, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
{ "add_n_8_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
@@ -713,51 +748,292 @@ tests_tbl[] =
{ "outrev_n_8888_1555_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 },
{ "outrev_n_8888_x888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 },
{ "outrev_n_8888_8888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 },
- { "over_reverse_n_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
+ { "over_reverse_n_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
+ { "in_reverse_8888_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_IN_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
{ "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 },
{ "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
};
-int
-main (int argc, char *argv[])
+static const test_entry_t special_patterns[] =
+{
+ { "add_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
+ { "add_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
+ { "src_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
+ { "src_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
+ { "src_0888_8888_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
+ { "src_0888_0565_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
+ { "src_n_8", PIXMAN_a8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8 },
+ { "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 },
+ { "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
+};
+
+/* Returns the sub-string's end pointer in string. */
+static const char *
+copy_sub_string (char *buf,
+ const char *string,
+ const char *scan_from,
+ const char *end)
{
- double x;
+ const char *delim;
+ size_t n;
+
+ delim = strchr (scan_from, '_');
+ if (!delim)
+ delim = end;
+
+ n = delim - string;
+ strncpy(buf, string, n);
+ buf[n] = '\0';
+
+ return delim;
+}
+
+static pixman_op_t
+parse_longest_operator (char *buf, const char **strp, const char *end)
+{
+ const char *p = *strp;
+ const char *sub_end;
+ const char *best_end = p;
+ pixman_op_t best_op = PIXMAN_OP_NONE;
+ pixman_op_t op;
+
+ while (p < end)
+ {
+ sub_end = copy_sub_string (buf, *strp, p, end);
+ op = operator_from_string (buf);
+ p = sub_end + 1;
+
+ if (op != PIXMAN_OP_NONE)
+ {
+ best_end = p;
+ best_op = op;
+ }
+ }
+
+ *strp = best_end;
+ return best_op;
+}
+
+static pixman_format_code_t
+parse_format (char *buf, const char **p, const char *end)
+{
+ pixman_format_code_t format;
+ const char *delim;
+
+ if (*p >= end)
+ return PIXMAN_null;
+
+ delim = copy_sub_string (buf, *p, *p, end);
+ format = format_from_string (buf);
+
+ if (format != PIXMAN_null)
+ *p = delim + 1;
+
+ return format;
+}
+
+static int
+parse_test_pattern (test_entry_t *test, const char *pattern)
+{
+ const char *p = pattern;
+ const char *end = pattern + strlen (pattern);
+ char buf[1024];
+ pixman_format_code_t format[3];
int i;
- const char *pattern = NULL;
- for (i = 1; i < argc; i++)
+
+ if (strlen (pattern) > sizeof (buf) - 1)
+ return -1;
+
+ /* Special cases that the parser cannot produce. */
+ for (i = 0; i < ARRAY_LENGTH (special_patterns); i++)
{
- if (argv[i][0] == '-')
- {
- if (strchr (argv[i] + 1, 'b'))
- {
- use_scaling = TRUE;
- filter = PIXMAN_FILTER_BILINEAR;
- }
- else if (strchr (argv[i] + 1, 'n'))
- {
- use_scaling = TRUE;
- filter = PIXMAN_FILTER_NEAREST;
- }
- }
- else
- {
- pattern = argv[i];
- }
+ if (strcmp (pattern, special_patterns[i].testname) == 0)
+ {
+ *test = special_patterns[i];
+ return 0;
+ }
}
- if (!pattern)
+ test->testname = pattern;
+
+ /* Extract operator, may contain delimiters,
+ * so take the longest string that matches.
+ */
+ test->op = parse_longest_operator (buf, &p, end);
+ if (test->op == PIXMAN_OP_NONE)
+ return -1;
+
+ /* extract up to three pixel formats */
+ format[0] = parse_format (buf, &p, end);
+ format[1] = parse_format (buf, &p, end);
+ format[2] = parse_format (buf, &p, end);
+
+ if (format[0] == PIXMAN_null || format[1] == PIXMAN_null)
+ return -1;
+
+ /* recognize CA flag */
+ test->mask_flags = 0;
+ if (p < end)
{
- printf ("Usage: lowlevel-blt-bench [-b] [-n] pattern\n");
- printf (" -n : benchmark nearest scaling\n");
- printf (" -b : benchmark bilinear scaling\n");
- return 1;
+ if (strcmp (p, "ca") == 0)
+ test->mask_flags |= CA_FLAG;
+ else
+ return -1; /* trailing garbage */
}
- src = aligned_malloc (4096, BUFSIZE * 3);
- memset (src, 0xCC, BUFSIZE * 3);
- dst = src + (BUFSIZE / 4);
- mask = dst + (BUFSIZE / 4);
+ test->src_fmt = format[0];
+ if (format[2] == PIXMAN_null)
+ {
+ test->mask_fmt = PIXMAN_null;
+ test->dst_fmt = format[1];
+ }
+ else
+ {
+ test->mask_fmt = format[1];
+ test->dst_fmt = format[2];
+ }
+
+ test->src_flags = 0;
+ if (test->src_fmt == PIXMAN_solid)
+ {
+ test->src_fmt = PIXMAN_a8r8g8b8;
+ test->src_flags |= SOLID_FLAG;
+ }
+
+ if (test->mask_fmt == PIXMAN_solid)
+ {
+ if (test->mask_flags & CA_FLAG)
+ test->mask_fmt = PIXMAN_a8r8g8b8;
+ else
+ test->mask_fmt = PIXMAN_a8;
+
+ test->mask_flags |= SOLID_FLAG;
+ }
+
+ return 0;
+}
+static int
+check_int (int got, int expected, const char *name, const char *field)
+{
+ if (got == expected)
+ return 0;
+
+ printf ("%s: %s failure: expected %d, got %d.\n",
+ name, field, expected, got);
+
+ return 1;
+}
+
+static int
+check_format (int got, int expected, const char *name, const char *field)
+{
+ if (got == expected)
+ return 0;
+
+ printf ("%s: %s failure: expected %s (%#x), got %s (%#x).\n",
+ name, field,
+ format_name (expected), expected,
+ format_name (got), got);
+
+ return 1;
+}
+
+static void
+parser_self_test (void)
+{
+ const test_entry_t *ent;
+ test_entry_t test;
+ int fails = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+ {
+ ent = &tests_tbl[i];
+
+ if (parse_test_pattern (&test, ent->testname) < 0)
+ {
+ printf ("parsing failed for '%s'\n", ent->testname);
+ fails++;
+ continue;
+ }
+
+ fails += check_format (test.src_fmt, ent->src_fmt,
+ ent->testname, "src_fmt");
+ fails += check_format (test.mask_fmt, ent->mask_fmt,
+ ent->testname, "mask_fmt");
+ fails += check_format (test.dst_fmt, ent->dst_fmt,
+ ent->testname, "dst_fmt");
+ fails += check_int (test.src_flags, ent->src_flags,
+ ent->testname, "src_flags");
+ fails += check_int (test.mask_flags, ent->mask_flags,
+ ent->testname, "mask_flags");
+ fails += check_int (test.op, ent->op, ent->testname, "op");
+ }
+
+ if (fails)
+ {
+ printf ("Parser self-test failed.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (!use_csv_output)
+ printf ("Parser self-test complete.\n");
+}
+
+static void
+print_test_details (const test_entry_t *test)
+{
+ printf ("%s: %s, src %s%s, mask %s%s%s, dst %s\n",
+ test->testname,
+ operator_name (test->op),
+ format_name (test->src_fmt),
+ test->src_flags & SOLID_FLAG ? " solid" : "",
+ format_name (test->mask_fmt),
+ test->mask_flags & SOLID_FLAG ? " solid" : "",
+ test->mask_flags & CA_FLAG ? " CA" : "",
+ format_name (test->dst_fmt));
+}
+
+static void
+run_one_test (const char *pattern, double bandwidth_, pixman_bool_t prdetails)
+{
+ test_entry_t test;
+
+ if (parse_test_pattern (&test, pattern) < 0)
+ {
+ printf ("Error: Could not parse the test pattern '%s'.\n", pattern);
+ return;
+ }
+
+ if (prdetails)
+ {
+ print_test_details (&test);
+ printf ("---\n");
+ }
+
+ bench_composite (pattern,
+ test.src_fmt,
+ test.src_flags,
+ test.op,
+ test.mask_fmt,
+ test.mask_flags,
+ test.dst_fmt,
+ bandwidth_ / 8);
+}
+
+static void
+run_default_tests (double bandwidth_)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+ run_one_test (tests_tbl[i].testname, bandwidth_, FALSE);
+}
+
+static void
+print_explanation (void)
+{
printf ("Benchmark for a set of most commonly used functions\n");
printf ("---\n");
printf ("All results are presented in millions of pixels per second\n");
@@ -785,9 +1061,14 @@ main (int argc, char *argv[])
printf ("RT - as R, but %dx%d average sized rectangles are copied\n",
TINYWIDTH, TINYWIDTH);
printf ("---\n");
- bandwidth = x = bench_memcpy ();
+}
+
+static void
+print_speed_scaling (double bw)
+{
printf ("reference memcpy speed = %.1fMB/s (%.1fMP/s for 32bpp fills)\n",
- x / 1000000., x / 4000000);
+ bw / 1000000., bw / 4000000);
+
if (use_scaling)
{
printf ("---\n");
@@ -798,23 +1079,85 @@ main (int argc, char *argv[])
else
printf ("UNKNOWN scaling\n");
}
+
printf ("---\n");
+}
- for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+static void
+usage (const char *progname)
+{
+ printf ("Usage: %s [-b] [-n] [-c] [-m M] pattern\n", progname);
+ printf (" -n : benchmark nearest scaling\n");
+ printf (" -b : benchmark bilinear scaling\n");
+ printf (" -c : print output as CSV data\n");
+ printf (" -m M : set reference memcpy speed to M MB/s instead of measuring it\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ const char *pattern = NULL;
+
+ for (i = 1; i < argc; i++)
{
- if (strcmp (pattern, "all") == 0 || strcmp (tests_tbl[i].testname, pattern) == 0)
+ if (argv[i][0] == '-')
{
- bench_composite (tests_tbl[i].testname,
- tests_tbl[i].src_fmt,
- tests_tbl[i].src_flags,
- tests_tbl[i].op,
- tests_tbl[i].mask_fmt,
- tests_tbl[i].mask_flags,
- tests_tbl[i].dst_fmt,
- bandwidth/8);
+ if (strchr (argv[i] + 1, 'b'))
+ {
+ use_scaling = TRUE;
+ filter = PIXMAN_FILTER_BILINEAR;
+ }
+ else if (strchr (argv[i] + 1, 'n'))
+ {
+ use_scaling = TRUE;
+ filter = PIXMAN_FILTER_NEAREST;
+ }
+
+ if (strchr (argv[i] + 1, 'c'))
+ use_csv_output = TRUE;
+
+ if (strcmp (argv[i], "-m") == 0 && i + 1 < argc)
+ bandwidth = atof (argv[++i]) * 1e6;
}
+ else
+ {
+ if (pattern)
+ {
+ pattern = NULL;
+ printf ("Error: extra arguments given.\n");
+ break;
+ }
+ pattern = argv[i];
+ }
+ }
+
+ if (!pattern)
+ {
+ usage (argv[0]);
+ return 1;
}
+ parser_self_test ();
+
+ src = aligned_malloc (4096, BUFSIZE * 3);
+ memset (src, 0xCC, BUFSIZE * 3);
+ dst = src + (BUFSIZE / 4);
+ mask = dst + (BUFSIZE / 4);
+
+ if (!use_csv_output)
+ print_explanation ();
+
+ if (bandwidth < 1.0)
+ bandwidth = bench_memcpy ();
+ if (!use_csv_output)
+ print_speed_scaling (bandwidth);
+
+ if (strcmp (pattern, "all") == 0)
+ run_default_tests (bandwidth);
+ else
+ run_one_test (pattern, bandwidth, !use_csv_output);
+
free (src);
return 0;
}
diff --git a/lib/pixman/test/pixel-test.c b/lib/pixman/test/pixel-test.c
index 8c525d202..7dc0eff3f 100644
--- a/lib/pixman/test/pixel-test.c
+++ b/lib/pixman/test/pixel-test.c
@@ -33,68 +33,2764 @@ struct pixel_combination_t
pixman_op_t op;
pixman_format_code_t src_format;
uint32_t src_pixel;
+ pixman_format_code_t mask_format;
+ uint32_t mask_pixel;
pixman_format_code_t dest_format;
uint32_t dest_pixel;
};
static const pixel_combination_t regressions[] =
{
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffc3ff,
+ PIXMAN_a8, 0x7b,
+ PIXMAN_a8r8g8b8, 0xff00c300,
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb5,
+ PIXMAN_a4r4g4b4, 0xe3ff,
+ PIXMAN_a2r2g2b2, 0x2e
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa6,
+ PIXMAN_a8r8g8b8, 0x2b00ff00,
+ PIXMAN_a4r4g4b4, 0x7e
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0x27000013,
+ PIXMAN_a2r2g2b2, 0x80,
+ PIXMAN_a4r4g4b4, 0x9d
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xe6f7,
+ PIXMAN_a2r2g2b2, 0xad,
+ PIXMAN_a4r4g4b4, 0x71
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0xff4f70ff,
+ PIXMAN_r5g6b5, 0xb828,
+ PIXMAN_a8r8g8b8, 0xcac400
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa9,
+ PIXMAN_a4r4g4b4, 0x41c2,
+ PIXMAN_a8r8g8b8, 0xffff2b
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x89,
+ PIXMAN_a8r8g8b8, 0x977cff61,
+ PIXMAN_a4r4g4b4, 0x36
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x81,
+ PIXMAN_r5g6b5, 0x6f9e,
+ PIXMAN_a4r4g4b4, 0x1eb
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb5,
+ PIXMAN_a4r4g4b4, 0xe247,
+ PIXMAN_a8r8g8b8, 0xffbaff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x97,
+ PIXMAN_a2r2g2b2, 0x9d,
+ PIXMAN_a2r2g2b2, 0x21
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb4,
+ PIXMAN_a2r2g2b2, 0x90,
+ PIXMAN_a8r8g8b8, 0xc0fd5c
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0xdf00ff70,
+ PIXMAN_a8r8g8b8, 0x2597ff27,
+ PIXMAN_a4r4g4b4, 0xf3
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb7,
+ PIXMAN_r3g3b2, 0xb1,
+ PIXMAN_a8r8g8b8, 0x9f4bcc
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xf39e,
+ PIXMAN_r5g6b5, 0x34,
+ PIXMAN_a8r8g8b8, 0xf6ae00
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0x3aff1dff,
+ PIXMAN_a2r2g2b2, 0x64,
+ PIXMAN_a8r8g8b8, 0x94ffb4
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa4,
+ PIXMAN_a2r2g2b2, 0x8a,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa5,
+ PIXMAN_a4r4g4b4, 0x1a,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb4,
+ PIXMAN_a2r2g2b2, 0xca,
+ PIXMAN_a4r4g4b4, 0x7b
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xbd,
+ PIXMAN_a4r4g4b4, 0xff37,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x96,
+ PIXMAN_a2r2g2b2, 0xbb,
+ PIXMAN_a8r8g8b8, 0x96ffff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x89,
+ PIXMAN_r3g3b2, 0x92,
+ PIXMAN_a4r4g4b4, 0xa8c
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xa95b,
+ PIXMAN_a2r2g2b2, 0x68,
+ PIXMAN_a8r8g8b8, 0x38ff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x90,
+ PIXMAN_a8r8g8b8, 0x53bd00ef,
+ PIXMAN_a8r8g8b8, 0xff0003
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1f5ffff,
+ PIXMAN_r3g3b2, 0x22,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x10000b6,
+ PIXMAN_a8r8g8b8, 0x9645,
+ PIXMAN_r5g6b5, 0x6
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x172ff00,
+ PIXMAN_a4r4g4b4, 0xff61,
+ PIXMAN_r3g3b2, 0xc
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x281ffc8,
+ PIXMAN_r5g6b5, 0x39b8,
+ PIXMAN_r5g6b5, 0x13
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100a2ff,
+ PIXMAN_a4r4g4b4, 0x6500,
+ PIXMAN_a2r2g2b2, 0x5
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff51,
+ PIXMAN_r5g6b5, 0x52ff,
+ PIXMAN_a2r2g2b2, 0x14
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x150d500,
+ PIXMAN_a8r8g8b8, 0x6200b7ff,
+ PIXMAN_a8r8g8b8, 0x1f5200
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2a9a700,
+ PIXMAN_a8r8g8b8, 0xf7003400,
+ PIXMAN_a8r8g8b8, 0x2200
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x200ffff,
+ PIXMAN_r5g6b5, 0x81ff,
+ PIXMAN_r5g6b5, 0x1f
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ff00ff,
+ PIXMAN_r5g6b5, 0x3f00,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3ff1aa4,
+ PIXMAN_a4r4g4b4, 0x2200,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x280ff2c,
+ PIXMAN_r3g3b2, 0xc6,
+ PIXMAN_a8r8g8b8, 0xfdfd44fe
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x13aff1d,
+ PIXMAN_a2r2g2b2, 0x4b,
+ PIXMAN_r5g6b5, 0x12a1
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2ffff88,
+ PIXMAN_a8r8g8b8, 0xff3a49,
+ PIXMAN_r5g6b5, 0xf7df
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1009700,
+ PIXMAN_a2r2g2b2, 0x56,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1aacbff,
+ PIXMAN_a4r4g4b4, 0x84,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x100b1ff,
+ PIXMAN_a2r2g2b2, 0xf5,
+ PIXMAN_a8r8g8b8, 0xfea89cff
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ff0000,
+ PIXMAN_r5g6b5, 0x6800,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x10064ff,
+ PIXMAN_r3g3b2, 0x61,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1bb00ff,
+ PIXMAN_r5g6b5, 0x76b5,
+ PIXMAN_a4r4g4b4, 0x500
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ffff41,
+ PIXMAN_r5g6b5, 0x7100,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ff1231,
+ PIXMAN_a8r8g8b8, 0x381089,
+ PIXMAN_r5g6b5, 0x38a5
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x16e5c49,
+ PIXMAN_a8r8g8b8, 0x4dfa3694,
+ PIXMAN_a8r8g8b8, 0x211c16
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x134ff62,
+ PIXMAN_a2r2g2b2, 0x14,
+ PIXMAN_r3g3b2, 0x8
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x300ffeb,
+ PIXMAN_r3g3b2, 0xc7,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x3ff8bff,
+ PIXMAN_r3g3b2, 0x3e,
+ PIXMAN_a8r8g8b8, 0x3008baa
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff00ff,
+ PIXMAN_a4r4g4b4, 0x3466,
+ PIXMAN_a4r4g4b4, 0x406
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ddc027,
+ PIXMAN_a4r4g4b4, 0x7d00,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2ffff00,
+ PIXMAN_a8r8g8b8, 0xc92cfb52,
+ PIXMAN_a4r4g4b4, 0x200
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ff116a,
+ PIXMAN_a4r4g4b4, 0x6000,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r5g6b5, 0x2f95,
+ PIXMAN_r5g6b5, 0x795
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffff00,
+ PIXMAN_a4r4g4b4, 0x354a,
+ PIXMAN_r5g6b5, 0x3180
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1d7ff00,
+ PIXMAN_a4r4g4b4, 0xd6ff,
+ PIXMAN_a8r8g8b8, 0xffff0700
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1bc5db7,
+ PIXMAN_r5g6b5, 0x944f,
+ PIXMAN_a4r4g4b4, 0xff05
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x185ffd9,
+ PIXMAN_a2r2g2b2, 0x9c,
+ PIXMAN_r5g6b5, 0x3c07
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1fa7f61,
+ PIXMAN_a8r8g8b8, 0xff31ff00,
+ PIXMAN_r3g3b2, 0xd2
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1c4ff00,
+ PIXMAN_r3g3b2, 0xb,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ff00ff,
+ PIXMAN_a8r8g8b8, 0x3f3caeda,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ff00,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_r5g6b5, 0xe0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff68ff,
+ PIXMAN_a4r4g4b4, 0x8046,
+ PIXMAN_r5g6b5, 0xec
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x100ff28,
+ PIXMAN_a8r8g8b8, 0x4c00,
+ PIXMAN_r5g6b5, 0x260
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_a4r4g4b4, 0xd92a,
+ PIXMAN_a8r8g8b8, 0x2200
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100289a,
+ PIXMAN_a8r8g8b8, 0x74ffb8ff,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1baff00,
+ PIXMAN_r5g6b5, 0x4e9d,
+ PIXMAN_r5g6b5, 0x3000
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1fcffad,
+ PIXMAN_r5g6b5, 0x42d7,
+ PIXMAN_a8r8g8b8, 0x1c6ffe5
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x183ff00,
+ PIXMAN_r3g3b2, 0x7e,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x2ff0076,
+ PIXMAN_a8r8g8b8, 0x2a0000,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3d8bbff,
+ PIXMAN_r5g6b5, 0x6900,
+ PIXMAN_a8r8g8b8, 0x35b0000
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x14f00ff,
+ PIXMAN_r5g6b5, 0xd48,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x28c72df,
+ PIXMAN_a8r8g8b8, 0xff5cff31,
+ PIXMAN_a4r4g4b4, 0x2
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffffff,
+ PIXMAN_a8r8g8b8, 0xffad8020,
+ PIXMAN_r5g6b5, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x100ff00,
+ PIXMAN_a2r2g2b2, 0x76,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1005d00,
+ PIXMAN_r5g6b5, 0x7b04,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x3cdfc3e,
+ PIXMAN_a8r8g8b8, 0x69ec21d3,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x200ffff,
+ PIXMAN_r5g6b5, 0x30ff,
+ PIXMAN_r5g6b5, 0x60ff
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x532fff4,
+ PIXMAN_r5g6b5, 0xcb,
+ PIXMAN_r5g6b5, 0xd9a1
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r3g3b2, 0x5f,
+ PIXMAN_a2r2g2b2, 0x10
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_a8r8g8b8, 0xffd60052,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ff6491,
+ PIXMAN_a8r8g8b8, 0x1e53ff00,
+ PIXMAN_r5g6b5, 0x1862
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_r3g3b2, 0xc7,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x29d0fff,
+ PIXMAN_a4r4g4b4, 0x25ff,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x141760a,
+ PIXMAN_a4r4g4b4, 0x7ec2,
+ PIXMAN_a4r4g4b4, 0x130
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1abedff,
+ PIXMAN_a8r8g8b8, 0x75520068,
+ PIXMAN_r3g3b2, 0x87
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x10000ff,
+ PIXMAN_a8r8g8b8, 0xff00e652,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x16006075,
+ PIXMAN_r5g6b5, 0xc00,
+ PIXMAN_a8r8g8b8, 0x27f0900
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x200ff00,
+ PIXMAN_a8r8g8b8, 0xd1b83f57,
+ PIXMAN_a4r4g4b4, 0xff75
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x14000c4,
+ PIXMAN_a4r4g4b4, 0x96,
+ PIXMAN_a2r2g2b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ff00d1,
+ PIXMAN_r3g3b2, 0x79,
+ PIXMAN_a2r2g2b2, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff00dc,
+ PIXMAN_a4r4g4b4, 0xc5ff,
+ PIXMAN_a2r2g2b2, 0x10
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffb2,
+ PIXMAN_a8r8g8b8, 0x4cff5700,
+ PIXMAN_r3g3b2, 0x48
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1327482,
+ PIXMAN_a8r8g8b8, 0x247ff,
+ PIXMAN_a8r8g8b8, 0x82
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1d0ff00,
+ PIXMAN_r3g3b2, 0xc9,
+ PIXMAN_r5g6b5, 0x240
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x13d35ff,
+ PIXMAN_a2r2g2b2, 0x6d,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffc6b2,
+ PIXMAN_a8r8g8b8, 0x5abe8e3c,
+ PIXMAN_r5g6b5, 0x5a27
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x15700ff,
+ PIXMAN_r3g3b2, 0xdd,
+ PIXMAN_a8r8g8b8, 0x55
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff11ff,
+ PIXMAN_r3g3b2, 0x30,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff00ff,
+ PIXMAN_a2r2g2b2, 0x6d,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1421d5f,
+ PIXMAN_a4r4g4b4, 0xff85,
+ PIXMAN_a8r8g8b8, 0x1420f00
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1d2ffff,
+ PIXMAN_r5g6b5, 0xfc,
+ PIXMAN_r5g6b5, 0x1c
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffff42,
+ PIXMAN_a4r4g4b4, 0x7100,
+ PIXMAN_a4r4g4b4, 0x771
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x25ae3d4,
+ PIXMAN_a8r8g8b8, 0x39ffc99a,
+ PIXMAN_a8r8g8b8, 0x14332f
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff0643,
+ PIXMAN_a8r8g8b8, 0x4c000000,
+ PIXMAN_r5g6b5, 0x4802
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1966a00,
+ PIXMAN_r3g3b2, 0x46,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x387ff59,
+ PIXMAN_r5g6b5, 0x512c,
+ PIXMAN_r5g6b5, 0x120
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1f7ffb0,
+ PIXMAN_r5g6b5, 0x63b8,
+ PIXMAN_a8r8g8b8, 0x1000089
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x185841c,
+ PIXMAN_a2r2g2b2, 0x5c,
+ PIXMAN_a8r8g8b8, 0x8400
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffc3ff,
+ PIXMAN_a8r8g8b8, 0xff7b,
+ PIXMAN_a8r8g8b8, 0xff00c300
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff7500,
+ PIXMAN_a2r2g2b2, 0x47,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1002361,
+ PIXMAN_a2r2g2b2, 0x7e,
+ PIXMAN_r5g6b5, 0x64
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x10000b6,
+ PIXMAN_a8r8g8b8, 0x59004463,
+ PIXMAN_a4r4g4b4, 0xffa7
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff5a49,
+ PIXMAN_a8r8g8b8, 0xff3fff2b,
+ PIXMAN_a8r8g8b8, 0x13f000c
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x3ffecfc,
+ PIXMAN_r3g3b2, 0x3c,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1630044,
+ PIXMAN_a2r2g2b2, 0x63,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1d2ff58,
+ PIXMAN_a8r8g8b8, 0x8f77ff,
+ PIXMAN_a4r4g4b4, 0x705
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x14dffff,
+ PIXMAN_a2r2g2b2, 0x9a,
+ PIXMAN_a8r8g8b8, 0x1a0000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ff92,
+ PIXMAN_a4r4g4b4, 0x540c,
+ PIXMAN_r5g6b5, 0x2a6
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_a4r4g4b4, 0xddd5,
+ PIXMAN_a4r4g4b4, 0xdd0
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r5g6b5, 0xff8c,
+ PIXMAN_a4r4g4b4, 0xff0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r3g3b2, 0x66,
+ PIXMAN_r5g6b5, 0x7d1f
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_a4r4g4b4, 0xff5b,
+ PIXMAN_a8r8g8b8, 0x5500
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2ed2dff,
+ PIXMAN_r5g6b5, 0x7ae7,
+ PIXMAN_r3g3b2, 0xce
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1b13205,
+ PIXMAN_a8r8g8b8, 0x35ffff00,
+ PIXMAN_r5g6b5, 0x2040
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1e60dff,
+ PIXMAN_a4r4g4b4, 0x760f,
+ PIXMAN_a2r2g2b2, 0x11
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x10000ff,
+ PIXMAN_a4r4g4b4, 0x3,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_a8r8g8b8, 0x6600,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x30000fa,
+ PIXMAN_a4r4g4b4, 0x23b7,
+ PIXMAN_a8r8g8b8, 0x21
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r3g3b2, 0x60,
+ PIXMAN_r3g3b2, 0x60
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3b31b30,
+ PIXMAN_r3g3b2, 0x2e,
+ PIXMAN_a8r8g8b8, 0x3000c20
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x160ffff,
+ PIXMAN_a4r4g4b4, 0xff42,
+ PIXMAN_r3g3b2, 0xed
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x172ffff,
+ PIXMAN_a4r4g4b4, 0x5100,
+ PIXMAN_r3g3b2, 0x29
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x16300ff,
+ PIXMAN_a4r4g4b4, 0x5007,
+ PIXMAN_a8r8g8b8, 0x77
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2ffff3a,
+ PIXMAN_a8r8g8b8, 0x26640083,
+ PIXMAN_a4r4g4b4, 0x220
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x106ff60,
+ PIXMAN_r5g6b5, 0xdce,
+ PIXMAN_a8r8g8b8, 0x100ba00
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100e7ff,
+ PIXMAN_r5g6b5, 0xa00,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2b500f1,
+ PIXMAN_a4r4g4b4, 0x7339,
+ PIXMAN_a8r8g8b8, 0x1000091
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff00ff,
+ PIXMAN_a4r4g4b4, 0xc863,
+ PIXMAN_r5g6b5, 0x6
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1ffffca,
+ PIXMAN_a8r8g8b8, 0x8b4cf000,
+ PIXMAN_r3g3b2, 0xd2
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1fffe00,
+ PIXMAN_r3g3b2, 0x88,
+ PIXMAN_r3g3b2, 0x8
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x16f0000,
+ PIXMAN_a2r2g2b2, 0x59,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x377ff43,
+ PIXMAN_a4r4g4b4, 0x2a,
+ PIXMAN_a8r8g8b8, 0x2d
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x11dffff,
+ PIXMAN_r3g3b2, 0xcb,
+ PIXMAN_r3g3b2, 0x8
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_r5g6b5, 0xbdab,
+ PIXMAN_a4r4g4b4, 0xbb0
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff3343,
+ PIXMAN_a8r8g8b8, 0x7a00ffff,
+ PIXMAN_a2r2g2b2, 0xd
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ebff4b,
+ PIXMAN_r3g3b2, 0x26,
+ PIXMAN_r3g3b2, 0x24
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2c1b3ff,
+ PIXMAN_a8r8g8b8, 0x3000152a,
+ PIXMAN_r3g3b2, 0x24
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1a7ffff,
+ PIXMAN_r3g3b2, 0x9,
+ PIXMAN_r5g6b5, 0x24a
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x4ff00ec,
+ PIXMAN_a8r8g8b8, 0x1da4961e,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff25ff,
+ PIXMAN_a8r8g8b8, 0x64b0ff00,
+ PIXMAN_r5g6b5, 0x606c
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1fd62ff,
+ PIXMAN_a4r4g4b4, 0x76b1,
+ PIXMAN_r5g6b5, 0x716e
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x194ffde,
+ PIXMAN_r5g6b5, 0x47ff,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x108ffff,
+ PIXMAN_a8r8g8b8, 0xffffff66,
+ PIXMAN_r5g6b5, 0xff0c
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x5ffffff,
+ PIXMAN_r5g6b5, 0xdf,
+ PIXMAN_r5g6b5, 0xc0
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ad31,
+ PIXMAN_a2r2g2b2, 0xc5,
+ PIXMAN_a4r4g4b4, 0x31
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff34,
+ PIXMAN_a8r8g8b8, 0x6a57c491,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1fffff1,
+ PIXMAN_r3g3b2, 0xaf,
+ PIXMAN_r5g6b5, 0xb01e
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff67ff,
+ PIXMAN_a4r4g4b4, 0x50ff,
+ PIXMAN_a8r8g8b8, 0x552255
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x11bffff,
+ PIXMAN_r5g6b5, 0xef0c,
+ PIXMAN_r5g6b5, 0xc
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x16cf37d,
+ PIXMAN_a4r4g4b4, 0xc561,
+ PIXMAN_r5g6b5, 0x2301
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffff9c,
+ PIXMAN_a4r4g4b4, 0x2700,
+ PIXMAN_a8r8g8b8, 0xffff
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x200f322,
+ PIXMAN_a8r8g8b8, 0xff3c7e,
+ PIXMAN_r5g6b5, 0x2
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1f14a33,
+ PIXMAN_a8r8g8b8, 0x26cff79,
+ PIXMAN_r3g3b2, 0xf9
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x11d922c,
+ PIXMAN_r3g3b2, 0xab,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_a2r2g2b2, 0xf5,
+ PIXMAN_r3g3b2, 0x9
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x18697ff,
+ PIXMAN_a4r4g4b4, 0x5700,
+ PIXMAN_r5g6b5, 0xfa6d
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x12000fc,
+ PIXMAN_a2r2g2b2, 0x41,
+ PIXMAN_a8r8g8b8, 0xb0054
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x100ccff,
+ PIXMAN_a4r4g4b4, 0x657e,
+ PIXMAN_r5g6b5, 0x3b1
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffff1f,
+ PIXMAN_a2r2g2b2, 0xa6,
+ PIXMAN_r5g6b5, 0x2a0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x11fff82,
+ PIXMAN_a4r4g4b4, 0xff94,
+ PIXMAN_a8r8g8b8, 0x1010123
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x154bd19,
+ PIXMAN_a4r4g4b4, 0xb600,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x10000ff,
+ PIXMAN_r5g6b5, 0x8e,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x21aff00,
+ PIXMAN_r5g6b5, 0x71ff,
+ PIXMAN_r3g3b2, 0xf2
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ad00a7,
+ PIXMAN_a4r4g4b4, 0x23,
+ PIXMAN_a8r8g8b8, 0x21
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x100ff00,
+ PIXMAN_r5g6b5, 0xb343,
+ PIXMAN_r3g3b2, 0xc
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x3ffa500,
+ PIXMAN_a8r8g8b8, 0x1af5b4,
+ PIXMAN_a8r8g8b8, 0xff1abc00
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ffff11,
+ PIXMAN_a8r8g8b8, 0x9f334f,
+ PIXMAN_a8r8g8b8, 0x9f0005
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2c75971,
+ PIXMAN_a4r4g4b4, 0x3900,
+ PIXMAN_a4r4g4b4, 0x211
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ff49,
+ PIXMAN_a8r8g8b8, 0x813dc25e,
+ PIXMAN_r5g6b5, 0x667d
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x10000ff,
+ PIXMAN_a4r4g4b4, 0x4bff,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x20ebcff,
+ PIXMAN_r5g6b5, 0xc9ff,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_r5g6b5, 0x51ff,
+ PIXMAN_r3g3b2, 0x44
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffd158,
+ PIXMAN_a8r8g8b8, 0x7d88ffce,
+ PIXMAN_r3g3b2, 0x6c
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1425e21,
+ PIXMAN_a2r2g2b2, 0xa5,
+ PIXMAN_r5g6b5, 0xe1
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x14b00ff,
+ PIXMAN_a8r8g8b8, 0xbe95004b,
+ PIXMAN_r5g6b5, 0x9
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x14fc0cd,
+ PIXMAN_a8r8g8b8, 0x2d12b78b,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff8230,
+ PIXMAN_a2r2g2b2, 0x4c,
+ PIXMAN_r3g3b2, 0x44
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff31ff,
+ PIXMAN_a2r2g2b2, 0x14,
+ PIXMAN_a8r8g8b8, 0x551000
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x17800ff,
+ PIXMAN_a4r4g4b4, 0x22,
+ PIXMAN_a8r8g8b8, 0x22
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x14500ff,
+ PIXMAN_a4r4g4b4, 0x6400,
+ PIXMAN_r5g6b5, 0xff78
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ff9d,
+ PIXMAN_r3g3b2, 0xcd,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x3ff00ff,
+ PIXMAN_a4r4g4b4, 0xf269,
+ PIXMAN_a4r4g4b4, 0x200
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ff28b8,
+ PIXMAN_a4r4g4b4, 0x33ff,
+ PIXMAN_r5g6b5, 0x3000
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1006278,
+ PIXMAN_a8r8g8b8, 0x8a7f18,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffcb00,
+ PIXMAN_a4r4g4b4, 0x7900,
+ PIXMAN_a2r2g2b2, 0x14
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x115ff00,
+ PIXMAN_a8r8g8b8, 0x508d,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x3ff30b5,
+ PIXMAN_r5g6b5, 0x2e60,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x182fffb,
+ PIXMAN_r3g3b2, 0x1,
+ PIXMAN_a8r8g8b8, 0x1000054
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x16fff00,
+ PIXMAN_r5g6b5, 0x7bc0,
+ PIXMAN_a8r8g8b8, 0x367900
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1d95dd8,
+ PIXMAN_a4r4g4b4, 0xfff5,
+ PIXMAN_r5g6b5, 0xff09
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ff3cdc,
+ PIXMAN_a8r8g8b8, 0x3bda45ff,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x13900f8,
+ PIXMAN_a8r8g8b8, 0x7e00ffff,
+ PIXMAN_a4r4g4b4, 0xff00
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x10ea9ff,
+ PIXMAN_a8r8g8b8, 0xff34ff22,
+ PIXMAN_r5g6b5, 0xff52
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2002e99,
+ PIXMAN_a4r4g4b4, 0x3000,
+ PIXMAN_r5g6b5, 0x43
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_r5g6b5, 0x19ff,
+ PIXMAN_r3g3b2, 0x3
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_a8r8g8b8, 0xffff4251,
+ PIXMAN_a2r2g2b2, 0x4
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x121c9ff,
+ PIXMAN_a4r4g4b4, 0xd2,
+ PIXMAN_a4r4g4b4, 0x2
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ff4d,
+ PIXMAN_a2r2g2b2, 0x5e,
+ PIXMAN_a2r2g2b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x29ab4ff,
+ PIXMAN_r3g3b2, 0x47,
+ PIXMAN_a8r8g8b8, 0x1900
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffc1ac,
+ PIXMAN_a8r8g8b8, 0xee4ed0ac,
+ PIXMAN_a8r8g8b8, 0x1009d74
+ },
+ { PIXMAN_OP_CONJOINT_IN_REVERSE,
+ PIXMAN_a8r8g8b8, 0x269dffdc,
+ PIXMAN_a8r8g8b8, 0xff0b00e0,
+ PIXMAN_a8r8g8b8, 0x2a200ff
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffffff,
+ PIXMAN_a4r4g4b4, 0x3200,
+ PIXMAN_r3g3b2, 0x24
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x100ffed,
+ PIXMAN_a8r8g8b8, 0x67004eff,
+ PIXMAN_a2r2g2b2, 0x5
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2fffd6a,
+ PIXMAN_a8r8g8b8, 0xc9003bff,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x253ff00,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_r5g6b5, 0xe0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x13600ad,
+ PIXMAN_r5g6b5, 0x35ae,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffa8ff,
+ PIXMAN_a8r8g8b8, 0xff5f00,
+ PIXMAN_r3g3b2, 0xe0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x10067ff,
+ PIXMAN_a4r4g4b4, 0x450d,
+ PIXMAN_a2r2g2b2, 0x1
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1ff01ff,
+ PIXMAN_r3g3b2, 0x77,
+ PIXMAN_r5g6b5, 0x6800
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x11da4ff,
+ PIXMAN_r5g6b5, 0x83c9,
+ PIXMAN_a4r4g4b4, 0x44
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffd4ff,
+ PIXMAN_r3g3b2, 0xaa,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ff0000,
+ PIXMAN_a8r8g8b8, 0x71002a,
+ PIXMAN_a4r4g4b4, 0x700
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1d7ffff,
+ PIXMAN_r5g6b5, 0x3696,
+ PIXMAN_a4r4g4b4, 0x200
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffffc8,
+ PIXMAN_r5g6b5, 0xe900,
+ PIXMAN_a8r8g8b8, 0x2000
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff004a,
+ PIXMAN_r3g3b2, 0x48,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x3ffe969,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_r5g6b5, 0xc0
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x300ff73,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_a8r8g8b8, 0x3000073
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ff93ff,
+ PIXMAN_a8r8g8b8, 0x61fc7d2b,
+ PIXMAN_a4r4g4b4, 0x2
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x11bffff,
+ PIXMAN_a4r4g4b4, 0xffb4,
+ PIXMAN_r5g6b5, 0x8
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1e9e100,
+ PIXMAN_a2r2g2b2, 0x56,
+ PIXMAN_a2r2g2b2, 0x14
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x3ffb656,
+ PIXMAN_r3g3b2, 0x4,
+ PIXMAN_a4r4g4b4, 0xff99
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ff00,
+ PIXMAN_r3g3b2, 0x68,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1006dff,
+ PIXMAN_a2r2g2b2, 0x5d,
+ PIXMAN_a8r8g8b8, 0xff00ff55
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x11c00cb,
+ PIXMAN_a2r2g2b2, 0x44,
+ PIXMAN_a4r4g4b4, 0x4
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1d0ff86,
+ PIXMAN_r3g3b2, 0x5c,
+ PIXMAN_a8r8g8b8, 0x3c0000
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2f25fff,
+ PIXMAN_r3g3b2, 0x36,
+ PIXMAN_a8r8g8b8, 0x2a444aa
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x134af85,
+ PIXMAN_r3g3b2, 0x29,
+ PIXMAN_r5g6b5, 0xf300
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x13398af,
+ PIXMAN_r3g3b2, 0xa5,
+ PIXMAN_a4r4g4b4, 0x13
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff57ff,
+ PIXMAN_a4r4g4b4, 0x252c,
+ PIXMAN_r3g3b2, 0x40
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x115ffff,
+ PIXMAN_r5g6b5, 0xffe3,
+ PIXMAN_r5g6b5, 0x3303
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffff00,
+ PIXMAN_r5g6b5, 0x6300,
+ PIXMAN_r3g3b2, 0x6c
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x4ccff9c,
+ PIXMAN_r5g6b5, 0xcc,
+ PIXMAN_a8r8g8b8, 0x400003d
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffc6dd,
+ PIXMAN_r5g6b5, 0x9bff,
+ PIXMAN_r5g6b5, 0x5bff
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x14fff95,
+ PIXMAN_r3g3b2, 0x46,
+ PIXMAN_a8r8g8b8, 0x1000063
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1e6b700,
+ PIXMAN_r5g6b5, 0xc1ff,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffff54,
+ PIXMAN_a8r8g8b8, 0x2e00ff,
+ PIXMAN_r5g6b5, 0x2800
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3ffffff,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_r5g6b5, 0xe0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1003550,
+ PIXMAN_r5g6b5, 0xffcc,
+ PIXMAN_r5g6b5, 0x1e0
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ffff74,
+ PIXMAN_r3g3b2, 0x28,
+ PIXMAN_a8r8g8b8, 0xfe2f49d7
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1e35100,
+ PIXMAN_r3g3b2, 0x57,
+ PIXMAN_r5g6b5, 0x4000
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x268ffa3,
+ PIXMAN_a4r4g4b4, 0x30,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x35700f8,
+ PIXMAN_r5g6b5, 0xa4,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x3ce1dff,
+ PIXMAN_r5g6b5, 0x2a5e,
+ PIXMAN_a8r8g8b8, 0x210000
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x494a7ff,
+ PIXMAN_a8r8g8b8, 0x1bffe400,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x10026d9,
+ PIXMAN_a8r8g8b8, 0xec00621f,
+ PIXMAN_r5g6b5, 0x63
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ff99,
+ PIXMAN_a8r8g8b8, 0xf334ff,
+ PIXMAN_a4r4g4b4, 0x30
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffc200,
+ PIXMAN_a8r8g8b8, 0x1e0000ff,
+ PIXMAN_a8r8g8b8, 0x1e1700
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff00ff,
+ PIXMAN_r3g3b2, 0x4b,
+ PIXMAN_r5g6b5, 0x4818
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2e800ff,
+ PIXMAN_a4r4g4b4, 0xd3,
+ PIXMAN_a4r4g4b4, 0xec
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x19a001f,
+ PIXMAN_r3g3b2, 0x76,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1cb00c3,
+ PIXMAN_a4r4g4b4, 0x5cff,
+ PIXMAN_r5g6b5, 0x4008
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff0000,
+ PIXMAN_r3g3b2, 0x2a,
+ PIXMAN_r5g6b5, 0xc5fb
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_a8r8g8b8, 0xea005a88,
+ PIXMAN_r3g3b2, 0xb3
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ffea,
+ PIXMAN_a4r4g4b4, 0x54eb,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x179ffff,
+ PIXMAN_r3g3b2, 0xa4,
+ PIXMAN_a8r8g8b8, 0x2400
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x17ad226,
+ PIXMAN_r3g3b2, 0xa4,
+ PIXMAN_r5g6b5, 0xe0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ff01,
+ PIXMAN_a2r2g2b2, 0x25,
+ PIXMAN_a4r4g4b4, 0x50
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x20000ff,
+ PIXMAN_a8r8g8b8, 0x2b00c127,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x200ff96,
+ PIXMAN_a4r4g4b4, 0x2300,
+ PIXMAN_r3g3b2, 0x6
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x200ffff,
+ PIXMAN_r3g3b2, 0x87,
+ PIXMAN_r5g6b5, 0x5bc8
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1fffff2,
+ PIXMAN_r3g3b2, 0x7e,
+ PIXMAN_a2r2g2b2, 0xe
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1ff8b00,
+ PIXMAN_a4r4g4b4, 0xd500,
+ PIXMAN_r3g3b2, 0x40
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ffffff,
+ PIXMAN_a8r8g8b8, 0x1bff38,
+ PIXMAN_a4r4g4b4, 0xf0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x158ff39,
+ PIXMAN_a4r4g4b4, 0x75dd,
+ PIXMAN_a8r8g8b8, 0xdd31
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1009b70,
+ PIXMAN_a4r4g4b4, 0xff40,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x12fb43f,
+ PIXMAN_a4r4g4b4, 0x69ff,
+ PIXMAN_a2r2g2b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff95,
+ PIXMAN_a2r2g2b2, 0x84,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x200d188,
+ PIXMAN_r5g6b5, 0xde6,
+ PIXMAN_r5g6b5, 0x3
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2c70000,
+ PIXMAN_r5g6b5, 0x24fa,
+ PIXMAN_a8r8g8b8, 0x21a0000
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x100ff24,
+ PIXMAN_a4r4g4b4, 0x835,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x10000cd,
+ PIXMAN_a2r2g2b2, 0x7f,
+ PIXMAN_a2r2g2b2, 0x1
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x379ffff,
+ PIXMAN_a8r8g8b8, 0x23ffff00,
+ PIXMAN_r5g6b5, 0x4eda
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x172e3ff,
+ PIXMAN_r3g3b2, 0xa6,
+ PIXMAN_r5g6b5, 0x100
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100f5ad,
+ PIXMAN_a4r4g4b4, 0x7908,
+ PIXMAN_a2r2g2b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100fff9,
+ PIXMAN_a2r2g2b2, 0xf1,
+ PIXMAN_r3g3b2, 0x1
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1abff00,
+ PIXMAN_r5g6b5, 0x31ff,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x112ffd1,
+ PIXMAN_r3g3b2, 0x9,
+ PIXMAN_a2r2g2b2, 0xdd
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ffbf,
+ PIXMAN_r3g3b2, 0x2c,
+ PIXMAN_a4r4g4b4, 0x60
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffb7ff,
+ PIXMAN_r3g3b2, 0x6b,
+ PIXMAN_a4r4g4b4, 0x630
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x20005ff,
+ PIXMAN_a4r4g4b4, 0x8462,
+ PIXMAN_r5g6b5, 0xb1e8
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff5b00,
+ PIXMAN_r5g6b5, 0x70ff,
+ PIXMAN_r3g3b2, 0x60
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffffc3,
+ PIXMAN_r3g3b2, 0x39,
+ PIXMAN_a8r8g8b8, 0x200db41
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x306ffff,
+ PIXMAN_a8r8g8b8, 0xdcffff1f,
+ PIXMAN_a8r8g8b8, 0x306ff00
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x193daff,
+ PIXMAN_a8r8g8b8, 0x69000000,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x2a200ff,
+ PIXMAN_a8r8g8b8, 0x183aff00,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100f1a5,
+ PIXMAN_a8r8g8b8, 0xb5fc21ff,
+ PIXMAN_r5g6b5, 0xfe00
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1630019,
+ PIXMAN_a8r8g8b8, 0x6affc400,
+ PIXMAN_r5g6b5, 0x56ff
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff8bc2,
+ PIXMAN_r3g3b2, 0xee,
+ PIXMAN_r5g6b5, 0x1c0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x260ffff,
+ PIXMAN_a4r4g4b4, 0x3f00,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x169ffed,
+ PIXMAN_a8r8g8b8, 0xffffff3f,
+ PIXMAN_a8r8g8b8, 0x169ff00
+ },
+ { PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x154c181,
+ PIXMAN_a4r4g4b4, 0x5100,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1e09c00,
+ PIXMAN_r5g6b5, 0xca00,
+ PIXMAN_a4r4g4b4, 0xb00
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ff8dff,
+ PIXMAN_a8r8g8b8, 0x610038ff,
+ PIXMAN_a8r8g8b8, 0x1001f02
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1e400ff,
+ PIXMAN_a4r4g4b4, 0x66bd,
+ PIXMAN_r3g3b2, 0x68
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x25362ff,
+ PIXMAN_a4r4g4b4, 0x31ff,
+ PIXMAN_a8r8g8b8, 0x111433
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3ad0039,
+ PIXMAN_r3g3b2, 0x26,
+ PIXMAN_a8r8g8b8, 0x3000026
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2e442ef,
+ PIXMAN_r3g3b2, 0x32,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1720000,
+ PIXMAN_a8r8g8b8, 0x55fdea00,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x14bb0d7,
+ PIXMAN_a8r8g8b8, 0x7fffff47,
+ PIXMAN_a2r2g2b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x13dffff,
+ PIXMAN_a8r8g8b8, 0xa3860672,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x120495a,
+ PIXMAN_a4r4g4b4, 0x407e,
+ PIXMAN_a8r8g8b8, 0x54
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff8fff,
+ PIXMAN_a2r2g2b2, 0x29,
+ PIXMAN_r5g6b5, 0xa
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100a31a,
+ PIXMAN_a4r4g4b4, 0xde4c,
+ PIXMAN_a4r4g4b4, 0x1
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1d4008c,
+ PIXMAN_r3g3b2, 0x79,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ff0000,
+ PIXMAN_a4r4g4b4, 0x7de4,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1b27e62,
+ PIXMAN_a4r4g4b4, 0x7941,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x300ff00,
+ PIXMAN_a8r8g8b8, 0xfcff255e,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x2ff00b8,
+ PIXMAN_a8r8g8b8, 0x19ff718d,
+ PIXMAN_r5g6b5, 0x1802
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x235ff13,
+ PIXMAN_a8r8g8b8, 0x34bcd9ff,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1006400,
+ PIXMAN_a4r4g4b4, 0x7000,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff8bff,
+ PIXMAN_a4r4g4b4, 0xfff4,
+ PIXMAN_a4r4g4b4, 0xf80
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x24630ff,
+ PIXMAN_a8r8g8b8, 0x1f00000b,
+ PIXMAN_a8r8g8b8, 0x9061f
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff8a00,
+ PIXMAN_a8r8g8b8, 0x79ffab00,
+ PIXMAN_r5g6b5, 0x7a00
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x19807ff,
+ PIXMAN_a4r4g4b4, 0x6794,
+ PIXMAN_a8r8g8b8, 0xff002e00
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x10000da,
+ PIXMAN_a4r4g4b4, 0xf864,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffffde,
+ PIXMAN_a2r2g2b2, 0x94,
+ PIXMAN_a8r8g8b8, 0x1000000
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x200c800,
+ PIXMAN_r5g6b5, 0xe9d4,
+ PIXMAN_a8r8g8b8, 0x2c00
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff00c9,
+ PIXMAN_r3g3b2, 0x4c,
+ PIXMAN_r5g6b5, 0x4800
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x122d5ff,
+ PIXMAN_r5g6b5, 0x418b,
+ PIXMAN_a4r4g4b4, 0x25
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ffff55,
+ PIXMAN_a2r2g2b2, 0x1c,
+ PIXMAN_a8r8g8b8, 0xff00
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x135ffff,
+ PIXMAN_r5g6b5, 0x39c4,
+ PIXMAN_r5g6b5, 0xb7
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x100d2c3,
+ PIXMAN_r3g3b2, 0x2a,
+ PIXMAN_a8r8g8b8, 0x3c00
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x17268ff,
+ PIXMAN_a8r8g8b8, 0x7c00ffff,
+ PIXMAN_r5g6b5, 0x318f
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff00ff,
+ PIXMAN_r3g3b2, 0x68,
+ PIXMAN_r3g3b2, 0xb4
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x200ffff,
+ PIXMAN_r5g6b5, 0xff86,
+ PIXMAN_a8r8g8b8, 0x200f300
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x18a23ff,
+ PIXMAN_a2r2g2b2, 0x44,
+ PIXMAN_a4r4g4b4, 0x205
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x16bff23,
+ PIXMAN_a8r8g8b8, 0x31fd00ff,
+ PIXMAN_r3g3b2, 0x7
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x137d1ff,
+ PIXMAN_a4r4g4b4, 0x56c1,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff5bff,
+ PIXMAN_a4r4g4b4, 0xfff4,
+ PIXMAN_a4r4g4b4, 0xf50
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x15c6b00,
+ PIXMAN_a8r8g8b8, 0x7d008a,
+ PIXMAN_a4r4g4b4, 0x200
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x12091ff,
+ PIXMAN_a8r8g8b8, 0xb74cff6b,
+ PIXMAN_a2r2g2b2, 0x8
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff5bff,
+ PIXMAN_a8r8g8b8, 0xff6ddce8,
+ PIXMAN_a2r2g2b2, 0x10
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_a4r4g4b4, 0xffb7,
+ PIXMAN_a4r4g4b4, 0xb0
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x173ffff,
+ PIXMAN_r5g6b5, 0xff2c,
+ PIXMAN_a4r4g4b4, 0x6
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x17102ff,
+ PIXMAN_a8r8g8b8, 0x955bff66,
+ PIXMAN_a8r8g8b8, 0x280066
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x3c7ff24,
+ PIXMAN_r5g6b5, 0xc4,
+ PIXMAN_r5g6b5, 0x163
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100c2a6,
+ PIXMAN_r5g6b5, 0xa9b9,
+ PIXMAN_a4r4g4b4, 0x8
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x26049ff,
+ PIXMAN_a4r4g4b4, 0xb2,
+ PIXMAN_r5g6b5, 0x8904
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2f100ff,
+ PIXMAN_r3g3b2, 0x30,
+ PIXMAN_a8r8g8b8, 0x2220100
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ffff88,
+ PIXMAN_r3g3b2, 0x7e,
+ PIXMAN_r3g3b2, 0x60
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x153ffab,
+ PIXMAN_a8r8g8b8, 0xfd10725a,
+ PIXMAN_r3g3b2, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff00d2,
+ PIXMAN_r5g6b5, 0xff6b,
+ PIXMAN_a8r8g8b8, 0x101014a
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100d965,
+ PIXMAN_a8r8g8b8, 0xff007b00,
+ PIXMAN_r3g3b2, 0xc
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ec0000,
+ PIXMAN_r5g6b5, 0x6fff,
+ PIXMAN_r5g6b5, 0x6000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x19d59a2,
+ PIXMAN_a8r8g8b8, 0x4a00ff7a,
+ PIXMAN_a8r8g8b8, 0x2e1a2f
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1eb0000,
+ PIXMAN_a4r4g4b4, 0x72bc,
+ PIXMAN_r5g6b5, 0x1800
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_a4r4g4b4, 0xc034,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x195ff15,
+ PIXMAN_a4r4g4b4, 0xb7b1,
+ PIXMAN_r5g6b5, 0x4000
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffdf94,
+ PIXMAN_a4r4g4b4, 0x78,
+ PIXMAN_r3g3b2, 0xc
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x26f00ff,
+ PIXMAN_a4r4g4b4, 0xff93,
+ PIXMAN_r5g6b5, 0x1dd2
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2ff3fc5,
+ PIXMAN_r3g3b2, 0x2f,
+ PIXMAN_a8r8g8b8, 0x240000
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1ff696e,
+ PIXMAN_a4r4g4b4, 0x22ff,
+ PIXMAN_r5g6b5, 0x34d
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x10033d9,
+ PIXMAN_a8r8g8b8, 0x38650000,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffff00,
+ PIXMAN_a4r4g4b4, 0x2070,
+ PIXMAN_r5g6b5, 0x2100
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1008746,
+ PIXMAN_a8r8g8b8, 0xb56971,
+ PIXMAN_r5g6b5, 0xc25c
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x144d200,
+ PIXMAN_a4r4g4b4, 0xff42,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1ffffd0,
+ PIXMAN_r5g6b5, 0x5b00,
+ PIXMAN_r3g3b2, 0x4c
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x10000ff,
+ PIXMAN_a8r8g8b8, 0xff006f,
+ PIXMAN_r5g6b5, 0xd
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x10666ff,
+ PIXMAN_a4r4g4b4, 0x39b2,
+ PIXMAN_r5g6b5, 0xa6
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x11a007d,
+ PIXMAN_r3g3b2, 0xf9,
+ PIXMAN_a8r8g8b8, 0x11a0000
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1eb90ee,
+ PIXMAN_r5g6b5, 0xd,
+ PIXMAN_a2r2g2b2, 0x1
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ff42d5,
+ PIXMAN_a4r4g4b4, 0x3400,
+ PIXMAN_r3g3b2, 0x40
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1dfff00,
+ PIXMAN_a8r8g8b8, 0x3ffff9d2,
+ PIXMAN_r5g6b5, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff6500,
+ PIXMAN_a2r2g2b2, 0x56,
+ PIXMAN_r3g3b2, 0x44
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x119ffe6,
+ PIXMAN_r3g3b2, 0x8d,
+ PIXMAN_a4r4g4b4, 0xff00
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x100cd00,
+ PIXMAN_r5g6b5, 0x33ff,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x569ffd7,
+ PIXMAN_r5g6b5, 0x8cc,
+ PIXMAN_r5g6b5, 0xc0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100876a,
+ PIXMAN_a8r8g8b8, 0x575447a5,
+ PIXMAN_r5g6b5, 0x164
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x12d00ff,
+ PIXMAN_a4r4g4b4, 0x3fff,
+ PIXMAN_a4r4g4b4, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ff953b,
+ PIXMAN_a4r4g4b4, 0x2914,
+ PIXMAN_r5g6b5, 0x20a1
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffead4,
+ PIXMAN_a8r8g8b8, 0xff00ea4e,
+ PIXMAN_r3g3b2, 0x5a
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x1ff6400,
+ PIXMAN_a2r2g2b2, 0x99,
+ PIXMAN_r5g6b5, 0xa620
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x17b0084,
+ PIXMAN_r3g3b2, 0xbd,
+ PIXMAN_a4r4g4b4, 0x500
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x4f90bbb,
+ PIXMAN_a8r8g8b8, 0xff00d21f,
+ PIXMAN_a8r8g8b8, 0xfb00fc4a
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ffbb1d,
+ PIXMAN_a8r8g8b8, 0x2dff79ff,
+ PIXMAN_r5g6b5, 0x2c0
+ },
+ { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ffff,
+ PIXMAN_a2r2g2b2, 0x43,
+ PIXMAN_a4r4g4b4, 0x6f
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1f000ff,
+ PIXMAN_a4r4g4b4, 0xb393,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1c60020,
+ PIXMAN_a8r8g8b8, 0x6bffffff,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1727d00,
+ PIXMAN_a2r2g2b2, 0x67,
+ PIXMAN_a4r4g4b4, 0x400
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x14a5194,
+ PIXMAN_a4r4g4b4, 0xd7ff,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x20003fa,
+ PIXMAN_a4r4g4b4, 0x24ff,
+ PIXMAN_a8r8g8b8, 0xffff1550
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1a6ff83,
+ PIXMAN_a4r4g4b4, 0xf400,
+ PIXMAN_r5g6b5, 0x2800
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ffcf00,
+ PIXMAN_r5g6b5, 0x71ff,
+ PIXMAN_a4r4g4b4, 0x30
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x333ffff,
+ PIXMAN_a4r4g4b4, 0x2c00,
+ PIXMAN_r3g3b2, 0x4
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1c2ffe8,
+ PIXMAN_r5g6b5, 0xc200,
+ PIXMAN_a8r8g8b8, 0xfeca41ff
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a2r2g2b2, 0x47,
+ PIXMAN_a8r8g8b8, 0x2ffff00,
+ PIXMAN_a8r8g8b8, 0x3aa0102
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffeb00,
+ PIXMAN_a4r4g4b4, 0xb493,
+ PIXMAN_a4r4g4b4, 0x400
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2afffff,
+ PIXMAN_r5g6b5, 0xcb,
+ PIXMAN_r5g6b5, 0xc0
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x183ff00,
+ PIXMAN_r3g3b2, 0x87,
+ PIXMAN_r5g6b5, 0xae91
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x3ffff00,
+ PIXMAN_a4r4g4b4, 0x2ba4,
+ PIXMAN_r5g6b5, 0x2100
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x215cbc2,
+ PIXMAN_a4r4g4b4, 0xafd3,
+ PIXMAN_a8r8g8b8, 0x115b000
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1853f65,
+ PIXMAN_a8r8g8b8, 0xc68cdc41,
+ PIXMAN_r5g6b5, 0x3
+ },
+ { PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x3ffff8f,
+ PIXMAN_a4r4g4b4, 0x8824,
+ PIXMAN_a4r4g4b4, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x28e08e6,
+ PIXMAN_a8r8g8b8, 0x2cffff31,
+ PIXMAN_r5g6b5, 0x1805
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x1b500be,
+ PIXMAN_r5g6b5, 0xd946,
+ PIXMAN_r5g6b5, 0x9800
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x133ffb3,
+ PIXMAN_a2r2g2b2, 0x42,
+ PIXMAN_a8r8g8b8, 0x11553c
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x21aff81,
+ PIXMAN_r3g3b2, 0xc7,
+ PIXMAN_r5g6b5, 0x120
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x12e004f,
+ PIXMAN_a4r4g4b4, 0xf617,
+ PIXMAN_a4r4g4b4, 0x102
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x164861f,
+ PIXMAN_r3g3b2, 0x4e,
+ PIXMAN_r5g6b5, 0x19c0
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff0eff,
+ PIXMAN_a8r8g8b8, 0xff5c00aa,
+ PIXMAN_r5g6b5, 0x5800
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x1e4c60f,
+ PIXMAN_a8r8g8b8, 0x38ff0e0c,
+ PIXMAN_a4r4g4b4, 0xff2a
+ },
+ { PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff0000,
+ PIXMAN_a8r8g8b8, 0x9f3d6700,
+ PIXMAN_r5g6b5, 0xf3ff
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x205ffd0,
+ PIXMAN_a8r8g8b8, 0xffc22b3b,
+ PIXMAN_a8r8g8b8, 0x2040000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x1ff0059,
+ PIXMAN_r5g6b5, 0x74ff,
+ PIXMAN_a8r8g8b8, 0x1730101
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x29affb8,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_a8r8g8b8, 0x2d25cff
+ },
+ { PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x1ffff8b,
+ PIXMAN_a4r4g4b4, 0xff7b,
+ PIXMAN_r5g6b5, 0x3a0
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2a86ad7,
+ PIXMAN_a4r4g4b4, 0xdc22,
+ PIXMAN_a8r8g8b8, 0x2860000
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x3ff00ff,
+ PIXMAN_r3g3b2, 0x33,
+ PIXMAN_r5g6b5, 0x2000
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1e50063,
+ PIXMAN_a8r8g8b8, 0x35ff95d7,
+ PIXMAN_r3g3b2, 0x20
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x2ffe6ff,
+ PIXMAN_a8r8g8b8, 0x153ef297,
+ PIXMAN_r5g6b5, 0x6d2
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x34ffeff,
+ PIXMAN_a4r4g4b4, 0x2e,
+ PIXMAN_r5g6b5, 0x1d
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2ffeada,
+ PIXMAN_r5g6b5, 0xabc6,
+ PIXMAN_a8r8g8b8, 0xfd15b256
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x100ff00,
+ PIXMAN_a8r8g8b8, 0xcff3f32,
+ PIXMAN_a8r8g8b8, 0x3f00
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x1e1b0f1,
+ PIXMAN_a8r8g8b8, 0xff63ff54,
+ PIXMAN_r3g3b2, 0x5d
+ },
+ { PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_a8r8g8b8, 0x2ffff23,
+ PIXMAN_a8r8g8b8, 0x380094ff,
+ PIXMAN_r5g6b5, 0x3a4b
+ },
+ { PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_a4r4g4b4, 0x1000,
+ PIXMAN_r5g6b5, 0xca,
+ PIXMAN_a8r8g8b8, 0x3434500
+ },
+ { PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_a8r8g8b8, 0x195ffe5,
+ PIXMAN_a4r4g4b4, 0x3a29,
+ PIXMAN_a8r8g8b8, 0x0
+ },
+ { PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_a8r8g8b8, 0x139007a,
+ PIXMAN_a4r4g4b4, 0x4979,
+ PIXMAN_r5g6b5, 0x84
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa9,
+ PIXMAN_a4r4g4b4, 0xfa18,
+ PIXMAN_a8r8g8b8, 0xabff67ff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x94,
+ PIXMAN_a4r4g4b4, 0x5109,
+ PIXMAN_a8r8g8b8, 0x3affffff
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_r5g6b5, 0xd038,
+ PIXMAN_r5g6b5, 0xff00,
+ PIXMAN_r5g6b5, 0xf9a5
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0x543128ff,
+ PIXMAN_a8r8g8b8, 0x7029ff,
+ PIXMAN_a8r8g8b8, 0x316b1d7
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_r5g6b5, 0x53ff,
+ PIXMAN_r5g6b5, 0x72ff,
+ PIXMAN_a8r8g8b8, 0xffffdeff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0x5b00002b,
+ PIXMAN_a4r4g4b4, 0xc3,
+ PIXMAN_a8r8g8b8, 0x23530be
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0xcefc0041,
+ PIXMAN_a8r8g8b8, 0xf60d02,
+ PIXMAN_a8r8g8b8, 0x1f2ffe5
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_r5g6b5, 0xffdb,
+ PIXMAN_r5g6b5, 0xc700,
+ PIXMAN_r5g6b5, 0x654
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_r5g6b5, 0xffc6,
+ PIXMAN_r5g6b5, 0xff09,
+ PIXMAN_r5g6b5, 0xfe58
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x95,
+ PIXMAN_r5g6b5, 0x1b4a,
+ PIXMAN_a8r8g8b8, 0xab234cff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x95,
+ PIXMAN_a4r4g4b4, 0x5e99,
+ PIXMAN_a8r8g8b8, 0x3b1c1cdd
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_r5g6b5, 0x22,
+ PIXMAN_r5g6b5, 0xd00,
+ PIXMAN_r5g6b5, 0xfbb1
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_r5g6b5, 0xffc8,
+ PIXMAN_a8r8g8b8, 0xa1a3ffff,
+ PIXMAN_r5g6b5, 0x44a
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0xffff7cff,
+ PIXMAN_r5g6b5, 0x900,
+ PIXMAN_a8r8g8b8, 0xffff94ec
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xa7,
+ PIXMAN_r5g6b5, 0xff,
+ PIXMAN_a8r8g8b8, 0xaa00cffe
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0x85,
+ PIXMAN_r5g6b5, 0xffb3,
+ PIXMAN_a8r8g8b8, 0xaaffff4a
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a8r8g8b8, 0x3500a118,
+ PIXMAN_a4r4g4b4, 0x9942,
+ PIXMAN_a8r8g8b8, 0x01ff405e
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xb5,
+ PIXMAN_x4a4, 0xe,
+ PIXMAN_a8r8g8b8, 0xffbaff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xe872,
+ PIXMAN_x2r10g10b10, 0xa648ff00,
+ PIXMAN_a2r10g10b10, 0x14ff00e8,
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x4d2db34,
+ PIXMAN_a8, 0x19,
+ PIXMAN_r5g6b5, 0x9700,
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x2ff0076,
+ PIXMAN_a8r8g8b8, 0x2a0000,
+ PIXMAN_r3g3b2, 0x0,
+ },
+ { PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_a8r8g8b8, 0x14f00ff,
+ PIXMAN_r5g6b5, 0xd48,
+ PIXMAN_a4r4g4b4, 0x0,
+ },
+ { PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_a8r8g8b8, 0x3d8bbff,
+ PIXMAN_r5g6b5, 0x6900,
+ PIXMAN_a8r8g8b8, 0x0,
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x2ff00ff,
+ PIXMAN_a4r4g4b4, 0x2300,
+ PIXMAN_r3g3b2, 0x0,
+ },
+ { PIXMAN_OP_SATURATE,
+ PIXMAN_a8r8g8b8, 0x4d2db34,
+ PIXMAN_a8r8g8b8, 0xff0019ff,
+ PIXMAN_r5g6b5, 0x9700,
+ },
+ { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_a8r8g8b8, 0x100ac05,
+ PIXMAN_r3g3b2, 0xef,
+ PIXMAN_a2r2g2b2, 0xff,
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a2r2g2b2, 0xbf,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x7e
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r5g6b5, 0xffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x33
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_a8r8g8b8, 0x84c4ffd7,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xffddff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a8r8g8b8, 0xff6e56,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x20ff1ade
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a4r4g4b4, 0xfe0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xbdff
+ },
+ { PIXMAN_OP_SCREEN,
+ PIXMAN_a8r8g8b8, 0x9671ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x43
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a2r2g2b2, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x39ff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_r5g6b5, 0xffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x1968
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a4r4g4b4, 0x4247,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xd8ffff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_r5g6b5, 0xff00,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x79
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r3g3b2, 0xe0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x39
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a8r8g8b8, 0xfff8,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0xff
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_r5g6b5, 0x75fc,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x11ff,
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_r3g3b2, 0x52,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0xc627
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0x9f2b,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x4b00e7f5
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a8r8g8b8, 0x00dfff5c,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x5e0f,
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_a8r8g8b8, 0xff00121b,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x3776
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_r5g6b5, 0x03e0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x01003c00,
+ },
{ PIXMAN_OP_OVER,
PIXMAN_a8r8g8b8, 0x0f00c300,
+ PIXMAN_null, 0x00,
PIXMAN_x14r6g6b6, 0x003c0,
},
{ PIXMAN_OP_DISJOINT_XOR,
PIXMAN_a4r4g4b4, 0xd0c0,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x5300ea00,
},
{ PIXMAN_OP_OVER,
PIXMAN_a8r8g8b8, 0x20c6bf00,
+ PIXMAN_null, 0x00,
PIXMAN_r5g6b5, 0xb9ff
},
{ PIXMAN_OP_OVER,
PIXMAN_a8r8g8b8, 0x204ac7ff,
+ PIXMAN_null, 0x00,
PIXMAN_r5g6b5, 0xc1ff
},
{ PIXMAN_OP_OVER_REVERSE,
PIXMAN_r5g6b5, 0xffc3,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x102d00dd
},
{ PIXMAN_OP_OVER_REVERSE,
PIXMAN_r5g6b5, 0x1f00,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x1bdf0c89
},
{ PIXMAN_OP_OVER_REVERSE,
PIXMAN_r5g6b5, 0xf9d2,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x1076bcf7
},
{ PIXMAN_OP_OVER_REVERSE,
PIXMAN_r5g6b5, 0x00c3,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x1bfe9ae5
},
{ PIXMAN_OP_OVER_REVERSE,
PIXMAN_r5g6b5, 0x09ff,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x0b00c16c
},
{ PIXMAN_OP_DISJOINT_ATOP,
PIXMAN_a2r2g2b2, 0xbc,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x9efff1ff
},
{ PIXMAN_OP_DISJOINT_ATOP,
PIXMAN_a4r4g4b4, 0xae5f,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0xf215b675
},
{ PIXMAN_OP_DISJOINT_ATOP_REVERSE,
PIXMAN_a8r8g8b8, 0xce007980,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x80ffe4ad
},
{ PIXMAN_OP_DISJOINT_XOR,
PIXMAN_a8r8g8b8, 0xb8b07bea,
+ PIXMAN_null, 0x00,
PIXMAN_a4r4g4b4, 0x939c
},
{ PIXMAN_OP_CONJOINT_ATOP_REVERSE,
PIXMAN_r5g6b5, 0x0063,
+ PIXMAN_null, 0x00,
PIXMAN_a8r8g8b8, 0x10bb1ed7,
},
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a2r2g2b2, 0xbf,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x7e
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a8r8g8b8, 0xffffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xff3fffff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_r3g3b2, 0x38,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x5b
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_a8r8g8b8, 0x2e9effff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x77
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r5g6b5, 0xffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x33
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a8r8g8b8, 0xd0089ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0xb1
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_r3g3b2, 0x8a,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xcd0004
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_a8r8g8b8, 0xffff1e3a,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xcf00
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_a8r8g8b8, 0x84c4ffd7,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xffddff
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_a4r4g4b4, 0xfd75,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x7f
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_r3g3b2, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x63ff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a8r8g8b8, 0xff6e56,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x20ff1ade
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a4r4g4b4, 0xfe0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xbdff
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_r5g6b5, 0x9799,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x8d
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_a8r8g8b8, 0xe8ff1c33,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0x6200
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_a8r8g8b8, 0x22ffffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x63
+ },
+ { PIXMAN_OP_SCREEN,
+ PIXMAN_a8r8g8b8, 0x9671ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x43
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a2r2g2b2, 0x83,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0xff
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_r3g3b2, 0x0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x97
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_r5g6b5, 0xb900,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x6800ff00
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a4r4g4b4, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0x8e
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xff00,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0xbc
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r5g6b5, 0xfffe,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x90
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_r3g3b2, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xc35f
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a2r2g2b2, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x39ff
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a2r2g2b2, 0x1e,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xbaff
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a8r8g8b8, 0xb4ffff26,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0xff
+ },
+ { PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_a4r4g4b4, 0xe3ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x878b
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a8r8g8b8, 0xff700044,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x6
+ },
+ { PIXMAN_OP_DARKEN,
+ PIXMAN_a2r2g2b2, 0xb6,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xcd00
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_a2r2g2b2, 0xfe,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x12
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a8r8g8b8, 0xb1ff006c,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xff7c
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r3g3b2, 0x4e,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x3c
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_r5g6b5, 0xffff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0x1968
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_r3g3b2, 0xe7,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x8cced6ac
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a4r4g4b4, 0xa500,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x1bff009d
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r5g6b5, 0x45ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x32
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a2r2g2b2, 0x18,
+ PIXMAN_null, 0x00,
+ PIXMAN_r5g6b5, 0xdc00
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a4r4g4b4, 0x4247,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xd8ffff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_r5g6b5, 0xff00,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x79
+ },
+ { PIXMAN_OP_COLOR_BURN,
+ PIXMAN_r3g3b2, 0xf,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x9fff00ff
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a2r2g2b2, 0x93,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xff
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a2r2g2b2, 0xa3,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0xca
+ },
+ { PIXMAN_OP_DIFFERENCE,
+ PIXMAN_r3g3b2, 0xe0,
+ PIXMAN_null, 0x00,
+ PIXMAN_a2r2g2b2, 0x39
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r3g3b2, 0x16,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x98ffff
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_r3g3b2, 0x96,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0x225f6c
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_a4r4g4b4, 0x12c7,
+ PIXMAN_null, 0x00,
+ PIXMAN_a4r4g4b4, 0xb100
+ },
+ { PIXMAN_OP_LIGHTEN,
+ PIXMAN_a8r8g8b8, 0xffda91,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0x6a
+ },
+ { PIXMAN_OP_EXCLUSION,
+ PIXMAN_a8r8g8b8, 0xfff8,
+ PIXMAN_null, 0x00,
+ PIXMAN_r3g3b2, 0xff
+ },
+ { PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_a2r2g2b2, 0xff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xf0ff48ca
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xf1ff,
+ PIXMAN_r5g6b5, 0x6eff,
+ PIXMAN_a8r8g8b8, 0xffffff,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xf1ff,
+ PIXMAN_a8, 0xdf,
+ PIXMAN_a8r8g8b8, 0xffffff,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xf1ff,
+ PIXMAN_null, 0x00,
+ PIXMAN_a8r8g8b8, 0xffffff,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xb867,
+ PIXMAN_a4r4g4b4, 0x82d9,
+ PIXMAN_a8r8g8b8, 0xffc5,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xa9f5,
+ PIXMAN_r5g6b5, 0xadff,
+ PIXMAN_a8r8g8b8, 0xffff00,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0x4900,
+ PIXMAN_r5g6b5, 0x865c,
+ PIXMAN_a8r8g8b8, 0xebff,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xd9ff,
+ PIXMAN_a8r8g8b8, 0xffffffff,
+ PIXMAN_a8r8g8b8, 0x8ff0d,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0x41ff,
+ PIXMAN_a4r4g4b4, 0xcff,
+ PIXMAN_a8r8g8b8, 0xe1ff00,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0x91ff,
+ PIXMAN_a2r2g2b2, 0xf3,
+ PIXMAN_a8r8g8b8, 0xe4ffb4,
+ },
+ { PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_r5g6b5, 0xb9ff,
+ PIXMAN_a2r2g2b2, 0xff,
+ PIXMAN_a8r8g8b8, 0xffff,
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a8r8g8b8, 0x473affff,
+ PIXMAN_r5g6b5, 0x2b00,
+ PIXMAN_r5g6b5, 0x1ff,
+ },
+ { PIXMAN_OP_OVERLAY,
+ PIXMAN_a8r8g8b8, 0xe4ff,
+ PIXMAN_r3g3b2, 0xff,
+ PIXMAN_r5g6b5, 0x89ff,
+ },
};
static void
@@ -159,35 +2855,59 @@ access (pixman_image_t *image, int x, int y)
}
static pixman_bool_t
-verify (int test_no, const pixel_combination_t *combination, int size)
+verify (int test_no, const pixel_combination_t *combination, int size,
+ pixman_bool_t component_alpha)
{
- pixman_image_t *src, *dest;
- pixel_checker_t src_checker, dest_checker;
- color_t source_color, dest_color, reference_color;
+ pixman_image_t *src, *mask, *dest;
+ pixel_checker_t src_checker, mask_checker, dest_checker;
+ color_t source_color, mask_color, dest_color, reference_color;
+ pixman_bool_t have_mask = (combination->mask_format != PIXMAN_null);
pixman_bool_t result = TRUE;
int i, j;
/* Compute reference color */
pixel_checker_init (&src_checker, combination->src_format);
+ if (have_mask)
+ pixel_checker_init (&mask_checker, combination->mask_format);
pixel_checker_init (&dest_checker, combination->dest_format);
+
pixel_checker_convert_pixel_to_color (
&src_checker, combination->src_pixel, &source_color);
+ if (combination->mask_format != PIXMAN_null)
+ {
+ pixel_checker_convert_pixel_to_color (
+ &mask_checker, combination->mask_pixel, &mask_color);
+ }
pixel_checker_convert_pixel_to_color (
&dest_checker, combination->dest_pixel, &dest_color);
+
do_composite (combination->op,
- &source_color, NULL, &dest_color,
- &reference_color, FALSE);
+ &source_color,
+ have_mask? &mask_color : NULL,
+ &dest_color,
+ &reference_color, component_alpha);
src = pixman_image_create_bits (
combination->src_format, size, size, NULL, -1);
+ if (have_mask)
+ {
+ mask = pixman_image_create_bits (
+ combination->mask_format, size, size, NULL, -1);
+
+ pixman_image_set_component_alpha (mask, component_alpha);
+ }
dest = pixman_image_create_bits (
combination->dest_format, size, size, NULL, -1);
fill (src, combination->src_pixel);
+ if (have_mask)
+ fill (mask, combination->mask_pixel);
fill (dest, combination->dest_pixel);
pixman_image_composite32 (
- combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size);
+ combination->op, src,
+ have_mask ? mask : NULL,
+ dest, 0, 0, 0, 0, 0, 0, size, size);
for (j = 0; j < size; ++j)
{
@@ -200,9 +2920,13 @@ verify (int test_no, const pixel_combination_t *combination, int size)
{
printf ("----------- Test %d failed ----------\n", test_no);
- printf (" operator: %s\n", operator_name (combination->op));
+ printf (" operator: %s (%s)\n", operator_name (combination->op),
+ have_mask? component_alpha ? "component alpha" : "unified alpha" : "no mask");
printf (" src format: %s\n", format_name (combination->src_format));
+ if (have_mask != PIXMAN_null)
+ printf (" mask format: %s\n", format_name (combination->mask_format));
printf (" dest format: %s\n", format_name (combination->dest_format));
+
printf (" - source ARGB: %f %f %f %f (pixel: %8x)\n",
source_color.a, source_color.r, source_color.g, source_color.b,
combination->src_pixel);
@@ -210,6 +2934,16 @@ verify (int test_no, const pixel_combination_t *combination, int size)
&a, &r, &g, &b);
printf (" %8d %8d %8d %8d\n", a, r, g, b);
+ if (have_mask)
+ {
+ printf (" - mask ARGB: %f %f %f %f (pixel: %8x)\n",
+ mask_color.a, mask_color.r, mask_color.g, mask_color.b,
+ combination->mask_pixel);
+ pixel_checker_split_pixel (&mask_checker, combination->mask_pixel,
+ &a, &r, &g, &b);
+ printf (" %8d %8d %8d %8d\n", a, r, g, b);
+ }
+
printf (" - dest ARGB: %f %f %f %f (pixel: %8x)\n",
dest_color.a, dest_color.r, dest_color.g, dest_color.b,
combination->dest_pixel);
@@ -248,19 +2982,41 @@ main (int argc, char **argv)
{
int result = 0;
int i, j;
+ int lo, hi;
+
+ if (argc > 1)
+ {
+ lo = atoi (argv[1]);
+ hi = lo + 1;
+ }
+ else
+ {
+ lo = 0;
+ hi = ARRAY_LENGTH (regressions);
+ }
- for (i = 0; i < ARRAY_LENGTH (regressions); ++i)
+ for (i = lo; i < hi; ++i)
{
const pixel_combination_t *combination = &(regressions[i]);
for (j = 1; j < 34; ++j)
{
- if (!verify (i, combination, j))
+ int k, ca;
+
+ ca = combination->mask_format == PIXMAN_null ? 1 : 2;
+
+ for (k = 0; k < ca; ++k)
{
- result = 1;
- break;
+ if (!verify (i, combination, j, k))
+ {
+ result = 1;
+ goto next_regression;
+ }
}
}
+
+ next_regression:
+ ;
}
return result;
diff --git a/lib/pixman/test/radial-invalid.c b/lib/pixman/test/radial-invalid.c
new file mode 100644
index 000000000..ec85fe320
--- /dev/null
+++ b/lib/pixman/test/radial-invalid.c
@@ -0,0 +1,54 @@
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+#define WIDTH 100
+#define HEIGHT 100
+
+int
+main ()
+{
+ pixman_image_t *radial;
+ pixman_image_t *dest = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, WIDTH, HEIGHT, NULL, -1);
+
+ static const pixman_transform_t xform =
+ {
+ { { 0x346f7, 0x0, 0x0 },
+ { 0x0, 0x346f7, 0x0 },
+ { 0x0, 0x0, 0x10000 }
+ },
+ };
+
+ static const pixman_gradient_stop_t stops[] =
+ {
+ { 0xde61, { 0x4481, 0x96e8, 0x1e6a, 0x29e1 } },
+ { 0xfdd5, { 0xfa10, 0xcc26, 0xbc43, 0x1eb7 } },
+ { 0xfe1e, { 0xd257, 0x5bac, 0x6fc2, 0xa33b } },
+ };
+
+ static const pixman_point_fixed_t inner = { 0x320000, 0x320000 };
+ static const pixman_point_fixed_t outer = { 0x320000, 0x3cb074 };
+
+ enable_divbyzero_exceptions ();
+ enable_invalid_exceptions ();
+
+ radial = pixman_image_create_radial_gradient (
+ &inner,
+ &outer,
+ 0xab074, /* inner radius */
+ 0x0, /* outer radius */
+ stops, sizeof (stops) / sizeof (stops[0]));
+
+ pixman_image_set_repeat (radial, PIXMAN_REPEAT_REFLECT);
+ pixman_image_set_transform (radial, &xform);
+
+ pixman_image_composite (
+ PIXMAN_OP_OVER,
+ radial, NULL, dest,
+ 0, 0, 0, 0,
+ 0, 0, WIDTH, HEIGHT);
+
+ return 0;
+}
diff --git a/lib/pixman/test/scaling-test.c b/lib/pixman/test/scaling-test.c
index e2f7fa9f4..0ece61110 100644
--- a/lib/pixman/test/scaling-test.c
+++ b/lib/pixman/test/scaling-test.c
@@ -73,7 +73,7 @@ test_composite (int testnum,
pixman_op_t op;
pixman_repeat_t repeat = PIXMAN_REPEAT_NONE;
pixman_repeat_t mask_repeat = PIXMAN_REPEAT_NONE;
- pixman_format_code_t src_fmt, dst_fmt;
+ pixman_format_code_t src_fmt, mask_fmt, dst_fmt;
uint32_t * srcbuf;
uint32_t * dstbuf;
uint32_t * maskbuf;
@@ -145,6 +145,7 @@ test_composite (int testnum,
prng_randmemset (dstbuf, dst_stride * dst_height, 0);
src_fmt = get_format (src_bpp);
+ mask_fmt = PIXMAN_a8;
dst_fmt = get_format (dst_bpp);
if (prng_rand_n (2))
@@ -169,7 +170,7 @@ test_composite (int testnum,
src_fmt, src_width, src_height, srcbuf, src_stride);
mask_img = pixman_image_create_bits (
- PIXMAN_a8, mask_width, mask_height, maskbuf, mask_stride);
+ mask_fmt, mask_width, mask_height, maskbuf, mask_stride);
dst_img = pixman_image_create_bits (
dst_fmt, dst_width, dst_height, dstbuf, dst_stride);
@@ -255,21 +256,6 @@ test_composite (int testnum,
else
pixman_image_set_filter (mask_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
- if (verbose)
- {
- printf ("src_fmt=%s, dst_fmt=%s\n",
- format_name (src_fmt), format_name (dst_fmt));
- printf ("op=%s, scale_x=%d, scale_y=%d, repeat=%d\n",
- operator_name (op), scale_x, scale_y, repeat);
- printf ("translate_x=%d, translate_y=%d\n",
- translate_x, translate_y);
- printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
- src_width, src_height, dst_width, dst_height);
- printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
- src_x, src_y, dst_x, dst_y);
- printf ("w=%d, h=%d\n", w, h);
- }
-
if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
@@ -352,10 +338,45 @@ test_composite (int testnum,
}
if (prng_rand_n (2) == 0)
- pixman_image_composite (op, src_img, NULL, dst_img,
- src_x, src_y, 0, 0, dst_x, dst_y, w, h);
- else
- pixman_image_composite (op, src_img, mask_img, dst_img,
+ {
+ mask_fmt = PIXMAN_null;
+ pixman_image_unref (mask_img);
+ mask_img = NULL;
+ mask_x = 0;
+ mask_y = 0;
+ }
+
+ if (verbose)
+ {
+ printf ("op=%s, src_fmt=%s, mask_fmt=%s, dst_fmt=%s\n",
+ operator_name (op), format_name (src_fmt),
+ format_name (mask_fmt), format_name (dst_fmt));
+ printf ("scale_x=%d, scale_y=%d, repeat=%d, filter=%d\n",
+ scale_x, scale_y, repeat, src_img->common.filter);
+ printf ("translate_x=%d, translate_y=%d\n",
+ translate_x, translate_y);
+ if (mask_fmt != PIXMAN_null)
+ {
+ printf ("mask_scale_x=%d, mask_scale_y=%d, "
+ "mask_repeat=%d, mask_filter=%d\n",
+ mask_scale_x, mask_scale_y, mask_repeat,
+ mask_img->common.filter);
+ printf ("mask_translate_x=%d, mask_translate_y=%d\n",
+ mask_translate_x, mask_translate_y);
+ }
+ printf ("src_width=%d, src_height=%d, src_x=%d, src_y=%d\n",
+ src_width, src_height, src_x, src_y);
+ if (mask_fmt != PIXMAN_null)
+ {
+ printf ("mask_width=%d, mask_height=%d, mask_x=%d, mask_y=%d\n",
+ mask_width, mask_height, mask_x, mask_y);
+ }
+ printf ("dst_width=%d, dst_height=%d, dst_x=%d, dst_y=%d\n",
+ dst_width, dst_height, dst_x, dst_y);
+ printf ("w=%d, h=%d\n", w, h);
+ }
+
+ pixman_image_composite (op, src_img, mask_img, dst_img,
src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
crc32 = compute_crc32_for_image (0, dst_img);
@@ -364,7 +385,8 @@ test_composite (int testnum,
print_image (dst_img);
pixman_image_unref (src_img);
- pixman_image_unref (mask_img);
+ if (mask_img != NULL)
+ pixman_image_unref (mask_img);
pixman_image_unref (dst_img);
if (src_stride < 0)
diff --git a/lib/pixman/test/solid-test.c b/lib/pixman/test/solid-test.c
new file mode 100644
index 000000000..c6ea39770
--- /dev/null
+++ b/lib/pixman/test/solid-test.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2015 RISC OS Open Ltd
+ *
+ * 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 the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ *
+ * Author: Ben Avison (bavison@riscosopen.org)
+ *
+ */
+
+#include "utils.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#define WIDTH 32
+#define HEIGHT 32
+
+static const pixman_op_t op_list[] = {
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_CLEAR,
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_DST,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_OVER_REVERSE,
+ PIXMAN_OP_IN,
+ PIXMAN_OP_IN_REVERSE,
+ PIXMAN_OP_OUT,
+ PIXMAN_OP_OUT_REVERSE,
+ PIXMAN_OP_ATOP,
+ PIXMAN_OP_ATOP_REVERSE,
+ PIXMAN_OP_XOR,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_MULTIPLY,
+ PIXMAN_OP_SCREEN,
+ PIXMAN_OP_OVERLAY,
+ PIXMAN_OP_DARKEN,
+ PIXMAN_OP_LIGHTEN,
+ PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_OP_DIFFERENCE,
+ PIXMAN_OP_EXCLUSION,
+#if 0 /* these use floating point math and are not always bitexact on different platforms */
+ PIXMAN_OP_SATURATE,
+ PIXMAN_OP_DISJOINT_CLEAR,
+ PIXMAN_OP_DISJOINT_SRC,
+ PIXMAN_OP_DISJOINT_DST,
+ PIXMAN_OP_DISJOINT_OVER,
+ PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_OP_DISJOINT_IN_REVERSE,
+ PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_OP_DISJOINT_OUT_REVERSE,
+ PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_OP_CONJOINT_CLEAR,
+ PIXMAN_OP_CONJOINT_SRC,
+ PIXMAN_OP_CONJOINT_DST,
+ PIXMAN_OP_CONJOINT_OVER,
+ PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_OP_CONJOINT_IN_REVERSE,
+ PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_OP_CONJOINT_OUT_REVERSE,
+ PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_OP_COLOR_BURN,
+ PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_OP_HSL_HUE,
+ PIXMAN_OP_HSL_SATURATION,
+ PIXMAN_OP_HSL_COLOR,
+ PIXMAN_OP_HSL_LUMINOSITY,
+#endif
+};
+
+/* The first eight format in the list are by far the most widely
+ * used formats, so we test those more than the others
+ */
+#define N_MOST_LIKELY_FORMATS 8
+
+static const pixman_format_code_t img_fmt_list[] = {
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a8b8g8r8,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_x8b8g8r8,
+ PIXMAN_r5g6b5,
+ PIXMAN_b5g6r5,
+ PIXMAN_a8,
+ PIXMAN_a1,
+ PIXMAN_r3g3b2,
+ PIXMAN_b8g8r8a8,
+ PIXMAN_b8g8r8x8,
+ PIXMAN_r8g8b8a8,
+ PIXMAN_r8g8b8x8,
+ PIXMAN_x14r6g6b6,
+ PIXMAN_r8g8b8,
+ PIXMAN_b8g8r8,
+#if 0 /* These are going to use floating point in the near future */
+ PIXMAN_x2r10g10b10,
+ PIXMAN_a2r10g10b10,
+ PIXMAN_x2b10g10r10,
+ PIXMAN_a2b10g10r10,
+#endif
+ PIXMAN_a1r5g5b5,
+ PIXMAN_x1r5g5b5,
+ PIXMAN_a1b5g5r5,
+ PIXMAN_x1b5g5r5,
+ PIXMAN_a4r4g4b4,
+ PIXMAN_x4r4g4b4,
+ PIXMAN_a4b4g4r4,
+ PIXMAN_x4b4g4r4,
+ PIXMAN_r3g3b2,
+ PIXMAN_b2g3r3,
+ PIXMAN_a2r2g2b2,
+ PIXMAN_a2b2g2r2,
+ PIXMAN_c8,
+ PIXMAN_g8,
+ PIXMAN_x4c4,
+ PIXMAN_x4g4,
+ PIXMAN_c4,
+ PIXMAN_g4,
+ PIXMAN_g1,
+ PIXMAN_x4a4,
+ PIXMAN_a4,
+ PIXMAN_r1g2b1,
+ PIXMAN_b1g2r1,
+ PIXMAN_a1r1g1b1,
+ PIXMAN_a1b1g1r1,
+ PIXMAN_null
+};
+
+static const pixman_format_code_t mask_fmt_list[] = {
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a8,
+ PIXMAN_a4,
+ PIXMAN_a1,
+ PIXMAN_null
+};
+
+static pixman_indexed_t rgb_palette[9];
+static pixman_indexed_t y_palette[9];
+
+static pixman_format_code_t
+random_format (const pixman_format_code_t *allowed_formats)
+{
+ int n = 0;
+
+ while (allowed_formats[n] != PIXMAN_null)
+ n++;
+
+ if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0)
+ n = N_MOST_LIKELY_FORMATS;
+
+ return allowed_formats[prng_rand_n (n)];
+}
+
+static pixman_image_t *
+create_multi_pixel_image (const pixman_format_code_t *allowed_formats,
+ uint32_t *buffer,
+ pixman_format_code_t *used_fmt)
+{
+ pixman_format_code_t fmt;
+ pixman_image_t *img;
+ int stride;
+
+ fmt = random_format (allowed_formats);
+ stride = (WIDTH * PIXMAN_FORMAT_BPP (fmt) + 31) / 32 * 4;
+ img = pixman_image_create_bits (fmt, WIDTH, HEIGHT, buffer, stride);
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
+ pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
+ else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
+ pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
+
+ prng_randmemset (buffer, WIDTH * HEIGHT * 4, 0);
+ image_endian_swap (img);
+
+ if (used_fmt)
+ *used_fmt = fmt;
+
+ return img;
+}
+
+static pixman_image_t *
+create_solid_image (const pixman_format_code_t *allowed_formats,
+ uint32_t *buffer,
+ pixman_format_code_t *used_fmt)
+{
+ if (prng_rand_n (2))
+ {
+ /* Use a repeating 1x1 bitmap image for solid */
+ pixman_format_code_t fmt;
+ pixman_image_t *img, *dummy_img;
+ uint32_t bpp, dummy_buf;
+
+ fmt = random_format (allowed_formats);
+ bpp = PIXMAN_FORMAT_BPP (fmt);
+ img = pixman_image_create_bits (fmt, 1, 1, buffer, 4);
+ pixman_image_set_repeat (img, PIXMAN_REPEAT_NORMAL);
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
+ pixman_image_set_indexed (img, &(rgb_palette[bpp]));
+ else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
+ pixman_image_set_indexed (img, &(y_palette[bpp]));
+
+ /* Force the flags to be calculated for image with initial
+ * bitmap contents of 0 or 2^bpp-1 by plotting from it into a
+ * separate throwaway image. It is simplest to write all 0s
+ * or all 1s to the first word irrespective of the colour
+ * depth even though we actually only care about the first
+ * pixel since the stride has to be a whole number of words.
+ */
+ *buffer = prng_rand_n (2) ? 0xFFFFFFFFu : 0;
+ dummy_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 1, 1,
+ &dummy_buf, 4);
+ pixman_image_composite (PIXMAN_OP_SRC, img, NULL, dummy_img,
+ 0, 0, 0, 0, 0, 0, 1, 1);
+ pixman_image_unref (dummy_img);
+
+ /* Now set the bitmap contents to a random value */
+ prng_randmemset (buffer, 4, 0);
+ image_endian_swap (img);
+
+ if (used_fmt)
+ *used_fmt = fmt;
+
+ return img;
+ }
+ else
+ {
+ /* Use a native solid image */
+ pixman_color_t color;
+ pixman_image_t *img;
+
+ color.alpha = prng_rand_n (UINT16_MAX + 1);
+ color.red = prng_rand_n (UINT16_MAX + 1);
+ color.green = prng_rand_n (UINT16_MAX + 1);
+ color.blue = prng_rand_n (UINT16_MAX + 1);
+ img = pixman_image_create_solid_fill (&color);
+
+ if (used_fmt)
+ *used_fmt = PIXMAN_solid;
+
+ return img;
+ }
+}
+
+static uint32_t
+test_solid (int testnum, int verbose)
+{
+ pixman_op_t op;
+ uint32_t src_buf[WIDTH * HEIGHT];
+ uint32_t dst_buf[WIDTH * HEIGHT];
+ uint32_t mask_buf[WIDTH * HEIGHT];
+ pixman_image_t *src_img;
+ pixman_image_t *dst_img;
+ pixman_image_t *mask_img = NULL;
+ pixman_format_code_t src_fmt, dst_fmt, mask_fmt = PIXMAN_null;
+ pixman_bool_t ca = 0;
+ uint32_t crc32;
+
+ prng_srand (testnum);
+
+ op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];
+
+ dst_img = create_multi_pixel_image (img_fmt_list, dst_buf, &dst_fmt);
+ switch (prng_rand_n (3))
+ {
+ case 0: /* Solid source, no mask */
+ src_img = create_solid_image (img_fmt_list, src_buf, &src_fmt);
+ break;
+ case 1: /* Solid source, bitmap mask */
+ src_img = create_solid_image (img_fmt_list, src_buf, &src_fmt);
+ mask_img = create_multi_pixel_image (mask_fmt_list, mask_buf, &mask_fmt);
+ break;
+ case 2: /* Bitmap image, solid mask */
+ src_img = create_multi_pixel_image (img_fmt_list, src_buf, &src_fmt);
+ mask_img = create_solid_image (mask_fmt_list, mask_buf, &mask_fmt);
+ break;
+ default:
+ abort ();
+ }
+
+ if (mask_img)
+ {
+ ca = prng_rand_n (2);
+ pixman_image_set_component_alpha (mask_img, ca);
+ }
+
+ if (verbose)
+ {
+ printf ("op=%s\n", operator_name (op));
+ printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n",
+ format_name (src_fmt), format_name (dst_fmt),
+ format_name (mask_fmt));
+ printf ("src_size=%u, mask_size=%u, component_alpha=%u\n",
+ src_fmt == PIXMAN_solid ? 1 : src_img->bits.width,
+ !mask_img || mask_fmt == PIXMAN_solid ? 1 : mask_img->bits.width,
+ ca);
+ }
+
+ pixman_image_composite (op, src_img, mask_img, dst_img,
+ 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+ if (verbose)
+ print_image (dst_img);
+
+ crc32 = compute_crc32_for_image (0, dst_img);
+
+ pixman_image_unref (src_img);
+ pixman_image_unref (dst_img);
+ if (mask_img)
+ pixman_image_unref (mask_img);
+
+ return crc32;
+}
+
+int
+main (int argc, const char *argv[])
+{
+ int i;
+
+ prng_srand (0);
+
+ for (i = 1; i <= 8; i++)
+ {
+ initialize_palette (&(rgb_palette[i]), i, TRUE);
+ initialize_palette (&(y_palette[i]), i, FALSE);
+ }
+
+ return fuzzer_test_main ("solid", 500000,
+ 0xC30FD380,
+ test_solid, argc, argv);
+}
diff --git a/lib/pixman/test/thread-test.c b/lib/pixman/test/thread-test.c
index 0b07b269d..1c2f0407a 100644
--- a/lib/pixman/test/thread-test.c
+++ b/lib/pixman/test/thread-test.c
@@ -38,38 +38,11 @@ static const pixman_op_t operators[] =
PIXMAN_OP_ATOP_REVERSE,
PIXMAN_OP_XOR,
PIXMAN_OP_ADD,
- PIXMAN_OP_SATURATE,
- PIXMAN_OP_DISJOINT_CLEAR,
- PIXMAN_OP_DISJOINT_SRC,
- PIXMAN_OP_DISJOINT_DST,
- PIXMAN_OP_DISJOINT_OVER,
- PIXMAN_OP_DISJOINT_OVER_REVERSE,
- PIXMAN_OP_DISJOINT_IN,
- PIXMAN_OP_DISJOINT_IN_REVERSE,
- PIXMAN_OP_DISJOINT_OUT,
- PIXMAN_OP_DISJOINT_OUT_REVERSE,
- PIXMAN_OP_DISJOINT_ATOP,
- PIXMAN_OP_DISJOINT_ATOP_REVERSE,
- PIXMAN_OP_DISJOINT_XOR,
- PIXMAN_OP_CONJOINT_CLEAR,
- PIXMAN_OP_CONJOINT_SRC,
- PIXMAN_OP_CONJOINT_DST,
- PIXMAN_OP_CONJOINT_OVER,
- PIXMAN_OP_CONJOINT_OVER_REVERSE,
- PIXMAN_OP_CONJOINT_IN,
- PIXMAN_OP_CONJOINT_IN_REVERSE,
- PIXMAN_OP_CONJOINT_OUT,
- PIXMAN_OP_CONJOINT_OUT_REVERSE,
- PIXMAN_OP_CONJOINT_ATOP,
- PIXMAN_OP_CONJOINT_ATOP_REVERSE,
- PIXMAN_OP_CONJOINT_XOR,
PIXMAN_OP_MULTIPLY,
PIXMAN_OP_SCREEN,
PIXMAN_OP_OVERLAY,
PIXMAN_OP_DARKEN,
PIXMAN_OP_LIGHTEN,
- PIXMAN_OP_COLOR_DODGE,
- PIXMAN_OP_COLOR_BURN,
PIXMAN_OP_HARD_LIGHT,
PIXMAN_OP_DIFFERENCE,
PIXMAN_OP_EXCLUSION,
@@ -183,7 +156,7 @@ main (void)
crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
-#define EXPECTED 0xE299B18E
+#define EXPECTED 0x82C4D9FB
if (crc32 != EXPECTED)
{
diff --git a/lib/pixman/test/tolerance-test.c b/lib/pixman/test/tolerance-test.c
new file mode 100644
index 000000000..320bb7fe0
--- /dev/null
+++ b/lib/pixman/test/tolerance-test.c
@@ -0,0 +1,360 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+#include "utils.h"
+
+#define MAX_WIDTH 16
+#define MAX_HEIGHT 16
+#define MAX_STRIDE 4
+
+static const pixman_format_code_t formats[] =
+{
+ PIXMAN_a2r10g10b10,
+ PIXMAN_x2r10g10b10,
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a4r4g4b4,
+ PIXMAN_a2r2g2b2,
+ PIXMAN_r5g6b5,
+ PIXMAN_r3g3b2,
+};
+
+static const pixman_op_t operators[] =
+{
+ PIXMAN_OP_CLEAR,
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_DST,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_OVER_REVERSE,
+ PIXMAN_OP_IN,
+ PIXMAN_OP_IN_REVERSE,
+ PIXMAN_OP_OUT,
+ PIXMAN_OP_OUT_REVERSE,
+ PIXMAN_OP_ATOP,
+ PIXMAN_OP_ATOP_REVERSE,
+ PIXMAN_OP_XOR,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_SATURATE,
+
+ PIXMAN_OP_DISJOINT_CLEAR,
+ PIXMAN_OP_DISJOINT_SRC,
+ PIXMAN_OP_DISJOINT_DST,
+ PIXMAN_OP_DISJOINT_OVER,
+ PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_OP_DISJOINT_IN_REVERSE,
+ PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_OP_DISJOINT_OUT_REVERSE,
+ PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_OP_DISJOINT_XOR,
+
+ PIXMAN_OP_CONJOINT_CLEAR,
+ PIXMAN_OP_CONJOINT_SRC,
+ PIXMAN_OP_CONJOINT_DST,
+ PIXMAN_OP_CONJOINT_OVER,
+ PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_OP_CONJOINT_IN_REVERSE,
+ PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_OP_CONJOINT_OUT_REVERSE,
+ PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_OP_CONJOINT_XOR,
+
+ PIXMAN_OP_MULTIPLY,
+ PIXMAN_OP_SCREEN,
+ PIXMAN_OP_OVERLAY,
+ PIXMAN_OP_DARKEN,
+ PIXMAN_OP_LIGHTEN,
+ PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_OP_COLOR_BURN,
+ PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_OP_DIFFERENCE,
+ PIXMAN_OP_EXCLUSION,
+};
+
+#define RANDOM_ELT(array) \
+ (array[prng_rand_n (ARRAY_LENGTH (array))])
+
+static void
+free_bits (pixman_image_t *image, void *data)
+{
+ free (image->bits.bits);
+}
+
+static pixman_image_t *
+create_image (pixman_image_t **clone)
+{
+ pixman_format_code_t format = RANDOM_ELT (formats);
+ pixman_image_t *image;
+ int width = prng_rand_n (MAX_WIDTH);
+ int height = prng_rand_n (MAX_HEIGHT);
+ int stride = ((width * (PIXMAN_FORMAT_BPP (format) / 8)) + 3) & ~3;
+ uint32_t *bytes = malloc (stride * height);
+
+ prng_randmemset (bytes, stride * height, RANDMEMSET_MORE_00_AND_FF);
+
+ image = pixman_image_create_bits (
+ format, width, height, bytes, stride);
+
+ pixman_image_set_destroy_function (image, free_bits, NULL);
+
+ assert (image);
+
+ if (clone)
+ {
+ uint32_t *bytes_dup = malloc (stride * height);
+
+ memcpy (bytes_dup, bytes, stride * height);
+
+ *clone = pixman_image_create_bits (
+ format, width, height, bytes_dup, stride);
+
+ pixman_image_set_destroy_function (*clone, free_bits, NULL);
+ }
+
+ return image;
+}
+
+static pixman_bool_t
+access (pixman_image_t *image, int x, int y, uint32_t *pixel)
+{
+ int bytes_per_pixel;
+ int stride;
+ uint8_t *location;
+
+ if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height)
+ return FALSE;
+
+ bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
+ stride = image->bits.rowstride * 4;
+
+ location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel;
+
+ if (bytes_per_pixel == 4)
+ *pixel = *(uint32_t *)location;
+ else if (bytes_per_pixel == 2)
+ *pixel = *(uint16_t *)location;
+ else if (bytes_per_pixel == 1)
+ *pixel = *(uint8_t *)location;
+ else
+ assert (0);
+
+ return TRUE;
+}
+
+static void
+get_color (pixel_checker_t *checker,
+ pixman_image_t *image,
+ int x, int y,
+ color_t *color,
+ uint32_t *pixel)
+{
+ if (!access (image, x, y, pixel))
+ {
+ color->a = 0.0;
+ color->r = 0.0;
+ color->g = 0.0;
+ color->b = 0.0;
+ }
+ else
+ {
+ pixel_checker_convert_pixel_to_color (
+ checker, *pixel, color);
+ }
+}
+
+static pixman_bool_t
+verify (int test_no,
+ pixman_op_t op,
+ pixman_image_t *source,
+ pixman_image_t *mask,
+ pixman_image_t *dest,
+ pixman_image_t *orig_dest,
+ int x, int y,
+ int width, int height,
+ pixman_bool_t component_alpha)
+{
+ pixel_checker_t dest_checker, src_checker, mask_checker;
+ int i, j;
+
+ pixel_checker_init (&src_checker, source->bits.format);
+ pixel_checker_init (&dest_checker, dest->bits.format);
+ pixel_checker_init (&mask_checker, mask->bits.format);
+
+ assert (dest->bits.format == orig_dest->bits.format);
+
+ for (j = y; j < y + height; ++j)
+ {
+ for (i = x; i < x + width; ++i)
+ {
+ color_t src_color, mask_color, orig_dest_color, result;
+ uint32_t dest_pixel, orig_dest_pixel, src_pixel, mask_pixel;
+
+ access (dest, i, j, &dest_pixel);
+
+ get_color (&src_checker,
+ source, i - x, j - y,
+ &src_color, &src_pixel);
+
+ get_color (&mask_checker,
+ mask, i - x, j - y,
+ &mask_color, &mask_pixel);
+
+ get_color (&dest_checker,
+ orig_dest, i, j,
+ &orig_dest_color, &orig_dest_pixel);
+
+ do_composite (op,
+ &src_color, &mask_color, &orig_dest_color,
+ &result, component_alpha);
+
+ if (!pixel_checker_check (&dest_checker, dest_pixel, &result))
+ {
+ int a, r, g, b;
+
+ printf ("--------- Test 0x%x failed ---------\n", test_no);
+
+ printf (" operator: %s (%s alpha)\n", operator_name (op),
+ component_alpha? "component" : "unified");
+ printf (" dest_x, dest_y: %d %d\n", x, y);
+ printf (" width, height: %d %d\n", width, height);
+ printf (" source: format: %-14s size: %2d x %2d\n",
+ format_name (source->bits.format),
+ source->bits.width, source->bits.height);
+ printf (" mask: format: %-14s size: %2d x %2d\n",
+ format_name (mask->bits.format),
+ mask->bits.width, mask->bits.height);
+ printf (" dest: format: %-14s size: %2d x %2d\n",
+ format_name (dest->bits.format),
+ dest->bits.width, dest->bits.height);
+ printf (" -- Failed pixel: (%d, %d) --\n", i, j);
+ printf (" source ARGB: %f %f %f %f (pixel: %x)\n",
+ src_color.a, src_color.r, src_color.g, src_color.b,
+ src_pixel);
+ printf (" mask ARGB: %f %f %f %f (pixel: %x)\n",
+ mask_color.a, mask_color.r, mask_color.g, mask_color.b,
+ mask_pixel);
+ printf (" dest ARGB: %f %f %f %f (pixel: %x)\n",
+ orig_dest_color.a, orig_dest_color.r, orig_dest_color.g, orig_dest_color.b,
+ orig_dest_pixel);
+ printf (" expected ARGB: %f %f %f %f\n",
+ result.a, result.r, result.g, result.b);
+
+ pixel_checker_get_min (&dest_checker, &result, &a, &r, &g, &b);
+ printf (" min acceptable: %8d %8d %8d %8d\n", a, r, g, b);
+
+ pixel_checker_split_pixel (&dest_checker, dest_pixel, &a, &r, &g, &b);
+ printf (" got: %8d %8d %8d %8d (pixel: %x)\n", a, r, g, b, dest_pixel);
+
+ pixel_checker_get_max (&dest_checker, &result, &a, &r, &g, &b);
+ printf (" max acceptable: %8d %8d %8d %8d\n", a, r, g, b);
+ printf ("\n");
+ printf (" { %s,\n", operator_name (op));
+ printf (" PIXMAN_%s,\t0x%x,\n", format_name (source->bits.format), src_pixel);
+ printf (" PIXMAN_%s,\t0x%x,\n", format_name (mask->bits.format), mask_pixel);
+ printf (" PIXMAN_%s,\t0x%x\n", format_name (dest->bits.format), orig_dest_pixel);
+ printf (" },\n");
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static pixman_bool_t
+do_check (int i)
+{
+ pixman_image_t *source, *dest, *mask;
+ pixman_op_t op;
+ int x, y, width, height;
+ pixman_image_t *dest_copy;
+ pixman_bool_t result = TRUE;
+ pixman_bool_t component_alpha;
+
+ prng_srand (i);
+ op = RANDOM_ELT (operators);
+ x = prng_rand_n (MAX_WIDTH);
+ y = prng_rand_n (MAX_HEIGHT);
+ width = prng_rand_n (MAX_WIDTH) + 4;
+ height = prng_rand_n (MAX_HEIGHT) + 4;
+
+ source = create_image (NULL);
+ mask = create_image (NULL);
+ dest = create_image (&dest_copy);
+
+ if (x >= dest->bits.width)
+ x = dest->bits.width / 2;
+ if (y >= dest->bits.height)
+ y = dest->bits.height / 2;
+ if (x + width > dest->bits.width)
+ width = dest->bits.width - x;
+ if (y + height > dest->bits.height)
+ height = dest->bits.height - y;
+
+ component_alpha = prng_rand_n (2);
+
+ pixman_image_set_component_alpha (mask, component_alpha);
+
+ pixman_image_composite32 (op, source, mask, dest,
+ 0, 0, 0, 0,
+ x, y, width, height);
+
+ if (!verify (i, op, source, mask, dest, dest_copy,
+ x, y, width, height, component_alpha))
+ {
+ result = FALSE;
+ }
+
+ pixman_image_unref (source);
+ pixman_image_unref (mask);
+ pixman_image_unref (dest);
+ pixman_image_unref (dest_copy);
+
+ return result;
+}
+
+#define N_TESTS 10000000
+
+int
+main (int argc, const char *argv[])
+{
+ int i;
+ int result = 0;
+
+ if (argc == 2)
+ {
+ if (strcmp (argv[1], "--forever") == 0)
+ {
+ uint32_t n;
+
+ prng_srand (time (0));
+
+ n = prng_rand();
+
+ for (;;)
+ do_check (n++);
+ }
+ else
+ {
+ do_check (strtol (argv[1], NULL, 0));
+ }
+ }
+ else
+ {
+#ifdef USE_OPENMP
+# pragma omp parallel for default(none) reduction(|:result)
+#endif
+ for (i = 0; i < N_TESTS; ++i)
+ {
+ if (!do_check (i))
+ result |= 1;
+ }
+ }
+
+ return result;
+}
diff --git a/lib/pixman/test/utils.c b/lib/pixman/test/utils.c
index ebe0ccc09..f8e42a5d3 100644
--- a/lib/pixman/test/utils.c
+++ b/lib/pixman/test/utils.c
@@ -4,6 +4,9 @@
#include <math.h>
#include <signal.h>
#include <stdlib.h>
+#include <float.h>
+#include <ctype.h>
+#include <limits.h>
#ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h>
@@ -27,6 +30,8 @@
#include <png.h>
#endif
+#define ROUND_UP(x, mult) (((x) + (mult) - 1) / (mult) * (mult))
+
/* Random number generator state
*/
@@ -375,7 +380,16 @@ typedef struct
int n_bytes;
} info_t;
-#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP)
+#if FENCE_MALLOC_ACTIVE
+
+unsigned long
+fence_get_page_size ()
+{
+ /* You can fake a page size here, if you want to test e.g. 64 kB
+ * pages on a 4 kB page system. Just put a multiplier below.
+ */
+ return getpagesize ();
+}
/* This is apparently necessary on at least OS X */
#ifndef MAP_ANONYMOUS
@@ -385,7 +399,7 @@ typedef struct
void *
fence_malloc (int64_t len)
{
- unsigned long page_size = getpagesize();
+ unsigned long page_size = fence_get_page_size ();
unsigned long page_mask = page_size - 1;
uint32_t n_payload_bytes = (len + page_mask) & ~page_mask;
uint32_t n_bytes =
@@ -434,7 +448,7 @@ fence_malloc (int64_t len)
void
fence_free (void *data)
{
- uint32_t page_size = getpagesize();
+ uint32_t page_size = fence_get_page_size ();
uint8_t *payload = data;
uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size;
uint8_t *initial_page = leading_protected - page_size;
@@ -443,7 +457,98 @@ fence_free (void *data)
munmap (info->addr, info->n_bytes);
}
-#else
+static void
+fence_image_destroy (pixman_image_t *image, void *data)
+{
+ fence_free (data);
+}
+
+/* Create an image with fence pages.
+ *
+ * Creates an image, where the data area is allocated with fence_malloc ().
+ * Each row has an additional page in the stride.
+ *
+ * min_width is only a minimum width for the image. The width is aligned up
+ * for the row size to be divisible by both page size and pixel size.
+ *
+ * If stride_fence is true, the additional page on each row will be
+ * armed to cause SIGSEGV or SIGBUS on all accesses. This should catch
+ * all accesses outside the valid row pixels.
+ */
+pixman_image_t *
+fence_image_create_bits (pixman_format_code_t format,
+ int min_width,
+ int height,
+ pixman_bool_t stride_fence)
+{
+ unsigned page_size = fence_get_page_size ();
+ unsigned page_mask = page_size - 1;
+ unsigned bitspp = PIXMAN_FORMAT_BPP (format);
+ unsigned bits_boundary;
+ unsigned row_bits;
+ int width; /* pixels */
+ unsigned stride; /* bytes */
+ void *pixels;
+ pixman_image_t *image;
+ int i;
+
+ /* must be power of two */
+ assert (page_size && (page_size & page_mask) == 0);
+
+ if (bitspp < 1 || min_width < 1 || height < 1)
+ abort ();
+
+ /* least common multiple between page size * 8 and bitspp */
+ bits_boundary = bitspp;
+ while (! (bits_boundary & 1))
+ bits_boundary >>= 1;
+ bits_boundary *= page_size * 8;
+
+ /* round up to bits_boundary */
+ row_bits = ROUND_UP ( (unsigned)min_width * bitspp, bits_boundary);
+ width = row_bits / bitspp;
+
+ stride = row_bits / 8;
+ if (stride_fence)
+ stride += page_size; /* add fence page */
+
+ if (UINT_MAX / stride < (unsigned)height)
+ abort ();
+
+ pixels = fence_malloc (stride * (unsigned)height);
+ if (!pixels)
+ return NULL;
+
+ if (stride_fence)
+ {
+ uint8_t *guard = (uint8_t *)pixels + stride - page_size;
+
+ /* arm row end fence pages */
+ for (i = 0; i < height; i++)
+ {
+ if (mprotect (guard + i * stride, page_size, PROT_NONE) == -1)
+ goto out_fail;
+ }
+ }
+
+ assert (width >= min_width);
+
+ image = pixman_image_create_bits_no_clear (format, width, height,
+ pixels, stride);
+ if (!image)
+ goto out_fail;
+
+ pixman_image_set_destroy_function (image, fence_image_destroy, pixels);
+
+ return image;
+
+out_fail:
+ fence_free (pixels);
+
+ return NULL;
+}
+
+#else /* FENCE_MALLOC_ACTIVE */
void *
fence_malloc (int64_t len)
@@ -457,7 +562,25 @@ fence_free (void *data)
free (data);
}
-#endif
+pixman_image_t *
+fence_image_create_bits (pixman_format_code_t format,
+ int min_width,
+ int height,
+ pixman_bool_t stride_fence)
+{
+ return pixman_image_create_bits (format, min_width, height, NULL, 0);
+ /* Implicitly allocated storage does not need a destroy function
+ * to get freed on refcount hitting zero.
+ */
+}
+
+unsigned long
+fence_get_page_size ()
+{
+ return 0;
+}
+
+#endif /* FENCE_MALLOC_ACTIVE */
uint8_t *
make_random_bytes (int n_bytes)
@@ -843,9 +966,21 @@ enable_divbyzero_exceptions (void)
{
#ifdef HAVE_FENV_H
#ifdef HAVE_FEENABLEEXCEPT
+#ifdef HAVE_FEDIVBYZERO
feenableexcept (FE_DIVBYZERO);
#endif
#endif
+#endif
+}
+
+void
+enable_invalid_exceptions (void)
+{
+#ifdef HAVE_FENV_H
+#ifdef HAVE_FEENABLEEXCEPT
+ feenableexcept (FE_INVALID);
+#endif
+#endif
}
void *
@@ -937,71 +1072,332 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
}
}
+struct operator_entry {
+ pixman_op_t op;
+ const char *name;
+ pixman_bool_t is_alias;
+};
+
+typedef struct operator_entry operator_entry_t;
+
+static const operator_entry_t op_list[] =
+{
+#define ENTRY(op) \
+ { PIXMAN_OP_##op, "PIXMAN_OP_" #op, FALSE }
+#define ALIAS(op, nam) \
+ { PIXMAN_OP_##op, nam, TRUE }
+
+ /* operator_name () will return the first hit in this table,
+ * so keep the list properly ordered between entries and aliases.
+ * Aliases are not listed by list_operators ().
+ */
+
+ ENTRY (CLEAR),
+ ENTRY (SRC),
+ ENTRY (DST),
+ ENTRY (OVER),
+ ENTRY (OVER_REVERSE),
+ ALIAS (OVER_REVERSE, "overrev"),
+ ENTRY (IN),
+ ENTRY (IN_REVERSE),
+ ALIAS (IN_REVERSE, "inrev"),
+ ENTRY (OUT),
+ ENTRY (OUT_REVERSE),
+ ALIAS (OUT_REVERSE, "outrev"),
+ ENTRY (ATOP),
+ ENTRY (ATOP_REVERSE),
+ ALIAS (ATOP_REVERSE, "atoprev"),
+ ENTRY (XOR),
+ ENTRY (ADD),
+ ENTRY (SATURATE),
+
+ ENTRY (DISJOINT_CLEAR),
+ ENTRY (DISJOINT_SRC),
+ ENTRY (DISJOINT_DST),
+ ENTRY (DISJOINT_OVER),
+ ENTRY (DISJOINT_OVER_REVERSE),
+ ENTRY (DISJOINT_IN),
+ ENTRY (DISJOINT_IN_REVERSE),
+ ENTRY (DISJOINT_OUT),
+ ENTRY (DISJOINT_OUT_REVERSE),
+ ENTRY (DISJOINT_ATOP),
+ ENTRY (DISJOINT_ATOP_REVERSE),
+ ENTRY (DISJOINT_XOR),
+
+ ENTRY (CONJOINT_CLEAR),
+ ENTRY (CONJOINT_SRC),
+ ENTRY (CONJOINT_DST),
+ ENTRY (CONJOINT_OVER),
+ ENTRY (CONJOINT_OVER_REVERSE),
+ ENTRY (CONJOINT_IN),
+ ENTRY (CONJOINT_IN_REVERSE),
+ ENTRY (CONJOINT_OUT),
+ ENTRY (CONJOINT_OUT_REVERSE),
+ ENTRY (CONJOINT_ATOP),
+ ENTRY (CONJOINT_ATOP_REVERSE),
+ ENTRY (CONJOINT_XOR),
+
+ ENTRY (MULTIPLY),
+ ENTRY (SCREEN),
+ ENTRY (OVERLAY),
+ ENTRY (DARKEN),
+ ENTRY (LIGHTEN),
+ ENTRY (COLOR_DODGE),
+ ENTRY (COLOR_BURN),
+ ENTRY (HARD_LIGHT),
+ ENTRY (SOFT_LIGHT),
+ ENTRY (DIFFERENCE),
+ ENTRY (EXCLUSION),
+ ENTRY (HSL_HUE),
+ ENTRY (HSL_SATURATION),
+ ENTRY (HSL_COLOR),
+ ENTRY (HSL_LUMINOSITY),
+
+ ALIAS (NONE, "<invalid operator 'none'>")
+
+#undef ENTRY
+#undef ALIAS
+};
+
+struct format_entry
+{
+ pixman_format_code_t format;
+ const char *name;
+ pixman_bool_t is_alias;
+};
+
+typedef struct format_entry format_entry_t;
+
+static const format_entry_t format_list[] =
+{
+#define ENTRY(f) \
+ { PIXMAN_##f, #f, FALSE }
+#define ALIAS(f, nam) \
+ { PIXMAN_##f, nam, TRUE }
+
+ /* format_name () will return the first hit in this table,
+ * so keep the list properly ordered between entries and aliases.
+ * Aliases are not listed by list_formats ().
+ */
+
+/* 32bpp formats */
+ ENTRY (a8r8g8b8),
+ ALIAS (a8r8g8b8, "8888"),
+ ENTRY (x8r8g8b8),
+ ALIAS (x8r8g8b8, "x888"),
+ ENTRY (a8b8g8r8),
+ ENTRY (x8b8g8r8),
+ ENTRY (b8g8r8a8),
+ ENTRY (b8g8r8x8),
+ ENTRY (r8g8b8a8),
+ ENTRY (r8g8b8x8),
+ ENTRY (x14r6g6b6),
+ ENTRY (x2r10g10b10),
+ ALIAS (x2r10g10b10, "2x10"),
+ ENTRY (a2r10g10b10),
+ ALIAS (a2r10g10b10, "2a10"),
+ ENTRY (x2b10g10r10),
+ ENTRY (a2b10g10r10),
+
+/* sRGB formats */
+ ENTRY (a8r8g8b8_sRGB),
+
+/* 24bpp formats */
+ ENTRY (r8g8b8),
+ ALIAS (r8g8b8, "0888"),
+ ENTRY (b8g8r8),
+
+/* 16 bpp formats */
+ ENTRY (r5g6b5),
+ ALIAS (r5g6b5, "0565"),
+ ENTRY (b5g6r5),
+
+ ENTRY (a1r5g5b5),
+ ALIAS (a1r5g5b5, "1555"),
+ ENTRY (x1r5g5b5),
+ ENTRY (a1b5g5r5),
+ ENTRY (x1b5g5r5),
+ ENTRY (a4r4g4b4),
+ ALIAS (a4r4g4b4, "4444"),
+ ENTRY (x4r4g4b4),
+ ENTRY (a4b4g4r4),
+ ENTRY (x4b4g4r4),
+
+/* 8bpp formats */
+ ENTRY (a8),
+ ALIAS (a8, "8"),
+ ENTRY (r3g3b2),
+ ENTRY (b2g3r3),
+ ENTRY (a2r2g2b2),
+ ALIAS (a2r2g2b2, "2222"),
+ ENTRY (a2b2g2r2),
+
+ ALIAS (c8, "x4c4 / c8"),
+ /* ENTRY (c8), */
+ ALIAS (g8, "x4g4 / g8"),
+ /* ENTRY (g8), */
+
+ ENTRY (x4a4),
+
+ /* These format codes are identical to c8 and g8, respectively. */
+ /* ENTRY (x4c4), */
+ /* ENTRY (x4g4), */
+
+/* 4 bpp formats */
+ ENTRY (a4),
+ ENTRY (r1g2b1),
+ ENTRY (b1g2r1),
+ ENTRY (a1r1g1b1),
+ ENTRY (a1b1g1r1),
+
+ ALIAS (c4, "c4"),
+ /* ENTRY (c4), */
+ ALIAS (g4, "g4"),
+ /* ENTRY (g4), */
+
+/* 1bpp formats */
+ ENTRY (a1),
+
+ ALIAS (g1, "g1"),
+ /* ENTRY (g1), */
+
+/* YUV formats */
+ ALIAS (yuy2, "yuy2"),
+ /* ENTRY (yuy2), */
+ ALIAS (yv12, "yv12"),
+ /* ENTRY (yv12), */
+
+/* Fake formats, not in pixman_format_code_t enum */
+ ALIAS (null, "null"),
+ ALIAS (solid, "solid"),
+ ALIAS (solid, "n"),
+ ALIAS (pixbuf, "pixbuf"),
+ ALIAS (rpixbuf, "rpixbuf"),
+ ALIAS (unknown, "unknown"),
+
+#undef ENTRY
+#undef ALIAS
+};
+
+pixman_format_code_t
+format_from_string (const char *s)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
+ {
+ const format_entry_t *ent = &format_list[i];
+
+ if (strcasecmp (ent->name, s) == 0)
+ return ent->format;
+ }
+
+ return PIXMAN_null;
+}
+
+static void
+emit (const char *s, int *n_chars)
+{
+ *n_chars += printf ("%s,", s);
+ if (*n_chars > 60)
+ {
+ printf ("\n ");
+ *n_chars = 0;
+ }
+ else
+ {
+ printf (" ");
+ (*n_chars)++;
+ }
+}
+
+void
+list_formats (void)
+{
+ int n_chars;
+ int i;
+
+ printf ("Formats:\n ");
+
+ n_chars = 0;
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
+ {
+ const format_entry_t *ent = &format_list[i];
+
+ if (ent->is_alias)
+ continue;
+
+ emit (ent->name, &n_chars);
+ }
+
+ printf ("\n\n");
+}
+
+void
+list_operators (void)
+{
+ char short_name [128] = { 0 };
+ int i, n_chars;
+
+ printf ("Operators:\n ");
+
+ n_chars = 0;
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+ {
+ const operator_entry_t *ent = &op_list[i];
+ int j;
+
+ if (ent->is_alias)
+ continue;
+
+ snprintf (short_name, sizeof (short_name) - 1, "%s",
+ ent->name + strlen ("PIXMAN_OP_"));
+
+ for (j = 0; short_name[j] != '\0'; ++j)
+ short_name[j] = tolower (short_name[j]);
+
+ emit (short_name, &n_chars);
+ }
+
+ printf ("\n\n");
+}
+
+pixman_op_t
+operator_from_string (const char *s)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+ {
+ const operator_entry_t *ent = &op_list[i];
+
+ if (ent->is_alias)
+ {
+ if (strcasecmp (ent->name, s) == 0)
+ return ent->op;
+ }
+ else
+ {
+ if (strcasecmp (ent->name + strlen ("PIXMAN_OP_"), s) == 0)
+ return ent->op;
+ }
+ }
+
+ return PIXMAN_OP_NONE;
+}
+
const char *
operator_name (pixman_op_t op)
{
- switch (op)
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
{
- case PIXMAN_OP_CLEAR: return "PIXMAN_OP_CLEAR";
- case PIXMAN_OP_SRC: return "PIXMAN_OP_SRC";
- case PIXMAN_OP_DST: return "PIXMAN_OP_DST";
- case PIXMAN_OP_OVER: return "PIXMAN_OP_OVER";
- case PIXMAN_OP_OVER_REVERSE: return "PIXMAN_OP_OVER_REVERSE";
- case PIXMAN_OP_IN: return "PIXMAN_OP_IN";
- case PIXMAN_OP_IN_REVERSE: return "PIXMAN_OP_IN_REVERSE";
- case PIXMAN_OP_OUT: return "PIXMAN_OP_OUT";
- case PIXMAN_OP_OUT_REVERSE: return "PIXMAN_OP_OUT_REVERSE";
- case PIXMAN_OP_ATOP: return "PIXMAN_OP_ATOP";
- case PIXMAN_OP_ATOP_REVERSE: return "PIXMAN_OP_ATOP_REVERSE";
- case PIXMAN_OP_XOR: return "PIXMAN_OP_XOR";
- case PIXMAN_OP_ADD: return "PIXMAN_OP_ADD";
- case PIXMAN_OP_SATURATE: return "PIXMAN_OP_SATURATE";
-
- case PIXMAN_OP_DISJOINT_CLEAR: return "PIXMAN_OP_DISJOINT_CLEAR";
- case PIXMAN_OP_DISJOINT_SRC: return "PIXMAN_OP_DISJOINT_SRC";
- case PIXMAN_OP_DISJOINT_DST: return "PIXMAN_OP_DISJOINT_DST";
- case PIXMAN_OP_DISJOINT_OVER: return "PIXMAN_OP_DISJOINT_OVER";
- case PIXMAN_OP_DISJOINT_OVER_REVERSE: return "PIXMAN_OP_DISJOINT_OVER_REVERSE";
- case PIXMAN_OP_DISJOINT_IN: return "PIXMAN_OP_DISJOINT_IN";
- case PIXMAN_OP_DISJOINT_IN_REVERSE: return "PIXMAN_OP_DISJOINT_IN_REVERSE";
- case PIXMAN_OP_DISJOINT_OUT: return "PIXMAN_OP_DISJOINT_OUT";
- case PIXMAN_OP_DISJOINT_OUT_REVERSE: return "PIXMAN_OP_DISJOINT_OUT_REVERSE";
- case PIXMAN_OP_DISJOINT_ATOP: return "PIXMAN_OP_DISJOINT_ATOP";
- case PIXMAN_OP_DISJOINT_ATOP_REVERSE: return "PIXMAN_OP_DISJOINT_ATOP_REVERSE";
- case PIXMAN_OP_DISJOINT_XOR: return "PIXMAN_OP_DISJOINT_XOR";
-
- case PIXMAN_OP_CONJOINT_CLEAR: return "PIXMAN_OP_CONJOINT_CLEAR";
- case PIXMAN_OP_CONJOINT_SRC: return "PIXMAN_OP_CONJOINT_SRC";
- case PIXMAN_OP_CONJOINT_DST: return "PIXMAN_OP_CONJOINT_DST";
- case PIXMAN_OP_CONJOINT_OVER: return "PIXMAN_OP_CONJOINT_OVER";
- case PIXMAN_OP_CONJOINT_OVER_REVERSE: return "PIXMAN_OP_CONJOINT_OVER_REVERSE";
- case PIXMAN_OP_CONJOINT_IN: return "PIXMAN_OP_CONJOINT_IN";
- case PIXMAN_OP_CONJOINT_IN_REVERSE: return "PIXMAN_OP_CONJOINT_IN_REVERSE";
- case PIXMAN_OP_CONJOINT_OUT: return "PIXMAN_OP_CONJOINT_OUT";
- case PIXMAN_OP_CONJOINT_OUT_REVERSE: return "PIXMAN_OP_CONJOINT_OUT_REVERSE";
- case PIXMAN_OP_CONJOINT_ATOP: return "PIXMAN_OP_CONJOINT_ATOP";
- case PIXMAN_OP_CONJOINT_ATOP_REVERSE: return "PIXMAN_OP_CONJOINT_ATOP_REVERSE";
- case PIXMAN_OP_CONJOINT_XOR: return "PIXMAN_OP_CONJOINT_XOR";
-
- case PIXMAN_OP_MULTIPLY: return "PIXMAN_OP_MULTIPLY";
- case PIXMAN_OP_SCREEN: return "PIXMAN_OP_SCREEN";
- case PIXMAN_OP_OVERLAY: return "PIXMAN_OP_OVERLAY";
- case PIXMAN_OP_DARKEN: return "PIXMAN_OP_DARKEN";
- case PIXMAN_OP_LIGHTEN: return "PIXMAN_OP_LIGHTEN";
- case PIXMAN_OP_COLOR_DODGE: return "PIXMAN_OP_COLOR_DODGE";
- case PIXMAN_OP_COLOR_BURN: return "PIXMAN_OP_COLOR_BURN";
- case PIXMAN_OP_HARD_LIGHT: return "PIXMAN_OP_HARD_LIGHT";
- case PIXMAN_OP_SOFT_LIGHT: return "PIXMAN_OP_SOFT_LIGHT";
- case PIXMAN_OP_DIFFERENCE: return "PIXMAN_OP_DIFFERENCE";
- case PIXMAN_OP_EXCLUSION: return "PIXMAN_OP_EXCLUSION";
- case PIXMAN_OP_HSL_HUE: return "PIXMAN_OP_HSL_HUE";
- case PIXMAN_OP_HSL_SATURATION: return "PIXMAN_OP_HSL_SATURATION";
- case PIXMAN_OP_HSL_COLOR: return "PIXMAN_OP_HSL_COLOR";
- case PIXMAN_OP_HSL_LUMINOSITY: return "PIXMAN_OP_HSL_LUMINOSITY";
-
- case PIXMAN_OP_NONE:
- return "<invalid operator 'none'>";
- };
+ const operator_entry_t *ent = &op_list[i];
+
+ if (ent->op == op)
+ return ent->name;
+ }
return "<unknown operator>";
}
@@ -1009,95 +1405,164 @@ operator_name (pixman_op_t op)
const char *
format_name (pixman_format_code_t format)
{
- switch (format)
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
{
-/* 32bpp formats */
- case PIXMAN_a8r8g8b8: return "a8r8g8b8";
- case PIXMAN_x8r8g8b8: return "x8r8g8b8";
- case PIXMAN_a8b8g8r8: return "a8b8g8r8";
- case PIXMAN_x8b8g8r8: return "x8b8g8r8";
- case PIXMAN_b8g8r8a8: return "b8g8r8a8";
- case PIXMAN_b8g8r8x8: return "b8g8r8x8";
- case PIXMAN_r8g8b8a8: return "r8g8b8a8";
- case PIXMAN_r8g8b8x8: return "r8g8b8x8";
- case PIXMAN_x14r6g6b6: return "x14r6g6b6";
- case PIXMAN_x2r10g10b10: return "x2r10g10b10";
- case PIXMAN_a2r10g10b10: return "a2r10g10b10";
- case PIXMAN_x2b10g10r10: return "x2b10g10r10";
- case PIXMAN_a2b10g10r10: return "a2b10g10r10";
+ const format_entry_t *ent = &format_list[i];
-/* sRGB formats */
- case PIXMAN_a8r8g8b8_sRGB: return "a8r8g8b8_sRGB";
+ if (ent->format == format)
+ return ent->name;
+ }
-/* 24bpp formats */
- case PIXMAN_r8g8b8: return "r8g8b8";
- case PIXMAN_b8g8r8: return "b8g8r8";
-
-/* 16bpp formats */
- case PIXMAN_r5g6b5: return "r5g6b5";
- case PIXMAN_b5g6r5: return "b5g6r5";
-
- case PIXMAN_a1r5g5b5: return "a1r5g5b5";
- case PIXMAN_x1r5g5b5: return "x1r5g5b5";
- case PIXMAN_a1b5g5r5: return "a1b5g5r5";
- case PIXMAN_x1b5g5r5: return "x1b5g5r5";
- case PIXMAN_a4r4g4b4: return "a4r4g4b4";
- case PIXMAN_x4r4g4b4: return "x4r4g4b4";
- case PIXMAN_a4b4g4r4: return "a4b4g4r4";
- case PIXMAN_x4b4g4r4: return "x4b4g4r4";
+ return "<unknown format>";
+};
-/* 8bpp formats */
- case PIXMAN_a8: return "a8";
- case PIXMAN_r3g3b2: return "r3g3b2";
- case PIXMAN_b2g3r3: return "b2g3r3";
- case PIXMAN_a2r2g2b2: return "a2r2g2b2";
- case PIXMAN_a2b2g2r2: return "a2b2g2r2";
-
-#if 0
- case PIXMAN_x4c4: return "x4c4";
- case PIXMAN_g8: return "g8";
-#endif
- case PIXMAN_c8: return "x4c4 / c8";
- case PIXMAN_x4g4: return "x4g4 / g8";
+#define IS_ZERO(f) (-DBL_MIN < (f) && (f) < DBL_MIN)
- case PIXMAN_x4a4: return "x4a4";
+typedef double (* blend_func_t) (double as, double s, double ad, double d);
-/* 4bpp formats */
- case PIXMAN_a4: return "a4";
- case PIXMAN_r1g2b1: return "r1g2b1";
- case PIXMAN_b1g2r1: return "b1g2r1";
- case PIXMAN_a1r1g1b1: return "a1r1g1b1";
- case PIXMAN_a1b1g1r1: return "a1b1g1r1";
+static force_inline double
+blend_multiply (double sa, double s, double da, double d)
+{
+ return d * s;
+}
- case PIXMAN_c4: return "c4";
- case PIXMAN_g4: return "g4";
+static force_inline double
+blend_screen (double sa, double s, double da, double d)
+{
+ return d * sa + s * da - s * d;
+}
-/* 1bpp formats */
- case PIXMAN_a1: return "a1";
+static force_inline double
+blend_overlay (double sa, double s, double da, double d)
+{
+ if (2 * d < da)
+ return 2 * s * d;
+ else
+ return sa * da - 2 * (da - d) * (sa - s);
+}
- case PIXMAN_g1: return "g1";
+static force_inline double
+blend_darken (double sa, double s, double da, double d)
+{
+ s = s * da;
+ d = d * sa;
-/* YUV formats */
- case PIXMAN_yuy2: return "yuy2";
- case PIXMAN_yv12: return "yv12";
- };
+ if (s > d)
+ return d;
+ else
+ return s;
+}
- /* Fake formats.
- *
- * This is separate switch to prevent GCC from complaining
- * that the values are not in the pixman_format_code_t enum.
- */
- switch ((uint32_t)format)
+static force_inline double
+blend_lighten (double sa, double s, double da, double d)
+{
+ s = s * da;
+ d = d * sa;
+
+ if (s > d)
+ return s;
+ else
+ return d;
+}
+
+static force_inline double
+blend_color_dodge (double sa, double s, double da, double d)
+{
+ if (IS_ZERO (d))
+ return 0.0f;
+ else if (d * sa >= sa * da - s * da)
+ return sa * da;
+ else if (IS_ZERO (sa - s))
+ return sa * da;
+ else
+ return sa * sa * d / (sa - s);
+}
+
+static force_inline double
+blend_color_burn (double sa, double s, double da, double d)
+{
+ if (d >= da)
+ return sa * da;
+ else if (sa * (da - d) >= s * da)
+ return 0.0f;
+ else if (IS_ZERO (s))
+ return 0.0f;
+ else
+ return sa * (da - sa * (da - d) / s);
+}
+
+static force_inline double
+blend_hard_light (double sa, double s, double da, double d)
+{
+ if (2 * s < sa)
+ return 2 * s * d;
+ else
+ return sa * da - 2 * (da - d) * (sa - s);
+}
+
+static force_inline double
+blend_soft_light (double sa, double s, double da, double d)
+{
+ if (2 * s <= sa)
{
- case PIXMAN_null: return "null";
- case PIXMAN_solid: return "solid";
- case PIXMAN_pixbuf: return "pixbuf";
- case PIXMAN_rpixbuf: return "rpixbuf";
- case PIXMAN_unknown: return "unknown";
- };
+ if (IS_ZERO (da))
+ return d * sa;
+ else
+ return d * sa - d * (da - d) * (sa - 2 * s) / da;
+ }
+ else
+ {
+ if (IS_ZERO (da))
+ {
+ return d * sa;
+ }
+ else
+ {
+ if (4 * d <= da)
+ return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3);
+ else
+ return d * sa + (sqrt (d * da) - d) * (2 * s - sa);
+ }
+ }
+}
- return "<unknown format>";
-};
+static force_inline double
+blend_difference (double sa, double s, double da, double d)
+{
+ double dsa = d * sa;
+ double sda = s * da;
+
+ if (sda < dsa)
+ return dsa - sda;
+ else
+ return sda - dsa;
+}
+
+static force_inline double
+blend_exclusion (double sa, double s, double da, double d)
+{
+ return s * da + d * sa - 2 * d * s;
+}
+
+static double
+clamp (double d)
+{
+ if (d > 1.0)
+ return 1.0;
+ else if (d < 0.0)
+ return 0.0;
+ else
+ return d;
+}
+
+static double
+blend_channel (double as, double s, double ad, double d,
+ blend_func_t blend)
+{
+ return clamp ((1 - ad) * s + (1 - as) * d + blend (as, s, ad, d));
+}
static double
calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
@@ -1336,6 +1801,21 @@ do_composite (pixman_op_t op,
{
color_t srcval, srcalpha;
+ static const blend_func_t blend_funcs[] =
+ {
+ blend_multiply,
+ blend_screen,
+ blend_overlay,
+ blend_darken,
+ blend_lighten,
+ blend_color_dodge,
+ blend_color_burn,
+ blend_hard_light,
+ blend_soft_light,
+ blend_difference,
+ blend_exclusion,
+ };
+
if (mask == NULL)
{
srcval = *src;
@@ -1370,10 +1850,22 @@ do_composite (pixman_op_t op,
srcalpha.a = src->a * mask->a;
}
- result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a);
- result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a);
- result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a);
- result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a);
+ if (op >= PIXMAN_OP_MULTIPLY)
+ {
+ blend_func_t func = blend_funcs[op - PIXMAN_OP_MULTIPLY];
+
+ result->a = srcalpha.a + dst->a - srcalpha.a * dst->a;
+ result->r = blend_channel (srcalpha.r, srcval.r, dst->a, dst->r, func);
+ result->g = blend_channel (srcalpha.g, srcval.g, dst->a, dst->g, func);
+ result->b = blend_channel (srcalpha.b, srcval.b, dst->a, dst->b, func);
+ }
+ else
+ {
+ result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a);
+ result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a);
+ result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a);
+ result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a);
+ }
}
static double
@@ -1580,7 +2072,7 @@ get_limits (const pixel_checker_t *checker, double limit,
/* The acceptable deviation in units of [0.0, 1.0]
*/
-#define DEVIATION (0.0064)
+#define DEVIATION (0.0128)
void
pixel_checker_get_max (const pixel_checker_t *checker, color_t *color,
diff --git a/lib/pixman/test/utils.h b/lib/pixman/test/utils.h
index ebb14d9e4..e299d1d06 100644
--- a/lib/pixman/test/utils.h
+++ b/lib/pixman/test/utils.h
@@ -86,6 +86,17 @@ is_little_endian (void)
void
image_endian_swap (pixman_image_t *img);
+#if defined (HAVE_MPROTECT) && defined (HAVE_GETPAGESIZE) && \
+ defined (HAVE_SYS_MMAN_H) && defined (HAVE_MMAP)
+/* fence_malloc and friends have working fence implementation.
+ * Without this, fence_malloc still allocs but does not catch
+ * out-of-bounds accesses.
+ */
+#define FENCE_MALLOC_ACTIVE 1
+#else
+#define FENCE_MALLOC_ACTIVE 0
+#endif
+
/* Allocate memory that is bounded by protected pages,
* so that out-of-bounds access will cause segfaults
*/
@@ -95,6 +106,16 @@ fence_malloc (int64_t len);
void
fence_free (void *data);
+pixman_image_t *
+fence_image_create_bits (pixman_format_code_t format,
+ int min_width,
+ int height,
+ pixman_bool_t stride_fence);
+
+/* Return the page size if FENCE_MALLOC_ACTIVE, or zero otherwise */
+unsigned long
+fence_get_page_size ();
+
/* Generate n_bytes random bytes in fence_malloced memory */
uint8_t *
make_random_bytes (int n_bytes);
@@ -120,6 +141,7 @@ fail_after (int seconds, const char *msg);
/* If possible, enable traps for floating point exceptions */
void enable_divbyzero_exceptions(void);
+void enable_invalid_exceptions(void);
/* Converts a8r8g8b8 pixels to pixels that
* - are not premultiplied,
@@ -186,6 +208,18 @@ convert_linear_to_srgb (double component);
void
initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
+pixman_format_code_t
+format_from_string (const char *s);
+
+void
+list_formats (void);
+
+void
+list_operators (void);
+
+pixman_op_t
+operator_from_string (const char *s);
+
const char *
operator_name (pixman_op_t op);