diff --git a/lib/pixman/Makefile.am b/lib/pixman/Makefile.am index c5ebe16b5..0bf8206c0 100644 --- a/lib/pixman/Makefile.am +++ b/lib/pixman/Makefile.am @@ -15,15 +15,20 @@ USERNAME=$$USER RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi) RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s -RELEASE_CAIRO_URL = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s -RELEASE_XORG_URL = http://xorg.freedesktop.org/archive/individual/lib +RELEASE_CAIRO_URL = https://cairographics.org/$(RELEASE_OR_SNAPSHOT)s +RELEASE_XORG_URL = https://www.x.org/releases/individual/lib RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org EXTRA_DIST = \ Makefile.win32 \ - Makefile.win32.common + Makefile.win32.common \ + meson.build \ + meson_options.txt \ + neon-test.S \ + arm-simd-test.S \ + $(NULL) tar_gz = $(PACKAGE)-$(VERSION).tar.gz tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 diff --git a/lib/pixman/Makefile.bsd-wrapper b/lib/pixman/Makefile.bsd-wrapper index 2ee795d89..77ade5fee 100644 --- a/lib/pixman/Makefile.bsd-wrapper +++ b/lib/pixman/Makefile.bsd-wrapper @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.24 2019/01/18 14:34:01 matthieu Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.25 2019/05/11 07:46:06 matthieu Exp $ .include -SHARED_LIBS= pixman-1 36.0 +SHARED_LIBS= pixman-1 38.4 .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 b090c784d..3e619b1c2 100644 --- a/lib/pixman/Makefile.in +++ b/lib/pixman/Makefile.in @@ -329,14 +329,19 @@ USERNAME = $$USER RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi) RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s -RELEASE_CAIRO_URL = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s -RELEASE_XORG_URL = http://xorg.freedesktop.org/archive/individual/lib +RELEASE_CAIRO_URL = https://cairographics.org/$(RELEASE_OR_SNAPSHOT)s +RELEASE_XORG_URL = https://www.x.org/releases/individual/lib RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org EXTRA_DIST = \ Makefile.win32 \ - Makefile.win32.common + Makefile.win32.common \ + meson.build \ + meson_options.txt \ + neon-test.S \ + arm-simd-test.S \ + $(NULL) tar_gz = $(PACKAGE)-$(VERSION).tar.gz tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 diff --git a/lib/pixman/aclocal.m4 b/lib/pixman/aclocal.m4 index 30eedaeef..09f4aa5dc 100644 --- a/lib/pixman/aclocal.m4 +++ b/lib/pixman/aclocal.m4 @@ -8606,32 +8606,63 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 1 (pkg-config-0.24) -# -# Copyright © 2004 Scott James Remnant . -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) @@ -8653,18 +8684,19 @@ if test -n "$PKG_CONFIG"; then PKG_CONFIG="" fi fi[]dnl -])# PKG_PROG_PKG_CONFIG +])dnl PKG_PROG_PKG_CONFIG -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ @@ -8674,8 +8706,10 @@ m4_ifvaln([$3], [else $3])dnl fi]) -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" @@ -8687,10 +8721,11 @@ m4_define([_PKG_CONFIG], else pkg_failed=untried fi[]dnl -])# _PKG_CONFIG +])dnl _PKG_CONFIG -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -8698,19 +8733,17 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then else _pkg_short_errors_supported=no fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED +])dnl _PKG_SHORT_ERRORS_SUPPORTED -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl @@ -8764,16 +8797,40 @@ else AC_MSG_RESULT([yes]) $3 fi[]dnl -])# PKG_CHECK_MODULES +])dnl PKG_CHECK_MODULES -# PKG_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable pkgconfigdir as the location where a module -# should install pkg-config .pc files. By default the directory is -# $libdir/pkgconfig, but the default can be changed by passing -# DIRECTORY. The user can override through the --with-pkgconfigdir -# parameter. +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -8784,16 +8841,18 @@ AC_ARG_WITH([pkgconfigdir], AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_INSTALLDIR +])dnl PKG_INSTALLDIR -# PKG_NOARCH_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable noarch_pkgconfigdir as the location where a -# module should install arch-independent pkg-config .pc files. By -# default the directory is $datadir/pkgconfig, but the default can be -# changed by passing DIRECTORY. The user can override through the -# --with-noarch-pkgconfigdir parameter. +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -8804,7 +8863,24 @@ AC_ARG_WITH([noarch-pkgconfigdir], AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_NOARCH_INSTALLDIR +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR # Copyright (C) 2002-2012 Free Software Foundation, Inc. # diff --git a/lib/pixman/arm-simd-test.S b/lib/pixman/arm-simd-test.S new file mode 100644 index 000000000..910c814d6 --- /dev/null +++ b/lib/pixman/arm-simd-test.S @@ -0,0 +1,10 @@ +.text +.arch armv6 +.object_arch armv4 +.arm +.altmacro +#ifndef __ARM_EABI__ +#error EABI is required (to be sure that calling conventions are compatible) +#endif +pld [r0] +uqadd8 r0, r0, r0 diff --git a/lib/pixman/configure b/lib/pixman/configure index e2480111c..8d2533b20 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.36.0. +# Generated by GNU Autoconf 2.69 for pixman 0.38.4. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pixman' PACKAGE_TARNAME='pixman' -PACKAGE_VERSION='0.36.0' -PACKAGE_STRING='pixman 0.36.0' +PACKAGE_VERSION='0.38.4' +PACKAGE_STRING='pixman 0.38.4' PACKAGE_BUGREPORT='pixman@lists.freedesktop.org' PACKAGE_URL='' @@ -1396,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.36.0 to adapt to many kinds of systems. +\`configure' configures pixman 0.38.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1466,7 +1466,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pixman 0.36.0:";; + short | recursive ) echo "Configuration of pixman 0.38.4:";; esac cat <<\_ACEOF @@ -1606,7 +1606,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pixman configure 0.36.0 +pixman configure 0.38.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2204,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.36.0, which was +It was created by pixman $as_me 0.38.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3028,7 +3028,7 @@ fi # Define the identity of the package. PACKAGE='pixman' - VERSION='0.36.0' + VERSION='0.38.4' cat >>confdefs.h <<_ACEOF @@ -12236,13 +12236,13 @@ fi -LT_VERSION_INFO="36:0:36" +LT_VERSION_INFO="38:4:38" PIXMAN_VERSION_MAJOR=0 -PIXMAN_VERSION_MINOR=36 +PIXMAN_VERSION_MINOR=38 -PIXMAN_VERSION_MICRO=0 +PIXMAN_VERSION_MICRO=4 @@ -15309,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.36.0, which was +This file was extended by pixman $as_me 0.38.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15375,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.36.0 +pixman config.status 0.38.4 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 63a7238dc..9a451c5dd 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], 36) -m4_define([pixman_micro], 0) +m4_define([pixman_minor], 38) +m4_define([pixman_micro], 4) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) diff --git a/lib/pixman/demos/Makefile.am b/lib/pixman/demos/Makefile.am index e04743d7f..44a555304 100644 --- a/lib/pixman/demos/Makefile.am +++ b/lib/pixman/demos/Makefile.am @@ -1,4 +1,9 @@ -EXTRA_DIST = parrot.c parrot.jpg scale.ui +EXTRA_DIST = \ + parrot.c \ + parrot.jpg \ + scale.ui \ + meson.build \ + $(NULL) if HAVE_GTK diff --git a/lib/pixman/demos/Makefile.in b/lib/pixman/demos/Makefile.in index 3d76a82af..836ac2e33 100644 --- a/lib/pixman/demos/Makefile.in +++ b/lib/pixman/demos/Makefile.in @@ -453,7 +453,13 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = parrot.c parrot.jpg scale.ui +EXTRA_DIST = \ + parrot.c \ + parrot.jpg \ + scale.ui \ + meson.build \ + $(NULL) + @HAVE_GTK_TRUE@AM_CFLAGS = $(OPENMP_CFLAGS) @HAVE_GTK_TRUE@AM_LDFLAGS = $(OPENMP_CFLAGS) @HAVE_GTK_TRUE@LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS) diff --git a/lib/pixman/demos/meson.build b/lib/pixman/demos/meson.build new file mode 100644 index 000000000..3461f795d --- /dev/null +++ b/lib/pixman/demos/meson.build @@ -0,0 +1,59 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +demos = [ + 'gradient-test', + 'alpha-test', + 'composite-test', + 'clip-test', + 'trap-test', + 'screen-test', + 'convolution-test', + 'radial-test', + 'linear-gradient', + 'conical-test', + 'tri-test', + 'checkerboard', + 'srgb-test', + 'srgb-trap-test', + 'scale', +] + +if dep_gtk.found() + + libdemo = static_library( + 'demo', + ['gtk-utils.c', config_h, version_h], + dependencies : [dep_gtk, dep_glib, dep_png, dep_m, dep_openmp], + include_directories : inc_pixman, + ) + + if dep_gtk.found() + foreach d : demos + executable( + d, + [d + '.c', config_h, version_h], + link_with : [libdemo, libtestutils], + dependencies : [dep_glib, dep_gtk, dep_openmp, idep_pixman], + ) + endforeach + endif + +endif diff --git a/lib/pixman/meson.build b/lib/pixman/meson.build new file mode 100644 index 000000000..fad22eea9 --- /dev/null +++ b/lib/pixman/meson.build @@ -0,0 +1,471 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +project( + 'pixman', + ['c'], + version : '0.38.4', + license : 'MIT', + meson_version : '>= 0.47.2', + default_options : ['buildtype=debugoptimized'], +) + +config = configuration_data() +cc = meson.get_compiler('c') +null_dep = dependency('', required : false) + +add_project_arguments( + cc.get_supported_arguments([ + '-Wdeclaration-after-statement', + '-fno-strict-aliasing', + '-fvisibility=hidden', + ]), + language : ['c'] +) + +# GCC and Clang both ignore -Wno options that they don't recognize, so test for +# -W, then add -Wno- if it's ignored +foreach opt : ['unused-local-typedefs'] + if cc.has_argument('-W' + opt) + add_project_arguments(['-Wno-' + opt], language : ['c']) + endif +endforeach + +use_loongson_mmi = get_option('loongson-mmi') +have_loongson_mmi = false +loongson_mmi_flags = ['-march=loongson2f'] +if not use_loongson_mmi.disabled() + if host_machine.cpu_family() == 'mips64' and cc.compiles(''' + #ifndef __mips_loongson_vector_rev + #error "Loongson Multimedia Instructions are only available on Loongson" + #endif + #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + #error "Need GCC >= 4.4 for Loongson MMI compilation" + #endif + #include "pixman/loongson-mmintrin.h" + int main () { + union { + __m64 v; + char c[8]; + } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} }; + int b = 4; + __m64 c = _mm_srli_pi16 (a.v, b); + return 0; + }''', + args : loongson_mmi_flags, + include_directories : include_directories('.'), + name : 'Loongson MMI Intrinsic Support') + have_loongson_mmi = true + endif +endif + +if have_loongson_mmi + config.set10('USE_LOONGSON_MMI', true) +elif use_loongson_mmi.enabled() + error('Loongson MMI Support unavailable, but required') +endif + +use_mmx = get_option('mmx') +have_mmx = false +mmx_flags = ['-mmmx', '-Winline'] +if not use_mmx.disabled() + if host_machine.cpu_family() == 'x86_64' + have_mmx = true + elif host_machine.cpu_family() == 'x86' and cc.compiles(''' + #include + #include + + /* 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; + + w = _mm_shuffle_pi16(v, 5); + + /* Some versions of clang will choke on this */ + asm ("pmulhuw %1, %0\n\t" + : "+y" (w) + : "y" (v) + ); + + return _mm_cvtsi64_si32 (v); + }''', + args : mmx_flags, + name : 'MMX Intrinsic Support') + have_mmx = true + endif +endif + +if have_mmx + config.set10('USE_X86_MMX', true) +elif use_mmx.enabled() + error('MMX Support unavailable, but required') +endif + +use_sse2 = get_option('sse2') +have_sse2 = false +sse2_flags = ['-msse2', '-Winline'] +if not use_sse2.disabled() + if host_machine.cpu_family() == 'x86' + if cc.compiles(''' + #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) + # if !defined(__amd64__) && !defined(__x86_64__) + # error "Need GCC >= 4.2 for SSE2 intrinsics on x86" + # endif + #endif + #include + #include + #include + int param; + int main () { + __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c; + c = _mm_xor_si128 (a, b); + return _mm_cvtsi128_si32(c); + }''', + args : sse2_flags, + name : 'SSE2 Intrinsic Support') + have_sse2 = true + endif + elif host_machine.cpu_family() == 'x86_64' + have_sse2 = true + endif +endif + +if have_sse2 + config.set10('USE_SSE2', true) +elif use_sse2.enabled() + error('sse2 Support unavailable, but required') +endif + +use_ssse3 = get_option('ssse3') +have_ssse3 = false +ssse3_flags =['-mssse3', '-Winline'] +if not use_ssse3.disabled() + if host_machine.cpu_family().startswith('x86') + if cc.compiles(''' + #include + #include + #include + int param; + int main () { + __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c; + c = _mm_xor_si128 (a, b); + return _mm_cvtsi128_si32(c); + }''', + args : ssse3_flags, + name : 'SSSE3 Intrinsic Support') + have_ssse3 = true + endif + endif +endif + +if have_ssse3 + config.set10('USE_SSSE3', true) +elif use_ssse3.enabled() + error('ssse3 Support unavailable, but required') +endif + +use_vmx = get_option('vmx') +have_vmx = false +vmx_flags = ['-maltivec', '-mabi=altivec'] +if not use_vmx.disabled() + if host_machine.cpu_family().startswith('ppc') + if cc.compiles(''' + #include + int main () { + vector unsigned int v = vec_splat_u32 (1); + v = vec_sub (v, v); + return 0; + }''', + args : vmx_flags, + name : 'VMX/Altivec Intrinsic Support') + have_vmx = true + endif + endif +endif + +if have_vmx + config.set10('USE_VMX', true) +elif use_vmx.enabled() + error('vmx Support unavailable, but required') +endif + +use_armv6_simd = get_option('arm-simd') +have_armv6_simd = false +if not use_armv6_simd.disabled() + if host_machine.cpu_family() == 'arm' + if cc.compiles(files('arm-simd-test.S'), name : 'ARMv6 SIMD Intrinsic Support') + have_armv6_simd = true + endif + endif +endif + +if have_armv6_simd + config.set10('USE_ARM_SIMD', true) +elif use_armv6_simd.enabled() + error('ARMv6 SIMD Support unavailable, but required') +endif + +use_neon = get_option('neon') +have_neon = false +if not use_neon.disabled() + if host_machine.cpu_family() == 'arm' + if cc.compiles(files('neon-test.S'), name : 'NEON Intrinsic Support') + have_neon = true + endif + endif +endif + +if have_neon + config.set10('USE_ARM_NEON', true) +elif use_neon.enabled() + error('NEON Support unavailable, but required') +endif + +use_iwmmxt = get_option('iwmmxt') +have_iwmmxt = false +iwmmxt_flags = ['-flax-vector-conversions', '-Winline'] +if not use_iwmmxt.disabled() + if get_option('iwmmxt2') + iwmmxt_flags += '-march=iwmmxt2' + else + iwmmxt_flags += '-march=iwmmxt' + endif + + if host_machine.cpu_family() == 'arm' + if cc.compiles(''' + #ifndef __IWMMXT__ + #error "IWMMXT not enabled (with -march=iwmmxt)" + #endif + #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) + #error "Need GCC >= 4.8 for IWMMXT intrinsics" + #endif + #include + int main () { + union { + __m64 v; + char c[8]; + } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} }; + int b = 4; + __m64 c = _mm_srli_si64 (a.v, b); + } + ''', + args : iwmmxt_flags, + name : 'IWMMXT Intrinsic Support') + have_iwmmxt = true + endif + endif +endif + +if have_iwmmxt + config.set10('USE_ARM_IWMMXT', true) +elif use_iwmmxt.enabled() + error('IWMMXT Support unavailable, but required') +endif + +use_mips_dspr2 = get_option('mips-dspr2') +have_mips_dspr2 = false +mips_dspr2_flags = ['-mdspr2'] +if not use_mips_dspr2.disabled() + if host_machine.cpu_family() == 'mips32' + if cc.compiles(''' + #if !(defined(__mips__) && __mips_isa_rev >= 2) + #error MIPS DSPr2 is currently only available on MIPS32r2 platforms. + #endif + int + main () + { + int c = 0, a = 0, b = 0; + __asm__ __volatile__ ( + "precr.qb.ph %[c], %[a], %[b] \n\t" + : [c] "=r" (c) + : [a] "r" (a), [b] "r" (b) + ); + return c; + }''', + args : mipds_dspr2_flags, + name : 'DSPr2 Intrinsic Support') + have_mips_dspr2 = true + endif + endif +endif + +if have_mips_dspr2 + config.set10('USE_MIPS_DSPR2', true) +elif use_mips_dspr2.enabled() + error('MIPS DSPr2 Support unavailable, but required') +endif + +use_gnu_asm = get_option('gnu-inline-asm') +if not use_gnu_asm.disabled() + if cc.compiles(''' + int main () { + /* Most modern architectures have a NOP instruction, so this is a fairly generic test. */ + asm volatile ( "\tnop\n" : : : "cc", "memory" ); + return 0; + } + ''', + name : 'GNU Inline ASM support.') + config.set10('USE_GCC_INLINE_ASM', true) + elif use_gnu_asm.enabled() + error('GNU inline assembly support missing but required.') + endif +endif + +if get_option('timers') + config.set('PIXMAN_TIMERS', 1) +endif +if get_option('gnuplot') + config.set('PIXMAN_GNUPLOT', 1) +endif + +dep_openmp = dependency('openmp', required : get_option('openmp')) +if dep_openmp.found() + config.set10('USE_OPENMP', true) +elif meson.version().version_compare('<0.51.0') +# In versions of meson before 0.51 the openmp dependency can still +# inject arguments in the the auto case when it is not found, the +# detection does work correctly in that case however, so we just +# replace dep_openmp with null_dep to work around this. + dep_openmp = null_dep +endif + +dep_gtk = dependency('gtk+-2.0', version : '>= 2.16', required : get_option('gtk')) +dep_glib = dependency('glib-2.0', required : get_option('gtk')) +dep_pixman = dependency('pixman-1', required : get_option('gtk'), + version : '>= ' + meson.project_version()) +dep_png = dependency('libpng', required : get_option('libpng')) +if dep_png.found() + config.set('HAVE_LIBPNG', 1) +endif +dep_m = cc.find_library('m', required : false) +dep_threads = dependency('threads') +if dep_threads.found() + config.set('HAVE_PTHREADS', 1) +endif + +funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap'] +# mingw claimes to have posix_memalign, but it doesn't +if host_machine.system() != 'windows' + funcs += 'posix_memalign' +endif + +foreach f : funcs + if cc.has_function(f) + config.set('HAVE_@0@'.format(f.to_upper()), 1) + endif +endforeach + +if cc.has_function('gettimeofday') + config.set('HAVE_GETTIMEOFDAY', 1) +endif + +# This is only used in one test, that defines _GNU_SOURCE +if cc.has_function('feenableexcept', + prefix : '#define _GNU_SOURCE\n#include ', + dependencies : dep_m) + config.set('HAVE_FEENABLEEXCEPT', 1) +endif + +if cc.has_header_symbol('fenv.h', 'FE_DIVBYZERO') + config.set('HAVE_FEDIVBYZERO', 1) +endif + +foreach h : ['sys/mman.h', 'fenv.h', 'unistd.h'] + if cc.check_header(h) + config.set('HAVE_@0@'.format(h.underscorify().to_upper()), 1) + endif +endforeach + +if (host_machine.system() == 'windows' and + cc.compiles('int __declspec(thread) foo;', name : 'TLS via __declspec(thread)')) + config.set('TLS', '__declspec(thread)') +elif cc.compiles('int __thread foo;', name : 'TLS via __thread') + config.set('TLS', '__thread') +endif + +if cc.links(''' + static int x = 1; + static void __attribute__((constructor)) constructor_function () { x = 0; } + int main (void) { return x; } + ''', + name : '__attribute__((constructor))') + config.set('TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR', 1) +endif + +if cc.links( + ' __float128 a = 1.0Q, b = 2.0Q; int main (void) { return a + b; }', + name : 'Has float128 support') + config.set('HAVE_FLOAT128', 1) +endif + +if cc.has_function('clz') + config.set('HAVE_BUILTIN_CLZ', 1) +endif + +if cc.links(''' + unsigned int __attribute__ ((vector_size(16))) e, a, b; + int main (void) { e = a - ((b << 27) + (b >> (32 - 27))) + 1; return e[0]; } + ''', + name : 'Support for GCC vector extensions') + config.set('HAVE_GCC_VECTOR_EXTENSIONS', 1) +endif + +if host_machine.endian() == 'big' + config.set('WORDS_BIGENDIAN', 1) +endif + +# Required to make pixman-private.h +config.set('PACKAGE', 'foo') + +version_conf = configuration_data() +split = meson.project_version().split('.') +version_conf.set('PIXMAN_VERSION_MAJOR', split[0]) +version_conf.set('PIXMAN_VERSION_MINOR', split[1]) +version_conf.set('PIXMAN_VERSION_MICRO', split[2]) + +add_project_arguments('-DHAVE_CONFIG_H', language : ['c']) + +subdir('pixman') +subdir('test') +subdir('demos') + +pkg = import('pkgconfig') +pkg.generate( + name : 'Pixman', + filebase : 'pixman-1', + description : 'The pixman library (version 1)', + libraries : libpixman, + subdirs: 'pixman-1', + version : meson.project_version(), +) diff --git a/lib/pixman/meson_options.txt b/lib/pixman/meson_options.txt new file mode 100644 index 000000000..79ff4a3af --- /dev/null +++ b/lib/pixman/meson_options.txt @@ -0,0 +1,103 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option( + 'loongson-mmi', + type : 'feature', + description : 'Use Loongson MMI intrinsic optimized paths', +) +option( + 'mmx', + type : 'feature', + description : 'Use X86 MMX intrinsic optimized paths', +) +option( + 'sse2', + type : 'feature', + description : 'Use X86 SSE2 intrinsic optimized paths', +) +option( + 'ssse3', + type : 'feature', + description : 'Use X86 SSSE3 intrinsic optimized paths', +) +option( + 'vmx', + type : 'feature', + description : 'Use PPC VMX/Altivec intrinsic optimized paths', +) +option( + 'arm-simd', + type : 'feature', + description : 'Use ARMv6 SIMD intrinsic optimized paths', +) +option( + 'neon', + type : 'feature', + description : 'Use ARM NEON intrinsic optimized paths', +) +option( + 'iwmmxt', + type : 'feature', + description : 'Use ARM IWMMXT intrinsic optimized paths', +) +option( + 'iwmmxt2', + type : 'boolean', + value : true, + description : 'Use ARM IWMMXT2 intrinsic instead of IWMMXT', +) +option( + 'mips-dspr2', + type : 'feature', + description : 'Use MIPS32 DSPr2 intrinsic optimized paths', +) +option( + 'gnu-inline-asm', + type : 'feature', + description : 'Use GNU style inline assembler', +) +option( + 'openmp', + type : 'feature', + description : 'Enable openmp support', +) +option( + 'timers', + type : 'boolean', + value : false, + description : 'Enable TIMER_* macros', +) +option( + 'gnuplot', + type : 'boolean', + value : false, + description : 'Enable output of filters that can be piped to gnuplot', +) +option( + 'gtk', + type : 'feature', + description : 'Enable tests using GTK', +) +option( + 'libpng', + type : 'feature', + description : 'Use libpng' +) diff --git a/lib/pixman/neon-test.S b/lib/pixman/neon-test.S new file mode 100644 index 000000000..c30a3990b --- /dev/null +++ b/lib/pixman/neon-test.S @@ -0,0 +1,12 @@ +.text +.fpu neon +.arch armv7a +.object_arch armv4 +.eabi_attribute 10, 0 +.arm +.altmacro +#ifndef __ARM_EABI__ +#error EABI is required (to be sure that calling conventions are compatible) +#endif +pld [r0] +vmovn.u16 d0, q0 diff --git a/lib/pixman/pixman/Makefile.am b/lib/pixman/pixman/Makefile.am index 581b6f61e..3de26153e 100644 --- a/lib/pixman/pixman/Makefile.am +++ b/lib/pixman/pixman/Makefile.am @@ -14,6 +14,7 @@ EXTRA_DIST = \ Makefile.win32 \ pixman-region.c \ solaris-hwcap.mapfile \ + meson.build \ $(NULL) # mmx code diff --git a/lib/pixman/pixman/Makefile.in b/lib/pixman/pixman/Makefile.in index f46887286..48e3b5c79 100644 --- a/lib/pixman/pixman/Makefile.in +++ b/lib/pixman/pixman/Makefile.in @@ -523,6 +523,7 @@ EXTRA_DIST = \ Makefile.win32 \ pixman-region.c \ solaris-hwcap.mapfile \ + meson.build \ $(NULL) @USE_X86_MMX_TRUE@libpixman_mmx_la_SOURCES = \ diff --git a/lib/pixman/pixman/meson.build b/lib/pixman/pixman/meson.build new file mode 100644 index 000000000..6ce87e7ad --- /dev/null +++ b/lib/pixman/pixman/meson.build @@ -0,0 +1,116 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +config_h = configure_file( + configuration : config, + output : 'config.h' +) + +version_h = configure_file( + configuration : version_conf, + input : 'pixman-version.h.in', + output : 'pixman-version.h', + install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'pixman-1') +) + +pixman_simd_libs = [] +simds = [ + # the mmx library can be compiled with mmx on x86/x86_64, iwmmxt on + # some arm cores, or loongson mmi on loongson mips systems. The + # libraries will all have the same name, "pixman-mmx", but there is + # no chance of more than one version being built in the same build + # because no system could have mmx, iwmmxt, and mmi, and it + # simplifies the build logic to give them the same name. + ['mmx', have_mmx, mmx_flags, []], + ['mmx', have_loongson_mmi, loongson_mmi_flags, []], + ['mmx', have_iwmmxt, iwmmxt_flags, []], + + ['sse2', have_sse2, sse2_flags, []], + ['ssse3', have_ssse3, ssse3_flags, []], + ['vmx', have_vmx, vmx_flags, []], + ['arm-simd', have_armv6_simd, [], + ['pixman-arm-simd-asm.S', 'pixman-arm-simd-asm-scaled.S']], + ['arm-neon', have_neon, [], + ['pixman-arm-neon-asm.S', 'pixman-arm-neon-asm-bilinear.S']], + ['mips-dspr2', have_mips_dspr2, mips_dspr2_flags, + ['pixman-mips-dspr2-asm.S', 'pixman-mips-memcpy-asm.S']], +] + +foreach simd : simds + if simd[1] + name = 'pixman-' + simd[0] + pixman_simd_libs += static_library( + name, + [name + '.c', config_h, version_h, simd[3]], + c_args : simd[2] + ) + endif +endforeach + +pixman_files = files( + 'pixman.c', + 'pixman-access.c', + 'pixman-access-accessors.c', + 'pixman-bits-image.c', + 'pixman-combine32.c', + 'pixman-combine-float.c', + 'pixman-conical-gradient.c', + 'pixman-filter.c', + 'pixman-x86.c', + 'pixman-mips.c', + 'pixman-arm.c', + 'pixman-ppc.c', + 'pixman-edge.c', + 'pixman-edge-accessors.c', + 'pixman-fast-path.c', + 'pixman-glyph.c', + 'pixman-general.c', + 'pixman-gradient-walker.c', + 'pixman-image.c', + 'pixman-implementation.c', + 'pixman-linear-gradient.c', + 'pixman-matrix.c', + 'pixman-noop.c', + 'pixman-radial-gradient.c', + 'pixman-region16.c', + 'pixman-region32.c', + 'pixman-solid-fill.c', + 'pixman-timer.c', + 'pixman-trap.c', + 'pixman-utils.c', +) + +libpixman = shared_library( + 'pixman-1', + [pixman_files, config_h, version_h], + link_with : [pixman_simd_libs], + dependencies : [dep_m, dep_threads], + version : meson.project_version(), + install : true, +) + +inc_pixman = include_directories('.') + +idep_pixman = declare_dependency( + link_with: libpixman, + include_directories : inc_pixman, +) + +install_headers('pixman.h', subdir : 'pixman-1') diff --git a/lib/pixman/pixman/pixman-bits-image.c b/lib/pixman/pixman/pixman-bits-image.c index 9fb91ff58..564789e9c 100644 --- a/lib/pixman/pixman/pixman-bits-image.c +++ b/lib/pixman/pixman/pixman-bits-image.c @@ -36,43 +36,45 @@ #include "pixman-combine32.h" #include "pixman-inlines.h" -static uint32_t * -_pixman_image_get_scanline_generic_float (pixman_iter_t * iter, - const uint32_t *mask) -{ - pixman_iter_get_scanline_t fetch_32 = iter->data; - uint32_t *buffer = iter->buffer; - - fetch_32 (iter, NULL); - - pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return iter->buffer; -} - /* Fetch functions */ -static force_inline uint32_t -fetch_pixel_no_alpha (bits_image_t *image, - int x, int y, pixman_bool_t check_bounds) +static force_inline void +fetch_pixel_no_alpha_32 (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds, + void *out) { + uint32_t *ret = out; + if (check_bounds && (x < 0 || x >= image->width || y < 0 || y >= image->height)) - { - return 0; - } - - return image->fetch_pixel_32 (image, x, y); + *ret = 0; + else + *ret = image->fetch_pixel_32 (image, x, y); } -typedef uint32_t (* get_pixel_t) (bits_image_t *image, - int x, int y, pixman_bool_t check_bounds); +static force_inline void +fetch_pixel_no_alpha_float (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds, + void *out) +{ + argb_t *ret = out; -static force_inline uint32_t + if (check_bounds && + (x < 0 || x >= image->width || y < 0 || y >= image->height)) + ret->a = ret->r = ret->g = ret->b = 0.f; + else + *ret = image->fetch_pixel_float (image, x, y); +} + +typedef void (* get_pixel_t) (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds, void *out); + +static force_inline void bits_image_fetch_pixel_nearest (bits_image_t *image, pixman_fixed_t x, pixman_fixed_t y, - get_pixel_t get_pixel) + get_pixel_t get_pixel, + void *out) { int x0 = pixman_fixed_to_int (x - pixman_fixed_e); int y0 = pixman_fixed_to_int (y - pixman_fixed_e); @@ -82,19 +84,20 @@ bits_image_fetch_pixel_nearest (bits_image_t *image, repeat (image->common.repeat, &x0, image->width); repeat (image->common.repeat, &y0, image->height); - return get_pixel (image, x0, y0, FALSE); + get_pixel (image, x0, y0, FALSE, out); } else { - return get_pixel (image, x0, y0, TRUE); + get_pixel (image, x0, y0, TRUE, out); } } -static force_inline uint32_t -bits_image_fetch_pixel_bilinear (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) +static force_inline void +bits_image_fetch_pixel_bilinear_32 (bits_image_t *image, + pixman_fixed_t x, + pixman_fixed_t y, + get_pixel_t get_pixel, + void *out) { pixman_repeat_t repeat_mode = image->common.repeat; int width = image->width; @@ -102,6 +105,7 @@ bits_image_fetch_pixel_bilinear (bits_image_t *image, int x1, y1, x2, y2; uint32_t tl, tr, bl, br; int32_t distx, disty; + uint32_t *ret = out; x1 = x - pixman_fixed_1 / 2; y1 = y - pixman_fixed_1 / 2; @@ -121,27 +125,140 @@ bits_image_fetch_pixel_bilinear (bits_image_t *image, repeat (repeat_mode, &x2, width); repeat (repeat_mode, &y2, height); - tl = get_pixel (image, x1, y1, FALSE); - bl = get_pixel (image, x1, y2, FALSE); - tr = get_pixel (image, x2, y1, FALSE); - br = get_pixel (image, x2, y2, FALSE); + get_pixel (image, x1, y1, FALSE, &tl); + get_pixel (image, x2, y1, FALSE, &tr); + get_pixel (image, x1, y2, FALSE, &bl); + get_pixel (image, x2, y2, FALSE, &br); } else { - tl = get_pixel (image, x1, y1, TRUE); - tr = get_pixel (image, x2, y1, TRUE); - bl = get_pixel (image, x1, y2, TRUE); - br = get_pixel (image, x2, y2, TRUE); + get_pixel (image, x1, y1, TRUE, &tl); + get_pixel (image, x2, y1, TRUE, &tr); + get_pixel (image, x1, y2, TRUE, &bl); + get_pixel (image, x2, y2, TRUE, &br); } - return bilinear_interpolation (tl, tr, bl, br, distx, disty); + *ret = bilinear_interpolation (tl, tr, bl, br, distx, disty); } -static force_inline uint32_t +static force_inline void +bits_image_fetch_pixel_bilinear_float (bits_image_t *image, + pixman_fixed_t x, + pixman_fixed_t y, + get_pixel_t get_pixel, + void *out) +{ + pixman_repeat_t repeat_mode = image->common.repeat; + int width = image->width; + int height = image->height; + int x1, y1, x2, y2; + argb_t tl, tr, bl, br; + float distx, disty; + argb_t *ret = out; + + x1 = x - pixman_fixed_1 / 2; + y1 = y - pixman_fixed_1 / 2; + + distx = ((float)pixman_fixed_fraction(x1)) / 65536.f; + disty = ((float)pixman_fixed_fraction(y1)) / 65536.f; + + x1 = pixman_fixed_to_int (x1); + y1 = pixman_fixed_to_int (y1); + x2 = x1 + 1; + y2 = y1 + 1; + + if (repeat_mode != PIXMAN_REPEAT_NONE) + { + repeat (repeat_mode, &x1, width); + repeat (repeat_mode, &y1, height); + repeat (repeat_mode, &x2, width); + repeat (repeat_mode, &y2, height); + + get_pixel (image, x1, y1, FALSE, &tl); + get_pixel (image, x2, y1, FALSE, &tr); + get_pixel (image, x1, y2, FALSE, &bl); + get_pixel (image, x2, y2, FALSE, &br); + } + else + { + get_pixel (image, x1, y1, TRUE, &tl); + get_pixel (image, x2, y1, TRUE, &tr); + get_pixel (image, x1, y2, TRUE, &bl); + get_pixel (image, x2, y2, TRUE, &br); + } + + *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty); +} + +static force_inline void accum_32(int *satot, int *srtot, + int *sgtot, int *sbtot, + const void *p, pixman_fixed_t f) +{ + uint32_t pixel = *(uint32_t *)p; + + *srtot += (int)RED_8 (pixel) * f; + *sgtot += (int)GREEN_8 (pixel) * f; + *sbtot += (int)BLUE_8 (pixel) * f; + *satot += (int)ALPHA_8 (pixel) * f; +} + +static force_inline void reduce_32(int satot, int srtot, + int sgtot, int sbtot, void *p) +{ + uint32_t *ret = p; + + satot = (satot + 0x8000) >> 16; + srtot = (srtot + 0x8000) >> 16; + sgtot = (sgtot + 0x8000) >> 16; + sbtot = (sbtot + 0x8000) >> 16; + + satot = CLIP (satot, 0, 0xff); + srtot = CLIP (srtot, 0, 0xff); + sgtot = CLIP (sgtot, 0, 0xff); + sbtot = CLIP (sbtot, 0, 0xff); + + *ret = ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); +} + +static force_inline void accum_float(int *satot, int *srtot, + int *sgtot, int *sbtot, + const void *p, pixman_fixed_t f) +{ + const argb_t *pixel = p; + + *satot += pixel->a * f; + *srtot += pixel->r * f; + *sgtot += pixel->g * f; + *sbtot += pixel->b * f; +} + +static force_inline void reduce_float(int satot, int srtot, + int sgtot, int sbtot, + void *p) +{ + argb_t *ret = p; + + ret->a = CLIP (satot / 65536.f, 0.f, 1.f); + ret->r = CLIP (srtot / 65536.f, 0.f, 1.f); + ret->g = CLIP (sgtot / 65536.f, 0.f, 1.f); + ret->b = CLIP (sbtot / 65536.f, 0.f, 1.f); +} + +typedef void (* accumulate_pixel_t) (int *satot, int *srtot, + int *sgtot, int *sbtot, + const void *pixel, pixman_fixed_t f); + +typedef void (* reduce_pixel_t) (int satot, int srtot, + int sgtot, int sbtot, void *out); + +static force_inline void bits_image_fetch_pixel_convolution (bits_image_t *image, pixman_fixed_t x, pixman_fixed_t y, - get_pixel_t get_pixel) + get_pixel_t get_pixel, + void *out, + accumulate_pixel_t accum, + reduce_pixel_t reduce) { pixman_fixed_t *params = image->common.filter_params; int x_off = (params[0] - pixman_fixed_1) >> 1; @@ -174,48 +291,39 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, if (f) { - uint32_t pixel; + /* Must be big enough to hold a argb_t */ + argb_t pixel; if (repeat_mode != PIXMAN_REPEAT_NONE) { repeat (repeat_mode, &rx, width); repeat (repeat_mode, &ry, height); - pixel = get_pixel (image, rx, ry, FALSE); + get_pixel (image, rx, ry, FALSE, &pixel); } else { - pixel = get_pixel (image, rx, ry, TRUE); + get_pixel (image, rx, ry, TRUE, &pixel); } - srtot += (int)RED_8 (pixel) * f; - sgtot += (int)GREEN_8 (pixel) * f; - sbtot += (int)BLUE_8 (pixel) * f; - satot += (int)ALPHA_8 (pixel) * f; + accum (&satot, &srtot, &sgtot, &sbtot, &pixel, f); } params++; } } - satot = (satot + 0x8000) >> 16; - srtot = (srtot + 0x8000) >> 16; - sgtot = (sgtot + 0x8000) >> 16; - sbtot = (sbtot + 0x8000) >> 16; - - satot = CLIP (satot, 0, 0xff); - srtot = CLIP (srtot, 0, 0xff); - sgtot = CLIP (sgtot, 0, 0xff); - sbtot = CLIP (sbtot, 0, 0xff); - - return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); + reduce (satot, srtot, sgtot, sbtot, out); } -static uint32_t -bits_image_fetch_pixel_separable_convolution (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) +static void +bits_image_fetch_pixel_separable_convolution (bits_image_t *image, + pixman_fixed_t x, + pixman_fixed_t y, + get_pixel_t get_pixel, + void *out, + accumulate_pixel_t accum, + reduce_pixel_t reduce) { pixman_fixed_t *params = image->common.filter_params; pixman_repeat_t repeat_mode = image->common.repeat; @@ -270,82 +378,91 @@ bits_image_fetch_pixel_separable_convolution (bits_image_t *image, if (fx) { + /* Must be big enough to hold a argb_t */ + argb_t pixel; pixman_fixed_t f; - uint32_t pixel; if (repeat_mode != PIXMAN_REPEAT_NONE) { repeat (repeat_mode, &rx, width); repeat (repeat_mode, &ry, height); - pixel = get_pixel (image, rx, ry, FALSE); + get_pixel (image, rx, ry, FALSE, &pixel); } else { - pixel = get_pixel (image, rx, ry, TRUE); + get_pixel (image, rx, ry, TRUE, &pixel); } f = (fy * fx + 0x8000) >> 16; - srtot += (int)RED_8 (pixel) * f; - sgtot += (int)GREEN_8 (pixel) * f; - sbtot += (int)BLUE_8 (pixel) * f; - satot += (int)ALPHA_8 (pixel) * f; + accum(&satot, &srtot, &sgtot, &sbtot, &pixel, f); } } } } - satot = (satot + 0x8000) >> 16; - srtot = (srtot + 0x8000) >> 16; - sgtot = (sgtot + 0x8000) >> 16; - sbtot = (sbtot + 0x8000) >> 16; - satot = CLIP (satot, 0, 0xff); - srtot = CLIP (srtot, 0, 0xff); - sgtot = CLIP (sgtot, 0, 0xff); - sbtot = CLIP (sbtot, 0, 0xff); - - return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); + reduce(satot, srtot, sgtot, sbtot, out); } -static force_inline uint32_t -bits_image_fetch_pixel_filtered (bits_image_t *image, +static force_inline void +bits_image_fetch_pixel_filtered (bits_image_t *image, + pixman_bool_t wide, pixman_fixed_t x, pixman_fixed_t y, - get_pixel_t get_pixel) + get_pixel_t get_pixel, + void *out) { switch (image->common.filter) { case PIXMAN_FILTER_NEAREST: case PIXMAN_FILTER_FAST: - return bits_image_fetch_pixel_nearest (image, x, y, get_pixel); + bits_image_fetch_pixel_nearest (image, x, y, get_pixel, out); break; case PIXMAN_FILTER_BILINEAR: case PIXMAN_FILTER_GOOD: case PIXMAN_FILTER_BEST: - return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel); + if (wide) + bits_image_fetch_pixel_bilinear_float (image, x, y, get_pixel, out); + else + bits_image_fetch_pixel_bilinear_32 (image, x, y, get_pixel, out); break; case PIXMAN_FILTER_CONVOLUTION: - return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); + if (wide) + bits_image_fetch_pixel_convolution (image, x, y, + get_pixel, out, + accum_float, + reduce_float); + else + bits_image_fetch_pixel_convolution (image, x, y, + get_pixel, out, + accum_32, reduce_32); break; case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: - return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel); + if (wide) + bits_image_fetch_pixel_separable_convolution (image, x, y, + get_pixel, out, + accum_float, + reduce_float); + else + bits_image_fetch_pixel_separable_convolution (image, x, y, + get_pixel, out, + accum_32, reduce_32); break; default: break; } - - return 0; } static uint32_t * -bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, - const uint32_t * mask) +__bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, + pixman_bool_t wide, + const uint32_t * mask) { pixman_image_t *image = iter->image; int offset = iter->x; @@ -357,6 +474,8 @@ bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, pixman_fixed_t ux, uy; pixman_vector_t v; int i; + get_pixel_t get_pixel = + wide ? fetch_pixel_no_alpha_float : fetch_pixel_no_alpha_32; /* reference point is the center of the pixel */ v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; @@ -384,27 +503,45 @@ bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, { if (!mask || mask[i]) { - buffer[i] = bits_image_fetch_pixel_filtered ( - &image->bits, x, y, fetch_pixel_no_alpha); + bits_image_fetch_pixel_filtered ( + &image->bits, wide, x, y, get_pixel, buffer); } x += ux; y += uy; + buffer += wide ? 4 : 1; } - return buffer; + return iter->buffer; +} + +static uint32_t * +bits_image_fetch_affine_no_alpha_32 (pixman_iter_t *iter, + const uint32_t *mask) +{ + return __bits_image_fetch_affine_no_alpha(iter, FALSE, mask); +} + +static uint32_t * +bits_image_fetch_affine_no_alpha_float (pixman_iter_t *iter, + const uint32_t *mask) +{ + return __bits_image_fetch_affine_no_alpha(iter, TRUE, mask); } /* General fetcher */ -static force_inline uint32_t -fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) +static force_inline void +fetch_pixel_general_32 (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds, + void *out) { - uint32_t pixel; + uint32_t pixel, *ret = out; if (check_bounds && (x < 0 || x >= image->width || y < 0 || y >= image->height)) { - return 0; + *ret = 0; + return; } pixel = image->fetch_pixel_32 (image, x, y); @@ -433,18 +570,59 @@ fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_boun pixel |= (pixel_a << 24); } - return pixel; + *ret = pixel; +} + +static force_inline void +fetch_pixel_general_float (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds, + void *out) +{ + argb_t *ret = out; + + if (check_bounds && + (x < 0 || x >= image->width || y < 0 || y >= image->height)) + { + ret->a = ret->r = ret->g = ret->b = 0; + return; + } + + *ret = image->fetch_pixel_float (image, x, y); + + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + if (x < 0 || x >= image->common.alpha_map->width || + y < 0 || y >= image->common.alpha_map->height) + { + ret->a = 0.f; + } + else + { + argb_t alpha; + + alpha = image->common.alpha_map->fetch_pixel_float ( + image->common.alpha_map, x, y); + + ret->a = alpha.a; + } + } } static uint32_t * -bits_image_fetch_general (pixman_iter_t *iter, - const uint32_t *mask) +__bits_image_fetch_general (pixman_iter_t *iter, + pixman_bool_t wide, + const uint32_t *mask) { pixman_image_t *image = iter->image; int offset = iter->x; int line = iter->y++; int width = iter->width; uint32_t * buffer = iter->buffer; + get_pixel_t get_pixel = + wide ? fetch_pixel_general_float : fetch_pixel_general_32; pixman_fixed_t x, y, w; pixman_fixed_t ux, uy, uw; @@ -493,16 +671,31 @@ bits_image_fetch_general (pixman_iter_t *iter, y0 = 0; } - buffer[i] = bits_image_fetch_pixel_filtered ( - &image->bits, x0, y0, fetch_pixel_general); + bits_image_fetch_pixel_filtered ( + &image->bits, wide, x0, y0, get_pixel, buffer); } x += ux; y += uy; w += uw; + buffer += wide ? 4 : 1; } - return buffer; + return iter->buffer; +} + +static uint32_t * +bits_image_fetch_general_32 (pixman_iter_t *iter, + const uint32_t *mask) +{ + return __bits_image_fetch_general(iter, FALSE, mask); +} + +static uint32_t * +bits_image_fetch_general_float (pixman_iter_t *iter, + const uint32_t *mask) +{ + return __bits_image_fetch_general(iter, TRUE, mask); } static void @@ -703,15 +896,15 @@ static const fetcher_info_t fetcher_info[] = /* Affine, no alpha */ { PIXMAN_any, (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM), - bits_image_fetch_affine_no_alpha, - _pixman_image_get_scanline_generic_float + bits_image_fetch_affine_no_alpha_32, + bits_image_fetch_affine_no_alpha_float, }, /* General */ { PIXMAN_any, 0, - bits_image_fetch_general, - _pixman_image_get_scanline_generic_float + bits_image_fetch_general_32, + bits_image_fetch_general_float, }, { PIXMAN_null }, @@ -741,7 +934,6 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) } else { - iter->data = info->get_scanline_32; iter->get_scanline = info->get_scanline_float; } return; diff --git a/lib/pixman/pixman/pixman-conical-gradient.c b/lib/pixman/pixman/pixman-conical-gradient.c index 8bb46aecd..a39e20c4e 100644 --- a/lib/pixman/pixman/pixman-conical-gradient.c +++ b/lib/pixman/pixman/pixman-conical-gradient.c @@ -51,7 +51,10 @@ coordinates_to_parameter (double x, double y, double angle) } static uint32_t * -conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +conical_get_scanline (pixman_iter_t *iter, + const uint32_t *mask, + int Bpp, + pixman_gradient_walker_write_t write_pixel) { pixman_image_t *image = iter->image; int x = iter->x; @@ -61,7 +64,7 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) gradient_t *gradient = (gradient_t *)image; conical_gradient_t *conical = (conical_gradient_t *)image; - uint32_t *end = buffer + width; + uint32_t *end = buffer + width * (Bpp / 4); pixman_gradient_walker_t walker; pixman_bool_t affine = TRUE; double cx = 1.; @@ -109,11 +112,12 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { double t = coordinates_to_parameter (rx, ry, conical->angle); - *buffer = _pixman_gradient_walker_pixel ( - &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); + write_pixel (&walker, + (pixman_fixed_48_16_t)pixman_double_to_fixed (t), + buffer); } - ++buffer; + buffer += (Bpp / 4); rx += cx; ry += cy; @@ -144,11 +148,12 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) t = coordinates_to_parameter (x, y, conical->angle); - *buffer = _pixman_gradient_walker_pixel ( - &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); + write_pixel (&walker, + (pixman_fixed_48_16_t)pixman_double_to_fixed (t), + buffer); } - ++buffer; + buffer += (Bpp / 4); rx += cx; ry += cy; @@ -160,15 +165,18 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) return iter->buffer; } +static uint32_t * +conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + return conical_get_scanline (iter, mask, 4, + _pixman_gradient_walker_write_narrow); +} + static uint32_t * conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { - uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; + return conical_get_scanline (iter, NULL, 16, + _pixman_gradient_walker_write_wide); } void diff --git a/lib/pixman/pixman/pixman-gradient-walker.c b/lib/pixman/pixman/pixman-gradient-walker.c index 822f8e62b..af4df586b 100644 --- a/lib/pixman/pixman/pixman-gradient-walker.c +++ b/lib/pixman/pixman/pixman-gradient-walker.c @@ -122,10 +122,9 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, left_c = right_c; } - /* The alpha channel is scaled to be in the [0, 255] interval, - * and the red/green/blue channels are scaled to be in [0, 1]. + /* The alpha/red/green/blue channels are scaled to be in [0, 1]. * This ensures that after premultiplication all channels will - * be in the [0, 255] interval. + * be in the [0, 1] interval. */ la = (left_c->alpha * (1.0f/257.0f)); lr = (left_c->red * (1.0f/257.0f)); @@ -143,7 +142,7 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX) { walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f; - walker->a_b = (la + ra) / 2.0f; + walker->a_b = (la + ra) / 510.0f; walker->r_b = (lr + rr) / 510.0f; walker->g_b = (lg + rg) / 510.0f; walker->b_b = (lb + rb) / 510.0f; @@ -152,12 +151,12 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, { float w_rec = 1.0f / (rx - lx); - walker->a_b = (la * rx - ra * lx) * w_rec; + walker->a_b = (la * rx - ra * lx) * w_rec * (1.0f/255.0f); walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f); walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f); walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f); - walker->a_s = (ra - la) * w_rec; + walker->a_s = (ra - la) * w_rec * (1.0f/255.0f); walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f); walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f); walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f); @@ -169,34 +168,97 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, walker->need_reset = FALSE; } -uint32_t -_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t x) +static argb_t +pixman_gradient_walker_pixel_float (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x) { - float a, r, g, b; - uint8_t a8, r8, g8, b8; - uint32_t v; + argb_t f; float y; if (walker->need_reset || x < walker->left_x || x >= walker->right_x) - gradient_walker_reset (walker, x); + gradient_walker_reset (walker, x); y = x * (1.0f / 65536.0f); - a = walker->a_s * y + walker->a_b; - r = a * (walker->r_s * y + walker->r_b); - g = a * (walker->g_s * y + walker->g_b); - b = a * (walker->b_s * y + walker->b_b); + f.a = walker->a_s * y + walker->a_b; + f.r = f.a * (walker->r_s * y + walker->r_b); + f.g = f.a * (walker->g_s * y + walker->g_b); + f.b = f.a * (walker->b_s * y + walker->b_b); - a8 = a + 0.5f; - r8 = r + 0.5f; - g8 = g + 0.5f; - b8 = b + 0.5f; - - v = ((a8 << 24) & 0xff000000) | - ((r8 << 16) & 0x00ff0000) | - ((g8 << 8) & 0x0000ff00) | - ((b8 >> 0) & 0x000000ff); - - return v; + return f; +} + +static uint32_t +pixman_gradient_walker_pixel_32 (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x) +{ + argb_t f; + float y; + + if (walker->need_reset || x < walker->left_x || x >= walker->right_x) + gradient_walker_reset (walker, x); + + y = x * (1.0f / 65536.0f); + + /* Instead of [0...1] for ARGB, we want [0...255], + * multiply alpha with 255 and the color channels + * also get multiplied by the alpha multiplier. + * + * We don't use pixman_contract_from_float because it causes a 2x + * slowdown to do so, and the values are already normalized, + * so we don't have to worry about values < 0.f or > 1.f + */ + f.a = 255.f * (walker->a_s * y + walker->a_b); + f.r = f.a * (walker->r_s * y + walker->r_b); + f.g = f.a * (walker->g_s * y + walker->g_b); + f.b = f.a * (walker->b_s * y + walker->b_b); + + return (((uint8_t)(f.a + .5f) << 24) & 0xff000000) | + (((uint8_t)(f.r + .5f) << 16) & 0x00ff0000) | + (((uint8_t)(f.g + .5f) << 8) & 0x0000ff00) | + (((uint8_t)(f.b + .5f) >> 0) & 0x000000ff); +} + +void +_pixman_gradient_walker_write_narrow (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer) +{ + *buffer = pixman_gradient_walker_pixel_32 (walker, x); +} + +void +_pixman_gradient_walker_write_wide (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer) +{ + *(argb_t *)buffer = pixman_gradient_walker_pixel_float (walker, x); +} + +void +_pixman_gradient_walker_fill_narrow (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer, + uint32_t *end) +{ + register uint32_t color; + + color = pixman_gradient_walker_pixel_32 (walker, x); + while (buffer < end) + *buffer++ = color; +} + +void +_pixman_gradient_walker_fill_wide (pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer, + uint32_t *end) +{ + register argb_t color; + argb_t *buffer_wide = (argb_t *)buffer; + argb_t *end_wide = (argb_t *)end; + + color = pixman_gradient_walker_pixel_float (walker, x); + while (buffer_wide < end_wide) + *buffer_wide++ = color; } diff --git a/lib/pixman/pixman/pixman-inlines.h b/lib/pixman/pixman/pixman-inlines.h index 1c8441d6d..332e20814 100644 --- a/lib/pixman/pixman/pixman-inlines.h +++ b/lib/pixman/pixman/pixman-inlines.h @@ -222,6 +222,31 @@ bilinear_interpolation (uint32_t tl, uint32_t tr, #endif #endif // BILINEAR_INTERPOLATION_BITS <= 4 +static force_inline argb_t +bilinear_interpolation_float (argb_t tl, argb_t tr, + argb_t bl, argb_t br, + float distx, float disty) +{ + float distxy, distxiy, distixy, distixiy; + argb_t r; + + distxy = distx * disty; + distxiy = distx - (1.f - distxy); + distixy = (1.f - distx) * disty; + distixiy = (1.f - distx) * (1.f - disty); + + r.a = tl.a * distixiy + tr.a * distxiy + + bl.a * distixy + br.a * distxy; + r.r = tl.r * distixiy + tr.r * distxiy + + bl.r * distixy + br.r * distxy; + r.g = tl.g * distixiy + tr.g * distxiy + + bl.g * distixy + br.g * distxy; + r.b = tl.b * distixiy + tr.b * distxiy + + bl.b * distixy + br.b * distxy; + + return r; +} + /* * For each scanline fetched from source image with PAD repeat: * - calculate how many pixels need to be padded on the left side diff --git a/lib/pixman/pixman/pixman-linear-gradient.c b/lib/pixman/pixman/pixman-linear-gradient.c index 40c8c9f37..3f528508a 100644 --- a/lib/pixman/pixman/pixman-linear-gradient.c +++ b/lib/pixman/pixman/pixman-linear-gradient.c @@ -89,8 +89,11 @@ linear_gradient_is_horizontal (pixman_image_t *image, } static uint32_t * -linear_get_scanline_narrow (pixman_iter_t *iter, - const uint32_t *mask) +linear_get_scanline (pixman_iter_t *iter, + const uint32_t *mask, + int Bpp, + pixman_gradient_walker_write_t write_pixel, + pixman_gradient_walker_fill_t fill_pixel) { pixman_image_t *image = iter->image; int x = iter->x; @@ -103,7 +106,7 @@ linear_get_scanline_narrow (pixman_iter_t *iter, pixman_fixed_48_16_t dx, dy; gradient_t *gradient = (gradient_t *)image; linear_gradient_t *linear = (linear_gradient_t *)image; - uint32_t *end = buffer + width; + uint32_t *end = buffer + width * (Bpp / 4); pixman_gradient_walker_t walker; _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); @@ -137,7 +140,7 @@ linear_get_scanline_narrow (pixman_iter_t *iter, if (l == 0 || unit.vector[2] == 0) { /* affine transformation only */ - pixman_fixed_32_32_t t, next_inc; + pixman_fixed_32_32_t t, next_inc; double inc; if (l == 0 || v.vector[2] == 0) @@ -152,7 +155,7 @@ linear_get_scanline_narrow (pixman_iter_t *iter, invden = pixman_fixed_1 * (double) pixman_fixed_1 / (l * (double) v.vector[2]); v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - + t = ((dx * v.vector[0] + dy * v.vector[1]) - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; } @@ -160,11 +163,7 @@ linear_get_scanline_narrow (pixman_iter_t *iter, if (((pixman_fixed_32_32_t )(inc * width)) == 0) { - register uint32_t color; - - color = _pixman_gradient_walker_pixel (&walker, t); - while (buffer < end) - *buffer++ = color; + fill_pixel (&walker, t, buffer, end); } else { @@ -175,12 +174,11 @@ linear_get_scanline_narrow (pixman_iter_t *iter, { if (!mask || *mask++) { - *buffer = _pixman_gradient_walker_pixel (&walker, - t + next_inc); + write_pixel (&walker, t + next_inc, buffer); } i++; next_inc = inc * i; - buffer++; + buffer += (Bpp / 4); } } } @@ -202,14 +200,14 @@ linear_get_scanline_narrow (pixman_iter_t *iter, invden = pixman_fixed_1 * (double) pixman_fixed_1 / (l * (double) v.vector[2]); v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - + t = ((dx * v.vector[0] + dy * v.vector[1]) - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; } - *buffer = _pixman_gradient_walker_pixel (&walker, t); + write_pixel (&walker, t, buffer); } - ++buffer; + buffer += (Bpp / 4); v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; @@ -222,15 +220,22 @@ linear_get_scanline_narrow (pixman_iter_t *iter, return iter->buffer; } +static uint32_t * +linear_get_scanline_narrow (pixman_iter_t *iter, + const uint32_t *mask) +{ + return linear_get_scanline (iter, mask, 4, + _pixman_gradient_walker_write_narrow, + _pixman_gradient_walker_fill_narrow); +} + + static uint32_t * linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { - uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; + return linear_get_scanline (iter, NULL, 16, + _pixman_gradient_walker_write_wide, + _pixman_gradient_walker_fill_wide); } void diff --git a/lib/pixman/pixman/pixman-private.h b/lib/pixman/pixman/pixman-private.h index 73a54146d..1bd969591 100644 --- a/lib/pixman/pixman/pixman-private.h +++ b/lib/pixman/pixman/pixman-private.h @@ -363,9 +363,38 @@ void _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, pixman_fixed_48_16_t pos); -uint32_t -_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t x); +typedef void (*pixman_gradient_walker_write_t) ( + pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer); + +void +_pixman_gradient_walker_write_narrow(pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer); + +void +_pixman_gradient_walker_write_wide(pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer); + +typedef void (*pixman_gradient_walker_fill_t) ( + pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer, + uint32_t *end); + +void +_pixman_gradient_walker_fill_narrow(pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer, + uint32_t *end); + +void +_pixman_gradient_walker_fill_wide(pixman_gradient_walker_t *walker, + pixman_fixed_48_16_t x, + uint32_t *buffer, + uint32_t *end); /* * Edges diff --git a/lib/pixman/pixman/pixman-radial-gradient.c b/lib/pixman/pixman/pixman-radial-gradient.c index 6a217963d..e8e99c98b 100644 --- a/lib/pixman/pixman/pixman-radial-gradient.c +++ b/lib/pixman/pixman/pixman-radial-gradient.c @@ -66,15 +66,18 @@ fdot (double x1, return x1 * x2 + y1 * y2 + z1 * z2; } -static uint32_t -radial_compute_color (double a, - double b, - double c, - double inva, - double dr, - double mindr, - pixman_gradient_walker_t *walker, - pixman_repeat_t repeat) +static void +radial_write_color (double a, + double b, + double c, + double inva, + double dr, + double mindr, + pixman_gradient_walker_t *walker, + pixman_repeat_t repeat, + int Bpp, + pixman_gradient_walker_write_t write_pixel, + uint32_t *buffer) { /* * In this function error propagation can lead to bad results: @@ -99,21 +102,31 @@ radial_compute_color (double a, double t; if (b == 0) - return 0; + { + memset (buffer, 0, Bpp); + return; + } t = pixman_fixed_1 / 2 * c / b; if (repeat == PIXMAN_REPEAT_NONE) { if (0 <= t && t <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t); + { + write_pixel (walker, t, buffer); + return; + } } else { if (t * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t); + { + write_pixel (walker, t, buffer); + return; + } } - return 0; + memset (buffer, 0, Bpp); + return; } discr = fdot (b, a, 0, b, -c, 0); @@ -139,24 +152,40 @@ radial_compute_color (double a, if (repeat == PIXMAN_REPEAT_NONE) { if (0 <= t0 && t0 <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t0); + { + write_pixel (walker, t0, buffer); + return; + } else if (0 <= t1 && t1 <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t1); + { + write_pixel (walker, t1, buffer); + return; + } } else { if (t0 * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t0); + { + write_pixel (walker, t0, buffer); + return; + } else if (t1 * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t1); + { + write_pixel (walker, t1, buffer); + return; + } } } - return 0; + memset (buffer, 0, Bpp); + return; } static uint32_t * -radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +radial_get_scanline (pixman_iter_t *iter, + const uint32_t *mask, + int Bpp, + pixman_gradient_walker_write_t write_pixel) { /* * Implementation of radial gradients following the PDF specification. @@ -247,7 +276,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) gradient_t *gradient = (gradient_t *)image; radial_gradient_t *radial = (radial_gradient_t *)image; - uint32_t *end = buffer + width; + uint32_t *end = buffer + width * (Bpp / 4); pixman_gradient_walker_t walker; pixman_vector_t v, unit; @@ -330,18 +359,21 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) { if (!mask || *mask++) { - *buffer = radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat); + radial_write_color (radial->a, b, c, + radial->inva, + radial->delta.radius, + radial->mindr, + &walker, + image->common.repeat, + Bpp, + write_pixel, + buffer); } b += db; c += dc; dc += ddc; - ++buffer; + buffer += (Bpp / 4); } } else @@ -375,20 +407,23 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) pdx, pdy, radial->c1.radius); /* / pixman_fixed_1 / pixman_fixed_1 */ - *buffer = radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat); + radial_write_color (radial->a, b, c, + radial->inva, + radial->delta.radius, + radial->mindr, + &walker, + image->common.repeat, + Bpp, + write_pixel, + buffer); } else { - *buffer = 0; + memset (buffer, 0, Bpp); } } - ++buffer; + buffer += (Bpp / 4); v.vector[0] += unit.vector[0]; v.vector[1] += unit.vector[1]; @@ -400,15 +435,18 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) return iter->buffer; } +static uint32_t * +radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) +{ + return radial_get_scanline (iter, mask, 4, + _pixman_gradient_walker_write_narrow); +} + static uint32_t * radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) { - uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; + return radial_get_scanline (iter, NULL, 16, + _pixman_gradient_walker_write_wide); } void @@ -422,11 +460,11 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) PIXMAN_EXPORT pixman_image_t * pixman_image_create_radial_gradient (const pixman_point_fixed_t * inner, - const pixman_point_fixed_t * outer, - pixman_fixed_t inner_radius, - pixman_fixed_t outer_radius, - const pixman_gradient_stop_t *stops, - int n_stops) + const pixman_point_fixed_t * outer, + pixman_fixed_t inner_radius, + pixman_fixed_t outer_radius, + const pixman_gradient_stop_t *stops, + int n_stops) { pixman_image_t *image; radial_gradient_t *radial; diff --git a/lib/pixman/test/Makefile.am b/lib/pixman/test/Makefile.am index 88dc36d2a..6dbed88d8 100644 --- a/lib/pixman/test/Makefile.am +++ b/lib/pixman/test/Makefile.am @@ -11,3 +11,7 @@ noinst_LTLIBRARIES = libutils.la noinst_PROGRAMS = $(TESTPROGRAMS) $(OTHERPROGRAMS) TESTS = $(TESTPROGRAMS) + +EXTRA_DIST = \ + meson.build \ + $(NULL) diff --git a/lib/pixman/test/Makefile.in b/lib/pixman/test/Makefile.in index 65463f1c1..fa245417e 100644 --- a/lib/pixman/test/Makefile.in +++ b/lib/pixman/test/Makefile.in @@ -607,6 +607,10 @@ LDADD = libutils.la $(top_builddir)/pixman/libpixman-1.la -lm $(PNG_LIBS) $(PTH AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(PNG_CFLAGS) libutils_la_SOURCES = $(libutils_sources) $(libutils_headers) noinst_LTLIBRARIES = libutils.la +EXTRA_DIST = \ + meson.build \ + $(NULL) + all: all-am .SUFFIXES: diff --git a/lib/pixman/test/meson.build b/lib/pixman/test/meson.build new file mode 100644 index 000000000..a2da1085b --- /dev/null +++ b/lib/pixman/test/meson.build @@ -0,0 +1,92 @@ +# Copyright © 2018 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +tests = [ + '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', + 'filter-reduction-test', + 'composite-traps-test', + 'region-contains-test', + 'glyph-test', + 'solid-test', + 'stress-test', + 'cover-test', + 'blitters-test', + 'affine-test', + 'scaling-test', + 'composite', + 'tolerance-test', +] + +progs = [ + 'lowlevel-blt-bench', + 'radial-perf-test', + 'check-formats', + 'scaling-bench', + 'affine-bench', +] + +libtestutils = static_library( + 'testutils', + ['utils.c', 'utils-prng.c', config_h], + dependencies : [dep_openmp, dep_m, dep_png, idep_pixman], +) + +foreach t : tests + test( + t, + executable( + t, + [t + '.c', config_h], + link_with : libtestutils, + dependencies : [dep_threads, dep_openmp, idep_pixman], + ), + timeout : 120, + is_parallel : true, + ) +endforeach + +foreach p : progs + executable( + p, + p + '.c', + link_with : libtestutils, + dependencies : [dep_openmp, idep_pixman], + ) +endforeach