mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-04-12 10:48:39 +03:00
add pixman vendor without submodule
This commit is contained in:
14
vendor/pixman/.editorconfig
vendored
Normal file
14
vendor/pixman/.editorconfig
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# To use this config on you editor, follow the instructions at:
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
tab_width = 8
|
||||
|
||||
[Makefile.*]
|
||||
indent_style = tab
|
||||
|
||||
[meson.build,meson_options.txt]
|
||||
indent_style = space
|
||||
indent_size = 2
|
56
vendor/pixman/.gitignore
vendored
Normal file
56
vendor/pixman/.gitignore
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
.msg
|
||||
*.pc
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h?
|
||||
config.h
|
||||
config.h.in
|
||||
.*.swp
|
||||
demos/*-test
|
||||
demos/checkerboard
|
||||
demos/clip-in
|
||||
demos/linear-gradient
|
||||
demos/quad2quad
|
||||
demos/scale
|
||||
demos/dither
|
||||
pixman/pixman-srgb.c
|
||||
pixman/pixman-version.h
|
||||
test/*-test
|
||||
test/affine-bench
|
||||
test/alpha-loop
|
||||
test/alphamap
|
||||
test/check-formats
|
||||
test/clip-in
|
||||
test/composite
|
||||
test/infinite-loop
|
||||
test/lowlevel-blt-bench
|
||||
test/radial-invalid
|
||||
test/region-translate
|
||||
test/scaling-bench
|
||||
test/trap-crasher
|
||||
*.pdb
|
||||
*.dll
|
||||
*.lib
|
||||
*.ilk
|
||||
*.obj
|
||||
*.exe
|
19
vendor/pixman/.gitlab-ci.yml
vendored
Normal file
19
vendor/pixman/.gitlab-ci.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
image: fedora:28
|
||||
|
||||
autotools-build:
|
||||
script:
|
||||
- dnf -y install dnf-plugins-core
|
||||
- dnf -y groupinstall buildsys-build
|
||||
- dnf -y builddep pixman
|
||||
- ./autogen.sh
|
||||
- make -sj4 check
|
||||
|
||||
meson-build:
|
||||
script:
|
||||
- dnf -y install dnf-plugins-core
|
||||
- dnf -y groupinstall buildsys-build
|
||||
- dnf -y builddep pixman
|
||||
- dnf -y install ninja-build
|
||||
- python3 -m pip install meson>=0.52.1
|
||||
- meson build
|
||||
- ninja -C build test
|
0
vendor/pixman/AUTHORS
vendored
Normal file
0
vendor/pixman/AUTHORS
vendored
Normal file
199
vendor/pixman/CODING_STYLE
vendored
Normal file
199
vendor/pixman/CODING_STYLE
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
Pixman coding style.
|
||||
====================
|
||||
|
||||
The pixman coding style is close to cairo's with one exception: braces
|
||||
go on their own line, rather than on the line of the if/while/for:
|
||||
|
||||
if (condition)
|
||||
{
|
||||
do_something();
|
||||
do_something_else();
|
||||
}
|
||||
|
||||
not
|
||||
|
||||
if (condition) {
|
||||
do_something();
|
||||
do_something_else();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Indentation
|
||||
===========
|
||||
|
||||
Each new level is indented four spaces:
|
||||
|
||||
if (condition)
|
||||
do_something();
|
||||
|
||||
This may be achieved with space characters or with a combination of
|
||||
tab characters and space characters. Tab characters are interpreted as
|
||||
|
||||
Advance to the next column which is a multiple of 8.
|
||||
|
||||
|
||||
Names
|
||||
=====
|
||||
|
||||
In all names, words are separated with underscores. Do not use
|
||||
CamelCase for any names.
|
||||
|
||||
Macros have ALL_CAPITAL_NAMES
|
||||
|
||||
Type names are in lower case and end with "_t". For example
|
||||
pixman_image_t.
|
||||
|
||||
Labels, functions and variables have lower case names.
|
||||
|
||||
|
||||
Braces
|
||||
======
|
||||
|
||||
Braces always go on their own line:
|
||||
|
||||
if (condition)
|
||||
{
|
||||
do_this ();
|
||||
do_that ();
|
||||
}
|
||||
else
|
||||
{
|
||||
do_the_other ();
|
||||
}
|
||||
|
||||
Rules for braces and substatements of if/while/for/do:
|
||||
|
||||
* If a substatement spans multiple lines, then there must be braces
|
||||
around it.
|
||||
|
||||
* If the condition of an if/while/for spans multiple lines, then
|
||||
braces must be used for the substatements.
|
||||
|
||||
* If one substatement of an if statement has braces, then the other
|
||||
must too.
|
||||
|
||||
* Otherwise, don't add braces.
|
||||
|
||||
|
||||
Comments
|
||||
========
|
||||
|
||||
For comments either like this:
|
||||
|
||||
/* One line comment */
|
||||
|
||||
or like this:
|
||||
|
||||
/* This is a multi-line comment
|
||||
*
|
||||
* It extends over multiple lines
|
||||
*/
|
||||
|
||||
Generally comments should say things that aren't clear from the code
|
||||
itself. If too many comments say obvious things, then people will just
|
||||
stop reading all comments, including the good ones.
|
||||
|
||||
|
||||
Whitespace
|
||||
==========
|
||||
|
||||
* Put a single space after commas
|
||||
|
||||
* Put spaces around arithmetic operators such a +, -, *, /:
|
||||
|
||||
y * stride + x
|
||||
|
||||
x / unit_x
|
||||
|
||||
* Do not put spaces after the address-of operator, the * when used as
|
||||
a pointer derefernce or the ! and ~ operators:
|
||||
|
||||
&foo;
|
||||
|
||||
~0x00000000
|
||||
|
||||
!condition
|
||||
|
||||
*result = 100
|
||||
|
||||
* Break up long lines (> ~80 characters) and use whitespace to align
|
||||
things nicely. This is one way:
|
||||
|
||||
some_very_long_function name (
|
||||
implementation, op, src, mask, dest,
|
||||
src_x, src_y, mask_x, mask_y, dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
This is another:
|
||||
|
||||
some_very_long_function_name (implementation, op,
|
||||
src, mask, dest,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
* Separate logically distinct chunks with a single newline. This
|
||||
obviously applies between functions, but also applies within a
|
||||
function or block or structure definition.
|
||||
|
||||
* Use a newline after a block of variable declarations.
|
||||
|
||||
* Use a single space before a left parenthesis, except where the
|
||||
standard will not allow it, (eg. when defining a parameterized macro).
|
||||
|
||||
* Don't eliminate newlines just because things would still fit on one
|
||||
line. This breaks the expected visual structure of the code making
|
||||
it much harder to read and understand:
|
||||
|
||||
if (condition) foo (); else bar (); /* Yuck! */
|
||||
|
||||
|
||||
Function Definitions
|
||||
====================
|
||||
|
||||
Function definitions should take the following form:
|
||||
|
||||
void
|
||||
my_function (int argument)
|
||||
{
|
||||
do_my_things ();
|
||||
}
|
||||
|
||||
If all the parameters to a function fit naturally on one line, format
|
||||
them that way. Otherwise, put one argument on each line, adding
|
||||
whitespace so that the parameter names are aligned with each other.
|
||||
|
||||
I.e., do either this:
|
||||
|
||||
void
|
||||
short_arguments (const char *str, int x, int y, int z)
|
||||
{
|
||||
}
|
||||
|
||||
or this:
|
||||
|
||||
void
|
||||
long_arguments (const char *char_star_arg,
|
||||
int int_arg,
|
||||
double *double_star_arg,
|
||||
double double_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Mode lines
|
||||
==========
|
||||
|
||||
Given the rules above, what is the best way to simplify one's life as
|
||||
a code monkey? Get your editor to do most of the tedious work of
|
||||
beautifying your code!
|
||||
|
||||
As a reward for reading this far, here are some mode lines for the more
|
||||
popular editors:
|
||||
/*
|
||||
* vim:sw=4:sts=4:ts=8:tw=78:fo=tcroq:cindent:cino=\:0,(0
|
||||
* vim:isk=a-z,A-Z,48-57,_,.,-,>
|
||||
*/
|
||||
|
42
vendor/pixman/COPYING
vendored
Normal file
42
vendor/pixman/COPYING
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
The following is the MIT license, agreed upon by most contributors.
|
||||
Copyright holders of new code should use this license statement where
|
||||
possible. They may also add themselves to the list below.
|
||||
|
||||
/*
|
||||
* Copyright 1987, 1988, 1989, 1998 The Open Group
|
||||
* Copyright 1987, 1988, 1989 Digital Equipment Corporation
|
||||
* Copyright 1999, 2004, 2008 Keith Packard
|
||||
* Copyright 2000 SuSE, Inc.
|
||||
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2004 Nicholas Miell
|
||||
* Copyright 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* Copyright 2005 Trolltech AS
|
||||
* Copyright 2007 Luca Barbato
|
||||
* Copyright 2008 Aaron Plattner, NVIDIA Corporation
|
||||
* Copyright 2008 Rodrigo Kumpera
|
||||
* Copyright 2008 André Tupinambá
|
||||
* Copyright 2008 Mozilla Corporation
|
||||
* Copyright 2008 Frederic Plourde
|
||||
* Copyright 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009, 2010 Nokia 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
0
vendor/pixman/ChangeLog
vendored
Normal file
0
vendor/pixman/ChangeLog
vendored
Normal file
234
vendor/pixman/INSTALL
vendored
Normal file
234
vendor/pixman/INSTALL
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
143
vendor/pixman/Makefile.am
vendored
Normal file
143
vendor/pixman/Makefile.am
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
SUBDIRS = pixman demos test
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfig_DATA=pixman-1.pc
|
||||
|
||||
$(pkgconfig_DATA): pixman-1.pc.in
|
||||
|
||||
snapshot:
|
||||
distdir="$(distdir)-`date '+%Y%m%d'`"; \
|
||||
test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist
|
||||
|
||||
GPGKEY=3892336E
|
||||
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 = 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 \
|
||||
meson.build \
|
||||
meson_options.txt \
|
||||
neon-test.S \
|
||||
a64-neon-test.S \
|
||||
arm-simd-test.S \
|
||||
$(NULL)
|
||||
|
||||
tar_gz = $(PACKAGE)-$(VERSION).tar.gz
|
||||
tar_xz = $(PACKAGE)-$(VERSION).tar.xz
|
||||
|
||||
sha512_tgz = $(tar_gz).sha512
|
||||
sha256_tgz = $(tar_gz).sha256
|
||||
|
||||
sha512_txz = $(tar_xz).sha512
|
||||
sha256_txz = $(tar_xz).sha256
|
||||
|
||||
gpg_file = $(sha512_tgz).asc
|
||||
|
||||
$(sha512_tgz): $(tar_gz)
|
||||
sha512sum $^ > $@
|
||||
|
||||
$(sha256_tgz): $(tar_gz)
|
||||
sha256sum $^ > $@
|
||||
|
||||
$(sha512_txz): $(tar_xz)
|
||||
sha512sum $^ > $@
|
||||
|
||||
$(sha256_txz): $(tar_xz)
|
||||
sha256sum $^ > $@
|
||||
|
||||
$(gpg_file): $(sha512_tgz)
|
||||
@echo "Please enter your GPG password to sign the checksum."
|
||||
gpg --armor --sign $^
|
||||
|
||||
HASHFILES = $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(sha256_txz)
|
||||
|
||||
release-verify-newer:
|
||||
@echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..."
|
||||
@ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \
|
||||
|| (echo "Ouch." && echo "Found: $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)/$(tar_gz)" \
|
||||
&& echo "Refusing to try to generate a new release of the same name." \
|
||||
&& false)
|
||||
@ssh $(RELEASE_CAIRO_HOST) test ! -e $(RELEASE_CAIRO_DIR)/$(tar_gz) \
|
||||
|| (echo "Ouch." && echo "Found: $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)/$(tar_gz)" \
|
||||
&& echo "Refusing to try to generate a new release of the same name." \
|
||||
&& false)
|
||||
@echo "Good."
|
||||
|
||||
release-remove-old:
|
||||
$(RM) $(tar_gz) $(tar_xz) $(HASHFILES) $(gpg_file)
|
||||
|
||||
ensure-prev:
|
||||
@if [ "$(PREV)" = "" ]; then \
|
||||
echo "" && \
|
||||
echo "You must set the PREV variable on the make command line to" && \
|
||||
echo "the last version." && \
|
||||
echo "" && \
|
||||
echo "For example:" && \
|
||||
echo " make PREV=0.7.3" && \
|
||||
echo "" && \
|
||||
false; \
|
||||
fi
|
||||
|
||||
release-check: ensure-prev release-verify-newer release-remove-old distcheck
|
||||
|
||||
release-tag:
|
||||
git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION)
|
||||
|
||||
release-upload: release-check $(tar_gz) $(tar_xz) $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(gpg_file)
|
||||
scp $(tar_gz) $(sha512_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)
|
||||
scp $(tar_gz) $(tar_xz) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)
|
||||
ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)"
|
||||
|
||||
RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi)
|
||||
|
||||
release-publish-message: $(HASHFILES) ensure-prev
|
||||
@echo "Please follow the instructions in RELEASING to push stuff out and"
|
||||
@echo "send out the announcement mails. Here is the excerpt you need:"
|
||||
@echo ""
|
||||
@echo "Lists: $(RELEASE_ANNOUNCE_LIST)"
|
||||
@echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available"
|
||||
@echo "============================== CUT HERE =============================="
|
||||
@echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)"
|
||||
@echo ""
|
||||
@echo "tar.gz:"
|
||||
@echo " $(RELEASE_CAIRO_URL)/$(tar_gz)"
|
||||
@echo " $(RELEASE_XORG_URL)/$(tar_gz)"
|
||||
@echo ""
|
||||
@echo "tar.xz:"
|
||||
@echo " $(RELEASE_XORG_URL)/$(tar_xz)"
|
||||
@echo ""
|
||||
@echo "Hashes:"
|
||||
@echo -n " SHA256: "
|
||||
@cat $(sha256_tgz)
|
||||
@echo -n " SHA256: "
|
||||
@cat $(sha256_txz)
|
||||
@echo -n " SHA512: "
|
||||
@cat $(sha512_tgz)
|
||||
@echo -n " SHA512: "
|
||||
@cat $(sha512_txz)
|
||||
@echo ""
|
||||
@echo "GPG signature:"
|
||||
@echo " $(RELEASE_CAIRO_URL)/$(gpg_file)"
|
||||
@echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)"
|
||||
@echo ""
|
||||
@echo "Git:"
|
||||
@echo " https://gitlab.freedesktop.org/pixman/pixman.git"
|
||||
@echo " tag: $(PACKAGE)-$(VERSION)"
|
||||
@echo ""
|
||||
@echo "Log:"
|
||||
@git log --no-merges "$(PACKAGE)-$(PREV)".."$(PACKAGE)-$(VERSION)" | git shortlog | awk '{ printf "\t"; print ; }' | cut -b1-80
|
||||
@echo "============================== CUT HERE =============================="
|
||||
@echo ""
|
||||
|
||||
release-publish: release-upload release-tag release-publish-message
|
||||
|
||||
.PHONY: release-upload release-publish release-publish-message release-tag
|
25
vendor/pixman/Makefile.win32
vendored
Normal file
25
vendor/pixman/Makefile.win32
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
default: all
|
||||
|
||||
top_srcdir = .
|
||||
include $(top_srcdir)/Makefile.win32.common
|
||||
|
||||
all: pixman test
|
||||
|
||||
pixman:
|
||||
@$(MAKE) -C pixman -f Makefile.win32
|
||||
|
||||
test:
|
||||
@$(MAKE) -C test -f Makefile.win32
|
||||
|
||||
clean_r:
|
||||
@$(MAKE) -C pixman -f Makefile.win32 clean
|
||||
@$(MAKE) -C test -f Makefile.win32 clean
|
||||
|
||||
check:
|
||||
@$(MAKE) -C test -f Makefile.win32 check
|
||||
|
||||
|
||||
clean: clean_r
|
||||
|
||||
|
||||
.PHONY: all pixman test clean check
|
73
vendor/pixman/Makefile.win32.common
vendored
Normal file
73
vendor/pixman/Makefile.win32.common
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
LIBRARY = pixman-1
|
||||
|
||||
ifeq ($(shell echo ""),)
|
||||
# POSIX style shell
|
||||
mkdir_p = mkdir -p $1
|
||||
rm = $(RM) $1
|
||||
echo = echo "$1"
|
||||
else
|
||||
# DOS/Windows style shell
|
||||
mkdir_p = if not exist $(subst /,\,$1) md $(subst /,\,$1)
|
||||
echo = echo $1
|
||||
rm = del $(subst /,\,$1)
|
||||
endif
|
||||
|
||||
CC = cl
|
||||
LD = link
|
||||
AR = lib
|
||||
PERL = perl
|
||||
|
||||
ifneq ($(shell echo ""),)
|
||||
RM = del
|
||||
endif
|
||||
|
||||
ifeq ($(top_builddir),)
|
||||
top_builddir = $(top_srcdir)
|
||||
endif
|
||||
|
||||
CFG_VAR = $(CFG)
|
||||
ifeq ($(CFG_VAR),)
|
||||
CFG_VAR = release
|
||||
endif
|
||||
|
||||
ifeq ($(CFG_VAR),debug)
|
||||
CFG_CFLAGS = -MDd -Od -Zi
|
||||
CFG_LDFLAGS = -DEBUG
|
||||
else
|
||||
CFG_CFLAGS = -MD -O2
|
||||
CFG_LDFLAGS =
|
||||
endif
|
||||
|
||||
# Package definitions, to be used instead of those provided in config.h
|
||||
PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT=""
|
||||
|
||||
BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman
|
||||
|
||||
PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS)
|
||||
PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS)
|
||||
PIXMAN_ARFLAGS = -nologo $(LDFLAGS)
|
||||
|
||||
|
||||
inform:
|
||||
ifneq ($(CFG),release)
|
||||
ifneq ($(CFG),debug)
|
||||
ifneq ($(CFG),)
|
||||
@echo "Invalid specified configuration option: "$(CFG)"."
|
||||
@echo
|
||||
@echo "Possible choices for configuration are 'release' and 'debug'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)"
|
||||
endif
|
||||
endif
|
||||
|
||||
$(CFG_VAR):
|
||||
@$(call mkdir_p,$@)
|
||||
|
||||
$(CFG_VAR)/%.obj: %.c $(libpixman_headers) | $(CFG_VAR)
|
||||
$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $<
|
||||
|
||||
clean: inform $(CFG_VAR)
|
||||
-$(call rm,$(CFG_VAR)/*.exe $(CFG_VAR)/*.ilk $(CFG_VAR)/*.lib $(CFG_VAR)/*.obj $(CFG_VAR)/*.pdb)
|
||||
|
||||
.PHONY: inform clean
|
0
vendor/pixman/NEWS
vendored
Normal file
0
vendor/pixman/NEWS
vendored
Normal file
140
vendor/pixman/README
vendored
Normal file
140
vendor/pixman/README
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
Pixman
|
||||
======
|
||||
|
||||
Pixman is a library that provides low-level pixel manipulation
|
||||
features such as image compositing and trapezoid rasterization.
|
||||
|
||||
Questions should be directed to the pixman mailing list:
|
||||
|
||||
https://lists.freedesktop.org/mailman/listinfo/pixman
|
||||
|
||||
You can also file bugs at
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman/-/issues/new
|
||||
|
||||
or submit improvements in form of a Merge Request via
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests
|
||||
|
||||
For real time discussions about pixman, feel free to join the IRC
|
||||
channels #cairo and #xorg-devel on the FreeNode IRC network.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
In order to contribute to pixman, you will need a working knowledge of
|
||||
the git version control system. For a quick getting started guide,
|
||||
there is the "Everyday Git With 20 Commands Or So guide"
|
||||
|
||||
https://www.kernel.org/pub/software/scm/git/docs/everyday.html
|
||||
|
||||
from the Git homepage. For more in depth git documentation, see the
|
||||
resources on the Git community documentation page:
|
||||
|
||||
https://git-scm.com/documentation
|
||||
|
||||
Pixman uses the infrastructure from the freedesktop.org umbrella
|
||||
project. For instructions about how to use the git service on
|
||||
freedesktop.org, see:
|
||||
|
||||
https://www.freedesktop.org/wiki/Infrastructure/git/Developers
|
||||
|
||||
The Pixman master repository can be found at:
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman
|
||||
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
|
||||
Patches should be submitted in form of Merge Requests via Gitlab.
|
||||
|
||||
You will first need to create a fork of the main pixman repository at
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman
|
||||
|
||||
via the Fork button on the top right. Once that is done you can add your
|
||||
personal repository as a remote to your local pixman development git checkout:
|
||||
|
||||
git remote add my-gitlab git@gitlab.freedesktop.org:YOURUSERNAME/pixman.git
|
||||
|
||||
git fetch my-gitlab
|
||||
|
||||
Make sure to have added ssh keys to your gitlab profile at
|
||||
|
||||
https://gitlab.freedesktop.org/profile/keys
|
||||
|
||||
Once that is set up, the general workflow for sending patches is to create a
|
||||
new local branch with your improvements and once it's ready push it to your
|
||||
personal pixman fork:
|
||||
|
||||
git checkout -b fix-some-bug
|
||||
...
|
||||
git push my-gitlab
|
||||
|
||||
The output of the `git push` command will include a link that allows you to
|
||||
create a Merge Request against the official pixman repository.
|
||||
|
||||
Whenever you make changes to your branch (add new commits or fix up commits)
|
||||
you push them back to your personal pixman fork:
|
||||
|
||||
git push -f my-gitlab
|
||||
|
||||
If there is an open Merge Request Gitlab will automatically pick up the
|
||||
changes from your branch and pixman developers can review them anew.
|
||||
|
||||
In order for your patches to be accepted, please consider the
|
||||
following guidelines:
|
||||
|
||||
- At each point in the series, pixman should compile and the test
|
||||
suite should pass.
|
||||
|
||||
The exception here is if you are changing the test suite to
|
||||
demonstrate a bug. In this case, make one commit that makes the
|
||||
test suite fail due to the bug, and then another commit that fixes
|
||||
the bug.
|
||||
|
||||
You can run the test suite with
|
||||
|
||||
make check
|
||||
|
||||
if you built pixman with autotools or
|
||||
|
||||
meson test -C builddir
|
||||
|
||||
if you built pixman with meson.
|
||||
|
||||
It will take around two minutes to run on a modern PC.
|
||||
|
||||
- Follow the coding style described in the CODING_STYLE file
|
||||
|
||||
- For bug fixes, include an update to the test suite to make sure
|
||||
the bug doesn't reappear.
|
||||
|
||||
- For new features, add tests of the feature to the test
|
||||
suite. Also, add a program demonstrating the new feature to the
|
||||
demos/ directory.
|
||||
|
||||
- Write descriptive commit messages. Useful information to include:
|
||||
- Benchmark results, before and after
|
||||
- Description of the bug that was fixed
|
||||
- Detailed rationale for any new API
|
||||
- Alternative approaches that were rejected (and why they
|
||||
don't work)
|
||||
- If review comments were incorporated, a brief version
|
||||
history describing what those changes were.
|
||||
|
||||
- For big patch series, write an introductory post with an overall
|
||||
description of the patch series, including benchmarks and
|
||||
motivation. Each commit message should still be descriptive and
|
||||
include enough information to understand why this particular commit
|
||||
was necessary.
|
||||
|
||||
Pixman has high standards for code quality and so almost everybody
|
||||
should expect to have the first versions of their patches rejected.
|
||||
|
||||
If you think that the reviewers are wrong about something, or that the
|
||||
guidelines above are wrong, feel free to discuss the issue. The purpose
|
||||
of the guidelines and code review is to ensure high code quality; it is
|
||||
not an exercise in compliance.
|
59
vendor/pixman/RELEASING
vendored
Normal file
59
vendor/pixman/RELEASING
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
Here are the steps to follow to create a new pixman release:
|
||||
|
||||
1) Ensure that there are no uncommitted changes or unpushed commits,
|
||||
and that you are up to date with the latest commits in the central
|
||||
repository. Here are a couple of useful commands:
|
||||
|
||||
git diff (no output)
|
||||
|
||||
git status (should report "nothing to commit")
|
||||
|
||||
git log master...origin (no output; note: *3* dots)
|
||||
|
||||
2) Increment pixman_(major|minor|micro) in configure.ac and meson.build
|
||||
according to the directions in those files.
|
||||
|
||||
3) Make sure that new version works, including
|
||||
|
||||
- make distcheck passes
|
||||
|
||||
- the X server still works with the new pixman version
|
||||
installed
|
||||
|
||||
- the cairo test suite hasn't gained any new failures compared
|
||||
to last pixman version.
|
||||
|
||||
4) Use "git commit" to record the changes made in step 2 and 3.
|
||||
|
||||
5) Generate and publish the tar files by running
|
||||
|
||||
make PREV=<last version> GPGKEY=<your gpg key id> release-publish
|
||||
|
||||
If your freedesktop user name is different from your local one,
|
||||
then also set the variable USER to your freedesktop user name.
|
||||
|
||||
6) Run
|
||||
|
||||
make release-publish-message
|
||||
|
||||
to generate a draft release announcement. Edit it as appropriate and
|
||||
send it to
|
||||
|
||||
cairo-announce@cairographics.org
|
||||
|
||||
pixman@lists.freedesktop.org
|
||||
|
||||
xorg-announce@lists.freedesktop.org
|
||||
|
||||
7) Increment pixman_micro to the next larger (odd) number in
|
||||
configure.ac. Commit this change, and push all commits created
|
||||
during this process using
|
||||
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
You must use "--tags" here; otherwise the new tag will not
|
||||
be pushed out.
|
||||
|
||||
8) Change the topic of the #cairo IRC channel on freenode to advertise
|
||||
the new version.
|
5
vendor/pixman/a64-neon-test.S
vendored
Normal file
5
vendor/pixman/a64-neon-test.S
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.text
|
||||
.arch armv8-a
|
||||
.altmacro
|
||||
prfm pldl2strm, [x0]
|
||||
xtn v0.8b, v0.8h
|
10
vendor/pixman/arm-simd-test.S
vendored
Normal file
10
vendor/pixman/arm-simd-test.S
vendored
Normal file
@ -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
|
14
vendor/pixman/autogen.sh
vendored
Executable file
14
vendor/pixman/autogen.sh
vendored
Executable file
@ -0,0 +1,14 @@
|
||||
#! /bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
|
||||
autoreconf -v --install || exit 1
|
||||
cd $ORIGDIR || exit $?
|
||||
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
$srcdir/configure "$@"
|
||||
fi
|
1199
vendor/pixman/configure.ac
vendored
Normal file
1199
vendor/pixman/configure.ac
vendored
Normal file
File diff suppressed because it is too large
Load Diff
581
vendor/pixman/meson.build
vendored
Normal file
581
vendor/pixman/meson.build
vendored
Normal file
@ -0,0 +1,581 @@
|
||||
# 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.42.3',
|
||||
license : 'MIT',
|
||||
meson_version : '>= 0.52.0',
|
||||
default_options : ['c_std=gnu99', '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',
|
||||
'-Wundef',
|
||||
# -ftrapping-math is the default for gcc, but -fno-trapping-math is the
|
||||
# default for clang. The FLOAT_IS_ZERO macro is used to guard against
|
||||
# floating-point exceptions, however with -fno-trapping-math, the compiler
|
||||
# can reorder floating-point operations so that they occur before the guard.
|
||||
# Note, this function is ignored in clang < 10.0.0.
|
||||
'-ftrapping-math'
|
||||
]),
|
||||
language : ['c']
|
||||
)
|
||||
|
||||
# GCC and Clang both ignore -Wno options that they don't recognize, so test for
|
||||
# -W<opt>, then add -Wno-<opt> 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 = ['-mloongson-mmi']
|
||||
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 = []
|
||||
|
||||
if cc.get_id() == 'msvc'
|
||||
mmx_flags = ['/w14710', '/w14714', '/wd4244']
|
||||
elif cc.get_id() == 'sun'
|
||||
mmx_flags = ['-xarch=sse']
|
||||
else
|
||||
mmx_flags = ['-mmmx', '-Winline']
|
||||
endif
|
||||
if not use_mmx.disabled()
|
||||
if host_machine.cpu_family() == 'x86_64' or cc.get_id() == 'msvc'
|
||||
have_mmx = true
|
||||
elif host_machine.cpu_family() == 'x86' and cc.compiles('''
|
||||
#include <mmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Check support for block expressions */
|
||||
#define _mm_shuffle_pi16(A, N) \
|
||||
({ \
|
||||
__m64 ret; \
|
||||
\
|
||||
/* Some versions of clang will choke on K */ \
|
||||
asm ("pshufw %2, %1, %0\n\t" \
|
||||
: "=y" (ret) \
|
||||
: "y" (A), "K" ((const int8_t)N) \
|
||||
); \
|
||||
\
|
||||
ret; \
|
||||
})
|
||||
|
||||
int main () {
|
||||
__m64 v = _mm_cvtsi32_si64 (1);
|
||||
__m64 w;
|
||||
|
||||
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
|
||||
# Inline assembly do not work on X64 MSVC, so we use
|
||||
# compatibility intrinsics there
|
||||
if cc.get_id() != 'msvc' or host_machine.cpu_family() != 'x86_64'
|
||||
config.set10('USE_X86_MMX', true)
|
||||
endif
|
||||
elif use_mmx.enabled()
|
||||
error('MMX Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_sse2 = get_option('sse2')
|
||||
have_sse2 = false
|
||||
sse2_flags = []
|
||||
if cc.get_id() == 'sun'
|
||||
sse2_flags = ['-xarch=sse2']
|
||||
elif cc.get_id() != 'msvc'
|
||||
sse2_flags = ['-msse2', '-Winline']
|
||||
endif
|
||||
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 <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
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 = []
|
||||
if cc.get_id() != 'msvc'
|
||||
ssse3_flags = ['-mssse3', '-Winline']
|
||||
endif
|
||||
|
||||
# x64 pre-2010 MSVC compilers crashes when building the ssse3 code
|
||||
if not use_ssse3.disabled() and not (cc.get_id() == 'msvc' and cc.version().version_compare('<16') and host_machine.cpu_family() == 'x86_64')
|
||||
if host_machine.cpu_family().startswith('x86')
|
||||
if cc.compiles('''
|
||||
#include <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
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 <altivec.h>
|
||||
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_a64neon = get_option('a64-neon')
|
||||
have_a64neon = false
|
||||
if not use_a64neon.disabled()
|
||||
if host_machine.cpu_family() == 'aarch64'
|
||||
if cc.compiles(files('a64-neon-test.S'), name : 'NEON A64 Intrinsic Support')
|
||||
have_a64neon = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_a64neon
|
||||
config.set10('USE_ARM_A64_NEON', true)
|
||||
elif use_a64neon.enabled()
|
||||
error('A64 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 <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_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
|
||||
|
||||
if cc.get_id() != 'msvc'
|
||||
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
|
||||
else
|
||||
# the MSVC implementation of openmp is not compliant enough for our
|
||||
# uses here, so we disable it here.
|
||||
# Please see: https://stackoverflow.com/questions/12560243/using-threadprivate-directive-in-visual-studio
|
||||
dep_openmp = null_dep
|
||||
endif
|
||||
|
||||
dep_gtk = dependency('gtk+-3.0', required : get_option('gtk'), required: get_option('demos'))
|
||||
dep_glib = dependency('glib-2.0', required : get_option('gtk'), required: get_option('demos'))
|
||||
|
||||
dep_png = null_dep
|
||||
if not get_option('libpng').disabled()
|
||||
dep_png = dependency('libpng', required : false)
|
||||
|
||||
# We need to look for the right library to link to for libpng,
|
||||
# when looking for libpng manually
|
||||
foreach png_ver : [ '16', '15', '14', '13', '12', '10' ]
|
||||
if not dep_png.found()
|
||||
dep_png = cc.find_library('libpng@0@'.format(png_ver), has_headers : ['png.h'], required : false)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if get_option('libpng').enabled() and not dep_png.found()
|
||||
error('libpng support requested but libpng library not found')
|
||||
endif
|
||||
endif
|
||||
|
||||
if dep_png.found()
|
||||
config.set('HAVE_LIBPNG', 1)
|
||||
endif
|
||||
dep_m = cc.find_library('m', required : false)
|
||||
dep_threads = dependency('threads')
|
||||
|
||||
# MSVC-style compilers do not come with pthreads, so we must link
|
||||
# to it explicitly, currently pthreads-win32 is supported
|
||||
pthreads_found = false
|
||||
|
||||
if dep_threads.found() and cc.has_header('pthread.h')
|
||||
if cc.get_argument_syntax() == 'msvc'
|
||||
pthread_lib = null_dep
|
||||
foreach pthread_type : ['VC3', 'VSE3', 'VCE3', 'VC2', 'VSE2', 'VCE2']
|
||||
if not pthread_lib.found()
|
||||
pthread_lib = cc.find_library('pthread@0@'.format(pthread_type), required : false)
|
||||
endif
|
||||
endforeach
|
||||
if pthread_lib.found()
|
||||
pthreads_found = true
|
||||
dep_threads = pthread_lib
|
||||
endif
|
||||
else
|
||||
pthreads_found = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if pthreads_found
|
||||
config.set('HAVE_PTHREADS', 1)
|
||||
endif
|
||||
|
||||
funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap', 'getisax', 'gettimeofday']
|
||||
# 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
|
||||
|
||||
# This is only used in one test, that defines _GNU_SOURCE
|
||||
if cc.has_function('feenableexcept',
|
||||
prefix : '#define _GNU_SOURCE\n#include <fenv.h>',
|
||||
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
|
||||
|
||||
use_tls = get_option('tls')
|
||||
have_tls = ''
|
||||
if not use_tls.disabled()
|
||||
# gcc on Windows only warns that __declspec(thread) isn't supported,
|
||||
# passing -Werror=attributes makes it fail.
|
||||
if (host_machine.system() == 'windows' and
|
||||
cc.compiles('int __declspec(thread) foo;',
|
||||
args : cc.get_supported_arguments(['-Werror=attributes']),
|
||||
name : 'TLS via __declspec(thread)'))
|
||||
have_tls = '__declspec(thread)'
|
||||
elif cc.compiles('int __thread foo;', name : 'TLS via __thread')
|
||||
have_tls = '__thread'
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_tls != ''
|
||||
config.set('TLS', have_tls)
|
||||
elif use_tls.enabled()
|
||||
error('Compiler TLS Support unavailable, but required')
|
||||
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
|
||||
|
||||
config.set('SIZEOF_LONG', cc.sizeof('long'))
|
||||
|
||||
# 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')
|
||||
|
||||
if not get_option('tests').disabled() or not get_option('demos').disabled()
|
||||
subdir(join_paths('test', 'utils'))
|
||||
endif
|
||||
|
||||
if not get_option('demos').disabled()
|
||||
subdir('demos')
|
||||
endif
|
||||
|
||||
if not get_option('tests').disabled()
|
||||
subdir('test')
|
||||
endif
|
||||
|
||||
pkg = import('pkgconfig')
|
||||
pkg.generate(libpixman,
|
||||
name : 'Pixman',
|
||||
filebase : 'pixman-1',
|
||||
description : 'The pixman library (version 1)',
|
||||
subdirs: 'pixman-1',
|
||||
version : meson.project_version(),
|
||||
)
|
128
vendor/pixman/meson_options.txt
vendored
Normal file
128
vendor/pixman/meson_options.txt
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
# 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(
|
||||
'a64-neon',
|
||||
type : 'feature',
|
||||
description : 'Use ARM A64 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(
|
||||
'tls',
|
||||
type : 'feature',
|
||||
description : 'Use compiler support for thread-local storage',
|
||||
)
|
||||
option(
|
||||
'cpu-features-path',
|
||||
type : 'string',
|
||||
description : 'Path to platform-specific cpu-features.[ch] for systems that do not provide it (e.g. Android)',
|
||||
)
|
||||
option(
|
||||
'openmp',
|
||||
type : 'feature',
|
||||
description : 'Enable OpenMP for tests',
|
||||
)
|
||||
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 demos using GTK',
|
||||
)
|
||||
option(
|
||||
'libpng',
|
||||
type : 'feature',
|
||||
description : 'Use libpng in tests'
|
||||
)
|
||||
option(
|
||||
'tests',
|
||||
type : 'feature',
|
||||
description : 'Build tests'
|
||||
)
|
||||
option(
|
||||
'demos',
|
||||
type : 'feature',
|
||||
description : 'Build demos'
|
||||
)
|
12
vendor/pixman/neon-test.S
vendored
Normal file
12
vendor/pixman/neon-test.S
vendored
Normal file
@ -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
|
5
vendor/pixman/pixman-1-uninstalled.pc.in
vendored
Normal file
5
vendor/pixman/pixman-1-uninstalled.pc.in
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
Name: Pixman
|
||||
Description: The pixman library (version 1)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${pc_top_builddir}/${pcfiledir}/pixman
|
||||
Libs: ${pc_top_builddir}/${pcfiledir}/pixman/libpixman-1.la
|
11
vendor/pixman/pixman-1.pc.in
vendored
Normal file
11
vendor/pixman/pixman-1.pc.in
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Pixman
|
||||
Description: The pixman library (version 1)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${includedir}/pixman-1
|
||||
Libs: -L${libdir} -lpixman-1
|
||||
|
158
vendor/pixman/pixman/Makefile.am
vendored
Normal file
158
vendor/pixman/pixman/Makefile.am
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
include $(top_srcdir)/pixman/Makefile.sources
|
||||
|
||||
lib_LTLIBRARIES = libpixman-1.la
|
||||
|
||||
libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@
|
||||
libpixman_1_la_LIBADD = @PTHREAD_LIBS@ -lm
|
||||
libpixman_1_la_SOURCES = $(libpixman_sources) $(libpixman_headers)
|
||||
|
||||
libpixmanincludedir = $(includedir)/pixman-1
|
||||
libpixmaninclude_HEADERS = pixman.h pixman-version.h
|
||||
noinst_LTLIBRARIES =
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win32 \
|
||||
dither/make-blue-noise.c \
|
||||
pixman-region.c \
|
||||
solaris-hwcap.mapfile \
|
||||
meson.build \
|
||||
$(NULL)
|
||||
|
||||
# mmx code
|
||||
if USE_X86_MMX
|
||||
noinst_LTLIBRARIES += libpixman-mmx.la
|
||||
libpixman_mmx_la_SOURCES = \
|
||||
pixman-mmx.c
|
||||
libpixman_mmx_la_CFLAGS = $(MMX_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(MMX_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-mmx.la
|
||||
|
||||
ASM_CFLAGS_mmx=$(MMX_CFLAGS)
|
||||
endif
|
||||
|
||||
# vmx code
|
||||
if USE_VMX
|
||||
noinst_LTLIBRARIES += libpixman-vmx.la
|
||||
libpixman_vmx_la_SOURCES = \
|
||||
pixman-vmx.c \
|
||||
pixman-combine32.h
|
||||
libpixman_vmx_la_CFLAGS = $(VMX_CFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-vmx.la
|
||||
|
||||
ASM_CFLAGS_vmx=$(VMX_CFLAGS)
|
||||
endif
|
||||
|
||||
# sse2 code
|
||||
if USE_SSE2
|
||||
noinst_LTLIBRARIES += libpixman-sse2.la
|
||||
libpixman_sse2_la_SOURCES = \
|
||||
pixman-sse2.c
|
||||
libpixman_sse2_la_CFLAGS = $(SSE2_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(SSE2_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-sse2.la
|
||||
|
||||
ASM_CFLAGS_sse2=$(SSE2_CFLAGS)
|
||||
endif
|
||||
|
||||
# ssse3 code
|
||||
if USE_SSSE3
|
||||
noinst_LTLIBRARIES += libpixman-ssse3.la
|
||||
libpixman_ssse3_la_SOURCES = \
|
||||
pixman-ssse3.c
|
||||
libpixman_ssse3_la_CFLAGS = $(SSSE3_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(SSSE3_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-ssse3.la
|
||||
|
||||
ASM_CFLAGS_ssse3=$(SSSE3_CFLAGS)
|
||||
endif
|
||||
|
||||
# arm simd code
|
||||
if USE_ARM_SIMD
|
||||
noinst_LTLIBRARIES += libpixman-arm-simd.la
|
||||
libpixman_arm_simd_la_SOURCES = \
|
||||
pixman-arm-simd.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arm-simd-asm.S \
|
||||
pixman-arm-simd-asm-scaled.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arm-simd-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arm-simd.la
|
||||
|
||||
ASM_CFLAGS_arm_simd=
|
||||
endif
|
||||
|
||||
# arm neon code
|
||||
if USE_ARM_NEON
|
||||
noinst_LTLIBRARIES += libpixman-arm-neon.la
|
||||
libpixman_arm_neon_la_SOURCES = \
|
||||
pixman-arm-neon.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arm-neon-asm.S \
|
||||
pixman-arm-neon-asm-bilinear.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arm-neon-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arm-neon.la
|
||||
|
||||
ASM_CFLAGS_arm_neon=
|
||||
endif
|
||||
|
||||
# arm a64 neon code
|
||||
if USE_ARM_A64_NEON
|
||||
noinst_LTLIBRARIES += libpixman-arma64-neon.la
|
||||
libpixman_arma64_neon_la_SOURCES = \
|
||||
pixman-arm-neon.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arma64-neon-asm.S \
|
||||
pixman-arma64-neon-asm-bilinear.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arma64-neon-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arma64-neon.la
|
||||
|
||||
ASM_CFLAGS_arm_neon=
|
||||
endif
|
||||
|
||||
# iwmmxt code
|
||||
if USE_ARM_IWMMXT
|
||||
libpixman_iwmmxt_la_SOURCES = pixman-mmx.c
|
||||
noinst_LTLIBRARIES += libpixman-iwmmxt.la
|
||||
libpixman_1_la_LIBADD += libpixman-iwmmxt.la
|
||||
|
||||
libpixman_iwmmxt_la-pixman-mmx.lo: pixman-mmx.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(IWMMXT_CFLAGS) -MT libpixman_iwmmxt_la-pixman-mmx.lo -MD -MP -MF $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo -c -o libpixman_iwmmxt_la-pixman-mmx.lo `test -f 'pixman-mmx.c' || echo '$(srcdir)/'`pixman-mmx.c
|
||||
$(AM_V_at)$(am__mv) $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Plo
|
||||
|
||||
libpixman_iwmmxt_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
|
||||
libpixman_iwmmxt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
||||
$(CFLAGS) $(IWMMXT_CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
|
||||
libpixman-iwmmxt.la: libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpixman_iwmmxt_la_LINK) libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_LIBADD) $(LIBS)
|
||||
endif
|
||||
|
||||
# mips dspr2 code
|
||||
if USE_MIPS_DSPR2
|
||||
noinst_LTLIBRARIES += libpixman-mips-dspr2.la
|
||||
libpixman_mips_dspr2_la_SOURCES = \
|
||||
pixman-mips-dspr2.c \
|
||||
pixman-mips-dspr2.h \
|
||||
pixman-mips-dspr2-asm.S \
|
||||
pixman-mips-dspr2-asm.h \
|
||||
pixman-mips-memcpy-asm.S
|
||||
libpixman_1_la_LIBADD += libpixman-mips-dspr2.la
|
||||
|
||||
ASM_CFLAGS_mips_dspr2=
|
||||
endif
|
||||
|
||||
# loongson code
|
||||
if USE_LOONGSON_MMI
|
||||
noinst_LTLIBRARIES += libpixman-loongson-mmi.la
|
||||
libpixman_loongson_mmi_la_SOURCES = pixman-mmx.c loongson-mmintrin.h
|
||||
libpixman_loongson_mmi_la_CFLAGS = $(LS_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(LS_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-loongson-mmi.la
|
||||
endif
|
||||
|
||||
.c.s : $(libpixmaninclude_HEADERS)
|
||||
$(CC) $(CFLAGS) $(ASM_CFLAGS_$(@:pixman-%.s=%)) $(ASM_CFLAGS_$(@:pixman-arm-%.s=arm_%)) -DHAVE_CONFIG_H -I$(srcdir) -I$(builddir) -I$(top_builddir) -S -o $@ $<
|
43
vendor/pixman/pixman/Makefile.sources
vendored
Normal file
43
vendor/pixman/pixman/Makefile.sources
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
libpixman_sources = \
|
||||
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 \
|
||||
$(NULL)
|
||||
|
||||
libpixman_headers = \
|
||||
dither/blue-noise-64x64.h \
|
||||
pixman.h \
|
||||
pixman-accessor.h \
|
||||
pixman-combine32.h \
|
||||
pixman-compiler.h \
|
||||
pixman-edge-imp.h \
|
||||
pixman-inlines.h \
|
||||
pixman-private.h \
|
||||
$(NULL)
|
93
vendor/pixman/pixman/Makefile.win32
vendored
Normal file
93
vendor/pixman/pixman/Makefile.win32
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
default: all
|
||||
|
||||
top_srcdir = ..
|
||||
include $(top_srcdir)/pixman/Makefile.sources
|
||||
include $(top_srcdir)/Makefile.win32.common
|
||||
|
||||
MMX_VAR = $(MMX)
|
||||
ifeq ($(MMX_VAR),)
|
||||
MMX_VAR=on
|
||||
endif
|
||||
|
||||
SSE2_VAR = $(SSE2)
|
||||
ifeq ($(SSE2_VAR),)
|
||||
SSE2_VAR=on
|
||||
endif
|
||||
|
||||
SSSE3_VAR = $(SSSE3)
|
||||
ifeq ($(SSSE3_VAR),)
|
||||
SSSE3_VAR=on
|
||||
endif
|
||||
|
||||
MMX_CFLAGS = -DUSE_X86_MMX -w14710 -w14714
|
||||
SSE2_CFLAGS = -DUSE_SSE2
|
||||
SSSE3_CFLAGS = -DUSE_SSSE3
|
||||
|
||||
# MMX compilation flags
|
||||
ifeq ($(MMX_VAR),on)
|
||||
PIXMAN_CFLAGS += $(MMX_CFLAGS)
|
||||
libpixman_sources += pixman-mmx.c
|
||||
endif
|
||||
|
||||
# SSE2 compilation flags
|
||||
ifeq ($(SSE2_VAR),on)
|
||||
PIXMAN_CFLAGS += $(SSE2_CFLAGS)
|
||||
libpixman_sources += pixman-sse2.c
|
||||
endif
|
||||
|
||||
# SSSE3 compilation flags
|
||||
ifeq ($(SSSE3_VAR),on)
|
||||
PIXMAN_CFLAGS += $(SSSE3_CFLAGS)
|
||||
libpixman_sources += pixman-ssse3.c
|
||||
endif
|
||||
|
||||
OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources))
|
||||
|
||||
# targets
|
||||
all: inform informMMX informSSE2 informSSSE3 $(CFG_VAR)/$(LIBRARY).lib
|
||||
|
||||
informMMX:
|
||||
ifneq ($(MMX),off)
|
||||
ifneq ($(MMX),on)
|
||||
ifneq ($(MMX),)
|
||||
@echo "Invalid specified MMX option : "$(MMX_VAR)"."
|
||||
@echo
|
||||
@echo "Possible choices for MMX are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting MMX flag to default value 'on'... (use MMX=on or MMX=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
informSSE2:
|
||||
ifneq ($(SSE2),off)
|
||||
ifneq ($(SSE2),on)
|
||||
ifneq ($(SSE2),)
|
||||
@echo "Invalid specified SSE option : "$(SSE2)"."
|
||||
@echo
|
||||
@echo "Possible choices for SSE2 are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting SSE2 flag to default value 'on'... (use SSE2=on or SSE2=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
informSSSE3:
|
||||
ifneq ($(SSSE3),off)
|
||||
ifneq ($(SSSE3),on)
|
||||
ifneq ($(SSSE3),)
|
||||
@echo "Invalid specified SSE option : "$(SSSE3)"."
|
||||
@echo
|
||||
@echo "Possible choices for SSSE3 are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting SSSE3 flag to default value 'on'... (use SSSE3=on or SSSE3=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# pixman linking
|
||||
$(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS)
|
||||
@$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^
|
||||
|
||||
.PHONY: all informMMX informSSE2 informSSSE3
|
77
vendor/pixman/pixman/dither/blue-noise-64x64.h
vendored
Normal file
77
vendor/pixman/pixman/dither/blue-noise-64x64.h
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/* WARNING: This file is generated by make-blue-noise.c
|
||||
* Please edit that file instead of this one.
|
||||
*/
|
||||
|
||||
#ifndef BLUE_NOISE_64X64_H
|
||||
#define BLUE_NOISE_64X64_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint16_t dither_blue_noise_64x64[4096] = {
|
||||
3039, 1368, 3169, 103, 2211, 1248, 2981, 668, 2633, 37, 3963, 2903, 384, 2564, 3115, 1973, 3348, 830, 2505, 1293, 3054, 1060, 1505, 3268, 400, 1341, 593, 3802, 3384, 429, 4082, 1411, 2503, 3863, 126, 1292, 1887, 2855, 205, 2094, 2977, 1899, 3924, 356, 3088, 2500, 3942, 1409, 2293, 1734, 3732, 1291, 3227, 277, 2054, 786, 2871, 411, 2425, 1678, 3986, 455, 2879, 2288,
|
||||
388, 1972, 3851, 778, 2768, 3697, 944, 2123, 1501, 3533, 937, 1713, 1381, 3888, 156, 1242, 516, 2888, 1607, 3676, 632, 2397, 3804, 2673, 1898, 3534, 2593, 1777, 1170, 2299, 3013, 1838, 523, 3053, 1647, 3601, 3197, 959, 1520, 3633, 893, 2437, 3367, 2187, 1258, 137, 1965, 401, 3546, 643, 3087, 2498, 733, 2786, 3371, 4053, 1266, 1977, 3663, 183, 2570, 2107, 1183, 3708,
|
||||
907, 2473, 1151, 3363, 1527, 1902, 232, 3903, 3060, 496, 2486, 3206, 2165, 861, 2387, 3653, 2101, 3972, 132, 2162, 3437, 1827, 215, 895, 3114, 271, 969, 2932, 197, 1598, 878, 3696, 1140, 2120, 904, 2431, 302, 3846, 2675, 481, 3187, 66, 1440, 650, 3833, 2826, 3435, 901, 2936, 2111, 250, 1875, 3609, 1174, 1747, 162, 2346, 3420, 913, 3172, 1383, 752, 3298, 1735,
|
||||
3540, 2938, 249, 2324, 526, 3099, 2561, 1324, 2347, 1861, 1200, 3702, 257, 3442, 1514, 2999, 992, 1766, 2735, 1163, 478, 2943, 1279, 3635, 2177, 1464, 3672, 2386, 3871, 3340, 2690, 64, 3489, 2811, 3999, 633, 1948, 1243, 2269, 1807, 1143, 2750, 3729, 1790, 2363, 1053, 1537, 2636, 4065, 1076, 1476, 3869, 450, 2200, 2676, 658, 2979, 1548, 544, 1913, 2838, 3911, 116, 2698,
|
||||
517, 1295, 3997, 1739, 3665, 1083, 3509, 599, 3400, 118, 2956, 720, 2689, 1907, 567, 2523, 284, 3397, 711, 3219, 2450, 3985, 1665, 2549, 562, 3011, 1855, 729, 1355, 528, 1908, 2456, 1384, 337, 1540, 2654, 3138, 3513, 703, 4080, 3314, 2047, 855, 3037, 209, 3317, 577, 1828, 17, 2336, 3193, 2748, 962, 3441, 1450, 3246, 1075, 3878, 2615, 3497, 1033, 2310, 1442, 2183,
|
||||
1654, 3254, 2061, 738, 2832, 148, 2030, 1670, 909, 3850, 2109, 1533, 4046, 1085, 3098, 3897, 1378, 2248, 3829, 1495, 1966, 23, 797, 3427, 1124, 4057, 95, 2787, 2190, 3074, 3950, 742, 3194, 1999, 3386, 1113, 16, 1657, 2804, 201, 1543, 383, 2559, 1325, 3604, 2068, 2493, 3771, 1284, 3460, 710, 1716, 2447, 80, 3811, 2032, 347, 2227, 15, 1689, 397, 3084, 662, 3798,
|
||||
973, 43, 2608, 3143, 1459, 2423, 4066, 2770, 3191, 1283, 2630, 314, 3235, 2289, 72, 1822, 2840, 924, 350, 2653, 1057, 3715, 2235, 2775, 346, 2083, 1553, 3292, 1081, 274, 1686, 1188, 2327, 3743, 578, 2234, 3916, 2519, 1011, 3056, 2207, 3438, 3890, 537, 1617, 837, 3094, 373, 2795, 1980, 276, 3951, 1353, 3015, 844, 1724, 3651, 2923, 1316, 4092, 2504, 3627, 1936, 2854,
|
||||
2461, 3929, 1193, 421, 3746, 820, 1180, 286, 2261, 532, 3625, 1812, 802, 1327, 3527, 670, 3730, 2025, 3124, 3565, 529, 2960, 1769, 1390, 3196, 2494, 3756, 796, 3618, 2602, 3463, 2847, 166, 953, 1745, 2900, 438, 2070, 1418, 3741, 639, 1205, 1891, 2882, 2282, 4012, 1182, 1696, 3630, 951, 2904, 2170, 3530, 375, 2320, 2742, 1132, 701, 3216, 2023, 847, 1230, 310, 3431,
|
||||
770, 1961, 3531, 1702, 2181, 3370, 1877, 3072, 1571, 3389, 1071, 2415, 3782, 2803, 1610, 2454, 1211, 182, 1655, 2322, 1282, 3372, 287, 3935, 704, 1232, 415, 1910, 2286, 1399, 556, 1964, 4068, 2444, 3605, 1272, 3345, 816, 3526, 256, 2402, 2777, 955, 345, 3289, 111, 2727, 635, 2396, 1488, 3331, 600, 1032, 1575, 4026, 515, 3507, 2433, 1605, 460, 3364, 2783, 1810, 1397,
|
||||
2334, 223, 2945, 688, 2533, 99, 2705, 624, 3944, 2073, 46, 2978, 508, 2132, 269, 3173, 3453, 2631, 4076, 694, 1892, 2586, 972, 2178, 3470, 1695, 2849, 3141, 77, 3884, 994, 3029, 1536, 673, 3083, 124, 2583, 1722, 2821, 1944, 4027, 1661, 3176, 3728, 1337, 1813, 3503, 2035, 3930, 157, 2537, 1865, 3096, 2646, 1941, 3252, 1449, 135, 2836, 3758, 2139, 84, 3678, 3106,
|
||||
3862, 1545, 3307, 1320, 3955, 1031, 3664, 1306, 2460, 776, 1487, 3294, 1187, 3990, 1903, 1021, 549, 1484, 943, 3027, 97, 3853, 1499, 2880, 198, 2575, 3995, 1089, 1587, 2475, 3282, 339, 2657, 1158, 2105, 1493, 3943, 580, 3232, 1287, 846, 48, 2480, 2112, 771, 2534, 459, 3134, 850, 1298, 3790, 325, 3652, 1249, 193, 940, 2202, 3895, 1829, 911, 1366, 2577, 1069, 534,
|
||||
2104, 1009, 2667, 392, 1983, 2917, 1645, 324, 3439, 2869, 3705, 1767, 2592, 756, 2916, 3683, 2276, 2850, 2053, 3594, 2403, 3181, 634, 3699, 1933, 906, 519, 2150, 3673, 764, 1770, 2220, 3795, 3336, 502, 3547, 2339, 1110, 301, 2210, 3354, 3643, 569, 1518, 2940, 3973, 1138, 1613, 2773, 2127, 2983, 1671, 769, 2161, 3800, 2730, 3127, 1179, 533, 3259, 2284, 4014, 1651, 2820,
|
||||
3566, 653, 1839, 3455, 2399, 789, 3149, 2244, 1863, 1099, 474, 2307, 158, 3541, 1312, 1711, 0, 3902, 360, 1629, 1091, 395, 1781, 1191, 2374, 3353, 1419, 3225, 206, 2931, 3553, 1046, 54, 1646, 2470, 910, 1860, 3137, 3770, 2635, 1562, 2809, 1215, 3788, 222, 2199, 3335, 67, 3606, 524, 1001, 3309, 2410, 3473, 591, 1619, 291, 2502, 3629, 2891, 335, 741, 3378, 168,
|
||||
2384, 3129, 4051, 22, 1444, 3613, 543, 3893, 186, 2665, 4062, 933, 3058, 2142, 449, 2711, 3224, 849, 1330, 3349, 2195, 2670, 3484, 2993, 32, 3774, 2722, 1859, 2548, 1268, 583, 2027, 3165, 2807, 4029, 227, 2897, 1434, 721, 1816, 195, 905, 2066, 3258, 1754, 970, 2674, 1880, 2338, 3915, 1485, 2660, 14, 1313, 2914, 2046, 4074, 791, 1917, 1301, 1725, 2687, 2019, 1443,
|
||||
418, 1186, 1664, 2859, 1049, 2056, 2741, 1226, 1589, 3186, 2042, 1377, 3449, 1574, 3941, 1063, 1930, 2501, 3751, 2930, 671, 4031, 888, 2081, 1544, 684, 1117, 351, 4052, 1698, 2393, 3881, 1439, 785, 1277, 2013, 3488, 441, 2459, 3980, 3061, 3481, 2543, 419, 3020, 609, 3515, 1350, 799, 2878, 348, 2034, 3966, 1824, 950, 3281, 1394, 2239, 3452, 55, 3922, 3119, 892, 3785,
|
||||
3023, 2140, 782, 2492, 3817, 241, 3355, 2424, 856, 3639, 612, 2556, 245, 2858, 705, 2316, 3562, 495, 1748, 128, 1912, 1454, 280, 2552, 3905, 3130, 2274, 3472, 834, 3055, 240, 2692, 471, 2272, 3301, 2632, 1080, 3693, 2136, 1029, 1364, 590, 1611, 4067, 1190, 2360, 3827, 261, 3180, 1768, 3471, 1103, 3003, 520, 3674, 151, 2571, 555, 3033, 982, 2353, 504, 1259, 2555,
|
||||
149, 3889, 3380, 493, 3178, 1681, 663, 1924, 2990, 49, 1792, 3861, 1192, 1987, 3273, 297, 1457, 3043, 1177, 2292, 3249, 2829, 3682, 1154, 1758, 428, 2872, 1993, 1500, 3703, 1129, 3421, 1840, 3754, 163, 659, 1733, 3182, 38, 2875, 1957, 3614, 2237, 78, 1873, 2801, 1513, 2121, 1074, 2516, 667, 3710, 1429, 2430, 2088, 2830, 1072, 3557, 1531, 2733, 1955, 3286, 3590, 1826,
|
||||
2778, 1068, 1932, 1452, 2279, 1185, 3564, 3952, 1391, 2726, 3313, 2331, 870, 3709, 1674, 2772, 4085, 808, 2596, 3848, 927, 538, 2335, 3334, 773, 3597, 1347, 109, 2663, 608, 2108, 2994, 936, 1524, 2922, 3968, 2422, 1467, 845, 3870, 321, 2704, 1073, 3308, 3680, 823, 430, 3375, 4030, 112, 2171, 2695, 267, 3374, 731, 1627, 3919, 1871, 352, 3839, 1370, 234, 794, 1532,
|
||||
3245, 647, 3575, 74, 3045, 2766, 285, 2174, 498, 1059, 1551, 385, 3125, 2598, 143, 1128, 2095, 3395, 318, 1590, 3524, 1345, 1969, 242, 2759, 2092, 947, 3926, 3244, 2356, 1658, 6, 3593, 2554, 1172, 1995, 371, 2755, 3417, 2294, 1570, 3164, 748, 2517, 1401, 3111, 2420, 1662, 2910, 1276, 3276, 854, 1804, 4000, 1253, 2987, 229, 2344, 3184, 649, 2196, 2921, 4095, 2389,
|
||||
1289, 2193, 2579, 4023, 757, 1858, 986, 3199, 2514, 3475, 4021, 2154, 651, 1432, 3468, 2404, 574, 1799, 3105, 2145, 86, 2614, 3218, 1565, 4088, 2481, 3079, 1815, 323, 1212, 3837, 759, 2159, 435, 3223, 784, 3659, 1114, 1888, 550, 1221, 3786, 1803, 499, 2117, 185, 3763, 942, 589, 2001, 3838, 1483, 3154, 2256, 468, 2544, 3403, 898, 1208, 2610, 3622, 967, 1929, 378,
|
||||
3781, 220, 1656, 1115, 3347, 2428, 3822, 1577, 712, 1959, 110, 2765, 1762, 3854, 979, 2928, 3714, 1371, 746, 3969, 2884, 975, 3779, 641, 1142, 159, 1460, 702, 3485, 2866, 2495, 3330, 1305, 3937, 1635, 2229, 2962, 146, 4055, 3091, 2417, 100, 3508, 2933, 4006, 1167, 1920, 2760, 3552, 2545, 433, 2845, 142, 1056, 1886, 3616, 1435, 2099, 3803, 1749, 27, 1446, 3350, 2843,
|
||||
884, 3310, 2948, 2103, 447, 1351, 187, 2895, 3655, 1256, 3036, 932, 3325, 2257, 451, 1915, 40, 2780, 2438, 1112, 1814, 423, 2290, 1905, 2898, 3419, 2306, 3760, 1938, 486, 1019, 1791, 3010, 2628, 203, 3408, 1269, 2507, 1606, 862, 2779, 2078, 952, 1529, 2638, 708, 3332, 1413, 2, 1726, 1156, 3500, 2392, 3791, 3076, 812, 107, 2861, 501, 3050, 3487, 2455, 594, 1731,
|
||||
2685, 1498, 680, 3908, 2621, 3529, 1786, 2236, 342, 2569, 1526, 3722, 230, 1290, 3203, 3947, 1609, 3516, 467, 3267, 3685, 1461, 3140, 3569, 367, 1759, 928, 2754, 1332, 2219, 4034, 260, 655, 1984, 978, 3814, 617, 2086, 3525, 279, 3841, 1373, 3361, 319, 2251, 3066, 407, 2382, 3918, 3133, 2168, 762, 1523, 507, 2641, 1677, 4025, 2413, 1584, 793, 2049, 1109, 3962, 2218,
|
||||
1194, 3692, 266, 1687, 981, 3103, 740, 3983, 1005, 3434, 570, 2383, 1942, 2718, 676, 2462, 1007, 2089, 1308, 2222, 233, 2568, 829, 1241, 2669, 3987, 514, 3303, 69, 3142, 1603, 3560, 2295, 3288, 1497, 2696, 1764, 2865, 1058, 3271, 1914, 477, 2529, 3927, 1736, 1273, 3752, 2029, 1012, 565, 2798, 4078, 1949, 3305, 1175, 2179, 380, 3366, 1195, 3849, 2637, 416, 2959, 125,
|
||||
3396, 2467, 2036, 3234, 2340, 68, 2819, 1436, 2011, 3139, 1704, 4073, 860, 3582, 1468, 2969, 211, 3157, 4056, 866, 2935, 2000, 3923, 31, 2157, 1477, 2429, 1147, 3792, 2557, 774, 2802, 1153, 3747, 464, 3192, 42, 3904, 539, 1474, 2283, 803, 2876, 1061, 75, 3477, 747, 2893, 1538, 3626, 251, 1322, 2506, 189, 2791, 3667, 939, 2991, 1971, 175, 3195, 1416, 3648, 1857,
|
||||
3052, 454, 851, 3789, 1271, 1906, 3694, 2484, 406, 2757, 26, 1189, 2909, 296, 2215, 3784, 1864, 637, 2715, 1673, 3445, 581, 1572, 3059, 3469, 761, 2984, 1737, 2058, 440, 1414, 1921, 121, 2527, 894, 2223, 1302, 2377, 3077, 2666, 3759, 3198, 1811, 3661, 2166, 2731, 1883, 359, 3285, 2458, 1805, 3459, 926, 3834, 675, 1893, 1496, 2612, 657, 3523, 1763, 2354, 564, 961,
|
||||
1367, 3977, 1588, 2714, 322, 3446, 1088, 625, 3887, 1354, 3535, 2090, 3316, 1760, 1127, 483, 3491, 1421, 2301, 94, 1202, 3740, 2311, 1014, 1878, 3836, 180, 3412, 991, 2868, 3953, 3450, 3081, 1632, 4071, 1882, 3543, 726, 1719, 179, 1171, 364, 1420, 622, 3090, 1490, 946, 4007, 2212, 1102, 619, 2739, 2189, 1669, 2937, 3426, 39, 3940, 2191, 1264, 887, 4091, 2792, 2135,
|
||||
4, 2883, 2281, 631, 3044, 1641, 2232, 3243, 1773, 2319, 827, 2591, 629, 3938, 2426, 3222, 2629, 1044, 3879, 3293, 1952, 2749, 275, 2590, 472, 1372, 2496, 660, 3669, 2264, 208, 915, 2167, 561, 2828, 307, 3265, 1104, 3964, 2155, 3425, 1951, 4077, 2391, 283, 3387, 2581, 115, 1415, 3069, 3896, 141, 3158, 1214, 442, 2405, 1349, 3085, 425, 2528, 3002, 312, 1602, 3588,
|
||||
1137, 3323, 1963, 1002, 3578, 2521, 127, 925, 2970, 273, 3737, 1573, 167, 2863, 1509, 800, 147, 2059, 2942, 409, 921, 3151, 1451, 3909, 3333, 2844, 2096, 1512, 3136, 1210, 1798, 2709, 1331, 3586, 1034, 1521, 2441, 2926, 488, 2585, 775, 3031, 2693, 879, 3602, 1173, 2028, 3654, 2781, 841, 1975, 1507, 3646, 768, 3991, 2012, 996, 3544, 1666, 3810, 1990, 3360, 753, 2597,
|
||||
3736, 304, 1473, 3828, 485, 1334, 4008, 2072, 3495, 1136, 2806, 2004, 3236, 1010, 2130, 3819, 1750, 3567, 644, 2515, 1794, 3636, 698, 2137, 1162, 832, 3761, 326, 2613, 513, 3302, 3820, 357, 3163, 2259, 3733, 101, 1922, 1386, 3587, 1640, 28, 1286, 2141, 1761, 2918, 693, 1639, 457, 3250, 2434, 365, 2599, 1729, 3284, 2643, 306, 2793, 689, 1090, 104, 1309, 2305, 1831,
|
||||
2776, 859, 2446, 2915, 1778, 3337, 2677, 614, 1508, 2409, 469, 4033, 1321, 3563, 402, 3131, 2720, 1093, 1569, 4042, 1229, 2277, 216, 3046, 1817, 57, 3006, 1684, 4059, 2016, 795, 2440, 1652, 1960, 610, 2763, 920, 3864, 3110, 1026, 2326, 3762, 3233, 521, 3856, 173, 2457, 3939, 2138, 1262, 3572, 989, 3021, 2238, 119, 1445, 3832, 1809, 2297, 3467, 2700, 3684, 3102, 394,
|
||||
4036, 2050, 3256, 89, 2198, 1079, 248, 1845, 3805, 3104, 880, 1779, 2688, 717, 2373, 1375, 262, 2249, 3071, 13, 2813, 3429, 1600, 3984, 2416, 3603, 1299, 2298, 998, 3492, 1393, 2951, 10, 4009, 1247, 3462, 1679, 2204, 414, 2736, 316, 1894, 2816, 1050, 3373, 1462, 3107, 817, 3464, 21, 1835, 4070, 568, 1178, 3718, 875, 3168, 466, 2974, 1458, 2084, 616, 1564, 1018,
|
||||
1693, 546, 1244, 3899, 716, 3160, 3608, 2877, 1220, 334, 3443, 2270, 44, 3000, 1843, 3928, 3405, 766, 3686, 2040, 587, 993, 2647, 387, 930, 2753, 630, 3274, 150, 2808, 453, 3638, 1092, 2352, 3030, 239, 2562, 700, 3240, 1257, 4016, 730, 1515, 2203, 2551, 417, 1866, 1123, 2348, 2902, 1550, 2678, 2075, 3238, 1630, 2531, 2115, 1255, 4054, 840, 290, 3874, 2477, 3399,
|
||||
2250, 3577, 2817, 1626, 2576, 1356, 2315, 792, 2087, 2618, 1612, 3855, 1263, 3637, 1036, 494, 1535, 2553, 1198, 1715, 3867, 3170, 1359, 1954, 3483, 1539, 2069, 3886, 1772, 2487, 1534, 2045, 3242, 806, 1578, 2018, 3948, 1423, 3596, 2076, 2466, 3424, 139, 3688, 871, 4049, 2852, 3342, 547, 3719, 327, 852, 3505, 207, 2794, 542, 3600, 45, 2411, 3324, 1788, 3012, 1235, 61,
|
||||
2655, 917, 253, 1986, 3738, 313, 1706, 4072, 120, 3229, 957, 597, 2024, 3262, 2453, 2857, 2002, 3190, 210, 2784, 2206, 300, 2400, 3766, 553, 3152, 218, 1150, 2988, 883, 3753, 627, 2664, 3831, 437, 3385, 1008, 2957, 60, 1636, 891, 2899, 1776, 3062, 1315, 2026, 194, 1643, 2079, 1296, 3201, 2465, 1379, 1927, 3898, 1125, 1847, 2846, 1552, 1028, 2725, 2169, 787, 3202,
|
||||
1441, 3982, 3032, 1052, 3251, 605, 2639, 3073, 1431, 3642, 2329, 2949, 341, 1634, 833, 129, 4020, 916, 3571, 669, 1506, 3411, 821, 2856, 1207, 2337, 2683, 3448, 340, 2214, 3128, 235, 1738, 1288, 2833, 2419, 606, 1884, 2668, 552, 3765, 1176, 399, 2302, 596, 3591, 2634, 767, 3845, 2767, 995, 3967, 491, 3057, 814, 2300, 3422, 691, 3797, 254, 3645, 509, 3478, 1836,
|
||||
2119, 475, 2445, 1525, 2175, 3539, 914, 1926, 473, 1157, 1800, 3971, 2701, 3739, 2129, 3486, 1333, 1784, 2366, 2982, 1070, 4089, 1802, 73, 1642, 3958, 835, 1837, 1480, 4043, 1217, 2469, 3416, 2113, 88, 3668, 1240, 3255, 3920, 2355, 3167, 2003, 2645, 3936, 3228, 1592, 1144, 3474, 2394, 79, 1820, 2241, 1594, 3656, 2584, 153, 1448, 3034, 2005, 2511, 1692, 1335, 3913, 217,
|
||||
2822, 3391, 745, 3813, 192, 1274, 2941, 3847, 2489, 3440, 744, 161, 1422, 1086, 572, 3004, 2617, 338, 3807, 2031, 236, 2472, 3065, 2098, 3358, 362, 2163, 3574, 497, 2788, 1970, 948, 3885, 685, 3100, 1712, 2228, 292, 1408, 1016, 164, 3537, 1417, 941, 34, 2172, 3001, 358, 1491, 3147, 699, 3356, 258, 1149, 2946, 1787, 3931, 382, 1146, 3291, 818, 2890, 2379, 1096,
|
||||
3679, 1328, 1901, 3162, 2747, 1730, 2253, 5, 1556, 2818, 2093, 3166, 2522, 3410, 2287, 1701, 956, 3237, 620, 1596, 3300, 1307, 511, 3701, 1020, 2939, 1362, 2532, 3208, 749, 3641, 160, 1522, 2624, 1095, 4086, 826, 2841, 3583, 2173, 1727, 723, 2925, 1911, 2482, 3726, 863, 1962, 4028, 1111, 2835, 3773, 2449, 2022, 582, 3278, 923, 2619, 2152, 4039, 92, 1934, 3145, 677,
|
||||
2530, 53, 2303, 1003, 458, 3989, 739, 3321, 1064, 369, 3556, 877, 1900, 426, 3876, 1, 3617, 2106, 1197, 2805, 3634, 857, 2706, 1504, 2418, 682, 3868, 20, 1139, 1688, 2333, 3311, 2907, 1945, 265, 2385, 3433, 1601, 636, 2620, 3095, 4044, 386, 3382, 1184, 527, 2814, 3414, 2342, 465, 1889, 1343, 874, 3479, 1502, 2233, 3689, 1385, 559, 2745, 1463, 3465, 376, 1718,
|
||||
3217, 4045, 1580, 3612, 2525, 1228, 3018, 1958, 3725, 2358, 1361, 3996, 1581, 3063, 1224, 2737, 1475, 2442, 3946, 191, 1796, 2128, 3975, 134, 1916, 3318, 1597, 2071, 3749, 2672, 403, 1278, 602, 3745, 3220, 1374, 445, 2064, 3830, 243, 1252, 2390, 1563, 2724, 3875, 1818, 1346, 165, 1650, 3264, 2680, 117, 2998, 4081, 343, 2799, 9, 3122, 1743, 3724, 1040, 2231, 3842, 1209,
|
||||
900, 398, 2851, 697, 1797, 3482, 293, 2679, 1649, 566, 2954, 91, 2697, 714, 2060, 3211, 781, 480, 3040, 1038, 2611, 666, 2989, 3458, 1201, 2796, 548, 2975, 839, 3121, 1850, 4001, 2208, 1631, 790, 2558, 2972, 1148, 3213, 1849, 3624, 971, 2102, 108, 772, 3101, 2589, 3777, 1042, 656, 3907, 2097, 1615, 2540, 805, 1935, 1231, 3494, 2451, 268, 2995, 750, 2682, 2020,
|
||||
3024, 1392, 2124, 3279, 106, 2217, 1387, 822, 3214, 3825, 2160, 1000, 2395, 3691, 228, 4038, 1872, 3413, 1608, 2225, 3536, 303, 1653, 886, 2541, 224, 4037, 2252, 1428, 172, 3504, 958, 2848, 113, 3628, 1834, 3979, 19, 2317, 779, 2797, 518, 3174, 3549, 1482, 2266, 444, 2014, 3555, 2439, 1213, 3113, 535, 1135, 3204, 3858, 2309, 931, 623, 2009, 3359, 1566, 140, 3550,
|
||||
1808, 3872, 2488, 1152, 3764, 2892, 3960, 2412, 353, 1223, 1825, 3444, 3116, 1717, 1082, 2313, 1280, 2661, 82, 3852, 1389, 3200, 2330, 3812, 2038, 3581, 1728, 1039, 3339, 2427, 586, 2580, 1238, 3328, 2280, 1047, 595, 2662, 1363, 3338, 1620, 3934, 2497, 1881, 1054, 3954, 3215, 864, 2887, 1801, 320, 3519, 2378, 3704, 1753, 424, 2958, 1660, 4005, 2601, 1116, 3912, 2381, 573,
|
||||
2740, 200, 828, 1667, 432, 1931, 1035, 1616, 3598, 2640, 728, 264, 1437, 557, 3501, 2966, 372, 3734, 974, 1978, 758, 2719, 1145, 452, 1433, 725, 2681, 408, 3843, 1918, 1547, 3906, 1996, 503, 1456, 3019, 3493, 1700, 3742, 355, 2134, 176, 1311, 615, 2867, 315, 1680, 1314, 8, 3297, 1494, 783, 1950, 83, 2656, 1382, 3561, 138, 2834, 1404, 330, 1904, 3156, 1027,
|
||||
1357, 3381, 3041, 3666, 2729, 734, 3415, 177, 3051, 2021, 4079, 2823, 3775, 2186, 2616, 869, 1668, 3148, 2367, 3315, 393, 4075, 1870, 2920, 3343, 2362, 3188, 1303, 2782, 825, 3171, 259, 2905, 3717, 2538, 184, 2074, 838, 2860, 2407, 1024, 3496, 3008, 3706, 1985, 2349, 3623, 2582, 4058, 2184, 2694, 3873, 2964, 990, 3346, 690, 2033, 1066, 2201, 3490, 2971, 718, 3700, 2188,
|
||||
4061, 391, 1989, 2325, 1430, 3150, 2125, 2526, 592, 1403, 976, 2351, 1165, 1851, 114, 3921, 2063, 613, 1358, 2785, 1623, 2254, 25, 3542, 1045, 246, 1852, 3554, 87, 2243, 3615, 1169, 727, 1705, 968, 3957, 3185, 1251, 500, 4063, 1751, 2622, 842, 1519, 90, 3393, 819, 490, 1874, 999, 571, 1275, 2271, 1586, 4040, 2448, 3126, 3731, 436, 885, 1708, 2421, 24, 1599,
|
||||
889, 2563, 1199, 645, 70, 4013, 1237, 3723, 1694, 3499, 3, 3266, 484, 2997, 3390, 1233, 2842, 3687, 152, 3480, 1084, 3698, 881, 2490, 1542, 3992, 2209, 692, 1690, 3022, 1470, 2625, 2114, 3512, 2359, 381, 2684, 1897, 3368, 1395, 3080, 289, 2065, 3981, 2758, 1141, 3097, 1472, 2870, 3352, 3707, 225, 3159, 505, 1895, 214, 1222, 1774, 2686, 3978, 3275, 1196, 3518, 2825,
|
||||
3270, 1720, 3796, 3466, 2650, 1841, 298, 899, 2862, 2091, 2671, 1744, 3735, 801, 1560, 349, 2262, 903, 1833, 2524, 512, 3117, 1793, 2827, 476, 3038, 1216, 2550, 3826, 980, 431, 4048, 35, 2992, 1265, 1595, 765, 3675, 76, 2247, 696, 3456, 1254, 2452, 664, 1757, 2133, 3750, 145, 2332, 1554, 1981, 3580, 2712, 868, 3640, 2919, 638, 2275, 1427, 309, 2595, 2006, 492,
|
||||
2226, 178, 2911, 836, 1528, 3028, 2240, 3327, 404, 3970, 707, 1294, 2464, 2131, 4032, 2600, 3319, 1406, 2913, 3974, 2156, 1425, 221, 3877, 2017, 811, 3662, 272, 3287, 1988, 2408, 3357, 1746, 598, 3239, 3823, 2182, 2934, 1078, 2604, 3840, 1697, 2906, 413, 3210, 3880, 331, 2644, 1260, 848, 3042, 2535, 1077, 1438, 3261, 2365, 1561, 3799, 85, 3082, 1876, 674, 3932, 1101,
|
||||
3644, 1344, 1943, 2401, 390, 3835, 1048, 2572, 1541, 1133, 3075, 3584, 308, 2889, 1065, 1869, 601, 3783, 282, 1181, 736, 3312, 2368, 1126, 3383, 1675, 2734, 1426, 628, 2873, 1317, 843, 2717, 2048, 1004, 2536, 333, 1782, 3295, 1517, 219, 2153, 815, 3502, 1579, 2268, 987, 3409, 1780, 4018, 354, 665, 3914, 47, 1956, 456, 1006, 2010, 3406, 1130, 3621, 2894, 1549, 3092,
|
||||
2485, 640, 3993, 3179, 1270, 3436, 585, 1925, 3757, 2304, 136, 1976, 1486, 646, 3520, 50, 3155, 1637, 2435, 3522, 1937, 2756, 3748, 661, 2224, 58, 3230, 2357, 1830, 3892, 170, 3607, 1447, 3949, 190, 3392, 1336, 584, 4010, 918, 3016, 3670, 1155, 2406, 52, 1304, 3009, 607, 2085, 2699, 3205, 1848, 2291, 3402, 2764, 3865, 3048, 2508, 735, 2710, 443, 2341, 897, 263,
|
||||
1785, 2769, 983, 56, 2197, 1685, 2703, 202, 2944, 810, 3377, 2626, 3787, 3047, 2055, 1236, 2752, 2122, 945, 3093, 96, 1624, 439, 3014, 1388, 4015, 977, 448, 3506, 1098, 2242, 3026, 506, 2361, 2952, 1862, 3619, 2790, 1992, 2483, 525, 1868, 2652, 4093, 1998, 3595, 2478, 3816, 122, 1412, 929, 3716, 1166, 1648, 813, 1300, 199, 1489, 3998, 1771, 1310, 3808, 2052, 3423,
|
||||
434, 3712, 1625, 3558, 2955, 853, 4019, 1348, 3511, 1732, 1246, 487, 934, 1672, 2510, 3965, 788, 3711, 396, 1369, 4090, 1055, 2603, 1879, 3528, 2518, 2067, 3005, 1516, 2588, 751, 1740, 3418, 1131, 1576, 686, 2296, 1118, 18, 3263, 1365, 3401, 294, 737, 3177, 410, 867, 1633, 2963, 3579, 2375, 252, 2881, 479, 2471, 3576, 2180, 3306, 332, 2255, 3035, 41, 2648, 1396,
|
||||
2929, 2230, 1219, 2512, 446, 2008, 3189, 2388, 626, 2164, 2831, 4047, 2376, 174, 3272, 368, 1469, 3226, 2578, 1991, 2874, 2263, 3681, 876, 188, 1239, 683, 3776, 226, 3183, 4083, 2148, 63, 2649, 3859, 299, 3086, 3933, 1585, 2185, 3767, 988, 1707, 2908, 1407, 1844, 2771, 2245, 1161, 560, 1755, 3376, 2051, 4064, 3135, 1832, 652, 2853, 1051, 3649, 760, 3290, 1105, 3945,
|
||||
872, 154, 3207, 713, 3780, 1453, 281, 1087, 3695, 30, 3299, 1919, 1400, 3551, 1119, 1890, 2314, 618, 1703, 3428, 724, 295, 3146, 1557, 3341, 2896, 1683, 2723, 1974, 1017, 541, 1380, 3720, 804, 3280, 2082, 997, 2567, 777, 2961, 213, 2707, 2328, 3632, 1025, 3891, 3304, 255, 4003, 3108, 2587, 1323, 743, 1479, 105, 1013, 3901, 1618, 2044, 2627, 1465, 1846, 576, 1994,
|
||||
2560, 3521, 1742, 2118, 2800, 3404, 1783, 2609, 2968, 1582, 1022, 412, 2713, 687, 2976, 3857, 2761, 3620, 62, 1108, 3844, 1340, 2100, 540, 2345, 3925, 405, 3457, 1319, 2468, 3362, 2815, 1867, 2372, 1281, 1714, 3690, 482, 3498, 1842, 1285, 3994, 558, 2039, 81, 2499, 678, 1481, 1923, 964, 12, 3824, 2980, 2205, 2762, 3432, 2398, 181, 3247, 462, 4094, 2350, 3589, 3089,
|
||||
1555, 1094, 4041, 247, 1267, 908, 3959, 2041, 732, 3860, 2343, 3132, 3769, 2144, 1621, 237, 912, 1329, 3025, 2146, 2642, 1775, 3721, 2746, 1121, 1953, 902, 2285, 130, 3671, 1659, 278, 3153, 522, 2721, 123, 2996, 1466, 2380, 377, 3231, 873, 1510, 3476, 3123, 1250, 2147, 3650, 2839, 3451, 2323, 1122, 3545, 379, 1765, 1218, 603, 3768, 1360, 938, 2885, 133, 1245, 363,
|
||||
2364, 554, 2743, 3344, 2474, 530, 3112, 169, 1297, 3430, 536, 1741, 98, 1043, 2574, 3253, 2246, 1854, 4022, 510, 3283, 204, 858, 3398, 36, 3118, 1478, 3794, 2986, 706, 2176, 922, 3559, 1097, 3976, 3322, 2149, 1160, 2810, 3883, 2007, 2513, 2953, 328, 1721, 3793, 422, 2566, 807, 329, 1638, 1967, 648, 2520, 3727, 3109, 2116, 2927, 2491, 1939, 3365, 1709, 2728, 3815,
|
||||
2037, 3120, 831, 1405, 1896, 3592, 1622, 2369, 2864, 2151, 1107, 2542, 3532, 1410, 3917, 427, 3568, 709, 2509, 1503, 1037, 2973, 2436, 1604, 4035, 2594, 563, 1819, 2659, 1234, 4004, 2565, 1511, 2273, 1823, 336, 882, 3772, 575, 1628, 171, 3570, 1120, 2260, 2716, 935, 3064, 1806, 1342, 3144, 3900, 2744, 3296, 985, 1546, 238, 896, 1663, 305, 3660, 695, 2213, 960, 3407,
|
||||
144, 1795, 3894, 2267, 51, 2708, 1023, 3818, 366, 1821, 4087, 2985, 755, 2057, 2912, 949, 1583, 2774, 231, 3447, 2258, 3866, 1982, 672, 1225, 2077, 3320, 1062, 370, 3241, 1968, 7, 3068, 681, 3631, 2573, 1567, 3175, 2321, 1067, 3070, 722, 1856, 3744, 642, 1471, 4084, 131, 3514, 2443, 531, 1227, 155, 2265, 4024, 2658, 3326, 3910, 1168, 3078, 1530, 3956, 489, 1424,
|
||||
3647, 1203, 420, 2924, 3755, 719, 3248, 1376, 3067, 890, 196, 1559, 3269, 270, 2432, 1885, 3212, 1164, 3778, 1752, 579, 1338, 344, 3585, 3017, 288, 3658, 2371, 3882, 1691, 611, 2789, 3809, 1339, 389, 2950, 2015, 59, 3548, 2751, 2158, 4011, 1352, 29, 3388, 2370, 2812, 1946, 954, 2110, 1558, 2947, 3573, 1909, 1326, 679, 1853, 2312, 551, 2702, 33, 2414, 3209, 2824,
|
||||
2547, 2143, 3379, 966, 1492, 1979, 2479, 463, 2194, 3657, 2738, 2318, 1261, 3713, 604, 4002, 11, 2192, 2967, 919, 2607, 3369, 2837, 1676, 2539, 984, 1568, 93, 2901, 1318, 3538, 1041, 2216, 1756, 3454, 1030, 4050, 1402, 798, 1723, 311, 3277, 2546, 2886, 2043, 461, 1206, 3677, 361, 3260, 3988, 809, 2605, 470, 3007, 3517, 102, 3221, 1398, 2062, 3611, 1134, 1928, 865,
|
||||
4060, 621, 1710, 2606, 3510, 317, 4017, 1682, 3329, 1159, 1940, 654, 3461, 1789, 1015, 2691, 1455, 3599, 374, 1947, 4069, 71, 2126, 763, 3961, 2278, 3161, 1997, 824, 2623, 2080, 244, 3257, 780, 2732, 2308, 545, 3351, 2476, 3806, 1204, 588, 1591, 963, 3610, 1699, 754, 3049, 2651, 1106, 65, 2221, 1644, 3821, 1100, 2463, 1614, 3801, 965, 2965, 715, 3394, 1593, 212,
|
||||
};
|
||||
|
||||
#endif /* BLUE_NOISE_64X64_H */
|
679
vendor/pixman/pixman/dither/make-blue-noise.c
vendored
Normal file
679
vendor/pixman/pixman/dither/make-blue-noise.c
vendored
Normal file
@ -0,0 +1,679 @@
|
||||
/* Blue noise generation using the void-and-cluster method as described in
|
||||
*
|
||||
* The void-and-cluster method for dither array generation
|
||||
* Ulichney, Robert A (1993)
|
||||
*
|
||||
* http://cv.ulichney.com/papers/1993-void-cluster.pdf
|
||||
*
|
||||
* Note that running with openmp (-DUSE_OPENMP) will trigger additional
|
||||
* randomness due to computing reductions in parallel, and is not recommended
|
||||
* unless generating very large dither arrays.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Booleans and utility functions */
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef int bool_t;
|
||||
|
||||
int
|
||||
imin (int x, int y)
|
||||
{
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
/* Memory allocation */
|
||||
void *
|
||||
malloc_abc (unsigned int a, unsigned int b, unsigned int c)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
else if (a * b >= INT32_MAX / c)
|
||||
return NULL;
|
||||
else
|
||||
return malloc (a * b * c);
|
||||
}
|
||||
|
||||
/* Random number generation */
|
||||
typedef uint32_t xorwow_state_t[5];
|
||||
|
||||
uint32_t
|
||||
xorwow_next (xorwow_state_t *state)
|
||||
{
|
||||
uint32_t s = (*state)[0],
|
||||
t = (*state)[3];
|
||||
(*state)[3] = (*state)[2];
|
||||
(*state)[2] = (*state)[1];
|
||||
(*state)[1] = s;
|
||||
|
||||
t ^= t >> 2;
|
||||
t ^= t << 1;
|
||||
t ^= s ^ (s << 4);
|
||||
|
||||
(*state)[0] = t;
|
||||
(*state)[4] += 362437;
|
||||
|
||||
return t + (*state)[4];
|
||||
}
|
||||
|
||||
float
|
||||
xorwow_float (xorwow_state_t *s)
|
||||
{
|
||||
return (xorwow_next (s) >> 9) / (float)((1 << 23) - 1);
|
||||
}
|
||||
|
||||
/* Floating point matrices
|
||||
*
|
||||
* Used to cache the cluster sizes.
|
||||
*/
|
||||
typedef struct matrix_t {
|
||||
int width;
|
||||
int height;
|
||||
float *buffer;
|
||||
} matrix_t;
|
||||
|
||||
bool_t
|
||||
matrix_init (matrix_t *matrix, int width, int height)
|
||||
{
|
||||
float *buffer;
|
||||
|
||||
if (!matrix)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (float));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
matrix->buffer = buffer;
|
||||
matrix->width = width;
|
||||
matrix->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
matrix_copy (matrix_t *dst, matrix_t const *src)
|
||||
{
|
||||
float *srcbuf = src->buffer,
|
||||
*srcend = src->buffer + src->width * src->height,
|
||||
*dstbuf = dst->buffer;
|
||||
|
||||
if (dst->width != src->width || dst->height != src->height)
|
||||
return FALSE;
|
||||
|
||||
while (srcbuf < srcend)
|
||||
*dstbuf++ = *srcbuf++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
float *
|
||||
matrix_get (matrix_t *matrix, int x, int y)
|
||||
{
|
||||
return &matrix->buffer[y * matrix->width + x];
|
||||
}
|
||||
|
||||
void
|
||||
matrix_destroy (matrix_t *matrix)
|
||||
{
|
||||
free (matrix->buffer);
|
||||
}
|
||||
|
||||
/* Binary patterns */
|
||||
typedef struct pattern_t {
|
||||
int width;
|
||||
int height;
|
||||
bool_t *buffer;
|
||||
} pattern_t;
|
||||
|
||||
bool_t
|
||||
pattern_init (pattern_t *pattern, int width, int height)
|
||||
{
|
||||
bool_t *buffer;
|
||||
|
||||
if (!pattern)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (bool_t));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
pattern->buffer = buffer;
|
||||
pattern->width = width;
|
||||
pattern->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
pattern_copy (pattern_t *dst, pattern_t const *src)
|
||||
{
|
||||
bool_t *srcbuf = src->buffer,
|
||||
*srcend = src->buffer + src->width * src->height,
|
||||
*dstbuf = dst->buffer;
|
||||
|
||||
if (dst->width != src->width || dst->height != src->height)
|
||||
return FALSE;
|
||||
|
||||
while (srcbuf < srcend)
|
||||
*dstbuf++ = *srcbuf++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t *
|
||||
pattern_get (pattern_t *pattern, int x, int y)
|
||||
{
|
||||
return &pattern->buffer[y * pattern->width + x];
|
||||
}
|
||||
|
||||
void
|
||||
pattern_fill_white_noise (pattern_t *pattern, float fraction,
|
||||
xorwow_state_t *s)
|
||||
{
|
||||
bool_t *buffer = pattern->buffer;
|
||||
bool_t *end = buffer + (pattern->width * pattern->height);
|
||||
|
||||
while (buffer < end)
|
||||
*buffer++ = xorwow_float (s) < fraction;
|
||||
}
|
||||
|
||||
void
|
||||
pattern_destroy (pattern_t *pattern)
|
||||
{
|
||||
free (pattern->buffer);
|
||||
}
|
||||
|
||||
/* Dither arrays */
|
||||
typedef struct array_t {
|
||||
int width;
|
||||
int height;
|
||||
uint32_t *buffer;
|
||||
} array_t;
|
||||
|
||||
bool_t
|
||||
array_init (array_t *array, int width, int height)
|
||||
{
|
||||
uint32_t *buffer;
|
||||
|
||||
if (!array)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (uint32_t));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
array->buffer = buffer;
|
||||
array->width = width;
|
||||
array->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
uint32_t *
|
||||
array_get (array_t *array, int x, int y)
|
||||
{
|
||||
return &array->buffer[y * array->width + x];
|
||||
}
|
||||
|
||||
bool_t
|
||||
array_save_ppm (array_t *array, const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "wb");
|
||||
|
||||
int i = 0;
|
||||
int bpp = 2;
|
||||
uint8_t buffer[1024];
|
||||
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
if (array->width * array->height - 1 < 256)
|
||||
bpp = 1;
|
||||
|
||||
fprintf(f, "P5 %d %d %d\n", array->width, array->height,
|
||||
array->width * array->height - 1);
|
||||
while (i < array->width * array->height)
|
||||
{
|
||||
int j = 0;
|
||||
for (; j < 1024 / bpp && j < array->width * array->height; ++j)
|
||||
{
|
||||
uint32_t v = array->buffer[i + j];
|
||||
if (bpp == 2)
|
||||
{
|
||||
buffer[2 * j] = v & 0xff;
|
||||
buffer[2 * j + 1] = (v & 0xff00) >> 8;
|
||||
} else {
|
||||
buffer[j] = v;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite((void *)buffer, bpp, j, f);
|
||||
i += j;
|
||||
}
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
array_save (array_t *array, const char *filename)
|
||||
{
|
||||
int x, y;
|
||||
FILE *f = fopen(filename, "wb");
|
||||
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
fprintf (f,
|
||||
"/* WARNING: This file is generated by make-blue-noise.c\n"
|
||||
" * Please edit that file instead of this one.\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"#ifndef BLUE_NOISE_%dX%d_H\n"
|
||||
"#define BLUE_NOISE_%dX%d_H\n"
|
||||
"\n"
|
||||
"#include <stdint.h>\n"
|
||||
"\n", array->width, array->height, array->width, array->height);
|
||||
|
||||
fprintf (f, "static const uint16_t dither_blue_noise_%dx%d[%d] = {\n",
|
||||
array->width, array->height, array->width * array->height);
|
||||
|
||||
for (y = 0; y < array->height; ++y)
|
||||
{
|
||||
fprintf (f, " ");
|
||||
for (x = 0; x < array->width; ++x)
|
||||
{
|
||||
if (x != 0)
|
||||
fprintf (f, ", ");
|
||||
|
||||
fprintf (f, "%d", *array_get (array, x, y));
|
||||
}
|
||||
|
||||
fprintf (f, ",\n");
|
||||
}
|
||||
fprintf (f, "};\n");
|
||||
|
||||
fprintf (f, "\n#endif /* BLUE_NOISE_%dX%d_H */\n",
|
||||
array->width, array->height);
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
array_destroy (array_t *array)
|
||||
{
|
||||
free (array->buffer);
|
||||
}
|
||||
|
||||
/* Dither array generation */
|
||||
bool_t
|
||||
compute_cluster_sizes (pattern_t *pattern, matrix_t *matrix)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
if (matrix->width != width || matrix->height != height)
|
||||
return FALSE;
|
||||
|
||||
int px, py, qx, qy, dx, dy;
|
||||
float tsqsi = 2.f * 1.5f * 1.5f;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel for default (none) \
|
||||
private (py, px, qy, qx, dx, dy) \
|
||||
shared (height, width, pattern, matrix, tsqsi)
|
||||
#endif
|
||||
for (py = 0; py < height; ++py)
|
||||
{
|
||||
for (px = 0; px < width; ++px)
|
||||
{
|
||||
bool_t pixel = *pattern_get (pattern, px, py);
|
||||
float dist = 0.f;
|
||||
|
||||
for (qx = 0; qx < width; ++qx)
|
||||
{
|
||||
dx = imin (abs (qx - px), width - abs (qx - px));
|
||||
dx = dx * dx;
|
||||
|
||||
for (qy = 0; qy < height; ++qy)
|
||||
{
|
||||
dy = imin (abs (qy - py), height - abs (qy - py));
|
||||
dy = dy * dy;
|
||||
|
||||
dist += (pixel == *pattern_get (pattern, qx, qy))
|
||||
* expf (- (dx + dy) / tsqsi);
|
||||
}
|
||||
}
|
||||
|
||||
*matrix_get (matrix, px, py) = dist;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
swap_pixel (pattern_t *pattern, matrix_t *matrix, int x, int y)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
bool_t new;
|
||||
|
||||
float f,
|
||||
dist = 0.f,
|
||||
tsqsi = 2.f * 1.5f * 1.5f;
|
||||
|
||||
int px, py, dx, dy;
|
||||
bool_t b;
|
||||
|
||||
new = !*pattern_get (pattern, x, y);
|
||||
*pattern_get (pattern, x, y) = new;
|
||||
|
||||
if (matrix->width != width || matrix->height != height)
|
||||
return FALSE;
|
||||
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel for reduction (+:dist) default (none) \
|
||||
private (px, py, dx, dy, b, f) \
|
||||
shared (x, y, width, height, pattern, matrix, new, tsqsi)
|
||||
#endif
|
||||
for (py = 0; py < height; ++py)
|
||||
{
|
||||
dy = imin (abs (py - y), height - abs (py - y));
|
||||
dy = dy * dy;
|
||||
|
||||
for (px = 0; px < width; ++px)
|
||||
{
|
||||
dx = imin (abs (px - x), width - abs (px - x));
|
||||
dx = dx * dx;
|
||||
|
||||
b = (*pattern_get (pattern, px, py) == new);
|
||||
f = expf (- (dx + dy) / tsqsi);
|
||||
*matrix_get (matrix, px, py) += (2 * b - 1) * f;
|
||||
|
||||
dist += b * f;
|
||||
}
|
||||
}
|
||||
|
||||
*matrix_get (matrix, x, y) = dist;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
largest_cluster (pattern_t *pattern, matrix_t *matrix,
|
||||
bool_t pixel, int *xmax, int *ymax)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
int x, y;
|
||||
|
||||
float vmax = -INFINITY;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel default (none) \
|
||||
private (x, y) \
|
||||
shared (height, width, pattern, matrix, pixel, xmax, ymax, vmax)
|
||||
#endif
|
||||
{
|
||||
int xbest = -1,
|
||||
ybest = -1;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
float vbest = -INFINITY;
|
||||
|
||||
#pragma omp for reduction (max: vmax) collapse (2)
|
||||
#endif
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (*pattern_get (pattern, x, y) != pixel)
|
||||
continue;
|
||||
|
||||
if (*matrix_get (matrix, x, y) > vmax)
|
||||
{
|
||||
vmax = *matrix_get (matrix, x, y);
|
||||
#ifdef USE_OPENMP
|
||||
vbest = vmax;
|
||||
#endif
|
||||
xbest = x;
|
||||
ybest = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp barrier
|
||||
#pragma omp critical
|
||||
{
|
||||
if (vmax == vbest)
|
||||
{
|
||||
*xmax = xbest;
|
||||
*ymax = ybest;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*xmax = xbest;
|
||||
*ymax = ybest;
|
||||
#endif
|
||||
}
|
||||
|
||||
assert (vmax > -INFINITY);
|
||||
}
|
||||
|
||||
void
|
||||
generate_initial_binary_pattern (pattern_t *pattern, matrix_t *matrix)
|
||||
{
|
||||
int xcluster = 0,
|
||||
ycluster = 0,
|
||||
xvoid = 0,
|
||||
yvoid = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
largest_cluster (pattern, matrix, TRUE, &xcluster, &ycluster);
|
||||
assert (*pattern_get (pattern, xcluster, ycluster) == TRUE);
|
||||
swap_pixel (pattern, matrix, xcluster, ycluster);
|
||||
|
||||
largest_cluster (pattern, matrix, FALSE, &xvoid, &yvoid);
|
||||
assert (*pattern_get (pattern, xvoid, yvoid) == FALSE);
|
||||
swap_pixel (pattern, matrix, xvoid, yvoid);
|
||||
|
||||
if (xcluster == xvoid && ycluster == yvoid)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t
|
||||
generate_dither_array (array_t *array,
|
||||
pattern_t const *prototype, matrix_t const *matrix,
|
||||
pattern_t *temp_pattern, matrix_t *temp_matrix)
|
||||
{
|
||||
int width = prototype->width,
|
||||
height = prototype->height;
|
||||
|
||||
int x, y, rank;
|
||||
|
||||
int initial_rank = 0;
|
||||
|
||||
if (array->width != width || array->height != height)
|
||||
return FALSE;
|
||||
|
||||
// Make copies of the prototype and associated sizes matrix since we will
|
||||
// trash them
|
||||
if (!pattern_copy (temp_pattern, prototype))
|
||||
return FALSE;
|
||||
|
||||
if (!matrix_copy (temp_matrix, matrix))
|
||||
return FALSE;
|
||||
|
||||
// Compute initial rank
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (*pattern_get (temp_pattern, x, y))
|
||||
initial_rank += 1;
|
||||
|
||||
*array_get (array, x, y) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 1
|
||||
for (rank = initial_rank; rank > 0; --rank)
|
||||
{
|
||||
largest_cluster (temp_pattern, temp_matrix, TRUE, &x, &y);
|
||||
swap_pixel (temp_pattern, temp_matrix, x, y);
|
||||
*array_get (array, x, y) = rank - 1;
|
||||
}
|
||||
|
||||
// Make copies again for phases 2 & 3
|
||||
if (!pattern_copy (temp_pattern, prototype))
|
||||
return FALSE;
|
||||
|
||||
if (!matrix_copy (temp_matrix, matrix))
|
||||
return FALSE;
|
||||
|
||||
// Phase 2 & 3
|
||||
for (rank = initial_rank; rank < width * height; ++rank)
|
||||
{
|
||||
largest_cluster (temp_pattern, temp_matrix, FALSE, &x, &y);
|
||||
swap_pixel (temp_pattern, temp_matrix, x, y);
|
||||
*array_get (array, x, y) = rank;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
generate (int size, xorwow_state_t *s,
|
||||
char const *c_filename, char const *ppm_filename)
|
||||
{
|
||||
bool_t ok = TRUE;
|
||||
|
||||
pattern_t prototype, temp_pattern;
|
||||
array_t array;
|
||||
matrix_t matrix, temp_matrix;
|
||||
|
||||
printf ("Generating %dx%d blue noise...\n", size, size);
|
||||
|
||||
if (!pattern_init (&prototype, size, size))
|
||||
return FALSE;
|
||||
|
||||
if (!pattern_init (&temp_pattern, size, size))
|
||||
{
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!matrix_init (&matrix, size, size))
|
||||
{
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!matrix_init (&temp_matrix, size, size))
|
||||
{
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!array_init (&array, size, size))
|
||||
{
|
||||
matrix_destroy (&temp_matrix);
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("Filling initial binary pattern with white noise...\n");
|
||||
pattern_fill_white_noise (&prototype, .1, s);
|
||||
|
||||
printf("Initializing cluster sizes...\n");
|
||||
if (!compute_cluster_sizes (&prototype, &matrix))
|
||||
{
|
||||
fprintf (stderr, "Error while computing cluster sizes\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Generating initial binary pattern...\n");
|
||||
generate_initial_binary_pattern (&prototype, &matrix);
|
||||
|
||||
printf("Generating dither array...\n");
|
||||
if (!generate_dither_array (&array, &prototype, &matrix,
|
||||
&temp_pattern, &temp_matrix))
|
||||
{
|
||||
fprintf (stderr, "Error while generating dither array\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Saving dither array...\n");
|
||||
if (!array_save (&array, c_filename))
|
||||
{
|
||||
fprintf (stderr, "Error saving dither array\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if SAVE_PPM
|
||||
if (!array_save_ppm (&array, ppm_filename))
|
||||
{
|
||||
fprintf (stderr, "Error saving dither array PPM\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
(void)ppm_filename;
|
||||
#endif
|
||||
|
||||
printf("All done!\n");
|
||||
|
||||
out:
|
||||
array_destroy (&array);
|
||||
matrix_destroy (&temp_matrix);
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
xorwow_state_t s = {1185956906, 12385940, 983948, 349208051, 901842};
|
||||
|
||||
if (!generate (64, &s, "blue-noise-64x64.h", "blue-noise-64x64.ppm"))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
412
vendor/pixman/pixman/loongson-mmintrin.h
vendored
Normal file
412
vendor/pixman/pixman/loongson-mmintrin.h
vendored
Normal file
@ -0,0 +1,412 @@
|
||||
/* The gcc-provided loongson intrinsic functions are way too fucking broken
|
||||
* to be of any use, otherwise I'd use them.
|
||||
*
|
||||
* - The hardware instructions are very similar to MMX or iwMMXt. Certainly
|
||||
* close enough that they could have implemented the _mm_*-style intrinsic
|
||||
* interface and had a ton of optimized code available to them. Instead they
|
||||
* implemented something much, much worse.
|
||||
*
|
||||
* - pshuf takes a dead first argument, causing extra instructions to be
|
||||
* generated.
|
||||
*
|
||||
* - There are no 64-bit shift or logical intrinsics, which means you have
|
||||
* to implement them with inline assembly, but this is a nightmare because
|
||||
* gcc doesn't understand that the integer vector datatypes are actually in
|
||||
* floating-point registers, so you end up with braindead code like
|
||||
*
|
||||
* punpcklwd $f9,$f9,$f5
|
||||
* dmtc1 v0,$f8
|
||||
* punpcklwd $f19,$f19,$f5
|
||||
* dmfc1 t9,$f9
|
||||
* dmtc1 v0,$f9
|
||||
* dmtc1 t9,$f20
|
||||
* dmfc1 s0,$f19
|
||||
* punpcklbh $f20,$f20,$f2
|
||||
*
|
||||
* where crap just gets copied back and forth between integer and floating-
|
||||
* point registers ad nauseum.
|
||||
*
|
||||
* Instead of trying to workaround the problems from these crap intrinsics, I
|
||||
* just implement the _mm_* intrinsics needed for pixman-mmx.c using inline
|
||||
* assembly.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* vectors are stored in 64-bit floating-point registers */
|
||||
typedef double __m64;
|
||||
/* having a 32-bit datatype allows us to use 32-bit loads in places like load8888 */
|
||||
typedef float __m32;
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_setzero_si64 (void)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_add_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_add_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_adds_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddush %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_adds_pu8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddusb %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_and_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("and %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_cmpeq_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pcmpeqw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_empty (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_madd_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmaddhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_mulhi_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmulhuh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_mullo_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmullh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_or_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("or %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_packs_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("packushb %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_packs_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("packsswh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
|
||||
(((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0))
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_set_pi16 (uint16_t __w3, uint16_t __w2, uint16_t __w1, uint16_t __w0)
|
||||
{
|
||||
if (__builtin_constant_p (__w3) &&
|
||||
__builtin_constant_p (__w2) &&
|
||||
__builtin_constant_p (__w1) &&
|
||||
__builtin_constant_p (__w0))
|
||||
{
|
||||
uint64_t val = ((uint64_t)__w3 << 48)
|
||||
| ((uint64_t)__w2 << 32)
|
||||
| ((uint64_t)__w1 << 16)
|
||||
| ((uint64_t)__w0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
else if (__w3 == __w2 && __w2 == __w1 && __w1 == __w0)
|
||||
{
|
||||
/* TODO: handle other cases */
|
||||
uint64_t val = __w3;
|
||||
uint64_t imm = _MM_SHUFFLE (0, 0, 0, 0);
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (*(__m64 *)&val), "f" (*(__m64 *)&imm)
|
||||
);
|
||||
return ret;
|
||||
} else {
|
||||
uint64_t val = ((uint64_t)__w3 << 48)
|
||||
| ((uint64_t)__w2 << 32)
|
||||
| ((uint64_t)__w1 << 16)
|
||||
| ((uint64_t)__w0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_set_pi32 (unsigned __i1, unsigned __i0)
|
||||
{
|
||||
if (__builtin_constant_p (__i1) &&
|
||||
__builtin_constant_p (__i0))
|
||||
{
|
||||
uint64_t val = ((uint64_t)__i1 << 32)
|
||||
| ((uint64_t)__i0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
else if (__i1 == __i0)
|
||||
{
|
||||
uint64_t imm = _MM_SHUFFLE (1, 0, 1, 0);
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (*(__m32 *)&__i1), "f" (*(__m64 *)&imm)
|
||||
);
|
||||
return ret;
|
||||
} else {
|
||||
uint64_t val = ((uint64_t)__i1 << 32)
|
||||
| ((uint64_t)__i0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
}
|
||||
#undef _MM_SHUFFLE
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_shuffle_pi16 (__m64 __m, int64_t __n)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__n)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_slli_pi16 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psllh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_slli_si64 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("dsll %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_pi16 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psrlh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_pi32 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psrlw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_si64 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("dsrl %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_sub_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psubh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpackhi_pi8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpckhbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpackhi_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpckhhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Since punpcklbh doesn't care about the high 32-bits, we use the __m32 datatype which
|
||||
* allows load8888 to use 32-bit loads */
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi8_f (__m32 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_xor_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("xor %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
loongson_extract_pi16 (__m64 __m, int64_t __pos)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pextrh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__pos)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
loongson_insert_pi16 (__m64 __m1, __m64 __m2, int64_t __pos)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pinsrh_%3 %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2), "i" (__pos)
|
||||
);
|
||||
return ret;
|
||||
}
|
115
vendor/pixman/pixman/make-srgb.pl
vendored
Normal file
115
vendor/pixman/pixman/make-srgb.pl
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
sub linear_to_srgb
|
||||
{
|
||||
my ($c) = @_;
|
||||
|
||||
if ($c < 0.0031308)
|
||||
{
|
||||
return $c * 12.92;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.055 * $c ** (1.0/2.4) - 0.055;
|
||||
}
|
||||
}
|
||||
|
||||
sub srgb_to_linear
|
||||
{
|
||||
my ($c) = @_;
|
||||
|
||||
if ($c < 0.04045)
|
||||
{
|
||||
return $c / 12.92;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (($c + 0.055) / 1.055) ** 2.4
|
||||
}
|
||||
}
|
||||
|
||||
my @linear_to_srgb;
|
||||
for my $linear (0 .. 4095)
|
||||
{
|
||||
my $srgb = int(linear_to_srgb($linear / 4095.0) * 255.0 + 0.5);
|
||||
push @linear_to_srgb, $srgb;
|
||||
}
|
||||
|
||||
my @srgb_to_linear;
|
||||
for my $srgb (0 .. 255)
|
||||
{
|
||||
my $linear = int(srgb_to_linear($srgb / 255.0) * 65535.0 + 0.5);
|
||||
push @srgb_to_linear, $linear;
|
||||
}
|
||||
|
||||
# Ensure that we have a lossless sRGB and back conversion loop.
|
||||
# some of the darkest shades need a little bias -- maximum is just
|
||||
# 5 increments out of 16. This gives us useful property with
|
||||
# least amount of error in the sRGB-to-linear table, and keeps the actual
|
||||
# table lookup in the other direction as simple as possible.
|
||||
for my $srgb (0 .. $#srgb_to_linear)
|
||||
{
|
||||
my $add = 0;
|
||||
while (1)
|
||||
{
|
||||
my $linear = $srgb_to_linear[$srgb];
|
||||
my $srgb_lossy = $linear_to_srgb[$linear >> 4];
|
||||
last if $srgb == $srgb_lossy;
|
||||
|
||||
# Add slight bias to this component until it rounds correctly
|
||||
$srgb_to_linear[$srgb] ++;
|
||||
$add ++;
|
||||
}
|
||||
die "Too many adds at $srgb" if $add > 5;
|
||||
}
|
||||
|
||||
print <<"PROLOG";
|
||||
/* WARNING: This file is generated by $0.
|
||||
* Please edit that file instead of this one.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
PROLOG
|
||||
|
||||
print "const uint8_t linear_to_srgb[" . @linear_to_srgb . "] =\n";
|
||||
print "{\n";
|
||||
for my $linear (0 .. $#linear_to_srgb)
|
||||
{
|
||||
if (($linear % 10) == 0)
|
||||
{
|
||||
print "\t";
|
||||
}
|
||||
print sprintf("%d, ", $linear_to_srgb[$linear]);
|
||||
if (($linear % 10) == 9)
|
||||
{
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
print "\n";
|
||||
|
||||
print "const uint16_t srgb_to_linear[" . @srgb_to_linear . "] =\n";
|
||||
print "{\n";
|
||||
for my $srgb (0 .. $#srgb_to_linear)
|
||||
{
|
||||
if (($srgb % 10) == 0)
|
||||
{
|
||||
print "\t";
|
||||
}
|
||||
print sprintf("%d, ", $srgb_to_linear[$srgb]);
|
||||
if (($srgb % 10) == 9)
|
||||
{
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
|
143
vendor/pixman/pixman/meson.build
vendored
Normal file
143
vendor/pixman/pixman/meson.build
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
# 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 : 'pixman-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')
|
||||
)
|
||||
|
||||
libpixman_extra_cargs = []
|
||||
default_library = get_option('default_library')
|
||||
if default_library != 'static' and cc.has_function_attribute('dllexport')
|
||||
libpixman_extra_cargs = ['-DPIXMAN_API=__declspec(dllexport)']
|
||||
endif
|
||||
|
||||
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']],
|
||||
['arm-neon', have_a64neon, [],
|
||||
['pixman-arma64-neon-asm.S', 'pixman-arma64-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',
|
||||
)
|
||||
|
||||
# Android cpu-features
|
||||
cpu_features_path = get_option('cpu-features-path')
|
||||
cpu_features_sources = []
|
||||
cpu_features_inc = []
|
||||
if cpu_features_path != ''
|
||||
message('Using cpu-features.[ch] from ' + cpu_features_path)
|
||||
cpu_features_sources = files(
|
||||
cpu_features_path / 'cpu-features.h',
|
||||
cpu_features_path / 'cpu-features.c',
|
||||
)
|
||||
cpu_features_inc = include_directories(cpu_features_path)
|
||||
endif
|
||||
|
||||
libpixman = library(
|
||||
'pixman-1',
|
||||
[pixman_files, config_h, version_h, cpu_features_sources],
|
||||
link_with: pixman_simd_libs,
|
||||
c_args : libpixman_extra_cargs,
|
||||
dependencies : [dep_m, dep_threads],
|
||||
include_directories : cpu_features_inc,
|
||||
version : meson.project_version(),
|
||||
install : true,
|
||||
)
|
||||
|
||||
inc_pixman = include_directories('.')
|
||||
|
||||
idep_pixman = declare_dependency(
|
||||
link_with: libpixman,
|
||||
include_directories : inc_pixman,
|
||||
)
|
||||
|
||||
if meson.version().version_compare('>= 0.54.0')
|
||||
meson.override_dependency('pixman-1', idep_pixman)
|
||||
endif
|
||||
|
||||
install_headers('pixman.h', subdir : 'pixman-1')
|
3
vendor/pixman/pixman/pixman-access-accessors.c
vendored
Normal file
3
vendor/pixman/pixman/pixman-access-accessors.c
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-access.c"
|
1715
vendor/pixman/pixman/pixman-access.c
vendored
Normal file
1715
vendor/pixman/pixman/pixman-access.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
25
vendor/pixman/pixman/pixman-accessor.h
vendored
Normal file
25
vendor/pixman/pixman/pixman-accessor.h
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
|
||||
#define READ(img, ptr) \
|
||||
(((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr))))
|
||||
#define WRITE(img, ptr,val) \
|
||||
(((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr))))
|
||||
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
uint8_t *_dst = (uint8_t*)(dst); \
|
||||
for(_i = 0; _i < (size_t) size; _i++) { \
|
||||
WRITE((img), _dst +_i, (val)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define READ(img, ptr) (*(ptr))
|
||||
#define WRITE(img, ptr, val) (*(ptr) = (val))
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
memset(dst, val, size)
|
||||
|
||||
#endif
|
||||
|
37
vendor/pixman/pixman/pixman-arm-asm.h
vendored
Normal file
37
vendor/pixman/pixman/pixman-arm-asm.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
* Copyright © 2010 Nokia Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
|
||||
/* Supplementary macro for setting function attributes */
|
||||
.macro pixman_asm_function fname
|
||||
.func fname
|
||||
.global fname
|
||||
#ifdef __ELF__
|
||||
.hidden fname
|
||||
.type fname, %function
|
||||
#endif
|
||||
fname:
|
||||
.endm
|
419
vendor/pixman/pixman/pixman-arm-common.h
vendored
Normal file
419
vendor/pixman/pixman/pixman-arm-common.h
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* Copyright © 2010 Nokia 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_ARM_COMMON_H
|
||||
#define PIXMAN_ARM_COMMON_H
|
||||
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
/* Define some macros which can expand into proxy functions between
|
||||
* ARM assembly optimized functions and the rest of pixman fast path API.
|
||||
*
|
||||
* All the low level ARM assembly functions have to use ARM EABI
|
||||
* calling convention and take up to 8 arguments:
|
||||
* width, height, dst, dst_stride, src, src_stride, mask, mask_stride
|
||||
*
|
||||
* The arguments are ordered with the most important coming first (the
|
||||
* first 4 arguments are passed to function in registers, the rest are
|
||||
* on stack). The last arguments are optional, for example if the
|
||||
* function is not using mask, then 'mask' and 'mask_stride' can be
|
||||
* omitted when doing a function call.
|
||||
*
|
||||
* Arguments 'src' and 'mask' contain either a pointer to the top left
|
||||
* pixel of the composited rectangle or a pixel color value depending
|
||||
* on the function type. In the case of just a color value (solid source
|
||||
* or mask), the corresponding stride argument is unused.
|
||||
*/
|
||||
|
||||
#define SKIP_ZERO_SRC 1
|
||||
#define SKIP_ZERO_MASK 2
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
uint32_t src); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
int32_t dst_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(flags, cputype, name, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
uint32_t src, \
|
||||
int32_t unused, \
|
||||
mask_type *mask, \
|
||||
int32_t mask_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
mask_type *mask_line; \
|
||||
int32_t dst_stride, mask_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src, 0, \
|
||||
mask_line, mask_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(flags, cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride, \
|
||||
uint32_t mask); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
uint32_t mask; \
|
||||
\
|
||||
mask = _pixman_image_get_solid ( \
|
||||
imp, mask_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride, \
|
||||
mask); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride, \
|
||||
mask_type *mask, \
|
||||
int32_t mask_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
mask_type *mask_line; \
|
||||
int32_t dst_stride, src_stride, mask_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride, \
|
||||
mask_line, mask_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
|
||||
int32_t w, \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
|
||||
vx, unit_x, \
|
||||
max_vx); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, COVER) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, NONE) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, PAD) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_normal_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, NORMAL)
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
|
||||
int32_t w, \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
const uint8_t * mask); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op (const uint8_t * mask, \
|
||||
dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
|
||||
vx, unit_x, \
|
||||
max_vx, \
|
||||
mask); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, PAD, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, NORMAL, TRUE, FALSE)
|
||||
|
||||
/* Provide entries for the fast path table */
|
||||
#define PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (op,s,d,func), \
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL (op,s,d,func)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst_type * dst, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
dst_type * dst, \
|
||||
const uint32_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NORMAL, \
|
||||
FLAG_NONE)
|
||||
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NORMAL, \
|
||||
FLAG_HAVE_NON_SOLID_MASK)
|
||||
|
||||
|
||||
#endif
|
21
vendor/pixman/pixman/pixman-arm-detect-win32.asm
vendored
Normal file
21
vendor/pixman/pixman/pixman-arm-detect-win32.asm
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
area pixman_msvc, code, readonly
|
||||
|
||||
export pixman_msvc_try_arm_simd_op
|
||||
|
||||
pixman_msvc_try_arm_simd_op
|
||||
;; I don't think the msvc arm asm knows how to do SIMD insns
|
||||
;; uqadd8 r3,r3,r3
|
||||
dcd 0xe6633f93
|
||||
mov pc,lr
|
||||
endp
|
||||
|
||||
export pixman_msvc_try_arm_neon_op
|
||||
|
||||
pixman_msvc_try_arm_neon_op
|
||||
;; I don't think the msvc arm asm knows how to do NEON insns
|
||||
;; veor d0,d0,d0
|
||||
dcd 0xf3000110
|
||||
mov pc,lr
|
||||
endp
|
||||
|
||||
end
|
1358
vendor/pixman/pixman/pixman-arm-neon-asm-bilinear.S
vendored
Normal file
1358
vendor/pixman/pixman/pixman-arm-neon-asm-bilinear.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3627
vendor/pixman/pixman/pixman-arm-neon-asm.S
vendored
Normal file
3627
vendor/pixman/pixman/pixman-arm-neon-asm.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1184
vendor/pixman/pixman/pixman-arm-neon-asm.h
vendored
Normal file
1184
vendor/pixman/pixman/pixman-arm-neon-asm.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
493
vendor/pixman/pixman/pixman-arm-neon.c
vendored
Normal file
493
vendor/pixman/pixman/pixman-arm-neon.c
vendored
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Copyright © 2009 ARM Ltd, Movial Creative Technologies Oy
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of ARM Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. ARM Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Ian Rickards (ian.rickards@arm.com)
|
||||
* Author: Jonathan Morton (jonathan.morton@movial.com)
|
||||
* Author: Markku Vire (markku.vire@movial.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-arm-common.h"
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0888,
|
||||
uint8_t, 3, uint8_t, 3)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_8888_rev,
|
||||
uint8_t, 3, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0565_rev,
|
||||
uint8_t, 3, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_pixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_rpixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_0565,
|
||||
uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, neon, in_n_8,
|
||||
uint8_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_0565_ca,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_0565_n_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, add_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8_8_8,
|
||||
uint8_t, 1, uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_0565_8_0565,
|
||||
uint16_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8_8888,
|
||||
uint32_t, 1, uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_8888,
|
||||
uint32_t, 1, uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_0565,
|
||||
uint32_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_0565_8_0565,
|
||||
uint16_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, OVER,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_0565,
|
||||
OVER, uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 0565_8_0565,
|
||||
OVER, uint16_t, uint16_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint8_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint8_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_0565_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint16_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint16_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8888_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint32_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint32_t src);
|
||||
|
||||
static pixman_bool_t
|
||||
arm_neon_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
/* stride is always multiple of 32bit units in pixman */
|
||||
int32_t byte_stride = stride * sizeof(uint32_t);
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_n_8_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint8_t *)(((char *) bits) + y * byte_stride + x),
|
||||
byte_stride,
|
||||
_xor & 0xff);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_n_0565_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
|
||||
byte_stride / 2,
|
||||
_xor & 0xffff);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_n_8888_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
|
||||
byte_stride / 4,
|
||||
_xor);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
arm_neon_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 16:
|
||||
pixman_composite_src_0565_0565_asm_neon (
|
||||
width, height,
|
||||
(uint16_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
|
||||
(uint16_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_8888_8888_asm_neon (
|
||||
width, height,
|
||||
(uint32_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
|
||||
(uint32_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 4), src_stride);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t arm_neon_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, neon_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, neon_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, neon_composite_src_0888_0888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, neon_composite_src_0888_8888_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, neon_composite_src_0888_0565_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, neon_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, neon_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, neon_composite_src_n_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, neon_composite_over_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, neon_composite_over_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, neon_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, neon_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, neon_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, neon_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, neon_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, neon_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, neon_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, neon_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, neon_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, neon_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, neon_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, neon_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, neon_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, neon_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, neon_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, neon_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, neon_composite_add_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8r8g8b8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8b8g8r8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, neon_composite_add_8_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, neon_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, neon_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, a8, x8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, x8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, a8, x8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, x8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, solid, x8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, x8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, solid, x8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, x8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, null, x8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, x8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, null, x8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, x8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN, solid, null, a8, neon_composite_in_n_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, neon_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, neon_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, neon_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, x8r8g8b8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, x8b8g8r8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888),
|
||||
/* Note: NONE repeat is not supported yet */
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
|
||||
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_8_0565),
|
||||
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, neon_0565_8_0565),
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, neon_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_x888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, x8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8_x888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, x8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
#define BIND_COMBINE_U(name) \
|
||||
void \
|
||||
pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \
|
||||
const uint32_t *dst, \
|
||||
const uint32_t *src, \
|
||||
const uint32_t *mask); \
|
||||
\
|
||||
void \
|
||||
pixman_composite_scanline_##name##_asm_neon (int32_t w, \
|
||||
const uint32_t *dst, \
|
||||
const uint32_t *src); \
|
||||
\
|
||||
static void \
|
||||
neon_combine_##name##_u (pixman_implementation_t *imp, \
|
||||
pixman_op_t op, \
|
||||
uint32_t * dest, \
|
||||
const uint32_t * src, \
|
||||
const uint32_t * mask, \
|
||||
int width) \
|
||||
{ \
|
||||
if (mask) \
|
||||
pixman_composite_scanline_##name##_mask_asm_neon (width, dest, \
|
||||
src, mask); \
|
||||
else \
|
||||
pixman_composite_scanline_##name##_asm_neon (width, dest, src); \
|
||||
}
|
||||
|
||||
BIND_COMBINE_U (over)
|
||||
BIND_COMBINE_U (add)
|
||||
BIND_COMBINE_U (out_reverse)
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, arm_neon_fast_paths);
|
||||
|
||||
imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u;
|
||||
imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u;
|
||||
imp->combine_32[PIXMAN_OP_OUT_REVERSE] = neon_combine_out_reverse_u;
|
||||
|
||||
imp->blt = arm_neon_blt;
|
||||
imp->fill = arm_neon_fill;
|
||||
|
||||
return imp;
|
||||
}
|
156
vendor/pixman/pixman/pixman-arm-simd-asm-scaled.S
vendored
Normal file
156
vendor/pixman/pixman/pixman-arm-simd-asm-scaled.S
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
* Copyright © 2010 Nokia Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
|
||||
/* Prevent the stack from becoming executable */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
.text
|
||||
.arch armv6
|
||||
.object_arch armv4
|
||||
.arm
|
||||
.altmacro
|
||||
.p2align 2
|
||||
|
||||
#include "pixman-arm-asm.h"
|
||||
|
||||
/*
|
||||
* Note: This code is only using armv5te instructions (not even armv6),
|
||||
* but is scheduled for ARM Cortex-A8 pipeline. So it might need to
|
||||
* be split into a few variants, tuned for each microarchitecture.
|
||||
*
|
||||
* TODO: In order to get good performance on ARM9/ARM11 cores (which don't
|
||||
* have efficient write combining), it needs to be changed to use 16-byte
|
||||
* aligned writes using STM instruction.
|
||||
*
|
||||
* Nearest scanline scaler macro template uses the following arguments:
|
||||
* fname - name of the function to generate
|
||||
* bpp_shift - (1 << bpp_shift) is the size of pixel in bytes
|
||||
* t - type suffix for LDR/STR instructions
|
||||
* prefetch_distance - prefetch in the source image by that many
|
||||
* pixels ahead
|
||||
* prefetch_braking_distance - stop prefetching when that many pixels are
|
||||
* remaining before the end of scanline
|
||||
*/
|
||||
|
||||
.macro generate_nearest_scanline_func fname, bpp_shift, t, \
|
||||
prefetch_distance, \
|
||||
prefetch_braking_distance
|
||||
|
||||
pixman_asm_function fname
|
||||
W .req r0
|
||||
DST .req r1
|
||||
SRC .req r2
|
||||
VX .req r3
|
||||
UNIT_X .req ip
|
||||
TMP1 .req r4
|
||||
TMP2 .req r5
|
||||
VXMASK .req r6
|
||||
PF_OFFS .req r7
|
||||
SRC_WIDTH_FIXED .req r8
|
||||
|
||||
ldr UNIT_X, [sp]
|
||||
push {r4, r5, r6, r7, r8, r10}
|
||||
mvn VXMASK, #((1 << bpp_shift) - 1)
|
||||
ldr SRC_WIDTH_FIXED, [sp, #28]
|
||||
|
||||
/* define helper macro */
|
||||
.macro scale_2_pixels
|
||||
ldr&t TMP1, [SRC, TMP1]
|
||||
and TMP2, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
str&t TMP1, [DST], #(1 << bpp_shift)
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
|
||||
ldr&t TMP2, [SRC, TMP2]
|
||||
and TMP1, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
str&t TMP2, [DST], #(1 << bpp_shift)
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
.endm
|
||||
|
||||
/* now do the scaling */
|
||||
and TMP1, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
subs W, W, #(8 + prefetch_braking_distance)
|
||||
blt 2f
|
||||
/* calculate prefetch offset */
|
||||
mov PF_OFFS, #prefetch_distance
|
||||
mla PF_OFFS, UNIT_X, PF_OFFS, VX
|
||||
1: /* main loop, process 8 pixels per iteration with prefetch */
|
||||
pld [SRC, PF_OFFS, asr #(16 - bpp_shift)]
|
||||
add PF_OFFS, UNIT_X, lsl #3
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
subs W, W, #8
|
||||
bge 1b
|
||||
2:
|
||||
subs W, W, #(4 - 8 - prefetch_braking_distance)
|
||||
blt 2f
|
||||
1: /* process the remaining pixels */
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
subs W, W, #4
|
||||
bge 1b
|
||||
2:
|
||||
tst W, #2
|
||||
beq 2f
|
||||
scale_2_pixels
|
||||
2:
|
||||
tst W, #1
|
||||
ldrne&t TMP1, [SRC, TMP1]
|
||||
strne&t TMP1, [DST]
|
||||
/* cleanup helper macro */
|
||||
.purgem scale_2_pixels
|
||||
.unreq DST
|
||||
.unreq SRC
|
||||
.unreq W
|
||||
.unreq VX
|
||||
.unreq UNIT_X
|
||||
.unreq TMP1
|
||||
.unreq TMP2
|
||||
.unreq VXMASK
|
||||
.unreq PF_OFFS
|
||||
.unreq SRC_WIDTH_FIXED
|
||||
/* return */
|
||||
pop {r4, r5, r6, r7, r8, r10}
|
||||
bx lr
|
||||
.endfunc
|
||||
.endm
|
||||
|
||||
generate_nearest_scanline_func \
|
||||
pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6, 1, h, 80, 32
|
||||
|
||||
generate_nearest_scanline_func \
|
||||
pixman_scaled_nearest_scanline_8888_8888_SRC_asm_armv6, 2, , 48, 32
|
1179
vendor/pixman/pixman/pixman-arm-simd-asm.S
vendored
Normal file
1179
vendor/pixman/pixman/pixman-arm-simd-asm.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
966
vendor/pixman/pixman/pixman-arm-simd-asm.h
vendored
Normal file
966
vendor/pixman/pixman/pixman-arm-simd-asm.h
vendored
Normal file
@ -0,0 +1,966 @@
|
||||
/*
|
||||
* Copyright © 2012 Raspberry Pi Foundation
|
||||
* Copyright © 2012 RISC OS Open Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Ben Avison (bavison@riscosopen.org)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Because the alignment of pixel data to cachelines, and even the number of
|
||||
* cachelines per row can vary from row to row, and because of the need to
|
||||
* preload each scanline once and only once, this prefetch strategy treats
|
||||
* each row of pixels independently. When a pixel row is long enough, there
|
||||
* are three distinct phases of prefetch:
|
||||
* * an inner loop section, where each time a cacheline of data is
|
||||
* processed, another cacheline is preloaded (the exact distance ahead is
|
||||
* determined empirically using profiling results from lowlevel-blt-bench)
|
||||
* * a leading section, where enough cachelines are preloaded to ensure no
|
||||
* cachelines escape being preloaded when the inner loop starts
|
||||
* * a trailing section, where a limited number (0 or more) of cachelines
|
||||
* are preloaded to deal with data (if any) that hangs off the end of the
|
||||
* last iteration of the inner loop, plus any trailing bytes that were not
|
||||
* enough to make up one whole iteration of the inner loop
|
||||
*
|
||||
* There are (in general) three distinct code paths, selected between
|
||||
* depending upon how long the pixel row is. If it is long enough that there
|
||||
* is at least one iteration of the inner loop (as described above) then
|
||||
* this is described as the "wide" case. If it is shorter than that, but
|
||||
* there are still enough bytes output that there is at least one 16-byte-
|
||||
* long, 16-byte-aligned write to the destination (the optimum type of
|
||||
* write), then this is the "medium" case. If it is not even this long, then
|
||||
* this is the "narrow" case, and there is no attempt to align writes to
|
||||
* 16-byte boundaries. In the "medium" and "narrow" cases, all the
|
||||
* cachelines containing data from the pixel row are prefetched up-front.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Determine whether we put the arguments on the stack for debugging.
|
||||
*/
|
||||
#undef DEBUG_PARAMS
|
||||
|
||||
/*
|
||||
* Bit flags for 'generate_composite_function' macro which are used
|
||||
* to tune generated functions behavior.
|
||||
*/
|
||||
.set FLAG_DST_WRITEONLY, 0
|
||||
.set FLAG_DST_READWRITE, 1
|
||||
.set FLAG_COND_EXEC, 0
|
||||
.set FLAG_BRANCH_OVER, 2
|
||||
.set FLAG_PROCESS_PRESERVES_PSR, 0
|
||||
.set FLAG_PROCESS_CORRUPTS_PSR, 4
|
||||
.set FLAG_PROCESS_DOESNT_STORE, 0
|
||||
.set FLAG_PROCESS_DOES_STORE, 8 /* usually because it needs to conditionally skip it */
|
||||
.set FLAG_NO_SPILL_LINE_VARS, 0
|
||||
.set FLAG_SPILL_LINE_VARS_WIDE, 16
|
||||
.set FLAG_SPILL_LINE_VARS_NON_WIDE, 32
|
||||
.set FLAG_SPILL_LINE_VARS, 48
|
||||
.set FLAG_PROCESS_CORRUPTS_SCRATCH, 0
|
||||
.set FLAG_PROCESS_PRESERVES_SCRATCH, 64
|
||||
.set FLAG_PROCESS_PRESERVES_WK0, 0
|
||||
.set FLAG_PROCESS_CORRUPTS_WK0, 128 /* if possible, use the specified register(s) instead so WK0 can hold number of leading pixels */
|
||||
.set FLAG_PRELOAD_DST, 0
|
||||
.set FLAG_NO_PRELOAD_DST, 256
|
||||
|
||||
/*
|
||||
* Number of bytes by which to adjust preload offset of destination
|
||||
* buffer (allows preload instruction to be moved before the load(s))
|
||||
*/
|
||||
.set DST_PRELOAD_BIAS, 0
|
||||
|
||||
/*
|
||||
* Offset into stack where mask and source pointer/stride can be accessed.
|
||||
*/
|
||||
#ifdef DEBUG_PARAMS
|
||||
.set ARGS_STACK_OFFSET, (9*4+9*4)
|
||||
#else
|
||||
.set ARGS_STACK_OFFSET, (9*4)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Offset into stack where space allocated during init macro can be accessed.
|
||||
*/
|
||||
.set LOCALS_STACK_OFFSET, 0
|
||||
|
||||
/*
|
||||
* Constants for selecting preferable prefetch type.
|
||||
*/
|
||||
.set PREFETCH_TYPE_NONE, 0
|
||||
.set PREFETCH_TYPE_STANDARD, 1
|
||||
|
||||
/*
|
||||
* Definitions of macros for load/store of pixel data.
|
||||
*/
|
||||
|
||||
.macro pixldst op, cond=al, numbytes, reg0, reg1, reg2, reg3, base, unaligned=0
|
||||
.if numbytes == 16
|
||||
.if unaligned == 1
|
||||
op&r&cond WK®0, [base], #4
|
||||
op&r&cond WK®1, [base], #4
|
||||
op&r&cond WK®2, [base], #4
|
||||
op&r&cond WK®3, [base], #4
|
||||
.else
|
||||
op&m&cond&ia base!, {WK®0,WK®1,WK®2,WK®3}
|
||||
.endif
|
||||
.elseif numbytes == 8
|
||||
.if unaligned == 1
|
||||
op&r&cond WK®0, [base], #4
|
||||
op&r&cond WK®1, [base], #4
|
||||
.else
|
||||
op&m&cond&ia base!, {WK®0,WK®1}
|
||||
.endif
|
||||
.elseif numbytes == 4
|
||||
op&r&cond WK®0, [base], #4
|
||||
.elseif numbytes == 2
|
||||
op&r&cond&h WK®0, [base], #2
|
||||
.elseif numbytes == 1
|
||||
op&r&cond&b WK®0, [base], #1
|
||||
.else
|
||||
.error "unsupported size: numbytes"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pixst_baseupdated cond, numbytes, reg0, reg1, reg2, reg3, base
|
||||
.if numbytes == 16
|
||||
stm&cond&db base, {WK®0,WK®1,WK®2,WK®3}
|
||||
.elseif numbytes == 8
|
||||
stm&cond&db base, {WK®0,WK®1}
|
||||
.elseif numbytes == 4
|
||||
str&cond WK®0, [base, #-4]
|
||||
.elseif numbytes == 2
|
||||
str&cond&h WK®0, [base, #-2]
|
||||
.elseif numbytes == 1
|
||||
str&cond&b WK®0, [base, #-1]
|
||||
.else
|
||||
.error "unsupported size: numbytes"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pixld cond, numbytes, firstreg, base, unaligned
|
||||
pixldst ld, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base, unaligned
|
||||
.endm
|
||||
|
||||
.macro pixst cond, numbytes, firstreg, base
|
||||
.if (flags) & FLAG_DST_READWRITE
|
||||
pixst_baseupdated cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base
|
||||
.else
|
||||
pixldst st, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro PF a, x:vararg
|
||||
.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_STANDARD)
|
||||
a x
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro preload_leading_step1 bpp, ptr, base
|
||||
/* If the destination is already 16-byte aligned, then we need to preload
|
||||
* between 0 and prefetch_distance (inclusive) cache lines ahead so there
|
||||
* are no gaps when the inner loop starts.
|
||||
*/
|
||||
.if bpp > 0
|
||||
PF bic, ptr, base, #31
|
||||
.set OFFSET, 0
|
||||
.rept prefetch_distance+1
|
||||
PF pld, [ptr, #OFFSET]
|
||||
.set OFFSET, OFFSET+32
|
||||
.endr
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro preload_leading_step2 bpp, bpp_shift, ptr, base
|
||||
/* However, if the destination is not 16-byte aligned, we may need to
|
||||
* preload more cache lines than that. The question we need to ask is:
|
||||
* are the bytes corresponding to the leading pixels more than the amount
|
||||
* by which the source pointer will be rounded down for preloading, and if
|
||||
* so, by how many cache lines? Effectively, we want to calculate
|
||||
* leading_bytes = ((-dst)&15)*src_bpp/dst_bpp
|
||||
* inner_loop_offset = (src+leading_bytes)&31
|
||||
* extra_needed = leading_bytes - inner_loop_offset
|
||||
* and test if extra_needed is <= 0, <= 32, or > 32 (where > 32 is only
|
||||
* possible when there are 4 src bytes for every 1 dst byte).
|
||||
*/
|
||||
.if bpp > 0
|
||||
.ifc base,DST
|
||||
/* The test can be simplified further when preloading the destination */
|
||||
PF tst, base, #16
|
||||
PF beq, 61f
|
||||
.else
|
||||
.if bpp/dst_w_bpp == 4
|
||||
PF add, SCRATCH, base, WK0, lsl #bpp_shift-dst_bpp_shift
|
||||
PF and, SCRATCH, SCRATCH, #31
|
||||
PF rsb, SCRATCH, SCRATCH, WK0, lsl #bpp_shift-dst_bpp_shift
|
||||
PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
|
||||
PF movs, SCRATCH, SCRATCH, lsl #32-6 /* so this sets NC / nc / Nc */
|
||||
PF bcs, 61f
|
||||
PF bpl, 60f
|
||||
PF pld, [ptr, #32*(prefetch_distance+2)]
|
||||
.else
|
||||
PF mov, SCRATCH, base, lsl #32-5
|
||||
PF add, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift
|
||||
PF rsbs, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift
|
||||
PF bls, 61f
|
||||
.endif
|
||||
.endif
|
||||
60: PF pld, [ptr, #32*(prefetch_distance+1)]
|
||||
61:
|
||||
.endif
|
||||
.endm
|
||||
|
||||
#define IS_END_OF_GROUP(INDEX,SIZE) ((SIZE) < 2 || ((INDEX) & ~((INDEX)+1)) & ((SIZE)/2))
|
||||
.macro preload_middle bpp, base, scratch_holds_offset
|
||||
.if bpp > 0
|
||||
/* prefetch distance = 256/bpp, stm distance = 128/dst_w_bpp */
|
||||
.if IS_END_OF_GROUP(SUBBLOCK,256/128*dst_w_bpp/bpp)
|
||||
.if scratch_holds_offset
|
||||
PF pld, [base, SCRATCH]
|
||||
.else
|
||||
PF bic, SCRATCH, base, #31
|
||||
PF pld, [SCRATCH, #32*prefetch_distance]
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro preload_trailing bpp, bpp_shift, base
|
||||
.if bpp > 0
|
||||
.if bpp*pix_per_block > 256
|
||||
/* Calculations are more complex if more than one fetch per block */
|
||||
PF and, WK1, base, #31
|
||||
PF add, WK1, WK1, WK0, lsl #bpp_shift
|
||||
PF add, WK1, WK1, #32*(bpp*pix_per_block/256-1)*(prefetch_distance+1)
|
||||
PF bic, SCRATCH, base, #31
|
||||
80: PF pld, [SCRATCH, #32*(prefetch_distance+1)]
|
||||
PF add, SCRATCH, SCRATCH, #32
|
||||
PF subs, WK1, WK1, #32
|
||||
PF bhi, 80b
|
||||
.else
|
||||
/* If exactly one fetch per block, then we need either 0, 1 or 2 extra preloads */
|
||||
PF mov, SCRATCH, base, lsl #32-5
|
||||
PF adds, SCRATCH, SCRATCH, X, lsl #32-5+bpp_shift
|
||||
PF adceqs, SCRATCH, SCRATCH, #0
|
||||
/* The instruction above has two effects: ensures Z is only
|
||||
* set if C was clear (so Z indicates that both shifted quantities
|
||||
* were 0), and clears C if Z was set (so C indicates that the sum
|
||||
* of the shifted quantities was greater and not equal to 32) */
|
||||
PF beq, 82f
|
||||
PF bic, SCRATCH, base, #31
|
||||
PF bcc, 81f
|
||||
PF pld, [SCRATCH, #32*(prefetch_distance+2)]
|
||||
81: PF pld, [SCRATCH, #32*(prefetch_distance+1)]
|
||||
82:
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro preload_line narrow_case, bpp, bpp_shift, base
|
||||
/* "narrow_case" - just means that the macro was invoked from the "narrow"
|
||||
* code path rather than the "medium" one - because in the narrow case,
|
||||
* the row of pixels is known to output no more than 30 bytes, then
|
||||
* (assuming the source pixels are no wider than the the destination
|
||||
* pixels) they cannot possibly straddle more than 2 32-byte cachelines,
|
||||
* meaning there's no need for a loop.
|
||||
* "bpp" - number of bits per pixel in the channel (source, mask or
|
||||
* destination) that's being preloaded, or 0 if this channel is not used
|
||||
* for reading
|
||||
* "bpp_shift" - log2 of ("bpp"/8) (except if "bpp"=0 of course)
|
||||
* "base" - base address register of channel to preload (SRC, MASK or DST)
|
||||
*/
|
||||
.if bpp > 0
|
||||
.if narrow_case && (bpp <= dst_w_bpp)
|
||||
/* In these cases, each line for each channel is in either 1 or 2 cache lines */
|
||||
PF bic, WK0, base, #31
|
||||
PF pld, [WK0]
|
||||
PF add, WK1, base, X, LSL #bpp_shift
|
||||
PF sub, WK1, WK1, #1
|
||||
PF bic, WK1, WK1, #31
|
||||
PF cmp, WK1, WK0
|
||||
PF beq, 90f
|
||||
PF pld, [WK1]
|
||||
90:
|
||||
.else
|
||||
PF bic, WK0, base, #31
|
||||
PF pld, [WK0]
|
||||
PF add, WK1, base, X, lsl #bpp_shift
|
||||
PF sub, WK1, WK1, #1
|
||||
PF bic, WK1, WK1, #31
|
||||
PF cmp, WK1, WK0
|
||||
PF beq, 92f
|
||||
91: PF add, WK0, WK0, #32
|
||||
PF cmp, WK0, WK1
|
||||
PF pld, [WK0]
|
||||
PF bne, 91b
|
||||
92:
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0
|
||||
.if decrementx
|
||||
sub&cond X, X, #8*numbytes/dst_w_bpp
|
||||
.endif
|
||||
process_tail cond, numbytes, firstreg
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst cond, numbytes, firstreg, DST
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & FLAG_BRANCH_OVER
|
||||
.ifc cond,mi
|
||||
bpl 100f
|
||||
.endif
|
||||
.ifc cond,cs
|
||||
bcc 100f
|
||||
.endif
|
||||
.ifc cond,ne
|
||||
beq 100f
|
||||
.endif
|
||||
conditional_process1_helper , process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
100:
|
||||
.else
|
||||
conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & (FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE)
|
||||
/* Can't interleave reads and writes */
|
||||
test
|
||||
conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_PSR
|
||||
test
|
||||
.endif
|
||||
conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx
|
||||
.else
|
||||
/* Can interleave reads and writes for better scheduling */
|
||||
test
|
||||
process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0
|
||||
process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0
|
||||
.if decrementx
|
||||
sub&cond1 X, X, #8*numbytes1/dst_w_bpp
|
||||
sub&cond2 X, X, #8*numbytes2/dst_w_bpp
|
||||
.endif
|
||||
process_tail cond1, numbytes1, firstreg1
|
||||
process_tail cond2, numbytes2, firstreg2
|
||||
pixst cond1, numbytes1, firstreg1, DST
|
||||
pixst cond2, numbytes2, firstreg2, DST
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro test_bits_1_0_ptr
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
movs SCRATCH, X, lsl #32-1 /* C,N = bits 1,0 of DST */
|
||||
.else
|
||||
movs SCRATCH, WK0, lsl #32-1 /* C,N = bits 1,0 of DST */
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro test_bits_3_2_ptr
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
movs SCRATCH, X, lsl #32-3 /* C,N = bits 3, 2 of DST */
|
||||
.else
|
||||
movs SCRATCH, WK0, lsl #32-3 /* C,N = bits 3, 2 of DST */
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro leading_15bytes process_head, process_tail
|
||||
/* On entry, WK0 bits 0-3 = number of bytes until destination is 16-byte aligned */
|
||||
.set DECREMENT_X, 1
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
.set DECREMENT_X, 0
|
||||
sub X, X, WK0, lsr #dst_bpp_shift
|
||||
str X, [sp, #LINE_SAVED_REG_COUNT*4]
|
||||
mov X, WK0
|
||||
.endif
|
||||
/* Use unaligned loads in all cases for simplicity */
|
||||
.if dst_w_bpp == 8
|
||||
conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X
|
||||
.elseif dst_w_bpp == 16
|
||||
test_bits_1_0_ptr
|
||||
conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X
|
||||
.endif
|
||||
conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
ldr X, [sp, #LINE_SAVED_REG_COUNT*4]
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro test_bits_3_2_pix
|
||||
movs SCRATCH, X, lsl #dst_bpp_shift+32-3
|
||||
.endm
|
||||
|
||||
.macro test_bits_1_0_pix
|
||||
.if dst_w_bpp == 8
|
||||
movs SCRATCH, X, lsl #dst_bpp_shift+32-1
|
||||
.else
|
||||
movs SCRATCH, X, lsr #1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0
|
||||
.if dst_w_bpp == 16
|
||||
test_bits_1_0_pix
|
||||
conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0
|
||||
.elseif dst_w_bpp == 8
|
||||
conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment
|
||||
110:
|
||||
.set SUBBLOCK, 0 /* this is a count of STMs; there can be up to 8 STMs per block */
|
||||
.rept pix_per_block*dst_w_bpp/128
|
||||
process_head , 16, 0, unaligned_src, unaligned_mask, 1
|
||||
.if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
preload_middle src_bpp, SRC, 1
|
||||
.elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
preload_middle mask_bpp, MASK, 1
|
||||
.else
|
||||
preload_middle src_bpp, SRC, 0
|
||||
preload_middle mask_bpp, MASK, 0
|
||||
.endif
|
||||
.if (dst_r_bpp > 0) && ((SUBBLOCK % 2) == 0) && (((flags) & FLAG_NO_PRELOAD_DST) == 0)
|
||||
/* Because we know that writes are 16-byte aligned, it's relatively easy to ensure that
|
||||
* destination prefetches are 32-byte aligned. It's also the easiest channel to offset
|
||||
* preloads for, to achieve staggered prefetches for multiple channels, because there are
|
||||
* always two STMs per prefetch, so there is always an opposite STM on which to put the
|
||||
* preload. Note, no need to BIC the base register here */
|
||||
PF pld, [DST, #32*prefetch_distance - dst_alignment]
|
||||
.endif
|
||||
process_tail , 16, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 16, 0, DST
|
||||
.endif
|
||||
.set SUBBLOCK, SUBBLOCK+1
|
||||
.endr
|
||||
subs X, X, #pix_per_block
|
||||
bhs 110b
|
||||
.endm
|
||||
|
||||
.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask
|
||||
/* Destination now 16-byte aligned; we have at least one block before we have to stop preloading */
|
||||
.if dst_r_bpp > 0
|
||||
tst DST, #16
|
||||
bne 111f
|
||||
process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 16 + DST_PRELOAD_BIAS
|
||||
b 112f
|
||||
111:
|
||||
.endif
|
||||
process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 0 + DST_PRELOAD_BIAS
|
||||
112:
|
||||
/* Just before the final (prefetch_distance+1) 32-byte blocks, deal with final preloads */
|
||||
.if (src_bpp*pix_per_block > 256) || (mask_bpp*pix_per_block > 256) || (dst_r_bpp*pix_per_block > 256)
|
||||
PF and, WK0, X, #pix_per_block-1
|
||||
.endif
|
||||
preload_trailing src_bpp, src_bpp_shift, SRC
|
||||
preload_trailing mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_trailing dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
add X, X, #(prefetch_distance+2)*pix_per_block - 128/dst_w_bpp
|
||||
/* The remainder of the line is handled identically to the medium case */
|
||||
medium_case_inner_loop_and_trailing_pixels process_head, process_tail,, exit_label, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro medium_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask
|
||||
120:
|
||||
process_head , 16, 0, unaligned_src, unaligned_mask, 0
|
||||
process_tail , 16, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 16, 0, DST
|
||||
.endif
|
||||
subs X, X, #128/dst_w_bpp
|
||||
bhs 120b
|
||||
/* Trailing pixels */
|
||||
tst X, #128/dst_w_bpp - 1
|
||||
beq exit_label
|
||||
trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro narrow_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask
|
||||
tst X, #16*8/dst_w_bpp
|
||||
conditional_process1 ne, process_head, process_tail, 16, 0, unaligned_src, unaligned_mask, 0
|
||||
/* Trailing pixels */
|
||||
/* In narrow case, it's relatively unlikely to be aligned, so let's do without a branch here */
|
||||
trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro switch_on_alignment action, process_head, process_tail, process_inner_loop, exit_label
|
||||
/* Note that if we're reading the destination, it's already guaranteed to be aligned at this point */
|
||||
.if mask_bpp == 8 || mask_bpp == 16
|
||||
tst MASK, #3
|
||||
bne 141f
|
||||
.endif
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
tst SRC, #3
|
||||
bne 140f
|
||||
.endif
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 0, 0
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
b exit_label
|
||||
140:
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 1, 0
|
||||
.endif
|
||||
.if mask_bpp == 8 || mask_bpp == 16
|
||||
b exit_label
|
||||
141:
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
tst SRC, #3
|
||||
bne 142f
|
||||
.endif
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 0, 1
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
b exit_label
|
||||
142:
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 1, 1
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro end_of_line restore_x, vars_spilled, loop_label, last_one
|
||||
.if vars_spilled
|
||||
/* Sadly, GAS doesn't seem have an equivalent of the DCI directive? */
|
||||
/* This is ldmia sp,{} */
|
||||
.word 0xE89D0000 | LINE_SAVED_REGS
|
||||
.endif
|
||||
subs Y, Y, #1
|
||||
.if vars_spilled
|
||||
.if (LINE_SAVED_REGS) & (1<<1)
|
||||
str Y, [sp]
|
||||
.endif
|
||||
.endif
|
||||
add DST, DST, STRIDE_D
|
||||
.if src_bpp > 0
|
||||
add SRC, SRC, STRIDE_S
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
add MASK, MASK, STRIDE_M
|
||||
.endif
|
||||
.if restore_x
|
||||
mov X, ORIG_W
|
||||
.endif
|
||||
bhs loop_label
|
||||
.ifc "last_one",""
|
||||
.if vars_spilled
|
||||
b 197f
|
||||
.else
|
||||
b 198f
|
||||
.endif
|
||||
.else
|
||||
.if (!vars_spilled) && ((flags) & FLAG_SPILL_LINE_VARS)
|
||||
b 198f
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro generate_composite_function fname, \
|
||||
src_bpp_, \
|
||||
mask_bpp_, \
|
||||
dst_w_bpp_, \
|
||||
flags_, \
|
||||
prefetch_distance_, \
|
||||
init, \
|
||||
newline, \
|
||||
cleanup, \
|
||||
process_head, \
|
||||
process_tail, \
|
||||
process_inner_loop
|
||||
|
||||
pixman_asm_function fname
|
||||
|
||||
/*
|
||||
* Make some macro arguments globally visible and accessible
|
||||
* from other macros
|
||||
*/
|
||||
.set src_bpp, src_bpp_
|
||||
.set mask_bpp, mask_bpp_
|
||||
.set dst_w_bpp, dst_w_bpp_
|
||||
.set flags, flags_
|
||||
.set prefetch_distance, prefetch_distance_
|
||||
|
||||
/*
|
||||
* Select prefetch type for this function.
|
||||
*/
|
||||
.if prefetch_distance == 0
|
||||
.set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE
|
||||
.else
|
||||
.set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_STANDARD
|
||||
.endif
|
||||
|
||||
.if src_bpp == 32
|
||||
.set src_bpp_shift, 2
|
||||
.elseif src_bpp == 24
|
||||
.set src_bpp_shift, 0
|
||||
.elseif src_bpp == 16
|
||||
.set src_bpp_shift, 1
|
||||
.elseif src_bpp == 8
|
||||
.set src_bpp_shift, 0
|
||||
.elseif src_bpp == 0
|
||||
.set src_bpp_shift, -1
|
||||
.else
|
||||
.error "requested src bpp (src_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if mask_bpp == 32
|
||||
.set mask_bpp_shift, 2
|
||||
.elseif mask_bpp == 24
|
||||
.set mask_bpp_shift, 0
|
||||
.elseif mask_bpp == 8
|
||||
.set mask_bpp_shift, 0
|
||||
.elseif mask_bpp == 0
|
||||
.set mask_bpp_shift, -1
|
||||
.else
|
||||
.error "requested mask bpp (mask_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if dst_w_bpp == 32
|
||||
.set dst_bpp_shift, 2
|
||||
.elseif dst_w_bpp == 24
|
||||
.set dst_bpp_shift, 0
|
||||
.elseif dst_w_bpp == 16
|
||||
.set dst_bpp_shift, 1
|
||||
.elseif dst_w_bpp == 8
|
||||
.set dst_bpp_shift, 0
|
||||
.else
|
||||
.error "requested dst bpp (dst_w_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if (((flags) & FLAG_DST_READWRITE) != 0)
|
||||
.set dst_r_bpp, dst_w_bpp
|
||||
.else
|
||||
.set dst_r_bpp, 0
|
||||
.endif
|
||||
|
||||
.set pix_per_block, 16*8/dst_w_bpp
|
||||
.if src_bpp != 0
|
||||
.if 32*8/src_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/src_bpp
|
||||
.endif
|
||||
.endif
|
||||
.if mask_bpp != 0
|
||||
.if 32*8/mask_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/mask_bpp
|
||||
.endif
|
||||
.endif
|
||||
.if dst_r_bpp != 0
|
||||
.if 32*8/dst_r_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/dst_r_bpp
|
||||
.endif
|
||||
.endif
|
||||
|
||||
/* The standard entry conditions set up by pixman-arm-common.h are:
|
||||
* r0 = width (pixels)
|
||||
* r1 = height (rows)
|
||||
* r2 = pointer to top-left pixel of destination
|
||||
* r3 = destination stride (pixels)
|
||||
* [sp] = source pixel value, or pointer to top-left pixel of source
|
||||
* [sp,#4] = 0 or source stride (pixels)
|
||||
* The following arguments are unused for non-mask operations
|
||||
* [sp,#8] = mask pixel value, or pointer to top-left pixel of mask
|
||||
* [sp,#12] = 0 or mask stride (pixels)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Assign symbolic names to registers
|
||||
*/
|
||||
X .req r0 /* pixels to go on this line */
|
||||
Y .req r1 /* lines to go */
|
||||
DST .req r2 /* destination pixel pointer */
|
||||
STRIDE_D .req r3 /* destination stride (bytes, minus width) */
|
||||
SRC .req r4 /* source pixel pointer */
|
||||
STRIDE_S .req r5 /* source stride (bytes, minus width) */
|
||||
MASK .req r6 /* mask pixel pointer (if applicable) */
|
||||
STRIDE_M .req r7 /* mask stride (bytes, minus width) */
|
||||
WK0 .req r8 /* pixel data registers */
|
||||
WK1 .req r9
|
||||
WK2 .req r10
|
||||
WK3 .req r11
|
||||
SCRATCH .req r12
|
||||
ORIG_W .req r14 /* width (pixels) */
|
||||
|
||||
push {r4-r11, lr} /* save all registers */
|
||||
|
||||
subs Y, Y, #1
|
||||
blo 199f
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
sub sp, sp, #9*4
|
||||
#endif
|
||||
|
||||
.if src_bpp > 0
|
||||
ldr SRC, [sp, #ARGS_STACK_OFFSET]
|
||||
ldr STRIDE_S, [sp, #ARGS_STACK_OFFSET+4]
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
ldr MASK, [sp, #ARGS_STACK_OFFSET+8]
|
||||
ldr STRIDE_M, [sp, #ARGS_STACK_OFFSET+12]
|
||||
.endif
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
add Y, Y, #1
|
||||
stmia sp, {r0-r7,pc}
|
||||
sub Y, Y, #1
|
||||
#endif
|
||||
|
||||
init
|
||||
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
/* Reserve a word in which to store X during leading pixels */
|
||||
sub sp, sp, #4
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET+4
|
||||
.endif
|
||||
|
||||
lsl STRIDE_D, #dst_bpp_shift /* stride in bytes */
|
||||
sub STRIDE_D, STRIDE_D, X, lsl #dst_bpp_shift
|
||||
.if src_bpp > 0
|
||||
lsl STRIDE_S, #src_bpp_shift
|
||||
sub STRIDE_S, STRIDE_S, X, lsl #src_bpp_shift
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
lsl STRIDE_M, #mask_bpp_shift
|
||||
sub STRIDE_M, STRIDE_M, X, lsl #mask_bpp_shift
|
||||
.endif
|
||||
|
||||
/* Are we not even wide enough to have one 16-byte aligned 16-byte block write? */
|
||||
cmp X, #2*16*8/dst_w_bpp - 1
|
||||
blo 170f
|
||||
.if src_bpp || mask_bpp || dst_r_bpp /* Wide and medium cases are the same for fill */
|
||||
/* To preload ahead on the current line, we need at least (prefetch_distance+2) 32-byte blocks on all prefetch channels */
|
||||
cmp X, #(prefetch_distance+3)*pix_per_block - 1
|
||||
blo 160f
|
||||
|
||||
/* Wide case */
|
||||
/* Adjust X so that the decrement instruction can also test for
|
||||
* inner loop termination. We want it to stop when there are
|
||||
* (prefetch_distance+1) complete blocks to go. */
|
||||
sub X, X, #(prefetch_distance+2)*pix_per_block
|
||||
mov ORIG_W, X
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
151: /* New line */
|
||||
newline
|
||||
preload_leading_step1 src_bpp, WK1, SRC
|
||||
preload_leading_step1 mask_bpp, WK2, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_leading_step1 dst_r_bpp, WK3, DST
|
||||
.endif
|
||||
|
||||
ands WK0, DST, #15
|
||||
beq 154f
|
||||
rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
|
||||
|
||||
preload_leading_step2 src_bpp, src_bpp_shift, WK1, SRC
|
||||
preload_leading_step2 mask_bpp, mask_bpp_shift, WK2, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_leading_step2 dst_r_bpp, dst_bpp_shift, WK3, DST
|
||||
.endif
|
||||
|
||||
leading_15bytes process_head, process_tail
|
||||
|
||||
154: /* Destination now 16-byte aligned; we have at least one prefetch on each channel as well as at least one 16-byte output block */
|
||||
.if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
and SCRATCH, SRC, #31
|
||||
rsb SCRATCH, SCRATCH, #32*prefetch_distance
|
||||
.elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
and SCRATCH, MASK, #31
|
||||
rsb SCRATCH, SCRATCH, #32*prefetch_distance
|
||||
.endif
|
||||
.ifc "process_inner_loop",""
|
||||
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, wide_case_inner_loop, 157f
|
||||
.else
|
||||
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, process_inner_loop, 157f
|
||||
.endif
|
||||
|
||||
157: /* Check for another line */
|
||||
end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_WIDE), 151b
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_WIDE
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.ltorg
|
||||
|
||||
160: /* Medium case */
|
||||
mov ORIG_W, X
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
161: /* New line */
|
||||
newline
|
||||
preload_line 0, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
|
||||
preload_line 0, mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_line 0, dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
|
||||
sub X, X, #128/dst_w_bpp /* simplifies inner loop termination */
|
||||
ands WK0, DST, #15
|
||||
beq 164f
|
||||
rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
|
||||
|
||||
leading_15bytes process_head, process_tail
|
||||
|
||||
164: /* Destination now 16-byte aligned; we have at least one 16-byte output block */
|
||||
switch_on_alignment medium_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 167f
|
||||
|
||||
167: /* Check for another line */
|
||||
end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 161b
|
||||
|
||||
.ltorg
|
||||
|
||||
170: /* Narrow case, less than 31 bytes, so no guarantee of at least one 16-byte block */
|
||||
.if dst_w_bpp < 32
|
||||
mov ORIG_W, X
|
||||
.endif
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.endif
|
||||
171: /* New line */
|
||||
newline
|
||||
preload_line 1, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
|
||||
preload_line 1, mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_line 1, dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
|
||||
.if dst_w_bpp == 8
|
||||
tst DST, #3
|
||||
beq 174f
|
||||
172: subs X, X, #1
|
||||
blo 177f
|
||||
process_head , 1, 0, 1, 1, 0
|
||||
process_tail , 1, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 1, 0, DST
|
||||
.endif
|
||||
tst DST, #3
|
||||
bne 172b
|
||||
.elseif dst_w_bpp == 16
|
||||
tst DST, #2
|
||||
beq 174f
|
||||
subs X, X, #1
|
||||
blo 177f
|
||||
process_head , 2, 0, 1, 1, 0
|
||||
process_tail , 2, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 2, 0, DST
|
||||
.endif
|
||||
.endif
|
||||
|
||||
174: /* Destination now 4-byte aligned; we have 0 or more output bytes to go */
|
||||
switch_on_alignment narrow_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 177f
|
||||
|
||||
177: /* Check for another line */
|
||||
end_of_line %(dst_w_bpp < 32), %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 171b, last_one
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
|
||||
197:
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS
|
||||
add sp, sp, #LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
198:
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET-4
|
||||
add sp, sp, #4
|
||||
.endif
|
||||
|
||||
cleanup
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
add sp, sp, #9*4 /* junk the debug copy of arguments */
|
||||
#endif
|
||||
199:
|
||||
pop {r4-r11, pc} /* exit */
|
||||
|
||||
.ltorg
|
||||
|
||||
.unreq X
|
||||
.unreq Y
|
||||
.unreq DST
|
||||
.unreq STRIDE_D
|
||||
.unreq SRC
|
||||
.unreq STRIDE_S
|
||||
.unreq MASK
|
||||
.unreq STRIDE_M
|
||||
.unreq WK0
|
||||
.unreq WK1
|
||||
.unreq WK2
|
||||
.unreq WK3
|
||||
.unreq SCRATCH
|
||||
.unreq ORIG_W
|
||||
.endfunc
|
||||
.endm
|
||||
|
||||
.macro line_saved_regs x:vararg
|
||||
.set LINE_SAVED_REGS, 0
|
||||
.set LINE_SAVED_REG_COUNT, 0
|
||||
.irp SAVED_REG,x
|
||||
.ifc "SAVED_REG","Y"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<1)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_D"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<3)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_S"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<5)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_M"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<7)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","ORIG_W"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<14)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.macro nop_macro x:vararg
|
||||
.endm
|
291
vendor/pixman/pixman/pixman-arm-simd.c
vendored
Normal file
291
vendor/pixman/pixman/pixman-arm-simd.c
vendored
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-arm-common.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, in_reverse_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, armv6, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, armv6, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8888_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint32_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint32_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_0565_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint16_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint16_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint8_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint8_t src);
|
||||
|
||||
static pixman_bool_t
|
||||
arm_simd_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride, /* in 32-bit words */
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
/* stride is always multiple of 32bit units in pixman */
|
||||
uint32_t byte_stride = stride * sizeof(uint32_t);
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_n_8_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint8_t *)(((char *) bits) + y * byte_stride + x),
|
||||
byte_stride,
|
||||
_xor & 0xff);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_n_0565_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
|
||||
byte_stride / 2,
|
||||
_xor & 0xffff);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_n_8888_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
|
||||
byte_stride / 4,
|
||||
_xor);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
arm_simd_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride, /* in 32-bit words */
|
||||
int dst_stride, /* in 32-bit words */
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_8_8_asm_armv6 (
|
||||
width, height,
|
||||
(uint8_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4,
|
||||
(uint8_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 1), src_stride * 4);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_0565_0565_asm_armv6 (
|
||||
width, height,
|
||||
(uint16_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
|
||||
(uint16_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_8888_8888_asm_armv6 (
|
||||
width, height,
|
||||
(uint32_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
|
||||
(uint32_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 4), src_stride);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t arm_simd_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8b8g8r8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8b8g8r8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, armv6_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, armv6_composite_over_reverse_n_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, a8r8g8b8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, x8r8g8b8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, a8b8g8r8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, x8b8g8r8, armv6_composite_in_reverse_8888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, armv6_composite_over_n_8888_8888_ca),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
|
||||
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths);
|
||||
|
||||
imp->blt = arm_simd_blt;
|
||||
imp->fill = arm_simd_fill;
|
||||
|
||||
return imp;
|
||||
}
|
256
vendor/pixman/pixman/pixman-arm.c
vendored
Normal file
256
vendor/pixman/pixman/pixman-arm.c
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ARM_V7 = (1 << 0),
|
||||
ARM_V6 = (1 << 1),
|
||||
ARM_VFP = (1 << 2),
|
||||
ARM_NEON = (1 << 3),
|
||||
ARM_IWMMXT = (1 << 4)
|
||||
} arm_cpu_features_t;
|
||||
|
||||
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
|
||||
#include <windows.h>
|
||||
|
||||
extern int pixman_msvc_try_arm_neon_op ();
|
||||
extern int pixman_msvc_try_arm_simd_op ();
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
pixman_msvc_try_arm_simd_op ();
|
||||
features |= ARM_V6;
|
||||
}
|
||||
__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
pixman_msvc_try_arm_neon_op ();
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */
|
||||
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_V6;
|
||||
|
||||
/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
|
||||
* contain separate executable images for each processor architecture.
|
||||
* So all we have to do is detect the armv7 architecture build. The
|
||||
* operating system automatically runs the armv7 binary for armv7 devices
|
||||
* and the armv6 binary for armv6 devices.
|
||||
*/
|
||||
#if defined(__ARM_NEON__)
|
||||
features |= ARM_NEON;
|
||||
#endif
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined(__ANDROID__) || defined(ANDROID) /* Android */
|
||||
|
||||
#include <cpu-features.h>
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
AndroidCpuFamily cpu_family;
|
||||
uint64_t cpu_features;
|
||||
|
||||
cpu_family = android_getCpuFamily();
|
||||
cpu_features = android_getCpuFeatures();
|
||||
|
||||
if (cpu_family == ANDROID_CPU_FAMILY_ARM)
|
||||
{
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
|
||||
features |= ARM_V7;
|
||||
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
|
||||
features |= ARM_VFP;
|
||||
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (__linux__) /* linux ELF */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
Elf32_auxv_t aux;
|
||||
int fd;
|
||||
|
||||
fd = open ("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
|
||||
{
|
||||
if (aux.a_type == AT_HWCAP)
|
||||
{
|
||||
uint32_t hwcap = aux.a_un.a_val;
|
||||
|
||||
/* hardcode these values to avoid depending on specific
|
||||
* versions of the hwcap header, e.g. HWCAP_NEON
|
||||
*/
|
||||
if ((hwcap & 64) != 0)
|
||||
features |= ARM_VFP;
|
||||
if ((hwcap & 512) != 0)
|
||||
features |= ARM_IWMMXT;
|
||||
/* this flag is only present on kernel 2.6.29 */
|
||||
if ((hwcap & 4096) != 0)
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
else if (aux.a_type == AT_PLATFORM)
|
||||
{
|
||||
const char *plat = (const char*) aux.a_un.a_val;
|
||||
|
||||
if (strncmp (plat, "v7l", 3) == 0)
|
||||
features |= (ARM_V7 | ARM_V6);
|
||||
else if (strncmp (plat, "v6l", 3) == 0)
|
||||
features |= ARM_V6;
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (_3DS) /* 3DS homebrew (devkitARM) */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_V6;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (PSP2) || defined (__SWITCH__)
|
||||
/* Vita (VitaSDK) or Switch (devkitA64) homebrew */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_NEON;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#else /* Unknown */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* Linux elf */
|
||||
|
||||
static pixman_bool_t
|
||||
have_feature (arm_cpu_features_t feature)
|
||||
{
|
||||
static pixman_bool_t initialized;
|
||||
static arm_cpu_features_t features;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
features = detect_cpu_features();
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return (features & feature) == feature;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_arm_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_ARM_SIMD
|
||||
if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6))
|
||||
imp = _pixman_implementation_create_arm_simd (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_IWMMXT
|
||||
if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT))
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_NEON
|
||||
if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON))
|
||||
imp = _pixman_implementation_create_arm_neon (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_A64_NEON
|
||||
/* neon is a part of aarch64 */
|
||||
if (!_pixman_disabled ("arm-neon"))
|
||||
imp = _pixman_implementation_create_arm_neon (imp);
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
1275
vendor/pixman/pixman/pixman-arma64-neon-asm-bilinear.S
vendored
Normal file
1275
vendor/pixman/pixman/pixman-arma64-neon-asm-bilinear.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3704
vendor/pixman/pixman/pixman-arma64-neon-asm.S
vendored
Normal file
3704
vendor/pixman/pixman/pixman-arma64-neon-asm.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1310
vendor/pixman/pixman/pixman-arma64-neon-asm.h
vendored
Normal file
1310
vendor/pixman/pixman/pixman-arma64-neon-asm.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1383
vendor/pixman/pixman/pixman-bits-image.c
vendored
Normal file
1383
vendor/pixman/pixman/pixman-bits-image.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1158
vendor/pixman/pixman/pixman-combine-float.c
vendored
Normal file
1158
vendor/pixman/pixman/pixman-combine-float.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1189
vendor/pixman/pixman/pixman-combine32.c
vendored
Normal file
1189
vendor/pixman/pixman/pixman-combine32.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
272
vendor/pixman/pixman/pixman-combine32.h
vendored
Normal file
272
vendor/pixman/pixman/pixman-combine32.h
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
#define COMPONENT_SIZE 8
|
||||
#define MASK 0xff
|
||||
#define ONE_HALF 0x80
|
||||
|
||||
#define A_SHIFT 8 * 3
|
||||
#define R_SHIFT 8 * 2
|
||||
#define G_SHIFT 8
|
||||
#define A_MASK 0xff000000
|
||||
#define R_MASK 0xff0000
|
||||
#define G_MASK 0xff00
|
||||
|
||||
#define RB_MASK 0xff00ff
|
||||
#define AG_MASK 0xff00ff00
|
||||
#define RB_ONE_HALF 0x800080
|
||||
#define RB_MASK_PLUS_ONE 0x1000100
|
||||
|
||||
#define ALPHA_8(x) ((x) >> A_SHIFT)
|
||||
#define RED_8(x) (((x) >> R_SHIFT) & MASK)
|
||||
#define GREEN_8(x) (((x) >> G_SHIFT) & MASK)
|
||||
#define BLUE_8(x) ((x) & MASK)
|
||||
|
||||
/*
|
||||
* ARMv6 has UQADD8 instruction, which implements unsigned saturated
|
||||
* addition for 8-bit values packed in 32-bit registers. It is very useful
|
||||
* for UN8x4_ADD_UN8x4, UN8_rb_ADD_UN8_rb and ADD_UN8 macros (which would
|
||||
* otherwise need a lot of arithmetic operations to simulate this operation).
|
||||
* Since most of the major ARM linux distros are built for ARMv7, we are
|
||||
* much less dependent on runtime CPU detection and can get practical
|
||||
* benefits from conditional compilation here for a lot of users.
|
||||
*/
|
||||
|
||||
#if defined(USE_GCC_INLINE_ASM) && defined(__arm__) && \
|
||||
!defined(__aarch64__) && (!defined(__thumb__) || defined(__thumb2__))
|
||||
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
|
||||
defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
|
||||
defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \
|
||||
defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7__) || \
|
||||
defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
|
||||
defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
static force_inline uint32_t
|
||||
un8x4_add_un8x4 (uint32_t x, uint32_t y)
|
||||
{
|
||||
uint32_t t;
|
||||
asm ("uqadd8 %0, %1, %2" : "=r" (t) : "%r" (x), "r" (y));
|
||||
return t;
|
||||
}
|
||||
|
||||
#define UN8x4_ADD_UN8x4(x, y) \
|
||||
((x) = un8x4_add_un8x4 ((x), (y)))
|
||||
|
||||
#define UN8_rb_ADD_UN8_rb(x, y, t) \
|
||||
((t) = un8x4_add_un8x4 ((x), (y)), (x) = (t))
|
||||
|
||||
#define ADD_UN8(x, y, t) \
|
||||
((t) = (x), un8x4_add_un8x4 ((t), (y)))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
|
||||
#define MUL_UN8(a, b, t) \
|
||||
((t) = (a) * (uint16_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
|
||||
#define DIV_UN8(a, b) \
|
||||
(((uint16_t) (a) * MASK + ((b) / 2)) / (b))
|
||||
|
||||
#ifndef ADD_UN8
|
||||
#define ADD_UN8(x, y, t) \
|
||||
((t) = (x) + (y), \
|
||||
(uint32_t) (uint8_t) ((t) | (0 - ((t) >> G_SHIFT))))
|
||||
#endif
|
||||
|
||||
#define DIV_ONE_UN8(x) \
|
||||
(((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
|
||||
|
||||
/*
|
||||
* The methods below use some tricks to be able to do two color
|
||||
* components at the same time.
|
||||
*/
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) & RB_MASK) * (a); \
|
||||
t += RB_ONE_HALF; \
|
||||
x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x &= RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = min (x_rb + y_rb, 255)
|
||||
*/
|
||||
#ifndef UN8_rb_ADD_UN8_rb
|
||||
#define UN8_rb_ADD_UN8_rb(x, y, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) + (y)); \
|
||||
t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
|
||||
x = (t & RB_MASK); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a_rb) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8_rb(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = (x & MASK) * (a & MASK); \
|
||||
t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
|
||||
t += RB_ONE_HALF; \
|
||||
t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x = t & RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((y) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((a) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = (y) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = min(x_c + y_c, 255)
|
||||
*/
|
||||
#ifndef UN8x4_ADD_UN8x4
|
||||
#define UN8x4_ADD_UN8x4(x, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x) & RB_MASK; \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT) & RB_MASK; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
#endif
|
234
vendor/pixman/pixman/pixman-compiler.h
vendored
Normal file
234
vendor/pixman/pixman/pixman-compiler.h
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
/* Pixman uses some non-standard compiler features. This file ensures
|
||||
* they exist
|
||||
*
|
||||
* The features are:
|
||||
*
|
||||
* FUNC must be defined to expand to the current function
|
||||
* PIXMAN_EXPORT should be defined to whatever is required to
|
||||
* export functions from a shared library
|
||||
* limits limits for various types must be defined
|
||||
* inline must be defined
|
||||
* force_inline must be defined
|
||||
*/
|
||||
#if defined (__GNUC__)
|
||||
# define FUNC ((const char*) (__PRETTY_FUNCTION__))
|
||||
#elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
# define FUNC ((const char*) (__func__))
|
||||
#else
|
||||
# define FUNC ((const char*) ("???"))
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define unlikely(expr) __builtin_expect ((expr), 0)
|
||||
#else
|
||||
# define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX (32767)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX (2147483647)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MIN
|
||||
# define UINT32_MIN (0)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MIN
|
||||
# define INT64_MIN (-9223372036854775807-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MAX
|
||||
# define INT64_MAX (9223372036854775807)
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 'inline' is available only in C++ in MSVC */
|
||||
# define inline __inline
|
||||
# define force_inline __forceinline
|
||||
# define noinline __declspec(noinline)
|
||||
#elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
|
||||
# define inline __inline__
|
||||
# define force_inline __inline__ __attribute__ ((__always_inline__))
|
||||
# define noinline __attribute__((noinline))
|
||||
#else
|
||||
# ifndef force_inline
|
||||
# define force_inline inline
|
||||
# endif
|
||||
# ifndef noinline
|
||||
# define noinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* GCC visibility */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
|
||||
# define PIXMAN_EXPORT __attribute__ ((visibility("default")))
|
||||
/* Sun Studio 8 visibility */
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
# define PIXMAN_EXPORT __global
|
||||
#elif defined (_MSC_VER) || defined(__MINGW32__)
|
||||
# define PIXMAN_EXPORT PIXMAN_API
|
||||
#else
|
||||
# define PIXMAN_EXPORT
|
||||
#endif
|
||||
|
||||
/* member offsets */
|
||||
#define CONTAINER_OF(type, member, data) \
|
||||
((type *)(((uint8_t *)data) - offsetof (type, member)))
|
||||
|
||||
/* TLS */
|
||||
#if defined(PIXMAN_NO_TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static TLS type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
|
||||
# define _NO_W32_PSEUDO_MODIFIERS
|
||||
# include <windows.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static volatile int tls_ ## name ## _initialized = 0; \
|
||||
static void *tls_ ## name ## _mutex = NULL; \
|
||||
static unsigned tls_ ## name ## _index; \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
TlsSetValue (tls_ ## name ## _index, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value; \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
if (!tls_ ## name ## _mutex) \
|
||||
{ \
|
||||
void *mutex = CreateMutexA (NULL, 0, NULL); \
|
||||
if (InterlockedCompareExchangePointer ( \
|
||||
&tls_ ## name ## _mutex, mutex, NULL) != NULL) \
|
||||
{ \
|
||||
CloseHandle (mutex); \
|
||||
} \
|
||||
} \
|
||||
WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
tls_ ## name ## _index = TlsAlloc (); \
|
||||
tls_ ## name ## _initialized = 1; \
|
||||
} \
|
||||
ReleaseMutex (tls_ ## name ## _mutex); \
|
||||
} \
|
||||
if (tls_ ## name ## _index == 0xFFFFFFFF) \
|
||||
return NULL; \
|
||||
value = TlsGetValue (tls_ ## name ## _index); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static __declspec(thread) type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(HAVE_PTHREADS)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
|
||||
static pthread_key_t tls_ ## name ## _key; \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _destroy_value (void *value) \
|
||||
{ \
|
||||
free (value); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _make_key (void) \
|
||||
{ \
|
||||
pthread_key_create (&tls_ ## name ## _key, \
|
||||
tls_ ## name ## _destroy_value); \
|
||||
} \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
pthread_setspecific (tls_ ## name ## _key, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value = NULL; \
|
||||
if (pthread_once (&tls_ ## name ## _once_control, \
|
||||
tls_ ## name ## _make_key) == 0) \
|
||||
{ \
|
||||
value = pthread_getspecific (tls_ ## name ## _key); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
} \
|
||||
return value; \
|
||||
}
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#else
|
||||
|
||||
# error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support."
|
||||
|
||||
#endif
|
220
vendor/pixman/pixman/pixman-conical-gradient.c
vendored
Normal file
220
vendor/pixman/pixman/pixman-conical-gradient.c
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static force_inline double
|
||||
coordinates_to_parameter (double x, double y, double angle)
|
||||
{
|
||||
double t;
|
||||
|
||||
t = atan2 (y, x) + angle;
|
||||
|
||||
while (t < 0)
|
||||
t += 2 * M_PI;
|
||||
|
||||
while (t >= 2 * M_PI)
|
||||
t -= 2 * M_PI;
|
||||
|
||||
return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
|
||||
* make rotation CCW
|
||||
*/
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
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;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
conical_gradient_t *conical = (conical_gradient_t *)image;
|
||||
uint32_t *end = buffer + width * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_bool_t affine = TRUE;
|
||||
double cx = 1.;
|
||||
double cy = 0.;
|
||||
double cz = 0.;
|
||||
double rx = x + 0.5;
|
||||
double ry = y + 0.5;
|
||||
double rz = 1.;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
pixman_vector_t v;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
cx = image->common.transform->matrix[0][0] / 65536.;
|
||||
cy = image->common.transform->matrix[1][0] / 65536.;
|
||||
cz = image->common.transform->matrix[2][0] / 65536.;
|
||||
|
||||
rx = v.vector[0] / 65536.;
|
||||
ry = v.vector[1] / 65536.;
|
||||
rz = v.vector[2] / 65536.;
|
||||
|
||||
affine =
|
||||
image->common.transform->matrix[2][0] == 0 &&
|
||||
v.vector[2] == pixman_fixed_1;
|
||||
}
|
||||
|
||||
if (affine)
|
||||
{
|
||||
rx -= conical->center.x / 65536.;
|
||||
ry -= conical->center.y / 65536.;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t = coordinates_to_parameter (rx, ry, conical->angle);
|
||||
|
||||
write_pixel (&walker,
|
||||
(pixman_fixed_48_16_t)pixman_double_to_fixed (t),
|
||||
buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (buffer < end)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (rz != 0)
|
||||
{
|
||||
x = rx / rz;
|
||||
y = ry / rz;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = y = 0.;
|
||||
}
|
||||
|
||||
x -= conical->center.x / 65536.;
|
||||
y -= conical->center.y / 65536.;
|
||||
|
||||
t = coordinates_to_parameter (x, y, conical->angle);
|
||||
|
||||
write_pixel (&walker,
|
||||
(pixman_fixed_48_16_t)pixman_double_to_fixed (t),
|
||||
buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
rz += cz;
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
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)
|
||||
{
|
||||
return conical_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = conical_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = conical_get_scanline_wide;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_conical_gradient (const pixman_point_fixed_t * center,
|
||||
pixman_fixed_t angle,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image = _pixman_image_allocate ();
|
||||
conical_gradient_t *conical;
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
conical = &image->conical;
|
||||
|
||||
if (!_pixman_init_gradient (&conical->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = MOD (angle, pixman_int_to_fixed (360));
|
||||
|
||||
image->type = CONICAL;
|
||||
|
||||
conical->center = *center;
|
||||
conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
4
vendor/pixman/pixman/pixman-edge-accessors.c
vendored
Normal file
4
vendor/pixman/pixman/pixman-edge-accessors.c
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-edge.c"
|
182
vendor/pixman/pixman/pixman-edge-imp.h
vendored
Normal file
182
vendor/pixman/pixman/pixman-edge-imp.h
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef rasterize_span
|
||||
#endif
|
||||
|
||||
static void
|
||||
RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t *l,
|
||||
pixman_edge_t *r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
pixman_fixed_t lx;
|
||||
pixman_fixed_t rx;
|
||||
int lxi;
|
||||
int rxi;
|
||||
|
||||
lx = l->x;
|
||||
rx = r->x;
|
||||
#if N_BITS == 1
|
||||
/* For the non-antialiased case, round the coordinates up, in effect
|
||||
* sampling just slightly to the left of the pixel. This is so that
|
||||
* when the sample point lies exactly on the line, we round towards
|
||||
* north-west.
|
||||
*
|
||||
* (The AA case does a similar adjustment in RENDER_SAMPLES_X)
|
||||
*/
|
||||
lx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
rx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
#endif
|
||||
/* clip X */
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
#if N_BITS == 1
|
||||
rx = pixman_int_to_fixed (width);
|
||||
#else
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
#endif
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
|
||||
/* Find pixel bounds for span */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
#if N_BITS == 1
|
||||
{
|
||||
|
||||
#define LEFT_MASK(x) \
|
||||
(((x) & 0x1f) ? \
|
||||
SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
|
||||
#define RIGHT_MASK(x) \
|
||||
(((32 - (x)) & 0x1f) ? \
|
||||
SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0)
|
||||
|
||||
#define MASK_BITS(x,w,l,n,r) { \
|
||||
n = (w); \
|
||||
r = RIGHT_MASK ((x) + n); \
|
||||
l = LEFT_MASK (x); \
|
||||
if (l) { \
|
||||
n -= 32 - ((x) & 0x1f); \
|
||||
if (n < 0) { \
|
||||
n = 0; \
|
||||
l &= r; \
|
||||
r = 0; \
|
||||
} \
|
||||
} \
|
||||
n >>= 5; \
|
||||
}
|
||||
|
||||
uint32_t *a = line;
|
||||
uint32_t startmask;
|
||||
uint32_t endmask;
|
||||
int nmiddle;
|
||||
int width = rxi - lxi;
|
||||
int x = lxi;
|
||||
|
||||
a += x >> 5;
|
||||
x &= 0x1f;
|
||||
|
||||
MASK_BITS (x, width, startmask, nmiddle, endmask);
|
||||
|
||||
if (startmask) {
|
||||
WRITE(image, a, READ(image, a) | startmask);
|
||||
a++;
|
||||
}
|
||||
while (nmiddle--)
|
||||
WRITE(image, a++, 0xffffffff);
|
||||
if (endmask)
|
||||
WRITE(image, a, READ(image, a) | endmask);
|
||||
}
|
||||
#else
|
||||
{
|
||||
DEFINE_ALPHA(line,lxi);
|
||||
int lxs;
|
||||
int rxs;
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, N_BITS);
|
||||
rxs = RENDER_SAMPLES_X (rx, N_BITS);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
ADD_ALPHA (rxs - lxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xi;
|
||||
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS) - lxs);
|
||||
STEP_ALPHA;
|
||||
for (xi = lxi + 1; xi < rxi; xi++)
|
||||
{
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS));
|
||||
STEP_ALPHA;
|
||||
}
|
||||
ADD_ALPHA (rxs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
break;
|
||||
|
||||
#if N_BITS > 1
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL(N_BITS);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG(N_BITS);
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef rasterize_span
|
385
vendor/pixman/pixman/pixman-edge.c
vendored
Normal file
385
vendor/pixman/pixman/pixman-edge.c
vendored
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-accessor.h"
|
||||
|
||||
/*
|
||||
* Step across a small sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_SMALL(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_small; \
|
||||
edge->e += edge->dx_small; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Step across a large sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_BIG(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_big; \
|
||||
edge->e += edge->dx_big; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
|
||||
#else
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 4
|
||||
#define RASTERIZE_EDGES rasterize_edges_4
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#define SHIFT_4(o) ((o) << 2)
|
||||
#else
|
||||
#define SHIFT_4(o) ((1 - (o)) << 2)
|
||||
#endif
|
||||
|
||||
#define GET_4(x, o) (((x) >> SHIFT_4 (o)) & 0xf)
|
||||
#define PUT_4(x, o, v) \
|
||||
(((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
|
||||
|
||||
#define DEFINE_ALPHA(line, x) \
|
||||
uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \
|
||||
int __ao = (x) & 1
|
||||
|
||||
#define STEP_ALPHA ((__ap += __ao), (__ao ^= 1))
|
||||
|
||||
#define ADD_ALPHA(a) \
|
||||
{ \
|
||||
uint8_t __o = READ (image, __ap); \
|
||||
uint8_t __a = (a) + GET_4 (__o, __ao); \
|
||||
WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
|
||||
}
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef ADD_ALPHA
|
||||
#undef STEP_ALPHA
|
||||
#undef DEFINE_ALPHA
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
|
||||
/*
|
||||
* 1 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 1
|
||||
#define RASTERIZE_EDGES rasterize_edges_1
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
/*
|
||||
* 8 bit alpha
|
||||
*/
|
||||
|
||||
static force_inline uint8_t
|
||||
clip255 (int x)
|
||||
{
|
||||
if (x > 255)
|
||||
return 255;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#define ADD_SATURATE_8(buf, val, length) \
|
||||
do \
|
||||
{ \
|
||||
int i__ = (length); \
|
||||
uint8_t *buf__ = (buf); \
|
||||
int val__ = (val); \
|
||||
\
|
||||
while (i__--) \
|
||||
{ \
|
||||
WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
|
||||
(buf__)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* We want to detect the case where we add the same value to a long
|
||||
* span of pixels. The triangles on the end are filled in while we
|
||||
* count how many sub-pixel scanlines contribute to the middle section.
|
||||
*
|
||||
* +--------------------------+
|
||||
* fill_height =| \ /
|
||||
* +------------------+
|
||||
* |================|
|
||||
* fill_start fill_end
|
||||
*/
|
||||
static void
|
||||
rasterize_edges_8 (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
int fill_start = -1, fill_end = -1;
|
||||
int fill_size = 0;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t *ap = (uint8_t *) line;
|
||||
pixman_fixed_t lx, rx;
|
||||
int lxi, rxi;
|
||||
|
||||
/* clip X */
|
||||
lx = l->x;
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
|
||||
rx = r->x;
|
||||
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
{
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
}
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
int lxs, rxs;
|
||||
|
||||
/* Find pixel bounds for span. */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, 8);
|
||||
rxs = RENDER_SAMPLES_X (rx, 8);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + rxs - lxs));
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
|
||||
|
||||
/* Move forward so that lxi/rxi is the pixel span */
|
||||
lxi++;
|
||||
|
||||
/* Don't bother trying to optimize the fill unless
|
||||
* the span is longer than 4 pixels. */
|
||||
if (rxi - lxi > 4)
|
||||
{
|
||||
if (fill_start < 0)
|
||||
{
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lxi >= fill_end || rxi < fill_start)
|
||||
{
|
||||
/* We're beyond what we saved, just fill it */
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update fill_start */
|
||||
if (lxi > fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
lxi - fill_start);
|
||||
fill_start = lxi;
|
||||
}
|
||||
else if (lxi < fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
|
||||
fill_start - lxi);
|
||||
}
|
||||
|
||||
/* Update fill_end */
|
||||
if (rxi < fill_end)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + rxi,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - rxi);
|
||||
fill_end = rxi;
|
||||
}
|
||||
else if (fill_end < rxi)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_end,
|
||||
N_X_FRAC (8),
|
||||
rxi - fill_end);
|
||||
}
|
||||
fill_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
|
||||
}
|
||||
|
||||
WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
|
||||
}
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
{
|
||||
/* We're done, make sure we clean up any remaining fill. */
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL (8);
|
||||
}
|
||||
else
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG (8);
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
|
||||
fill_start = fill_end = -1;
|
||||
fill_size = 0;
|
||||
}
|
||||
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
static
|
||||
#endif
|
||||
void
|
||||
PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
switch (PIXMAN_FORMAT_BPP (image->bits.format))
|
||||
{
|
||||
case 1:
|
||||
rasterize_edges_1 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rasterize_edges_4 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
rasterize_edges_8 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_rasterize_edges (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
return_if_fail (image->type == BITS);
|
||||
return_if_fail (PIXMAN_FORMAT_TYPE (image->bits.format) == PIXMAN_TYPE_A);
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
pixman_rasterize_edges_accessors (image, l, r, t, b);
|
||||
else
|
||||
pixman_rasterize_edges_no_accessors (image, l, r, t, b);
|
||||
}
|
||||
|
||||
#endif
|
3298
vendor/pixman/pixman/pixman-fast-path.c
vendored
Normal file
3298
vendor/pixman/pixman/pixman-fast-path.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
491
vendor/pixman/pixman/pixman-filter.c
vendored
Normal file
491
vendor/pixman/pixman/pixman-filter.c
vendored
Normal file
@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright 2012, Red Hat, Inc.
|
||||
* Copyright 2012, Soren Sandmann
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <soren.sandmann@gmail.com>
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
typedef double (* kernel_func_t) (double x);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixman_kernel_t kernel;
|
||||
kernel_func_t func;
|
||||
double width;
|
||||
} filter_info_t;
|
||||
|
||||
static double
|
||||
impulse_kernel (double x)
|
||||
{
|
||||
return (x == 0.0)? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
static double
|
||||
box_kernel (double x)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static double
|
||||
linear_kernel (double x)
|
||||
{
|
||||
return 1 - fabs (x);
|
||||
}
|
||||
|
||||
static double
|
||||
gaussian_kernel (double x)
|
||||
{
|
||||
#define SQRT2 (1.4142135623730950488016887242096980785696718753769480)
|
||||
#define SIGMA (SQRT2 / 2.0)
|
||||
|
||||
return exp (- x * x / (2 * SIGMA * SIGMA)) / (SIGMA * sqrt (2.0 * M_PI));
|
||||
}
|
||||
|
||||
static double
|
||||
sinc (double x)
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 1.0;
|
||||
else
|
||||
return sin (M_PI * x) / (M_PI * x);
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos (double x, int n)
|
||||
{
|
||||
return sinc (x) * sinc (x * (1.0 / n));
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos2_kernel (double x)
|
||||
{
|
||||
return lanczos (x, 2);
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos3_kernel (double x)
|
||||
{
|
||||
return lanczos (x, 3);
|
||||
}
|
||||
|
||||
static double
|
||||
nice_kernel (double x)
|
||||
{
|
||||
return lanczos3_kernel (x * 0.75);
|
||||
}
|
||||
|
||||
static double
|
||||
general_cubic (double x, double B, double C)
|
||||
{
|
||||
double ax = fabs(x);
|
||||
|
||||
if (ax < 1)
|
||||
{
|
||||
return (((12 - 9 * B - 6 * C) * ax +
|
||||
(-18 + 12 * B + 6 * C)) * ax * ax +
|
||||
(6 - 2 * B)) / 6;
|
||||
}
|
||||
else if (ax < 2)
|
||||
{
|
||||
return ((((-B - 6 * C) * ax +
|
||||
(6 * B + 30 * C)) * ax +
|
||||
(-12 * B - 48 * C)) * ax +
|
||||
(8 * B + 24 * C)) / 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
cubic_kernel (double x)
|
||||
{
|
||||
/* This is the Mitchell-Netravali filter.
|
||||
*
|
||||
* (0.0, 0.5) would give us the Catmull-Rom spline,
|
||||
* but that one seems to be indistinguishable from Lanczos2.
|
||||
*/
|
||||
return general_cubic (x, 1/3.0, 1/3.0);
|
||||
}
|
||||
|
||||
static const filter_info_t filters[] =
|
||||
{
|
||||
{ PIXMAN_KERNEL_IMPULSE, impulse_kernel, 0.0 },
|
||||
{ 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, 5.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS2, lanczos2_kernel, 4.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS3, lanczos3_kernel, 6.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS3_STRETCHED, nice_kernel, 8.0 },
|
||||
};
|
||||
|
||||
/* This function scales @kernel2 by @scale, then
|
||||
* aligns @x1 in @kernel1 with @x2 in @kernel2 and
|
||||
* and integrates the product of the kernels across @width.
|
||||
*
|
||||
* This function assumes that the intervals are within
|
||||
* the kernels in question. E.g., the caller must not
|
||||
* try to integrate a linear kernel ouside of [-1:1]
|
||||
*/
|
||||
static double
|
||||
integral (pixman_kernel_t kernel1, double x1,
|
||||
pixman_kernel_t kernel2, double scale, double x2,
|
||||
double width)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
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 (kernel2 == PIXMAN_KERNEL_LINEAR && x2 < 0 && x2 + width > 0)
|
||||
{
|
||||
return
|
||||
integral (kernel1, x1, kernel2, scale, x2, - x2) +
|
||||
integral (kernel1, x1 - x2, kernel2, scale, 0, width + x2);
|
||||
}
|
||||
else if (kernel1 == PIXMAN_KERNEL_IMPULSE)
|
||||
{
|
||||
assert (width == 0.0);
|
||||
return filters[kernel2].func (x2 * scale);
|
||||
}
|
||||
else if (kernel2 == PIXMAN_KERNEL_IMPULSE)
|
||||
{
|
||||
assert (width == 0.0);
|
||||
return filters[kernel1].func (x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 / N_SEGMENTS;
|
||||
int i;
|
||||
|
||||
s = SAMPLE (x1, x2);
|
||||
|
||||
for (i = 1; i < N_SEGMENTS; i += 2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
s += SAMPLE (x1 + width, x2 + width);
|
||||
|
||||
return h * s * (1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_1d_filter (int width,
|
||||
pixman_kernel_t reconstruct,
|
||||
pixman_kernel_t sample,
|
||||
double scale,
|
||||
int n_phases,
|
||||
pixman_fixed_t *pstart,
|
||||
pixman_fixed_t *pend
|
||||
)
|
||||
{
|
||||
pixman_fixed_t *p = pstart;
|
||||
double step;
|
||||
int i;
|
||||
if(width <= 0) return;
|
||||
step = 1.0 / n_phases;
|
||||
|
||||
for (i = 0; i < n_phases; ++i)
|
||||
{
|
||||
double frac = step / 2.0 + i * step;
|
||||
pixman_fixed_t new_total;
|
||||
int x, x1, x2;
|
||||
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;
|
||||
assert( p >= pstart && p + (x2 - x1) <= pend ); /* assert validity of the following loop */
|
||||
total = 0;
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
double pos = x + 0.5 - frac;
|
||||
double rlow = - filters[reconstruct].width / 2.0;
|
||||
double rhigh = rlow + filters[reconstruct].width;
|
||||
double slow = pos - scale * filters[sample].width / 2.0;
|
||||
double shigh = slow + scale * filters[sample].width;
|
||||
double c = 0.0;
|
||||
double ilow, ihigh;
|
||||
|
||||
if (rhigh >= slow && rlow <= shigh)
|
||||
{
|
||||
ilow = MAX (slow, rlow);
|
||||
ihigh = MIN (shigh, rhigh);
|
||||
|
||||
c = integral (reconstruct, ilow,
|
||||
sample, 1.0 / scale, ilow - pos,
|
||||
ihigh - ilow);
|
||||
}
|
||||
|
||||
*p = (pixman_fixed_t)floor (c * 65536.0 + 0.5);
|
||||
total += *p;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Normalize, with error diffusion */
|
||||
p -= width;
|
||||
assert(p >= pstart && p + (x2 - x1) <= pend); /* assert validity of the following loop */
|
||||
|
||||
total = 65536.0 / total;
|
||||
new_total = 0;
|
||||
e = 0.0;
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
double v = (*p) * total + e;
|
||||
pixman_fixed_t t = floor (v + 0.5);
|
||||
|
||||
e = v - t;
|
||||
new_total += t;
|
||||
*p++ = t;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
assert(p - width >= pstart && p - width < pend); /* assert... */
|
||||
*(p - width) += pixman_fixed_1 - new_total;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_fixed_t *
|
||||
pixman_filter_create_separable_convolution (int *n_values,
|
||||
pixman_fixed_t scale_x,
|
||||
pixman_fixed_t scale_y,
|
||||
pixman_kernel_t reconstruct_x,
|
||||
pixman_kernel_t reconstruct_y,
|
||||
pixman_kernel_t sample_x,
|
||||
pixman_kernel_t sample_y,
|
||||
int subsample_bits_x,
|
||||
int subsample_bits_y)
|
||||
{
|
||||
double sx = fabs (pixman_fixed_to_double (scale_x));
|
||||
double sy = fabs (pixman_fixed_to_double (scale_y));
|
||||
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);
|
||||
|
||||
height = filter_width (reconstruct_y, sample_y, sy);
|
||||
subsample_y = (1 << subsample_bits_y);
|
||||
|
||||
*n_values = 4 + width * subsample_x + height * subsample_y;
|
||||
|
||||
params = malloc (*n_values * sizeof (pixman_fixed_t));
|
||||
if (!params)
|
||||
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);
|
||||
|
||||
{
|
||||
pixman_fixed_t
|
||||
*xparams = params+4,
|
||||
*yparams = xparams + width*subsample_x,
|
||||
*endparams = params + *n_values;
|
||||
create_1d_filter(width, reconstruct_x, sample_x, sx, subsample_x,
|
||||
xparams, yparams);
|
||||
create_1d_filter(height, reconstruct_y, sample_y, sy, subsample_y,
|
||||
yparams, endparams);
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_GNUPLOT
|
||||
gnuplot_filter(width, subsample_x, params + 4);
|
||||
#endif
|
||||
|
||||
return params;
|
||||
}
|
264
vendor/pixman/pixman/pixman-general.c
vendored
Normal file
264
vendor/pixman/pixman/pixman-general.c
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* 2008 Aaron Plattner, NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static void
|
||||
general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
|
||||
switch (image->type)
|
||||
{
|
||||
case BITS:
|
||||
if ((iter->iter_flags & ITER_SRC) == ITER_SRC)
|
||||
_pixman_bits_image_src_iter_init (image, iter);
|
||||
else
|
||||
_pixman_bits_image_dest_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case LINEAR:
|
||||
_pixman_linear_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case RADIAL:
|
||||
_pixman_radial_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case CONICAL:
|
||||
_pixman_conical_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case SOLID:
|
||||
_pixman_log_error (FUNC, "Solid image not handled by noop");
|
||||
break;
|
||||
|
||||
default:
|
||||
_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_iter_info_t general_iters[] =
|
||||
{
|
||||
{ PIXMAN_any, 0, 0, general_iter_init, NULL, NULL },
|
||||
{ PIXMAN_null },
|
||||
};
|
||||
|
||||
typedef struct op_info_t op_info_t;
|
||||
struct op_info_t
|
||||
{
|
||||
uint8_t src, dst;
|
||||
};
|
||||
|
||||
#define ITER_IGNORE_BOTH \
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
|
||||
|
||||
static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
|
||||
{
|
||||
/* Src Dst */
|
||||
{ ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */
|
||||
{ ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */
|
||||
{ 0, ITER_LOCALIZED_ALPHA }, /* OVER */
|
||||
{ ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */
|
||||
{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */
|
||||
{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */
|
||||
{ 0, 0 }, /* ATOP */
|
||||
{ 0, 0 }, /* ATOP_REVERSE */
|
||||
{ 0, 0 }, /* XOR */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */
|
||||
{ 0, 0 }, /* SATURATE */
|
||||
};
|
||||
|
||||
#define SCANLINE_BUFFER_LENGTH 8192
|
||||
|
||||
static pixman_bool_t
|
||||
operator_needs_division (pixman_op_t op)
|
||||
{
|
||||
static const uint8_t needs_division[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* SATURATE */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* DISJOINT */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* CONJOINT */
|
||||
0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, /* blend ops */
|
||||
};
|
||||
|
||||
return needs_division[op];
|
||||
}
|
||||
|
||||
static void
|
||||
general_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
PIXMAN_COMPOSITE_ARGS (info);
|
||||
uint8_t stack_scanline_buffer[3 * SCANLINE_BUFFER_LENGTH];
|
||||
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
|
||||
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
|
||||
pixman_iter_t src_iter, mask_iter, dest_iter;
|
||||
pixman_combine_32_func_t compose;
|
||||
pixman_bool_t component_alpha;
|
||||
iter_flags_t width_flag, src_iter_flags;
|
||||
int Bpp;
|
||||
int i;
|
||||
|
||||
if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(dest_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
!(operator_needs_division (op)) &&
|
||||
(dest_image->bits.dither == PIXMAN_DITHER_NONE))
|
||||
{
|
||||
width_flag = ITER_NARROW;
|
||||
Bpp = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
width_flag = ITER_WIDE;
|
||||
Bpp = 16;
|
||||
}
|
||||
|
||||
#define ALIGN(addr) \
|
||||
((uint8_t *)((((uintptr_t)(addr)) + 15) & (~15)))
|
||||
|
||||
if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3))
|
||||
return;
|
||||
|
||||
if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 15 * 3)
|
||||
{
|
||||
scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 15 * 3);
|
||||
|
||||
if (!scanline_buffer)
|
||||
return;
|
||||
|
||||
memset (scanline_buffer, 0, width * Bpp * 3 + 15 * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (stack_scanline_buffer, 0, sizeof (stack_scanline_buffer));
|
||||
}
|
||||
|
||||
src_buffer = ALIGN (scanline_buffer);
|
||||
mask_buffer = ALIGN (src_buffer + width * Bpp);
|
||||
dest_buffer = ALIGN (mask_buffer + width * Bpp);
|
||||
|
||||
if (width_flag == ITER_WIDE)
|
||||
{
|
||||
/* To make sure there aren't any NANs in the buffers */
|
||||
memset (src_buffer, 0, width * Bpp);
|
||||
memset (mask_buffer, 0, width * Bpp);
|
||||
memset (dest_buffer, 0, width * Bpp);
|
||||
}
|
||||
|
||||
/* src iter */
|
||||
src_iter_flags = width_flag | op_flags[op].src | ITER_SRC;
|
||||
|
||||
_pixman_implementation_iter_init (imp->toplevel, &src_iter, src_image,
|
||||
src_x, src_y, width, height,
|
||||
src_buffer, src_iter_flags,
|
||||
info->src_flags);
|
||||
|
||||
/* mask iter */
|
||||
if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
|
||||
{
|
||||
/* If it doesn't matter what the source is, then it doesn't matter
|
||||
* what the mask is
|
||||
*/
|
||||
mask_image = NULL;
|
||||
}
|
||||
|
||||
component_alpha = mask_image && mask_image->common.component_alpha;
|
||||
|
||||
_pixman_implementation_iter_init (
|
||||
imp->toplevel, &mask_iter,
|
||||
mask_image, mask_x, mask_y, width, height, mask_buffer,
|
||||
ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB),
|
||||
info->mask_flags);
|
||||
|
||||
/* dest iter */
|
||||
_pixman_implementation_iter_init (
|
||||
imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
|
||||
dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
|
||||
|
||||
compose = _pixman_implementation_lookup_combiner (
|
||||
imp->toplevel, op, component_alpha, width_flag != ITER_WIDE);
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
{
|
||||
uint32_t *s, *m, *d;
|
||||
|
||||
m = mask_iter.get_scanline (&mask_iter, NULL);
|
||||
s = src_iter.get_scanline (&src_iter, m);
|
||||
d = dest_iter.get_scanline (&dest_iter, NULL);
|
||||
|
||||
compose (imp->toplevel, op, d, s, m, width);
|
||||
|
||||
dest_iter.write_back (&dest_iter);
|
||||
}
|
||||
|
||||
if (src_iter.fini)
|
||||
src_iter.fini (&src_iter);
|
||||
if (mask_iter.fini)
|
||||
mask_iter.fini (&mask_iter);
|
||||
if (dest_iter.fini)
|
||||
dest_iter.fini (&dest_iter);
|
||||
|
||||
if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
|
||||
free (scanline_buffer);
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t general_fast_path[] =
|
||||
{
|
||||
{ PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
|
||||
{ PIXMAN_OP_NONE }
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_general (void)
|
||||
{
|
||||
pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
|
||||
|
||||
_pixman_setup_combiner_functions_32 (imp);
|
||||
_pixman_setup_combiner_functions_float (imp);
|
||||
|
||||
imp->iter_info = general_iters;
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
676
vendor/pixman/pixman/pixman-glyph.c
vendored
Normal file
676
vendor/pixman/pixman/pixman-glyph.c
vendored
Normal file
@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Copyright 2010, 2012, Soren Sandmann <sandmann@cs.au.dk>
|
||||
* Copyright 2010, 2011, 2012, Red Hat, Inc
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@cs.au.dk>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct glyph_metrics_t glyph_metrics_t;
|
||||
typedef struct glyph_t glyph_t;
|
||||
|
||||
#define TOMBSTONE ((glyph_t *)0x1)
|
||||
|
||||
/* XXX: These numbers are arbitrary---we've never done any measurements.
|
||||
*/
|
||||
#define N_GLYPHS_HIGH_WATER (16384)
|
||||
#define N_GLYPHS_LOW_WATER (8192)
|
||||
#define HASH_SIZE (2 * N_GLYPHS_HIGH_WATER)
|
||||
#define HASH_MASK (HASH_SIZE - 1)
|
||||
|
||||
struct glyph_t
|
||||
{
|
||||
void * font_key;
|
||||
void * glyph_key;
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
pixman_image_t * image;
|
||||
pixman_link_t mru_link;
|
||||
};
|
||||
|
||||
struct pixman_glyph_cache_t
|
||||
{
|
||||
int n_glyphs;
|
||||
int n_tombstones;
|
||||
int freeze_count;
|
||||
pixman_list_t mru;
|
||||
glyph_t * glyphs[HASH_SIZE];
|
||||
};
|
||||
|
||||
static void
|
||||
free_glyph (glyph_t *glyph)
|
||||
{
|
||||
pixman_list_unlink (&glyph->mru_link);
|
||||
pixman_image_unref (glyph->image);
|
||||
free (glyph);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hash (const void *font_key, const void *glyph_key)
|
||||
{
|
||||
size_t key = (size_t)font_key + (size_t)glyph_key;
|
||||
|
||||
/* This hash function is based on one found on Thomas Wang's
|
||||
* web page at
|
||||
*
|
||||
* http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
*
|
||||
*/
|
||||
key = (key << 15) - key - 1;
|
||||
key = key ^ (key >> 12);
|
||||
key = key + (key << 2);
|
||||
key = key ^ (key >> 4);
|
||||
key = key + (key << 3) + (key << 11);
|
||||
key = key ^ (key >> 16);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static glyph_t *
|
||||
lookup_glyph (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
unsigned idx;
|
||||
glyph_t *g;
|
||||
|
||||
idx = hash (font_key, glyph_key);
|
||||
while ((g = cache->glyphs[idx++ & HASH_MASK]))
|
||||
{
|
||||
if (g != TOMBSTONE &&
|
||||
g->font_key == font_key &&
|
||||
g->glyph_key == glyph_key)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_glyph (pixman_glyph_cache_t *cache,
|
||||
glyph_t *glyph)
|
||||
{
|
||||
unsigned idx;
|
||||
glyph_t **loc;
|
||||
|
||||
idx = hash (glyph->font_key, glyph->glyph_key);
|
||||
|
||||
/* Note: we assume that there is room in the table. If there isn't,
|
||||
* this will be an infinite loop.
|
||||
*/
|
||||
do
|
||||
{
|
||||
loc = &cache->glyphs[idx++ & HASH_MASK];
|
||||
} while (*loc && *loc != TOMBSTONE);
|
||||
|
||||
if (*loc == TOMBSTONE)
|
||||
cache->n_tombstones--;
|
||||
cache->n_glyphs++;
|
||||
|
||||
*loc = glyph;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_glyph (pixman_glyph_cache_t *cache,
|
||||
glyph_t *glyph)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
idx = hash (glyph->font_key, glyph->glyph_key);
|
||||
while (cache->glyphs[idx & HASH_MASK] != glyph)
|
||||
idx++;
|
||||
|
||||
cache->glyphs[idx & HASH_MASK] = TOMBSTONE;
|
||||
cache->n_tombstones++;
|
||||
cache->n_glyphs--;
|
||||
|
||||
/* Eliminate tombstones if possible */
|
||||
if (cache->glyphs[(idx + 1) & HASH_MASK] == NULL)
|
||||
{
|
||||
while (cache->glyphs[idx & HASH_MASK] == TOMBSTONE)
|
||||
{
|
||||
cache->glyphs[idx & HASH_MASK] = NULL;
|
||||
cache->n_tombstones--;
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_table (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HASH_SIZE; ++i)
|
||||
{
|
||||
glyph_t *glyph = cache->glyphs[i];
|
||||
|
||||
if (glyph && glyph != TOMBSTONE)
|
||||
free_glyph (glyph);
|
||||
|
||||
cache->glyphs[i] = NULL;
|
||||
}
|
||||
|
||||
cache->n_glyphs = 0;
|
||||
cache->n_tombstones = 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_glyph_cache_t *
|
||||
pixman_glyph_cache_create (void)
|
||||
{
|
||||
pixman_glyph_cache_t *cache;
|
||||
|
||||
if (!(cache = malloc (sizeof *cache)))
|
||||
return NULL;
|
||||
|
||||
memset (cache->glyphs, 0, sizeof (cache->glyphs));
|
||||
cache->n_glyphs = 0;
|
||||
cache->n_tombstones = 0;
|
||||
cache->freeze_count = 0;
|
||||
|
||||
pixman_list_init (&cache->mru);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
return_if_fail (cache->freeze_count == 0);
|
||||
|
||||
clear_table (cache);
|
||||
|
||||
free (cache);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
cache->freeze_count++;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
if (--cache->freeze_count == 0 &&
|
||||
cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER)
|
||||
{
|
||||
if (cache->n_tombstones > N_GLYPHS_HIGH_WATER)
|
||||
{
|
||||
/* More than half the entries are
|
||||
* tombstones. Just dump the whole table.
|
||||
*/
|
||||
clear_table (cache);
|
||||
}
|
||||
|
||||
while (cache->n_glyphs > N_GLYPHS_LOW_WATER)
|
||||
{
|
||||
glyph_t *glyph = CONTAINER_OF (glyph_t, mru_link, cache->mru.tail);
|
||||
|
||||
remove_glyph (cache, glyph);
|
||||
free_glyph (glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT const void *
|
||||
pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
return lookup_glyph (cache, font_key, glyph_key);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT const void *
|
||||
pixman_glyph_cache_insert (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key,
|
||||
int origin_x,
|
||||
int origin_y,
|
||||
pixman_image_t *image)
|
||||
{
|
||||
glyph_t *glyph;
|
||||
int32_t width, height;
|
||||
|
||||
return_val_if_fail (cache->freeze_count > 0, NULL);
|
||||
return_val_if_fail (image->type == BITS, NULL);
|
||||
|
||||
width = image->bits.width;
|
||||
height = image->bits.height;
|
||||
|
||||
if (cache->n_glyphs >= HASH_SIZE)
|
||||
return NULL;
|
||||
|
||||
if (!(glyph = malloc (sizeof *glyph)))
|
||||
return NULL;
|
||||
|
||||
glyph->font_key = font_key;
|
||||
glyph->glyph_key = glyph_key;
|
||||
glyph->origin_x = origin_x;
|
||||
glyph->origin_y = origin_y;
|
||||
|
||||
if (!(glyph->image = pixman_image_create_bits (
|
||||
image->bits.format, width, height, NULL, -1)))
|
||||
{
|
||||
free (glyph);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixman_image_composite32 (PIXMAN_OP_SRC,
|
||||
image, NULL, glyph->image, 0, 0, 0, 0, 0, 0,
|
||||
width, height);
|
||||
|
||||
if (PIXMAN_FORMAT_A (glyph->image->bits.format) != 0 &&
|
||||
PIXMAN_FORMAT_RGB (glyph->image->bits.format) != 0)
|
||||
{
|
||||
pixman_image_set_component_alpha (glyph->image, TRUE);
|
||||
}
|
||||
|
||||
pixman_list_prepend (&cache->mru, &glyph->mru_link);
|
||||
|
||||
_pixman_image_validate (glyph->image);
|
||||
insert_glyph (cache, glyph);
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_remove (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
glyph_t *glyph;
|
||||
|
||||
if ((glyph = lookup_glyph (cache, font_key, glyph_key)))
|
||||
{
|
||||
remove_glyph (cache, glyph);
|
||||
|
||||
free_glyph (glyph);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_get_extents (pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
pixman_glyph_t *glyphs,
|
||||
pixman_box32_t *extents)
|
||||
{
|
||||
int i;
|
||||
|
||||
extents->x1 = extents->y1 = INT32_MAX;
|
||||
extents->x2 = extents->y2 = INT32_MIN;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
x1 = glyphs[i].x - glyph->origin_x;
|
||||
y1 = glyphs[i].y - glyph->origin_y;
|
||||
x2 = glyphs[i].x - glyph->origin_x + glyph->image->bits.width;
|
||||
y2 = glyphs[i].y - glyph->origin_y + glyph->image->bits.height;
|
||||
|
||||
if (x1 < extents->x1)
|
||||
extents->x1 = x1;
|
||||
if (y1 < extents->y1)
|
||||
extents->y1 = y1;
|
||||
if (x2 > extents->x2)
|
||||
extents->x2 = x2;
|
||||
if (y2 > extents->y2)
|
||||
extents->y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function returns a format that is suitable for use as a mask for the
|
||||
* set of glyphs in question.
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_format_code_t
|
||||
pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_format_code_t format = PIXMAN_a1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
const glyph_t *glyph = glyphs[i].glyph;
|
||||
pixman_format_code_t glyph_format = glyph->image->bits.format;
|
||||
|
||||
if (PIXMAN_FORMAT_TYPE (glyph_format) == PIXMAN_TYPE_A)
|
||||
{
|
||||
if (PIXMAN_FORMAT_A (glyph_format) > PIXMAN_FORMAT_A (format))
|
||||
format = glyph_format;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PIXMAN_a8r8g8b8;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
box32_intersect (pixman_box32_t *dest,
|
||||
const pixman_box32_t *box1,
|
||||
const pixman_box32_t *box2)
|
||||
{
|
||||
dest->x1 = MAX (box1->x1, box2->x1);
|
||||
dest->y1 = MAX (box1->y1, box2->y1);
|
||||
dest->x2 = MIN (box1->x2, box2->x2);
|
||||
dest->y2 = MIN (box1->y2, box2->y2);
|
||||
|
||||
return dest->x2 > dest->x1 && dest->y2 > dest->y1;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
|
||||
__attribute__((__force_align_arg_pointer__))
|
||||
#endif
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_glyphs_no_mask (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dest,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_region32_t region;
|
||||
pixman_format_code_t glyph_format = PIXMAN_null;
|
||||
uint32_t glyph_flags = 0;
|
||||
pixman_format_code_t dest_format;
|
||||
uint32_t dest_flags;
|
||||
pixman_composite_func_t func = NULL;
|
||||
pixman_implementation_t *implementation = NULL;
|
||||
pixman_composite_info_t info;
|
||||
int i;
|
||||
|
||||
_pixman_image_validate (src);
|
||||
_pixman_image_validate (dest);
|
||||
|
||||
dest_format = dest->common.extended_format_code;
|
||||
dest_flags = dest->common.flags;
|
||||
|
||||
pixman_region32_init (®ion);
|
||||
if (!_pixman_compute_composite_region32 (
|
||||
®ion,
|
||||
src, NULL, dest,
|
||||
src_x - dest_x, src_y - dest_y, 0, 0, 0, 0,
|
||||
dest->bits.width, dest->bits.height))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
info.op = op;
|
||||
info.src_image = src;
|
||||
info.dest_image = dest;
|
||||
info.src_flags = src->common.flags;
|
||||
info.dest_flags = dest->common.flags;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
pixman_image_t *glyph_img = glyph->image;
|
||||
pixman_box32_t glyph_box;
|
||||
pixman_box32_t *pbox;
|
||||
uint32_t extra = FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
pixman_box32_t composite_box;
|
||||
int n;
|
||||
|
||||
glyph_box.x1 = dest_x + glyphs[i].x - glyph->origin_x;
|
||||
glyph_box.y1 = dest_y + glyphs[i].y - glyph->origin_y;
|
||||
glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
|
||||
glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
|
||||
|
||||
pbox = pixman_region32_rectangles (®ion, &n);
|
||||
|
||||
info.mask_image = glyph_img;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (box32_intersect (&composite_box, pbox, &glyph_box))
|
||||
{
|
||||
if (glyph_img->common.extended_format_code != glyph_format ||
|
||||
glyph_img->common.flags != glyph_flags)
|
||||
{
|
||||
glyph_format = glyph_img->common.extended_format_code;
|
||||
glyph_flags = glyph_img->common.flags;
|
||||
|
||||
_pixman_implementation_lookup_composite (
|
||||
get_implementation(), op,
|
||||
src->common.extended_format_code, src->common.flags,
|
||||
glyph_format, glyph_flags | extra,
|
||||
dest_format, dest_flags,
|
||||
&implementation, &func);
|
||||
}
|
||||
|
||||
info.src_x = src_x + composite_box.x1 - dest_x;
|
||||
info.src_y = src_y + composite_box.y1 - dest_y;
|
||||
info.mask_x = composite_box.x1 - (dest_x + glyphs[i].x - glyph->origin_x);
|
||||
info.mask_y = composite_box.y1 - (dest_y + glyphs[i].y - glyph->origin_y);
|
||||
info.dest_x = composite_box.x1;
|
||||
info.dest_y = composite_box.y1;
|
||||
info.width = composite_box.x2 - composite_box.x1;
|
||||
info.height = composite_box.y2 - composite_box.y1;
|
||||
|
||||
info.mask_flags = glyph_flags;
|
||||
|
||||
func (implementation, &info);
|
||||
}
|
||||
|
||||
pbox++;
|
||||
}
|
||||
pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
|
||||
}
|
||||
|
||||
out:
|
||||
pixman_region32_fini (®ion);
|
||||
}
|
||||
|
||||
static void
|
||||
add_glyphs (pixman_glyph_cache_t *cache,
|
||||
pixman_image_t *dest,
|
||||
int off_x, int off_y,
|
||||
int n_glyphs, const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_format_code_t glyph_format = PIXMAN_null;
|
||||
uint32_t glyph_flags = 0;
|
||||
pixman_composite_func_t func = NULL;
|
||||
pixman_implementation_t *implementation = NULL;
|
||||
pixman_format_code_t dest_format;
|
||||
uint32_t dest_flags;
|
||||
pixman_box32_t dest_box;
|
||||
pixman_composite_info_t info;
|
||||
pixman_image_t *white_img = NULL;
|
||||
pixman_bool_t white_src = FALSE;
|
||||
int i;
|
||||
|
||||
_pixman_image_validate (dest);
|
||||
|
||||
dest_format = dest->common.extended_format_code;
|
||||
dest_flags = dest->common.flags;
|
||||
|
||||
info.op = PIXMAN_OP_ADD;
|
||||
info.dest_image = dest;
|
||||
info.src_x = 0;
|
||||
info.src_y = 0;
|
||||
info.dest_flags = dest_flags;
|
||||
|
||||
dest_box.x1 = 0;
|
||||
dest_box.y1 = 0;
|
||||
dest_box.x2 = dest->bits.width;
|
||||
dest_box.y2 = dest->bits.height;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
pixman_image_t *glyph_img = glyph->image;
|
||||
pixman_box32_t glyph_box;
|
||||
pixman_box32_t composite_box;
|
||||
|
||||
if (glyph_img->common.extended_format_code != glyph_format ||
|
||||
glyph_img->common.flags != glyph_flags)
|
||||
{
|
||||
pixman_format_code_t src_format, mask_format;
|
||||
|
||||
glyph_format = glyph_img->common.extended_format_code;
|
||||
glyph_flags = glyph_img->common.flags;
|
||||
|
||||
if (glyph_format == dest->bits.format)
|
||||
{
|
||||
src_format = glyph_format;
|
||||
mask_format = PIXMAN_null;
|
||||
info.src_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
info.mask_flags = FAST_PATH_IS_OPAQUE;
|
||||
info.mask_image = NULL;
|
||||
white_src = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!white_img)
|
||||
{
|
||||
static const pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
|
||||
if (!(white_img = pixman_image_create_solid_fill (&white)))
|
||||
goto out;
|
||||
|
||||
_pixman_image_validate (white_img);
|
||||
}
|
||||
|
||||
src_format = PIXMAN_solid;
|
||||
mask_format = glyph_format;
|
||||
info.src_flags = white_img->common.flags;
|
||||
info.mask_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
info.src_image = white_img;
|
||||
white_src = TRUE;
|
||||
}
|
||||
|
||||
_pixman_implementation_lookup_composite (
|
||||
get_implementation(), PIXMAN_OP_ADD,
|
||||
src_format, info.src_flags,
|
||||
mask_format, info.mask_flags,
|
||||
dest_format, dest_flags,
|
||||
&implementation, &func);
|
||||
}
|
||||
|
||||
glyph_box.x1 = glyphs[i].x - glyph->origin_x + off_x;
|
||||
glyph_box.y1 = glyphs[i].y - glyph->origin_y + off_y;
|
||||
glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
|
||||
glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
|
||||
|
||||
if (box32_intersect (&composite_box, &glyph_box, &dest_box))
|
||||
{
|
||||
int src_x = composite_box.x1 - glyph_box.x1;
|
||||
int src_y = composite_box.y1 - glyph_box.y1;
|
||||
|
||||
if (white_src)
|
||||
info.mask_image = glyph_img;
|
||||
else
|
||||
info.src_image = glyph_img;
|
||||
|
||||
info.mask_x = info.src_x = src_x;
|
||||
info.mask_y = info.src_y = src_y;
|
||||
info.dest_x = composite_box.x1;
|
||||
info.dest_y = composite_box.y1;
|
||||
info.width = composite_box.x2 - composite_box.x1;
|
||||
info.height = composite_box.y2 - composite_box.y1;
|
||||
|
||||
func (implementation, &info);
|
||||
|
||||
pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (white_img)
|
||||
pixman_image_unref (white_img);
|
||||
}
|
||||
|
||||
/* Conceptually, for each glyph, (white IN glyph) is PIXMAN_OP_ADDed to an
|
||||
* infinitely big mask image at the position such that the glyph origin point
|
||||
* is positioned at the (glyphs[i].x, glyphs[i].y) point.
|
||||
*
|
||||
* Then (mask_x, mask_y) in the infinite mask and (src_x, src_y) in the source
|
||||
* image are both aligned with (dest_x, dest_y) in the destination image. Then
|
||||
* these three images are composited within the
|
||||
*
|
||||
* (dest_x, dest_y, dst_x + width, dst_y + height)
|
||||
*
|
||||
* rectangle.
|
||||
*
|
||||
* TODO:
|
||||
* - Trim the mask to the destination clip/image?
|
||||
* - Trim composite region based on sources, when the op ignores 0s.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
|
||||
__attribute__((__force_align_arg_pointer__))
|
||||
#endif
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_glyphs (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dest,
|
||||
pixman_format_code_t mask_format,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
int32_t mask_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_image_t *mask;
|
||||
|
||||
if (!(mask = pixman_image_create_bits (mask_format, width, height, NULL, -1)))
|
||||
return;
|
||||
|
||||
if (PIXMAN_FORMAT_A (mask_format) != 0 &&
|
||||
PIXMAN_FORMAT_RGB (mask_format) != 0)
|
||||
{
|
||||
pixman_image_set_component_alpha (mask, TRUE);
|
||||
}
|
||||
|
||||
add_glyphs (cache, mask, - mask_x, - mask_y, n_glyphs, glyphs);
|
||||
|
||||
pixman_image_composite32 (op, src, mask, dest,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
pixman_image_unref (mask);
|
||||
}
|
264
vendor/pixman/pixman/pixman-gradient-walker.c
vendored
Normal file
264
vendor/pixman/pixman/pixman-gradient-walker.c
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
walker->num_stops = gradient->n_stops;
|
||||
walker->stops = gradient->stops;
|
||||
walker->left_x = 0;
|
||||
walker->right_x = 0x10000;
|
||||
walker->a_s = 0.0f;
|
||||
walker->a_b = 0.0f;
|
||||
walker->r_s = 0.0f;
|
||||
walker->r_b = 0.0f;
|
||||
walker->g_s = 0.0f;
|
||||
walker->g_b = 0.0f;
|
||||
walker->b_s = 0.0f;
|
||||
walker->b_b = 0.0f;
|
||||
walker->repeat = repeat;
|
||||
|
||||
walker->need_reset = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t pos)
|
||||
{
|
||||
int64_t x, left_x, right_x;
|
||||
pixman_color_t *left_c, *right_c;
|
||||
int n, count = walker->num_stops;
|
||||
pixman_gradient_stop_t *stops = walker->stops;
|
||||
float la, lr, lg, lb;
|
||||
float ra, rr, rg, rb;
|
||||
float lx, rx;
|
||||
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
x = (int32_t)pos & 0xffff;
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
x = (int32_t)pos & 0xffff;
|
||||
if ((int32_t)pos & 0x10000)
|
||||
x = 0x10000 - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pos;
|
||||
}
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
}
|
||||
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
if ((int32_t)pos & 0x10000)
|
||||
{
|
||||
pixman_color_t *tmp_c;
|
||||
int32_t tmp_x;
|
||||
|
||||
tmp_x = 0x10000 - right_x;
|
||||
right_x = 0x10000 - left_x;
|
||||
left_x = tmp_x;
|
||||
|
||||
tmp_c = right_c;
|
||||
right_c = left_c;
|
||||
left_c = tmp_c;
|
||||
|
||||
x = 0x10000 - x;
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (n == 0)
|
||||
right_c = left_c;
|
||||
else if (n == count)
|
||||
left_c = right_c;
|
||||
}
|
||||
|
||||
/* 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, 1] interval.
|
||||
*/
|
||||
la = (left_c->alpha * (1.0f/257.0f));
|
||||
lr = (left_c->red * (1.0f/257.0f));
|
||||
lg = (left_c->green * (1.0f/257.0f));
|
||||
lb = (left_c->blue * (1.0f/257.0f));
|
||||
|
||||
ra = (right_c->alpha * (1.0f/257.0f));
|
||||
rr = (right_c->red * (1.0f/257.0f));
|
||||
rg = (right_c->green * (1.0f/257.0f));
|
||||
rb = (right_c->blue * (1.0f/257.0f));
|
||||
|
||||
lx = left_x * (1.0f/65536.0f);
|
||||
rx = right_x * (1.0f/65536.0f);
|
||||
|
||||
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) / 510.0f;
|
||||
walker->r_b = (lr + rr) / 510.0f;
|
||||
walker->g_b = (lg + rg) / 510.0f;
|
||||
walker->b_b = (lb + rb) / 510.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float w_rec = 1.0f / (rx - lx);
|
||||
|
||||
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 * (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);
|
||||
}
|
||||
|
||||
walker->left_x = left_x;
|
||||
walker->right_x = right_x;
|
||||
|
||||
walker->need_reset = FALSE;
|
||||
}
|
||||
|
||||
static argb_t
|
||||
pixman_gradient_walker_pixel_float (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);
|
||||
|
||||
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);
|
||||
|
||||
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 (((uint32_t)(f.a + .5f) << 24) & 0xff000000) |
|
||||
(((uint32_t)(f.r + .5f) << 16) & 0x00ff0000) |
|
||||
(((uint32_t)(f.g + .5f) << 8) & 0x0000ff00) |
|
||||
(((uint32_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;
|
||||
}
|
994
vendor/pixman/pixman/pixman-image.c
vendored
Normal file
994
vendor/pixman/pixman/pixman-image.c
vendored
Normal file
@ -0,0 +1,994 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
static void
|
||||
gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
gradient_t *gradient = &image->gradient;
|
||||
int n = gradient->n_stops;
|
||||
pixman_gradient_stop_t *stops = gradient->stops;
|
||||
pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
|
||||
pixman_gradient_stop_t *end = &(gradient->stops[n]);
|
||||
|
||||
switch (gradient->common.repeat)
|
||||
{
|
||||
default:
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = transparent_black;
|
||||
end->x = INT32_MAX;
|
||||
end->color = transparent_black;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
begin->x = stops[n - 1].x - pixman_fixed_1;
|
||||
begin->color = stops[n - 1].color;
|
||||
end->x = stops[0].x + pixman_fixed_1;
|
||||
end->color = stops[0].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
begin->x = - stops[0].x;
|
||||
begin->color = stops[0].color;
|
||||
end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = stops[0].color;
|
||||
end->x = INT32_MAX;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_init_gradient (gradient_t * gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
return_val_if_fail (n_stops > 0, FALSE);
|
||||
|
||||
/* We allocate two extra stops, one before the beginning of the stop list,
|
||||
* and one after the end. These stops are initialized to whatever color
|
||||
* would be used for positions outside the range of the stop list.
|
||||
*
|
||||
* This saves a bit of computation in the gradient walker.
|
||||
*
|
||||
* The pointer we store in the gradient_t struct still points to the
|
||||
* first user-supplied struct, so when freeing, we will have to
|
||||
* subtract one.
|
||||
*/
|
||||
gradient->stops =
|
||||
pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
|
||||
if (!gradient->stops)
|
||||
return FALSE;
|
||||
|
||||
gradient->stops += 1;
|
||||
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
|
||||
gradient->n_stops = n_stops;
|
||||
|
||||
gradient->common.property_changed = gradient_property_changed;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_init (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = &image->common;
|
||||
|
||||
pixman_region32_init (&common->clip_region);
|
||||
|
||||
common->alpha_count = 0;
|
||||
common->have_clip_region = FALSE;
|
||||
common->clip_sources = FALSE;
|
||||
common->transform = NULL;
|
||||
common->repeat = PIXMAN_REPEAT_NONE;
|
||||
common->filter = PIXMAN_FILTER_NEAREST;
|
||||
common->filter_params = NULL;
|
||||
common->n_filter_params = 0;
|
||||
common->alpha_map = NULL;
|
||||
common->component_alpha = FALSE;
|
||||
common->ref_count = 1;
|
||||
common->property_changed = NULL;
|
||||
common->client_clip = FALSE;
|
||||
common->destroy_func = NULL;
|
||||
common->destroy_data = NULL;
|
||||
common->dirty = TRUE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_image_fini (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
common->ref_count--;
|
||||
|
||||
if (common->ref_count == 0)
|
||||
{
|
||||
if (image->common.destroy_func)
|
||||
image->common.destroy_func (image, image->common.destroy_data);
|
||||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
free (common->transform);
|
||||
free (common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
||||
if (image->type == LINEAR ||
|
||||
image->type == RADIAL ||
|
||||
image->type == CONICAL)
|
||||
{
|
||||
if (image->gradient.stops)
|
||||
{
|
||||
/* See _pixman_init_gradient() for an explanation of the - 1 */
|
||||
free (image->gradient.stops - 1);
|
||||
}
|
||||
|
||||
/* This will trigger if someone adds a property_changed
|
||||
* method to the linear/radial/conical gradient overwriting
|
||||
* the general one.
|
||||
*/
|
||||
assert (
|
||||
image->common.property_changed == gradient_property_changed);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void)
|
||||
{
|
||||
pixman_image_t *image = malloc (sizeof (pixman_image_t));
|
||||
|
||||
if (image)
|
||||
_pixman_image_init (image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
image_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.dirty = TRUE;
|
||||
}
|
||||
|
||||
/* Ref Counting */
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_ref (pixman_image_t *image)
|
||||
{
|
||||
image->common.ref_count++;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/* returns TRUE when the image is freed */
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_unref (pixman_image_t *image)
|
||||
{
|
||||
if (_pixman_image_fini (image))
|
||||
{
|
||||
free (image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_destroy_function (pixman_image_t * image,
|
||||
pixman_image_destroy_func_t func,
|
||||
void * data)
|
||||
{
|
||||
image->common.destroy_func = func;
|
||||
image->common.destroy_data = data;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void *
|
||||
pixman_image_get_destroy_data (pixman_image_t *image)
|
||||
{
|
||||
return image->common.destroy_data;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_reset_clip_region (pixman_image_t *image)
|
||||
{
|
||||
image->common.have_clip_region = FALSE;
|
||||
}
|
||||
|
||||
/* Executive Summary: This function is a no-op that only exists
|
||||
* for historical reasons.
|
||||
*
|
||||
* There used to be a bug in the X server where it would rely on
|
||||
* out-of-bounds accesses when it was asked to composite with a
|
||||
* window as the source. It would create a pixman image pointing
|
||||
* to some bogus position in memory, but then set a clip region
|
||||
* to the position where the actual bits were.
|
||||
*
|
||||
* Due to a bug in old versions of pixman, where it would not clip
|
||||
* against the image bounds when a clip region was set, this would
|
||||
* actually work. So when the pixman bug was fixed, a workaround was
|
||||
* added to allow certain out-of-bound accesses. This function disabled
|
||||
* those workarounds.
|
||||
*
|
||||
* Since 0.21.2, pixman doesn't do these workarounds anymore, so now
|
||||
* this function is a no-op.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_disable_out_of_bounds_workaround (void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
compute_image_info (pixman_image_t *image)
|
||||
{
|
||||
pixman_format_code_t code;
|
||||
uint32_t flags = 0;
|
||||
|
||||
/* Transform */
|
||||
if (!image->common.transform)
|
||||
{
|
||||
flags |= (FAST_PATH_ID_TRANSFORM |
|
||||
FAST_PATH_X_UNIT_POSITIVE |
|
||||
FAST_PATH_Y_UNIT_ZERO |
|
||||
FAST_PATH_AFFINE_TRANSFORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= FAST_PATH_HAS_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[2][0] == 0 &&
|
||||
image->common.transform->matrix[2][1] == 0 &&
|
||||
image->common.transform->matrix[2][2] == pixman_fixed_1)
|
||||
{
|
||||
flags |= FAST_PATH_AFFINE_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[0][1] == 0 &&
|
||||
image->common.transform->matrix[1][0] == 0)
|
||||
{
|
||||
if (image->common.transform->matrix[0][0] == -pixman_fixed_1 &&
|
||||
image->common.transform->matrix[1][1] == -pixman_fixed_1)
|
||||
{
|
||||
flags |= FAST_PATH_ROTATE_180_TRANSFORM;
|
||||
}
|
||||
flags |= FAST_PATH_SCALE_TRANSFORM;
|
||||
}
|
||||
else if (image->common.transform->matrix[0][0] == 0 &&
|
||||
image->common.transform->matrix[1][1] == 0)
|
||||
{
|
||||
pixman_fixed_t m01 = image->common.transform->matrix[0][1];
|
||||
pixman_fixed_t m10 = image->common.transform->matrix[1][0];
|
||||
|
||||
if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
|
||||
else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
if (image->common.transform->matrix[0][0] > 0)
|
||||
flags |= FAST_PATH_X_UNIT_POSITIVE;
|
||||
|
||||
if (image->common.transform->matrix[1][0] == 0)
|
||||
flags |= FAST_PATH_Y_UNIT_ZERO;
|
||||
}
|
||||
|
||||
/* Filter */
|
||||
switch (image->common.filter)
|
||||
{
|
||||
case PIXMAN_FILTER_NEAREST:
|
||||
case PIXMAN_FILTER_FAST:
|
||||
flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_BILINEAR:
|
||||
case PIXMAN_FILTER_GOOD:
|
||||
case PIXMAN_FILTER_BEST:
|
||||
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
|
||||
/* Here we have a chance to optimize BILINEAR filter to NEAREST if
|
||||
* they are equivalent for the currently used transformation matrix.
|
||||
*/
|
||||
if (flags & FAST_PATH_ID_TRANSFORM)
|
||||
{
|
||||
flags |= FAST_PATH_NEAREST_FILTER;
|
||||
}
|
||||
else if (flags & FAST_PATH_AFFINE_TRANSFORM)
|
||||
{
|
||||
/* 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 (*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)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
case PIXMAN_FILTER_CONVOLUTION:
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
|
||||
flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Repeat mode */
|
||||
switch (image->common.repeat)
|
||||
{
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
flags |=
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Component alpha */
|
||||
if (image->common.component_alpha)
|
||||
flags |= FAST_PATH_COMPONENT_ALPHA;
|
||||
else
|
||||
flags |= FAST_PATH_UNIFIED_ALPHA;
|
||||
|
||||
flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
|
||||
|
||||
/* Type specific checks */
|
||||
switch (image->type)
|
||||
{
|
||||
case SOLID:
|
||||
code = PIXMAN_solid;
|
||||
|
||||
if (image->solid.color.alpha == 0xffff)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
|
||||
case BITS:
|
||||
if (image->bits.width == 1 &&
|
||||
image->bits.height == 1 &&
|
||||
image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
code = PIXMAN_solid;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = image->bits.format;
|
||||
flags |= FAST_PATH_BITS_IMAGE;
|
||||
}
|
||||
|
||||
if (!PIXMAN_FORMAT_A (image->bits.format) &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
|
||||
{
|
||||
flags |= FAST_PATH_SAMPLES_OPAQUE;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
}
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
flags &= ~FAST_PATH_NO_ACCESSORS;
|
||||
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
break;
|
||||
|
||||
case RADIAL:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
/*
|
||||
* As explained in pixman-radial-gradient.c, every point of
|
||||
* the plane has a valid associated radius (and thus will be
|
||||
* colored) if and only if a is negative (i.e. one of the two
|
||||
* circles contains the other one).
|
||||
*/
|
||||
|
||||
if (image->radial.a >= 0)
|
||||
break;
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case CONICAL:
|
||||
case LINEAR:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
int i;
|
||||
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
for (i = 0; i < image->gradient.n_stops; ++i)
|
||||
{
|
||||
if (image->gradient.stops[i].color.alpha != 0xffff)
|
||||
{
|
||||
flags &= ~FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
code = PIXMAN_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Alpha maps are only supported for BITS images, so it's always
|
||||
* safe to ignore their presense for non-BITS images
|
||||
*/
|
||||
if (!image->common.alpha_map || image->type != BITS)
|
||||
{
|
||||
flags |= FAST_PATH_NO_ALPHA_MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
}
|
||||
|
||||
/* Both alpha maps and convolution filters can introduce
|
||||
* non-opaqueness in otherwise opaque images. Also
|
||||
* an image with component alpha turned on is only opaque
|
||||
* if all channels are opaque, so we simply turn it off
|
||||
* unconditionally for those images.
|
||||
*/
|
||||
if (image->common.alpha_map ||
|
||||
image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
|
||||
image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION ||
|
||||
image->common.component_alpha)
|
||||
{
|
||||
flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
|
||||
}
|
||||
|
||||
image->common.flags = flags;
|
||||
image->common.extended_format_code = code;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_validate (pixman_image_t *image)
|
||||
{
|
||||
if (image->common.dirty)
|
||||
{
|
||||
compute_image_info (image);
|
||||
|
||||
/* It is important that property_changed is
|
||||
* called *after* compute_image_info() because
|
||||
* property_changed() can make use of the flags
|
||||
* to set up accessors etc.
|
||||
*/
|
||||
if (image->common.property_changed)
|
||||
image->common.property_changed (image);
|
||||
|
||||
image->common.dirty = FALSE;
|
||||
}
|
||||
|
||||
if (image->common.alpha_map)
|
||||
_pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region32 (pixman_image_t * image,
|
||||
const pixman_region32_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region (pixman_image_t * image,
|
||||
const pixman_region16_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_has_client_clip (pixman_image_t *image,
|
||||
pixman_bool_t client_clip)
|
||||
{
|
||||
image->common.client_clip = client_clip;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_transform (pixman_image_t * image,
|
||||
const pixman_transform_t *transform)
|
||||
{
|
||||
static const pixman_transform_t id =
|
||||
{
|
||||
{ { pixman_fixed_1, 0, 0 },
|
||||
{ 0, pixman_fixed_1, 0 },
|
||||
{ 0, 0, pixman_fixed_1 } }
|
||||
};
|
||||
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (common->transform == transform)
|
||||
return TRUE;
|
||||
|
||||
if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
free (common->transform);
|
||||
common->transform = NULL;
|
||||
result = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (common->transform &&
|
||||
memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (common->transform == NULL)
|
||||
common->transform = malloc (sizeof (pixman_transform_t));
|
||||
|
||||
if (common->transform == NULL)
|
||||
{
|
||||
result = FALSE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy (common->transform, transform, sizeof(pixman_transform_t));
|
||||
|
||||
result = TRUE;
|
||||
|
||||
out:
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
if (image->common.repeat == repeat)
|
||||
return;
|
||||
|
||||
image->common.repeat = repeat;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_dither (pixman_image_t *image,
|
||||
pixman_dither_t dither)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.dither == dither)
|
||||
return;
|
||||
|
||||
image->bits.dither = dither;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_dither_offset (pixman_image_t *image,
|
||||
int offset_x,
|
||||
int offset_y)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.dither_offset_x == offset_x &&
|
||||
image->bits.dither_offset_y == offset_y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
image->bits.dither_offset_x = offset_x;
|
||||
image->bits.dither_offset_y = offset_y;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_filter (pixman_image_t * image,
|
||||
pixman_filter_t filter,
|
||||
const pixman_fixed_t *params,
|
||||
int n_params)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_fixed_t *new_params;
|
||||
|
||||
if (params == common->filter_params && filter == common->filter)
|
||||
return TRUE;
|
||||
|
||||
if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION)
|
||||
{
|
||||
int width = pixman_fixed_to_int (params[0]);
|
||||
int height = pixman_fixed_to_int (params[1]);
|
||||
int x_phase_bits = pixman_fixed_to_int (params[2]);
|
||||
int y_phase_bits = pixman_fixed_to_int (params[3]);
|
||||
int n_x_phases = (1 << x_phase_bits);
|
||||
int n_y_phases = (1 << y_phase_bits);
|
||||
|
||||
return_val_if_fail (
|
||||
n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE);
|
||||
}
|
||||
|
||||
new_params = NULL;
|
||||
if (params)
|
||||
{
|
||||
new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
|
||||
if (!new_params)
|
||||
return FALSE;
|
||||
|
||||
memcpy (new_params,
|
||||
params, n_params * sizeof (pixman_fixed_t));
|
||||
}
|
||||
|
||||
common->filter = filter;
|
||||
|
||||
if (common->filter_params)
|
||||
free (common->filter_params);
|
||||
|
||||
common->filter_params = new_params;
|
||||
common->n_filter_params = n_params;
|
||||
|
||||
image_property_changed (image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_source_clipping (pixman_image_t *image,
|
||||
pixman_bool_t clip_sources)
|
||||
{
|
||||
if (image->common.clip_sources == clip_sources)
|
||||
return;
|
||||
|
||||
image->common.clip_sources = clip_sources;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
/* Unlike all the other property setters, this function does not
|
||||
* copy the content of indexed. Doing this copying is simply
|
||||
* way, way too expensive.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_indexed (pixman_image_t * image,
|
||||
const pixman_indexed_t *indexed)
|
||||
{
|
||||
bits_image_t *bits = (bits_image_t *)image;
|
||||
|
||||
if (bits->indexed == indexed)
|
||||
return;
|
||||
|
||||
bits->indexed = indexed;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_alpha_map (pixman_image_t *image,
|
||||
pixman_image_t *alpha_map,
|
||||
int16_t x,
|
||||
int16_t y)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
return_if_fail (!alpha_map || alpha_map->type == BITS);
|
||||
|
||||
if (alpha_map && common->alpha_count > 0)
|
||||
{
|
||||
/* If this image is being used as an alpha map itself,
|
||||
* then you can't give it an alpha map of its own.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha_map && alpha_map->common.alpha_map)
|
||||
{
|
||||
/* If the image has an alpha map of its own,
|
||||
* then it can't be used as an alpha map itself
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (common->alpha_map != (bits_image_t *)alpha_map)
|
||||
{
|
||||
if (common->alpha_map)
|
||||
{
|
||||
common->alpha_map->common.alpha_count--;
|
||||
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
}
|
||||
|
||||
if (alpha_map)
|
||||
{
|
||||
common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
|
||||
|
||||
common->alpha_map->common.alpha_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
common->alpha_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
common->alpha_origin_x = x;
|
||||
common->alpha_origin_y = y;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_component_alpha (pixman_image_t *image,
|
||||
pixman_bool_t component_alpha)
|
||||
{
|
||||
if (image->common.component_alpha == component_alpha)
|
||||
return;
|
||||
|
||||
image->common.component_alpha = component_alpha;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_get_component_alpha (pixman_image_t *image)
|
||||
{
|
||||
return image->common.component_alpha;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_accessors (pixman_image_t * image,
|
||||
pixman_read_memory_func_t read_func,
|
||||
pixman_write_memory_func_t write_func)
|
||||
{
|
||||
return_if_fail (image != NULL);
|
||||
|
||||
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;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT uint32_t *
|
||||
pixman_image_get_data (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.bits;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_width (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_height (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_stride (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.rowstride * (int) sizeof (uint32_t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_depth (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return PIXMAN_FORMAT_DEPTH (image->bits.format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_format_code_t
|
||||
pixman_image_get_format (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.format;
|
||||
|
||||
return PIXMAN_null;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_pixman_image_get_solid (pixman_implementation_t *imp,
|
||||
pixman_image_t * image,
|
||||
pixman_format_code_t format)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
if (image->type == SOLID)
|
||||
{
|
||||
result = image->solid.color_32;
|
||||
}
|
||||
else if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.format == PIXMAN_a8r8g8b8)
|
||||
result = image->bits.bits[0];
|
||||
else if (image->bits.format == PIXMAN_x8r8g8b8)
|
||||
result = image->bits.bits[0] | 0xff000000;
|
||||
else if (image->bits.format == PIXMAN_a8)
|
||||
result = (uint32_t)(*(uint8_t *)image->bits.bits) << 24;
|
||||
else
|
||||
goto otherwise;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixman_iter_t iter;
|
||||
|
||||
otherwise:
|
||||
_pixman_implementation_iter_init (
|
||||
imp, &iter, image, 0, 0, 1, 1,
|
||||
(uint8_t *)&result,
|
||||
ITER_NARROW | ITER_SRC, image->common.flags);
|
||||
|
||||
result = *iter.get_scanline (&iter, NULL);
|
||||
|
||||
if (iter.fini)
|
||||
iter.fini (&iter);
|
||||
}
|
||||
|
||||
/* If necessary, convert RGB <--> BGR. */
|
||||
if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB
|
||||
&& PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB)
|
||||
{
|
||||
result = (((result & 0xff000000) >> 0) |
|
||||
((result & 0x00ff0000) >> 16) |
|
||||
((result & 0x0000ff00) >> 0) |
|
||||
((result & 0x000000ff) << 16));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
417
vendor/pixman/pixman/pixman-implementation.c
vendored
Normal file
417
vendor/pixman/pixman/pixman-implementation.c
vendored
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create (pixman_implementation_t *fallback,
|
||||
const pixman_fast_path_t *fast_paths)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
|
||||
assert (fast_paths);
|
||||
|
||||
if ((imp = malloc (sizeof (pixman_implementation_t))))
|
||||
{
|
||||
pixman_implementation_t *d;
|
||||
|
||||
memset (imp, 0, sizeof *imp);
|
||||
|
||||
imp->fallback = fallback;
|
||||
imp->fast_paths = fast_paths;
|
||||
|
||||
/* Make sure the whole fallback chain has the right toplevel */
|
||||
for (d = imp; d != NULL; d = d->fallback)
|
||||
d->toplevel = imp;
|
||||
}
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
#define N_CACHED_FAST_PATHS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
pixman_implementation_t * imp;
|
||||
pixman_fast_path_t fast_path;
|
||||
} cache [N_CACHED_FAST_PATHS];
|
||||
} cache_t;
|
||||
|
||||
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache)
|
||||
|
||||
static void
|
||||
dummy_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel,
|
||||
pixman_op_t op,
|
||||
pixman_format_code_t src_format,
|
||||
uint32_t src_flags,
|
||||
pixman_format_code_t mask_format,
|
||||
uint32_t mask_flags,
|
||||
pixman_format_code_t dest_format,
|
||||
uint32_t dest_flags,
|
||||
pixman_implementation_t **out_imp,
|
||||
pixman_composite_func_t *out_func)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
cache_t *cache;
|
||||
int i;
|
||||
|
||||
/* Check cache for fast paths */
|
||||
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
|
||||
|
||||
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
|
||||
{
|
||||
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
|
||||
|
||||
/* Note that we check for equality here, not whether
|
||||
* the cached fast path matches. This is to prevent
|
||||
* us from selecting an overly general fast path
|
||||
* when a more specific one would work.
|
||||
*/
|
||||
if (info->op == op &&
|
||||
info->src_format == src_format &&
|
||||
info->mask_format == mask_format &&
|
||||
info->dest_format == dest_format &&
|
||||
info->src_flags == src_flags &&
|
||||
info->mask_flags == mask_flags &&
|
||||
info->dest_flags == dest_flags &&
|
||||
info->func)
|
||||
{
|
||||
*out_imp = cache->cache[i].imp;
|
||||
*out_func = cache->cache[i].fast_path.func;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
}
|
||||
|
||||
for (imp = toplevel; imp != NULL; imp = imp->fallback)
|
||||
{
|
||||
const pixman_fast_path_t *info = imp->fast_paths;
|
||||
|
||||
while (info->op != PIXMAN_OP_NONE)
|
||||
{
|
||||
if ((info->op == op || info->op == PIXMAN_OP_any) &&
|
||||
/* Formats */
|
||||
((info->src_format == src_format) ||
|
||||
(info->src_format == PIXMAN_any)) &&
|
||||
((info->mask_format == mask_format) ||
|
||||
(info->mask_format == PIXMAN_any)) &&
|
||||
((info->dest_format == dest_format) ||
|
||||
(info->dest_format == PIXMAN_any)) &&
|
||||
/* Flags */
|
||||
(info->src_flags & src_flags) == info->src_flags &&
|
||||
(info->mask_flags & mask_flags) == info->mask_flags &&
|
||||
(info->dest_flags & dest_flags) == info->dest_flags)
|
||||
{
|
||||
*out_imp = imp;
|
||||
*out_func = info->func;
|
||||
|
||||
/* Set i to the last spot in the cache so that the
|
||||
* move-to-front code below will work
|
||||
*/
|
||||
i = N_CACHED_FAST_PATHS - 1;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
|
||||
++info;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should never reach this point */
|
||||
_pixman_log_error (
|
||||
FUNC,
|
||||
"No composite function found\n"
|
||||
"\n"
|
||||
"The most likely cause of this is that this system has issues with\n"
|
||||
"thread local storage\n");
|
||||
|
||||
*out_imp = NULL;
|
||||
*out_func = dummy_composite_rect;
|
||||
return;
|
||||
|
||||
update_cache:
|
||||
if (i)
|
||||
{
|
||||
while (i--)
|
||||
cache->cache[i + 1] = cache->cache[i];
|
||||
|
||||
cache->cache[0].imp = *out_imp;
|
||||
cache->cache[0].fast_path.op = op;
|
||||
cache->cache[0].fast_path.src_format = src_format;
|
||||
cache->cache[0].fast_path.src_flags = src_flags;
|
||||
cache->cache[0].fast_path.mask_format = mask_format;
|
||||
cache->cache[0].fast_path.mask_flags = mask_flags;
|
||||
cache->cache[0].fast_path.dest_format = dest_format;
|
||||
cache->cache[0].fast_path.dest_flags = dest_flags;
|
||||
cache->cache[0].fast_path.func = *out_func;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_combine (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * pd,
|
||||
const uint32_t * ps,
|
||||
const uint32_t * pm,
|
||||
int w)
|
||||
{
|
||||
}
|
||||
|
||||
pixman_combine_32_func_t
|
||||
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_bool_t component_alpha,
|
||||
pixman_bool_t narrow)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
pixman_combine_32_func_t f = NULL;
|
||||
|
||||
switch ((narrow << 1) | component_alpha)
|
||||
{
|
||||
case 0: /* not narrow, not component alpha */
|
||||
f = (pixman_combine_32_func_t)imp->combine_float[op];
|
||||
break;
|
||||
|
||||
case 1: /* not narrow, component_alpha */
|
||||
f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
|
||||
break;
|
||||
|
||||
case 2: /* narrow, not component alpha */
|
||||
f = imp->combine_32[op];
|
||||
break;
|
||||
|
||||
case 3: /* narrow, component_alpha */
|
||||
f = imp->combine_32_ca[op];
|
||||
break;
|
||||
}
|
||||
|
||||
if (f)
|
||||
return f;
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
/* We should never reach this point */
|
||||
_pixman_log_error (FUNC, "No known combine function\n");
|
||||
return dummy_combine;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_blt (pixman_implementation_t * imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
if (imp->blt &&
|
||||
(*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
|
||||
width, height))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t filler)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
if (imp->fill &&
|
||||
((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_iter_init (pixman_implementation_t *imp,
|
||||
pixman_iter_t *iter,
|
||||
pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint8_t *buffer,
|
||||
iter_flags_t iter_flags,
|
||||
uint32_t image_flags)
|
||||
{
|
||||
pixman_format_code_t format;
|
||||
|
||||
iter->image = image;
|
||||
iter->buffer = (uint32_t *)buffer;
|
||||
iter->x = x;
|
||||
iter->y = y;
|
||||
iter->width = width;
|
||||
iter->height = height;
|
||||
iter->iter_flags = iter_flags;
|
||||
iter->image_flags = image_flags;
|
||||
iter->fini = NULL;
|
||||
|
||||
if (!iter->image)
|
||||
{
|
||||
iter->get_scanline = get_scanline_null;
|
||||
return;
|
||||
}
|
||||
|
||||
format = iter->image->common.extended_format_code;
|
||||
|
||||
while (imp)
|
||||
{
|
||||
if (imp->iter_info)
|
||||
{
|
||||
const pixman_iter_info_t *info;
|
||||
|
||||
for (info = imp->iter_info; info->format != PIXMAN_null; ++info)
|
||||
{
|
||||
if ((info->format == PIXMAN_any || info->format == format) &&
|
||||
(info->image_flags & image_flags) == info->image_flags &&
|
||||
(info->iter_flags & iter_flags) == info->iter_flags)
|
||||
{
|
||||
iter->get_scanline = info->get_scanline;
|
||||
iter->write_back = info->write_back;
|
||||
|
||||
if (info->initializer)
|
||||
info->initializer (iter, info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_disabled (const char *name)
|
||||
{
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv ("PIXMAN_DISABLE")))
|
||||
{
|
||||
do
|
||||
{
|
||||
const char *end;
|
||||
int len;
|
||||
|
||||
if ((end = strchr (env, ' ')))
|
||||
len = end - env;
|
||||
else
|
||||
len = strlen (env);
|
||||
|
||||
if (strlen (name) == len && strncmp (name, env, len) == 0)
|
||||
{
|
||||
printf ("pixman: Disabled %s implementation\n", name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
env += len;
|
||||
}
|
||||
while (*env++);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t empty_fast_path[] =
|
||||
{
|
||||
{ PIXMAN_OP_NONE }
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_choose_implementation (void)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
|
||||
imp = _pixman_implementation_create_general();
|
||||
|
||||
if (!_pixman_disabled ("fast"))
|
||||
imp = _pixman_implementation_create_fast_path (imp);
|
||||
|
||||
imp = _pixman_x86_get_implementations (imp);
|
||||
imp = _pixman_arm_get_implementations (imp);
|
||||
imp = _pixman_ppc_get_implementations (imp);
|
||||
imp = _pixman_mips_get_implementations (imp);
|
||||
|
||||
imp = _pixman_implementation_create_noop (imp);
|
||||
|
||||
if (_pixman_disabled ("wholeops"))
|
||||
{
|
||||
pixman_implementation_t *cur;
|
||||
|
||||
/* Disable all whole-operation paths except the general one,
|
||||
* so that optimized iterators are used as much as possible.
|
||||
*/
|
||||
for (cur = imp; cur->fallback; cur = cur->fallback)
|
||||
cur->fast_paths = empty_fast_path;
|
||||
}
|
||||
|
||||
return imp;
|
||||
}
|
1365
vendor/pixman/pixman/pixman-inlines.h
vendored
Normal file
1365
vendor/pixman/pixman/pixman-inlines.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
292
vendor/pixman/pixman/pixman-linear-gradient.c
vendored
Normal file
292
vendor/pixman/pixman/pixman-linear-gradient.c
vendored
Normal file
@ -0,0 +1,292 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static pixman_bool_t
|
||||
linear_gradient_is_horizontal (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
linear_gradient_t *linear = (linear_gradient_t *)image;
|
||||
pixman_vector_t v;
|
||||
pixman_fixed_32_32_t l;
|
||||
pixman_fixed_48_16_t dx, dy;
|
||||
double inc;
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
/* projective transformation */
|
||||
if (image->common.transform->matrix[2][0] != 0 ||
|
||||
image->common.transform->matrix[2][1] != 0 ||
|
||||
image->common.transform->matrix[2][2] == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
v.vector[0] = image->common.transform->matrix[0][1];
|
||||
v.vector[1] = image->common.transform->matrix[1][1];
|
||||
v.vector[2] = image->common.transform->matrix[2][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
v.vector[0] = 0;
|
||||
v.vector[1] = pixman_fixed_1;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* compute how much the input of the gradient walked changes
|
||||
* when moving vertically through the whole image
|
||||
*/
|
||||
inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
|
||||
(dx * v.vector[0] + dy * v.vector[1]) /
|
||||
(v.vector[2] * (double) l);
|
||||
|
||||
/* check that casting to integer would result in 0 */
|
||||
if (-1 < inc && inc < 1)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
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;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t * buffer = iter->buffer;
|
||||
|
||||
pixman_vector_t v, unit;
|
||||
pixman_fixed_32_32_t l;
|
||||
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 * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
unit.vector[0] = image->common.transform->matrix[0][0];
|
||||
unit.vector[1] = image->common.transform->matrix[1][0];
|
||||
unit.vector[2] = image->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0 || unit.vector[2] == 0)
|
||||
{
|
||||
/* affine transformation only */
|
||||
pixman_fixed_32_32_t t, next_inc;
|
||||
double inc;
|
||||
|
||||
if (l == 0 || v.vector[2] == 0)
|
||||
{
|
||||
t = 0;
|
||||
inc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
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]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
|
||||
}
|
||||
next_inc = 0;
|
||||
|
||||
if (((pixman_fixed_32_32_t )(inc * width)) == 0)
|
||||
{
|
||||
fill_pixel (&walker, t, buffer, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
write_pixel (&walker, t + next_inc, buffer);
|
||||
}
|
||||
i++;
|
||||
next_inc = inc * i;
|
||||
buffer += (Bpp / 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective transformation */
|
||||
double t;
|
||||
|
||||
t = 0;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
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]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
}
|
||||
|
||||
write_pixel (&walker, t, buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
|
||||
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)
|
||||
{
|
||||
return linear_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide,
|
||||
_pixman_gradient_walker_fill_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (linear_gradient_is_horizontal (
|
||||
iter->image, iter->x, iter->y, iter->width, iter->height))
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
linear_get_scanline_narrow (iter, NULL);
|
||||
else
|
||||
linear_get_scanline_wide (iter, NULL);
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = linear_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = linear_get_scanline_wide;
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_linear_gradient (const pixman_point_fixed_t * p1,
|
||||
const pixman_point_fixed_t * p2,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
linear_gradient_t *linear;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
linear = &image->linear;
|
||||
|
||||
if (!_pixman_init_gradient (&linear->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linear->p1 = *p1;
|
||||
linear->p2 = *p2;
|
||||
|
||||
image->type = LINEAR;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
1073
vendor/pixman/pixman/pixman-matrix.c
vendored
Normal file
1073
vendor/pixman/pixman/pixman-matrix.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4283
vendor/pixman/pixman/pixman-mips-dspr2-asm.S
vendored
Normal file
4283
vendor/pixman/pixman/pixman-mips-dspr2-asm.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
711
vendor/pixman/pixman/pixman-mips-dspr2-asm.h
vendored
Normal file
711
vendor/pixman/pixman/pixman-mips-dspr2-asm.h
vendored
Normal file
@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_MIPS_DSPR2_ASM_H
|
||||
#define PIXMAN_MIPS_DSPR2_ASM_H
|
||||
|
||||
#define zero $0
|
||||
#define AT $1
|
||||
#define v0 $2
|
||||
#define v1 $3
|
||||
#define a0 $4
|
||||
#define a1 $5
|
||||
#define a2 $6
|
||||
#define a3 $7
|
||||
#define t0 $8
|
||||
#define t1 $9
|
||||
#define t2 $10
|
||||
#define t3 $11
|
||||
#define t4 $12
|
||||
#define t5 $13
|
||||
#define t6 $14
|
||||
#define t7 $15
|
||||
#define s0 $16
|
||||
#define s1 $17
|
||||
#define s2 $18
|
||||
#define s3 $19
|
||||
#define s4 $20
|
||||
#define s5 $21
|
||||
#define s6 $22
|
||||
#define s7 $23
|
||||
#define t8 $24
|
||||
#define t9 $25
|
||||
#define k0 $26
|
||||
#define k1 $27
|
||||
#define gp $28
|
||||
#define sp $29
|
||||
#define fp $30
|
||||
#define s8 $30
|
||||
#define ra $31
|
||||
|
||||
/*
|
||||
* LEAF_MIPS32R2 - declare leaf routine for MIPS32r2
|
||||
*/
|
||||
#define LEAF_MIPS32R2(symbol) \
|
||||
.globl symbol; \
|
||||
.align 2; \
|
||||
.hidden symbol; \
|
||||
.type symbol, @function; \
|
||||
.ent symbol, 0; \
|
||||
symbol: .frame sp, 0, ra; \
|
||||
.set push; \
|
||||
.set arch=mips32r2; \
|
||||
.set noreorder; \
|
||||
.set noat;
|
||||
|
||||
/*
|
||||
* LEAF_MIPS32R2 - declare leaf routine for MIPS DSPr2
|
||||
*/
|
||||
#define LEAF_MIPS_DSPR2(symbol) \
|
||||
LEAF_MIPS32R2(symbol) \
|
||||
.set dspr2;
|
||||
|
||||
/*
|
||||
* END - mark end of function
|
||||
*/
|
||||
#define END(function) \
|
||||
.set pop; \
|
||||
.end function; \
|
||||
.size function,.-function
|
||||
|
||||
/*
|
||||
* Checks if stack offset is big enough for storing/restoring regs_num
|
||||
* number of register to/from stack. Stack offset must be greater than
|
||||
* or equal to the number of bytes needed for storing registers (regs_num*4).
|
||||
* Since MIPS ABI allows usage of first 16 bytes of stack frame (this is
|
||||
* preserved for input arguments of the functions, already stored in a0-a3),
|
||||
* stack size can be further optimized by utilizing this space.
|
||||
*/
|
||||
.macro CHECK_STACK_OFFSET regs_num, stack_offset
|
||||
.if \stack_offset < \regs_num * 4 - 16
|
||||
.error "Stack offset too small."
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Saves set of registers on stack. Maximum number of registers that
|
||||
* can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
|
||||
* Stack offset is number of bytes that are added to stack pointer (sp)
|
||||
* before registers are pushed in order to provide enough space on stack
|
||||
* (offset must be multiple of 4, and must be big enough, as described by
|
||||
* CHECK_STACK_OFFSET macro). This macro is intended to be used in
|
||||
* combination with RESTORE_REGS_FROM_STACK macro. Example:
|
||||
* SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
|
||||
* RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
|
||||
*/
|
||||
.macro SAVE_REGS_ON_STACK stack_offset = 0, r1, \
|
||||
r2 = 0, r3 = 0, r4 = 0, \
|
||||
r5 = 0, r6 = 0, r7 = 0, \
|
||||
r8 = 0, r9 = 0, r10 = 0, \
|
||||
r11 = 0, r12 = 0, r13 = 0, \
|
||||
r14 = 0
|
||||
.if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
|
||||
.error "Stack offset must be pozitive and multiple of 4."
|
||||
.endif
|
||||
.if \stack_offset != 0
|
||||
addiu sp, sp, -\stack_offset
|
||||
.endif
|
||||
sw \r1, 0(sp)
|
||||
.if \r2 != 0
|
||||
sw \r2, 4(sp)
|
||||
.endif
|
||||
.if \r3 != 0
|
||||
sw \r3, 8(sp)
|
||||
.endif
|
||||
.if \r4 != 0
|
||||
sw \r4, 12(sp)
|
||||
.endif
|
||||
.if \r5 != 0
|
||||
CHECK_STACK_OFFSET 5, \stack_offset
|
||||
sw \r5, 16(sp)
|
||||
.endif
|
||||
.if \r6 != 0
|
||||
CHECK_STACK_OFFSET 6, \stack_offset
|
||||
sw \r6, 20(sp)
|
||||
.endif
|
||||
.if \r7 != 0
|
||||
CHECK_STACK_OFFSET 7, \stack_offset
|
||||
sw \r7, 24(sp)
|
||||
.endif
|
||||
.if \r8 != 0
|
||||
CHECK_STACK_OFFSET 8, \stack_offset
|
||||
sw \r8, 28(sp)
|
||||
.endif
|
||||
.if \r9 != 0
|
||||
CHECK_STACK_OFFSET 9, \stack_offset
|
||||
sw \r9, 32(sp)
|
||||
.endif
|
||||
.if \r10 != 0
|
||||
CHECK_STACK_OFFSET 10, \stack_offset
|
||||
sw \r10, 36(sp)
|
||||
.endif
|
||||
.if \r11 != 0
|
||||
CHECK_STACK_OFFSET 11, \stack_offset
|
||||
sw \r11, 40(sp)
|
||||
.endif
|
||||
.if \r12 != 0
|
||||
CHECK_STACK_OFFSET 12, \stack_offset
|
||||
sw \r12, 44(sp)
|
||||
.endif
|
||||
.if \r13 != 0
|
||||
CHECK_STACK_OFFSET 13, \stack_offset
|
||||
sw \r13, 48(sp)
|
||||
.endif
|
||||
.if \r14 != 0
|
||||
CHECK_STACK_OFFSET 14, \stack_offset
|
||||
sw \r14, 52(sp)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Restores set of registers from stack. Maximum number of registers that
|
||||
* can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
|
||||
* Stack offset is number of bytes that are added to stack pointer (sp)
|
||||
* after registers are restored (offset must be multiple of 4, and must
|
||||
* be big enough, as described by CHECK_STACK_OFFSET macro). This macro is
|
||||
* intended to be used in combination with RESTORE_REGS_FROM_STACK macro.
|
||||
* Example:
|
||||
* SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
|
||||
* RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
|
||||
*/
|
||||
.macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1, \
|
||||
r2 = 0, r3 = 0, r4 = 0, \
|
||||
r5 = 0, r6 = 0, r7 = 0, \
|
||||
r8 = 0, r9 = 0, r10 = 0, \
|
||||
r11 = 0, r12 = 0, r13 = 0, \
|
||||
r14 = 0
|
||||
.if (\stack_offset < 0) || (\stack_offset - (\stack_offset/4)*4)
|
||||
.error "Stack offset must be pozitive and multiple of 4."
|
||||
.endif
|
||||
lw \r1, 0(sp)
|
||||
.if \r2 != 0
|
||||
lw \r2, 4(sp)
|
||||
.endif
|
||||
.if \r3 != 0
|
||||
lw \r3, 8(sp)
|
||||
.endif
|
||||
.if \r4 != 0
|
||||
lw \r4, 12(sp)
|
||||
.endif
|
||||
.if \r5 != 0
|
||||
CHECK_STACK_OFFSET 5, \stack_offset
|
||||
lw \r5, 16(sp)
|
||||
.endif
|
||||
.if \r6 != 0
|
||||
CHECK_STACK_OFFSET 6, \stack_offset
|
||||
lw \r6, 20(sp)
|
||||
.endif
|
||||
.if \r7 != 0
|
||||
CHECK_STACK_OFFSET 7, \stack_offset
|
||||
lw \r7, 24(sp)
|
||||
.endif
|
||||
.if \r8 != 0
|
||||
CHECK_STACK_OFFSET 8, \stack_offset
|
||||
lw \r8, 28(sp)
|
||||
.endif
|
||||
.if \r9 != 0
|
||||
CHECK_STACK_OFFSET 9, \stack_offset
|
||||
lw \r9, 32(sp)
|
||||
.endif
|
||||
.if \r10 != 0
|
||||
CHECK_STACK_OFFSET 10, \stack_offset
|
||||
lw \r10, 36(sp)
|
||||
.endif
|
||||
.if \r11 != 0
|
||||
CHECK_STACK_OFFSET 11, \stack_offset
|
||||
lw \r11, 40(sp)
|
||||
.endif
|
||||
.if \r12 != 0
|
||||
CHECK_STACK_OFFSET 12, \stack_offset
|
||||
lw \r12, 44(sp)
|
||||
.endif
|
||||
.if \r13 != 0
|
||||
CHECK_STACK_OFFSET 13, \stack_offset
|
||||
lw \r13, 48(sp)
|
||||
.endif
|
||||
.if \r14 != 0
|
||||
CHECK_STACK_OFFSET 14, \stack_offset
|
||||
lw \r14, 52(sp)
|
||||
.endif
|
||||
.if \stack_offset != 0
|
||||
addiu sp, sp, \stack_offset
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of single r5g6b5 pixel (in_565) to single a8r8g8b8 pixel
|
||||
* returned in (out_8888) register. Requires two temporary registers
|
||||
* (scratch1 and scratch2).
|
||||
*/
|
||||
.macro CONVERT_1x0565_TO_1x8888 in_565, \
|
||||
out_8888, \
|
||||
scratch1, scratch2
|
||||
lui \out_8888, 0xff00
|
||||
sll \scratch1, \in_565, 0x3
|
||||
andi \scratch2, \scratch1, 0xff
|
||||
ext \scratch1, \in_565, 0x2, 0x3
|
||||
or \scratch1, \scratch2, \scratch1
|
||||
or \out_8888, \out_8888, \scratch1
|
||||
|
||||
sll \scratch1, \in_565, 0x5
|
||||
andi \scratch1, \scratch1, 0xfc00
|
||||
srl \scratch2, \in_565, 0x1
|
||||
andi \scratch2, \scratch2, 0x300
|
||||
or \scratch2, \scratch1, \scratch2
|
||||
or \out_8888, \out_8888, \scratch2
|
||||
|
||||
andi \scratch1, \in_565, 0xf800
|
||||
srl \scratch2, \scratch1, 0x5
|
||||
andi \scratch2, \scratch2, 0xff00
|
||||
or \scratch1, \scratch1, \scratch2
|
||||
sll \scratch1, \scratch1, 0x8
|
||||
or \out_8888, \out_8888, \scratch1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of two r5g6b5 pixels (in1_565 and in2_565) to two a8r8g8b8 pixels
|
||||
* returned in (out1_8888 and out2_8888) registers. Requires four scratch
|
||||
* registers (scratch1 ... scratch4). It also requires maskG and maskB for
|
||||
* color component extractions. These masks must have following values:
|
||||
* li maskG, 0x07e007e0
|
||||
* li maskB, 0x001F001F
|
||||
*/
|
||||
.macro CONVERT_2x0565_TO_2x8888 in1_565, in2_565, \
|
||||
out1_8888, out2_8888, \
|
||||
maskG, maskB, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
sll \scratch1, \in1_565, 16
|
||||
or \scratch1, \scratch1, \in2_565
|
||||
lui \out2_8888, 0xff00
|
||||
ori \out2_8888, \out2_8888, 0xff00
|
||||
shrl.ph \scratch2, \scratch1, 11
|
||||
and \scratch3, \scratch1, \maskG
|
||||
shra.ph \scratch4, \scratch2, 2
|
||||
shll.ph \scratch2, \scratch2, 3
|
||||
shll.ph \scratch3, \scratch3, 5
|
||||
or \scratch2, \scratch2, \scratch4
|
||||
shrl.qb \scratch4, \scratch3, 6
|
||||
or \out2_8888, \out2_8888, \scratch2
|
||||
or \scratch3, \scratch3, \scratch4
|
||||
and \scratch1, \scratch1, \maskB
|
||||
shll.ph \scratch2, \scratch1, 3
|
||||
shra.ph \scratch4, \scratch1, 2
|
||||
or \scratch2, \scratch2, \scratch4
|
||||
or \scratch3, \scratch2, \scratch3
|
||||
precrq.ph.w \out1_8888, \out2_8888, \scratch3
|
||||
precr_sra.ph.w \out2_8888, \scratch3, 0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of single a8r8g8b8 pixel (in_8888) to single r5g6b5 pixel
|
||||
* returned in (out_565) register. Requires two temporary registers
|
||||
* (scratch1 and scratch2).
|
||||
*/
|
||||
.macro CONVERT_1x8888_TO_1x0565 in_8888, \
|
||||
out_565, \
|
||||
scratch1, scratch2
|
||||
ext \out_565, \in_8888, 0x3, 0x5
|
||||
srl \scratch1, \in_8888, 0x5
|
||||
andi \scratch1, \scratch1, 0x07e0
|
||||
srl \scratch2, \in_8888, 0x8
|
||||
andi \scratch2, \scratch2, 0xf800
|
||||
or \out_565, \out_565, \scratch1
|
||||
or \out_565, \out_565, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of two a8r8g8b8 pixels (in1_8888 and in2_8888) to two r5g6b5
|
||||
* pixels returned in (out1_565 and out2_565) registers. Requires two temporary
|
||||
* registers (scratch1 and scratch2). It also requires maskR, maskG and maskB
|
||||
* for color component extractions. These masks must have following values:
|
||||
* li maskR, 0xf800f800
|
||||
* li maskG, 0x07e007e0
|
||||
* li maskB, 0x001F001F
|
||||
* Value of input register in2_8888 is lost.
|
||||
*/
|
||||
.macro CONVERT_2x8888_TO_2x0565 in1_8888, in2_8888, \
|
||||
out1_565, out2_565, \
|
||||
maskR, maskG, maskB, \
|
||||
scratch1, scratch2
|
||||
precr.qb.ph \scratch1, \in2_8888, \in1_8888
|
||||
precrq.qb.ph \in2_8888, \in2_8888, \in1_8888
|
||||
and \out1_565, \scratch1, \maskR
|
||||
shrl.ph \scratch1, \scratch1, 3
|
||||
shll.ph \in2_8888, \in2_8888, 3
|
||||
and \scratch1, \scratch1, \maskB
|
||||
or \out1_565, \out1_565, \scratch1
|
||||
and \in2_8888, \in2_8888, \maskG
|
||||
or \out1_565, \out1_565, \in2_8888
|
||||
srl \out2_565, \out1_565, 16
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply pixel (a8) with single pixel (a8r8g8b8). It requires maskLSR needed
|
||||
* for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_UN8x4_MUL_UN8 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3
|
||||
replv.ph \m_8, \m_8 /* 0 | M | 0 | M */
|
||||
muleu_s.ph.qbl \scratch1, \s_8888, \m_8 /* A*M | R*M */
|
||||
muleu_s.ph.qbr \scratch2, \s_8888, \m_8 /* G*M | B*M */
|
||||
shra_r.ph \scratch3, \scratch1, 8
|
||||
shra_r.ph \d_8888, \scratch2, 8
|
||||
and \scratch3, \scratch3, \maskLSR /* 0 |A*M| 0 |R*M */
|
||||
and \d_8888, \d_8888, \maskLSR /* 0 |G*M| 0 |B*M */
|
||||
addq.ph \scratch1, \scratch1, \scratch3 /* A*M+A*M | R*M+R*M */
|
||||
addq.ph \scratch2, \scratch2, \d_8888 /* G*M+G*M | B*M+B*M */
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
precr.qb.ph \d_8888, \scratch1, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply two pixels (a8) with two pixels (a8r8g8b8). It requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
replv.ph \m1_8, \m1_8 /* 0 | M1 | 0 | M1 */
|
||||
replv.ph \m2_8, \m2_8 /* 0 | M2 | 0 | M2 */
|
||||
muleu_s.ph.qbl \scratch1, \s1_8888, \m1_8 /* A1*M1 | R1*M1 */
|
||||
muleu_s.ph.qbr \scratch2, \s1_8888, \m1_8 /* G1*M1 | B1*M1 */
|
||||
muleu_s.ph.qbl \scratch3, \s2_8888, \m2_8 /* A2*M2 | R2*M2 */
|
||||
muleu_s.ph.qbr \scratch4, \s2_8888, \m2_8 /* G2*M2 | B2*M2 */
|
||||
shra_r.ph \scratch5, \scratch1, 8
|
||||
shra_r.ph \d1_8888, \scratch2, 8
|
||||
shra_r.ph \scratch6, \scratch3, 8
|
||||
shra_r.ph \d2_8888, \scratch4, 8
|
||||
and \scratch5, \scratch5, \maskLSR /* 0 |A1*M1| 0 |R1*M1 */
|
||||
and \d1_8888, \d1_8888, \maskLSR /* 0 |G1*M1| 0 |B1*M1 */
|
||||
and \scratch6, \scratch6, \maskLSR /* 0 |A2*M2| 0 |R2*M2 */
|
||||
and \d2_8888, \d2_8888, \maskLSR /* 0 |G2*M2| 0 |B2*M2 */
|
||||
addq.ph \scratch1, \scratch1, \scratch5
|
||||
addq.ph \scratch2, \scratch2, \d1_8888
|
||||
addq.ph \scratch3, \scratch3, \scratch6
|
||||
addq.ph \scratch4, \scratch4, \d2_8888
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
shra_r.ph \scratch3, \scratch3, 8
|
||||
shra_r.ph \scratch4, \scratch4, 8
|
||||
precr.qb.ph \d1_8888, \scratch1, \scratch2
|
||||
precr.qb.ph \d2_8888, \scratch3, \scratch4
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply pixel (a8r8g8b8) with single pixel (a8r8g8b8). It requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_UN8x4_MUL_UN8x4 s_8888, \
|
||||
m_8888, \
|
||||
d_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
preceu.ph.qbl \scratch1, \m_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch2, \m_8888 /* 0 | G | 0 | B */
|
||||
muleu_s.ph.qbl \scratch3, \s_8888, \scratch1 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch4, \s_8888, \scratch2 /* G*G | B*B */
|
||||
shra_r.ph \scratch1, \scratch3, 8
|
||||
shra_r.ph \scratch2, \scratch4, 8
|
||||
and \scratch1, \scratch1, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \scratch2, \scratch2, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
addq.ph \scratch1, \scratch1, \scratch3
|
||||
addq.ph \scratch2, \scratch2, \scratch4
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
precr.qb.ph \d_8888, \scratch1, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply two pixels (a8r8g8b8) with two pixels (a8r8g8b8). It requires
|
||||
* maskLSR needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8x4 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8888, \
|
||||
m2_8888, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
preceu.ph.qbl \scratch1, \m1_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch2, \m1_8888 /* 0 | G | 0 | B */
|
||||
preceu.ph.qbl \scratch3, \m2_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch4, \m2_8888 /* 0 | G | 0 | B */
|
||||
muleu_s.ph.qbl \scratch5, \s1_8888, \scratch1 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch6, \s1_8888, \scratch2 /* G*G | B*B */
|
||||
muleu_s.ph.qbl \scratch1, \s2_8888, \scratch3 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch2, \s2_8888, \scratch4 /* G*G | B*B */
|
||||
shra_r.ph \scratch3, \scratch5, 8
|
||||
shra_r.ph \scratch4, \scratch6, 8
|
||||
shra_r.ph \d1_8888, \scratch1, 8
|
||||
shra_r.ph \d2_8888, \scratch2, 8
|
||||
and \scratch3, \scratch3, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \scratch4, \scratch4, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
and \d1_8888, \d1_8888, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \d2_8888, \d2_8888, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
addq.ph \scratch3, \scratch3, \scratch5
|
||||
addq.ph \scratch4, \scratch4, \scratch6
|
||||
addq.ph \d1_8888, \d1_8888, \scratch1
|
||||
addq.ph \d2_8888, \d2_8888, \scratch2
|
||||
shra_r.ph \scratch3, \scratch3, 8
|
||||
shra_r.ph \scratch4, \scratch4, 8
|
||||
shra_r.ph \scratch5, \d1_8888, 8
|
||||
shra_r.ph \scratch6, \d2_8888, 8
|
||||
precr.qb.ph \d1_8888, \scratch3, \scratch4
|
||||
precr.qb.ph \d2_8888, \scratch5, \scratch6
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8
|
||||
* destination pixel (d_8888) using a8 mask (m_8). It also requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_8888_8_8888 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \
|
||||
\scratch1, \maskLSR, \
|
||||
\scratch2, \scratch3, \scratch4
|
||||
|
||||
not \scratch2, \scratch1
|
||||
srl \scratch2, \scratch2, 24
|
||||
|
||||
MIPS_UN8x4_MUL_UN8 \d_8888, \scratch2, \
|
||||
\d_8888, \maskLSR, \
|
||||
\scratch3, \scratch4, \out_8888
|
||||
|
||||
addu_s.qb \out_8888, \d_8888, \scratch1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two
|
||||
* a8r8g8b8 destination pixels (d1_8888 and d2_8888) using a8 masks (m1_8 and
|
||||
* m2_8). It also requires maskLSR needed for rounding process. maskLSR must
|
||||
* have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_2x8888_2x8_2x8888 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \
|
||||
\m1_8, \m2_8, \
|
||||
\scratch1, \scratch2, \
|
||||
\maskLSR, \
|
||||
\scratch3, \scratch4, \out1_8888, \
|
||||
\out2_8888, \scratch5, \scratch6
|
||||
|
||||
not \scratch3, \scratch1
|
||||
srl \scratch3, \scratch3, 24
|
||||
not \scratch4, \scratch2
|
||||
srl \scratch4, \scratch4, 24
|
||||
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \
|
||||
\scratch3, \scratch4, \
|
||||
\d1_8888, \d2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch5, \scratch6, \out1_8888, \
|
||||
\out2_8888, \scratch3, \scratch4
|
||||
|
||||
addu_s.qb \out1_8888, \d1_8888, \scratch1
|
||||
addu_s.qb \out2_8888, \d2_8888, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8
|
||||
* destination pixel (d_8888). It also requires maskLSR needed for rounding
|
||||
* process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_8888_8888 s_8888, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
not \scratch1, \s_8888
|
||||
srl \scratch1, \scratch1, 24
|
||||
|
||||
MIPS_UN8x4_MUL_UN8 \d_8888, \scratch1, \
|
||||
\out_8888, \maskLSR, \
|
||||
\scratch2, \scratch3, \scratch4
|
||||
|
||||
addu_s.qb \out_8888, \out_8888, \s_8888
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two
|
||||
* a8r8g8b8 destination pixels (d1_8888 and d2_8888). It also requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_2x8888_2x8888 s1_8888, \
|
||||
s2_8888, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
not \scratch1, \s1_8888
|
||||
srl \scratch1, \scratch1, 24
|
||||
not \scratch2, \s2_8888
|
||||
srl \scratch2, \scratch2, 24
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \
|
||||
\scratch1, \scratch2, \
|
||||
\out1_8888, \out2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch3, \scratch4, \scratch5, \
|
||||
\scratch6, \d1_8888, \d2_8888
|
||||
|
||||
addu_s.qb \out1_8888, \out1_8888, \s1_8888
|
||||
addu_s.qb \out2_8888, \out2_8888, \s2_8888
|
||||
.endm
|
||||
|
||||
.macro MIPS_UN8x4_MUL_UN8_ADD_UN8x4 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3
|
||||
MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \
|
||||
\out_8888, \maskLSR, \
|
||||
\scratch1, \scratch2, \scratch3
|
||||
|
||||
addu_s.qb \out_8888, \out_8888, \d_8888
|
||||
.endm
|
||||
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \
|
||||
\m1_8, \m2_8, \
|
||||
\out1_8888, \out2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch1, \scratch2, \scratch3, \
|
||||
\scratch4, \scratch5, \scratch6
|
||||
|
||||
addu_s.qb \out1_8888, \out1_8888, \d1_8888
|
||||
addu_s.qb \out2_8888, \out2_8888, \d2_8888
|
||||
.endm
|
||||
|
||||
.macro BILINEAR_INTERPOLATE_SINGLE_PIXEL tl, tr, bl, br, \
|
||||
scratch1, scratch2, \
|
||||
alpha, red, green, blue \
|
||||
wt1, wt2, wb1, wb2
|
||||
andi \scratch1, \tl, 0xff
|
||||
andi \scratch2, \tr, 0xff
|
||||
andi \alpha, \bl, 0xff
|
||||
andi \red, \br, 0xff
|
||||
|
||||
multu $ac0, \wt1, \scratch1
|
||||
maddu $ac0, \wt2, \scratch2
|
||||
maddu $ac0, \wb1, \alpha
|
||||
maddu $ac0, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 8, 8
|
||||
ext \scratch2, \tr, 8, 8
|
||||
ext \alpha, \bl, 8, 8
|
||||
ext \red, \br, 8, 8
|
||||
|
||||
multu $ac1, \wt1, \scratch1
|
||||
maddu $ac1, \wt2, \scratch2
|
||||
maddu $ac1, \wb1, \alpha
|
||||
maddu $ac1, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 16, 8
|
||||
ext \scratch2, \tr, 16, 8
|
||||
ext \alpha, \bl, 16, 8
|
||||
ext \red, \br, 16, 8
|
||||
|
||||
mflo \blue, $ac0
|
||||
|
||||
multu $ac2, \wt1, \scratch1
|
||||
maddu $ac2, \wt2, \scratch2
|
||||
maddu $ac2, \wb1, \alpha
|
||||
maddu $ac2, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 24, 8
|
||||
ext \scratch2, \tr, 24, 8
|
||||
ext \alpha, \bl, 24, 8
|
||||
ext \red, \br, 24, 8
|
||||
|
||||
mflo \green, $ac1
|
||||
|
||||
multu $ac3, \wt1, \scratch1
|
||||
maddu $ac3, \wt2, \scratch2
|
||||
maddu $ac3, \wb1, \alpha
|
||||
maddu $ac3, \wb2, \red
|
||||
|
||||
mflo \red, $ac2
|
||||
mflo \alpha, $ac3
|
||||
|
||||
precr.qb.ph \alpha, \alpha, \red
|
||||
precr.qb.ph \scratch1, \green, \blue
|
||||
precrq.qb.ph \tl, \alpha, \scratch1
|
||||
.endm
|
||||
|
||||
#endif //PIXMAN_MIPS_DSPR2_ASM_H
|
459
vendor/pixman/pixman/pixman-mips-dspr2.c
vendored
Normal file
459
vendor/pixman/pixman/pixman-mips-dspr2.c
vendored
Normal file
@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-mips-dspr2.h"
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0888_0888,
|
||||
uint8_t, 3, uint8_t, 3)
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_8888_rev,
|
||||
uint8_t, 3, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_0565_rev,
|
||||
uint8_t, 3, uint16_t, 1)
|
||||
#endif
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_pixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_rpixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_0565_ca,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_0565_n_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, add_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_0565,
|
||||
uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (0, in_n_8,
|
||||
uint8_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8_8_8, uint8_t, 1,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8_8888, uint32_t, 1,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8888_8888, uint32_t, 1,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_0565_8_0565, uint16_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_8888, uint32_t, 1,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_0565, uint32_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_0565_8_0565, uint16_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8888_8888, uint32_t, 1,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_0565, OVER,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_0565,
|
||||
OVER, uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 0565_8_0565,
|
||||
OVER, uint16_t, uint16_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
static pixman_bool_t
|
||||
mips_dspr2_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
uint8_t *byte_line;
|
||||
uint32_t byte_width;
|
||||
switch (bpp)
|
||||
{
|
||||
case 16:
|
||||
stride = stride * (int) sizeof (uint32_t) / 2;
|
||||
byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
|
||||
byte_width = width * 2;
|
||||
stride *= 2;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *dst = byte_line;
|
||||
byte_line += stride;
|
||||
pixman_fill_buff16_mips (dst, byte_width, _xor & 0xffff);
|
||||
}
|
||||
return TRUE;
|
||||
case 32:
|
||||
stride = stride * (int) sizeof (uint32_t) / 4;
|
||||
byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
|
||||
byte_width = width * 4;
|
||||
stride *= 4;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *dst = byte_line;
|
||||
byte_line += stride;
|
||||
pixman_fill_buff32_mips (dst, byte_width, _xor);
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
mips_dspr2_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
uint8_t *src_bytes;
|
||||
uint8_t *dst_bytes;
|
||||
uint32_t byte_width;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 16:
|
||||
src_stride = src_stride * (int) sizeof (uint32_t) / 2;
|
||||
dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
|
||||
src_bytes =(uint8_t *)(((uint16_t *)src_bits)
|
||||
+ src_stride * (src_y) + (src_x));
|
||||
dst_bytes = (uint8_t *)(((uint16_t *)dst_bits)
|
||||
+ dst_stride * (dest_y) + (dest_x));
|
||||
byte_width = width * 2;
|
||||
src_stride *= 2;
|
||||
dst_stride *= 2;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *src = src_bytes;
|
||||
uint8_t *dst = dst_bytes;
|
||||
src_bytes += src_stride;
|
||||
dst_bytes += dst_stride;
|
||||
pixman_mips_fast_memcpy (dst, src, byte_width);
|
||||
}
|
||||
return TRUE;
|
||||
case 32:
|
||||
src_stride = src_stride * (int) sizeof (uint32_t) / 4;
|
||||
dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
|
||||
src_bytes = (uint8_t *)(((uint32_t *)src_bits)
|
||||
+ src_stride * (src_y) + (src_x));
|
||||
dst_bytes = (uint8_t *)(((uint32_t *)dst_bits)
|
||||
+ dst_stride * (dest_y) + (dest_x));
|
||||
byte_width = width * 4;
|
||||
src_stride *= 4;
|
||||
dst_stride *= 4;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *src = src_bytes;
|
||||
uint8_t *dst = dst_bytes;
|
||||
src_bytes += src_stride;
|
||||
dst_bytes += dst_stride;
|
||||
pixman_mips_fast_memcpy (dst, src, byte_width);
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t mips_dspr2_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mips_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mips_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, mips_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, mips_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, mips_composite_src_0888_0888),
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, mips_composite_src_0888_8888_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, mips_composite_src_0888_0565_rev),
|
||||
#endif
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, mips_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, mips_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, mips_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, mips_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, mips_composite_src_n_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mips_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mips_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, mips_composite_over_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mips_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mips_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mips_composite_over_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mips_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mips_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mips_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mips_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, mips_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, mips_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, mips_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, mips_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, mips_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, mips_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, mips_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, mips_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mips_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mips_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mips_composite_add_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, mips_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, mips_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, mips_composite_add_8_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, mips_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, mips_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, mips_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, mips_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, mips_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, mips_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mips_composite_add_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mips_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mips_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, mips_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, mips_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, mips_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, mips_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, mips_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, mips_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN, solid, null, a8, mips_composite_in_n_8),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mips_8888_8888),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_0565),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, mips_0565_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888),
|
||||
/* Note: NONE repeat is not supported yet */
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, mips_0565_8888),
|
||||
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_8_0565),
|
||||
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, mips_0565_8_0565),
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, mips_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8_x888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
static void
|
||||
mips_dspr2_combine_over_u (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
if (mask)
|
||||
pixman_composite_over_8888_8888_8888_asm_mips (
|
||||
dest, (uint32_t *)src, (uint32_t *)mask, width);
|
||||
else
|
||||
pixman_composite_over_8888_8888_asm_mips (
|
||||
dest, (uint32_t *)src, width);
|
||||
}
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, mips_dspr2_fast_paths);
|
||||
|
||||
imp->combine_32[PIXMAN_OP_OVER] = mips_dspr2_combine_over_u;
|
||||
|
||||
imp->blt = mips_dspr2_blt;
|
||||
imp->fill = mips_dspr2_fill;
|
||||
|
||||
return imp;
|
||||
}
|
432
vendor/pixman/pixman/pixman-mips-dspr2.h
vendored
Normal file
432
vendor/pixman/pixman/pixman-mips-dspr2.h
vendored
Normal file
@ -0,0 +1,432 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_MIPS_DSPR2_H
|
||||
#define PIXMAN_MIPS_DSPR2_H
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
#define SKIP_ZERO_SRC 1
|
||||
#define SKIP_ZERO_MASK 2
|
||||
#define DO_FAST_MEMCPY 3
|
||||
|
||||
void
|
||||
pixman_mips_fast_memcpy (void *dst, void *src, uint32_t n_bytes);
|
||||
void
|
||||
pixman_fill_buff16_mips (void *dst, uint32_t n_bytes, uint16_t value);
|
||||
void
|
||||
pixman_fill_buff32_mips (void *dst, uint32_t n_bytes, uint32_t value);
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST(flags, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
\
|
||||
if (flags == DO_FAST_MEMCPY) \
|
||||
pixman_mips_fast_memcpy (dst, src, width * bpp); \
|
||||
else \
|
||||
pixman_composite_##name##_asm_mips (dst, src, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_N_DST(flags, name, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
uint32_t src, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
int32_t dst_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
\
|
||||
pixman_composite_##name##_asm_mips (dst, src, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST(flags, name, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
uint32_t src, \
|
||||
mask_type *mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
mask_type *mask_line, *mask; \
|
||||
int32_t dst_stride, mask_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
mask = mask_line; \
|
||||
mask_line += mask_stride; \
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST(flags, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
uint32_t mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
uint32_t mask; \
|
||||
\
|
||||
mask = _pixman_image_get_solid ( \
|
||||
imp, mask_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
\
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST(name, src_type, src_cnt, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
mask_type *mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
mask_type *mask_line, *mask; \
|
||||
int32_t dst_stride, src_stride, mask_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
mask = mask_line; \
|
||||
mask_line += mask_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST(name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_mips_##name##_##op (dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, w, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, COVER) \
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_none_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, NONE) \
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, PAD)
|
||||
|
||||
/* Provide entries for the fast path table */
|
||||
#define PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
const uint8_t * mask, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_mips_##name##_##op (const uint8_t * mask, \
|
||||
dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, \
|
||||
mask, w, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, TRUE, FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips( \
|
||||
dst_type * dst, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \
|
||||
const uint32_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips (dst, src_top, \
|
||||
src_bottom, w, \
|
||||
wt, wb, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NORMAL, \
|
||||
FLAG_NONE)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \
|
||||
dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NORMAL, \
|
||||
FLAG_HAVE_NON_SOLID_MASK)
|
||||
|
||||
#endif //PIXMAN_MIPS_DSPR2_H
|
382
vendor/pixman/pixman/pixman-mips-memcpy-asm.S
vendored
Normal file
382
vendor/pixman/pixman/pixman-mips-memcpy-asm.S
vendored
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "pixman-mips-dspr2-asm.h"
|
||||
|
||||
/*
|
||||
* This routine could be optimized for MIPS64. The current code only
|
||||
* uses MIPS32 instructions.
|
||||
*/
|
||||
|
||||
#ifdef EB
|
||||
# define LWHI lwl /* high part is left in big-endian */
|
||||
# define SWHI swl /* high part is left in big-endian */
|
||||
# define LWLO lwr /* low part is right in big-endian */
|
||||
# define SWLO swr /* low part is right in big-endian */
|
||||
#else
|
||||
# define LWHI lwr /* high part is right in little-endian */
|
||||
# define SWHI swr /* high part is right in little-endian */
|
||||
# define LWLO lwl /* low part is left in big-endian */
|
||||
# define SWLO swl /* low part is left in big-endian */
|
||||
#endif
|
||||
|
||||
LEAF_MIPS32R2(pixman_mips_fast_memcpy)
|
||||
|
||||
slti AT, a2, 8
|
||||
bne AT, zero, $last8
|
||||
move v0, a0 /* memcpy returns the dst pointer */
|
||||
|
||||
/* Test if the src and dst are word-aligned, or can be made word-aligned */
|
||||
xor t8, a1, a0
|
||||
andi t8, t8, 0x3 /* t8 is a0/a1 word-displacement */
|
||||
|
||||
bne t8, zero, $unaligned
|
||||
negu a3, a0
|
||||
|
||||
andi a3, a3, 0x3 /* we need to copy a3 bytes to make a0/a1 aligned */
|
||||
beq a3, zero, $chk16w /* when a3=0 then the dst (a0) is word-aligned */
|
||||
subu a2, a2, a3 /* now a2 is the remining bytes count */
|
||||
|
||||
LWHI t8, 0(a1)
|
||||
addu a1, a1, a3
|
||||
SWHI t8, 0(a0)
|
||||
addu a0, a0, a3
|
||||
|
||||
/* Now the dst/src are mutually word-aligned with word-aligned addresses */
|
||||
$chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */
|
||||
/* t8 is the byte count after 64-byte chunks */
|
||||
|
||||
beq a2, t8, $chk8w /* if a2==t8, no 64-byte chunks */
|
||||
/* There will be at most 1 32-byte chunk after it */
|
||||
subu a3, a2, t8 /* subtract from a2 the reminder */
|
||||
/* Here a3 counts bytes in 16w chunks */
|
||||
addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */
|
||||
|
||||
addu t0, a0, a2 /* t0 is the "past the end" address */
|
||||
|
||||
/*
|
||||
* When in the loop we exercise "pref 30, x(a0)", the a0+x should not be past
|
||||
* the "t0-32" address
|
||||
* This means: for x=128 the last "safe" a0 address is "t0-160"
|
||||
* Alternatively, for x=64 the last "safe" a0 address is "t0-96"
|
||||
* In the current version we use "pref 30, 128(a0)", so "t0-160" is the limit
|
||||
*/
|
||||
subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */
|
||||
|
||||
pref 0, 0(a1) /* bring the first line of src, addr 0 */
|
||||
pref 0, 32(a1) /* bring the second line of src, addr 32 */
|
||||
pref 0, 64(a1) /* bring the third line of src, addr 64 */
|
||||
pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */
|
||||
/* In case the a0 > t9 don't use "pref 30" at all */
|
||||
sgtu v1, a0, t9
|
||||
bgtz v1, $loop16w /* skip "pref 30, 64(a0)" for too short arrays */
|
||||
nop
|
||||
/* otherwise, start with using pref30 */
|
||||
pref 30, 64(a0)
|
||||
$loop16w:
|
||||
pref 0, 96(a1)
|
||||
lw t0, 0(a1)
|
||||
bgtz v1, $skip_pref30_96 /* skip "pref 30, 96(a0)" */
|
||||
lw t1, 4(a1)
|
||||
pref 30, 96(a0) /* continue setting up the dest, addr 96 */
|
||||
$skip_pref30_96:
|
||||
lw t2, 8(a1)
|
||||
lw t3, 12(a1)
|
||||
lw t4, 16(a1)
|
||||
lw t5, 20(a1)
|
||||
lw t6, 24(a1)
|
||||
lw t7, 28(a1)
|
||||
pref 0, 128(a1) /* bring the next lines of src, addr 128 */
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
|
||||
lw t0, 32(a1)
|
||||
bgtz v1, $skip_pref30_128 /* skip "pref 30, 128(a0)" */
|
||||
lw t1, 36(a1)
|
||||
pref 30, 128(a0) /* continue setting up the dest, addr 128 */
|
||||
$skip_pref30_128:
|
||||
lw t2, 40(a1)
|
||||
lw t3, 44(a1)
|
||||
lw t4, 48(a1)
|
||||
lw t5, 52(a1)
|
||||
lw t6, 56(a1)
|
||||
lw t7, 60(a1)
|
||||
pref 0, 160(a1) /* bring the next lines of src, addr 160 */
|
||||
|
||||
sw t0, 32(a0)
|
||||
sw t1, 36(a0)
|
||||
sw t2, 40(a0)
|
||||
sw t3, 44(a0)
|
||||
sw t4, 48(a0)
|
||||
sw t5, 52(a0)
|
||||
sw t6, 56(a0)
|
||||
sw t7, 60(a0)
|
||||
|
||||
addiu a0, a0, 64 /* adding 64 to dest */
|
||||
sgtu v1, a0, t9
|
||||
bne a0, a3, $loop16w
|
||||
addiu a1, a1, 64 /* adding 64 to src */
|
||||
move a2, t8
|
||||
|
||||
/* Here we have src and dest word-aligned but less than 64-bytes to go */
|
||||
|
||||
$chk8w:
|
||||
pref 0, 0x0(a1)
|
||||
andi t8, a2, 0x1f /* is there a 32-byte chunk? */
|
||||
/* the t8 is the reminder count past 32-bytes */
|
||||
beq a2, t8, $chk1w /* when a2=t8, no 32-byte chunk */
|
||||
nop
|
||||
|
||||
lw t0, 0(a1)
|
||||
lw t1, 4(a1)
|
||||
lw t2, 8(a1)
|
||||
lw t3, 12(a1)
|
||||
lw t4, 16(a1)
|
||||
lw t5, 20(a1)
|
||||
lw t6, 24(a1)
|
||||
lw t7, 28(a1)
|
||||
addiu a1, a1, 32
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
addiu a0, a0, 32
|
||||
|
||||
$chk1w:
|
||||
andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */
|
||||
beq a2, t8, $last8
|
||||
subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */
|
||||
addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */
|
||||
|
||||
/* copying in words (4-byte chunks) */
|
||||
$wordCopy_loop:
|
||||
lw t3, 0(a1) /* the first t3 may be equal t0 ... optimize? */
|
||||
addiu a1, a1, 4
|
||||
addiu a0, a0, 4
|
||||
bne a0, a3, $wordCopy_loop
|
||||
sw t3, -4(a0)
|
||||
|
||||
/* For the last (<8) bytes */
|
||||
$last8:
|
||||
blez a2, leave
|
||||
addu a3, a0, a2 /* a3 is the last dst address */
|
||||
$last8loop:
|
||||
lb v1, 0(a1)
|
||||
addiu a1, a1, 1
|
||||
addiu a0, a0, 1
|
||||
bne a0, a3, $last8loop
|
||||
sb v1, -1(a0)
|
||||
|
||||
leave: j ra
|
||||
nop
|
||||
|
||||
/*
|
||||
* UNALIGNED case
|
||||
*/
|
||||
|
||||
$unaligned:
|
||||
/* got here with a3="negu a0" */
|
||||
andi a3, a3, 0x3 /* test if the a0 is word aligned */
|
||||
beqz a3, $ua_chk16w
|
||||
subu a2, a2, a3 /* bytes left after initial a3 bytes */
|
||||
|
||||
LWHI v1, 0(a1)
|
||||
LWLO v1, 3(a1)
|
||||
addu a1, a1, a3 /* a3 may be here 1, 2 or 3 */
|
||||
SWHI v1, 0(a0)
|
||||
addu a0, a0, a3 /* below the dst will be word aligned (NOTE1) */
|
||||
|
||||
$ua_chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */
|
||||
/* t8 is the byte count after 64-byte chunks */
|
||||
beq a2, t8, $ua_chk8w /* if a2==t8, no 64-byte chunks */
|
||||
/* There will be at most 1 32-byte chunk after it */
|
||||
subu a3, a2, t8 /* subtract from a2 the reminder */
|
||||
/* Here a3 counts bytes in 16w chunks */
|
||||
addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */
|
||||
|
||||
addu t0, a0, a2 /* t0 is the "past the end" address */
|
||||
|
||||
subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */
|
||||
|
||||
pref 0, 0(a1) /* bring the first line of src, addr 0 */
|
||||
pref 0, 32(a1) /* bring the second line of src, addr 32 */
|
||||
pref 0, 64(a1) /* bring the third line of src, addr 64 */
|
||||
pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */
|
||||
/* In case the a0 > t9 don't use "pref 30" at all */
|
||||
sgtu v1, a0, t9
|
||||
bgtz v1, $ua_loop16w /* skip "pref 30, 64(a0)" for too short arrays */
|
||||
nop
|
||||
/* otherwise, start with using pref30 */
|
||||
pref 30, 64(a0)
|
||||
$ua_loop16w:
|
||||
pref 0, 96(a1)
|
||||
LWHI t0, 0(a1)
|
||||
LWLO t0, 3(a1)
|
||||
LWHI t1, 4(a1)
|
||||
bgtz v1, $ua_skip_pref30_96
|
||||
LWLO t1, 7(a1)
|
||||
pref 30, 96(a0) /* continue setting up the dest, addr 96 */
|
||||
$ua_skip_pref30_96:
|
||||
LWHI t2, 8(a1)
|
||||
LWLO t2, 11(a1)
|
||||
LWHI t3, 12(a1)
|
||||
LWLO t3, 15(a1)
|
||||
LWHI t4, 16(a1)
|
||||
LWLO t4, 19(a1)
|
||||
LWHI t5, 20(a1)
|
||||
LWLO t5, 23(a1)
|
||||
LWHI t6, 24(a1)
|
||||
LWLO t6, 27(a1)
|
||||
LWHI t7, 28(a1)
|
||||
LWLO t7, 31(a1)
|
||||
pref 0, 128(a1) /* bring the next lines of src, addr 128 */
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
|
||||
LWHI t0, 32(a1)
|
||||
LWLO t0, 35(a1)
|
||||
LWHI t1, 36(a1)
|
||||
bgtz v1, $ua_skip_pref30_128
|
||||
LWLO t1, 39(a1)
|
||||
pref 30, 128(a0) /* continue setting up the dest, addr 128 */
|
||||
$ua_skip_pref30_128:
|
||||
LWHI t2, 40(a1)
|
||||
LWLO t2, 43(a1)
|
||||
LWHI t3, 44(a1)
|
||||
LWLO t3, 47(a1)
|
||||
LWHI t4, 48(a1)
|
||||
LWLO t4, 51(a1)
|
||||
LWHI t5, 52(a1)
|
||||
LWLO t5, 55(a1)
|
||||
LWHI t6, 56(a1)
|
||||
LWLO t6, 59(a1)
|
||||
LWHI t7, 60(a1)
|
||||
LWLO t7, 63(a1)
|
||||
pref 0, 160(a1) /* bring the next lines of src, addr 160 */
|
||||
|
||||
sw t0, 32(a0)
|
||||
sw t1, 36(a0)
|
||||
sw t2, 40(a0)
|
||||
sw t3, 44(a0)
|
||||
sw t4, 48(a0)
|
||||
sw t5, 52(a0)
|
||||
sw t6, 56(a0)
|
||||
sw t7, 60(a0)
|
||||
|
||||
addiu a0, a0, 64 /* adding 64 to dest */
|
||||
sgtu v1, a0, t9
|
||||
bne a0, a3, $ua_loop16w
|
||||
addiu a1, a1, 64 /* adding 64 to src */
|
||||
move a2, t8
|
||||
|
||||
/* Here we have src and dest word-aligned but less than 64-bytes to go */
|
||||
|
||||
$ua_chk8w:
|
||||
pref 0, 0x0(a1)
|
||||
andi t8, a2, 0x1f /* is there a 32-byte chunk? */
|
||||
/* the t8 is the reminder count */
|
||||
beq a2, t8, $ua_chk1w /* when a2=t8, no 32-byte chunk */
|
||||
|
||||
LWHI t0, 0(a1)
|
||||
LWLO t0, 3(a1)
|
||||
LWHI t1, 4(a1)
|
||||
LWLO t1, 7(a1)
|
||||
LWHI t2, 8(a1)
|
||||
LWLO t2, 11(a1)
|
||||
LWHI t3, 12(a1)
|
||||
LWLO t3, 15(a1)
|
||||
LWHI t4, 16(a1)
|
||||
LWLO t4, 19(a1)
|
||||
LWHI t5, 20(a1)
|
||||
LWLO t5, 23(a1)
|
||||
LWHI t6, 24(a1)
|
||||
LWLO t6, 27(a1)
|
||||
LWHI t7, 28(a1)
|
||||
LWLO t7, 31(a1)
|
||||
addiu a1, a1, 32
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
addiu a0, a0, 32
|
||||
|
||||
$ua_chk1w:
|
||||
andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */
|
||||
beq a2, t8, $ua_smallCopy
|
||||
subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */
|
||||
addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */
|
||||
|
||||
/* copying in words (4-byte chunks) */
|
||||
$ua_wordCopy_loop:
|
||||
LWHI v1, 0(a1)
|
||||
LWLO v1, 3(a1)
|
||||
addiu a1, a1, 4
|
||||
addiu a0, a0, 4 /* note: dst=a0 is word aligned here, see NOTE1 */
|
||||
bne a0, a3, $ua_wordCopy_loop
|
||||
sw v1, -4(a0)
|
||||
|
||||
/* Now less than 4 bytes (value in a2) left to copy */
|
||||
$ua_smallCopy:
|
||||
beqz a2, leave
|
||||
addu a3, a0, a2 /* a3 is the last dst address */
|
||||
$ua_smallCopy_loop:
|
||||
lb v1, 0(a1)
|
||||
addiu a1, a1, 1
|
||||
addiu a0, a0, 1
|
||||
bne a0, a3, $ua_smallCopy_loop
|
||||
sb v1, -1(a0)
|
||||
|
||||
j ra
|
||||
nop
|
||||
|
||||
END(pixman_mips_fast_memcpy)
|
94
vendor/pixman/pixman/pixman-mips.c
vendored
Normal file
94
vendor/pixman/pixman/pixman-mips.c
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static pixman_bool_t
|
||||
have_feature (const char *search_string)
|
||||
{
|
||||
#if defined (__linux__) /* linux ELF */
|
||||
/* Simple detection of MIPS features at runtime for Linux.
|
||||
* It is based on /proc/cpuinfo, which reveals hardware configuration
|
||||
* to user-space applications. According to MIPS (early 2010), no similar
|
||||
* facility is universally available on the MIPS architectures, so it's up
|
||||
* to individual OSes to provide such.
|
||||
*/
|
||||
const char *file_name = "/proc/cpuinfo";
|
||||
char cpuinfo_line[256];
|
||||
FILE *f = NULL;
|
||||
|
||||
if ((f = fopen (file_name, "r")) == NULL)
|
||||
return FALSE;
|
||||
|
||||
while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
|
||||
{
|
||||
if (strstr (cpuinfo_line, search_string) != NULL)
|
||||
{
|
||||
fclose (f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
#endif
|
||||
|
||||
/* Did not find string in the proc file, or not Linux ELF. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_mips_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_LOONGSON_MMI
|
||||
/* I really don't know if some Loongson CPUs don't have MMI. */
|
||||
if (!_pixman_disabled ("loongson-mmi") && have_feature ("Loongson"))
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MIPS_DSPR2
|
||||
if (!_pixman_disabled ("mips-dspr2"))
|
||||
{
|
||||
int already_compiling_everything_for_dspr2 = 0;
|
||||
#if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
|
||||
already_compiling_everything_for_dspr2 = 1;
|
||||
#endif
|
||||
if (already_compiling_everything_for_dspr2 ||
|
||||
/* Only currently available MIPS core that supports DSPr2 is 74K. */
|
||||
have_feature ("MIPS 74K"))
|
||||
{
|
||||
imp = _pixman_implementation_create_mips_dspr2 (imp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
4153
vendor/pixman/pixman/pixman-mmx.c
vendored
Normal file
4153
vendor/pixman/pixman/pixman-mmx.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
161
vendor/pixman/pixman/pixman-noop.c
vendored
Normal file
161
vendor/pixman/pixman/pixman-noop.c
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2011 Red Hat, Inc.
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
static void
|
||||
noop_composite (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
uint32_t *result = iter->buffer;
|
||||
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_solid_narrow (pixman_iter_t *iter,
|
||||
const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
uint32_t *end = buffer + iter->width;
|
||||
uint32_t color;
|
||||
|
||||
if (iter->image->type == SOLID)
|
||||
color = image->solid.color_32;
|
||||
else
|
||||
color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_solid_wide (pixman_iter_t *iter,
|
||||
const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
argb_t *buffer = (argb_t *)iter->buffer;
|
||||
argb_t *end = buffer + iter->width;
|
||||
argb_t color;
|
||||
|
||||
if (iter->image->type == SOLID)
|
||||
color = image->solid.color_float;
|
||||
else
|
||||
color = image->bits.fetch_pixel_float (&image->bits, 0, 0);
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
|
||||
iter->buffer =
|
||||
image->bits.bits + iter->y * image->bits.rowstride + iter->x;
|
||||
}
|
||||
|
||||
static void
|
||||
dest_write_back_direct (pixman_iter_t *iter)
|
||||
{
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
}
|
||||
|
||||
static const pixman_iter_info_t noop_iters[] =
|
||||
{
|
||||
/* Source iters */
|
||||
{ PIXMAN_any,
|
||||
0, ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_SRC,
|
||||
NULL,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL
|
||||
},
|
||||
{ PIXMAN_solid,
|
||||
FAST_PATH_NO_ALPHA_MAP, ITER_NARROW | ITER_SRC,
|
||||
noop_init_solid_narrow,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL,
|
||||
},
|
||||
{ PIXMAN_solid,
|
||||
FAST_PATH_NO_ALPHA_MAP, ITER_WIDE | ITER_SRC,
|
||||
noop_init_solid_wide,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL
|
||||
},
|
||||
{ PIXMAN_a8r8g8b8,
|
||||
FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |
|
||||
FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,
|
||||
ITER_NARROW | ITER_SRC,
|
||||
noop_init_direct_buffer,
|
||||
noop_get_scanline,
|
||||
NULL
|
||||
},
|
||||
/* Dest iters */
|
||||
{ PIXMAN_a8r8g8b8,
|
||||
FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST,
|
||||
noop_init_direct_buffer,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
dest_write_back_direct
|
||||
},
|
||||
{ PIXMAN_x8r8g8b8,
|
||||
FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST | ITER_LOCALIZED_ALPHA,
|
||||
noop_init_direct_buffer,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
dest_write_back_direct
|
||||
},
|
||||
{ PIXMAN_null },
|
||||
};
|
||||
|
||||
static const pixman_fast_path_t noop_fast_paths[] =
|
||||
{
|
||||
{ PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite },
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_noop (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, noop_fast_paths);
|
||||
|
||||
imp->iter_info = noop_iters;
|
||||
|
||||
return imp;
|
||||
}
|
173
vendor/pixman/pixman/pixman-ppc.c
vendored
Normal file
173
vendor/pixman/pixman/pixman-ppc.c
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef USE_VMX
|
||||
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-maltivec -mabi=altivec", as gcc would try to save vector register
|
||||
* across function calls causing SIGILL on cpus without Altivec/vmx.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int error, have_vmx;
|
||||
size_t length = sizeof(have_vmx);
|
||||
|
||||
error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int error, have_vmx;
|
||||
int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
|
||||
size_t length = sizeof(have_vmx);
|
||||
|
||||
error = sysctl (mib, 2, &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error != 0)
|
||||
return FALSE;
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__FreeBSD__)
|
||||
#include <machine/cpu.h>
|
||||
#include <sys/auxv.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
|
||||
unsigned long cpufeatures;
|
||||
int have_vmx;
|
||||
|
||||
if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)))
|
||||
return FALSE;
|
||||
|
||||
have_vmx = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__linux__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/auxvec.h>
|
||||
#include <asm/cputable.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int have_vmx = FALSE;
|
||||
int fd;
|
||||
struct
|
||||
{
|
||||
unsigned long type;
|
||||
unsigned long value;
|
||||
} aux;
|
||||
|
||||
fd = open ("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while (read (fd, &aux, sizeof (aux)) == sizeof (aux))
|
||||
{
|
||||
if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC))
|
||||
{
|
||||
have_vmx = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
static jmp_buf jump_env;
|
||||
|
||||
static void
|
||||
vmx_test (int sig,
|
||||
siginfo_t *si,
|
||||
void * unused)
|
||||
{
|
||||
longjmp (jump_env, 1);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
struct sigaction sa, osa;
|
||||
int jmp_result;
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_sigaction = vmx_test;
|
||||
sigaction (SIGILL, &sa, &osa);
|
||||
jmp_result = setjmp (jump_env);
|
||||
if (jmp_result == 0)
|
||||
{
|
||||
asm volatile ( "vor 0, 0, 0" );
|
||||
}
|
||||
sigaction (SIGILL, &osa, NULL);
|
||||
return (jmp_result == 0);
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
#endif /* USE_VMX */
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_ppc_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_VMX
|
||||
if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
|
||||
imp = _pixman_implementation_create_vmx (imp);
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
1193
vendor/pixman/pixman/pixman-private.h
vendored
Normal file
1193
vendor/pixman/pixman/pixman-private.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
509
vendor/pixman/pixman/pixman-radial-gradient.c
vendored
Normal file
509
vendor/pixman/pixman/pixman-radial-gradient.c
vendored
Normal file
@ -0,0 +1,509 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static inline pixman_fixed_32_32_t
|
||||
dot (pixman_fixed_48_16_t x1,
|
||||
pixman_fixed_48_16_t y1,
|
||||
pixman_fixed_48_16_t z1,
|
||||
pixman_fixed_48_16_t x2,
|
||||
pixman_fixed_48_16_t y2,
|
||||
pixman_fixed_48_16_t z2)
|
||||
{
|
||||
/*
|
||||
* Exact computation, assuming that the input values can
|
||||
* be represented as pixman_fixed_16_16_t
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
static inline double
|
||||
fdot (double x1,
|
||||
double y1,
|
||||
double z1,
|
||||
double x2,
|
||||
double y2,
|
||||
double z2)
|
||||
{
|
||||
/*
|
||||
* Error can be unbound in some special cases.
|
||||
* Using clever dot product algorithms (for example compensated
|
||||
* dot product) would improve this but make the code much less
|
||||
* obvious
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
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:
|
||||
* - discr can have an unbound error (if b*b-a*c is very small),
|
||||
* potentially making it the opposite sign of what it should have been
|
||||
* (thus clearing a pixel that would have been colored or vice-versa)
|
||||
* or propagating the error to sqrtdiscr;
|
||||
* if discr has the wrong sign or b is very small, this can lead to bad
|
||||
* results
|
||||
*
|
||||
* - the algorithm used to compute the solutions of the quadratic
|
||||
* equation is not numerically stable (but saves one division compared
|
||||
* to the numerically stable one);
|
||||
* this can be a problem if a*c is much smaller than b*b
|
||||
*
|
||||
* - the above problems are worse if a is small (as inva becomes bigger)
|
||||
*/
|
||||
double discr;
|
||||
|
||||
if (a == 0)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (b == 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)
|
||||
{
|
||||
write_pixel (walker, t, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset (buffer, 0, Bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
discr = fdot (b, a, 0, b, -c, 0);
|
||||
if (discr >= 0)
|
||||
{
|
||||
double sqrtdiscr, t0, t1;
|
||||
|
||||
sqrtdiscr = sqrt (discr);
|
||||
t0 = (b + sqrtdiscr) * inva;
|
||||
t1 = (b - sqrtdiscr) * inva;
|
||||
|
||||
/*
|
||||
* The root that must be used is the biggest one that belongs
|
||||
* to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any
|
||||
* solution that results in a positive radius otherwise).
|
||||
*
|
||||
* If a > 0, t0 is the biggest solution, so if it is valid, it
|
||||
* is the correct result.
|
||||
*
|
||||
* If a < 0, only one of the solutions can be valid, so the
|
||||
* order in which they are tested is not important.
|
||||
*/
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t0 && t0 <= pixman_fixed_1)
|
||||
{
|
||||
write_pixel (walker, t0, buffer);
|
||||
return;
|
||||
}
|
||||
else if (0 <= t1 && t1 <= pixman_fixed_1)
|
||||
{
|
||||
write_pixel (walker, t1, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t0 * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t0, buffer);
|
||||
return;
|
||||
}
|
||||
else if (t1 * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t1, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset (buffer, 0, Bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
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.
|
||||
* See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
|
||||
* Manual (PDF 32000-1:2008 at the time of this writing).
|
||||
*
|
||||
* In the radial gradient problem we are given two circles (c₁,r₁) and
|
||||
* (c₂,r₂) that define the gradient itself.
|
||||
*
|
||||
* Mathematically the gradient can be defined as the family of circles
|
||||
*
|
||||
* ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂)
|
||||
*
|
||||
* excluding those circles whose radius would be < 0. When a point
|
||||
* belongs to more than one circle, the one with a bigger t is the only
|
||||
* one that contributes to its color. When a point does not belong
|
||||
* to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0).
|
||||
* Further limitations on the range of values for t are imposed when
|
||||
* the gradient is not repeated, namely t must belong to [0,1].
|
||||
*
|
||||
* The graphical result is the same as drawing the valid (radius > 0)
|
||||
* circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
|
||||
* is not repeated) using SOURCE operator composition.
|
||||
*
|
||||
* It looks like a cone pointing towards the viewer if the ending circle
|
||||
* is smaller than the starting one, a cone pointing inside the page if
|
||||
* the starting circle is the smaller one and like a cylinder if they
|
||||
* have the same radius.
|
||||
*
|
||||
* What we actually do is, given the point whose color we are interested
|
||||
* in, compute the t values for that point, solving for t in:
|
||||
*
|
||||
* length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
|
||||
*
|
||||
* Let's rewrite it in a simpler way, by defining some auxiliary
|
||||
* variables:
|
||||
*
|
||||
* cd = c₂ - c₁
|
||||
* pd = p - c₁
|
||||
* dr = r₂ - r₁
|
||||
* length(t·cd - pd) = r₁ + t·dr
|
||||
*
|
||||
* which actually means
|
||||
*
|
||||
* hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr
|
||||
*
|
||||
* or
|
||||
*
|
||||
* ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr.
|
||||
*
|
||||
* If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes:
|
||||
*
|
||||
* (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)²
|
||||
*
|
||||
* where we can actually expand the squares and solve for t:
|
||||
*
|
||||
* t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² =
|
||||
* = r₁² + 2·r₁·t·dr + t²·dr²
|
||||
*
|
||||
* (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t +
|
||||
* (pdx² + pdy² - r₁²) = 0
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* At² - 2Bt + C = 0
|
||||
*
|
||||
* The solutions (unless the equation degenerates because of A = 0) are:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* The solution we are going to prefer is the bigger one, unless the
|
||||
* radius associated to it is negative (or it falls outside the valid t
|
||||
* range).
|
||||
*
|
||||
* Additional observations (useful for optimizations):
|
||||
* A does not depend on p
|
||||
*
|
||||
* A < 0 <=> one of the two circles completely contains the other one
|
||||
* <=> for every p, the radiuses associated with the two t solutions
|
||||
* have opposite sign
|
||||
*/
|
||||
pixman_image_t *image = iter->image;
|
||||
int x = iter->x;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
radial_gradient_t *radial = (radial_gradient_t *)image;
|
||||
uint32_t *end = buffer + width * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_vector_t v, unit;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
unit.vector[0] = image->common.transform->matrix[0][0];
|
||||
unit.vector[1] = image->common.transform->matrix[1][0];
|
||||
unit.vector[2] = image->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)
|
||||
{
|
||||
/*
|
||||
* Given:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* where
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* det = B² - A·C
|
||||
*
|
||||
* Since we have an affine transformation, we know that (pdx, pdy)
|
||||
* increase linearly with each pixel,
|
||||
*
|
||||
* pdx = pdx₀ + n·ux,
|
||||
* pdy = pdy₀ + n·uy,
|
||||
*
|
||||
* we can then express B, C and det through multiple differentiation.
|
||||
*/
|
||||
pixman_fixed_32_32_t b, db, c, dc, ddc;
|
||||
|
||||
/* warning: this computation may overflow */
|
||||
v.vector[0] -= radial->c1.x;
|
||||
v.vector[1] -= radial->c1.y;
|
||||
|
||||
/*
|
||||
* B and C are computed and updated exactly.
|
||||
* If fdot was used instead of dot, in the worst case it would
|
||||
* lose 11 bits of precision in each of the multiplication and
|
||||
* summing up would zero out all the bit that were preserved,
|
||||
* thus making the result 0 instead of the correct one.
|
||||
* This would mean a worst case of unbound relative error or
|
||||
* about 2^10 absolute error
|
||||
*/
|
||||
b = dot (v.vector[0], v.vector[1], radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
db = dot (unit.vector[0], unit.vector[1], 0,
|
||||
radial->delta.x, radial->delta.y, 0);
|
||||
|
||||
c = dot (v.vector[0], v.vector[1],
|
||||
-((pixman_fixed_48_16_t) radial->c1.radius),
|
||||
v.vector[0], v.vector[1], radial->c1.radius);
|
||||
dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0],
|
||||
2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1],
|
||||
0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
ddc = 2 * dot (unit.vector[0], unit.vector[1], 0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
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 += (Bpp / 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective */
|
||||
/* Warning:
|
||||
* error propagation guarantees are much looser than in the affine case
|
||||
*/
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double pdx, pdy, invv2, b, c;
|
||||
|
||||
invv2 = 1. * pixman_fixed_1 / v.vector[2];
|
||||
|
||||
pdx = v.vector[0] * invv2 - radial->c1.x;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
pdy = v.vector[1] * invv2 - radial->c1.y;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
b = fdot (pdx, pdy, radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y,
|
||||
radial->delta.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
c = fdot (pdx, pdy, -radial->c1.radius,
|
||||
pdx, pdy, radial->c1.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
radial_write_color (radial->a, b, c,
|
||||
radial->inva,
|
||||
radial->delta.radius,
|
||||
radial->mindr,
|
||||
&walker,
|
||||
image->common.repeat,
|
||||
Bpp,
|
||||
write_pixel,
|
||||
buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (buffer, 0, Bpp);
|
||||
}
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
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)
|
||||
{
|
||||
return radial_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = radial_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = radial_get_scanline_wide;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
radial_gradient_t *radial;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
radial = &image->radial;
|
||||
|
||||
if (!_pixman_init_gradient (&radial->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image->type = RADIAL;
|
||||
|
||||
radial->c1.x = inner->x;
|
||||
radial->c1.y = inner->y;
|
||||
radial->c1.radius = inner_radius;
|
||||
radial->c2.x = outer->x;
|
||||
radial->c2.y = outer->y;
|
||||
radial->c2.radius = outer_radius;
|
||||
|
||||
/* warning: this computations may overflow */
|
||||
radial->delta.x = radial->c2.x - radial->c1.x;
|
||||
radial->delta.y = radial->c2.y - radial->c1.y;
|
||||
radial->delta.radius = radial->c2.radius - radial->c1.radius;
|
||||
|
||||
/* computed exactly, then cast to double -> every bit of the double
|
||||
representation is correct (53 bits) */
|
||||
radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
if (radial->a != 0)
|
||||
radial->inva = 1. * pixman_fixed_1 / radial->a;
|
||||
|
||||
radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;
|
||||
|
||||
return image;
|
||||
}
|
2800
vendor/pixman/pixman/pixman-region.c
vendored
Normal file
2800
vendor/pixman/pixman/pixman-region.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
67
vendor/pixman/pixman/pixman-region16.c
vendored
Normal file
67
vendor/pixman/pixman/pixman-region16.c
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#undef PIXMAN_DISABLE_DEPRECATED
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef pixman_box16_t box_type_t;
|
||||
typedef pixman_region16_data_t region_data_type_t;
|
||||
typedef pixman_region16_t region_type_t;
|
||||
typedef int32_t overflow_int_t;
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} point_type_t;
|
||||
|
||||
#define PREFIX(x) pixman_region##x
|
||||
|
||||
#define PIXMAN_REGION_MAX INT16_MAX
|
||||
#define PIXMAN_REGION_MIN INT16_MIN
|
||||
|
||||
#include "pixman-region.c"
|
||||
|
||||
/* This function exists only to make it possible to preserve the X ABI -
|
||||
* it should go away at first opportunity.
|
||||
*
|
||||
* The problem is that the X ABI exports the three structs and has used
|
||||
* them through macros. So the X server calls this function with
|
||||
* the addresses of those structs which makes the existing code continue to
|
||||
* work.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_region_set_static_pointers (pixman_box16_t *empty_box,
|
||||
pixman_region16_data_t *empty_data,
|
||||
pixman_region16_data_t *broken_data)
|
||||
{
|
||||
pixman_region_empty_box = empty_box;
|
||||
pixman_region_empty_data = empty_data;
|
||||
pixman_broken_data = broken_data;
|
||||
}
|
47
vendor/pixman/pixman/pixman-region32.c
vendored
Normal file
47
vendor/pixman/pixman/pixman-region32.c
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef pixman_box32_t box_type_t;
|
||||
typedef pixman_region32_data_t region_data_type_t;
|
||||
typedef pixman_region32_t region_type_t;
|
||||
typedef int64_t overflow_int_t;
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} point_type_t;
|
||||
|
||||
#define PREFIX(x) pixman_region32##x
|
||||
|
||||
#define PIXMAN_REGION_MAX INT32_MAX
|
||||
#define PIXMAN_REGION_MIN INT32_MIN
|
||||
|
||||
#include "pixman-region.c"
|
67
vendor/pixman/pixman/pixman-solid-fill.c
vendored
Normal file
67
vendor/pixman/pixman/pixman-solid-fill.c
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007, 2009 Red Hat, Inc.
|
||||
* Copyright © 2009 Soren Sandmann
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
static uint32_t
|
||||
color_to_uint32 (const pixman_color_t *color)
|
||||
{
|
||||
return
|
||||
((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
|
||||
color_to_float (const pixman_color_t *color)
|
||||
{
|
||||
argb_t result;
|
||||
|
||||
result.a = pixman_unorm_to_float (color->alpha, 16);
|
||||
result.r = pixman_unorm_to_float (color->red, 16);
|
||||
result.g = pixman_unorm_to_float (color->green, 16);
|
||||
result.b = pixman_unorm_to_float (color->blue, 16);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_solid_fill (const pixman_color_t *color)
|
||||
{
|
||||
pixman_image_t *img = _pixman_image_allocate ();
|
||||
|
||||
if (!img)
|
||||
return NULL;
|
||||
|
||||
img->type = SOLID;
|
||||
img->solid.color = *color;
|
||||
img->solid.color_32 = color_to_uint32 (color);
|
||||
img->solid.color_float = color_to_float (color);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
6528
vendor/pixman/pixman/pixman-sse2.c
vendored
Normal file
6528
vendor/pixman/pixman/pixman-sse2.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
351
vendor/pixman/pixman/pixman-ssse3.c
vendored
Normal file
351
vendor/pixman/pixman/pixman-ssse3.c
vendored
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright © 2013 Soren Sandmann Pedersen
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann (soren.sandmann@gmail.com)
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <tmmintrin.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int y;
|
||||
uint64_t * buffer;
|
||||
} line_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
line_t lines[2];
|
||||
pixman_fixed_t y;
|
||||
pixman_fixed_t x;
|
||||
uint64_t data[1];
|
||||
} bilinear_info_t;
|
||||
|
||||
static void
|
||||
ssse3_fetch_horizontal (bits_image_t *image, line_t *line,
|
||||
int y, pixman_fixed_t x, pixman_fixed_t ux, int n)
|
||||
{
|
||||
uint32_t *bits = image->bits + y * image->rowstride;
|
||||
__m128i vx = _mm_set_epi16 (
|
||||
- (x + 1), x, - (x + 1), x,
|
||||
- (x + ux + 1), x + ux, - (x + ux + 1), x + ux);
|
||||
__m128i vux = _mm_set_epi16 (
|
||||
- 2 * ux, 2 * ux, - 2 * ux, 2 * ux,
|
||||
- 2 * ux, 2 * ux, - 2 * ux, 2 * ux);
|
||||
__m128i vaddc = _mm_set_epi16 (1, 0, 1, 0, 1, 0, 1, 0);
|
||||
__m128i *b = (__m128i *)line->buffer;
|
||||
__m128i vrl0, vrl1;
|
||||
|
||||
while ((n -= 2) >= 0)
|
||||
{
|
||||
__m128i vw, vr, s;
|
||||
|
||||
vrl1 = _mm_loadl_epi64 (
|
||||
(__m128i *)(bits + pixman_fixed_to_int (x + ux)));
|
||||
/* vrl1: R1, L1 */
|
||||
|
||||
final_pixel:
|
||||
vrl0 = _mm_loadl_epi64 (
|
||||
(__m128i *)(bits + pixman_fixed_to_int (x)));
|
||||
/* vrl0: R0, L0 */
|
||||
|
||||
/* The weights are based on vx which is a vector of
|
||||
*
|
||||
* - (x + 1), x, - (x + 1), x,
|
||||
* - (x + ux + 1), x + ux, - (x + ux + 1), x + ux
|
||||
*
|
||||
* so the 16 bit weights end up like this:
|
||||
*
|
||||
* iw0, w0, iw0, w0, iw1, w1, iw1, w1
|
||||
*
|
||||
* and after shifting and packing, we get these bytes:
|
||||
*
|
||||
* iw0, w0, iw0, w0, iw1, w1, iw1, w1,
|
||||
* iw0, w0, iw0, w0, iw1, w1, iw1, w1,
|
||||
*
|
||||
* which means the first and the second input pixel
|
||||
* have to be interleaved like this:
|
||||
*
|
||||
* la0, ra0, lr0, rr0, la1, ra1, lr1, rr1,
|
||||
* lg0, rg0, lb0, rb0, lg1, rg1, lb1, rb1
|
||||
*
|
||||
* before maddubsw can be used.
|
||||
*/
|
||||
|
||||
vw = _mm_add_epi16 (
|
||||
vaddc, _mm_srli_epi16 (vx, 16 - BILINEAR_INTERPOLATION_BITS));
|
||||
/* vw: iw0, w0, iw0, w0, iw1, w1, iw1, w1
|
||||
*/
|
||||
|
||||
vw = _mm_packus_epi16 (vw, vw);
|
||||
/* vw: iw0, w0, iw0, w0, iw1, w1, iw1, w1,
|
||||
* iw0, w0, iw0, w0, iw1, w1, iw1, w1
|
||||
*/
|
||||
vx = _mm_add_epi16 (vx, vux);
|
||||
|
||||
x += 2 * ux;
|
||||
|
||||
vr = _mm_unpacklo_epi16 (vrl1, vrl0);
|
||||
/* vr: rar0, rar1, rgb0, rgb1, lar0, lar1, lgb0, lgb1 */
|
||||
|
||||
s = _mm_shuffle_epi32 (vr, _MM_SHUFFLE (1, 0, 3, 2));
|
||||
/* s: lar0, lar1, lgb0, lgb1, rar0, rar1, rgb0, rgb1 */
|
||||
|
||||
vr = _mm_unpackhi_epi8 (vr, s);
|
||||
/* vr: la0, ra0, lr0, rr0, la1, ra1, lr1, rr1,
|
||||
* lg0, rg0, lb0, rb0, lg1, rg1, lb1, rb1
|
||||
*/
|
||||
|
||||
vr = _mm_maddubs_epi16 (vr, vw);
|
||||
|
||||
/* When the weight is 0, the inverse weight is
|
||||
* 128 which can't be represented in a signed byte.
|
||||
* As a result maddubsw computes the following:
|
||||
*
|
||||
* r = l * -128 + r * 0
|
||||
*
|
||||
* rather than the desired
|
||||
*
|
||||
* r = l * 128 + r * 0
|
||||
*
|
||||
* We fix this by taking the absolute value of the
|
||||
* result.
|
||||
*/
|
||||
vr = _mm_abs_epi16 (vr);
|
||||
|
||||
/* vr: A0, R0, A1, R1, G0, B0, G1, B1 */
|
||||
_mm_store_si128 (b++, vr);
|
||||
}
|
||||
|
||||
if (n == -1)
|
||||
{
|
||||
vrl1 = _mm_setzero_si128();
|
||||
goto final_pixel;
|
||||
}
|
||||
|
||||
line->y = y;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
ssse3_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
pixman_fixed_t fx, ux;
|
||||
bilinear_info_t *info = iter->data;
|
||||
line_t *line0, *line1;
|
||||
int y0, y1;
|
||||
int32_t dist_y;
|
||||
__m128i vw;
|
||||
int i;
|
||||
|
||||
fx = info->x;
|
||||
ux = iter->image->common.transform->matrix[0][0];
|
||||
|
||||
y0 = pixman_fixed_to_int (info->y);
|
||||
y1 = y0 + 1;
|
||||
|
||||
line0 = &info->lines[y0 & 0x01];
|
||||
line1 = &info->lines[y1 & 0x01];
|
||||
|
||||
if (line0->y != y0)
|
||||
{
|
||||
ssse3_fetch_horizontal (
|
||||
&iter->image->bits, line0, y0, fx, ux, iter->width);
|
||||
}
|
||||
|
||||
if (line1->y != y1)
|
||||
{
|
||||
ssse3_fetch_horizontal (
|
||||
&iter->image->bits, line1, y1, fx, ux, iter->width);
|
||||
}
|
||||
|
||||
dist_y = pixman_fixed_to_bilinear_weight (info->y);
|
||||
dist_y <<= (16 - BILINEAR_INTERPOLATION_BITS);
|
||||
|
||||
vw = _mm_set_epi16 (
|
||||
dist_y, dist_y, dist_y, dist_y, dist_y, dist_y, dist_y, dist_y);
|
||||
|
||||
for (i = 0; i + 3 < iter->width; i += 4)
|
||||
{
|
||||
__m128i top0 = _mm_load_si128 ((__m128i *)(line0->buffer + i));
|
||||
__m128i bot0 = _mm_load_si128 ((__m128i *)(line1->buffer + i));
|
||||
__m128i top1 = _mm_load_si128 ((__m128i *)(line0->buffer + i + 2));
|
||||
__m128i bot1 = _mm_load_si128 ((__m128i *)(line1->buffer + i + 2));
|
||||
__m128i r0, r1, tmp, p;
|
||||
|
||||
r0 = _mm_mulhi_epu16 (
|
||||
_mm_sub_epi16 (bot0, top0), vw);
|
||||
tmp = _mm_cmplt_epi16 (bot0, top0);
|
||||
tmp = _mm_and_si128 (tmp, vw);
|
||||
r0 = _mm_sub_epi16 (r0, tmp);
|
||||
r0 = _mm_add_epi16 (r0, top0);
|
||||
r0 = _mm_srli_epi16 (r0, BILINEAR_INTERPOLATION_BITS);
|
||||
/* r0: A0 R0 A1 R1 G0 B0 G1 B1 */
|
||||
r0 = _mm_shuffle_epi32 (r0, _MM_SHUFFLE (2, 0, 3, 1));
|
||||
/* r0: A1 R1 G1 B1 A0 R0 G0 B0 */
|
||||
|
||||
r1 = _mm_mulhi_epu16 (
|
||||
_mm_sub_epi16 (bot1, top1), vw);
|
||||
tmp = _mm_cmplt_epi16 (bot1, top1);
|
||||
tmp = _mm_and_si128 (tmp, vw);
|
||||
r1 = _mm_sub_epi16 (r1, tmp);
|
||||
r1 = _mm_add_epi16 (r1, top1);
|
||||
r1 = _mm_srli_epi16 (r1, BILINEAR_INTERPOLATION_BITS);
|
||||
r1 = _mm_shuffle_epi32 (r1, _MM_SHUFFLE (2, 0, 3, 1));
|
||||
/* r1: A3 R3 G3 B3 A2 R2 G2 B2 */
|
||||
|
||||
p = _mm_packus_epi16 (r0, r1);
|
||||
|
||||
_mm_storeu_si128 ((__m128i *)(iter->buffer + i), p);
|
||||
}
|
||||
|
||||
while (i < iter->width)
|
||||
{
|
||||
__m128i top0 = _mm_load_si128 ((__m128i *)(line0->buffer + i));
|
||||
__m128i bot0 = _mm_load_si128 ((__m128i *)(line1->buffer + i));
|
||||
__m128i r0, tmp, p;
|
||||
|
||||
r0 = _mm_mulhi_epu16 (
|
||||
_mm_sub_epi16 (bot0, top0), vw);
|
||||
tmp = _mm_cmplt_epi16 (bot0, top0);
|
||||
tmp = _mm_and_si128 (tmp, vw);
|
||||
r0 = _mm_sub_epi16 (r0, tmp);
|
||||
r0 = _mm_add_epi16 (r0, top0);
|
||||
r0 = _mm_srli_epi16 (r0, BILINEAR_INTERPOLATION_BITS);
|
||||
/* r0: A0 R0 A1 R1 G0 B0 G1 B1 */
|
||||
r0 = _mm_shuffle_epi32 (r0, _MM_SHUFFLE (2, 0, 3, 1));
|
||||
/* r0: A1 R1 G1 B1 A0 R0 G0 B0 */
|
||||
|
||||
p = _mm_packus_epi16 (r0, r0);
|
||||
|
||||
if (iter->width - i == 1)
|
||||
{
|
||||
*(uint32_t *)(iter->buffer + i) = _mm_cvtsi128_si32 (p);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mm_storel_epi64 ((__m128i *)(iter->buffer + i), p);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
info->y += iter->image->common.transform->matrix[1][1];
|
||||
|
||||
return iter->buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
ssse3_bilinear_cover_iter_fini (pixman_iter_t *iter)
|
||||
{
|
||||
free (iter->data);
|
||||
}
|
||||
|
||||
static void
|
||||
ssse3_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info)
|
||||
{
|
||||
int width = iter->width;
|
||||
bilinear_info_t *info;
|
||||
pixman_vector_t v;
|
||||
|
||||
/* Reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (!pixman_transform_point_3d (iter->image->common.transform, &v))
|
||||
goto fail;
|
||||
|
||||
info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t) + 64);
|
||||
if (!info)
|
||||
goto fail;
|
||||
|
||||
info->x = v.vector[0] - pixman_fixed_1 / 2;
|
||||
info->y = v.vector[1] - pixman_fixed_1 / 2;
|
||||
|
||||
#define ALIGN(addr) \
|
||||
((void *)((((uintptr_t)(addr)) + 15) & (~15)))
|
||||
|
||||
/* It is safe to set the y coordinates to -1 initially
|
||||
* because COVER_CLIP_BILINEAR ensures that we will only
|
||||
* be asked to fetch lines in the [0, height) interval
|
||||
*/
|
||||
info->lines[0].y = -1;
|
||||
info->lines[0].buffer = ALIGN (&(info->data[0]));
|
||||
info->lines[1].y = -1;
|
||||
info->lines[1].buffer = ALIGN (info->lines[0].buffer + width);
|
||||
|
||||
iter->get_scanline = ssse3_fetch_bilinear_cover;
|
||||
iter->fini = ssse3_bilinear_cover_iter_fini;
|
||||
|
||||
iter->data = info;
|
||||
return;
|
||||
|
||||
fail:
|
||||
/* Something went wrong, either a bad matrix or OOM; in such cases,
|
||||
* we don't guarantee any particular rendering.
|
||||
*/
|
||||
_pixman_log_error (
|
||||
FUNC, "Allocation failure or bad matrix, skipping rendering\n");
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
iter->fini = NULL;
|
||||
}
|
||||
|
||||
static const pixman_iter_info_t ssse3_iters[] =
|
||||
{
|
||||
{ PIXMAN_a8r8g8b8,
|
||||
(FAST_PATH_STANDARD_FLAGS |
|
||||
FAST_PATH_SCALE_TRANSFORM |
|
||||
FAST_PATH_BILINEAR_FILTER |
|
||||
FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR),
|
||||
ITER_NARROW | ITER_SRC,
|
||||
ssse3_bilinear_cover_iter_init,
|
||||
NULL, NULL
|
||||
},
|
||||
|
||||
{ PIXMAN_null },
|
||||
};
|
||||
|
||||
static const pixman_fast_path_t ssse3_fast_paths[] =
|
||||
{
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_ssse3 (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, ssse3_fast_paths);
|
||||
|
||||
imp->iter_info = ssse3_iters;
|
||||
|
||||
return imp;
|
||||
}
|
66
vendor/pixman/pixman/pixman-timer.c
vendored
Normal file
66
vendor/pixman/pixman/pixman-timer.c
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef PIXMAN_TIMERS
|
||||
|
||||
static pixman_timer_t *timers;
|
||||
|
||||
static void
|
||||
dump_timers (void)
|
||||
{
|
||||
pixman_timer_t *timer;
|
||||
|
||||
for (timer = timers; timer != NULL; timer = timer->next)
|
||||
{
|
||||
printf ("%s: total: %llu n: %llu avg: %f\n",
|
||||
timer->name,
|
||||
timer->total,
|
||||
timer->n_times,
|
||||
timer->total / (double)timer->n_times);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pixman_timer_register (pixman_timer_t *timer)
|
||||
{
|
||||
static int initialized;
|
||||
|
||||
int atexit (void (*function)(void));
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
atexit (dump_timers);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
timer->next = timers;
|
||||
timers = timer;
|
||||
}
|
||||
|
||||
#endif
|
711
vendor/pixman/pixman/pixman-trap.c
vendored
Normal file
711
vendor/pixman/pixman/pixman-trap.c
vendored
Normal file
@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
/*
|
||||
* Compute the smallest value greater than or equal to y which is on a
|
||||
* grid row.
|
||||
*/
|
||||
|
||||
PIXMAN_EXPORT pixman_fixed_t
|
||||
pixman_sample_ceil_y (pixman_fixed_t y, int n)
|
||||
{
|
||||
pixman_fixed_t f = pixman_fixed_frac (y);
|
||||
pixman_fixed_t i = pixman_fixed_floor (y);
|
||||
|
||||
f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
|
||||
Y_FRAC_FIRST (n);
|
||||
|
||||
if (f > Y_FRAC_LAST (n))
|
||||
{
|
||||
if (pixman_fixed_to_int (i) == 0x7fff)
|
||||
{
|
||||
f = 0xffff; /* saturate */
|
||||
}
|
||||
else
|
||||
{
|
||||
f = Y_FRAC_FIRST (n);
|
||||
i += pixman_fixed_1;
|
||||
}
|
||||
}
|
||||
return (i | f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the largest value strictly less than y which is on a
|
||||
* grid row.
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_fixed_t
|
||||
pixman_sample_floor_y (pixman_fixed_t y,
|
||||
int n)
|
||||
{
|
||||
pixman_fixed_t f = pixman_fixed_frac (y);
|
||||
pixman_fixed_t i = pixman_fixed_floor (y);
|
||||
|
||||
f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
|
||||
Y_FRAC_FIRST (n);
|
||||
|
||||
if (f < Y_FRAC_FIRST (n))
|
||||
{
|
||||
if (pixman_fixed_to_int (i) == 0xffff8000)
|
||||
{
|
||||
f = 0; /* saturate */
|
||||
}
|
||||
else
|
||||
{
|
||||
f = Y_FRAC_LAST (n);
|
||||
i -= pixman_fixed_1;
|
||||
}
|
||||
}
|
||||
return (i | f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Step an edge by any amount (including negative values)
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_edge_step (pixman_edge_t *e,
|
||||
int n)
|
||||
{
|
||||
pixman_fixed_48_16_t ne;
|
||||
|
||||
e->x += n * e->stepx;
|
||||
|
||||
ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
if (ne > 0)
|
||||
{
|
||||
int nx = (ne + e->dy - 1) / e->dy;
|
||||
e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
|
||||
e->x += nx * e->signdx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ne <= -e->dy)
|
||||
{
|
||||
int nx = (-ne) / e->dy;
|
||||
e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
|
||||
e->x -= nx * e->signdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A private routine to initialize the multi-step
|
||||
* elements of an edge structure
|
||||
*/
|
||||
static void
|
||||
_pixman_edge_multi_init (pixman_edge_t * e,
|
||||
int n,
|
||||
pixman_fixed_t *stepx_p,
|
||||
pixman_fixed_t *dx_p)
|
||||
{
|
||||
pixman_fixed_t stepx;
|
||||
pixman_fixed_48_16_t ne;
|
||||
|
||||
ne = n * (pixman_fixed_48_16_t) e->dx;
|
||||
stepx = n * e->stepx;
|
||||
|
||||
if (ne > 0)
|
||||
{
|
||||
int nx = ne / e->dy;
|
||||
ne -= nx * (pixman_fixed_48_16_t)e->dy;
|
||||
stepx += nx * e->signdx;
|
||||
}
|
||||
|
||||
*dx_p = ne;
|
||||
*stepx_p = stepx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize one edge structure given the line endpoints and a
|
||||
* starting y value
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_edge_init (pixman_edge_t *e,
|
||||
int n,
|
||||
pixman_fixed_t y_start,
|
||||
pixman_fixed_t x_top,
|
||||
pixman_fixed_t y_top,
|
||||
pixman_fixed_t x_bot,
|
||||
pixman_fixed_t y_bot)
|
||||
{
|
||||
pixman_fixed_t dx, dy;
|
||||
|
||||
e->x = x_top;
|
||||
e->e = 0;
|
||||
dx = x_bot - x_top;
|
||||
dy = y_bot - y_top;
|
||||
e->dy = dy;
|
||||
e->dx = 0;
|
||||
|
||||
if (dy)
|
||||
{
|
||||
if (dx >= 0)
|
||||
{
|
||||
e->signdx = 1;
|
||||
e->stepx = dx / dy;
|
||||
e->dx = dx % dy;
|
||||
e->e = -dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->signdx = -1;
|
||||
e->stepx = -(-dx / dy);
|
||||
e->dx = -dx % dy;
|
||||
e->e = 0;
|
||||
}
|
||||
|
||||
_pixman_edge_multi_init (e, STEP_Y_SMALL (n),
|
||||
&e->stepx_small, &e->dx_small);
|
||||
|
||||
_pixman_edge_multi_init (e, STEP_Y_BIG (n),
|
||||
&e->stepx_big, &e->dx_big);
|
||||
}
|
||||
pixman_edge_step (e, y_start - y_top);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize one edge structure given a line, starting y value
|
||||
* and a pixel offset for the line
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_line_fixed_edge_init (pixman_edge_t * e,
|
||||
int n,
|
||||
pixman_fixed_t y,
|
||||
const pixman_line_fixed_t *line,
|
||||
int x_off,
|
||||
int y_off)
|
||||
{
|
||||
pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
|
||||
pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
const pixman_point_fixed_t *top, *bot;
|
||||
|
||||
if (line->p1.y <= line->p2.y)
|
||||
{
|
||||
top = &line->p1;
|
||||
bot = &line->p2;
|
||||
}
|
||||
else
|
||||
{
|
||||
top = &line->p2;
|
||||
bot = &line->p1;
|
||||
}
|
||||
|
||||
pixman_edge_init (e, n, y,
|
||||
top->x + x_off_fixed,
|
||||
top->y + y_off_fixed,
|
||||
bot->x + x_off_fixed,
|
||||
bot->y + y_off_fixed);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_add_traps (pixman_image_t * image,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
int ntrap,
|
||||
const pixman_trap_t *traps)
|
||||
{
|
||||
int bpp;
|
||||
int height;
|
||||
|
||||
pixman_fixed_t x_off_fixed;
|
||||
pixman_fixed_t y_off_fixed;
|
||||
pixman_edge_t l, r;
|
||||
pixman_fixed_t t, b;
|
||||
|
||||
_pixman_image_validate (image);
|
||||
|
||||
height = image->bits.height;
|
||||
bpp = PIXMAN_FORMAT_BPP (image->bits.format);
|
||||
|
||||
x_off_fixed = pixman_int_to_fixed (x_off);
|
||||
y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
|
||||
while (ntrap--)
|
||||
{
|
||||
t = traps->top.y + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = pixman_sample_ceil_y (t, bpp);
|
||||
|
||||
b = traps->bot.y + y_off_fixed;
|
||||
if (pixman_fixed_to_int (b) >= height)
|
||||
b = pixman_int_to_fixed (height) - 1;
|
||||
b = pixman_sample_floor_y (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
pixman_edge_init (&l, bpp, t,
|
||||
traps->top.l + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.l + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
pixman_edge_init (&r, bpp, t,
|
||||
traps->top.r + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.r + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
pixman_rasterize_edges (image, &l, &r, t, b);
|
||||
}
|
||||
|
||||
traps++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dump_image (pixman_image_t *image,
|
||||
const char * title)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!image->type == BITS)
|
||||
printf ("%s is not a regular image\n", title);
|
||||
|
||||
if (!image->bits.format == PIXMAN_a8)
|
||||
printf ("%s is not an alpha mask\n", title);
|
||||
|
||||
printf ("\n\n\n%s: \n", title);
|
||||
|
||||
for (i = 0; i < image->bits.height; ++i)
|
||||
{
|
||||
uint8_t *line =
|
||||
(uint8_t *)&(image->bits.bits[i * image->bits.rowstride]);
|
||||
|
||||
for (j = 0; j < image->bits.width; ++j)
|
||||
printf ("%c", line[j] ? '#' : ' ');
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_add_trapezoids (pixman_image_t * image,
|
||||
int16_t x_off,
|
||||
int y_off,
|
||||
int ntraps,
|
||||
const pixman_trapezoid_t *traps)
|
||||
{
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
dump_image (image, "before");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ntraps; ++i)
|
||||
{
|
||||
const pixman_trapezoid_t *trap = &(traps[i]);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
continue;
|
||||
|
||||
pixman_rasterize_trapezoid (image, trap, x_off, y_off);
|
||||
}
|
||||
|
||||
#if 0
|
||||
dump_image (image, "after");
|
||||
#endif
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_rasterize_trapezoid (pixman_image_t * image,
|
||||
const pixman_trapezoid_t *trap,
|
||||
int x_off,
|
||||
int y_off)
|
||||
{
|
||||
int bpp;
|
||||
int height;
|
||||
|
||||
pixman_fixed_t y_off_fixed;
|
||||
pixman_edge_t l, r;
|
||||
pixman_fixed_t t, b;
|
||||
|
||||
return_if_fail (image->type == BITS);
|
||||
|
||||
_pixman_image_validate (image);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
return;
|
||||
|
||||
height = image->bits.height;
|
||||
bpp = PIXMAN_FORMAT_BPP (image->bits.format);
|
||||
|
||||
y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
|
||||
t = trap->top + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = pixman_sample_ceil_y (t, bpp);
|
||||
|
||||
b = trap->bottom + y_off_fixed;
|
||||
if (pixman_fixed_to_int (b) >= height)
|
||||
b = pixman_int_to_fixed (height) - 1;
|
||||
b = pixman_sample_floor_y (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
|
||||
pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
|
||||
|
||||
pixman_rasterize_edges (image, &l, &r, t, b);
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
|
||||
{
|
||||
FALSE, /* Clear 0 0 */
|
||||
FALSE, /* Src 1 0 */
|
||||
TRUE, /* Dst 0 1 */
|
||||
TRUE, /* Over 1 1-Aa */
|
||||
TRUE, /* OverReverse 1-Ab 1 */
|
||||
FALSE, /* In Ab 0 */
|
||||
FALSE, /* InReverse 0 Aa */
|
||||
FALSE, /* Out 1-Ab 0 */
|
||||
TRUE, /* OutReverse 0 1-Aa */
|
||||
TRUE, /* Atop Ab 1-Aa */
|
||||
FALSE, /* AtopReverse 1-Ab Aa */
|
||||
TRUE, /* Xor 1-Ab 1-Aa */
|
||||
TRUE, /* Add 1 1 */
|
||||
};
|
||||
|
||||
static pixman_bool_t
|
||||
get_trap_extents (pixman_op_t op, pixman_image_t *dest,
|
||||
const pixman_trapezoid_t *traps, int n_traps,
|
||||
pixman_box32_t *box)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* When the operator is such that a zero source has an
|
||||
* effect on the underlying image, we have to
|
||||
* composite across the entire destination
|
||||
*/
|
||||
if (!zero_src_has_no_effect [op])
|
||||
{
|
||||
box->x1 = 0;
|
||||
box->y1 = 0;
|
||||
box->x2 = dest->bits.width;
|
||||
box->y2 = dest->bits.height;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
box->x1 = INT32_MAX;
|
||||
box->y1 = INT32_MAX;
|
||||
box->x2 = INT32_MIN;
|
||||
box->y2 = INT32_MIN;
|
||||
|
||||
for (i = 0; i < n_traps; ++i)
|
||||
{
|
||||
const pixman_trapezoid_t *trap = &(traps[i]);
|
||||
int y1, y2;
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
continue;
|
||||
|
||||
y1 = pixman_fixed_to_int (trap->top);
|
||||
if (y1 < box->y1)
|
||||
box->y1 = y1;
|
||||
|
||||
y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
|
||||
if (y2 > box->y2)
|
||||
box->y2 = y2;
|
||||
|
||||
#define EXTEND_MIN(x) \
|
||||
if (pixman_fixed_to_int ((x)) < box->x1) \
|
||||
box->x1 = pixman_fixed_to_int ((x));
|
||||
#define EXTEND_MAX(x) \
|
||||
if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2) \
|
||||
box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
|
||||
|
||||
#define EXTEND(x) \
|
||||
EXTEND_MIN(x); \
|
||||
EXTEND_MAX(x);
|
||||
|
||||
EXTEND(trap->left.p1.x);
|
||||
EXTEND(trap->left.p2.x);
|
||||
EXTEND(trap->right.p1.x);
|
||||
EXTEND(trap->right.p2.x);
|
||||
}
|
||||
|
||||
if (box->x1 >= box->x2 || box->y1 >= box->y2)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pixman_composite_trapezoids()
|
||||
*
|
||||
* All the trapezoids are conceptually rendered to an infinitely big image.
|
||||
* The (0, 0) coordinates of this image are then aligned with the (x, y)
|
||||
* coordinates of the source image, and then both images are aligned with
|
||||
* the (x, y) coordinates of the destination. Then these three images are
|
||||
* composited across the entire destination.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_trapezoids (pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * dst,
|
||||
pixman_format_code_t mask_format,
|
||||
int x_src,
|
||||
int y_src,
|
||||
int x_dst,
|
||||
int y_dst,
|
||||
int n_traps,
|
||||
const pixman_trapezoid_t * traps)
|
||||
{
|
||||
int i;
|
||||
|
||||
return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A);
|
||||
|
||||
if (n_traps <= 0)
|
||||
return;
|
||||
|
||||
_pixman_image_validate (src);
|
||||
_pixman_image_validate (dst);
|
||||
|
||||
if (op == PIXMAN_OP_ADD &&
|
||||
(src->common.flags & FAST_PATH_IS_OPAQUE) &&
|
||||
(mask_format == dst->common.extended_format_code) &&
|
||||
!(dst->common.have_clip_region))
|
||||
{
|
||||
for (i = 0; i < n_traps; ++i)
|
||||
{
|
||||
const pixman_trapezoid_t *trap = &(traps[i]);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
continue;
|
||||
|
||||
pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixman_image_t *tmp;
|
||||
pixman_box32_t box;
|
||||
int i;
|
||||
|
||||
if (!get_trap_extents (op, dst, traps, n_traps, &box))
|
||||
return;
|
||||
|
||||
if (!(tmp = pixman_image_create_bits (
|
||||
mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < n_traps; ++i)
|
||||
{
|
||||
const pixman_trapezoid_t *trap = &(traps[i]);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
continue;
|
||||
|
||||
pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
|
||||
}
|
||||
|
||||
pixman_image_composite (op, src, tmp, dst,
|
||||
x_src + box.x1, y_src + box.y1,
|
||||
0, 0,
|
||||
x_dst + box.x1, y_dst + box.y1,
|
||||
box.x2 - box.x1, box.y2 - box.y1);
|
||||
|
||||
pixman_image_unref (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
|
||||
{
|
||||
if (a->y == b->y)
|
||||
return a->x > b->x;
|
||||
return a->y > b->y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the definition of this function is a bit odd because
|
||||
* of the X coordinate space (y increasing downwards).
|
||||
*/
|
||||
static int
|
||||
clockwise (const pixman_point_fixed_t *ref,
|
||||
const pixman_point_fixed_t *a,
|
||||
const pixman_point_fixed_t *b)
|
||||
{
|
||||
pixman_point_fixed_t ad, bd;
|
||||
|
||||
ad.x = a->x - ref->x;
|
||||
ad.y = a->y - ref->y;
|
||||
bd.x = b->x - ref->x;
|
||||
bd.y = b->y - ref->y;
|
||||
|
||||
return ((pixman_fixed_32_32_t) bd.y * ad.x -
|
||||
(pixman_fixed_32_32_t) ad.y * bd.x) < 0;
|
||||
}
|
||||
|
||||
static void
|
||||
triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
|
||||
{
|
||||
const pixman_point_fixed_t *top, *left, *right, *tmp;
|
||||
|
||||
top = &tri->p1;
|
||||
left = &tri->p2;
|
||||
right = &tri->p3;
|
||||
|
||||
if (greater_y (top, left))
|
||||
{
|
||||
tmp = left;
|
||||
left = top;
|
||||
top = tmp;
|
||||
}
|
||||
|
||||
if (greater_y (top, right))
|
||||
{
|
||||
tmp = right;
|
||||
right = top;
|
||||
top = tmp;
|
||||
}
|
||||
|
||||
if (clockwise (top, right, left))
|
||||
{
|
||||
tmp = right;
|
||||
right = left;
|
||||
left = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two cases:
|
||||
*
|
||||
* + +
|
||||
* / \ / \
|
||||
* / \ / \
|
||||
* / + + \
|
||||
* / -- -- \
|
||||
* / -- -- \
|
||||
* / --- --- \
|
||||
* +-- --+
|
||||
*/
|
||||
|
||||
traps->top = top->y;
|
||||
traps->left.p1 = *top;
|
||||
traps->left.p2 = *left;
|
||||
traps->right.p1 = *top;
|
||||
traps->right.p2 = *right;
|
||||
|
||||
if (right->y < left->y)
|
||||
traps->bottom = right->y;
|
||||
else
|
||||
traps->bottom = left->y;
|
||||
|
||||
traps++;
|
||||
|
||||
*traps = *(traps - 1);
|
||||
|
||||
if (right->y < left->y)
|
||||
{
|
||||
traps->top = right->y;
|
||||
traps->bottom = left->y;
|
||||
traps->right.p1 = *right;
|
||||
traps->right.p2 = *left;
|
||||
}
|
||||
else
|
||||
{
|
||||
traps->top = left->y;
|
||||
traps->bottom = right->y;
|
||||
traps->left.p1 = *left;
|
||||
traps->left.p2 = *right;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_trapezoid_t *
|
||||
convert_triangles (int n_tris, const pixman_triangle_t *tris)
|
||||
{
|
||||
pixman_trapezoid_t *traps;
|
||||
int i;
|
||||
|
||||
if (n_tris <= 0)
|
||||
return NULL;
|
||||
|
||||
traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
|
||||
if (!traps)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < n_tris; ++i)
|
||||
triangle_to_trapezoids (&(tris[i]), traps + 2 * i);
|
||||
|
||||
return traps;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_triangles (pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * dst,
|
||||
pixman_format_code_t mask_format,
|
||||
int x_src,
|
||||
int y_src,
|
||||
int x_dst,
|
||||
int y_dst,
|
||||
int n_tris,
|
||||
const pixman_triangle_t * tris)
|
||||
{
|
||||
pixman_trapezoid_t *traps;
|
||||
|
||||
if ((traps = convert_triangles (n_tris, tris)))
|
||||
{
|
||||
pixman_composite_trapezoids (op, src, dst, mask_format,
|
||||
x_src, y_src, x_dst, y_dst,
|
||||
n_tris * 2, traps);
|
||||
|
||||
free (traps);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_add_triangles (pixman_image_t *image,
|
||||
int32_t x_off,
|
||||
int32_t y_off,
|
||||
int n_tris,
|
||||
const pixman_triangle_t *tris)
|
||||
{
|
||||
pixman_trapezoid_t *traps;
|
||||
|
||||
if ((traps = convert_triangles (n_tris, tris)))
|
||||
{
|
||||
pixman_add_trapezoids (image, x_off, y_off,
|
||||
n_tris * 2, traps);
|
||||
|
||||
free (traps);
|
||||
}
|
||||
}
|
330
vendor/pixman/pixman/pixman-utils.c
vendored
Normal file
330
vendor/pixman/pixman/pixman-utils.c
vendored
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 1999 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_multiply_overflows_size (size_t a, size_t b)
|
||||
{
|
||||
return a >= SIZE_MAX / b;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_multiply_overflows_int (unsigned int a, unsigned int b)
|
||||
{
|
||||
return a >= INT32_MAX / b;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_addition_overflows_int (unsigned int a, unsigned int b)
|
||||
{
|
||||
return a > INT32_MAX - b;
|
||||
}
|
||||
|
||||
void *
|
||||
pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c)
|
||||
{
|
||||
if (!b || a >= INT32_MAX / b || (a * b) > INT32_MAX - c)
|
||||
return NULL;
|
||||
|
||||
return malloc (a * b + c);
|
||||
}
|
||||
|
||||
void *
|
||||
pixman_malloc_ab (unsigned int a,
|
||||
unsigned int b)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
|
||||
return malloc (a * b);
|
||||
}
|
||||
|
||||
void *
|
||||
pixman_malloc_abc (unsigned int a,
|
||||
unsigned int b,
|
||||
unsigned int c)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
else if (a * b >= INT32_MAX / c)
|
||||
return NULL;
|
||||
else
|
||||
return malloc (a * b * c);
|
||||
}
|
||||
|
||||
static force_inline uint16_t
|
||||
float_to_unorm (float f, int n_bits)
|
||||
{
|
||||
uint32_t u;
|
||||
|
||||
if (f > 1.0)
|
||||
f = 1.0;
|
||||
if (f < 0.0)
|
||||
f = 0.0;
|
||||
|
||||
u = f * (1 << n_bits);
|
||||
u -= (u >> n_bits);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static force_inline float
|
||||
unorm_to_float (uint16_t u, int n_bits)
|
||||
{
|
||||
uint32_t m = ((1 << n_bits) - 1);
|
||||
|
||||
return (u & m) * (1.f / (float)m);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function expands images from a8r8g8b8 to argb_t. To preserve
|
||||
* precision, it needs to know from which source format the a8r8g8b8 pixels
|
||||
* originally came.
|
||||
*
|
||||
* For example, if the source was PIXMAN_x1r5g5b5 and the red component
|
||||
* contained bits 12345, then the 8-bit value is 12345123. To correctly
|
||||
* expand this to floating point, it should be 12345 / 31.0 and not
|
||||
* 12345123 / 255.0.
|
||||
*/
|
||||
void
|
||||
pixman_expand_to_float (argb_t *dst,
|
||||
const uint32_t *src,
|
||||
pixman_format_code_t format,
|
||||
int width)
|
||||
{
|
||||
static const float multipliers[16] = {
|
||||
0.0f,
|
||||
1.0f / ((1 << 1) - 1),
|
||||
1.0f / ((1 << 2) - 1),
|
||||
1.0f / ((1 << 3) - 1),
|
||||
1.0f / ((1 << 4) - 1),
|
||||
1.0f / ((1 << 5) - 1),
|
||||
1.0f / ((1 << 6) - 1),
|
||||
1.0f / ((1 << 7) - 1),
|
||||
1.0f / ((1 << 8) - 1),
|
||||
1.0f / ((1 << 9) - 1),
|
||||
1.0f / ((1 << 10) - 1),
|
||||
1.0f / ((1 << 11) - 1),
|
||||
1.0f / ((1 << 12) - 1),
|
||||
1.0f / ((1 << 13) - 1),
|
||||
1.0f / ((1 << 14) - 1),
|
||||
1.0f / ((1 << 15) - 1),
|
||||
};
|
||||
int a_size, r_size, g_size, b_size;
|
||||
int a_shift, r_shift, g_shift, b_shift;
|
||||
float a_mul, r_mul, g_mul, b_mul;
|
||||
uint32_t a_mask, r_mask, g_mask, b_mask;
|
||||
int i;
|
||||
|
||||
if (!PIXMAN_FORMAT_VIS (format))
|
||||
format = PIXMAN_a8r8g8b8;
|
||||
|
||||
/*
|
||||
* Determine the sizes of each component and the masks and shifts
|
||||
* required to extract them from the source pixel.
|
||||
*/
|
||||
a_size = PIXMAN_FORMAT_A (format);
|
||||
r_size = PIXMAN_FORMAT_R (format);
|
||||
g_size = PIXMAN_FORMAT_G (format);
|
||||
b_size = PIXMAN_FORMAT_B (format);
|
||||
|
||||
a_shift = 32 - a_size;
|
||||
r_shift = 24 - r_size;
|
||||
g_shift = 16 - g_size;
|
||||
b_shift = 8 - b_size;
|
||||
|
||||
a_mask = ((1 << a_size) - 1);
|
||||
r_mask = ((1 << r_size) - 1);
|
||||
g_mask = ((1 << g_size) - 1);
|
||||
b_mask = ((1 << b_size) - 1);
|
||||
|
||||
a_mul = multipliers[a_size];
|
||||
r_mul = multipliers[r_size];
|
||||
g_mul = multipliers[g_size];
|
||||
b_mul = multipliers[b_size];
|
||||
|
||||
/* Start at the end so that we can do the expansion in place
|
||||
* when src == dst
|
||||
*/
|
||||
for (i = width - 1; i >= 0; i--)
|
||||
{
|
||||
const uint32_t pixel = src[i];
|
||||
|
||||
dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f;
|
||||
dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul;
|
||||
dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul;
|
||||
dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
pixman_float_to_unorm (float f, int n_bits)
|
||||
{
|
||||
return float_to_unorm (f, n_bits);
|
||||
}
|
||||
|
||||
float
|
||||
pixman_unorm_to_float (uint16_t u, int n_bits)
|
||||
{
|
||||
return unorm_to_float (u, n_bits);
|
||||
}
|
||||
|
||||
void
|
||||
pixman_contract_from_float (uint32_t *dst,
|
||||
const argb_t *src,
|
||||
int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; ++i)
|
||||
{
|
||||
uint32_t a, r, g, b;
|
||||
|
||||
a = float_to_unorm (src[i].a, 8);
|
||||
r = float_to_unorm (src[i].r, 8);
|
||||
g = float_to_unorm (src[i].g, 8);
|
||||
b = float_to_unorm (src[i].b, 8);
|
||||
|
||||
dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t *
|
||||
_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return iter->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
uint8_t *b = (uint8_t *)image->bits.bits;
|
||||
int s = image->bits.rowstride * 4;
|
||||
|
||||
iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8;
|
||||
iter->stride = s;
|
||||
}
|
||||
|
||||
#define N_TMP_BOXES (16)
|
||||
|
||||
pixman_bool_t
|
||||
pixman_region16_copy_from_region32 (pixman_region16_t *dst,
|
||||
pixman_region32_t *src)
|
||||
{
|
||||
int n_boxes, i;
|
||||
pixman_box32_t *boxes32;
|
||||
pixman_box16_t *boxes16;
|
||||
pixman_bool_t retval;
|
||||
|
||||
boxes32 = pixman_region32_rectangles (src, &n_boxes);
|
||||
|
||||
boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
|
||||
|
||||
if (!boxes16)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_boxes; ++i)
|
||||
{
|
||||
boxes16[i].x1 = boxes32[i].x1;
|
||||
boxes16[i].y1 = boxes32[i].y1;
|
||||
boxes16[i].x2 = boxes32[i].x2;
|
||||
boxes16[i].y2 = boxes32[i].y2;
|
||||
}
|
||||
|
||||
pixman_region_fini (dst);
|
||||
retval = pixman_region_init_rects (dst, boxes16, n_boxes);
|
||||
free (boxes16);
|
||||
return retval;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_region32_copy_from_region16 (pixman_region32_t *dst,
|
||||
pixman_region16_t *src)
|
||||
{
|
||||
int n_boxes, i;
|
||||
pixman_box16_t *boxes16;
|
||||
pixman_box32_t *boxes32;
|
||||
pixman_box32_t tmp_boxes[N_TMP_BOXES];
|
||||
pixman_bool_t retval;
|
||||
|
||||
boxes16 = pixman_region_rectangles (src, &n_boxes);
|
||||
|
||||
if (n_boxes > N_TMP_BOXES)
|
||||
boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
|
||||
else
|
||||
boxes32 = tmp_boxes;
|
||||
|
||||
if (!boxes32)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_boxes; ++i)
|
||||
{
|
||||
boxes32[i].x1 = boxes16[i].x1;
|
||||
boxes32[i].y1 = boxes16[i].y1;
|
||||
boxes32[i].x2 = boxes16[i].x2;
|
||||
boxes32[i].y2 = boxes16[i].y2;
|
||||
}
|
||||
|
||||
pixman_region32_fini (dst);
|
||||
retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
|
||||
|
||||
if (boxes32 != tmp_boxes)
|
||||
free (boxes32);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* This function is exported for the sake of the test suite and not part
|
||||
* of the ABI.
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_implementation_t *
|
||||
_pixman_internal_only_get_implementation (void)
|
||||
{
|
||||
return get_implementation ();
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_log_error (const char *function, const char *message)
|
||||
{
|
||||
static int n_messages = 0;
|
||||
|
||||
if (n_messages < 10)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"*** BUG ***\n"
|
||||
"In %s: %s\n"
|
||||
"Set a breakpoint on '_pixman_log_error' to debug\n\n",
|
||||
function, message);
|
||||
|
||||
n_messages++;
|
||||
}
|
||||
}
|
54
vendor/pixman/pixman/pixman-version.h.in
vendored
Normal file
54
vendor/pixman/pixman/pixman-version.h.in
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_VERSION_H__
|
||||
#define PIXMAN_VERSION_H__
|
||||
|
||||
#ifndef PIXMAN_H__
|
||||
# error pixman-version.h should only be included by pixman.h
|
||||
#endif
|
||||
|
||||
#define PIXMAN_VERSION_MAJOR @PIXMAN_VERSION_MAJOR@
|
||||
#define PIXMAN_VERSION_MINOR @PIXMAN_VERSION_MINOR@
|
||||
#define PIXMAN_VERSION_MICRO @PIXMAN_VERSION_MICRO@
|
||||
|
||||
#define PIXMAN_VERSION_STRING "@PIXMAN_VERSION_MAJOR@.@PIXMAN_VERSION_MINOR@.@PIXMAN_VERSION_MICRO@"
|
||||
|
||||
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
|
||||
((major) * 10000) \
|
||||
+ ((minor) * 100) \
|
||||
+ ((micro) * 1))
|
||||
|
||||
#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \
|
||||
PIXMAN_VERSION_MAJOR, \
|
||||
PIXMAN_VERSION_MINOR, \
|
||||
PIXMAN_VERSION_MICRO)
|
||||
|
||||
#ifndef PIXMAN_API
|
||||
# define PIXMAN_API
|
||||
#endif
|
||||
|
||||
#endif /* PIXMAN_VERSION_H__ */
|
3159
vendor/pixman/pixman/pixman-vmx.c
vendored
Normal file
3159
vendor/pixman/pixman/pixman-vmx.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
249
vendor/pixman/pixman/pixman-x86.c
vendored
Normal file
249
vendor/pixman/pixman/pixman-x86.c
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#if defined(USE_X86_MMX) || defined (USE_SSE2) || defined (USE_SSSE3)
|
||||
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
|
||||
* that would lead to SIGILL instructions on old CPUs that don't have
|
||||
* it.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
X86_MMX = (1 << 0),
|
||||
X86_MMX_EXTENSIONS = (1 << 1),
|
||||
X86_SSE = (1 << 2) | X86_MMX_EXTENSIONS,
|
||||
X86_SSE2 = (1 << 3),
|
||||
X86_CMOV = (1 << 4),
|
||||
X86_SSSE3 = (1 << 5)
|
||||
} cpu_features_t;
|
||||
|
||||
#ifdef HAVE_GETISAX
|
||||
|
||||
#include <sys/auxv.h>
|
||||
|
||||
static cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
cpu_features_t features = 0;
|
||||
unsigned int result = 0;
|
||||
|
||||
if (getisax (&result, 1))
|
||||
{
|
||||
if (result & AV_386_CMOV)
|
||||
features |= X86_CMOV;
|
||||
if (result & AV_386_MMX)
|
||||
features |= X86_MMX;
|
||||
if (result & AV_386_AMD_MMX)
|
||||
features |= X86_MMX_EXTENSIONS;
|
||||
if (result & AV_386_SSE)
|
||||
features |= X86_SSE;
|
||||
if (result & AV_386_SSE2)
|
||||
features |= X86_SSE2;
|
||||
if (result & AV_386_SSSE3)
|
||||
features |= X86_SSSE3;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define _PIXMAN_X86_64 \
|
||||
(defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64))
|
||||
|
||||
static pixman_bool_t
|
||||
have_cpuid (void)
|
||||
{
|
||||
#if _PIXMAN_X86_64 || defined (_MSC_VER)
|
||||
|
||||
return TRUE;
|
||||
|
||||
#elif defined (__GNUC__)
|
||||
uint32_t result;
|
||||
|
||||
__asm__ volatile (
|
||||
"pushf" "\n\t"
|
||||
"pop %%eax" "\n\t"
|
||||
"mov %%eax, %%ecx" "\n\t"
|
||||
"xor $0x00200000, %%eax" "\n\t"
|
||||
"push %%eax" "\n\t"
|
||||
"popf" "\n\t"
|
||||
"pushf" "\n\t"
|
||||
"pop %%eax" "\n\t"
|
||||
"xor %%ecx, %%eax" "\n\t"
|
||||
"mov %%eax, %0" "\n\t"
|
||||
: "=r" (result)
|
||||
:
|
||||
: "%eax", "%ecx");
|
||||
|
||||
return !!result;
|
||||
|
||||
#else
|
||||
#error "Unknown compiler"
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
pixman_cpuid (uint32_t feature,
|
||||
uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
|
||||
{
|
||||
#if defined (__GNUC__)
|
||||
|
||||
#if _PIXMAN_X86_64
|
||||
__asm__ volatile (
|
||||
"cpuid" "\n\t"
|
||||
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
|
||||
: "a" (feature));
|
||||
#else
|
||||
/* On x86-32 we need to be careful about the handling of %ebx
|
||||
* and %esp. We can't declare either one as clobbered
|
||||
* since they are special registers (%ebx is the "PIC
|
||||
* register" holding an offset to global data, %esp the
|
||||
* stack pointer), so we need to make sure that %ebx is
|
||||
* preserved, and that %esp has its original value when
|
||||
* accessing the output operands.
|
||||
*/
|
||||
__asm__ volatile (
|
||||
"xchg %%ebx, %1" "\n\t"
|
||||
"cpuid" "\n\t"
|
||||
"xchg %%ebx, %1" "\n\t"
|
||||
: "=a" (*a), "=r" (*b), "=c" (*c), "=d" (*d)
|
||||
: "a" (feature));
|
||||
#endif
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
int info[4];
|
||||
|
||||
__cpuid (info, feature);
|
||||
|
||||
*a = info[0];
|
||||
*b = info[1];
|
||||
*c = info[2];
|
||||
*d = info[3];
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
}
|
||||
|
||||
static cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
uint32_t a, b, c, d;
|
||||
cpu_features_t features = 0;
|
||||
|
||||
if (!have_cpuid())
|
||||
return features;
|
||||
|
||||
/* Get feature bits */
|
||||
pixman_cpuid (0x01, &a, &b, &c, &d);
|
||||
if (d & (1 << 15))
|
||||
features |= X86_CMOV;
|
||||
if (d & (1 << 23))
|
||||
features |= X86_MMX;
|
||||
if (d & (1 << 25))
|
||||
features |= X86_SSE;
|
||||
if (d & (1 << 26))
|
||||
features |= X86_SSE2;
|
||||
if (c & (1 << 9))
|
||||
features |= X86_SSSE3;
|
||||
|
||||
/* Check for AMD specific features */
|
||||
if ((features & X86_MMX) && !(features & X86_SSE))
|
||||
{
|
||||
char vendor[13];
|
||||
|
||||
/* Get vendor string */
|
||||
memset (vendor, 0, sizeof vendor);
|
||||
|
||||
pixman_cpuid (0x00, &a, &b, &c, &d);
|
||||
memcpy (vendor + 0, &b, 4);
|
||||
memcpy (vendor + 4, &d, 4);
|
||||
memcpy (vendor + 8, &c, 4);
|
||||
|
||||
if (strcmp (vendor, "AuthenticAMD") == 0 ||
|
||||
strcmp (vendor, "HygonGenuine") == 0 ||
|
||||
strcmp (vendor, "Geode by NSC") == 0)
|
||||
{
|
||||
pixman_cpuid (0x80000000, &a, &b, &c, &d);
|
||||
if (a >= 0x80000001)
|
||||
{
|
||||
pixman_cpuid (0x80000001, &a, &b, &c, &d);
|
||||
|
||||
if (d & (1 << 22))
|
||||
features |= X86_MMX_EXTENSIONS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static pixman_bool_t
|
||||
have_feature (cpu_features_t feature)
|
||||
{
|
||||
static pixman_bool_t initialized;
|
||||
static cpu_features_t features;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
features = detect_cpu_features();
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return (features & feature) == feature;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_x86_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#define MMX_BITS (X86_MMX | X86_MMX_EXTENSIONS)
|
||||
#define SSE2_BITS (X86_MMX | X86_MMX_EXTENSIONS | X86_SSE | X86_SSE2)
|
||||
#define SSSE3_BITS (X86_SSE | X86_SSE2 | X86_SSSE3)
|
||||
|
||||
#ifdef USE_X86_MMX
|
||||
if (!_pixman_disabled ("mmx") && have_feature (MMX_BITS))
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSE2
|
||||
if (!_pixman_disabled ("sse2") && have_feature (SSE2_BITS))
|
||||
imp = _pixman_implementation_create_sse2 (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSSE3
|
||||
if (!_pixman_disabled ("ssse3") && have_feature (SSSE3_BITS))
|
||||
imp = _pixman_implementation_create_ssse3 (imp);
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
1134
vendor/pixman/pixman/pixman.c
vendored
Normal file
1134
vendor/pixman/pixman/pixman.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1426
vendor/pixman/pixman/pixman.h
vendored
Normal file
1426
vendor/pixman/pixman/pixman.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
168
vendor/pixman/pixman/rounding.txt
vendored
Normal file
168
vendor/pixman/pixman/rounding.txt
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
*** General notes about rounding
|
||||
|
||||
Suppose a function is sampled at positions [k + o] where k is an
|
||||
integer and o is a fractional offset 0 <= o < 1.
|
||||
|
||||
To round a value to the nearest sample, breaking ties by rounding up,
|
||||
we can do this:
|
||||
|
||||
round(x) = floor(x - o + 0.5) + o
|
||||
|
||||
That is, first subtract o to let us pretend that the samples are at
|
||||
integer coordinates, then add 0.5 and floor to round to nearest
|
||||
integer, then add the offset back in.
|
||||
|
||||
To break ties by rounding down:
|
||||
|
||||
round(x) = ceil(x - o - 0.5) + o
|
||||
|
||||
or if we have an epsilon value:
|
||||
|
||||
round(x) = floor(x - o + 0.5 - e) + o
|
||||
|
||||
To always round *up* to the next sample:
|
||||
|
||||
round_up(x) = ceil(x - o) + o
|
||||
|
||||
To always round *down* to the previous sample:
|
||||
|
||||
round_down(x) = floor(x - o) + o
|
||||
|
||||
If a set of samples is stored in an array, you get from the sample
|
||||
position to an index by subtracting the position of the first sample
|
||||
in the array:
|
||||
|
||||
index(s) = s - first_sample
|
||||
|
||||
|
||||
*** Application to pixman
|
||||
|
||||
In pixman, images are sampled with o = 0.5, that is, pixels are
|
||||
located midways between integers. We usually break ties by rounding
|
||||
down (i.e., "round towards north-west").
|
||||
|
||||
|
||||
-- NEAREST filtering:
|
||||
|
||||
The NEAREST filter simply picks the closest pixel to the given
|
||||
position:
|
||||
|
||||
round(x) = floor(x - 0.5 + 0.5 - e) + 0.5 = floor (x - e) + 0.5
|
||||
|
||||
The first sample of a pixman image has position 0.5, so to find the
|
||||
index in the pixel array, we have to subtract 0.5:
|
||||
|
||||
floor (x - e) + 0.5 - 0.5 = floor (x - e).
|
||||
|
||||
Therefore a 16.16 fixed-point image location is turned into a pixel
|
||||
value with NEAREST filtering by doing this:
|
||||
|
||||
pixels[((y - e) >> 16) * stride + ((x - e) >> 16)]
|
||||
|
||||
where stride is the number of pixels allocated per scanline and e =
|
||||
0x0001.
|
||||
|
||||
|
||||
-- CONVOLUTION filtering:
|
||||
|
||||
A convolution matrix is considered a sampling of a function f at
|
||||
values surrounding 0. For example, this convolution matrix:
|
||||
|
||||
[a, b, c, d]
|
||||
|
||||
is interpreted as the values of a function f:
|
||||
|
||||
a = f(-1.5)
|
||||
b = f(-0.5)
|
||||
c = f(0.5)
|
||||
d = f(1.5)
|
||||
|
||||
The sample offset in this case is o = 0.5 and the first sample has
|
||||
position s0 = -1.5. If the matrix is:
|
||||
|
||||
[a, b, c, d, e]
|
||||
|
||||
the sample offset is o = 0 and the first sample has position s0 =
|
||||
-2.0. In general we have
|
||||
|
||||
s0 = (- width / 2.0 + 0.5).
|
||||
|
||||
and
|
||||
|
||||
o = frac (s0)
|
||||
|
||||
To evaluate f at a position between the samples, we round to the
|
||||
closest sample, and then we subtract the position of the first sample
|
||||
to get the index in the matrix:
|
||||
|
||||
f(t) = matrix[floor(t - o + 0.5) + o - s0]
|
||||
|
||||
Note that in this case we break ties by rounding up.
|
||||
|
||||
If we write s0 = m + o, where m is an integer, this is equivalent to
|
||||
|
||||
f(t) = matrix[floor(t - o + 0.5) + o - (m + o)]
|
||||
= matrix[floor(t - o + 0.5 - m) + o - o]
|
||||
= matrix[floor(t - s0 + 0.5)]
|
||||
|
||||
The convolution filter in pixman positions f such that 0 aligns with
|
||||
the given position x. For a given pixel x0 in the image, the closest
|
||||
sample of f is then computed by taking (x - x0) and rounding that to
|
||||
the closest index:
|
||||
|
||||
i = floor ((x0 - x) - s0 + 0.5)
|
||||
|
||||
To perform the convolution, we have to find the first pixel x0 whose
|
||||
corresponding sample has index 0. We can write x0 = k + 0.5, where k
|
||||
is an integer:
|
||||
|
||||
0 = floor(k + 0.5 - x - s0 + 0.5)
|
||||
|
||||
= k + floor(1 - x - s0)
|
||||
|
||||
= k - ceil(x + s0 - 1)
|
||||
|
||||
= k - floor(x + s0 - e)
|
||||
|
||||
= k - floor(x - (width - 1) / 2.0 - e)
|
||||
|
||||
And so the final formula for the index k of x0 in the image is:
|
||||
|
||||
k = floor(x - (width - 1) / 2.0 - e)
|
||||
|
||||
Computing the result is then simply a matter of convolving all the
|
||||
pixels starting at k with all the samples in the matrix.
|
||||
|
||||
|
||||
--- SEPARABLE_CONVOLUTION
|
||||
|
||||
For this filter, x is first rounded to one of n regularly spaced
|
||||
subpixel positions. This subpixel position determines which of n
|
||||
convolution matrices is being used.
|
||||
|
||||
Then, as in a regular convolution filter, the first pixel to be used
|
||||
is determined:
|
||||
|
||||
k = floor (x - (width - 1) / 2.0 - e)
|
||||
|
||||
and then the image pixels starting there are convolved with the chosen
|
||||
matrix. If we write x = xi + frac, where xi is an integer, we get
|
||||
|
||||
k = xi + floor (frac - (width - 1) / 2.0 - e)
|
||||
|
||||
so the location of k relative to x is given by:
|
||||
|
||||
(k + 0.5 - x) = xi + floor (frac - (width - 1) / 2.0 - e) + 0.5 - x
|
||||
|
||||
= floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
|
||||
|
||||
which means the contents of the matrix corresponding to (frac) should
|
||||
contain width samplings of the function, with the first sample at:
|
||||
|
||||
floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
|
||||
= ceil (frac - width / 2.0 - 0.5) + 0.5 - frac
|
||||
|
||||
This filter is called separable because each of the k x k convolution
|
||||
matrices is specified with two k-wide vectors, one for each dimension,
|
||||
where each entry in the matrix is computed as the product of the
|
||||
corresponding entries in the vectors.
|
30
vendor/pixman/pixman/solaris-hwcap.mapfile
vendored
Normal file
30
vendor/pixman/pixman/solaris-hwcap.mapfile
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, 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 (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Override the linker's detection of CMOV/MMX/SSE instructions so this
|
||||
# library isn't flagged as only usable on CPU's with those ISA's, since it
|
||||
# checks at runtime for availability before calling them
|
||||
|
||||
hwcap_1 = V0x0 FPU OVERRIDE;
|
Reference in New Issue
Block a user