Home | History | Annotate | Line # | Download | only in pixman
      1 #ifndef PIXMAN_PRIVATE_H
      2 #define PIXMAN_PRIVATE_H
      3 
      4 /*
      5  * The defines which are shared between C and assembly code
      6  */
      7 
      8 /* bilinear interpolation precision (must be < 8) */
      9 #define BILINEAR_INTERPOLATION_BITS 7
     10 #define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS)
     11 
     12 /*
     13  * C specific part
     14  */
     15 
     16 #ifndef __ASSEMBLER__
     17 
     18 #ifndef PACKAGE
     19 #  error config.h must be included before pixman-private.h
     20 #endif
     21 
     22 #define PIXMAN_DISABLE_DEPRECATED
     23 #define PIXMAN_USE_INTERNAL_API
     24 
     25 #include "pixman.h"
     26 #include <time.h>
     27 #include <assert.h>
     28 #include <stdio.h>
     29 #include <string.h>
     30 #include <stddef.h>
     31 #include <float.h>
     32 
     33 #include "pixman-compiler.h"
     34 
     35 /*
     36  * Images
     37  */
     38 typedef struct image_common image_common_t;
     39 typedef struct solid_fill solid_fill_t;
     40 typedef struct gradient gradient_t;
     41 typedef struct linear_gradient linear_gradient_t;
     42 typedef struct horizontal_gradient horizontal_gradient_t;
     43 typedef struct vertical_gradient vertical_gradient_t;
     44 typedef struct conical_gradient conical_gradient_t;
     45 typedef struct radial_gradient radial_gradient_t;
     46 typedef struct bits_image bits_image_t;
     47 typedef struct circle circle_t;
     48 
     49 typedef struct argb_t argb_t;
     50 
     51 struct argb_t
     52 {
     53     float a;
     54     float r;
     55     float g;
     56     float b;
     57 };
     58 
     59 typedef void (*fetch_scanline_t) (bits_image_t   *image,
     60 				  int             x,
     61 				  int             y,
     62 				  int             width,
     63 				  uint32_t       *buffer,
     64 				  const uint32_t *mask);
     65 
     66 typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image,
     67 				      int           x,
     68 				      int           y);
     69 
     70 typedef argb_t (*fetch_pixel_float_t) (bits_image_t *image,
     71 				       int           x,
     72 				       int           y);
     73 
     74 typedef void (*store_scanline_t) (bits_image_t *  image,
     75 				  int             x,
     76 				  int             y,
     77 				  int             width,
     78 				  const uint32_t *values);
     79 
     80 typedef enum
     81 {
     82     BITS,
     83     LINEAR,
     84     CONICAL,
     85     RADIAL,
     86     SOLID
     87 } image_type_t;
     88 
     89 typedef void (*property_changed_func_t) (pixman_image_t *image);
     90 
     91 struct image_common
     92 {
     93     image_type_t                type;
     94     int32_t                     ref_count;
     95     pixman_region32_t           clip_region;
     96     int32_t			alpha_count;	    /* How many times this image is being used as an alpha map */
     97     pixman_bool_t               have_clip_region;   /* FALSE if there is no clip */
     98     pixman_bool_t               client_clip;        /* Whether the source clip was
     99 						       set by a client */
    100     pixman_bool_t               clip_sources;       /* Whether the clip applies when
    101 						     * the image is used as a source
    102 						     */
    103     pixman_bool_t		dirty;
    104     pixman_transform_t *        transform;
    105     pixman_repeat_t             repeat;
    106     pixman_filter_t             filter;
    107     pixman_fixed_t *            filter_params;
    108     int                         n_filter_params;
    109     bits_image_t *              alpha_map;
    110     int                         alpha_origin_x;
    111     int                         alpha_origin_y;
    112     pixman_bool_t               component_alpha;
    113     property_changed_func_t     property_changed;
    114 
    115     pixman_image_destroy_func_t destroy_func;
    116     void *                      destroy_data;
    117 
    118     uint32_t			flags;
    119     pixman_format_code_t	extended_format_code;
    120 };
    121 
    122 struct solid_fill
    123 {
    124     image_common_t common;
    125     pixman_color_t color;
    126 
    127     uint32_t	   color_32;
    128     argb_t	   color_float;
    129 };
    130 
    131 struct gradient
    132 {
    133     image_common_t	    common;
    134     int                     n_stops;
    135     pixman_gradient_stop_t *stops;
    136 };
    137 
    138 struct linear_gradient
    139 {
    140     gradient_t           common;
    141     pixman_point_fixed_t p1;
    142     pixman_point_fixed_t p2;
    143 };
    144 
    145 struct circle
    146 {
    147     pixman_fixed_t x;
    148     pixman_fixed_t y;
    149     pixman_fixed_t radius;
    150 };
    151 
    152 struct radial_gradient
    153 {
    154     gradient_t common;
    155 
    156     circle_t   c1;
    157     circle_t   c2;
    158 
    159     circle_t   delta;
    160     double     a;
    161     double     inva;
    162     double     mindr;
    163 };
    164 
    165 struct conical_gradient
    166 {
    167     gradient_t           common;
    168     pixman_point_fixed_t center;
    169     double		 angle;
    170 };
    171 
    172 struct bits_image
    173 {
    174     image_common_t             common;
    175     pixman_format_code_t       format;
    176     const pixman_indexed_t *   indexed;
    177     int                        width;
    178     int                        height;
    179     uint32_t *                 bits;
    180     uint32_t *                 free_me;
    181     int                        rowstride;  /* in number of uint32_t's */
    182 
    183     pixman_dither_t            dither;
    184     uint32_t                   dither_offset_y;
    185     uint32_t                   dither_offset_x;
    186 
    187     fetch_scanline_t           fetch_scanline_32;
    188     fetch_pixel_32_t	       fetch_pixel_32;
    189     store_scanline_t           store_scanline_32;
    190 
    191     fetch_scanline_t	       fetch_scanline_float;
    192     fetch_pixel_float_t	       fetch_pixel_float;
    193     store_scanline_t           store_scanline_float;
    194 
    195     /* Used for indirect access to the bits */
    196     pixman_read_memory_func_t  read_func;
    197     pixman_write_memory_func_t write_func;
    198 };
    199 
    200 union pixman_image
    201 {
    202     image_type_t       type;
    203     image_common_t     common;
    204     bits_image_t       bits;
    205     gradient_t         gradient;
    206     linear_gradient_t  linear;
    207     conical_gradient_t conical;
    208     radial_gradient_t  radial;
    209     solid_fill_t       solid;
    210 };
    211 
    212 typedef struct pixman_iter_t pixman_iter_t;
    213 typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const uint32_t *mask);
    214 typedef void      (* pixman_iter_write_back_t)   (pixman_iter_t *iter);
    215 typedef void	  (* pixman_iter_fini_t)	 (pixman_iter_t *iter);
    216 
    217 typedef enum
    218 {
    219     ITER_NARROW =               (1 << 0),
    220     ITER_WIDE =                 (1 << 1),
    221 
    222     /* "Localized alpha" is when the alpha channel is used only to compute
    223      * the alpha value of the destination. This means that the computation
    224      * of the RGB values of the result is independent of the alpha value.
    225      *
    226      * For example, the OVER operator has localized alpha for the
    227      * destination, because the RGB values of the result can be computed
    228      * without knowing the destination alpha. Similarly, ADD has localized
    229      * alpha for both source and destination because the RGB values of the
    230      * result can be computed without knowing the alpha value of source or
    231      * destination.
    232      *
    233      * When he destination is xRGB, this is useful knowledge, because then
    234      * we can treat it as if it were ARGB, which means in some cases we can
    235      * avoid copying it to a temporary buffer.
    236      */
    237     ITER_LOCALIZED_ALPHA =	(1 << 2),
    238     ITER_IGNORE_ALPHA =		(1 << 3),
    239     ITER_IGNORE_RGB =		(1 << 4),
    240 
    241     /* These indicate whether the iterator is for a source
    242      * or a destination image
    243      */
    244     ITER_SRC =			(1 << 5),
    245     ITER_DEST =			(1 << 6)
    246 } iter_flags_t;
    247 
    248 struct pixman_iter_t
    249 {
    250     /* These are initialized by _pixman_implementation_{src,dest}_init */
    251     pixman_image_t *		image;
    252     uint32_t *			buffer;
    253     int				x, y;
    254     int				width;
    255     int				height;
    256     iter_flags_t		iter_flags;
    257     uint32_t			image_flags;
    258 
    259     /* These function pointers are initialized by the implementation */
    260     pixman_iter_get_scanline_t	get_scanline;
    261     pixman_iter_write_back_t	write_back;
    262     pixman_iter_fini_t          fini;
    263 
    264     /* These fields are scratch data that implementations can use */
    265     void *			data;
    266     uint8_t *			bits;
    267     int				stride;
    268 };
    269 
    270 typedef struct pixman_iter_info_t pixman_iter_info_t;
    271 typedef void (* pixman_iter_initializer_t) (pixman_iter_t *iter,
    272                                             const pixman_iter_info_t *info);
    273 struct pixman_iter_info_t
    274 {
    275     pixman_format_code_t	format;
    276     uint32_t			image_flags;
    277     iter_flags_t		iter_flags;
    278     pixman_iter_initializer_t	initializer;
    279     pixman_iter_get_scanline_t	get_scanline;
    280     pixman_iter_write_back_t	write_back;
    281 };
    282 
    283 void
    284 _pixman_bits_image_setup_accessors (bits_image_t *image);
    285 
    286 void
    287 _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter);
    288 
    289 void
    290 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter);
    291 
    292 void
    293 _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t  *iter);
    294 
    295 void
    296 _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
    297 
    298 void
    299 _pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
    300 
    301 void
    302 _pixman_image_init (pixman_image_t *image);
    303 
    304 pixman_bool_t
    305 _pixman_bits_image_init (pixman_image_t *     image,
    306                          pixman_format_code_t format,
    307                          int                  width,
    308                          int                  height,
    309                          uint32_t *           bits,
    310                          int                  rowstride,
    311 			 pixman_bool_t	      clear);
    312 pixman_bool_t
    313 _pixman_image_fini (pixman_image_t *image);
    314 
    315 pixman_image_t *
    316 _pixman_image_allocate (void);
    317 
    318 pixman_bool_t
    319 _pixman_init_gradient (gradient_t *                  gradient,
    320                        const pixman_gradient_stop_t *stops,
    321                        int                           n_stops);
    322 void
    323 _pixman_image_reset_clip_region (pixman_image_t *image);
    324 
    325 void
    326 _pixman_image_validate (pixman_image_t *image);
    327 
    328 #define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul)	\
    329     do									\
    330     {									\
    331 	uint32_t *__bits__;						\
    332 	int       __stride__;						\
    333         								\
    334 	__bits__ = image->bits.bits;					\
    335 	__stride__ = image->bits.rowstride;				\
    336 	(out_stride) =							\
    337 	    __stride__ * (int) sizeof (uint32_t) / (int) sizeof (type);	\
    338 	(line) =							\
    339 	    ((type *) __bits__) + (out_stride) * (y) + (mul) * (x);	\
    340     } while (0)
    341 
    342 /*
    343  * Gradient walker
    344  */
    345 typedef struct
    346 {
    347     float		    a_s, a_b;
    348     float		    r_s, r_b;
    349     float		    g_s, g_b;
    350     float		    b_s, b_b;
    351     pixman_fixed_48_16_t    left_x;
    352     pixman_fixed_48_16_t    right_x;
    353 
    354     pixman_gradient_stop_t *stops;
    355     int                     num_stops;
    356     pixman_repeat_t	    repeat;
    357 
    358     pixman_bool_t           need_reset;
    359 } pixman_gradient_walker_t;
    360 
    361 void
    362 _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
    363                               gradient_t *              gradient,
    364 			      pixman_repeat_t           repeat);
    365 
    366 void
    367 _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
    368                                pixman_fixed_48_16_t      pos);
    369 
    370 typedef void (*pixman_gradient_walker_write_t) (
    371     pixman_gradient_walker_t *walker,
    372     pixman_fixed_48_16_t      x,
    373     uint32_t                 *buffer);
    374 
    375 void
    376 _pixman_gradient_walker_write_narrow(pixman_gradient_walker_t *walker,
    377 				     pixman_fixed_48_16_t      x,
    378 				     uint32_t                 *buffer);
    379 
    380 void
    381 _pixman_gradient_walker_write_wide(pixman_gradient_walker_t *walker,
    382 				   pixman_fixed_48_16_t      x,
    383 				   uint32_t                 *buffer);
    384 
    385 typedef void (*pixman_gradient_walker_fill_t) (
    386     pixman_gradient_walker_t *walker,
    387     pixman_fixed_48_16_t      x,
    388     uint32_t                 *buffer,
    389     uint32_t                 *end);
    390 
    391 void
    392 _pixman_gradient_walker_fill_narrow(pixman_gradient_walker_t *walker,
    393 				    pixman_fixed_48_16_t      x,
    394 				    uint32_t                 *buffer,
    395 				    uint32_t                 *end);
    396 
    397 void
    398 _pixman_gradient_walker_fill_wide(pixman_gradient_walker_t *walker,
    399 				  pixman_fixed_48_16_t      x,
    400 				  uint32_t                 *buffer,
    401 				  uint32_t                 *end);
    402 
    403 /*
    404  * Edges
    405  */
    406 
    407 #define MAX_ALPHA(n)    ((1 << (n)) - 1)
    408 #define N_Y_FRAC(n)     ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)
    409 #define N_X_FRAC(n)     ((n) == 1 ? 1 : (1 << ((n) / 2)) + 1)
    410 
    411 #define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n))
    412 #define STEP_Y_BIG(n)   (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
    413 
    414 #define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2)
    415 #define Y_FRAC_LAST(n)  (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
    416 
    417 #define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n))
    418 #define STEP_X_BIG(n)   (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
    419 
    420 #define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2)
    421 #define X_FRAC_LAST(n)  (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
    422 
    423 #define RENDER_SAMPLES_X(x, n)						\
    424     ((n) == 1? 0 : (pixman_fixed_frac (x) +				\
    425 		    X_FRAC_FIRST (n)) / STEP_X_SMALL (n))
    426 
    427 void
    428 pixman_rasterize_edges_accessors (pixman_image_t *image,
    429                                   pixman_edge_t * l,
    430                                   pixman_edge_t * r,
    431                                   pixman_fixed_t  t,
    432                                   pixman_fixed_t  b);
    433 
    434 /*
    435  * Implementations
    436  */
    437 typedef struct pixman_implementation_t pixman_implementation_t;
    438 
    439 typedef struct
    440 {
    441     pixman_op_t              op;
    442     pixman_image_t *         src_image;
    443     pixman_image_t *         mask_image;
    444     pixman_image_t *         dest_image;
    445     int32_t                  src_x;
    446     int32_t                  src_y;
    447     int32_t                  mask_x;
    448     int32_t                  mask_y;
    449     int32_t                  dest_x;
    450     int32_t                  dest_y;
    451     int32_t                  width;
    452     int32_t                  height;
    453 
    454     uint32_t                 src_flags;
    455     uint32_t                 mask_flags;
    456     uint32_t                 dest_flags;
    457 } pixman_composite_info_t;
    458 
    459 #define PIXMAN_COMPOSITE_ARGS(info)					\
    460     MAYBE_UNUSED pixman_op_t        op = info->op;			\
    461     MAYBE_UNUSED pixman_image_t *   src_image = info->src_image;	\
    462     MAYBE_UNUSED pixman_image_t *   mask_image = info->mask_image;	\
    463     MAYBE_UNUSED pixman_image_t *   dest_image = info->dest_image;	\
    464     MAYBE_UNUSED int32_t            src_x = info->src_x;		\
    465     MAYBE_UNUSED int32_t            src_y = info->src_y;		\
    466     MAYBE_UNUSED int32_t            mask_x = info->mask_x;		\
    467     MAYBE_UNUSED int32_t            mask_y = info->mask_y;		\
    468     MAYBE_UNUSED int32_t            dest_x = info->dest_x;		\
    469     MAYBE_UNUSED int32_t            dest_y = info->dest_y;		\
    470     MAYBE_UNUSED int32_t            width = info->width;		\
    471     MAYBE_UNUSED int32_t            height = info->height
    472 
    473 typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
    474 					  pixman_op_t              op,
    475 					  uint32_t *               dest,
    476 					  const uint32_t *         src,
    477 					  const uint32_t *         mask,
    478 					  int                      width);
    479 
    480 typedef void (*pixman_combine_float_func_t) (pixman_implementation_t *imp,
    481 					     pixman_op_t	      op,
    482 					     float *		      dest,
    483 					     const float *	      src,
    484 					     const float *	      mask,
    485 					     int		      n_pixels);
    486 
    487 typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp,
    488 					 pixman_composite_info_t *info);
    489 typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
    490 					    uint32_t *               src_bits,
    491 					    uint32_t *               dst_bits,
    492 					    int                      src_stride,
    493 					    int                      dst_stride,
    494 					    int                      src_bpp,
    495 					    int                      dst_bpp,
    496 					    int                      src_x,
    497 					    int                      src_y,
    498 					    int                      dest_x,
    499 					    int                      dest_y,
    500 					    int                      width,
    501 					    int                      height);
    502 typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
    503 					     uint32_t *               bits,
    504 					     int                      stride,
    505 					     int                      bpp,
    506 					     int                      x,
    507 					     int                      y,
    508 					     int                      width,
    509 					     int                      height,
    510 					     uint32_t                 filler);
    511 
    512 void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
    513 void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp);
    514 
    515 typedef struct
    516 {
    517     pixman_op_t             op;
    518     pixman_format_code_t    src_format;
    519     uint32_t		    src_flags;
    520     pixman_format_code_t    mask_format;
    521     uint32_t		    mask_flags;
    522     pixman_format_code_t    dest_format;
    523     uint32_t		    dest_flags;
    524     pixman_composite_func_t func;
    525 } pixman_fast_path_t;
    526 
    527 struct pixman_implementation_t
    528 {
    529     pixman_implementation_t *	toplevel;
    530     pixman_implementation_t *	fallback;
    531     const pixman_fast_path_t *	fast_paths;
    532     const pixman_iter_info_t *  iter_info;
    533 
    534     pixman_blt_func_t		blt;
    535     pixman_fill_func_t		fill;
    536 
    537     pixman_combine_32_func_t	combine_32[PIXMAN_N_OPERATORS];
    538     pixman_combine_32_func_t	combine_32_ca[PIXMAN_N_OPERATORS];
    539     pixman_combine_float_func_t	combine_float[PIXMAN_N_OPERATORS];
    540     pixman_combine_float_func_t	combine_float_ca[PIXMAN_N_OPERATORS];
    541 };
    542 
    543 uint32_t
    544 _pixman_image_get_solid (pixman_implementation_t *imp,
    545 			 pixman_image_t *         image,
    546                          pixman_format_code_t     format);
    547 
    548 pixman_implementation_t *
    549 _pixman_implementation_create (pixman_implementation_t *fallback,
    550 			       const pixman_fast_path_t *fast_paths);
    551 
    552 void
    553 _pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
    554 					 pixman_op_t               op,
    555 					 pixman_format_code_t      src_format,
    556 					 uint32_t                  src_flags,
    557 					 pixman_format_code_t      mask_format,
    558 					 uint32_t                  mask_flags,
    559 					 pixman_format_code_t      dest_format,
    560 					 uint32_t                  dest_flags,
    561 					 pixman_implementation_t **out_imp,
    562 					 pixman_composite_func_t  *out_func);
    563 
    564 pixman_combine_32_func_t
    565 _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
    566 					pixman_op_t		 op,
    567 					pixman_bool_t		 component_alpha,
    568 					pixman_bool_t		 wide);
    569 
    570 pixman_bool_t
    571 _pixman_implementation_blt (pixman_implementation_t *imp,
    572                             uint32_t *               src_bits,
    573                             uint32_t *               dst_bits,
    574                             int                      src_stride,
    575                             int                      dst_stride,
    576                             int                      src_bpp,
    577                             int                      dst_bpp,
    578                             int                      src_x,
    579                             int                      src_y,
    580                             int                      dest_x,
    581                             int                      dest_y,
    582                             int                      width,
    583                             int                      height);
    584 
    585 pixman_bool_t
    586 _pixman_implementation_fill (pixman_implementation_t *imp,
    587                              uint32_t *               bits,
    588                              int                      stride,
    589                              int                      bpp,
    590                              int                      x,
    591                              int                      y,
    592                              int                      width,
    593                              int                      height,
    594                              uint32_t                 filler);
    595 
    596 void
    597 _pixman_implementation_iter_init (pixman_implementation_t       *imp,
    598                                   pixman_iter_t                 *iter,
    599                                   pixman_image_t                *image,
    600                                   int                            x,
    601                                   int                            y,
    602                                   int                            width,
    603                                   int                            height,
    604                                   uint8_t                       *buffer,
    605                                   iter_flags_t                   flags,
    606                                   uint32_t                       image_flags);
    607 
    608 /* Specific implementations */
    609 pixman_implementation_t *
    610 _pixman_implementation_create_general (void);
    611 
    612 pixman_implementation_t *
    613 _pixman_implementation_create_fast_path (pixman_implementation_t *fallback);
    614 
    615 pixman_implementation_t *
    616 _pixman_implementation_create_noop (pixman_implementation_t *fallback);
    617 
    618 #if defined USE_X86_MMX || defined USE_LOONGSON_MMI
    619 pixman_implementation_t *
    620 _pixman_implementation_create_mmx (pixman_implementation_t *fallback);
    621 #endif
    622 
    623 #ifdef USE_SSE2
    624 pixman_implementation_t *
    625 _pixman_implementation_create_sse2 (pixman_implementation_t *fallback);
    626 #endif
    627 
    628 #ifdef USE_SSSE3
    629 pixman_implementation_t *
    630 _pixman_implementation_create_ssse3 (pixman_implementation_t *fallback);
    631 #endif
    632 
    633 #ifdef USE_ARM_SIMD
    634 pixman_implementation_t *
    635 _pixman_implementation_create_arm_simd (pixman_implementation_t *fallback);
    636 #endif
    637 
    638 #ifdef USE_ARM_NEON
    639 pixman_implementation_t *
    640 _pixman_implementation_create_arm_neon (pixman_implementation_t *fallback);
    641 #endif
    642 
    643 #ifdef USE_ARM_A64_NEON
    644 pixman_implementation_t *
    645 _pixman_implementation_create_arm_neon (pixman_implementation_t *fallback);
    646 #endif
    647 
    648 #ifdef USE_MIPS_DSPR2
    649 pixman_implementation_t *
    650 _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback);
    651 #endif
    652 
    653 #ifdef USE_VMX
    654 pixman_implementation_t *
    655 _pixman_implementation_create_vmx (pixman_implementation_t *fallback);
    656 #endif
    657 
    658 #ifdef USE_RVV
    659 pixman_implementation_t *
    660 _pixman_implementation_create_rvv (pixman_implementation_t *fallback);
    661 #endif
    662 
    663 pixman_bool_t
    664 _pixman_implementation_disabled (const char *name);
    665 
    666 pixman_implementation_t *
    667 _pixman_x86_get_implementations (pixman_implementation_t *imp);
    668 
    669 pixman_implementation_t *
    670 _pixman_arm_get_implementations (pixman_implementation_t *imp);
    671 
    672 pixman_implementation_t *
    673 _pixman_ppc_get_implementations (pixman_implementation_t *imp);
    674 
    675 pixman_implementation_t *
    676 _pixman_mips_get_implementations (pixman_implementation_t *imp);
    677 
    678 pixman_implementation_t *
    679 _pixman_riscv_get_implementations (pixman_implementation_t *imp);
    680 
    681 pixman_implementation_t *
    682 _pixman_choose_implementation (void);
    683 
    684 pixman_bool_t
    685 _pixman_disabled (const char *name);
    686 
    687 
    688 /*
    689  * Utilities
    690  */
    691 pixman_bool_t
    692 _pixman_compute_composite_region32 (pixman_region32_t * region,
    693 				    pixman_image_t *    src_image,
    694 				    pixman_image_t *    mask_image,
    695 				    pixman_image_t *    dest_image,
    696 				    int32_t             src_x,
    697 				    int32_t             src_y,
    698 				    int32_t             mask_x,
    699 				    int32_t             mask_y,
    700 				    int32_t             dest_x,
    701 				    int32_t             dest_y,
    702 				    int32_t             width,
    703 				    int32_t             height);
    704 uint32_t *
    705 _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
    706 
    707 void
    708 _pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info);
    709 
    710 /* These "formats" all have depth 0, so they
    711  * will never clash with any real ones
    712  */
    713 #define PIXMAN_null             PIXMAN_FORMAT (0, 0, 0, 0, 0, 0)
    714 #define PIXMAN_solid            PIXMAN_FORMAT (0, 1, 0, 0, 0, 0)
    715 #define PIXMAN_pixbuf		PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
    716 #define PIXMAN_rpixbuf		PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
    717 #define PIXMAN_unknown		PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
    718 #define PIXMAN_any		PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
    719 
    720 #define FAST_PATH_ID_TRANSFORM			(1 <<  0)
    721 #define FAST_PATH_NO_ALPHA_MAP			(1 <<  1)
    722 #define FAST_PATH_NO_CONVOLUTION_FILTER		(1 <<  2)
    723 #define FAST_PATH_NO_PAD_REPEAT			(1 <<  3)
    724 #define FAST_PATH_NO_REFLECT_REPEAT		(1 <<  4)
    725 #define FAST_PATH_NO_ACCESSORS			(1 <<  5)
    726 #define FAST_PATH_NARROW_FORMAT			(1 <<  6)
    727 #define FAST_PATH_COMPONENT_ALPHA		(1 <<  8)
    728 #define FAST_PATH_SAMPLES_OPAQUE		(1 <<  7)
    729 #define FAST_PATH_UNIFIED_ALPHA			(1 <<  9)
    730 #define FAST_PATH_SCALE_TRANSFORM		(1 << 10)
    731 #define FAST_PATH_NEAREST_FILTER		(1 << 11)
    732 #define FAST_PATH_HAS_TRANSFORM			(1 << 12)
    733 #define FAST_PATH_IS_OPAQUE			(1 << 13)
    734 #define FAST_PATH_NO_NORMAL_REPEAT		(1 << 14)
    735 #define FAST_PATH_NO_NONE_REPEAT		(1 << 15)
    736 #define FAST_PATH_X_UNIT_POSITIVE		(1 << 16)
    737 #define FAST_PATH_AFFINE_TRANSFORM		(1 << 17)
    738 #define FAST_PATH_Y_UNIT_ZERO			(1 << 18)
    739 #define FAST_PATH_BILINEAR_FILTER		(1 << 19)
    740 #define FAST_PATH_ROTATE_90_TRANSFORM		(1 << 20)
    741 #define FAST_PATH_ROTATE_180_TRANSFORM		(1 << 21)
    742 #define FAST_PATH_ROTATE_270_TRANSFORM		(1 << 22)
    743 #define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST	(1 << 23)
    744 #define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR	(1 << 24)
    745 #define FAST_PATH_BITS_IMAGE			(1 << 25)
    746 #define FAST_PATH_SEPARABLE_CONVOLUTION_FILTER  (1 << 26)
    747 
    748 #define FAST_PATH_PAD_REPEAT						\
    749     (FAST_PATH_NO_NONE_REPEAT		|				\
    750      FAST_PATH_NO_NORMAL_REPEAT		|				\
    751      FAST_PATH_NO_REFLECT_REPEAT)
    752 
    753 #define FAST_PATH_NORMAL_REPEAT						\
    754     (FAST_PATH_NO_NONE_REPEAT		|				\
    755      FAST_PATH_NO_PAD_REPEAT		|				\
    756      FAST_PATH_NO_REFLECT_REPEAT)
    757 
    758 #define FAST_PATH_NONE_REPEAT						\
    759     (FAST_PATH_NO_NORMAL_REPEAT		|				\
    760      FAST_PATH_NO_PAD_REPEAT		|				\
    761      FAST_PATH_NO_REFLECT_REPEAT)
    762 
    763 #define FAST_PATH_REFLECT_REPEAT					\
    764     (FAST_PATH_NO_NONE_REPEAT		|				\
    765      FAST_PATH_NO_NORMAL_REPEAT		|				\
    766      FAST_PATH_NO_PAD_REPEAT)
    767 
    768 #define FAST_PATH_STANDARD_FLAGS					\
    769     (FAST_PATH_NO_CONVOLUTION_FILTER	|				\
    770      FAST_PATH_NO_ACCESSORS		|				\
    771      FAST_PATH_NO_ALPHA_MAP		|				\
    772      FAST_PATH_NARROW_FORMAT)
    773 
    774 #define FAST_PATH_STD_DEST_FLAGS					\
    775     (FAST_PATH_NO_ACCESSORS		|				\
    776      FAST_PATH_NO_ALPHA_MAP		|				\
    777      FAST_PATH_NARROW_FORMAT)
    778 
    779 #define SOURCE_FLAGS(format)						\
    780     (FAST_PATH_STANDARD_FLAGS |						\
    781      ((PIXMAN_ ## format == PIXMAN_solid) ?				\
    782       0 : (FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | FAST_PATH_NEAREST_FILTER | FAST_PATH_ID_TRANSFORM)))
    783 
    784 #define MASK_FLAGS(format, extra)					\
    785     ((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
    786 
    787 #define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \
    788     PIXMAN_OP_ ## op,							\
    789     PIXMAN_ ## src,							\
    790     src_flags,							        \
    791     PIXMAN_ ## mask,						        \
    792     mask_flags,							        \
    793     PIXMAN_ ## dest,	                                                \
    794     dest_flags,							        \
    795     func
    796 
    797 #define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func)			\
    798     { FAST_PATH (							\
    799 	    op,								\
    800 	    src,  SOURCE_FLAGS (src),					\
    801 	    mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA),		\
    802 	    dest, FAST_PATH_STD_DEST_FLAGS,				\
    803 	    func) }
    804 
    805 #define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func)		\
    806     { FAST_PATH (							\
    807 	    op,								\
    808 	    src,  SOURCE_FLAGS (src),					\
    809 	    mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA),		\
    810 	    dest, FAST_PATH_STD_DEST_FLAGS,				\
    811 	    func) }
    812 
    813 extern pixman_implementation_t *global_implementation;
    814 
    815 static force_inline pixman_implementation_t *
    816 get_implementation (void)
    817 {
    818 #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
    819     if (!global_implementation)
    820 	global_implementation = _pixman_choose_implementation ();
    821 #endif
    822     return global_implementation;
    823 }
    824 
    825 /* This function is exported for the sake of the test suite and not part
    826  * of the ABI.
    827  */
    828 PIXMAN_EXPORT pixman_implementation_t *
    829 _pixman_internal_only_get_reference_implementation (void);
    830 
    831 /* This function is exported for the sake of the test suite and not part
    832  * of the ABI.
    833  */
    834 PIXMAN_EXPORT pixman_implementation_t *
    835 _pixman_internal_only_get_implementation (void);
    836 
    837 /* This function is exported for the sake of the test suite and not part
    838  * of the ABI.
    839  */
    840 PIXMAN_EXPORT pixman_fast_path_t *
    841 _pixman_implementation_get_reference_fast_path (void);
    842 
    843 /* This function is exported for the sake of the test suite and not part
    844  * of the ABI.
    845  */
    846 PIXMAN_EXPORT int
    847 _pixman_implementation_get_reference_fast_path_size ();
    848 
    849 /* Memory allocation helpers */
    850 void *
    851 pixman_malloc_ab (unsigned int n, unsigned int b);
    852 
    853 void *
    854 pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
    855 
    856 void *
    857 pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c);
    858 
    859 pixman_bool_t
    860 _pixman_multiply_overflows_size (size_t a, size_t b);
    861 
    862 pixman_bool_t
    863 _pixman_multiply_overflows_int (unsigned int a, unsigned int b);
    864 
    865 pixman_bool_t
    866 _pixman_addition_overflows_int (unsigned int a, unsigned int b);
    867 
    868 /* Compositing utilities */
    869 void
    870 pixman_expand_to_float (argb_t               *dst,
    871 			const uint32_t       *src,
    872 			pixman_format_code_t  format,
    873 			int                   width);
    874 
    875 void
    876 pixman_contract_from_float (uint32_t     *dst,
    877 			    const argb_t *src,
    878 			    int           width);
    879 
    880 /* Region Helpers */
    881 pixman_bool_t
    882 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
    883                                     const pixman_region16_t *src);
    884 
    885 pixman_bool_t
    886 pixman_region32_copy_from_region64f (pixman_region32_t *dst,
    887                                      const pixman_region64f_t *src);
    888 
    889 pixman_bool_t
    890 pixman_region16_copy_from_region32 (pixman_region16_t *dst,
    891                                     const pixman_region32_t *src);
    892 
    893 /* Doubly linked lists */
    894 typedef struct pixman_link_t pixman_link_t;
    895 struct pixman_link_t
    896 {
    897     pixman_link_t *next;
    898     pixman_link_t *prev;
    899 };
    900 
    901 typedef struct pixman_list_t pixman_list_t;
    902 struct pixman_list_t
    903 {
    904     pixman_link_t *head;
    905     pixman_link_t *tail;
    906 };
    907 
    908 static force_inline void
    909 pixman_list_init (pixman_list_t *list)
    910 {
    911     list->head = (pixman_link_t *)list;
    912     list->tail = (pixman_link_t *)list;
    913 }
    914 
    915 static force_inline void
    916 pixman_list_prepend (pixman_list_t *list, pixman_link_t *link)
    917 {
    918     link->next = list->head;
    919     link->prev = (pixman_link_t *)list;
    920     list->head->prev = link;
    921     list->head = link;
    922 }
    923 
    924 static force_inline void
    925 pixman_list_unlink (pixman_link_t *link)
    926 {
    927     link->prev->next = link->next;
    928     link->next->prev = link->prev;
    929 }
    930 
    931 static force_inline void
    932 pixman_list_move_to_front (pixman_list_t *list, pixman_link_t *link)
    933 {
    934     pixman_list_unlink (link);
    935     pixman_list_prepend (list, link);
    936 }
    937 
    938 /* Misc macros */
    939 
    940 #ifndef FALSE
    941 #   define FALSE 0
    942 #endif
    943 
    944 #ifndef TRUE
    945 #   define TRUE 1
    946 #endif
    947 
    948 #ifndef MIN
    949 #  define MIN(a, b) ((a < b) ? a : b)
    950 #endif
    951 
    952 #ifndef MAX
    953 #  define MAX(a, b) ((a > b) ? a : b)
    954 #endif
    955 
    956 /* Integer division that rounds towards -infinity */
    957 #define DIV(a, b)					   \
    958     ((((a) < 0) == ((b) < 0)) ? (a) / (b) :                \
    959      ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
    960 
    961 /* Modulus that produces the remainder wrt. DIV */
    962 #define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
    963 
    964 #define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v)))
    965 
    966 #define FLOAT_IS_ZERO(f)     (-FLT_MIN < (f) && (f) < FLT_MIN)
    967 
    968 /* Conversion between 8888 and 0565 */
    969 
    970 static force_inline uint16_t
    971 convert_8888_to_0565 (uint32_t s)
    972 {
    973     /* The following code can be compiled into just 4 instructions on ARM */
    974     uint32_t a, b;
    975     a = (s >> 3) & 0x1F001F;
    976     b = s & 0xFC00;
    977     a |= a >> 5;
    978     a |= b >> 5;
    979     return (uint16_t)a;
    980 }
    981 
    982 static force_inline uint32_t
    983 convert_0565_to_0888 (uint16_t s)
    984 {
    985     return (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) |
    986             ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) |
    987             ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)));
    988 }
    989 
    990 static force_inline uint32_t
    991 convert_0565_to_8888 (uint16_t s)
    992 {
    993     return convert_0565_to_0888 (s) | 0xff000000;
    994 }
    995 
    996 /* Trivial versions that are useful in macros */
    997 
    998 static force_inline uint32_t
    999 convert_8888_to_8888 (uint32_t s)
   1000 {
   1001     return s;
   1002 }
   1003 
   1004 static force_inline uint32_t
   1005 convert_x888_to_8888 (uint32_t s)
   1006 {
   1007     return s | 0xff000000;
   1008 }
   1009 
   1010 static force_inline uint16_t
   1011 convert_0565_to_0565 (uint16_t s)
   1012 {
   1013     return s;
   1014 }
   1015 
   1016 #define PIXMAN_FORMAT_IS_WIDE(f)					\
   1017     (PIXMAN_FORMAT_A (f) > 8 ||						\
   1018      PIXMAN_FORMAT_R (f) > 8 ||						\
   1019      PIXMAN_FORMAT_G (f) > 8 ||						\
   1020      PIXMAN_FORMAT_B (f) > 8 ||						\
   1021      PIXMAN_FORMAT_TYPE (f) == PIXMAN_TYPE_ARGB_SRGB)
   1022 
   1023 #ifdef WORDS_BIGENDIAN
   1024 #   define SCREEN_SHIFT_LEFT(x,n)	((x) << (n))
   1025 #   define SCREEN_SHIFT_RIGHT(x,n)	((x) >> (n))
   1026 #else
   1027 #   define SCREEN_SHIFT_LEFT(x,n)	((x) >> (n))
   1028 #   define SCREEN_SHIFT_RIGHT(x,n)	((x) << (n))
   1029 #endif
   1030 
   1031 static force_inline uint32_t
   1032 unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
   1033 {
   1034     uint32_t result;
   1035 
   1036     if (from_bits == 0)
   1037 	return 0;
   1038 
   1039     /* Delete any extra bits */
   1040     val &= ((1 << from_bits) - 1);
   1041 
   1042     if (from_bits >= to_bits)
   1043 	return val >> (from_bits - to_bits);
   1044 
   1045     /* Start out with the high bit of val in the high bit of result. */
   1046     result = val << (to_bits - from_bits);
   1047 
   1048     /* Copy the bits in result, doubling the number of bits each time, until
   1049      * we fill all to_bits. Unrolled manually because from_bits and to_bits
   1050      * are usually known statically, so the compiler can turn all of this
   1051      * into a few shifts.
   1052      */
   1053 #define REPLICATE()							\
   1054     do									\
   1055     {									\
   1056 	if (from_bits < to_bits)					\
   1057 	{								\
   1058 	    result |= result >> from_bits;				\
   1059 									\
   1060 	    from_bits *= 2;						\
   1061 	}								\
   1062     }									\
   1063     while (0)
   1064 
   1065     REPLICATE();
   1066     REPLICATE();
   1067     REPLICATE();
   1068     REPLICATE();
   1069     REPLICATE();
   1070 
   1071     return result;
   1072 }
   1073 
   1074 uint16_t pixman_float_to_unorm (float f, int n_bits);
   1075 float pixman_unorm_to_float (uint16_t u, int n_bits);
   1076 
   1077 /*
   1078  * Various debugging code
   1079  */
   1080 
   1081 #define COMPILE_TIME_ASSERT(x)						\
   1082     do { typedef int compile_time_assertion [(x)?1:-1]; } while (0)
   1083 
   1084 void
   1085 _pixman_log_error (const char *function, const char *message);
   1086 
   1087 #define return_if_fail(expr)                                            \
   1088     do                                                                  \
   1089     {                                                                   \
   1090 	if (unlikely (!(expr)))                                         \
   1091 	{								\
   1092 	    _pixman_log_error (FUNC, "The expression " # expr " was false"); \
   1093 	    return;							\
   1094 	}								\
   1095     }                                                                   \
   1096     while (0)
   1097 
   1098 #define return_val_if_fail(expr, retval)                                \
   1099     do                                                                  \
   1100     {                                                                   \
   1101 	if (unlikely (!(expr)))                                         \
   1102 	{								\
   1103 	    _pixman_log_error (FUNC, "The expression " # expr " was false"); \
   1104 	    return (retval);						\
   1105 	}								\
   1106     }                                                                   \
   1107     while (0)
   1108 
   1109 #define critical_if_fail(expr)						\
   1110     do									\
   1111     {									\
   1112 	if (unlikely (!(expr)))                                         \
   1113 	    _pixman_log_error (FUNC, "The expression " # expr " was false"); \
   1114     }									\
   1115     while (0)
   1116 
   1117 /*
   1118  * Matrix
   1119  */
   1120 
   1121 typedef struct { pixman_fixed_48_16_t v[3]; } pixman_vector_48_16_t;
   1122 
   1123 PIXMAN_EXPORT
   1124 pixman_bool_t
   1125 pixman_transform_point_31_16 (const pixman_transform_t    *t,
   1126                               const pixman_vector_48_16_t *v,
   1127                               pixman_vector_48_16_t       *result);
   1128 
   1129 PIXMAN_EXPORT
   1130 void
   1131 pixman_transform_point_31_16_3d (const pixman_transform_t    *t,
   1132                                  const pixman_vector_48_16_t *v,
   1133                                  pixman_vector_48_16_t       *result);
   1134 
   1135 PIXMAN_EXPORT
   1136 void
   1137 pixman_transform_point_31_16_affine (const pixman_transform_t    *t,
   1138                                      const pixman_vector_48_16_t *v,
   1139                                      pixman_vector_48_16_t       *result);
   1140 
   1141 /*
   1142  * Timers
   1143  */
   1144 
   1145 #ifdef PIXMAN_TIMERS
   1146 
   1147 static inline uint64_t
   1148 oil_profile_stamp_rdtsc (void)
   1149 {
   1150     uint32_t hi, lo;
   1151 
   1152     __asm__ __volatile__ ("rdtsc\n" : "=a" (lo), "=d" (hi));
   1153 
   1154     return lo | (((uint64_t)hi) << 32);
   1155 }
   1156 
   1157 #define OIL_STAMP oil_profile_stamp_rdtsc
   1158 
   1159 typedef struct pixman_timer_t pixman_timer_t;
   1160 
   1161 struct pixman_timer_t
   1162 {
   1163     int             initialized;
   1164     const char *    name;
   1165     uint64_t        n_times;
   1166     uint64_t        total;
   1167     pixman_timer_t *next;
   1168 };
   1169 
   1170 extern int timer_defined;
   1171 
   1172 void pixman_timer_register (pixman_timer_t *timer);
   1173 
   1174 #define TIMER_BEGIN(tname)                                              \
   1175     {                                                                   \
   1176 	static pixman_timer_t timer ## tname;                           \
   1177 	uint64_t              begin ## tname;                           \
   1178         								\
   1179 	if (!timer ## tname.initialized)				\
   1180 	{                                                               \
   1181 	    timer ## tname.initialized = 1;				\
   1182 	    timer ## tname.name = # tname;				\
   1183 	    pixman_timer_register (&timer ## tname);			\
   1184 	}                                                               \
   1185 									\
   1186 	timer ## tname.n_times++;					\
   1187 	begin ## tname = OIL_STAMP ();
   1188 
   1189 #define TIMER_END(tname)                                                \
   1190     timer ## tname.total += OIL_STAMP () - begin ## tname;		\
   1191     }
   1192 
   1193 #else
   1194 
   1195 #define TIMER_BEGIN(tname)
   1196 #define TIMER_END(tname)
   1197 
   1198 #endif /* PIXMAN_TIMERS */
   1199 
   1200 #endif /* __ASSEMBLER__ */
   1201 
   1202 #endif /* PIXMAN_PRIVATE_H */
   1203