diff options
29 files changed, 874 insertions, 234 deletions
diff --git a/lib/pixman/Makefile.am b/lib/pixman/Makefile.am index 6e56d5140..c5ebe16b5 100644 --- a/lib/pixman/Makefile.am +++ b/lib/pixman/Makefile.am @@ -124,7 +124,7 @@ release-publish-message: $(HASHFILES) ensure-prev @echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)" @echo "" @echo "Git:" - @echo " git://git.freedesktop.org/git/pixman" + @echo " https://gitlab.freedesktop.org/pixman/pixman.git" @echo " tag: $(PACKAGE)-$(VERSION)" @echo "" @echo "Log:" diff --git a/lib/pixman/Makefile.bsd-wrapper b/lib/pixman/Makefile.bsd-wrapper index dfefaed6f..2ee795d89 100644 --- a/lib/pixman/Makefile.bsd-wrapper +++ b/lib/pixman/Makefile.bsd-wrapper @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.23 2014/07/20 19:22:20 matthieu Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.24 2019/01/18 14:34:01 matthieu Exp $ .include <bsd.own.mk> -SHARED_LIBS= pixman-1 32.6 +SHARED_LIBS= pixman-1 36.0 .if ${MACHINE_ARCH} == arm CONFIGURE_ARGS += --disable-arm-simd --disable-arm-neon diff --git a/lib/pixman/Makefile.in b/lib/pixman/Makefile.in index 79792a925..b090c784d 100644 --- a/lib/pixman/Makefile.in +++ b/lib/pixman/Makefile.in @@ -243,6 +243,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PIXMAN_GNUPLOT = @PIXMAN_GNUPLOT@ PIXMAN_TIMERS = @PIXMAN_TIMERS@ PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ @@ -972,7 +973,7 @@ release-publish-message: $(HASHFILES) ensure-prev @echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)" @echo "" @echo "Git:" - @echo " git://git.freedesktop.org/git/pixman" + @echo " https://gitlab.freedesktop.org/pixman/pixman.git" @echo " tag: $(PACKAGE)-$(VERSION)" @echo "" @echo "Log:" diff --git a/lib/pixman/compile b/lib/pixman/compile index 0fc915d98..96fe54c1b 100755 --- a/lib/pixman/compile +++ b/lib/pixman/compile @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -255,7 +255,8 @@ EOF echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,10 +340,10 @@ exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: #! /bin/sh diff --git a/lib/pixman/config.h.in b/lib/pixman/config.h.in index ab705701e..27adb16dc 100644 --- a/lib/pixman/config.h.in +++ b/lib/pixman/config.h.in @@ -112,6 +112,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* enable output that can be piped to gnuplot */ +#undef PIXMAN_GNUPLOT + /* enable TIMER_BEGIN/TIMER_END macros */ #undef PIXMAN_TIMERS diff --git a/lib/pixman/configure b/lib/pixman/configure index 44e3c8529..e2480111c 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.34.0. +# Generated by GNU Autoconf 2.69 for pixman 0.36.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.34.0' -PACKAGE_STRING='pixman 0.34.0' +PACKAGE_VERSION='0.36.0' +PACKAGE_STRING='pixman 0.36.0' PACKAGE_BUGREPORT='pixman@lists.freedesktop.org' PACKAGE_URL='' @@ -651,6 +651,7 @@ GTK_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG +PIXMAN_GNUPLOT PIXMAN_TIMERS TESTPROGS_EXTRA_LDFLAGS USE_GCC_INLINE_ASM_FALSE @@ -833,6 +834,7 @@ enable_mips_dspr2 enable_gcc_inline_asm enable_static_testprogs enable_timers +enable_gnuplot enable_gtk enable_libpng ' @@ -1394,7 +1396,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.34.0 to adapt to many kinds of systems. +\`configure' configures pixman 0.36.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1464,7 +1466,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pixman 0.34.0:";; + short | recursive ) echo "Configuration of pixman 0.36.0:";; esac cat <<\_ACEOF @@ -1503,6 +1505,8 @@ Optional Features: --enable-static-testprogs build test programs as static binaries [default=no] --enable-timers enable TIMER_BEGIN and TIMER_END macros [default=no] + --enable-gnuplot enable output of filters that can be piped to + gnuplot [default=no] --enable-gtk enable tests using GTK+ [default=auto] --enable-libpng Build support for libpng (default: auto) @@ -1602,7 +1606,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pixman configure 0.34.0 +pixman configure 0.36.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2200,7 +2204,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.34.0, which was +It was created by pixman $as_me 0.36.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3024,7 +3028,7 @@ fi # Define the identity of the package. PACKAGE='pixman' - VERSION='0.34.0' + VERSION='0.36.0' cat >>confdefs.h <<_ACEOF @@ -12232,11 +12236,11 @@ fi -LT_VERSION_INFO="34:0:34" +LT_VERSION_INFO="36:0:36" PIXMAN_VERSION_MAJOR=0 -PIXMAN_VERSION_MINOR=34 +PIXMAN_VERSION_MINOR=36 PIXMAN_VERSION_MICRO=0 @@ -13468,6 +13472,22 @@ fi +# Check whether --enable-gnuplot was given. +if test "${enable_gnuplot+set}" = set; then : + enableval=$enable_gnuplot; enable_gnuplot=$enableval +else + enable_gnuplot=no +fi + + +if test $enable_gnuplot = yes ; then + +$as_echo "#define PIXMAN_GNUPLOT 1" >>confdefs.h + +fi + + + # Check whether --enable-gtk was given. if test "${enable_gtk+set}" = set; then : enableval=$enable_gtk; enable_gtk=$enableval @@ -15289,7 +15309,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.34.0, which was +This file was extended by pixman $as_me 0.36.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15355,7 +15375,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.34.0 +pixman config.status 0.36.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 b08d7a127..63a7238dc 100644 --- a/lib/pixman/configure.ac +++ b/lib/pixman/configure.ac @@ -53,7 +53,7 @@ AC_PREREQ([2.57]) # m4_define([pixman_major], 0) -m4_define([pixman_minor], 34) +m4_define([pixman_minor], 36) m4_define([pixman_micro], 0) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) @@ -836,6 +836,19 @@ fi AC_SUBST(PIXMAN_TIMERS) dnl =================================== +dnl gnuplot + +AC_ARG_ENABLE(gnuplot, + [AC_HELP_STRING([--enable-gnuplot], + [enable output of filters that can be piped to gnuplot [default=no]])], + [enable_gnuplot=$enableval], [enable_gnuplot=no]) + +if test $enable_gnuplot = yes ; then + AC_DEFINE(PIXMAN_GNUPLOT, 1, [enable output that can be piped to gnuplot]) +fi +AC_SUBST(PIXMAN_GNUPLOT) + +dnl =================================== dnl GTK+ AC_ARG_ENABLE(gtk, diff --git a/lib/pixman/demos/Makefile.in b/lib/pixman/demos/Makefile.in index ee9be86ea..3d76a82af 100644 --- a/lib/pixman/demos/Makefile.in +++ b/lib/pixman/demos/Makefile.in @@ -375,6 +375,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PIXMAN_GNUPLOT = @PIXMAN_GNUPLOT@ PIXMAN_TIMERS = @PIXMAN_TIMERS@ PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ diff --git a/lib/pixman/demos/scale.c b/lib/pixman/demos/scale.c index d00307e44..0995ad08d 100644 --- a/lib/pixman/demos/scale.c +++ b/lib/pixman/demos/scale.c @@ -55,50 +55,70 @@ get_widget (app_t *app, const char *name) return widget; } -static double -min4 (double a, double b, double c, double d) -{ - double m1, m2; - - m1 = MIN (a, b); - m2 = MIN (c, d); - return MIN (m1, m2); -} - -static double -max4 (double a, double b, double c, double d) -{ - double m1, m2; - - m1 = MAX (a, b); - m2 = MAX (c, d); - return MAX (m1, m2); -} - +/* Figure out the boundary of a diameter=1 circle transformed into an ellipse + * by trans. Proof that this is the correct calculation: + * + * Transform x,y to u,v by this matrix calculation: + * + * |u| |a c| |x| + * |v| = |b d|*|y| + * + * Horizontal component: + * + * u = ax+cy (1) + * + * For each x,y on a radius-1 circle (p is angle to the point): + * + * x^2+y^2 = 1 + * x = cos(p) + * y = sin(p) + * dx/dp = -sin(p) = -y + * dy/dp = cos(p) = x + * + * Figure out derivative of (1) relative to p: + * + * du/dp = a(dx/dp) + c(dy/dp) + * = -ay + cx + * + * The min and max u are when du/dp is zero: + * + * -ay + cx = 0 + * cx = ay + * c = ay/x (2) + * y = cx/a (3) + * + * Substitute (2) into (1) and simplify: + * + * u = ax + ay^2/x + * = a(x^2+y^2)/x + * = a/x (because x^2+y^2 = 1) + * x = a/u (4) + * + * Substitute (4) into (3) and simplify: + * + * y = c(a/u)/a + * y = c/u (5) + * + * Square (4) and (5) and add: + * + * x^2+y^2 = (a^2+c^2)/u^2 + * + * But x^2+y^2 is 1: + * + * 1 = (a^2+c^2)/u^2 + * u^2 = a^2+c^2 + * u = hypot(a,c) + * + * Similarily the max/min of v is at: + * + * v = hypot(b,d) + * + */ static void compute_extents (pixman_f_transform_t *trans, double *sx, double *sy) { - double min_x, max_x, min_y, max_y; - pixman_f_vector_t v[4] = - { - { { 1, 1, 1 } }, - { { -1, 1, 1 } }, - { { -1, -1, 1 } }, - { { 1, -1, 1 } }, - }; - - pixman_f_transform_point (trans, &v[0]); - pixman_f_transform_point (trans, &v[1]); - pixman_f_transform_point (trans, &v[2]); - pixman_f_transform_point (trans, &v[3]); - - min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); - max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); - min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); - max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); - - *sx = (max_x - min_x) / 2.0; - *sy = (max_y - min_y) / 2.0; + *sx = hypot (trans->m[0][0], trans->m[0][1]) / trans->m[2][2]; + *sy = hypot (trans->m[1][0], trans->m[1][1]) / trans->m[2][2]; } typedef struct diff --git a/lib/pixman/demos/scale.ui b/lib/pixman/demos/scale.ui index ee985dd1c..d498d26e8 100644 --- a/lib/pixman/demos/scale.ui +++ b/lib/pixman/demos/scale.ui @@ -177,6 +177,7 @@ id="lock_checkbutton"> <property name="label" translatable="yes">Lock X and Y Dimensions</property> <property name="xalign">0.0</property> + <property name="active">True</property> </object> <packing> <property name="expand">False</property> @@ -301,6 +302,7 @@ <object class="GtkSpinButton" id="subsample_spin_button"> <property name="visible">True</property> <property name="adjustment">subsample_adjustment</property> + <property name="value">4</property> </object> <packing> <property name="left_attach">1</property> diff --git a/lib/pixman/pixman/Makefile.in b/lib/pixman/pixman/Makefile.in index 1fc80ecf4..f46887286 100644 --- a/lib/pixman/pixman/Makefile.in +++ b/lib/pixman/pixman/Makefile.in @@ -384,6 +384,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PIXMAN_GNUPLOT = @PIXMAN_GNUPLOT@ PIXMAN_TIMERS = @PIXMAN_TIMERS@ PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ diff --git a/lib/pixman/pixman/pixman-access.c b/lib/pixman/pixman/pixman-access.c index 4f0642d77..8dfd35f45 100644 --- a/lib/pixman/pixman/pixman-access.c +++ b/lib/pixman/pixman/pixman-access.c @@ -642,6 +642,48 @@ fetch_scanline_a2r10g10b10_float (bits_image_t * image, } /* Expects a float buffer */ +#ifndef PIXMAN_FB_ACCESSORS +static void +fetch_scanline_rgbf_float (bits_image_t *image, + int x, + int y, + int width, + uint32_t * b, + const uint32_t *mask) +{ + const float *bits = (float *)image->bits + y * image->rowstride; + const float *pixel = bits + x * 3; + argb_t *buffer = (argb_t *)b; + + for (; width--; buffer++) { + buffer->r = *pixel++; + buffer->g = *pixel++; + buffer->b = *pixel++; + buffer->a = 1.f; + } +} + +static void +fetch_scanline_rgbaf_float (bits_image_t *image, + int x, + int y, + int width, + uint32_t * b, + const uint32_t *mask) +{ + const float *bits = (float *)image->bits + y * image->rowstride; + const float *pixel = bits + x * 4; + argb_t *buffer = (argb_t *)b; + + for (; width--; buffer++) { + buffer->r = *pixel++; + buffer->g = *pixel++; + buffer->b = *pixel++; + buffer->a = *pixel++; + } +} +#endif + static void fetch_scanline_x2r10g10b10_float (bits_image_t *image, int x, @@ -805,6 +847,40 @@ fetch_scanline_yv12 (bits_image_t *image, /**************************** Pixel wise fetching *****************************/ +#ifndef PIXMAN_FB_ACCESSORS +static argb_t +fetch_pixel_rgbf_float (bits_image_t *image, + int offset, + int line) +{ + float *bits = (float *)image->bits + line * image->rowstride; + argb_t argb; + + argb.r = bits[offset * 3]; + argb.g = bits[offset * 3 + 1]; + argb.b = bits[offset * 3 + 2]; + argb.a = 1.f; + + return argb; +} + +static argb_t +fetch_pixel_rgbaf_float (bits_image_t *image, + int offset, + int line) +{ + float *bits = (float *)image->bits + line * image->rowstride; + argb_t argb; + + argb.r = bits[offset * 4]; + argb.g = bits[offset * 4 + 1]; + argb.b = bits[offset * 4 + 2]; + argb.a = bits[offset * 4 + 3]; + + return argb; +} +#endif + static argb_t fetch_pixel_x2r10g10b10_float (bits_image_t *image, int offset, @@ -962,6 +1038,45 @@ fetch_pixel_yv12 (bits_image_t *image, /*********************************** Store ************************************/ +#ifndef PIXMAN_FB_ACCESSORS +static void +store_scanline_rgbaf_float (bits_image_t * image, + int x, + int y, + int width, + const uint32_t *v) +{ + float *bits = (float *)image->bits + image->rowstride * y + 4 * x; + const argb_t *values = (argb_t *)v; + + for (; width; width--, values++) + { + *bits++ = values->r; + *bits++ = values->g; + *bits++ = values->b; + *bits++ = values->a; + } +} + +static void +store_scanline_rgbf_float (bits_image_t * image, + int x, + int y, + int width, + const uint32_t *v) +{ + float *bits = (float *)image->bits + image->rowstride * y + 3 * x; + const argb_t *values = (argb_t *)v; + + for (; width; width--, values++) + { + *bits++ = values->r; + *bits++ = values->g; + *bits++ = values->b; + } +} +#endif + static void store_scanline_a2r10g10b10_float (bits_image_t * image, int x, @@ -1351,7 +1466,18 @@ static const format_info_t accessors[] = FORMAT_INFO (g1), /* Wide formats */ - +#ifndef PIXMAN_FB_ACCESSORS + { PIXMAN_rgba_float, + NULL, fetch_scanline_rgbaf_float, + fetch_pixel_generic_lossy_32, fetch_pixel_rgbaf_float, + NULL, store_scanline_rgbaf_float }, + + { PIXMAN_rgb_float, + NULL, fetch_scanline_rgbf_float, + fetch_pixel_generic_lossy_32, fetch_pixel_rgbf_float, + NULL, store_scanline_rgbf_float }, +#endif + { PIXMAN_a2r10g10b10, NULL, fetch_scanline_a2r10g10b10_float, fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float, diff --git a/lib/pixman/pixman/pixman-bits-image.c b/lib/pixman/pixman/pixman-bits-image.c index dcdcc6994..9fb91ff58 100644 --- a/lib/pixman/pixman/pixman-bits-image.c +++ b/lib/pixman/pixman/pixman-bits-image.c @@ -948,6 +948,9 @@ _pixman_bits_image_init (pixman_image_t * image, { uint32_t *free_me = NULL; + if (PIXMAN_FORMAT_BPP (format) == 128) + return_val_if_fail(!(rowstride % 4), FALSE); + if (!bits && width && height) { int rowstride_bytes; diff --git a/lib/pixman/pixman/pixman-fast-path.c b/lib/pixman/pixman/pixman-fast-path.c index 53d4a1f90..b4daa2657 100644 --- a/lib/pixman/pixman/pixman-fast-path.c +++ b/lib/pixman/pixman/pixman-fast-path.c @@ -3258,9 +3258,9 @@ static const pixman_iter_info_t fast_iters[] = }, #define AFFINE_FAST_PATHS(name, format, repeat) \ - SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ + NEAREST_AFFINE_FAST_PATH(name, format, repeat) \ BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ - NEAREST_AFFINE_FAST_PATH(name, format, repeat) + SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD) AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE) diff --git a/lib/pixman/pixman/pixman-filter.c b/lib/pixman/pixman/pixman-filter.c index b2bf53fed..5f3b752f9 100644 --- a/lib/pixman/pixman/pixman-filter.c +++ b/lib/pixman/pixman/pixman-filter.c @@ -109,14 +109,16 @@ general_cubic (double x, double B, double C) if (ax < 1) { - return ((12 - 9 * B - 6 * C) * ax * ax * ax + - (-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6; + return (((12 - 9 * B - 6 * C) * ax + + (-18 + 12 * B + 6 * C)) * ax * ax + + (6 - 2 * B)) / 6; } - else if (ax >= 1 && ax < 2) + else if (ax < 2) { - return ((-B - 6 * C) * ax * ax * ax + - (6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) * - ax + (8 * B + 24 * C)) / 6; + return ((((-B - 6 * C) * ax + + (6 * B + 30 * C)) * ax + + (-12 * B - 48 * C)) * ax + + (8 * B + 24 * C)) / 6; } else { @@ -141,7 +143,7 @@ static const filter_info_t filters[] = { PIXMAN_KERNEL_BOX, box_kernel, 1.0 }, { PIXMAN_KERNEL_LINEAR, linear_kernel, 2.0 }, { PIXMAN_KERNEL_CUBIC, cubic_kernel, 4.0 }, - { PIXMAN_KERNEL_GAUSSIAN, gaussian_kernel, 6 * SIGMA }, + { PIXMAN_KERNEL_GAUSSIAN, gaussian_kernel, 5.0 }, { PIXMAN_KERNEL_LANCZOS2, lanczos2_kernel, 4.0 }, { PIXMAN_KERNEL_LANCZOS3, lanczos3_kernel, 6.0 }, { PIXMAN_KERNEL_LANCZOS3_STRETCHED, nice_kernel, 8.0 }, @@ -160,18 +162,21 @@ integral (pixman_kernel_t kernel1, double x1, pixman_kernel_t kernel2, double scale, double x2, double width) { - /* If the integration interval crosses zero, break it into - * two separate integrals. This ensures that filters such - * as LINEAR that are not differentiable at 0 will still - * integrate properly. + if (kernel1 == PIXMAN_KERNEL_BOX && kernel2 == PIXMAN_KERNEL_BOX) + { + return width; + } + /* The LINEAR filter is not differentiable at 0, so if the + * integration interval crosses zero, break it into two + * separate integrals. */ - if (x1 < 0 && x1 + width > 0) + else if (kernel1 == PIXMAN_KERNEL_LINEAR && x1 < 0 && x1 + width > 0) { return integral (kernel1, x1, kernel2, scale, x2, - x1) + integral (kernel1, 0, kernel2, scale, x2 - x1, width + x1); } - else if (x2 < 0 && x2 + width > 0) + else if (kernel2 == PIXMAN_KERNEL_LINEAR && x2 < 0 && x2 + width > 0) { return integral (kernel1, x1, kernel2, scale, x2, - x2) + @@ -189,13 +194,19 @@ integral (pixman_kernel_t kernel1, double x1, } else { - /* Integration via Simpson's rule */ -#define N_SEGMENTS 128 + /* Integration via Simpson's rule + * See http://www.intmath.com/integration/6-simpsons-rule.php + * 12 segments (6 cubic approximations) seems to produce best + * result for lanczos3.linear, which was the combination that + * showed the most errors. This makes sense as the lanczos3 + * filter is 6 wide. + */ +#define N_SEGMENTS 12 #define SAMPLE(a1, a2) \ (filters[kernel1].func ((a1)) * filters[kernel2].func ((a2) * scale)) double s = 0.0; - double h = width / (double)N_SEGMENTS; + double h = width / N_SEGMENTS; int i; s = SAMPLE (x1, x2); @@ -204,11 +215,14 @@ integral (pixman_kernel_t kernel1, double x1, { double a1 = x1 + h * i; double a2 = x2 + h * i; + s += 4 * SAMPLE (a1, a2); + } + for (i = 2; i < N_SEGMENTS; i += 2) + { + double a1 = x1 + h * i; + double a2 = x2 + h * i; s += 2 * SAMPLE (a1, a2); - - if (i >= 2 && i < N_SEGMENTS - 1) - s += 4 * SAMPLE (a1, a2); } s += SAMPLE (x1 + width, x2 + width); @@ -217,25 +231,17 @@ integral (pixman_kernel_t kernel1, double x1, } } -static pixman_fixed_t * -create_1d_filter (int *width, +static void +create_1d_filter (int width, pixman_kernel_t reconstruct, pixman_kernel_t sample, double scale, - int n_phases) + int n_phases, + pixman_fixed_t *p) { - pixman_fixed_t *params, *p; double step; - double size; int i; - size = scale * filters[sample].width + filters[reconstruct].width; - *width = ceil (size); - - p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t)); - if (!params) - return NULL; - step = 1.0 / n_phases; for (i = 0; i < n_phases; ++i) @@ -243,15 +249,15 @@ create_1d_filter (int *width, double frac = step / 2.0 + i * step; pixman_fixed_t new_total; int x, x1, x2; - double total; + double total, e; /* Sample convolution of reconstruction and sampling * filter. See rounding.txt regarding the rounding * and sample positions. */ - x1 = ceil (frac - *width / 2.0 - 0.5); - x2 = x1 + *width; + x1 = ceil (frac - width / 2.0 - 0.5); + x2 = x1 + width; total = 0; for (x = x1; x < x2; ++x) @@ -274,29 +280,154 @@ create_1d_filter (int *width, ihigh - ilow); } - total += c; - *p++ = (pixman_fixed_t)(c * 65536.0 + 0.5); + *p = (pixman_fixed_t)floor (c * 65536.0 + 0.5); + total += *p; + p++; } - /* Normalize */ - p -= *width; - total = 1 / total; + /* Normalize, with error diffusion */ + p -= width; + total = 65536.0 / total; new_total = 0; + e = 0.0; for (x = x1; x < x2; ++x) { - pixman_fixed_t t = (*p) * total + 0.5; + double v = (*p) * total + e; + pixman_fixed_t t = floor (v + 0.5); + e = v - t; new_total += t; *p++ = t; } - if (new_total != pixman_fixed_1) - *(p - *width / 2) += (pixman_fixed_1 - new_total); + /* pixman_fixed_e's worth of error may remain; put it + * at the first sample, since that is the only one that + * hasn't had any error diffused into it. + */ + *(p - width) += pixman_fixed_1 - new_total; } +} - return params; + +static int +filter_width (pixman_kernel_t reconstruct, pixman_kernel_t sample, double size) +{ + return ceil (filters[reconstruct].width + size * filters[sample].width); +} + +#ifdef PIXMAN_GNUPLOT + +/* If enable-gnuplot is configured, then you can pipe the output of a + * pixman-using program to gnuplot and get a continuously-updated plot + * of the horizontal filter. This works well with demos/scale to test + * the filter generation. + * + * The plot is all the different subposition filters shuffled + * together. This is misleading in a few cases: + * + * IMPULSE.BOX - goes up and down as the subfilters have different + * numbers of non-zero samples + * IMPULSE.TRIANGLE - somewhat crooked for the same reason + * 1-wide filters - looks triangular, but a 1-wide box would be more + * accurate + */ +static void +gnuplot_filter (int width, int n_phases, const pixman_fixed_t* p) +{ + double step; + int i, j; + int first; + + step = 1.0 / n_phases; + + printf ("set style line 1 lc rgb '#0060ad' lt 1 lw 0.5 pt 7 pi 1 ps 0.5\n"); + printf ("plot [x=%g:%g] '-' with linespoints ls 1\n", -width*0.5, width*0.5); + /* Print a point at the origin so that y==0 line is included: */ + printf ("0 0\n\n"); + + /* The position of the first sample of the phase corresponding to + * frac is given by: + * + * ceil (frac - width / 2.0 - 0.5) + 0.5 - frac + * + * We have to find the frac that minimizes this expression. + * + * For odd widths, we have + * + * ceil (frac - width / 2.0 - 0.5) + 0.5 - frac + * = ceil (frac) + K - frac + * = 1 + K - frac + * + * for some K, so this is minimized when frac is maximized and + * strictly growing with frac. So for odd widths, we can simply + * start at the last phase and go backwards. + * + * For even widths, we have + * + * ceil (frac - width / 2.0 - 0.5) + 0.5 - frac + * = ceil (frac - 0.5) + K - frac + * + * The graph for this function (ignoring K) looks like this: + * + * 0.5 + * | |\ + * | | \ + * | | \ + * 0 | | \ + * |\ | + * | \ | + * | \ | + * -0.5 | \| + * --------------------------------- + * 0 0.5 1 + * + * So in this case we need to start with the phase whose frac is + * less than, but as close as possible to 0.5, then go backwards + * until we hit the first phase, then wrap around to the last + * phase and continue backwards. + * + * Which phase is as close as possible 0.5? The locations of the + * sampling point corresponding to the kth phase is given by + * 1/(2 * n_phases) + k / n_phases: + * + * 1/(2 * n_phases) + k / n_phases = 0.5 + * + * from which it follows that + * + * k = (n_phases - 1) / 2 + * + * rounded down is the phase in question. + */ + if (width & 1) + first = n_phases - 1; + else + first = (n_phases - 1) / 2; + + for (j = 0; j < width; ++j) + { + for (i = 0; i < n_phases; ++i) + { + int phase = first - i; + double frac, pos; + + if (phase < 0) + phase = n_phases + phase; + + frac = step / 2.0 + phase * step; + pos = ceil (frac - width / 2.0 - 0.5) + 0.5 - frac + j; + + printf ("%g %g\n", + pos, + pixman_fixed_to_double (*(p + phase * width + j))); + } + } + + printf ("e\n"); + fflush (stdout); } +#endif + /* Create the parameter list for a SEPARABLE_CONVOLUTION filter * with the given kernels and scale parameters */ @@ -313,38 +444,35 @@ pixman_filter_create_separable_convolution (int *n_values, { double sx = fabs (pixman_fixed_to_double (scale_x)); double sy = fabs (pixman_fixed_to_double (scale_y)); - pixman_fixed_t *horz = NULL, *vert = NULL, *params = NULL; + pixman_fixed_t *params; int subsample_x, subsample_y; int width, height; + width = filter_width (reconstruct_x, sample_x, sx); subsample_x = (1 << subsample_bits_x); - subsample_y = (1 << subsample_bits_y); - horz = create_1d_filter (&width, reconstruct_x, sample_x, sx, subsample_x); - vert = create_1d_filter (&height, reconstruct_y, sample_y, sy, subsample_y); + height = filter_width (reconstruct_y, sample_y, sy); + subsample_y = (1 << subsample_bits_y); - if (!horz || !vert) - goto out; - *n_values = 4 + width * subsample_x + height * subsample_y; params = malloc (*n_values * sizeof (pixman_fixed_t)); if (!params) - goto out; + return NULL; params[0] = pixman_int_to_fixed (width); params[1] = pixman_int_to_fixed (height); params[2] = pixman_int_to_fixed (subsample_bits_x); params[3] = pixman_int_to_fixed (subsample_bits_y); - memcpy (params + 4, horz, - width * subsample_x * sizeof (pixman_fixed_t)); - memcpy (params + 4 + width * subsample_x, vert, - height * subsample_y * sizeof (pixman_fixed_t)); + create_1d_filter (width, reconstruct_x, sample_x, sx, subsample_x, + params + 4); + create_1d_filter (height, reconstruct_y, sample_y, sy, subsample_y, + params + 4 + width * subsample_x); -out: - free (horz); - free (vert); +#ifdef PIXMAN_GNUPLOT + gnuplot_filter(width, subsample_x, params + 4); +#endif return params; } diff --git a/lib/pixman/pixman/pixman-image.c b/lib/pixman/pixman/pixman-image.c index 1ff1a4974..7a851e221 100644 --- a/lib/pixman/pixman/pixman-image.c +++ b/lib/pixman/pixman/pixman-image.c @@ -335,37 +335,47 @@ compute_image_info (pixman_image_t *image) { flags |= FAST_PATH_NEAREST_FILTER; } - else if ( - /* affine and integer translation components in matrix ... */ - ((flags & FAST_PATH_AFFINE_TRANSFORM) && - !pixman_fixed_frac (image->common.transform->matrix[0][2] | - image->common.transform->matrix[1][2])) && - ( - /* ... combined with a simple rotation */ - (flags & (FAST_PATH_ROTATE_90_TRANSFORM | - FAST_PATH_ROTATE_180_TRANSFORM | - FAST_PATH_ROTATE_270_TRANSFORM)) || - /* ... or combined with a simple non-rotated translation */ - (image->common.transform->matrix[0][0] == pixman_fixed_1 && - image->common.transform->matrix[1][1] == pixman_fixed_1 && - image->common.transform->matrix[0][1] == 0 && - image->common.transform->matrix[1][0] == 0) - ) - ) + else if (flags & FAST_PATH_AFFINE_TRANSFORM) { - /* FIXME: there are some affine-test failures, showing that - * handling of BILINEAR and NEAREST filter is not quite - * equivalent when getting close to 32K for the translation - * components of the matrix. That's likely some bug, but for - * now just skip BILINEAR->NEAREST optimization in this case. + /* Suppose the transform is + * + * [ t00, t01, t02 ] + * [ t10, t11, t12 ] + * [ 0, 0, 1 ] + * + * and the destination coordinates are (n + 0.5, m + 0.5). Then + * the transformed x coordinate is: + * + * tx = t00 * (n + 0.5) + t01 * (m + 0.5) + t02 + * = t00 * n + t01 * m + t02 + (t00 + t01) * 0.5 + * + * which implies that if t00, t01 and t02 are all integers + * and (t00 + t01) is odd, then tx will be an integer plus 0.5, + * which means a BILINEAR filter will reduce to NEAREST. The same + * applies in the y direction */ - pixman_fixed_t magic_limit = pixman_int_to_fixed (30000); - if (image->common.transform->matrix[0][2] <= magic_limit && - image->common.transform->matrix[1][2] <= magic_limit && - image->common.transform->matrix[0][2] >= -magic_limit && - image->common.transform->matrix[1][2] >= -magic_limit) + pixman_fixed_t (*t)[3] = image->common.transform->matrix; + + if ((pixman_fixed_frac ( + t[0][0] | t[0][1] | t[0][2] | + t[1][0] | t[1][1] | t[1][2]) == 0) && + (pixman_fixed_to_int ( + (t[0][0] + t[0][1]) & (t[1][0] + t[1][1])) % 2) == 1) { - flags |= FAST_PATH_NEAREST_FILTER; + /* FIXME: there are some affine-test failures, showing that + * handling of BILINEAR and NEAREST filter is not quite + * equivalent when getting close to 32K for the translation + * components of the matrix. That's likely some bug, but for + * now just skip BILINEAR->NEAREST optimization in this case. + */ + pixman_fixed_t magic_limit = pixman_int_to_fixed (30000); + if (image->common.transform->matrix[0][2] <= magic_limit && + image->common.transform->matrix[1][2] <= magic_limit && + image->common.transform->matrix[0][2] >= -magic_limit && + image->common.transform->matrix[1][2] >= -magic_limit) + { + flags |= FAST_PATH_NEAREST_FILTER; + } } } break; @@ -832,6 +842,10 @@ pixman_image_set_accessors (pixman_image_t * image, if (image->type == BITS) { + /* Accessors only work for <= 32 bpp. */ + if (PIXMAN_FORMAT_BPP(image->bits.format) > 32) + return_if_fail (!read_func && !write_func); + image->bits.read_func = read_func; image->bits.write_func = write_func; diff --git a/lib/pixman/pixman/pixman-private.h b/lib/pixman/pixman/pixman-private.h index 73108a01d..73a54146d 100644 --- a/lib/pixman/pixman/pixman-private.h +++ b/lib/pixman/pixman/pixman-private.h @@ -1,5 +1,3 @@ -#include <float.h> - #ifndef PIXMAN_PRIVATE_H #define PIXMAN_PRIVATE_H @@ -30,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <stddef.h> +#include <float.h> #include "pixman-compiler.h" diff --git a/lib/pixman/pixman/pixman-solid-fill.c b/lib/pixman/pixman/pixman-solid-fill.c index 5f9fef630..4694ebc70 100644 --- a/lib/pixman/pixman/pixman-solid-fill.c +++ b/lib/pixman/pixman/pixman-solid-fill.c @@ -30,10 +30,10 @@ static uint32_t color_to_uint32 (const pixman_color_t *color) { return - (color->alpha >> 8 << 24) | - (color->red >> 8 << 16) | - (color->green & 0xff00) | - (color->blue >> 8); + ((unsigned int) color->alpha >> 8 << 24) | + ((unsigned int) color->red >> 8 << 16) | + ((unsigned int) color->green & 0xff00) | + ((unsigned int) color->blue >> 8); } static argb_t diff --git a/lib/pixman/pixman/pixman.c b/lib/pixman/pixman/pixman.c index f932eac3c..c09b52808 100644 --- a/lib/pixman/pixman/pixman.c +++ b/lib/pixman/pixman/pixman.c @@ -777,6 +777,11 @@ color_to_pixel (const pixman_color_t *color, { uint32_t c = color_to_uint32 (color); + if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA_FLOAT) + { + return FALSE; + } + if (!(format == PIXMAN_a8r8g8b8 || format == PIXMAN_x8r8g8b8 || format == PIXMAN_a8b8g8r8 || diff --git a/lib/pixman/pixman/pixman.h b/lib/pixman/pixman/pixman.h index 509ba5e53..d644589d6 100644 --- a/lib/pixman/pixman/pixman.h +++ b/lib/pixman/pixman/pixman.h @@ -654,12 +654,24 @@ struct pixman_indexed ((g) << 4) | \ ((b))) -#define PIXMAN_FORMAT_BPP(f) (((f) >> 24) ) -#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff) -#define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f) -#define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f) -#define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f) -#define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f) +#define PIXMAN_FORMAT_BYTE(bpp,type,a,r,g,b) \ + (((bpp >> 3) << 24) | \ + (3 << 22) | ((type) << 16) | \ + ((a >> 3) << 12) | \ + ((r >> 3) << 8) | \ + ((g >> 3) << 4) | \ + ((b >> 3))) + +#define PIXMAN_FORMAT_RESHIFT(val, ofs, num) \ + (((val >> (ofs)) & ((1 << (num)) - 1)) << ((val >> 22) & 3)) + +#define PIXMAN_FORMAT_BPP(f) PIXMAN_FORMAT_RESHIFT(f, 24, 8) +#define PIXMAN_FORMAT_SHIFT(f) ((uint32_t)((f >> 22) & 3)) +#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0x3f) +#define PIXMAN_FORMAT_A(f) PIXMAN_FORMAT_RESHIFT(f, 12, 4) +#define PIXMAN_FORMAT_R(f) PIXMAN_FORMAT_RESHIFT(f, 8, 4) +#define PIXMAN_FORMAT_G(f) PIXMAN_FORMAT_RESHIFT(f, 4, 4) +#define PIXMAN_FORMAT_B(f) PIXMAN_FORMAT_RESHIFT(f, 0, 4) #define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff) #define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff) #define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \ @@ -678,15 +690,22 @@ struct pixman_indexed #define PIXMAN_TYPE_BGRA 8 #define PIXMAN_TYPE_RGBA 9 #define PIXMAN_TYPE_ARGB_SRGB 10 +#define PIXMAN_TYPE_RGBA_FLOAT 11 #define PIXMAN_FORMAT_COLOR(f) \ (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \ PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA || \ - PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA) + PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA || \ + PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA_FLOAT) -/* 32bpp formats */ typedef enum { +/* 128bpp formats */ + PIXMAN_rgba_float = PIXMAN_FORMAT_BYTE(128,PIXMAN_TYPE_RGBA_FLOAT,32,32,32,32), +/* 96bpp formats */ + PIXMAN_rgb_float = PIXMAN_FORMAT_BYTE(96,PIXMAN_TYPE_RGBA_FLOAT,0,32,32,32), + +/* 32bpp formats */ PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8), PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8), PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8), diff --git a/lib/pixman/test-driver b/lib/pixman/test-driver index 8e575b017..b8521a482 100644 --- a/lib/pixman/test-driver +++ b/lib/pixman/test-driver @@ -1,9 +1,9 @@ #! /bin/sh # test-driver - basic testsuite driver script. -scriptversion=2013-07-13.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/lib/pixman/test/Makefile.in b/lib/pixman/test/Makefile.in index 1f72a0f48..65463f1c1 100644 --- a/lib/pixman/test/Makefile.in +++ b/lib/pixman/test/Makefile.in @@ -84,11 +84,11 @@ am__EXEEXT_1 = oob-test$(EXEEXT) infinite-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) \ + matrix-test$(EXEEXT) filter-reduction-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) \ @@ -173,6 +173,12 @@ fetch_test_LDADD = $(LDADD) fetch_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +filter_reduction_test_SOURCES = filter-reduction-test.c +filter_reduction_test_OBJECTS = filter-reduction-test.$(OBJEXT) +filter_reduction_test_LDADD = $(LDADD) +filter_reduction_test_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) glyph_test_SOURCES = glyph-test.c glyph_test_OBJECTS = glyph-test.$(OBJEXT) glyph_test_LDADD = $(LDADD) @@ -355,26 +361,26 @@ 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-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 + fetch-test.c filter-reduction-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-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-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 + fetch-test.c filter-reduction-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-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;; \ @@ -457,6 +463,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PIXMAN_GNUPLOT = @PIXMAN_GNUPLOT@ PIXMAN_TIMERS = @PIXMAN_TIMERS@ PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ @@ -558,6 +565,7 @@ TESTPROGRAMS = \ gradient-crash-test \ pixel-test \ matrix-test \ + filter-reduction-test \ composite-traps-test \ region-contains-test \ glyph-test \ @@ -695,6 +703,9 @@ fence-image-self-test$(EXEEXT): $(fence_image_self_test_OBJECTS) $(fence_image_s 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) +filter-reduction-test$(EXEEXT): $(filter_reduction_test_OBJECTS) $(filter_reduction_test_DEPENDENCIES) $(EXTRA_filter_reduction_test_DEPENDENCIES) + @rm -f filter-reduction-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(filter_reduction_test_OBJECTS) $(filter_reduction_test_LDADD) $(LIBS) glyph-test$(EXEEXT): $(glyph_test_OBJECTS) $(glyph_test_DEPENDENCIES) $(EXTRA_glyph_test_DEPENDENCIES) @rm -f glyph-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(glyph_test_OBJECTS) $(glyph_test_LDADD) $(LIBS) @@ -787,6 +798,7 @@ distclean-compile: @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)/filter-reduction-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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infinite-loop.Po@am__quote@ diff --git a/lib/pixman/test/Makefile.sources b/lib/pixman/test/Makefile.sources index 5d55e676a..0a5623165 100644 --- a/lib/pixman/test/Makefile.sources +++ b/lib/pixman/test/Makefile.sources @@ -21,6 +21,7 @@ TESTPROGRAMS = \ gradient-crash-test \ pixel-test \ matrix-test \ + filter-reduction-test \ composite-traps-test \ region-contains-test \ glyph-test \ diff --git a/lib/pixman/test/alphamap.c b/lib/pixman/test/alphamap.c index 4d09076fb..150d33eed 100644 --- a/lib/pixman/test/alphamap.c +++ b/lib/pixman/test/alphamap.c @@ -10,7 +10,8 @@ static const pixman_format_code_t formats[] = PIXMAN_a8r8g8b8, PIXMAN_a2r10g10b10, PIXMAN_a4r4g4b4, - PIXMAN_a8 + PIXMAN_a8, + PIXMAN_rgba_float, }; static const pixman_format_code_t alpha_formats[] = @@ -18,7 +19,8 @@ static const pixman_format_code_t alpha_formats[] = PIXMAN_null, PIXMAN_a8, PIXMAN_a2r10g10b10, - PIXMAN_a4r4g4b4 + PIXMAN_a4r4g4b4, + PIXMAN_rgba_float, }; static const int origins[] = @@ -41,7 +43,10 @@ make_image (pixman_format_code_t format) uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; pixman_image_t *image; - bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + if (format != PIXMAN_rgba_float) + bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + else + bits = (uint32_t *)make_random_floats (WIDTH * HEIGHT * bpp); image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); @@ -51,11 +56,11 @@ make_image (pixman_format_code_t format) return image; } -static uint8_t +static float get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) { uint8_t *bits; - uint8_t r; + uint32_t r; if (image->common.alpha_map) { @@ -69,7 +74,7 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) } else { - return 0; + return 0.f; } } @@ -78,28 +83,32 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) if (image->bits.format == PIXMAN_a8) { r = bits[y * WIDTH + x]; + return r / 255.f; } else if (image->bits.format == PIXMAN_a2r10g10b10) { r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; - r |= r << 2; - r |= r << 4; + return r / 3.f; } else if (image->bits.format == PIXMAN_a8r8g8b8) { r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; + return r / 255.f; } else if (image->bits.format == PIXMAN_a4r4g4b4) { r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; - r |= r << 4; + return r / 15.f; + } + else if (image->bits.format == PIXMAN_rgba_float) + { + return ((float *)bits)[y * WIDTH * 4 + x * 4 + 3]; } else { assert (0); + return 0.f; } - - return r; } static uint16_t @@ -133,6 +142,11 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) r |= r << 4; r |= r << 8; } + else if (image->bits.format == PIXMAN_rgba_float) + { + double tmp = ((float *)bits)[y * WIDTH * 4 + x * 4]; + return tmp * 65535.; + } else { assert (0); @@ -141,6 +155,23 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) return r; } +static float get_alpha_err(pixman_format_code_t sf, pixman_format_code_t saf, + pixman_format_code_t df, pixman_format_code_t daf) +{ + pixman_format_code_t s = saf != PIXMAN_null ? saf : sf; + pixman_format_code_t d = daf != PIXMAN_null ? daf : df; + + /* There are cases where we go through the 8 bit compositing + * path even with 10bpc and higher formats. + */ + if (PIXMAN_FORMAT_A(s) == PIXMAN_FORMAT_A(d)) + return 1.f / 255.f; + else if (PIXMAN_FORMAT_A(s) > PIXMAN_FORMAT_A(d)) + return 1.f / ((1 << PIXMAN_FORMAT_A(d)) - 1); + else + return 1.f / ((1 << PIXMAN_FORMAT_A(s)) - 1); +} + static int run_test (int s, int d, int sa, int da, int soff, int doff) { @@ -151,15 +182,11 @@ run_test (int s, int d, int sa, int da, int soff, int doff) pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha; pixman_transform_t t1; int j, k; - int n_alpha_bits, n_red_bits; + int n_red_bits; soff = origins[soff]; doff = origins[doff]; - n_alpha_bits = PIXMAN_FORMAT_A (df); - if (daf != PIXMAN_null) - n_alpha_bits = PIXMAN_FORMAT_A (daf); - n_red_bits = PIXMAN_FORMAT_R (df); /* Source */ @@ -211,21 +238,25 @@ run_test (int s, int d, int sa, int da, int soff, int doff) { for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) { - uint8_t sa, da, oda, refa; + float sa, da, oda, refa; uint16_t sr, dr, odr, refr; + float err; + + err = get_alpha_err(sf, saf, df, daf); sa = get_alpha (src, k, j, soff, soff); da = get_alpha (dst, k, j, doff, doff); oda = get_alpha (orig_dst, k, j, doff, doff); - if (sa + oda > 255) - refa = 255; + if (sa + oda > 1.f) + refa = 1.f; else refa = sa + oda; - if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits)) + if (da - err > refa || + da + err < refa) { - printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", + printf ("\nWrong alpha value at (%d, %d). Should be %g; got %g. Source was %g, original dest was %g\n", k, j, refa, da, sa, oda); printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", diff --git a/lib/pixman/test/filter-reduction-test.c b/lib/pixman/test/filter-reduction-test.c new file mode 100644 index 000000000..705fa4b09 --- /dev/null +++ b/lib/pixman/test/filter-reduction-test.c @@ -0,0 +1,112 @@ +#include <stdlib.h> +#include <stdio.h> +#include "utils.h" + +static const pixman_fixed_t entries[] = +{ + pixman_double_to_fixed (-1.0), + pixman_double_to_fixed (-0.5), + pixman_double_to_fixed (-1/3.0), + pixman_double_to_fixed (0.0), + pixman_double_to_fixed (0.5), + pixman_double_to_fixed (1.0), + pixman_double_to_fixed (1.5), + pixman_double_to_fixed (2.0), + pixman_double_to_fixed (3.0), +}; + +#define SIZE 12 + +static uint32_t +test_scale (const pixman_transform_t *xform, uint32_t crc) +{ + uint32_t *srcbuf, *dstbuf; + pixman_image_t *src, *dest; + + srcbuf = malloc (SIZE * SIZE * 4); + prng_randmemset (srcbuf, SIZE * SIZE * 4, 0); + src = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, SIZE, SIZE, srcbuf, SIZE * 4); + + dstbuf = malloc (SIZE * SIZE * 4); + prng_randmemset (dstbuf, SIZE * SIZE * 4, 0); + dest = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, SIZE, SIZE, dstbuf, SIZE * 4); + + pixman_image_set_transform (src, xform); + pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL); + pixman_image_set_filter (src, PIXMAN_FILTER_BILINEAR, NULL, 0); + + image_endian_swap (src); + image_endian_swap (dest); + + pixman_image_composite (PIXMAN_OP_SRC, + src, NULL, dest, + 0, 0, 0, 0, 0, 0, + SIZE, SIZE); + + crc = compute_crc32_for_image (crc, dest); + + pixman_image_unref (src); + pixman_image_unref (dest); + + free (srcbuf); + free (dstbuf); + + return crc; +} + +#if BILINEAR_INTERPOLATION_BITS == 7 +#define CHECKSUM 0x02169677 +#elif BILINEAR_INTERPOLATION_BITS == 4 +#define CHECKSUM 0xE44B29AC +#else +#define CHECKSUM 0x00000000 +#endif + +int +main (int argc, const char *argv[]) +{ + const pixman_fixed_t *end = entries + ARRAY_LENGTH (entries); + const pixman_fixed_t *t0, *t1, *t2, *t3, *t4, *t5; + uint32_t crc = 0; + + prng_srand (0x56EA1DBD); + + for (t0 = entries; t0 < end; ++t0) + { + for (t1 = entries; t1 < end; ++t1) + { + for (t2 = entries; t2 < end; ++t2) + { + for (t3 = entries; t3 < end; ++t3) + { + for (t4 = entries; t4 < end; ++t4) + { + for (t5 = entries; t5 < end; ++t5) + { + pixman_transform_t xform = { + { { *t0, *t1, *t2 }, + { *t3, *t4, *t5 }, + { 0, 0, pixman_fixed_1 } } + }; + + crc = test_scale (&xform, crc); + } + } + } + } + } + } + + if (crc != CHECKSUM) + { + printf ("filter-reduction-test failed! (checksum=0x%08X, expected 0x%08X)\n", crc, CHECKSUM); + return 1; + } + else + { + printf ("filter-reduction-test passed (checksum=0x%08X)\n", crc); + return 0; + } +} diff --git a/lib/pixman/test/stress-test.c b/lib/pixman/test/stress-test.c index 1f03c7543..6b4f7d606 100644 --- a/lib/pixman/test/stress-test.c +++ b/lib/pixman/test/stress-test.c @@ -11,6 +11,8 @@ static const pixman_format_code_t image_formats[] = { + PIXMAN_rgba_float, + PIXMAN_rgb_float, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_r5g6b5, @@ -100,6 +102,14 @@ get_size (void) } } +static uint32_t +real_reader (const void *src, int size); + +static void *xor_ptr(const void *ptr) +{ + return (void *)(((intptr_t)ptr) ^ (intptr_t)0x8000000080000000); +} + static void destroy (pixman_image_t *image, void *data) { @@ -114,6 +124,9 @@ destroy (pixman_image_t *image, void *data) if (image->bits.rowstride < 0) bits -= (- image->bits.rowstride * (image->bits.height - 1)); + if (image->bits.read_func == real_reader) + bits = xor_ptr(bits); + fence_free (bits); } } @@ -124,6 +137,7 @@ destroy (pixman_image_t *image, void *data) static uint32_t real_reader (const void *src, int size) { + src = xor_ptr(src); switch (size) { case 1: @@ -141,6 +155,7 @@ real_reader (const void *src, int size) static void real_writer (void *src, uint32_t value, int size) { + src = xor_ptr(src); switch (size) { case 1: @@ -247,9 +262,20 @@ create_random_bits_image (alpha_preference_t alpha_preference) pixman_filter_t filter; pixman_fixed_t *coefficients = NULL; int n_coefficients = 0; + int align_add, align_mask; /* format */ format = random_format (alpha_preference); + switch (PIXMAN_FORMAT_BPP (format)) { + case 128: + align_mask = 15; + align_add = align_mask + prng_rand_n (65); + break; + default: + align_mask = 3; + align_add = align_mask + prng_rand_n (17); + break; + } indexed = NULL; if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) @@ -291,9 +317,12 @@ create_random_bits_image (alpha_preference_t alpha_preference) { default: case 0: - stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); - stride = (stride + 3) & (~3); - bits = (uint32_t *)make_random_bytes (height * stride); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); + if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float) + bits = (uint32_t *)make_random_floats (height * stride); + else + bits = (uint32_t *)make_random_bytes (height * stride); break; case 1: @@ -302,8 +331,8 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 2: /* Zero-filled */ - stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; @@ -311,8 +340,8 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 3: /* Filled with 0xFF */ - stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; @@ -320,27 +349,35 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 4: /* bits is a bad pointer, has read/write functions */ - stride = 232; - bits = (void *)0x01; - read_func = fake_reader; - write_func = fake_writer; - break; + if (PIXMAN_FORMAT_BPP (format) <= 32) { + stride = 232; + bits = (void *)0x01; + read_func = fake_reader; + write_func = fake_writer; + break; + } case 5: /* bits is a real pointer, has read/write functions */ - stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; memset (bits, 0xff, height * stride); - read_func = real_reader; - write_func = real_writer; + if (PIXMAN_FORMAT_BPP (format) <= 32) { + bits = xor_ptr(bits); + read_func = real_reader; + write_func = real_writer; + } break; case 6: /* bits is a real pointer, stride is negative */ - stride = (width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17)); - stride = (stride + 3) & (~3); - bits = (uint32_t *)make_random_bytes (height * stride); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); + if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float) + bits = (uint32_t *)make_random_floats (height * stride); + else + bits = (uint32_t *)make_random_bytes (height * stride); if (!bits) return NULL; bits += ((height - 1) * stride) / 4; diff --git a/lib/pixman/test/utils-prng.c b/lib/pixman/test/utils-prng.c index c27b5be83..0cf53dde2 100644 --- a/lib/pixman/test/utils-prng.c +++ b/lib/pixman/test/utils-prng.c @@ -199,12 +199,25 @@ randmemset_internal (prng_t *prng, } else { + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + #ifdef HAVE_GCC_VECTOR_EXTENSIONS - const uint8x16 bswap_shufflemask = +# if __has_builtin(__builtin_shufflevector) + randdata.vb = + __builtin_shufflevector (randdata.vb, randdata.vb, + 3, 2, 1, 0, 7, 6 , 5, 4, + 11, 10, 9, 8, 15, 14, 13, 12); +# else + static const uint8x16 bswap_shufflemask = { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }; randdata.vb = __builtin_shuffle (randdata.vb, bswap_shufflemask); +# endif + store_rand_128_data (buf, &randdata, aligned); buf += 16; #else diff --git a/lib/pixman/test/utils.c b/lib/pixman/test/utils.c index f8e42a5d3..4eeb06849 100644 --- a/lib/pixman/test/utils.c +++ b/lib/pixman/test/utils.c @@ -595,6 +595,21 @@ make_random_bytes (int n_bytes) return bytes; } +float * +make_random_floats (int n_bytes) +{ + uint8_t *bytes = fence_malloc (n_bytes); + float *vals = (float *)bytes; + + if (!bytes) + return 0; + + for (n_bytes /= 4; n_bytes; vals++, n_bytes--) + *vals = (float)rand() / (float)RAND_MAX; + + return (float *)bytes; +} + void a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels) { @@ -1180,6 +1195,11 @@ static const format_entry_t format_list[] = * Aliases are not listed by list_formats (). */ +/* 128bpp formats */ + ENTRY (rgba_float), +/* 96bpp formats */ + ENTRY (rgb_float), + /* 32bpp formats */ ENTRY (a8r8g8b8), ALIAS (a8r8g8b8, "8888"), @@ -1914,6 +1934,10 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) checker->format = format; + if (format == PIXMAN_rgba_float || + format == PIXMAN_rgb_float) + return; + switch (PIXMAN_FORMAT_TYPE (format)) { case PIXMAN_TYPE_A: @@ -1970,10 +1994,19 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) checker->bw = PIXMAN_FORMAT_B (format); } +static void +pixel_checker_require_uint32_format (const pixel_checker_t *checker) +{ + assert (checker->format != PIXMAN_rgba_float && + checker->format != PIXMAN_rgb_float); +} + void pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel, int *a, int *r, int *g, int *b) { + pixel_checker_require_uint32_format(checker); + *a = (pixel & checker->am) >> checker->as; *r = (pixel & checker->rm) >> checker->rs; *g = (pixel & checker->gm) >> checker->gs; @@ -1987,6 +2020,8 @@ pixel_checker_get_masks (const pixel_checker_t *checker, uint32_t *gm, uint32_t *bm) { + pixel_checker_require_uint32_format(checker); + if (am) *am = checker->am; if (rm) @@ -2003,6 +2038,8 @@ pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker, { int a, r, g, b; + pixel_checker_require_uint32_format(checker); + pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b); if (checker->am == 0) @@ -2078,6 +2115,8 @@ void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, int *am, int *rm, int *gm, int *bm) { + pixel_checker_require_uint32_format(checker); + get_limits (checker, DEVIATION, color, am, rm, gm, bm); } @@ -2085,6 +2124,8 @@ void pixel_checker_get_min (const pixel_checker_t *checker, color_t *color, int *am, int *rm, int *gm, int *bm) { + pixel_checker_require_uint32_format(checker); + get_limits (checker, - DEVIATION, color, am, rm, gm, bm); } @@ -2096,6 +2137,8 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel, int32_t ai, ri, gi, bi; pixman_bool_t result; + pixel_checker_require_uint32_format(checker); + pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo); pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi); pixel_checker_split_pixel (checker, pixel, &ai, &ri, &gi, &bi); @@ -2108,3 +2151,36 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel, return result; } + +static void +color_limits (const pixel_checker_t *checker, + double limit, const color_t *color, color_t *out) +{ + if (PIXMAN_FORMAT_A(checker->format)) + out->a = color->a + limit; + else + out->a = 1.; + + out->r = color->r + limit; + out->g = color->g + limit; + out->b = color->b + limit; +} + +pixman_bool_t +pixel_checker_check_color (const pixel_checker_t *checker, + const color_t *actual, const color_t *reference) +{ + color_t min, max; + pixman_bool_t result; + + color_limits(checker, -DEVIATION, reference, &min); + color_limits(checker, DEVIATION, reference, &max); + + result = + actual->a >= min.a && actual->a <= max.a && + actual->r >= min.r && actual->r <= max.r && + actual->g >= min.g && actual->g <= max.g && + actual->b >= min.b && actual->b <= max.b; + + return result; +} diff --git a/lib/pixman/test/utils.h b/lib/pixman/test/utils.h index e299d1d06..e5ac945ab 100644 --- a/lib/pixman/test/utils.h +++ b/lib/pixman/test/utils.h @@ -119,6 +119,8 @@ fence_get_page_size (); /* Generate n_bytes random bytes in fence_malloced memory */ uint8_t * make_random_bytes (int n_bytes); +float * +make_random_floats (int n_bytes); /* Return current time in seconds */ double |