Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2009 Red Hat, Inc.
  3.  * Copyright © 2000 SuSE, Inc.
  4.  * Copyright © 2007 Red Hat, Inc.
  5.  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  6.  *             2005 Lars Knoll & Zack Rusin, Trolltech
  7.  *             2008 Aaron Plattner, NVIDIA Corporation
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and its
  10.  * documentation for any purpose is hereby granted without fee, provided that
  11.  * the above copyright notice appear in all copies and that both that
  12.  * copyright notice and this permission notice appear in supporting
  13.  * documentation, and that the name of Red Hat not be used in advertising or
  14.  * publicity pertaining to distribution of the software without specific,
  15.  * written prior permission.  Red Hat makes no representations about the
  16.  * suitability of this software for any purpose.  It is provided "as is"
  17.  * without express or implied warranty.
  18.  *
  19.  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  20.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  21.  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
  22.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  23.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  24.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  25.  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  26.  * SOFTWARE.
  27.  */
  28. #ifdef HAVE_CONFIG_H
  29. #include <config.h>
  30. #endif
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <math.h>
  34. #include <limits.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include "pixman-private.h"
  39.  
  40. static pixman_bool_t
  41. general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
  42. {
  43.     pixman_image_t *image = iter->image;
  44.  
  45.     if (image->type == LINEAR)
  46.         _pixman_linear_gradient_iter_init (image, iter);
  47.     else if (image->type == RADIAL)
  48.         _pixman_radial_gradient_iter_init (image, iter);
  49.     else if (image->type == CONICAL)
  50.         _pixman_conical_gradient_iter_init (image, iter);
  51.     else if (image->type == BITS)
  52.         _pixman_bits_image_src_iter_init (image, iter);
  53.     else if (image->type == SOLID)
  54.         _pixman_log_error (FUNC, "Solid image not handled by noop");
  55.     else        
  56.         _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
  57.  
  58.     return TRUE;
  59. }
  60.  
  61. static pixman_bool_t
  62. general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
  63. {
  64.     if (iter->image->type == BITS)
  65.     {
  66.         _pixman_bits_image_dest_iter_init (iter->image, iter);
  67.  
  68.         return TRUE;
  69.     }
  70.     else
  71.     {
  72.         _pixman_log_error (FUNC, "Trying to write to a non-writable image");
  73.  
  74.         return FALSE;
  75.     }
  76. }
  77.  
  78. typedef struct op_info_t op_info_t;
  79. struct op_info_t
  80. {
  81.     uint8_t src, dst;
  82. };
  83.  
  84. #define ITER_IGNORE_BOTH                                                \
  85.     (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
  86.  
  87. static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
  88. {
  89.     /* Src                   Dst                   */
  90.     { ITER_IGNORE_BOTH,      ITER_IGNORE_BOTH      }, /* CLEAR */
  91.     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_BOTH      }, /* SRC */
  92.     { ITER_IGNORE_BOTH,      ITER_LOCALIZED_ALPHA  }, /* DST */
  93.     { 0,                     ITER_LOCALIZED_ALPHA  }, /* OVER */
  94.     { ITER_LOCALIZED_ALPHA,  0                     }, /* OVER_REVERSE */
  95.     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* IN */
  96.     { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* IN_REVERSE */
  97.     { ITER_LOCALIZED_ALPHA,  ITER_IGNORE_RGB       }, /* OUT */
  98.     { ITER_IGNORE_RGB,       ITER_LOCALIZED_ALPHA  }, /* OUT_REVERSE */
  99.     { 0,                     0                     }, /* ATOP */
  100.     { 0,                     0                     }, /* ATOP_REVERSE */
  101.     { 0,                     0                     }, /* XOR */
  102.     { ITER_LOCALIZED_ALPHA,  ITER_LOCALIZED_ALPHA  }, /* ADD */
  103.     { 0,                     0                     }, /* SATURATE */
  104. };
  105.  
  106. #define SCANLINE_BUFFER_LENGTH 8192
  107.  
  108. static void
  109. general_composite_rect  (pixman_implementation_t *imp,
  110.                          pixman_composite_info_t *info)
  111. {
  112.     PIXMAN_COMPOSITE_ARGS (info);
  113.     uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
  114.     uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
  115.     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
  116.     pixman_iter_t src_iter, mask_iter, dest_iter;
  117.     pixman_combine_32_func_t compose;
  118.     pixman_bool_t component_alpha;
  119.     iter_flags_t narrow, src_iter_flags;
  120.     int Bpp;
  121.     int i;
  122.  
  123.     if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT)                 &&
  124.         (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
  125.         (dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
  126.     {
  127.         narrow = ITER_NARROW;
  128.         Bpp = 4;
  129.     }
  130.     else
  131.     {
  132.         narrow = 0;
  133.         Bpp = 16;
  134.     }
  135.  
  136.     if (width * Bpp > SCANLINE_BUFFER_LENGTH)
  137.     {
  138.         scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
  139.  
  140.         if (!scanline_buffer)
  141.             return;
  142.     }
  143.  
  144.     src_buffer = scanline_buffer;
  145.     mask_buffer = src_buffer + width * Bpp;
  146.     dest_buffer = mask_buffer + width * Bpp;
  147.  
  148.     if (!narrow)
  149.     {
  150.         /* To make sure there aren't any NANs in the buffers */
  151.         memset (src_buffer, 0, width * Bpp);
  152.         memset (mask_buffer, 0, width * Bpp);
  153.         memset (dest_buffer, 0, width * Bpp);
  154.     }
  155.    
  156.     /* src iter */
  157.     src_iter_flags = narrow | op_flags[op].src;
  158.  
  159.     _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
  160.                                           src_x, src_y, width, height,
  161.                                           src_buffer, src_iter_flags, info->src_flags);
  162.  
  163.     /* mask iter */
  164.     if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
  165.         (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
  166.     {
  167.         /* If it doesn't matter what the source is, then it doesn't matter
  168.          * what the mask is
  169.          */
  170.         mask_image = NULL;
  171.     }
  172.  
  173.     component_alpha =
  174.         mask_image                            &&
  175.         mask_image->common.type == BITS       &&
  176.         mask_image->common.component_alpha    &&
  177.         PIXMAN_FORMAT_RGB (mask_image->bits.format);
  178.  
  179.     _pixman_implementation_src_iter_init (
  180.         imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
  181.         mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB), info->mask_flags);
  182.  
  183.     /* dest iter */
  184.     _pixman_implementation_dest_iter_init (
  185.         imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
  186.         dest_buffer, narrow | op_flags[op].dst, info->dest_flags);
  187.  
  188.     compose = _pixman_implementation_lookup_combiner (
  189.         imp->toplevel, op, component_alpha, narrow);
  190.  
  191.     for (i = 0; i < height; ++i)
  192.     {
  193.         uint32_t *s, *m, *d;
  194.  
  195.         m = mask_iter.get_scanline (&mask_iter, NULL);
  196.         s = src_iter.get_scanline (&src_iter, m);
  197.         d = dest_iter.get_scanline (&dest_iter, NULL);
  198.  
  199.         compose (imp->toplevel, op, d, s, m, width);
  200.  
  201.         dest_iter.write_back (&dest_iter);
  202.     }
  203.  
  204.     if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
  205.         free (scanline_buffer);
  206. }
  207.  
  208. static const pixman_fast_path_t general_fast_path[] =
  209. {
  210.     { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
  211.     { PIXMAN_OP_NONE }
  212. };
  213.  
  214. pixman_implementation_t *
  215. _pixman_implementation_create_general (void)
  216. {
  217.     pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
  218.  
  219.     _pixman_setup_combiner_functions_32 (imp);
  220.     _pixman_setup_combiner_functions_float (imp);
  221.  
  222.     imp->src_iter_init = general_src_iter_init;
  223.     imp->dest_iter_init = general_dest_iter_init;
  224.  
  225.     return imp;
  226. }
  227.  
  228.