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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * Copyright © 2009 Red Hat, Inc.
     3  *
     4  * Permission to use, copy, modify, distribute, and sell this software and its
     5  * documentation for any purpose is hereby granted without fee, provided that
     6  * the above copyright notice appear in all copies and that both that
     7  * copyright notice and this permission notice appear in supporting
     8  * documentation, and that the name of Red Hat not be used in advertising or
     9  * publicity pertaining to distribution of the software without specific,
    10  * written prior permission.  Red Hat makes no representations about the
    11  * suitability of this software for any purpose.  It is provided "as is"
    12  * without express or implied warranty.
    13  *
    14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    19  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
    20  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    21  * SOFTWARE.
    22  */
    24 #ifdef HAVE_CONFIG_H
    25 #include <config.h>
    26 #endif
    27 #include <stdlib.h>
    28 #include "pixman-private.h"
    30 pixman_implementation_t *
    31 _pixman_implementation_create (pixman_implementation_t *fallback,
    32 			       const pixman_fast_path_t *fast_paths)
    33 {
    34     pixman_implementation_t *imp;
    36     assert (fast_paths);
    38     if ((imp = malloc (sizeof (pixman_implementation_t))))
    39     {
    40 	pixman_implementation_t *d;
    42 	memset (imp, 0, sizeof *imp);
    44 	imp->fallback = fallback;
    45 	imp->fast_paths = fast_paths;
    47 	/* Make sure the whole fallback chain has the right toplevel */
    48 	for (d = imp; d != NULL; d = d->fallback)
    49 	    d->toplevel = imp;
    50     }
    52     return imp;
    53 }
    55 #define N_CACHED_FAST_PATHS 8
    57 typedef struct
    58 {
    59     struct
    60     {
    61 	pixman_implementation_t *	imp;
    62 	pixman_fast_path_t		fast_path;
    63     } cache [N_CACHED_FAST_PATHS];
    64 } cache_t;
    66 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
    68 static void
    69 dummy_composite_rect (pixman_implementation_t *imp,
    70 		      pixman_composite_info_t *info)
    71 {
    72 }
    74 void
    75 _pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
    76 					 pixman_op_t               op,
    77 					 pixman_format_code_t      src_format,
    78 					 uint32_t                  src_flags,
    79 					 pixman_format_code_t      mask_format,
    80 					 uint32_t                  mask_flags,
    81 					 pixman_format_code_t      dest_format,
    82 					 uint32_t                  dest_flags,
    83 					 pixman_implementation_t **out_imp,
    84 					 pixman_composite_func_t  *out_func)
    85 {
    86     pixman_implementation_t *imp;
    87     cache_t *cache;
    88     int i;
    90     /* Check cache for fast paths */
    91     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
    93     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
    94     {
    95 	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
    97 	/* Note that we check for equality here, not whether
    98 	 * the cached fast path matches. This is to prevent
    99 	 * us from selecting an overly general fast path
   100 	 * when a more specific one would work.
   101 	 */
   102 	if (info->op == op			&&
   103 	    info->src_format == src_format	&&
   104 	    info->mask_format == mask_format	&&
   105 	    info->dest_format == dest_format	&&
   106 	    info->src_flags == src_flags	&&
   107 	    info->mask_flags == mask_flags	&&
   108 	    info->dest_flags == dest_flags	&&
   109 	    info->func)
   110 	{
   111 	    *out_imp = cache->cache[i].imp;
   112 	    *out_func = cache->cache[i].fast_path.func;
   114 	    goto update_cache;
   115 	}
   116     }
   118     for (imp = toplevel; imp != NULL; imp = imp->fallback)
   119     {
   120 	const pixman_fast_path_t *info = imp->fast_paths;
   122 	while (info->op != PIXMAN_OP_NONE)
   123 	{
   124 	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
   125 		/* Formats */
   126 		((info->src_format == src_format) ||
   127 		 (info->src_format == PIXMAN_any))			&&
   128 		((info->mask_format == mask_format) ||
   129 		 (info->mask_format == PIXMAN_any))			&&
   130 		((info->dest_format == dest_format) ||
   131 		 (info->dest_format == PIXMAN_any))			&&
   132 		/* Flags */
   133 		(info->src_flags & src_flags) == info->src_flags	&&
   134 		(info->mask_flags & mask_flags) == info->mask_flags	&&
   135 		(info->dest_flags & dest_flags) == info->dest_flags)
   136 	    {
   137 		*out_imp = imp;
   138 		*out_func = info->func;
   140 		/* Set i to the last spot in the cache so that the
   141 		 * move-to-front code below will work
   142 		 */
   143 		i = N_CACHED_FAST_PATHS - 1;
   145 		goto update_cache;
   146 	    }
   148 	    ++info;
   149 	}
   150     }
   152     /* We should never reach this point */
   153     _pixman_log_error (FUNC, "No known composite function\n");
   154     *out_imp = NULL;
   155     *out_func = dummy_composite_rect;
   157 update_cache:
   158     if (i)
   159     {
   160 	while (i--)
   161 	    cache->cache[i + 1] = cache->cache[i];
   163 	cache->cache[0].imp = *out_imp;
   164 	cache->cache[0].fast_path.op = op;
   165 	cache->cache[0].fast_path.src_format = src_format;
   166 	cache->cache[0].fast_path.src_flags = src_flags;
   167 	cache->cache[0].fast_path.mask_format = mask_format;
   168 	cache->cache[0].fast_path.mask_flags = mask_flags;
   169 	cache->cache[0].fast_path.dest_format = dest_format;
   170 	cache->cache[0].fast_path.dest_flags = dest_flags;
   171 	cache->cache[0].fast_path.func = *out_func;
   172     }
   173 }
   175 static void
   176 dummy_combine (pixman_implementation_t *imp,
   177 	       pixman_op_t              op,
   178 	       uint32_t *               pd,
   179 	       const uint32_t *         ps,
   180 	       const uint32_t *         pm,
   181 	       int                      w)
   182 {
   183 }
   185 pixman_combine_32_func_t
   186 _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
   187 					pixman_op_t		 op,
   188 					pixman_bool_t		 component_alpha,
   189 					pixman_bool_t		 narrow,
   190 					pixman_bool_t		 rgb16)
   191 {
   192     while (imp)
   193     {
   194 	pixman_combine_32_func_t f = NULL;
   196 	switch ((narrow << 1) | component_alpha)
   197 	{
   198 	case 0: /* not narrow, not component alpha */
   199 	    f = (pixman_combine_32_func_t)imp->combine_float[op];
   200 	    break;
   202 	case 1: /* not narrow, component_alpha */
   203 	    f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
   204 	    break;
   206 	case 2: /* narrow, not component alpha */
   207 	    f = imp->combine_32[op];
   208 	    break;
   210 	case 3: /* narrow, component_alpha */
   211 	    f = imp->combine_32_ca[op];
   212 	    break;
   213 	}
   214 	if (rgb16)
   215 	    f = (pixman_combine_32_func_t *)imp->combine_16[op];
   217 	if (f)
   218 	    return f;
   220 	imp = imp->fallback;
   221     }
   223     /* We should never reach this point */
   224     _pixman_log_error (FUNC, "No known combine function\n");
   225     return dummy_combine;
   226 }
   228 pixman_bool_t
   229 _pixman_implementation_blt (pixman_implementation_t * imp,
   230                             uint32_t *                src_bits,
   231                             uint32_t *                dst_bits,
   232                             int                       src_stride,
   233                             int                       dst_stride,
   234                             int                       src_bpp,
   235                             int                       dst_bpp,
   236                             int                       src_x,
   237                             int                       src_y,
   238                             int                       dest_x,
   239                             int                       dest_y,
   240                             int                       width,
   241                             int                       height)
   242 {
   243     while (imp)
   244     {
   245 	if (imp->blt &&
   246 	    (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
   247 			 src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
   248 			 width, height))
   249 	{
   250 	    return TRUE;
   251 	}
   253 	imp = imp->fallback;
   254     }
   256     return FALSE;
   257 }
   259 pixman_bool_t
   260 _pixman_implementation_fill (pixman_implementation_t *imp,
   261                              uint32_t *               bits,
   262                              int                      stride,
   263                              int                      bpp,
   264                              int                      x,
   265                              int                      y,
   266                              int                      width,
   267                              int                      height,
   268                              uint32_t                 filler)
   269 {
   270     while (imp)
   271     {
   272 	if (imp->fill &&
   273 	    ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
   274 	{
   275 	    return TRUE;
   276 	}
   278 	imp = imp->fallback;
   279     }
   281     return FALSE;
   282 }
   284 pixman_bool_t
   285 _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
   286 				      pixman_iter_t             *iter,
   287 				      pixman_image_t		*image,
   288 				      int			 x,
   289 				      int			 y,
   290 				      int			 width,
   291 				      int			 height,
   292 				      uint8_t			*buffer,
   293 				      iter_flags_t		 iter_flags,
   294 				      uint32_t                   image_flags)
   295 {
   296     iter->image = image;
   297     iter->buffer = (uint32_t *)buffer;
   298     iter->x = x;
   299     iter->y = y;
   300     iter->width = width;
   301     iter->height = height;
   302     iter->iter_flags = iter_flags;
   303     iter->image_flags = image_flags;
   305     while (imp)
   306     {
   307 	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
   308 	    return TRUE;
   310 	imp = imp->fallback;
   311     }
   313     return FALSE;
   314 }
   316 pixman_bool_t
   317 _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
   318 				       pixman_iter_t            *iter,
   319 				       pixman_image_t		*image,
   320 				       int			 x,
   321 				       int			 y,
   322 				       int			 width,
   323 				       int			 height,
   324 				       uint8_t			*buffer,
   325 				       iter_flags_t		 iter_flags,
   326 				       uint32_t                  image_flags)
   327 {
   328     iter->image = image;
   329     iter->buffer = (uint32_t *)buffer;
   330     iter->x = x;
   331     iter->y = y;
   332     iter->width = width;
   333     iter->height = height;
   334     iter->iter_flags = iter_flags;
   335     iter->image_flags = image_flags;
   337     while (imp)
   338     {
   339 	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
   340 	    return TRUE;
   342 	imp = imp->fallback;
   343     }
   345     return FALSE;
   346 }
   348 pixman_bool_t
   349 _pixman_disabled (const char *name)
   350 {
   351     const char *env;
   353     if ((env = getenv ("PIXMAN_DISABLE")))
   354     {
   355 	do
   356 	{
   357 	    const char *end;
   358 	    int len;
   360 	    if ((end = strchr (env, ' ')))
   361 		len = end - env;
   362 	    else
   363 		len = strlen (env);
   365 	    if (strlen (name) == len && strncmp (name, env, len) == 0)
   366 	    {
   367 		printf ("pixman: Disabled %s implementation\n", name);
   368 		return TRUE;
   369 	    }
   371 	    env += len;
   372 	}
   373 	while (*env++);
   374     }
   376     return FALSE;
   377 }
   379 pixman_implementation_t *
   380 _pixman_choose_implementation (void)
   381 {
   382     pixman_implementation_t *imp;
   384     imp = _pixman_implementation_create_general();
   386     if (!_pixman_disabled ("fast"))
   387 	imp = _pixman_implementation_create_fast_path (imp);
   389     imp = _pixman_x86_get_implementations (imp);
   390     imp = _pixman_arm_get_implementations (imp);
   391     imp = _pixman_ppc_get_implementations (imp);
   392     imp = _pixman_mips_get_implementations (imp);
   394     imp = _pixman_implementation_create_noop (imp);
   396     return imp;
   397 }

mercurial