LCOV - code coverage report
Current view: top level - gfx/cairo/libpixman/src - pixman-implementation.c (source / functions) Hit Total Coverage
Test: output.info Lines: 69 143 48.3 %
Date: 2017-07-14 16:53:18 Functions: 6 14 42.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :  */
      23             : 
      24             : #ifdef HAVE_CONFIG_H
      25             : #include <config.h>
      26             : #endif
      27             : #include <stdlib.h>
      28             : #include "pixman-private.h"
      29             : 
      30             : pixman_implementation_t *
      31           4 : _pixman_implementation_create (pixman_implementation_t *fallback,
      32             :                                const pixman_fast_path_t *fast_paths)
      33             : {
      34             :     pixman_implementation_t *imp;
      35             : 
      36           4 :     assert (fast_paths);
      37             : 
      38           4 :     if ((imp = malloc (sizeof (pixman_implementation_t))))
      39             :     {
      40             :         pixman_implementation_t *d;
      41             : 
      42           4 :         memset (imp, 0, sizeof *imp);
      43             : 
      44           4 :         imp->fallback = fallback;
      45           4 :         imp->fast_paths = fast_paths;
      46             :         
      47             :         /* Make sure the whole fallback chain has the right toplevel */
      48          14 :         for (d = imp; d != NULL; d = d->fallback)
      49          10 :             d->toplevel = imp;
      50             :     }
      51             : 
      52           4 :     return imp;
      53             : }
      54             : 
      55             : #define N_CACHED_FAST_PATHS 8
      56             : 
      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;
      65             : 
      66          24 : PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
      67             : 
      68             : static void
      69           0 : dummy_composite_rect (pixman_implementation_t *imp,
      70             :                       pixman_composite_info_t *info)
      71             : {
      72           0 : }
      73             : 
      74             : void
      75          22 : _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;
      89             : 
      90             :     /* Check cache for fast paths */
      91          22 :     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
      92             : 
      93          30 :     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
      94             :     {
      95          29 :         const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
      96             : 
      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          50 :         if (info->op == op                   &&
     103          42 :             info->src_format == src_format   &&
     104          42 :             info->mask_format == mask_format &&
     105          42 :             info->dest_format == dest_format &&
     106          42 :             info->src_flags == src_flags     &&
     107          42 :             info->mask_flags == mask_flags   &&
     108          42 :             info->dest_flags == dest_flags   &&
     109          21 :             info->func)
     110             :         {
     111          21 :             *out_imp = cache->cache[i].imp;
     112          21 :             *out_func = cache->cache[i].fast_path.func;
     113             : 
     114          21 :             goto update_cache;
     115             :         }
     116             :     }
     117             : 
     118           2 :     for (imp = toplevel; imp != NULL; imp = imp->fallback)
     119             :     {
     120           2 :         const pixman_fast_path_t *info = imp->fast_paths;
     121             : 
     122          78 :         while (info->op != PIXMAN_OP_NONE)
     123             :         {
     124          86 :             if ((info->op == op || info->op == PIXMAN_OP_any)             &&
     125             :                 /* Formats */
     126          20 :                 ((info->src_format == src_format) ||
     127          11 :                  (info->src_format == PIXMAN_any))                   &&
     128           2 :                 ((info->mask_format == mask_format) ||
     129           2 :                  (info->mask_format == PIXMAN_any))                  &&
     130           3 :                 ((info->dest_format == dest_format) ||
     131           2 :                  (info->dest_format == PIXMAN_any))                  &&
     132             :                 /* Flags */
     133           2 :                 (info->src_flags & src_flags) == info->src_flags      &&
     134           2 :                 (info->mask_flags & mask_flags) == info->mask_flags   &&
     135           1 :                 (info->dest_flags & dest_flags) == info->dest_flags)
     136             :             {
     137           1 :                 *out_imp = imp;
     138           1 :                 *out_func = info->func;
     139             : 
     140             :                 /* Set i to the last spot in the cache so that the
     141             :                  * move-to-front code below will work
     142             :                  */
     143           1 :                 i = N_CACHED_FAST_PATHS - 1;
     144             : 
     145           1 :                 goto update_cache;
     146             :             }
     147             : 
     148          74 :             ++info;
     149             :         }
     150             :     }
     151             : 
     152             :     /* We should never reach this point */
     153             :     _pixman_log_error (FUNC, "No known composite function\n");
     154           0 :     *out_imp = NULL;
     155           0 :     *out_func = dummy_composite_rect;
     156             : 
     157             : update_cache:
     158          22 :     if (i)
     159             :     {
     160           9 :         while (i--)
     161           7 :             cache->cache[i + 1] = cache->cache[i];
     162             : 
     163           1 :         cache->cache[0].imp = *out_imp;
     164           1 :         cache->cache[0].fast_path.op = op;
     165           1 :         cache->cache[0].fast_path.src_format = src_format;
     166           1 :         cache->cache[0].fast_path.src_flags = src_flags;
     167           1 :         cache->cache[0].fast_path.mask_format = mask_format;
     168           1 :         cache->cache[0].fast_path.mask_flags = mask_flags;
     169           1 :         cache->cache[0].fast_path.dest_format = dest_format;
     170           1 :         cache->cache[0].fast_path.dest_flags = dest_flags;
     171           1 :         cache->cache[0].fast_path.func = *out_func;
     172             :     }
     173          22 : }
     174             : 
     175             : static void
     176           0 : 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           0 : }
     184             : 
     185             : pixman_combine_32_func_t
     186           0 : _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           0 :     while (imp)
     193             :     {
     194           0 :         pixman_combine_32_func_t f = NULL;
     195             : 
     196           0 :         switch ((narrow << 1) | component_alpha)
     197             :         {
     198             :         case 0: /* not narrow, not component alpha */
     199           0 :             f = (pixman_combine_32_func_t)imp->combine_float[op];
     200           0 :             break;
     201             :             
     202             :         case 1: /* not narrow, component_alpha */
     203           0 :             f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
     204           0 :             break;
     205             : 
     206             :         case 2: /* narrow, not component alpha */
     207           0 :             f = imp->combine_32[op];
     208           0 :             break;
     209             : 
     210             :         case 3: /* narrow, component_alpha */
     211           0 :             f = imp->combine_32_ca[op];
     212           0 :             break;
     213             :         }
     214           0 :         if (rgb16)
     215           0 :             f = (pixman_combine_32_func_t *)imp->combine_16[op];
     216             : 
     217           0 :         if (f)
     218           0 :             return f;
     219             : 
     220           0 :         imp = imp->fallback;
     221             :     }
     222             : 
     223             :     /* We should never reach this point */
     224             :     _pixman_log_error (FUNC, "No known combine function\n");
     225           0 :     return dummy_combine;
     226             : }
     227             : 
     228             : pixman_bool_t
     229           0 : _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           0 :     while (imp)
     244             :     {
     245           0 :         if (imp->blt &&
     246           0 :             (*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           0 :             return TRUE;
     251             :         }
     252             : 
     253           0 :         imp = imp->fallback;
     254             :     }
     255             : 
     256           0 :     return FALSE;
     257             : }
     258             : 
     259             : pixman_bool_t
     260           0 : _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           0 :     while (imp)
     271             :     {
     272           0 :         if (imp->fill &&
     273           0 :             ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
     274             :         {
     275           0 :             return TRUE;
     276             :         }
     277             : 
     278           0 :         imp = imp->fallback;
     279             :     }
     280             : 
     281           0 :     return FALSE;
     282             : }
     283             : 
     284             : pixman_bool_t
     285           0 : _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           0 :     iter->image = image;
     297           0 :     iter->buffer = (uint32_t *)buffer;
     298           0 :     iter->x = x;
     299           0 :     iter->y = y;
     300           0 :     iter->width = width;
     301           0 :     iter->height = height;
     302           0 :     iter->iter_flags = iter_flags;
     303           0 :     iter->image_flags = image_flags;
     304             : 
     305           0 :     while (imp)
     306             :     {
     307           0 :         if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
     308           0 :             return TRUE;
     309             : 
     310           0 :         imp = imp->fallback;
     311             :     }
     312             : 
     313           0 :     return FALSE;
     314             : }
     315             : 
     316             : pixman_bool_t
     317           0 : _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           0 :     iter->image = image;
     329           0 :     iter->buffer = (uint32_t *)buffer;
     330           0 :     iter->x = x;
     331           0 :     iter->y = y;
     332           0 :     iter->width = width;
     333           0 :     iter->height = height;
     334           0 :     iter->iter_flags = iter_flags;
     335           0 :     iter->image_flags = image_flags;
     336             : 
     337           0 :     while (imp)
     338             :     {
     339           0 :         if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
     340           0 :             return TRUE;
     341             : 
     342           0 :         imp = imp->fallback;
     343             :     }
     344             : 
     345           0 :     return FALSE;
     346             : }
     347             : 
     348             : pixman_bool_t
     349           2 : _pixman_disabled (const char *name)
     350             : {
     351             :     const char *env;
     352             : 
     353           2 :     if ((env = getenv ("PIXMAN_DISABLE")))
     354             :     {
     355             :         do
     356             :         {
     357             :             const char *end;
     358             :             int len;
     359             : 
     360           0 :             if ((end = strchr (env, ' ')))
     361           0 :                 len = end - env;
     362             :             else
     363           0 :                 len = strlen (env);
     364             : 
     365           0 :             if (strlen (name) == len && strncmp (name, env, len) == 0)
     366             :             {
     367           0 :                 printf ("pixman: Disabled %s implementation\n", name);
     368           0 :                 return TRUE;
     369             :             }
     370             : 
     371           0 :             env += len;
     372             :         }
     373           0 :         while (*env++);
     374             :     }
     375             : 
     376           2 :     return FALSE;
     377             : }
     378             : 
     379             : pixman_implementation_t *
     380           1 : _pixman_choose_implementation (void)
     381             : {
     382             :     pixman_implementation_t *imp;
     383             : 
     384           1 :     imp = _pixman_implementation_create_general();
     385             : 
     386           1 :     if (!_pixman_disabled ("fast"))
     387           1 :         imp = _pixman_implementation_create_fast_path (imp);
     388             : 
     389           1 :     imp = _pixman_x86_get_implementations (imp);
     390           1 :     imp = _pixman_arm_get_implementations (imp);
     391           1 :     imp = _pixman_ppc_get_implementations (imp);
     392           1 :     imp = _pixman_mips_get_implementations (imp);
     393             : 
     394           1 :     imp = _pixman_implementation_create_noop (imp);
     395             : 
     396           1 :     return imp;
     397             : }

Generated by: LCOV version 1.13