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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/libpixman/src/pixman-general.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,243 @@
     1.4 +/*
     1.5 + * Copyright © 2009 Red Hat, Inc.
     1.6 + * Copyright © 2000 SuSE, Inc.
     1.7 + * Copyright © 2007 Red Hat, Inc.
     1.8 + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
     1.9 + *             2005 Lars Knoll & Zack Rusin, Trolltech
    1.10 + *             2008 Aaron Plattner, NVIDIA Corporation
    1.11 + *
    1.12 + * Permission to use, copy, modify, distribute, and sell this software and its
    1.13 + * documentation for any purpose is hereby granted without fee, provided that
    1.14 + * the above copyright notice appear in all copies and that both that
    1.15 + * copyright notice and this permission notice appear in supporting
    1.16 + * documentation, and that the name of Red Hat not be used in advertising or
    1.17 + * publicity pertaining to distribution of the software without specific,
    1.18 + * written prior permission.  Red Hat makes no representations about the
    1.19 + * suitability of this software for any purpose.  It is provided "as is"
    1.20 + * without express or implied warranty.
    1.21 + *
    1.22 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    1.23 + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    1.24 + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.25 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    1.26 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    1.27 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
    1.28 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    1.29 + * SOFTWARE.
    1.30 + */
    1.31 +#ifdef HAVE_CONFIG_H
    1.32 +#include <config.h>
    1.33 +#endif
    1.34 +#include <stdlib.h>
    1.35 +#include <string.h>
    1.36 +#include <math.h>
    1.37 +#include <limits.h>
    1.38 +#include <stdio.h>
    1.39 +#include <stdlib.h>
    1.40 +#include <string.h>
    1.41 +#include "pixman-private.h"
    1.42 +
    1.43 +static pixman_bool_t
    1.44 +general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
    1.45 +{
    1.46 +    pixman_image_t *image = iter->image;
    1.47 +
    1.48 +    if (image->type == LINEAR)
    1.49 +	_pixman_linear_gradient_iter_init (image, iter);
    1.50 +    else if (image->type == RADIAL)
    1.51 +	_pixman_radial_gradient_iter_init (image, iter);
    1.52 +    else if (image->type == CONICAL)
    1.53 +	_pixman_conical_gradient_iter_init (image, iter);
    1.54 +    else if (image->type == BITS)
    1.55 +	_pixman_bits_image_src_iter_init (image, iter);
    1.56 +    else if (image->type == SOLID)
    1.57 +        _pixman_log_error (FUNC, "Solid image not handled by noop");
    1.58 +    else         
    1.59 +	_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
    1.60 +
    1.61 +    return TRUE;
    1.62 +}
    1.63 +
    1.64 +static pixman_bool_t
    1.65 +general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
    1.66 +{
    1.67 +    if (iter->image->type == BITS)
    1.68 +    {
    1.69 +	_pixman_bits_image_dest_iter_init (iter->image, iter);
    1.70 +
    1.71 +	return TRUE;
    1.72 +    }
    1.73 +    else
    1.74 +    {
    1.75 +	_pixman_log_error (FUNC, "Trying to write to a non-writable image");
    1.76 +
    1.77 +	return FALSE;
    1.78 +    }
    1.79 +}
    1.80 +
    1.81 +typedef struct op_info_t op_info_t;
    1.82 +struct op_info_t
    1.83 +{
    1.84 +    uint8_t src, dst;
    1.85 +};
    1.86 +
    1.87 +#define ITER_IGNORE_BOTH						\
    1.88 +    (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
    1.89 +
    1.90 +static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
    1.91 +{
    1.92 +    /* Src                   Dst                   */
    1.93 +    { ITER_IGNORE_BOTH,      ITER_IGNORE_BOTH      }, /* CLEAR */
    1.94 +    { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_BOTH      }, /* SRC */
    1.95 +    { ITER_IGNORE_BOTH,      ITER_LOCALIZED_ALPHA  }, /* DST */
    1.96 +    { 0,                     ITER_LOCALIZED_ALPHA  }, /* OVER */
    1.97 +    { ITER_LOCALIZED_ALPHA,  0                     }, /* OVER_REVERSE */
    1.98 +    { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* IN */
    1.99 +    { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* IN_REVERSE */
   1.100 +    { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* OUT */
   1.101 +    { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* OUT_REVERSE */
   1.102 +    { 0,                     0                     }, /* ATOP */
   1.103 +    { 0,                     0                     }, /* ATOP_REVERSE */
   1.104 +    { 0,                     0                     }, /* XOR */
   1.105 +    { ITER_LOCALIZED_ALPHA,  ITER_LOCALIZED_ALPHA  }, /* ADD */
   1.106 +    { 0,                     0                     }, /* SATURATE */
   1.107 +};
   1.108 +
   1.109 +#define SCANLINE_BUFFER_LENGTH 8192
   1.110 +
   1.111 +static void
   1.112 +general_composite_rect  (pixman_implementation_t *imp,
   1.113 +                         pixman_composite_info_t *info)
   1.114 +{
   1.115 +    PIXMAN_COMPOSITE_ARGS (info);
   1.116 +    uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
   1.117 +    uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
   1.118 +    uint8_t *src_buffer, *mask_buffer, *dest_buffer;
   1.119 +    pixman_iter_t src_iter, mask_iter, dest_iter;
   1.120 +    pixman_combine_32_func_t compose;
   1.121 +    pixman_bool_t component_alpha;
   1.122 +    iter_flags_t narrow, src_iter_flags;
   1.123 +    iter_flags_t rgb16;
   1.124 +    int Bpp;
   1.125 +    int i;
   1.126 +
   1.127 +    if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT)		    &&
   1.128 +	(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
   1.129 +	(dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
   1.130 +    {
   1.131 +	narrow = ITER_NARROW;
   1.132 +	Bpp = 4;
   1.133 +    }
   1.134 +    else
   1.135 +    {
   1.136 +	narrow = 0;
   1.137 +	Bpp = 16;
   1.138 +    }
   1.139 +
   1.140 +    // XXX: This special casing is bad. Ideally, we'd keep the general code general perhaps
   1.141 +    // by having it deal more specifically with different intermediate formats
   1.142 +    if (
   1.143 +	(dest_image->common.flags & FAST_PATH_16_FORMAT && (src_image->type == LINEAR || src_image->type == RADIAL)) &&
   1.144 +	( op == PIXMAN_OP_SRC ||
   1.145 +         (op == PIXMAN_OP_OVER && (src_image->common.flags & FAST_PATH_IS_OPAQUE))
   1.146 +	)
   1.147 +	) {
   1.148 +	rgb16 = ITER_16;
   1.149 +    } else {
   1.150 +	rgb16 = 0;
   1.151 +    }
   1.152 +
   1.153 +
   1.154 +    if (width * Bpp > SCANLINE_BUFFER_LENGTH)
   1.155 +    {
   1.156 +	scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
   1.157 +
   1.158 +	if (!scanline_buffer)
   1.159 +	    return;
   1.160 +    }
   1.161 +
   1.162 +    src_buffer = scanline_buffer;
   1.163 +    mask_buffer = src_buffer + width * Bpp;
   1.164 +    dest_buffer = mask_buffer + width * Bpp;
   1.165 +
   1.166 +    if (!narrow)
   1.167 +    {
   1.168 +	/* To make sure there aren't any NANs in the buffers */
   1.169 +	memset (src_buffer, 0, width * Bpp);
   1.170 +	memset (mask_buffer, 0, width * Bpp);
   1.171 +	memset (dest_buffer, 0, width * Bpp);
   1.172 +    }
   1.173 +    
   1.174 +    /* src iter */
   1.175 +    src_iter_flags = narrow | op_flags[op].src | rgb16;
   1.176 +
   1.177 +    _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
   1.178 +					  src_x, src_y, width, height,
   1.179 +					  src_buffer, src_iter_flags, info->src_flags);
   1.180 +
   1.181 +    /* mask iter */
   1.182 +    if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
   1.183 +	(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
   1.184 +    {
   1.185 +	/* If it doesn't matter what the source is, then it doesn't matter
   1.186 +	 * what the mask is
   1.187 +	 */
   1.188 +	mask_image = NULL;
   1.189 +    }
   1.190 +
   1.191 +    component_alpha =
   1.192 +        mask_image			      &&
   1.193 +        mask_image->common.type == BITS       &&
   1.194 +        mask_image->common.component_alpha    &&
   1.195 +        PIXMAN_FORMAT_RGB (mask_image->bits.format);
   1.196 +
   1.197 +    _pixman_implementation_src_iter_init (
   1.198 +	imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
   1.199 +	mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB), info->mask_flags);
   1.200 +
   1.201 +    /* dest iter */
   1.202 +    _pixman_implementation_dest_iter_init (
   1.203 +	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
   1.204 +	dest_buffer, narrow | op_flags[op].dst | rgb16, info->dest_flags);
   1.205 +
   1.206 +    compose = _pixman_implementation_lookup_combiner (
   1.207 +	imp->toplevel, op, component_alpha, narrow, !!rgb16);
   1.208 +
   1.209 +    for (i = 0; i < height; ++i)
   1.210 +    {
   1.211 +	uint32_t *s, *m, *d;
   1.212 +
   1.213 +	m = mask_iter.get_scanline (&mask_iter, NULL);
   1.214 +	s = src_iter.get_scanline (&src_iter, m);
   1.215 +	d = dest_iter.get_scanline (&dest_iter, NULL);
   1.216 +
   1.217 +	compose (imp->toplevel, op, d, s, m, width);
   1.218 +
   1.219 +	dest_iter.write_back (&dest_iter);
   1.220 +    }
   1.221 +
   1.222 +    if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
   1.223 +	free (scanline_buffer);
   1.224 +}
   1.225 +
   1.226 +static const pixman_fast_path_t general_fast_path[] =
   1.227 +{
   1.228 +    { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any,	0, PIXMAN_any, 0, general_composite_rect },
   1.229 +    { PIXMAN_OP_NONE }
   1.230 +};
   1.231 +
   1.232 +pixman_implementation_t *
   1.233 +_pixman_implementation_create_general (void)
   1.234 +{
   1.235 +    pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
   1.236 +
   1.237 +    _pixman_setup_combiner_functions_16 (imp);
   1.238 +    _pixman_setup_combiner_functions_32 (imp);
   1.239 +    _pixman_setup_combiner_functions_float (imp);
   1.240 +
   1.241 +    imp->src_iter_init = general_src_iter_init;
   1.242 +    imp->dest_iter_init = general_dest_iter_init;
   1.243 +
   1.244 +    return imp;
   1.245 +}
   1.246 +

mercurial