11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2009 Red Hat, Inc.
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Permission to use, copy, modify, distribute, and sell this software and its
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation for any purpose is hereby granted without fee, provided that
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the above copyright notice appear in all copies and that both that
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copyright notice and this permission notice appear in supporting
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation, and that the name of Red Hat not be used in advertising or
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * publicity pertaining to distribution of the software without specific,
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * written prior permission.  Red Hat makes no representations about the
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * suitability of this software for any purpose.  It is provided "as is"
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * without express or implied warranty.
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SOFTWARE.
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef HAVE_CONFIG_H
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <config.h>
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h>
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-private.h"
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_implementation_t *
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_create (pixman_implementation_t *fallback,
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			       const pixman_fast_path_t *fast_paths)
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_implementation_t *imp;
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    assert (fast_paths);
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if ((imp = malloc (sizeof (pixman_implementation_t))))
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_implementation_t *d;
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	memset (imp, 0, sizeof *imp);
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp->fallback = fallback;
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp->fast_paths = fast_paths;
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* Make sure the whole fallback chain has the right toplevel */
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (d = imp; d != NULL; d = d->fallback)
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    d->toplevel = imp;
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return imp;
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define N_CACHED_FAST_PATHS 8
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
571176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_implementation_t *	imp;
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_fast_path_t		fast_path;
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    } cache [N_CACHED_FAST_PATHS];
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} cache_t;
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
661176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdummy_composite_rect (pixman_implementation_t *imp,
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		      pixman_composite_info_t *info)
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_op_t               op,
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_format_code_t      src_format,
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 uint32_t                  src_flags,
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_format_code_t      mask_format,
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 uint32_t                  mask_flags,
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_format_code_t      dest_format,
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 uint32_t                  dest_flags,
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_implementation_t **out_imp,
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 pixman_composite_func_t  *out_func)
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_implementation_t *imp;
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    cache_t *cache;
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int i;
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* Check cache for fast paths */
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* Note that we check for equality here, not whether
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * the cached fast path matches. This is to prevent
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * us from selecting an overly general fast path
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 * when a more specific one would work.
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	 */
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (info->op == op			&&
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->src_format == src_format	&&
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->mask_format == mask_format	&&
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->dest_format == dest_format	&&
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->src_flags == src_flags	&&
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->mask_flags == mask_flags	&&
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->dest_flags == dest_flags	&&
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    info->func)
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    *out_imp = cache->cache[i].imp;
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    *out_func = cache->cache[i].fast_path.func;
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    goto update_cache;
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (imp = toplevel; imp != NULL; imp = imp->fallback)
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	const pixman_fast_path_t *info = imp->fast_paths;
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	while (info->op != PIXMAN_OP_NONE)
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* Formats */
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		((info->src_format == src_format) ||
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 (info->src_format == PIXMAN_any))			&&
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		((info->mask_format == mask_format) ||
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 (info->mask_format == PIXMAN_any))			&&
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		((info->dest_format == dest_format) ||
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 (info->dest_format == PIXMAN_any))			&&
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* Flags */
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		(info->src_flags & src_flags) == info->src_flags	&&
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		(info->mask_flags & mask_flags) == info->mask_flags	&&
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		(info->dest_flags & dest_flags) == info->dest_flags)
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		*out_imp = imp;
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		*out_func = info->func;
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		/* Set i to the last spot in the cache so that the
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 * move-to-front code below will work
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		 */
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		i = N_CACHED_FAST_PATHS - 1;
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		goto update_cache;
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ++info;
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* We should never reach this point */
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_log_error (
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        FUNC,
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        "No composite function found\n"
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        "\n"
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        "The most likely cause of this is that this system has issues with\n"
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        "thread local storage\n");
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    *out_imp = NULL;
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    *out_func = dummy_composite_rect;
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return;
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reckupdate_cache:
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (i)
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	while (i--)
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    cache->cache[i + 1] = cache->cache[i];
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].imp = *out_imp;
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.op = op;
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.src_format = src_format;
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.src_flags = src_flags;
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.mask_format = mask_format;
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.mask_flags = mask_flags;
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.dest_format = dest_format;
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.dest_flags = dest_flags;
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	cache->cache[0].fast_path.func = *out_func;
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdummy_combine (pixman_implementation_t *imp,
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	       pixman_op_t              op,
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	       uint32_t *               pd,
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	       const uint32_t *         ps,
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	       const uint32_t *         pm,
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	       int                      w)
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_combine_32_func_t
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					pixman_op_t		 op,
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					pixman_bool_t		 component_alpha,
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					pixman_bool_t		 narrow)
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (imp)
1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_combine_32_func_t f = NULL;
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	switch ((narrow << 1) | component_alpha)
2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 0: /* not narrow, not component alpha */
2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    f = (pixman_combine_32_func_t)imp->combine_float[op];
2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 1: /* not narrow, component_alpha */
2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 2: /* narrow, not component alpha */
2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    f = imp->combine_32[op];
2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 3: /* narrow, component_alpha */
2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    f = imp->combine_32_ca[op];
2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (f)
2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return f;
2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = imp->fallback;
2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    /* We should never reach this point */
2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    _pixman_log_error (FUNC, "No known combine function\n");
2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return dummy_combine;
2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_blt (pixman_implementation_t * imp,
2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            uint32_t *                src_bits,
2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            uint32_t *                dst_bits,
2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       src_stride,
2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       dst_stride,
2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       src_bpp,
2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       dst_bpp,
2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       src_x,
2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       src_y,
2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       dest_x,
2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       dest_y,
2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       width,
2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            int                       height)
2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (imp)
2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (imp->blt &&
2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			 width, height))
2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return TRUE;
2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = imp->fallback;
2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_fill (pixman_implementation_t *imp,
2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             uint32_t *               bits,
2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      stride,
2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      bpp,
2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      x,
2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      y,
2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      width,
2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             int                      height,
2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             uint32_t                 filler)
2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (imp)
2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (imp->fill &&
2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return TRUE;
2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = imp->fallback;
2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      pixman_iter_t             *iter,
2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      pixman_image_t		*image,
2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      int			 x,
2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      int			 y,
2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      int			 width,
2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      int			 height,
2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      uint8_t			*buffer,
2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      iter_flags_t		 iter_flags,
2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      uint32_t                   image_flags)
2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->image = image;
3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->buffer = (uint32_t *)buffer;
3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->x = x;
3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->y = y;
3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->width = width;
3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->height = height;
3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->iter_flags = iter_flags;
3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->image_flags = image_flags;
3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (imp)
3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return TRUE;
3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = imp->fallback;
3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       pixman_iter_t            *iter,
3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       pixman_image_t		*image,
3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       int			 x,
3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       int			 y,
3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       int			 width,
3271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       int			 height,
3281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       uint8_t			*buffer,
3291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       iter_flags_t		 iter_flags,
3301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				       uint32_t                  image_flags)
3311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->image = image;
3331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->buffer = (uint32_t *)buffer;
3341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->x = x;
3351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->y = y;
3361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->width = width;
3371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->height = height;
3381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->iter_flags = iter_flags;
3391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    iter->image_flags = image_flags;
3401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    while (imp)
3421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
3441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    return TRUE;
3451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = imp->fallback;
3471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
3501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3521176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t
3531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_disabled (const char *name)
3541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    const char *env;
3561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if ((env = getenv ("PIXMAN_DISABLE")))
3581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
3591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	do
3601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
3611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    const char *end;
3621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    int len;
3631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if ((end = strchr (env, ' ')))
3651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		len = end - env;
3661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    else
3671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		len = strlen (env);
3681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (strlen (name) == len && strncmp (name, env, len) == 0)
3701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
3711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		printf ("pixman: Disabled %s implementation\n", name);
3721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		return TRUE;
3731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
3741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    env += len;
3761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
3771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	while (*env++);
3781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
3791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return FALSE;
3811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3831176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_implementation_t *
3841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_choose_implementation (void)
3851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_implementation_t *imp;
3871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_implementation_create_general();
3891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!_pixman_disabled ("fast"))
3911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	imp = _pixman_implementation_create_fast_path (imp);
3921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_x86_get_implementations (imp);
3941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_arm_get_implementations (imp);
3951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_ppc_get_implementations (imp);
3961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_mips_get_implementations (imp);
3971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    imp = _pixman_implementation_create_noop (imp);
3991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
4001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return imp;
4011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
402