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