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