gfx/cairo/libpixman/src/pixman-implementation.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/libpixman/src/pixman-implementation.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,397 @@
     1.4 +/*
     1.5 + * Copyright © 2009 Red Hat, Inc.
     1.6 + *
     1.7 + * Permission to use, copy, modify, distribute, and sell this software and its
     1.8 + * documentation for any purpose is hereby granted without fee, provided that
     1.9 + * the above copyright notice appear in all copies and that both that
    1.10 + * copyright notice and this permission notice appear in supporting
    1.11 + * documentation, and that the name of Red Hat not be used in advertising or
    1.12 + * publicity pertaining to distribution of the software without specific,
    1.13 + * written prior permission.  Red Hat makes no representations about the
    1.14 + * suitability of this software for any purpose.  It is provided "as is"
    1.15 + * without express or implied warranty.
    1.16 + *
    1.17 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    1.18 + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    1.19 + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.20 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    1.21 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    1.22 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
    1.23 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    1.24 + * SOFTWARE.
    1.25 + */
    1.26 +
    1.27 +#ifdef HAVE_CONFIG_H
    1.28 +#include <config.h>
    1.29 +#endif
    1.30 +#include <stdlib.h>
    1.31 +#include "pixman-private.h"
    1.32 +
    1.33 +pixman_implementation_t *
    1.34 +_pixman_implementation_create (pixman_implementation_t *fallback,
    1.35 +			       const pixman_fast_path_t *fast_paths)
    1.36 +{
    1.37 +    pixman_implementation_t *imp;
    1.38 +
    1.39 +    assert (fast_paths);
    1.40 +
    1.41 +    if ((imp = malloc (sizeof (pixman_implementation_t))))
    1.42 +    {
    1.43 +	pixman_implementation_t *d;
    1.44 +
    1.45 +	memset (imp, 0, sizeof *imp);
    1.46 +
    1.47 +	imp->fallback = fallback;
    1.48 +	imp->fast_paths = fast_paths;
    1.49 +	
    1.50 +	/* Make sure the whole fallback chain has the right toplevel */
    1.51 +	for (d = imp; d != NULL; d = d->fallback)
    1.52 +	    d->toplevel = imp;
    1.53 +    }
    1.54 +
    1.55 +    return imp;
    1.56 +}
    1.57 +
    1.58 +#define N_CACHED_FAST_PATHS 8
    1.59 +
    1.60 +typedef struct
    1.61 +{
    1.62 +    struct
    1.63 +    {
    1.64 +	pixman_implementation_t *	imp;
    1.65 +	pixman_fast_path_t		fast_path;
    1.66 +    } cache [N_CACHED_FAST_PATHS];
    1.67 +} cache_t;
    1.68 +
    1.69 +PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
    1.70 +
    1.71 +static void
    1.72 +dummy_composite_rect (pixman_implementation_t *imp,
    1.73 +		      pixman_composite_info_t *info)
    1.74 +{
    1.75 +}
    1.76 +
    1.77 +void
    1.78 +_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
    1.79 +					 pixman_op_t               op,
    1.80 +					 pixman_format_code_t      src_format,
    1.81 +					 uint32_t                  src_flags,
    1.82 +					 pixman_format_code_t      mask_format,
    1.83 +					 uint32_t                  mask_flags,
    1.84 +					 pixman_format_code_t      dest_format,
    1.85 +					 uint32_t                  dest_flags,
    1.86 +					 pixman_implementation_t **out_imp,
    1.87 +					 pixman_composite_func_t  *out_func)
    1.88 +{
    1.89 +    pixman_implementation_t *imp;
    1.90 +    cache_t *cache;
    1.91 +    int i;
    1.92 +
    1.93 +    /* Check cache for fast paths */
    1.94 +    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
    1.95 +
    1.96 +    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
    1.97 +    {
    1.98 +	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
    1.99 +
   1.100 +	/* Note that we check for equality here, not whether
   1.101 +	 * the cached fast path matches. This is to prevent
   1.102 +	 * us from selecting an overly general fast path
   1.103 +	 * when a more specific one would work.
   1.104 +	 */
   1.105 +	if (info->op == op			&&
   1.106 +	    info->src_format == src_format	&&
   1.107 +	    info->mask_format == mask_format	&&
   1.108 +	    info->dest_format == dest_format	&&
   1.109 +	    info->src_flags == src_flags	&&
   1.110 +	    info->mask_flags == mask_flags	&&
   1.111 +	    info->dest_flags == dest_flags	&&
   1.112 +	    info->func)
   1.113 +	{
   1.114 +	    *out_imp = cache->cache[i].imp;
   1.115 +	    *out_func = cache->cache[i].fast_path.func;
   1.116 +
   1.117 +	    goto update_cache;
   1.118 +	}
   1.119 +    }
   1.120 +
   1.121 +    for (imp = toplevel; imp != NULL; imp = imp->fallback)
   1.122 +    {
   1.123 +	const pixman_fast_path_t *info = imp->fast_paths;
   1.124 +
   1.125 +	while (info->op != PIXMAN_OP_NONE)
   1.126 +	{
   1.127 +	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
   1.128 +		/* Formats */
   1.129 +		((info->src_format == src_format) ||
   1.130 +		 (info->src_format == PIXMAN_any))			&&
   1.131 +		((info->mask_format == mask_format) ||
   1.132 +		 (info->mask_format == PIXMAN_any))			&&
   1.133 +		((info->dest_format == dest_format) ||
   1.134 +		 (info->dest_format == PIXMAN_any))			&&
   1.135 +		/* Flags */
   1.136 +		(info->src_flags & src_flags) == info->src_flags	&&
   1.137 +		(info->mask_flags & mask_flags) == info->mask_flags	&&
   1.138 +		(info->dest_flags & dest_flags) == info->dest_flags)
   1.139 +	    {
   1.140 +		*out_imp = imp;
   1.141 +		*out_func = info->func;
   1.142 +
   1.143 +		/* Set i to the last spot in the cache so that the
   1.144 +		 * move-to-front code below will work
   1.145 +		 */
   1.146 +		i = N_CACHED_FAST_PATHS - 1;
   1.147 +
   1.148 +		goto update_cache;
   1.149 +	    }
   1.150 +
   1.151 +	    ++info;
   1.152 +	}
   1.153 +    }
   1.154 +
   1.155 +    /* We should never reach this point */
   1.156 +    _pixman_log_error (FUNC, "No known composite function\n");
   1.157 +    *out_imp = NULL;
   1.158 +    *out_func = dummy_composite_rect;
   1.159 +
   1.160 +update_cache:
   1.161 +    if (i)
   1.162 +    {
   1.163 +	while (i--)
   1.164 +	    cache->cache[i + 1] = cache->cache[i];
   1.165 +
   1.166 +	cache->cache[0].imp = *out_imp;
   1.167 +	cache->cache[0].fast_path.op = op;
   1.168 +	cache->cache[0].fast_path.src_format = src_format;
   1.169 +	cache->cache[0].fast_path.src_flags = src_flags;
   1.170 +	cache->cache[0].fast_path.mask_format = mask_format;
   1.171 +	cache->cache[0].fast_path.mask_flags = mask_flags;
   1.172 +	cache->cache[0].fast_path.dest_format = dest_format;
   1.173 +	cache->cache[0].fast_path.dest_flags = dest_flags;
   1.174 +	cache->cache[0].fast_path.func = *out_func;
   1.175 +    }
   1.176 +}
   1.177 +
   1.178 +static void
   1.179 +dummy_combine (pixman_implementation_t *imp,
   1.180 +	       pixman_op_t              op,
   1.181 +	       uint32_t *               pd,
   1.182 +	       const uint32_t *         ps,
   1.183 +	       const uint32_t *         pm,
   1.184 +	       int                      w)
   1.185 +{
   1.186 +}
   1.187 +
   1.188 +pixman_combine_32_func_t
   1.189 +_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
   1.190 +					pixman_op_t		 op,
   1.191 +					pixman_bool_t		 component_alpha,
   1.192 +					pixman_bool_t		 narrow,
   1.193 +					pixman_bool_t		 rgb16)
   1.194 +{
   1.195 +    while (imp)
   1.196 +    {
   1.197 +	pixman_combine_32_func_t f = NULL;
   1.198 +
   1.199 +	switch ((narrow << 1) | component_alpha)
   1.200 +	{
   1.201 +	case 0: /* not narrow, not component alpha */
   1.202 +	    f = (pixman_combine_32_func_t)imp->combine_float[op];
   1.203 +	    break;
   1.204 +	    
   1.205 +	case 1: /* not narrow, component_alpha */
   1.206 +	    f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
   1.207 +	    break;
   1.208 +
   1.209 +	case 2: /* narrow, not component alpha */
   1.210 +	    f = imp->combine_32[op];
   1.211 +	    break;
   1.212 +
   1.213 +	case 3: /* narrow, component_alpha */
   1.214 +	    f = imp->combine_32_ca[op];
   1.215 +	    break;
   1.216 +	}
   1.217 +	if (rgb16)
   1.218 +	    f = (pixman_combine_32_func_t *)imp->combine_16[op];
   1.219 +
   1.220 +	if (f)
   1.221 +	    return f;
   1.222 +
   1.223 +	imp = imp->fallback;
   1.224 +    }
   1.225 +
   1.226 +    /* We should never reach this point */
   1.227 +    _pixman_log_error (FUNC, "No known combine function\n");
   1.228 +    return dummy_combine;
   1.229 +}
   1.230 +
   1.231 +pixman_bool_t
   1.232 +_pixman_implementation_blt (pixman_implementation_t * imp,
   1.233 +                            uint32_t *                src_bits,
   1.234 +                            uint32_t *                dst_bits,
   1.235 +                            int                       src_stride,
   1.236 +                            int                       dst_stride,
   1.237 +                            int                       src_bpp,
   1.238 +                            int                       dst_bpp,
   1.239 +                            int                       src_x,
   1.240 +                            int                       src_y,
   1.241 +                            int                       dest_x,
   1.242 +                            int                       dest_y,
   1.243 +                            int                       width,
   1.244 +                            int                       height)
   1.245 +{
   1.246 +    while (imp)
   1.247 +    {
   1.248 +	if (imp->blt &&
   1.249 +	    (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
   1.250 +			 src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
   1.251 +			 width, height))
   1.252 +	{
   1.253 +	    return TRUE;
   1.254 +	}
   1.255 +
   1.256 +	imp = imp->fallback;
   1.257 +    }
   1.258 +
   1.259 +    return FALSE;
   1.260 +}
   1.261 +
   1.262 +pixman_bool_t
   1.263 +_pixman_implementation_fill (pixman_implementation_t *imp,
   1.264 +                             uint32_t *               bits,
   1.265 +                             int                      stride,
   1.266 +                             int                      bpp,
   1.267 +                             int                      x,
   1.268 +                             int                      y,
   1.269 +                             int                      width,
   1.270 +                             int                      height,
   1.271 +                             uint32_t                 filler)
   1.272 +{
   1.273 +    while (imp)
   1.274 +    {
   1.275 +	if (imp->fill &&
   1.276 +	    ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
   1.277 +	{
   1.278 +	    return TRUE;
   1.279 +	}
   1.280 +
   1.281 +	imp = imp->fallback;
   1.282 +    }
   1.283 +
   1.284 +    return FALSE;
   1.285 +}
   1.286 +
   1.287 +pixman_bool_t
   1.288 +_pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
   1.289 +				      pixman_iter_t             *iter,
   1.290 +				      pixman_image_t		*image,
   1.291 +				      int			 x,
   1.292 +				      int			 y,
   1.293 +				      int			 width,
   1.294 +				      int			 height,
   1.295 +				      uint8_t			*buffer,
   1.296 +				      iter_flags_t		 iter_flags,
   1.297 +				      uint32_t                   image_flags)
   1.298 +{
   1.299 +    iter->image = image;
   1.300 +    iter->buffer = (uint32_t *)buffer;
   1.301 +    iter->x = x;
   1.302 +    iter->y = y;
   1.303 +    iter->width = width;
   1.304 +    iter->height = height;
   1.305 +    iter->iter_flags = iter_flags;
   1.306 +    iter->image_flags = image_flags;
   1.307 +
   1.308 +    while (imp)
   1.309 +    {
   1.310 +	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
   1.311 +	    return TRUE;
   1.312 +
   1.313 +	imp = imp->fallback;
   1.314 +    }
   1.315 +
   1.316 +    return FALSE;
   1.317 +}
   1.318 +
   1.319 +pixman_bool_t
   1.320 +_pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
   1.321 +				       pixman_iter_t            *iter,
   1.322 +				       pixman_image_t		*image,
   1.323 +				       int			 x,
   1.324 +				       int			 y,
   1.325 +				       int			 width,
   1.326 +				       int			 height,
   1.327 +				       uint8_t			*buffer,
   1.328 +				       iter_flags_t		 iter_flags,
   1.329 +				       uint32_t                  image_flags)
   1.330 +{
   1.331 +    iter->image = image;
   1.332 +    iter->buffer = (uint32_t *)buffer;
   1.333 +    iter->x = x;
   1.334 +    iter->y = y;
   1.335 +    iter->width = width;
   1.336 +    iter->height = height;
   1.337 +    iter->iter_flags = iter_flags;
   1.338 +    iter->image_flags = image_flags;
   1.339 +
   1.340 +    while (imp)
   1.341 +    {
   1.342 +	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
   1.343 +	    return TRUE;
   1.344 +
   1.345 +	imp = imp->fallback;
   1.346 +    }
   1.347 +
   1.348 +    return FALSE;
   1.349 +}
   1.350 +
   1.351 +pixman_bool_t
   1.352 +_pixman_disabled (const char *name)
   1.353 +{
   1.354 +    const char *env;
   1.355 +
   1.356 +    if ((env = getenv ("PIXMAN_DISABLE")))
   1.357 +    {
   1.358 +	do
   1.359 +	{
   1.360 +	    const char *end;
   1.361 +	    int len;
   1.362 +
   1.363 +	    if ((end = strchr (env, ' ')))
   1.364 +		len = end - env;
   1.365 +	    else
   1.366 +		len = strlen (env);
   1.367 +
   1.368 +	    if (strlen (name) == len && strncmp (name, env, len) == 0)
   1.369 +	    {
   1.370 +		printf ("pixman: Disabled %s implementation\n", name);
   1.371 +		return TRUE;
   1.372 +	    }
   1.373 +
   1.374 +	    env += len;
   1.375 +	}
   1.376 +	while (*env++);
   1.377 +    }
   1.378 +
   1.379 +    return FALSE;
   1.380 +}
   1.381 +
   1.382 +pixman_implementation_t *
   1.383 +_pixman_choose_implementation (void)
   1.384 +{
   1.385 +    pixman_implementation_t *imp;
   1.386 +
   1.387 +    imp = _pixman_implementation_create_general();
   1.388 +
   1.389 +    if (!_pixman_disabled ("fast"))
   1.390 +	imp = _pixman_implementation_create_fast_path (imp);
   1.391 +
   1.392 +    imp = _pixman_x86_get_implementations (imp);
   1.393 +    imp = _pixman_arm_get_implementations (imp);
   1.394 +    imp = _pixman_ppc_get_implementations (imp);
   1.395 +    imp = _pixman_mips_get_implementations (imp);
   1.396 +
   1.397 +    imp = _pixman_implementation_create_noop (imp);
   1.398 +
   1.399 +    return imp;
   1.400 +}

mercurial